1// SPDX-License-Identifier: MIT
2/*
3 * Copyright 2022 Advanced Micro Devices, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: AMD
24 *
25 */
26
27#define UNIT_TEST 0
28#if !UNIT_TEST
29#include "dc.h"
30#endif
31#include "../display_mode_lib.h"
32#include "display_mode_vba_314.h"
33#include "../dml_inline_defs.h"
34
35/*
36 * NOTE:
37 *   This file is gcc-parsable HW gospel, coming straight from HW engineers.
38 *
39 * It doesn't adhere to Linux kernel style and sometimes will do things in odd
40 * ways. Unless there is something clearly wrong with it the code should
41 * remain as-is as it provides us with a guarantee from HW that it is correct.
42 */
43
44#define BPP_INVALID 0
45#define BPP_BLENDED_PIPE 0xffffffff
46#define DCN314_MAX_DSC_IMAGE_WIDTH 5184
47#define DCN314_MAX_FMT_420_BUFFER_WIDTH 4096
48
49// For DML-C changes that hasn't been propagated to VBA yet
50//#define __DML_VBA_ALLOW_DELTA__
51
52// Move these to ip parameters/constant
53
54// At which vstartup the DML start to try if the mode can be supported
55#define __DML_VBA_MIN_VSTARTUP__    9
56
57// Delay in DCFCLK from ARB to DET (1st num is ARB to SDPIF, 2nd number is SDPIF to DET)
58#define __DML_ARB_TO_RET_DELAY__    (7 + 95)
59
60// fudge factor for min dcfclk calclation
61#define __DML_MIN_DCFCLK_FACTOR__   1.15
62
63typedef struct {
64	double DPPCLK;
65	double DISPCLK;
66	double PixelClock;
67	double DCFCLKDeepSleep;
68	unsigned int DPPPerPlane;
69	bool ScalerEnabled;
70	double VRatio;
71	double VRatioChroma;
72	enum scan_direction_class SourceScan;
73	unsigned int BlockWidth256BytesY;
74	unsigned int BlockHeight256BytesY;
75	unsigned int BlockWidth256BytesC;
76	unsigned int BlockHeight256BytesC;
77	unsigned int InterlaceEnable;
78	unsigned int NumberOfCursors;
79	unsigned int VBlank;
80	unsigned int HTotal;
81	unsigned int DCCEnable;
82	bool ODMCombineIsEnabled;
83	enum source_format_class SourcePixelFormat;
84	int BytePerPixelY;
85	int BytePerPixelC;
86	bool ProgressiveToInterlaceUnitInOPP;
87} Pipe;
88
89#define BPP_INVALID 0
90#define BPP_BLENDED_PIPE 0xffffffff
91
92static bool CalculateBytePerPixelAnd256BBlockSizes(
93		enum source_format_class SourcePixelFormat,
94		enum dm_swizzle_mode SurfaceTiling,
95		unsigned int *BytePerPixelY,
96		unsigned int *BytePerPixelC,
97		double *BytePerPixelDETY,
98		double *BytePerPixelDETC,
99		unsigned int *BlockHeight256BytesY,
100		unsigned int *BlockHeight256BytesC,
101		unsigned int *BlockWidth256BytesY,
102		unsigned int *BlockWidth256BytesC);
103static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
104static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib);
105static unsigned int dscceComputeDelay(
106		unsigned int bpc,
107		double BPP,
108		unsigned int sliceWidth,
109		unsigned int numSlices,
110		enum output_format_class pixelFormat,
111		enum output_encoder_class Output);
112static unsigned int dscComputeDelay(enum output_format_class pixelFormat, enum output_encoder_class Output);
113static bool CalculatePrefetchSchedule(
114		struct display_mode_lib *mode_lib,
115		double HostVMInefficiencyFactor,
116		Pipe *myPipe,
117		unsigned int DSCDelay,
118		double DPPCLKDelaySubtotalPlusCNVCFormater,
119		double DPPCLKDelaySCL,
120		double DPPCLKDelaySCLLBOnly,
121		double DPPCLKDelayCNVCCursor,
122		double DISPCLKDelaySubtotal,
123		unsigned int DPP_RECOUT_WIDTH,
124		enum output_format_class OutputFormat,
125		unsigned int MaxInterDCNTileRepeaters,
126		unsigned int VStartup,
127		unsigned int MaxVStartup,
128		unsigned int GPUVMPageTableLevels,
129		bool GPUVMEnable,
130		bool HostVMEnable,
131		unsigned int HostVMMaxNonCachedPageTableLevels,
132		double HostVMMinPageSize,
133		bool DynamicMetadataEnable,
134		bool DynamicMetadataVMEnabled,
135		int DynamicMetadataLinesBeforeActiveRequired,
136		unsigned int DynamicMetadataTransmittedBytes,
137		double UrgentLatency,
138		double UrgentExtraLatency,
139		double TCalc,
140		unsigned int PDEAndMetaPTEBytesFrame,
141		unsigned int MetaRowByte,
142		unsigned int PixelPTEBytesPerRow,
143		double PrefetchSourceLinesY,
144		unsigned int SwathWidthY,
145		double VInitPreFillY,
146		unsigned int MaxNumSwathY,
147		double PrefetchSourceLinesC,
148		unsigned int SwathWidthC,
149		double VInitPreFillC,
150		unsigned int MaxNumSwathC,
151		int swath_width_luma_ub,
152		int swath_width_chroma_ub,
153		unsigned int SwathHeightY,
154		unsigned int SwathHeightC,
155		double TWait,
156		double *DSTXAfterScaler,
157		double *DSTYAfterScaler,
158		double *DestinationLinesForPrefetch,
159		double *PrefetchBandwidth,
160		double *DestinationLinesToRequestVMInVBlank,
161		double *DestinationLinesToRequestRowInVBlank,
162		double *VRatioPrefetchY,
163		double *VRatioPrefetchC,
164		double *RequiredPrefetchPixDataBWLuma,
165		double *RequiredPrefetchPixDataBWChroma,
166		bool *NotEnoughTimeForDynamicMetadata,
167		double *Tno_bw,
168		double *prefetch_vmrow_bw,
169		double *Tdmdl_vm,
170		double *Tdmdl,
171		double *TSetup,
172		int *VUpdateOffsetPix,
173		double *VUpdateWidthPix,
174		double *VReadyOffsetPix);
175static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
176static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
177static void CalculateDCCConfiguration(
178		bool DCCEnabled,
179		bool DCCProgrammingAssumesScanDirectionUnknown,
180		enum source_format_class SourcePixelFormat,
181		unsigned int SurfaceWidthLuma,
182		unsigned int SurfaceWidthChroma,
183		unsigned int SurfaceHeightLuma,
184		unsigned int SurfaceHeightChroma,
185		double DETBufferSize,
186		unsigned int RequestHeight256ByteLuma,
187		unsigned int RequestHeight256ByteChroma,
188		enum dm_swizzle_mode TilingFormat,
189		unsigned int BytePerPixelY,
190		unsigned int BytePerPixelC,
191		double BytePerPixelDETY,
192		double BytePerPixelDETC,
193		enum scan_direction_class ScanOrientation,
194		unsigned int *MaxUncompressedBlockLuma,
195		unsigned int *MaxUncompressedBlockChroma,
196		unsigned int *MaxCompressedBlockLuma,
197		unsigned int *MaxCompressedBlockChroma,
198		unsigned int *IndependentBlockLuma,
199		unsigned int *IndependentBlockChroma);
200static double CalculatePrefetchSourceLines(
201		struct display_mode_lib *mode_lib,
202		double VRatio,
203		double vtaps,
204		bool Interlace,
205		bool ProgressiveToInterlaceUnitInOPP,
206		unsigned int SwathHeight,
207		unsigned int ViewportYStart,
208		double *VInitPreFill,
209		unsigned int *MaxNumSwath);
210static unsigned int CalculateVMAndRowBytes(
211		struct display_mode_lib *mode_lib,
212		bool DCCEnable,
213		unsigned int BlockHeight256Bytes,
214		unsigned int BlockWidth256Bytes,
215		enum source_format_class SourcePixelFormat,
216		unsigned int SurfaceTiling,
217		unsigned int BytePerPixel,
218		enum scan_direction_class ScanDirection,
219		unsigned int SwathWidth,
220		unsigned int ViewportHeight,
221		bool GPUVMEnable,
222		bool HostVMEnable,
223		unsigned int HostVMMaxNonCachedPageTableLevels,
224		unsigned int GPUVMMinPageSize,
225		unsigned int HostVMMinPageSize,
226		unsigned int PTEBufferSizeInRequests,
227		unsigned int Pitch,
228		unsigned int DCCMetaPitch,
229		unsigned int *MacroTileWidth,
230		unsigned int *MetaRowByte,
231		unsigned int *PixelPTEBytesPerRow,
232		bool *PTEBufferSizeNotExceeded,
233		int *dpte_row_width_ub,
234		unsigned int *dpte_row_height,
235		unsigned int *MetaRequestWidth,
236		unsigned int *MetaRequestHeight,
237		unsigned int *meta_row_width,
238		unsigned int *meta_row_height,
239		int *vm_group_bytes,
240		unsigned int *dpte_group_bytes,
241		unsigned int *PixelPTEReqWidth,
242		unsigned int *PixelPTEReqHeight,
243		unsigned int *PTERequestSize,
244		int *DPDE0BytesFrame,
245		int *MetaPTEBytesFrame);
246static double CalculateTWait(unsigned int PrefetchMode, double DRAMClockChangeLatency, double UrgentLatency, double SREnterPlusExitTime);
247static void CalculateRowBandwidth(
248		bool GPUVMEnable,
249		enum source_format_class SourcePixelFormat,
250		double VRatio,
251		double VRatioChroma,
252		bool DCCEnable,
253		double LineTime,
254		unsigned int MetaRowByteLuma,
255		unsigned int MetaRowByteChroma,
256		unsigned int meta_row_height_luma,
257		unsigned int meta_row_height_chroma,
258		unsigned int PixelPTEBytesPerRowLuma,
259		unsigned int PixelPTEBytesPerRowChroma,
260		unsigned int dpte_row_height_luma,
261		unsigned int dpte_row_height_chroma,
262		double *meta_row_bw,
263		double *dpte_row_bw);
264
265static void CalculateFlipSchedule(
266		struct display_mode_lib *mode_lib,
267		unsigned int k,
268		double HostVMInefficiencyFactor,
269		double UrgentExtraLatency,
270		double UrgentLatency,
271		double PDEAndMetaPTEBytesPerFrame,
272		double MetaRowBytes,
273		double DPTEBytesPerRow);
274static double CalculateWriteBackDelay(
275		enum source_format_class WritebackPixelFormat,
276		double WritebackHRatio,
277		double WritebackVRatio,
278		unsigned int WritebackVTaps,
279		int WritebackDestinationWidth,
280		int WritebackDestinationHeight,
281		int WritebackSourceHeight,
282		unsigned int HTotal);
283
284static void CalculateVupdateAndDynamicMetadataParameters(
285		int MaxInterDCNTileRepeaters,
286		double DPPCLK,
287		double DISPCLK,
288		double DCFClkDeepSleep,
289		double PixelClock,
290		int HTotal,
291		int VBlank,
292		int DynamicMetadataTransmittedBytes,
293		int DynamicMetadataLinesBeforeActiveRequired,
294		int InterlaceEnable,
295		bool ProgressiveToInterlaceUnitInOPP,
296		double *TSetup,
297		double *Tdmbf,
298		double *Tdmec,
299		double *Tdmsks,
300		int *VUpdateOffsetPix,
301		double *VUpdateWidthPix,
302		double *VReadyOffsetPix);
303
304static void CalculateWatermarksAndDRAMSpeedChangeSupport(
305		struct display_mode_lib *mode_lib,
306		unsigned int PrefetchMode,
307		double DCFCLK,
308		double ReturnBW,
309		double UrgentLatency,
310		double ExtraLatency,
311		double SOCCLK,
312		double DCFCLKDeepSleep,
313		unsigned int DETBufferSizeY[],
314		unsigned int DETBufferSizeC[],
315		unsigned int SwathHeightY[],
316		unsigned int SwathHeightC[],
317		double SwathWidthY[],
318		double SwathWidthC[],
319		unsigned int DPPPerPlane[],
320		double BytePerPixelDETY[],
321		double BytePerPixelDETC[],
322		bool UnboundedRequestEnabled,
323		unsigned int CompressedBufferSizeInkByte,
324		enum clock_change_support *DRAMClockChangeSupport,
325		double *StutterExitWatermark,
326		double *StutterEnterPlusExitWatermark,
327		double *Z8StutterExitWatermark,
328		double *Z8StutterEnterPlusExitWatermark);
329
330static void CalculateDCFCLKDeepSleep(
331		struct display_mode_lib *mode_lib,
332		unsigned int NumberOfActivePlanes,
333		int BytePerPixelY[],
334		int BytePerPixelC[],
335		double VRatio[],
336		double VRatioChroma[],
337		double SwathWidthY[],
338		double SwathWidthC[],
339		unsigned int DPPPerPlane[],
340		double HRatio[],
341		double HRatioChroma[],
342		double PixelClock[],
343		double PSCL_THROUGHPUT[],
344		double PSCL_THROUGHPUT_CHROMA[],
345		double DPPCLK[],
346		double ReadBandwidthLuma[],
347		double ReadBandwidthChroma[],
348		int ReturnBusWidth,
349		double *DCFCLKDeepSleep);
350
351static void CalculateUrgentBurstFactor(
352		int swath_width_luma_ub,
353		int swath_width_chroma_ub,
354		unsigned int SwathHeightY,
355		unsigned int SwathHeightC,
356		double LineTime,
357		double UrgentLatency,
358		double CursorBufferSize,
359		unsigned int CursorWidth,
360		unsigned int CursorBPP,
361		double VRatio,
362		double VRatioC,
363		double BytePerPixelInDETY,
364		double BytePerPixelInDETC,
365		double DETBufferSizeY,
366		double DETBufferSizeC,
367		double *UrgentBurstFactorCursor,
368		double *UrgentBurstFactorLuma,
369		double *UrgentBurstFactorChroma,
370		bool *NotEnoughUrgentLatencyHiding);
371
372static void UseMinimumDCFCLK(
373		struct display_mode_lib *mode_lib,
374		int MaxPrefetchMode,
375		int ReorderingBytes);
376
377static void CalculatePixelDeliveryTimes(
378		unsigned int NumberOfActivePlanes,
379		double VRatio[],
380		double VRatioChroma[],
381		double VRatioPrefetchY[],
382		double VRatioPrefetchC[],
383		unsigned int swath_width_luma_ub[],
384		unsigned int swath_width_chroma_ub[],
385		unsigned int DPPPerPlane[],
386		double HRatio[],
387		double HRatioChroma[],
388		double PixelClock[],
389		double PSCL_THROUGHPUT[],
390		double PSCL_THROUGHPUT_CHROMA[],
391		double DPPCLK[],
392		int BytePerPixelC[],
393		enum scan_direction_class SourceScan[],
394		unsigned int NumberOfCursors[],
395		unsigned int CursorWidth[][DC__NUM_CURSOR__MAX],
396		unsigned int CursorBPP[][DC__NUM_CURSOR__MAX],
397		unsigned int BlockWidth256BytesY[],
398		unsigned int BlockHeight256BytesY[],
399		unsigned int BlockWidth256BytesC[],
400		unsigned int BlockHeight256BytesC[],
401		double DisplayPipeLineDeliveryTimeLuma[],
402		double DisplayPipeLineDeliveryTimeChroma[],
403		double DisplayPipeLineDeliveryTimeLumaPrefetch[],
404		double DisplayPipeLineDeliveryTimeChromaPrefetch[],
405		double DisplayPipeRequestDeliveryTimeLuma[],
406		double DisplayPipeRequestDeliveryTimeChroma[],
407		double DisplayPipeRequestDeliveryTimeLumaPrefetch[],
408		double DisplayPipeRequestDeliveryTimeChromaPrefetch[],
409		double CursorRequestDeliveryTime[],
410		double CursorRequestDeliveryTimePrefetch[]);
411
412static void CalculateMetaAndPTETimes(
413		int NumberOfActivePlanes,
414		bool GPUVMEnable,
415		int MetaChunkSize,
416		int MinMetaChunkSizeBytes,
417		int HTotal[],
418		double VRatio[],
419		double VRatioChroma[],
420		double DestinationLinesToRequestRowInVBlank[],
421		double DestinationLinesToRequestRowInImmediateFlip[],
422		bool DCCEnable[],
423		double PixelClock[],
424		int BytePerPixelY[],
425		int BytePerPixelC[],
426		enum scan_direction_class SourceScan[],
427		int dpte_row_height[],
428		int dpte_row_height_chroma[],
429		int meta_row_width[],
430		int meta_row_width_chroma[],
431		int meta_row_height[],
432		int meta_row_height_chroma[],
433		int meta_req_width[],
434		int meta_req_width_chroma[],
435		int meta_req_height[],
436		int meta_req_height_chroma[],
437		int dpte_group_bytes[],
438		int PTERequestSizeY[],
439		int PTERequestSizeC[],
440		int PixelPTEReqWidthY[],
441		int PixelPTEReqHeightY[],
442		int PixelPTEReqWidthC[],
443		int PixelPTEReqHeightC[],
444		int dpte_row_width_luma_ub[],
445		int dpte_row_width_chroma_ub[],
446		double DST_Y_PER_PTE_ROW_NOM_L[],
447		double DST_Y_PER_PTE_ROW_NOM_C[],
448		double DST_Y_PER_META_ROW_NOM_L[],
449		double DST_Y_PER_META_ROW_NOM_C[],
450		double TimePerMetaChunkNominal[],
451		double TimePerChromaMetaChunkNominal[],
452		double TimePerMetaChunkVBlank[],
453		double TimePerChromaMetaChunkVBlank[],
454		double TimePerMetaChunkFlip[],
455		double TimePerChromaMetaChunkFlip[],
456		double time_per_pte_group_nom_luma[],
457		double time_per_pte_group_vblank_luma[],
458		double time_per_pte_group_flip_luma[],
459		double time_per_pte_group_nom_chroma[],
460		double time_per_pte_group_vblank_chroma[],
461		double time_per_pte_group_flip_chroma[]);
462
463static void CalculateVMGroupAndRequestTimes(
464		unsigned int NumberOfActivePlanes,
465		bool GPUVMEnable,
466		unsigned int GPUVMMaxPageTableLevels,
467		unsigned int HTotal[],
468		int BytePerPixelC[],
469		double DestinationLinesToRequestVMInVBlank[],
470		double DestinationLinesToRequestVMInImmediateFlip[],
471		bool DCCEnable[],
472		double PixelClock[],
473		int dpte_row_width_luma_ub[],
474		int dpte_row_width_chroma_ub[],
475		int vm_group_bytes[],
476		unsigned int dpde0_bytes_per_frame_ub_l[],
477		unsigned int dpde0_bytes_per_frame_ub_c[],
478		int meta_pte_bytes_per_frame_ub_l[],
479		int meta_pte_bytes_per_frame_ub_c[],
480		double TimePerVMGroupVBlank[],
481		double TimePerVMGroupFlip[],
482		double TimePerVMRequestVBlank[],
483		double TimePerVMRequestFlip[]);
484
485static void CalculateStutterEfficiency(
486		struct display_mode_lib *mode_lib,
487		int CompressedBufferSizeInkByte,
488		bool UnboundedRequestEnabled,
489		int ConfigReturnBufferSizeInKByte,
490		int MetaFIFOSizeInKEntries,
491		int ZeroSizeBufferEntries,
492		int NumberOfActivePlanes,
493		int ROBBufferSizeInKByte,
494		double TotalDataReadBandwidth,
495		double DCFCLK,
496		double ReturnBW,
497		double COMPBUF_RESERVED_SPACE_64B,
498		double COMPBUF_RESERVED_SPACE_ZS,
499		double SRExitTime,
500		double SRExitZ8Time,
501		bool SynchronizedVBlank,
502		double Z8StutterEnterPlusExitWatermark,
503		double StutterEnterPlusExitWatermark,
504		bool ProgressiveToInterlaceUnitInOPP,
505		bool Interlace[],
506		double MinTTUVBlank[],
507		int DPPPerPlane[],
508		unsigned int DETBufferSizeY[],
509		int BytePerPixelY[],
510		double BytePerPixelDETY[],
511		double SwathWidthY[],
512		int SwathHeightY[],
513		int SwathHeightC[],
514		double NetDCCRateLuma[],
515		double NetDCCRateChroma[],
516		double DCCFractionOfZeroSizeRequestsLuma[],
517		double DCCFractionOfZeroSizeRequestsChroma[],
518		int HTotal[],
519		int VTotal[],
520		double PixelClock[],
521		double VRatio[],
522		enum scan_direction_class SourceScan[],
523		int BlockHeight256BytesY[],
524		int BlockWidth256BytesY[],
525		int BlockHeight256BytesC[],
526		int BlockWidth256BytesC[],
527		int DCCYMaxUncompressedBlock[],
528		int DCCCMaxUncompressedBlock[],
529		int VActive[],
530		bool DCCEnable[],
531		bool WritebackEnable[],
532		double ReadBandwidthPlaneLuma[],
533		double ReadBandwidthPlaneChroma[],
534		double meta_row_bw[],
535		double dpte_row_bw[],
536		double *StutterEfficiencyNotIncludingVBlank,
537		double *StutterEfficiency,
538		int *NumberOfStutterBurstsPerFrame,
539		double *Z8StutterEfficiencyNotIncludingVBlank,
540		double *Z8StutterEfficiency,
541		int *Z8NumberOfStutterBurstsPerFrame,
542		double *StutterPeriod);
543
544static void CalculateSwathAndDETConfiguration(
545		bool ForceSingleDPP,
546		int NumberOfActivePlanes,
547		unsigned int DETBufferSizeInKByte,
548		double MaximumSwathWidthLuma[],
549		double MaximumSwathWidthChroma[],
550		enum scan_direction_class SourceScan[],
551		enum source_format_class SourcePixelFormat[],
552		enum dm_swizzle_mode SurfaceTiling[],
553		int ViewportWidth[],
554		int ViewportHeight[],
555		int SurfaceWidthY[],
556		int SurfaceWidthC[],
557		int SurfaceHeightY[],
558		int SurfaceHeightC[],
559		int Read256BytesBlockHeightY[],
560		int Read256BytesBlockHeightC[],
561		int Read256BytesBlockWidthY[],
562		int Read256BytesBlockWidthC[],
563		enum odm_combine_mode ODMCombineEnabled[],
564		int BlendingAndTiming[],
565		int BytePerPixY[],
566		int BytePerPixC[],
567		double BytePerPixDETY[],
568		double BytePerPixDETC[],
569		int HActive[],
570		double HRatio[],
571		double HRatioChroma[],
572		int DPPPerPlane[],
573		int swath_width_luma_ub[],
574		int swath_width_chroma_ub[],
575		double SwathWidth[],
576		double SwathWidthChroma[],
577		int SwathHeightY[],
578		int SwathHeightC[],
579		unsigned int DETBufferSizeY[],
580		unsigned int DETBufferSizeC[],
581		bool ViewportSizeSupportPerPlane[],
582		bool *ViewportSizeSupport);
583static void CalculateSwathWidth(
584		bool ForceSingleDPP,
585		int NumberOfActivePlanes,
586		enum source_format_class SourcePixelFormat[],
587		enum scan_direction_class SourceScan[],
588		int ViewportWidth[],
589		int ViewportHeight[],
590		int SurfaceWidthY[],
591		int SurfaceWidthC[],
592		int SurfaceHeightY[],
593		int SurfaceHeightC[],
594		enum odm_combine_mode ODMCombineEnabled[],
595		int BytePerPixY[],
596		int BytePerPixC[],
597		int Read256BytesBlockHeightY[],
598		int Read256BytesBlockHeightC[],
599		int Read256BytesBlockWidthY[],
600		int Read256BytesBlockWidthC[],
601		int BlendingAndTiming[],
602		int HActive[],
603		double HRatio[],
604		int DPPPerPlane[],
605		double SwathWidthSingleDPPY[],
606		double SwathWidthSingleDPPC[],
607		double SwathWidthY[],
608		double SwathWidthC[],
609		int MaximumSwathHeightY[],
610		int MaximumSwathHeightC[],
611		int swath_width_luma_ub[],
612		int swath_width_chroma_ub[]);
613
614static double CalculateExtraLatency(
615		int RoundTripPingLatencyCycles,
616		int ReorderingBytes,
617		double DCFCLK,
618		int TotalNumberOfActiveDPP,
619		int PixelChunkSizeInKByte,
620		int TotalNumberOfDCCActiveDPP,
621		int MetaChunkSize,
622		double ReturnBW,
623		bool GPUVMEnable,
624		bool HostVMEnable,
625		int NumberOfActivePlanes,
626		int NumberOfDPP[],
627		int dpte_group_bytes[],
628		double HostVMInefficiencyFactor,
629		double HostVMMinPageSize,
630		int HostVMMaxNonCachedPageTableLevels);
631
632static double CalculateExtraLatencyBytes(
633		int ReorderingBytes,
634		int TotalNumberOfActiveDPP,
635		int PixelChunkSizeInKByte,
636		int TotalNumberOfDCCActiveDPP,
637		int MetaChunkSize,
638		bool GPUVMEnable,
639		bool HostVMEnable,
640		int NumberOfActivePlanes,
641		int NumberOfDPP[],
642		int dpte_group_bytes[],
643		double HostVMInefficiencyFactor,
644		double HostVMMinPageSize,
645		int HostVMMaxNonCachedPageTableLevels);
646
647static double CalculateUrgentLatency(
648		double UrgentLatencyPixelDataOnly,
649		double UrgentLatencyPixelMixedWithVMData,
650		double UrgentLatencyVMDataOnly,
651		bool DoUrgentLatencyAdjustment,
652		double UrgentLatencyAdjustmentFabricClockComponent,
653		double UrgentLatencyAdjustmentFabricClockReference,
654		double FabricClockSingle);
655
656static void CalculateUnboundedRequestAndCompressedBufferSize(
657		unsigned int DETBufferSizeInKByte,
658		int ConfigReturnBufferSizeInKByte,
659		enum unbounded_requesting_policy UseUnboundedRequestingFinal,
660		int TotalActiveDPP,
661		bool NoChromaPlanes,
662		int MaxNumDPP,
663		int CompressedBufferSegmentSizeInkByteFinal,
664		enum output_encoder_class *Output,
665		bool *UnboundedRequestEnabled,
666		int *CompressedBufferSizeInkByte);
667
668static bool UnboundedRequest(enum unbounded_requesting_policy UseUnboundedRequestingFinal, int TotalNumberOfActiveDPP, bool NoChroma, enum output_encoder_class Output);
669static unsigned int CalculateMaxVStartup(
670		unsigned int VTotal,
671		unsigned int VActive,
672		unsigned int VBlankNom,
673		unsigned int HTotal,
674		double PixelClock,
675		bool ProgressiveTointerlaceUnitinOPP,
676		bool Interlace,
677		unsigned int VBlankNomDefaultUS,
678		double WritebackDelayTime);
679
680void dml314_recalculate(struct display_mode_lib *mode_lib)
681{
682	ModeSupportAndSystemConfiguration(mode_lib);
683	PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
684	DisplayPipeConfiguration(mode_lib);
685#ifdef __DML_VBA_DEBUG__
686	dml_print("DML::%s: Calling DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation\n", __func__);
687#endif
688	DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
689}
690
691static unsigned int dscceComputeDelay(
692		unsigned int bpc,
693		double BPP,
694		unsigned int sliceWidth,
695		unsigned int numSlices,
696		enum output_format_class pixelFormat,
697		enum output_encoder_class Output)
698{
699	// valid bpc         = source bits per component in the set of {8, 10, 12}
700	// valid bpp         = increments of 1/16 of a bit
701	//                    min = 6/7/8 in N420/N422/444, respectively
702	//                    max = such that compression is 1:1
703	//valid sliceWidth  = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
704	//valid numSlices   = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
705	//valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
706
707	// fixed value
708	unsigned int rcModelSize = 8192;
709
710	// N422/N420 operate at 2 pixels per clock
711	unsigned int pixelsPerClock = 0, lstall, D, initalXmitDelay, w, s, ix, wx, P, l0, a, ax, L, Delay, pixels;
712
713	if (pixelFormat == dm_420)
714		pixelsPerClock = 2;
715	else if (pixelFormat == dm_444)
716		pixelsPerClock = 1;
717	else if (pixelFormat == dm_n422)
718		pixelsPerClock = 2;
719	// #all other modes operate at 1 pixel per clock
720	else
721		pixelsPerClock = 1;
722
723	//initial transmit delay as per PPS
724	initalXmitDelay = dml_round(rcModelSize / 2.0 / BPP / pixelsPerClock);
725
726	//compute ssm delay
727	if (bpc == 8)
728		D = 81;
729	else if (bpc == 10)
730		D = 89;
731	else
732		D = 113;
733
734	//divide by pixel per cycle to compute slice width as seen by DSC
735	w = sliceWidth / pixelsPerClock;
736
737	//422 mode has an additional cycle of delay
738	if (pixelFormat == dm_420 || pixelFormat == dm_444 || pixelFormat == dm_n422)
739		s = 0;
740	else
741		s = 1;
742
743	//main calculation for the dscce
744	ix = initalXmitDelay + 45;
745	wx = (w + 2) / 3;
746	P = 3 * wx - w;
747	l0 = ix / w;
748	a = ix + P * l0;
749	ax = (a + 2) / 3 + D + 6 + 1;
750	L = (ax + wx - 1) / wx;
751	if ((ix % w) == 0 && P != 0)
752		lstall = 1;
753	else
754		lstall = 0;
755	Delay = L * wx * (numSlices - 1) + ax + s + lstall + 22;
756
757	//dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
758	pixels = Delay * 3 * pixelsPerClock;
759	return pixels;
760}
761
762static unsigned int dscComputeDelay(enum output_format_class pixelFormat, enum output_encoder_class Output)
763{
764	unsigned int Delay = 0;
765
766	if (pixelFormat == dm_420) {
767		//   sfr
768		Delay = Delay + 2;
769		//   dsccif
770		Delay = Delay + 0;
771		//   dscc - input deserializer
772		Delay = Delay + 3;
773		//   dscc gets pixels every other cycle
774		Delay = Delay + 2;
775		//   dscc - input cdc fifo
776		Delay = Delay + 12;
777		//   dscc gets pixels every other cycle
778		Delay = Delay + 13;
779		//   dscc - cdc uncertainty
780		Delay = Delay + 2;
781		//   dscc - output cdc fifo
782		Delay = Delay + 7;
783		//   dscc gets pixels every other cycle
784		Delay = Delay + 3;
785		//   dscc - cdc uncertainty
786		Delay = Delay + 2;
787		//   dscc - output serializer
788		Delay = Delay + 1;
789		//   sft
790		Delay = Delay + 1;
791	} else if (pixelFormat == dm_n422) {
792		//   sfr
793		Delay = Delay + 2;
794		//   dsccif
795		Delay = Delay + 1;
796		//   dscc - input deserializer
797		Delay = Delay + 5;
798		//  dscc - input cdc fifo
799		Delay = Delay + 25;
800		//   dscc - cdc uncertainty
801		Delay = Delay + 2;
802		//   dscc - output cdc fifo
803		Delay = Delay + 10;
804		//   dscc - cdc uncertainty
805		Delay = Delay + 2;
806		//   dscc - output serializer
807		Delay = Delay + 1;
808		//   sft
809		Delay = Delay + 1;
810	} else {
811		//   sfr
812		Delay = Delay + 2;
813		//   dsccif
814		Delay = Delay + 0;
815		//   dscc - input deserializer
816		Delay = Delay + 3;
817		//   dscc - input cdc fifo
818		Delay = Delay + 12;
819		//   dscc - cdc uncertainty
820		Delay = Delay + 2;
821		//   dscc - output cdc fifo
822		Delay = Delay + 7;
823		//   dscc - output serializer
824		Delay = Delay + 1;
825		//   dscc - cdc uncertainty
826		Delay = Delay + 2;
827		//   sft
828		Delay = Delay + 1;
829	}
830
831	return Delay;
832}
833
834static bool CalculatePrefetchSchedule(
835		struct display_mode_lib *mode_lib,
836		double HostVMInefficiencyFactor,
837		Pipe *myPipe,
838		unsigned int DSCDelay,
839		double DPPCLKDelaySubtotalPlusCNVCFormater,
840		double DPPCLKDelaySCL,
841		double DPPCLKDelaySCLLBOnly,
842		double DPPCLKDelayCNVCCursor,
843		double DISPCLKDelaySubtotal,
844		unsigned int DPP_RECOUT_WIDTH,
845		enum output_format_class OutputFormat,
846		unsigned int MaxInterDCNTileRepeaters,
847		unsigned int VStartup,
848		unsigned int MaxVStartup,
849		unsigned int GPUVMPageTableLevels,
850		bool GPUVMEnable,
851		bool HostVMEnable,
852		unsigned int HostVMMaxNonCachedPageTableLevels,
853		double HostVMMinPageSize,
854		bool DynamicMetadataEnable,
855		bool DynamicMetadataVMEnabled,
856		int DynamicMetadataLinesBeforeActiveRequired,
857		unsigned int DynamicMetadataTransmittedBytes,
858		double UrgentLatency,
859		double UrgentExtraLatency,
860		double TCalc,
861		unsigned int PDEAndMetaPTEBytesFrame,
862		unsigned int MetaRowByte,
863		unsigned int PixelPTEBytesPerRow,
864		double PrefetchSourceLinesY,
865		unsigned int SwathWidthY,
866		double VInitPreFillY,
867		unsigned int MaxNumSwathY,
868		double PrefetchSourceLinesC,
869		unsigned int SwathWidthC,
870		double VInitPreFillC,
871		unsigned int MaxNumSwathC,
872		int swath_width_luma_ub,
873		int swath_width_chroma_ub,
874		unsigned int SwathHeightY,
875		unsigned int SwathHeightC,
876		double TWait,
877		double *DSTXAfterScaler,
878		double *DSTYAfterScaler,
879		double *DestinationLinesForPrefetch,
880		double *PrefetchBandwidth,
881		double *DestinationLinesToRequestVMInVBlank,
882		double *DestinationLinesToRequestRowInVBlank,
883		double *VRatioPrefetchY,
884		double *VRatioPrefetchC,
885		double *RequiredPrefetchPixDataBWLuma,
886		double *RequiredPrefetchPixDataBWChroma,
887		bool *NotEnoughTimeForDynamicMetadata,
888		double *Tno_bw,
889		double *prefetch_vmrow_bw,
890		double *Tdmdl_vm,
891		double *Tdmdl,
892		double *TSetup,
893		int *VUpdateOffsetPix,
894		double *VUpdateWidthPix,
895		double *VReadyOffsetPix)
896{
897	bool MyError = false;
898	unsigned int DPPCycles, DISPCLKCycles;
899	double DSTTotalPixelsAfterScaler;
900	double LineTime;
901	double dst_y_prefetch_equ;
902#ifdef __DML_VBA_DEBUG__
903	double Tsw_oto;
904#endif
905	double prefetch_bw_oto;
906	double prefetch_bw_pr;
907	double Tvm_oto;
908	double Tr0_oto;
909	double Tvm_oto_lines;
910	double Tr0_oto_lines;
911	double dst_y_prefetch_oto;
912	double TimeForFetchingMetaPTE = 0;
913	double TimeForFetchingRowInVBlank = 0;
914	double LinesToRequestPrefetchPixelData = 0;
915	unsigned int HostVMDynamicLevelsTrips;
916	double trip_to_mem;
917	double Tvm_trips;
918	double Tr0_trips;
919	double Tvm_trips_rounded;
920	double Tr0_trips_rounded;
921	double Lsw_oto;
922	double Tpre_rounded;
923	double prefetch_bw_equ;
924	double Tvm_equ;
925	double Tr0_equ;
926	double Tdmbf;
927	double Tdmec;
928	double Tdmsks;
929	double prefetch_sw_bytes;
930	double bytes_pp;
931	double dep_bytes;
932	int max_vratio_pre = 4;
933	double min_Lsw;
934	double Tsw_est1 = 0;
935	double Tsw_est3 = 0;
936	double  max_Tsw = 0;
937
938	if (GPUVMEnable == true && HostVMEnable == true) {
939		HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
940	} else {
941		HostVMDynamicLevelsTrips = 0;
942	}
943#ifdef __DML_VBA_DEBUG__
944	dml_print("DML::%s: GPUVMEnable=%d HostVMEnable=%d HostVMInefficiencyFactor=%f\n", __func__, GPUVMEnable, HostVMEnable, HostVMInefficiencyFactor);
945#endif
946	CalculateVupdateAndDynamicMetadataParameters(
947			MaxInterDCNTileRepeaters,
948			myPipe->DPPCLK,
949			myPipe->DISPCLK,
950			myPipe->DCFCLKDeepSleep,
951			myPipe->PixelClock,
952			myPipe->HTotal,
953			myPipe->VBlank,
954			DynamicMetadataTransmittedBytes,
955			DynamicMetadataLinesBeforeActiveRequired,
956			myPipe->InterlaceEnable,
957			myPipe->ProgressiveToInterlaceUnitInOPP,
958			TSetup,
959			&Tdmbf,
960			&Tdmec,
961			&Tdmsks,
962			VUpdateOffsetPix,
963			VUpdateWidthPix,
964			VReadyOffsetPix);
965
966	LineTime = myPipe->HTotal / myPipe->PixelClock;
967	trip_to_mem = UrgentLatency;
968	Tvm_trips = UrgentExtraLatency + trip_to_mem * (GPUVMPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1);
969
970#ifdef __DML_VBA_ALLOW_DELTA__
971	if (DynamicMetadataVMEnabled == true && GPUVMEnable == true) {
972#else
973	if (DynamicMetadataVMEnabled == true) {
974#endif
975		*Tdmdl = TWait + Tvm_trips + trip_to_mem;
976	} else {
977		*Tdmdl = TWait + UrgentExtraLatency;
978	}
979
980#ifdef __DML_VBA_ALLOW_DELTA__
981	if (DynamicMetadataEnable == false) {
982		*Tdmdl = 0.0;
983	}
984#endif
985
986	if (DynamicMetadataEnable == true) {
987		if (VStartup * LineTime < *TSetup + *Tdmdl + Tdmbf + Tdmec + Tdmsks) {
988			*NotEnoughTimeForDynamicMetadata = true;
989			dml_print("DML::%s: Not Enough Time for Dynamic Meta!\n", __func__);
990			dml_print("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, Tdmbf);
991			dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, Tdmec);
992			dml_print("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, Tdmsks);
993			dml_print("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd\n", __func__, *Tdmdl);
994		} else {
995			*NotEnoughTimeForDynamicMetadata = false;
996		}
997	} else {
998		*NotEnoughTimeForDynamicMetadata = false;
999	}
1000
1001	*Tdmdl_vm = (DynamicMetadataEnable == true && DynamicMetadataVMEnabled == true && GPUVMEnable == true ? TWait + Tvm_trips : 0);
1002
1003	if (myPipe->ScalerEnabled)
1004		DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCL;
1005	else
1006		DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCLLBOnly;
1007
1008	DPPCycles = DPPCycles + myPipe->NumberOfCursors * DPPCLKDelayCNVCCursor;
1009
1010	DISPCLKCycles = DISPCLKDelaySubtotal;
1011
1012	if (myPipe->DPPCLK == 0.0 || myPipe->DISPCLK == 0.0)
1013		return true;
1014
1015	*DSTXAfterScaler = DPPCycles * myPipe->PixelClock / myPipe->DPPCLK + DISPCLKCycles * myPipe->PixelClock / myPipe->DISPCLK + DSCDelay;
1016
1017#ifdef __DML_VBA_DEBUG__
1018	dml_print("DML::%s: DPPCycles: %d\n", __func__, DPPCycles);
1019	dml_print("DML::%s: PixelClock: %f\n", __func__, myPipe->PixelClock);
1020	dml_print("DML::%s: DPPCLK: %f\n", __func__, myPipe->DPPCLK);
1021	dml_print("DML::%s: DISPCLKCycles: %d\n", __func__, DISPCLKCycles);
1022	dml_print("DML::%s: DISPCLK: %f\n", __func__, myPipe->DISPCLK);
1023	dml_print("DML::%s: DSCDelay: %d\n", __func__, DSCDelay);
1024	dml_print("DML::%s: DSTXAfterScaler: %d\n", __func__, *DSTXAfterScaler);
1025	dml_print("DML::%s: ODMCombineIsEnabled: %d\n", __func__, myPipe->ODMCombineIsEnabled);
1026#endif
1027
1028	*DSTXAfterScaler = *DSTXAfterScaler + ((myPipe->ODMCombineIsEnabled) ? 18 : 0) + (myPipe->DPPPerPlane - 1) * DPP_RECOUT_WIDTH;
1029
1030	if (OutputFormat == dm_420 || (myPipe->InterlaceEnable && myPipe->ProgressiveToInterlaceUnitInOPP))
1031		*DSTYAfterScaler = 1;
1032	else
1033		*DSTYAfterScaler = 0;
1034
1035	DSTTotalPixelsAfterScaler = *DSTYAfterScaler * myPipe->HTotal + *DSTXAfterScaler;
1036	*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / myPipe->HTotal, 1);
1037	*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * myPipe->HTotal));
1038
1039#ifdef __DML_VBA_DEBUG__
1040	dml_print("DML::%s: DSTXAfterScaler: %d (final)\n", __func__, *DSTXAfterScaler);
1041#endif
1042
1043	MyError = false;
1044
1045	Tr0_trips = trip_to_mem * (HostVMDynamicLevelsTrips + 1);
1046	Tvm_trips_rounded = dml_ceil(4.0 * Tvm_trips / LineTime, 1) / 4 * LineTime;
1047	Tr0_trips_rounded = dml_ceil(4.0 * Tr0_trips / LineTime, 1) / 4 * LineTime;
1048
1049#ifdef __DML_VBA_ALLOW_DELTA__
1050	if (!myPipe->DCCEnable) {
1051		Tr0_trips = 0.0;
1052		Tr0_trips_rounded = 0.0;
1053	}
1054#endif
1055
1056	if (!GPUVMEnable) {
1057		Tvm_trips = 0.0;
1058		Tvm_trips_rounded = 0.0;
1059	}
1060
1061	if (GPUVMEnable) {
1062		if (GPUVMPageTableLevels >= 3) {
1063			*Tno_bw = UrgentExtraLatency + trip_to_mem * ((GPUVMPageTableLevels - 2) - 1);
1064		} else {
1065			*Tno_bw = 0;
1066		}
1067	} else if (!myPipe->DCCEnable) {
1068		*Tno_bw = LineTime;
1069	} else {
1070		*Tno_bw = LineTime / 4;
1071	}
1072
1073	if (myPipe->SourcePixelFormat == dm_420_8 || myPipe->SourcePixelFormat == dm_420_10 || myPipe->SourcePixelFormat == dm_420_12)
1074		bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC / 4;
1075	else
1076		bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC;
1077	/*rev 99*/
1078	prefetch_bw_pr = bytes_pp * myPipe->PixelClock / (double) myPipe->DPPPerPlane;
1079	prefetch_bw_pr = dml_min(1, myPipe->VRatio) * prefetch_bw_pr;
1080	max_Tsw = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
1081	prefetch_sw_bytes = PrefetchSourceLinesY * swath_width_luma_ub * myPipe->BytePerPixelY + PrefetchSourceLinesC * swath_width_chroma_ub * myPipe->BytePerPixelC;
1082	prefetch_bw_oto = dml_max(prefetch_bw_pr, prefetch_sw_bytes / max_Tsw);
1083
1084	min_Lsw = dml_max(1, dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / max_vratio_pre);
1085	Lsw_oto = dml_ceil(4 * dml_max(prefetch_sw_bytes / prefetch_bw_oto / LineTime, min_Lsw), 1) / 4;
1086#ifdef __DML_VBA_DEBUG__
1087	Tsw_oto = Lsw_oto * LineTime;
1088#endif
1089
1090
1091#ifdef __DML_VBA_DEBUG__
1092	dml_print("DML: HTotal: %d\n", myPipe->HTotal);
1093	dml_print("DML: prefetch_bw_oto: %f\n", prefetch_bw_oto);
1094	dml_print("DML: PrefetchSourceLinesY: %f\n", PrefetchSourceLinesY);
1095	dml_print("DML: swath_width_luma_ub: %d\n", swath_width_luma_ub);
1096	dml_print("DML: BytePerPixelY: %d\n", myPipe->BytePerPixelY);
1097	dml_print("DML: Tsw_oto: %f\n", Tsw_oto);
1098#endif
1099
1100	if (GPUVMEnable == true)
1101		Tvm_oto = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_oto, Tvm_trips, LineTime / 4.0);
1102	else
1103		Tvm_oto = LineTime / 4.0;
1104
1105	if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
1106		Tr0_oto = dml_max4((MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_oto, Tr0_trips, // PREVIOUS_ERROR (missing this term)
1107				LineTime - Tvm_oto,
1108				LineTime / 4);
1109	} else {
1110		Tr0_oto = (LineTime - Tvm_oto) / 2.0;
1111	}
1112
1113#ifdef __DML_VBA_DEBUG__
1114	dml_print("DML::%s: Tvm_trips = %f\n", __func__, Tvm_trips);
1115	dml_print("DML::%s: Tr0_trips = %f\n", __func__, Tr0_trips);
1116	dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, MetaRowByte);
1117	dml_print("DML::%s: MetaRowByte = %d\n", __func__, MetaRowByte);
1118	dml_print("DML::%s: PixelPTEBytesPerRow = %d\n", __func__, PixelPTEBytesPerRow);
1119	dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
1120	dml_print("DML::%s: prefetch_bw_oto = %f\n", __func__, prefetch_bw_oto);
1121	dml_print("DML::%s: Tr0_oto = %f\n", __func__, Tr0_oto);
1122	dml_print("DML::%s: Tvm_oto = %f\n", __func__, Tvm_oto);
1123#endif
1124
1125	Tvm_oto_lines = dml_ceil(4.0 * Tvm_oto / LineTime, 1) / 4.0;
1126	Tr0_oto_lines = dml_ceil(4.0 * Tr0_oto / LineTime, 1) / 4.0;
1127	dst_y_prefetch_oto = Tvm_oto_lines + 2 * Tr0_oto_lines + Lsw_oto;
1128	dst_y_prefetch_equ =  VStartup - (*TSetup + dml_max(TWait + TCalc, *Tdmdl)) / LineTime - (*DSTYAfterScaler + *DSTXAfterScaler / myPipe->HTotal);
1129	dst_y_prefetch_equ = dml_floor(4.0 * (dst_y_prefetch_equ + 0.125), 1) / 4.0;
1130	Tpre_rounded = dst_y_prefetch_equ * LineTime;
1131
1132	dep_bytes = dml_max(PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor, MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor);
1133
1134	if (prefetch_sw_bytes < dep_bytes)
1135		prefetch_sw_bytes = 2 * dep_bytes;
1136
1137	dml_print("DML: dst_y_prefetch_oto: %f\n", dst_y_prefetch_oto);
1138	dml_print("DML: Tvm_oto_lines: %f\n", Tvm_oto_lines);
1139	dml_print("DML: Tr0_oto_lines: %f\n", Tr0_oto_lines);
1140	dml_print("DML: Lsw_oto: %f\n", Lsw_oto);
1141	dml_print("DML: LineTime: %f\n", LineTime);
1142	dml_print("DML: dst_y_prefetch_equ: %f (after round)\n", dst_y_prefetch_equ);
1143
1144	dml_print("DML: LineTime: %f\n", LineTime);
1145	dml_print("DML: VStartup: %d\n", VStartup);
1146	dml_print("DML: Tvstartup: %fus - time between vstartup and first pixel of active\n", VStartup * LineTime);
1147	dml_print("DML: TSetup: %fus - time from vstartup to vready\n", *TSetup);
1148	dml_print("DML: TCalc: %fus - time for calculations in dchub starting at vready\n", TCalc);
1149	dml_print("DML: TWait: %fus - time for fabric to become ready max(pstate exit,cstate enter/exit, urgent latency) after TCalc\n", TWait);
1150	dml_print("DML: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", Tdmbf);
1151	dml_print("DML: Tdmec: %fus - time dio takes to transfer dmd\n", Tdmec);
1152	dml_print("DML: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", Tdmsks);
1153	dml_print("DML: Tdmdl_vm: %fus - time for vm stages of dmd\n", *Tdmdl_vm);
1154	dml_print("DML: Tdmdl: %fus - time for fabric to become ready and fetch dmd\n", *Tdmdl);
1155	dml_print("DML: DSTXAfterScaler: %f pixels - number of pixel clocks pipeline and buffer delay after scaler\n", *DSTXAfterScaler);
1156	dml_print("DML: DSTYAfterScaler: %f lines - number of lines of pipeline and buffer delay after scaler\n", *DSTYAfterScaler);
1157
1158	*PrefetchBandwidth = 0;
1159	*DestinationLinesToRequestVMInVBlank = 0;
1160	*DestinationLinesToRequestRowInVBlank = 0;
1161	*VRatioPrefetchY = 0;
1162	*VRatioPrefetchC = 0;
1163	*RequiredPrefetchPixDataBWLuma = 0;
1164	if (dst_y_prefetch_equ > 1) {
1165		double PrefetchBandwidth1;
1166		double PrefetchBandwidth2;
1167		double PrefetchBandwidth3;
1168		double PrefetchBandwidth4;
1169
1170		if (Tpre_rounded - *Tno_bw > 0) {
1171			PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
1172					+ prefetch_sw_bytes) / (Tpre_rounded - *Tno_bw);
1173			Tsw_est1 = prefetch_sw_bytes / PrefetchBandwidth1;
1174		} else {
1175			PrefetchBandwidth1 = 0;
1176		}
1177
1178		if (VStartup == MaxVStartup && Tsw_est1 / LineTime < min_Lsw && Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - *Tno_bw > 0) {
1179			PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor)
1180					/ (Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - *Tno_bw);
1181		}
1182
1183		if (Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded > 0)
1184			PrefetchBandwidth2 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + prefetch_sw_bytes) / (Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded);
1185		else
1186			PrefetchBandwidth2 = 0;
1187
1188		if (Tpre_rounded - Tvm_trips_rounded > 0) {
1189			PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
1190					+ prefetch_sw_bytes) / (Tpre_rounded - Tvm_trips_rounded);
1191			Tsw_est3 = prefetch_sw_bytes / PrefetchBandwidth3;
1192		} else {
1193			PrefetchBandwidth3 = 0;
1194		}
1195
1196#ifdef __DML_VBA_DEBUG__
1197		dml_print("DML::%s: Tpre_rounded: %f\n", __func__, Tpre_rounded);
1198		dml_print("DML::%s: Tvm_trips_rounded: %f\n", __func__, Tvm_trips_rounded);
1199		dml_print("DML::%s: PrefetchBandwidth3: %f\n", __func__, PrefetchBandwidth3);
1200#endif
1201		if (VStartup == MaxVStartup && Tsw_est3 / LineTime < min_Lsw && Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - Tvm_trips_rounded > 0) {
1202			PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor)
1203					/ (Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - Tvm_trips_rounded);
1204		}
1205
1206		if (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded > 0)
1207			PrefetchBandwidth4 = prefetch_sw_bytes / (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded);
1208		else
1209			PrefetchBandwidth4 = 0;
1210
1211		{
1212			bool Case1OK;
1213			bool Case2OK;
1214			bool Case3OK;
1215
1216			if (PrefetchBandwidth1 > 0) {
1217				if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth1 >= Tvm_trips_rounded
1218						&& (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth1 >= Tr0_trips_rounded) {
1219					Case1OK = true;
1220				} else {
1221					Case1OK = false;
1222				}
1223			} else {
1224				Case1OK = false;
1225			}
1226
1227			if (PrefetchBandwidth2 > 0) {
1228				if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth2 >= Tvm_trips_rounded
1229						&& (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth2 < Tr0_trips_rounded) {
1230					Case2OK = true;
1231				} else {
1232					Case2OK = false;
1233				}
1234			} else {
1235				Case2OK = false;
1236			}
1237
1238			if (PrefetchBandwidth3 > 0) {
1239				if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth3 < Tvm_trips_rounded
1240						&& (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth3 >= Tr0_trips_rounded) {
1241					Case3OK = true;
1242				} else {
1243					Case3OK = false;
1244				}
1245			} else {
1246				Case3OK = false;
1247			}
1248
1249			if (Case1OK) {
1250				prefetch_bw_equ = PrefetchBandwidth1;
1251			} else if (Case2OK) {
1252				prefetch_bw_equ = PrefetchBandwidth2;
1253			} else if (Case3OK) {
1254				prefetch_bw_equ = PrefetchBandwidth3;
1255			} else {
1256				prefetch_bw_equ = PrefetchBandwidth4;
1257			}
1258
1259#ifdef __DML_VBA_DEBUG__
1260			dml_print("DML::%s: Case1OK: %d\n", __func__, Case1OK);
1261			dml_print("DML::%s: Case2OK: %d\n", __func__, Case2OK);
1262			dml_print("DML::%s: Case3OK: %d\n", __func__, Case3OK);
1263			dml_print("DML::%s: prefetch_bw_equ: %f\n", __func__, prefetch_bw_equ);
1264#endif
1265
1266			if (prefetch_bw_equ > 0) {
1267				if (GPUVMEnable == true) {
1268					Tvm_equ = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_equ, Tvm_trips, LineTime / 4);
1269				} else {
1270					Tvm_equ = LineTime / 4;
1271				}
1272
1273				if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
1274					Tr0_equ = dml_max4(
1275							(MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_equ,
1276							Tr0_trips,
1277							(LineTime - Tvm_equ) / 2,
1278							LineTime / 4);
1279				} else {
1280					Tr0_equ = (LineTime - Tvm_equ) / 2;
1281				}
1282			} else {
1283				Tvm_equ = 0;
1284				Tr0_equ = 0;
1285				dml_print("DML: prefetch_bw_equ equals 0! %s:%d\n", __FILE__, __LINE__);
1286			}
1287		}
1288
1289		if (dst_y_prefetch_oto < dst_y_prefetch_equ) {
1290			*DestinationLinesForPrefetch = dst_y_prefetch_oto;
1291			TimeForFetchingMetaPTE = Tvm_oto;
1292			TimeForFetchingRowInVBlank = Tr0_oto;
1293			*PrefetchBandwidth = prefetch_bw_oto;
1294		} else {
1295			*DestinationLinesForPrefetch = dst_y_prefetch_equ;
1296			TimeForFetchingMetaPTE = Tvm_equ;
1297			TimeForFetchingRowInVBlank = Tr0_equ;
1298			*PrefetchBandwidth = prefetch_bw_equ;
1299		}
1300
1301		*DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0;
1302
1303		*DestinationLinesToRequestRowInVBlank = dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0;
1304
1305#ifdef __DML_VBA_ALLOW_DELTA__
1306		LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch
1307		// See note above dated 5/30/2018
1308		//                      - ((NumberOfCursors > 0 || GPUVMEnable || DCCEnable) ?
1309				- ((GPUVMEnable || myPipe->DCCEnable) ? (*DestinationLinesToRequestVMInVBlank + 2 * *DestinationLinesToRequestRowInVBlank) : 0.0); // TODO: Did someone else add this??
1310#else
1311		LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch - *DestinationLinesToRequestVMInVBlank - 2 * *DestinationLinesToRequestRowInVBlank;
1312#endif
1313
1314#ifdef __DML_VBA_DEBUG__
1315		dml_print("DML::%s: DestinationLinesForPrefetch = %f\n", __func__, *DestinationLinesForPrefetch);
1316		dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n", __func__, *DestinationLinesToRequestVMInVBlank);
1317		dml_print("DML::%s: TimeForFetchingRowInVBlank = %f\n", __func__, TimeForFetchingRowInVBlank);
1318		dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
1319		dml_print("DML::%s: DestinationLinesToRequestRowInVBlank = %f\n", __func__, *DestinationLinesToRequestRowInVBlank);
1320		dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, PrefetchSourceLinesY);
1321		dml_print("DML::%s: LinesToRequestPrefetchPixelData = %f\n", __func__, LinesToRequestPrefetchPixelData);
1322#endif
1323
1324		if (LinesToRequestPrefetchPixelData > 0 && prefetch_bw_equ > 0) {
1325
1326			*VRatioPrefetchY = (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData;
1327			*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1328#ifdef __DML_VBA_DEBUG__
1329			dml_print("DML::%s: VRatioPrefetchY = %f\n", __func__, *VRatioPrefetchY);
1330			dml_print("DML::%s: SwathHeightY = %d\n", __func__, SwathHeightY);
1331			dml_print("DML::%s: VInitPreFillY = %f\n", __func__, VInitPreFillY);
1332#endif
1333			if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
1334				if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
1335					*VRatioPrefetchY = dml_max(
1336							(double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData,
1337							(double) MaxNumSwathY * SwathHeightY / (LinesToRequestPrefetchPixelData - (VInitPreFillY - 3.0) / 2.0));
1338					*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1339				} else {
1340					MyError = true;
1341					dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1342					*VRatioPrefetchY = 0;
1343				}
1344#ifdef __DML_VBA_DEBUG__
1345				dml_print("DML::%s: VRatioPrefetchY = %f\n", __func__, *VRatioPrefetchY);
1346				dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, PrefetchSourceLinesY);
1347				dml_print("DML::%s: MaxNumSwathY = %d\n", __func__, MaxNumSwathY);
1348#endif
1349			}
1350
1351			*VRatioPrefetchC = (double) PrefetchSourceLinesC / LinesToRequestPrefetchPixelData;
1352			*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1353
1354#ifdef __DML_VBA_DEBUG__
1355			dml_print("DML::%s: VRatioPrefetchC = %f\n", __func__, *VRatioPrefetchC);
1356			dml_print("DML::%s: SwathHeightC = %d\n", __func__, SwathHeightC);
1357			dml_print("DML::%s: VInitPreFillC = %f\n", __func__, VInitPreFillC);
1358#endif
1359			if ((SwathHeightC > 4) || VInitPreFillC > 3) {
1360				if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
1361					*VRatioPrefetchC = dml_max(
1362							*VRatioPrefetchC,
1363							(double) MaxNumSwathC * SwathHeightC / (LinesToRequestPrefetchPixelData - (VInitPreFillC - 3.0) / 2.0));
1364					*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1365				} else {
1366					MyError = true;
1367					dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1368					*VRatioPrefetchC = 0;
1369				}
1370#ifdef __DML_VBA_DEBUG__
1371				dml_print("DML::%s: VRatioPrefetchC = %f\n", __func__, *VRatioPrefetchC);
1372				dml_print("DML::%s: PrefetchSourceLinesC = %f\n", __func__, PrefetchSourceLinesC);
1373				dml_print("DML::%s: MaxNumSwathC = %d\n", __func__, MaxNumSwathC);
1374#endif
1375			}
1376
1377#ifdef __DML_VBA_DEBUG__
1378			dml_print("DML::%s: BytePerPixelY = %d\n", __func__, myPipe->BytePerPixelY);
1379			dml_print("DML::%s: swath_width_luma_ub = %d\n", __func__, swath_width_luma_ub);
1380			dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
1381#endif
1382
1383			*RequiredPrefetchPixDataBWLuma = (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData * myPipe->BytePerPixelY * swath_width_luma_ub / LineTime;
1384
1385#ifdef __DML_VBA_DEBUG__
1386			dml_print("DML::%s: RequiredPrefetchPixDataBWLuma = %f\n", __func__, *RequiredPrefetchPixDataBWLuma);
1387#endif
1388
1389			*RequiredPrefetchPixDataBWChroma = (double) PrefetchSourceLinesC / LinesToRequestPrefetchPixelData * myPipe->BytePerPixelC * swath_width_chroma_ub
1390					/ LineTime;
1391		} else {
1392			MyError = true;
1393			dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1394			dml_print("DML: LinesToRequestPrefetchPixelData: %f, should be > 0\n", LinesToRequestPrefetchPixelData);
1395			*VRatioPrefetchY = 0;
1396			*VRatioPrefetchC = 0;
1397			*RequiredPrefetchPixDataBWLuma = 0;
1398			*RequiredPrefetchPixDataBWChroma = 0;
1399		}
1400
1401		dml_print(
1402				"DML: Tpre: %fus - sum of time to request meta pte, 2 x data pte + meta data, swaths\n",
1403				(double) LinesToRequestPrefetchPixelData * LineTime + 2.0 * TimeForFetchingRowInVBlank + TimeForFetchingMetaPTE);
1404		dml_print("DML:  Tvm: %fus - time to fetch page tables for meta surface\n", TimeForFetchingMetaPTE);
1405		dml_print("DML:  Tr0: %fus - time to fetch first row of data pagetables and first row of meta data (done in parallel)\n", TimeForFetchingRowInVBlank);
1406		dml_print(
1407				"DML:  Tsw: %fus = time to fetch enough pixel data and cursor data to feed the scalers init position and detile\n",
1408				(double) LinesToRequestPrefetchPixelData * LineTime);
1409		dml_print("DML: To: %fus - time for propagation from scaler to optc\n", (*DSTYAfterScaler + ((double) (*DSTXAfterScaler) / (double) myPipe->HTotal)) * LineTime);
1410		dml_print("DML: Tvstartup - TSetup - Tcalc - Twait - Tpre - To > 0\n");
1411		dml_print(
1412				"DML: Tslack(pre): %fus - time left over in schedule\n",
1413				VStartup * LineTime - TimeForFetchingMetaPTE - 2 * TimeForFetchingRowInVBlank
1414						- (*DSTYAfterScaler + ((double) (*DSTXAfterScaler) / (double) myPipe->HTotal)) * LineTime - TWait - TCalc - *TSetup);
1415		dml_print("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %d\n", PixelPTEBytesPerRow);
1416
1417	} else {
1418		MyError = true;
1419		dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1420	}
1421
1422	{
1423		double prefetch_vm_bw;
1424		double prefetch_row_bw;
1425
1426		if (PDEAndMetaPTEBytesFrame == 0) {
1427			prefetch_vm_bw = 0;
1428		} else if (*DestinationLinesToRequestVMInVBlank > 0) {
1429#ifdef __DML_VBA_DEBUG__
1430			dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, PDEAndMetaPTEBytesFrame);
1431			dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
1432			dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n", __func__, *DestinationLinesToRequestVMInVBlank);
1433			dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
1434#endif
1435			prefetch_vm_bw = PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInVBlank * LineTime);
1436#ifdef __DML_VBA_DEBUG__
1437			dml_print("DML::%s: prefetch_vm_bw = %f\n", __func__, prefetch_vm_bw);
1438#endif
1439		} else {
1440			prefetch_vm_bw = 0;
1441			MyError = true;
1442			dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1443		}
1444
1445		if (MetaRowByte + PixelPTEBytesPerRow == 0) {
1446			prefetch_row_bw = 0;
1447		} else if (*DestinationLinesToRequestRowInVBlank > 0) {
1448			prefetch_row_bw = (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInVBlank * LineTime);
1449
1450#ifdef __DML_VBA_DEBUG__
1451			dml_print("DML::%s: MetaRowByte = %d\n", __func__, MetaRowByte);
1452			dml_print("DML::%s: PixelPTEBytesPerRow = %d\n", __func__, PixelPTEBytesPerRow);
1453			dml_print("DML::%s: DestinationLinesToRequestRowInVBlank = %f\n", __func__, *DestinationLinesToRequestRowInVBlank);
1454			dml_print("DML::%s: prefetch_row_bw = %f\n", __func__, prefetch_row_bw);
1455#endif
1456		} else {
1457			prefetch_row_bw = 0;
1458			MyError = true;
1459			dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1460		}
1461
1462		*prefetch_vmrow_bw = dml_max(prefetch_vm_bw, prefetch_row_bw);
1463	}
1464
1465	if (MyError) {
1466		*PrefetchBandwidth = 0;
1467		TimeForFetchingMetaPTE = 0;
1468		TimeForFetchingRowInVBlank = 0;
1469		*DestinationLinesToRequestVMInVBlank = 0;
1470		*DestinationLinesToRequestRowInVBlank = 0;
1471		*DestinationLinesForPrefetch = 0;
1472		LinesToRequestPrefetchPixelData = 0;
1473		*VRatioPrefetchY = 0;
1474		*VRatioPrefetchC = 0;
1475		*RequiredPrefetchPixDataBWLuma = 0;
1476		*RequiredPrefetchPixDataBWChroma = 0;
1477	}
1478
1479	return MyError;
1480}
1481
1482static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
1483{
1484	return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
1485}
1486
1487static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
1488{
1489	return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4.0 / Clock, 1);
1490}
1491
1492static void CalculateDCCConfiguration(
1493		bool DCCEnabled,
1494		bool DCCProgrammingAssumesScanDirectionUnknown,
1495		enum source_format_class SourcePixelFormat,
1496		unsigned int SurfaceWidthLuma,
1497		unsigned int SurfaceWidthChroma,
1498		unsigned int SurfaceHeightLuma,
1499		unsigned int SurfaceHeightChroma,
1500		double DETBufferSize,
1501		unsigned int RequestHeight256ByteLuma,
1502		unsigned int RequestHeight256ByteChroma,
1503		enum dm_swizzle_mode TilingFormat,
1504		unsigned int BytePerPixelY,
1505		unsigned int BytePerPixelC,
1506		double BytePerPixelDETY,
1507		double BytePerPixelDETC,
1508		enum scan_direction_class ScanOrientation,
1509		unsigned int *MaxUncompressedBlockLuma,
1510		unsigned int *MaxUncompressedBlockChroma,
1511		unsigned int *MaxCompressedBlockLuma,
1512		unsigned int *MaxCompressedBlockChroma,
1513		unsigned int *IndependentBlockLuma,
1514		unsigned int *IndependentBlockChroma)
1515{
1516	int yuv420;
1517	int horz_div_l;
1518	int horz_div_c;
1519	int vert_div_l;
1520	int vert_div_c;
1521
1522	int swath_buf_size;
1523	double detile_buf_vp_horz_limit;
1524	double detile_buf_vp_vert_limit;
1525
1526	int MAS_vp_horz_limit;
1527	int MAS_vp_vert_limit;
1528	int max_vp_horz_width;
1529	int max_vp_vert_height;
1530	int eff_surf_width_l;
1531	int eff_surf_width_c;
1532	int eff_surf_height_l;
1533	int eff_surf_height_c;
1534
1535	int full_swath_bytes_horz_wc_l;
1536	int full_swath_bytes_horz_wc_c;
1537	int full_swath_bytes_vert_wc_l;
1538	int full_swath_bytes_vert_wc_c;
1539	int req128_horz_wc_l;
1540	int req128_horz_wc_c;
1541	int req128_vert_wc_l;
1542	int req128_vert_wc_c;
1543	int segment_order_horz_contiguous_luma;
1544	int segment_order_horz_contiguous_chroma;
1545	int segment_order_vert_contiguous_luma;
1546	int segment_order_vert_contiguous_chroma;
1547
1548	typedef enum {
1549		REQ_256Bytes, REQ_128BytesNonContiguous, REQ_128BytesContiguous, REQ_NA
1550	} RequestType;
1551	RequestType RequestLuma;
1552	RequestType RequestChroma;
1553
1554	yuv420 = ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12) ? 1 : 0);
1555	horz_div_l = 1;
1556	horz_div_c = 1;
1557	vert_div_l = 1;
1558	vert_div_c = 1;
1559
1560	if (BytePerPixelY == 1)
1561		vert_div_l = 0;
1562	if (BytePerPixelC == 1)
1563		vert_div_c = 0;
1564	if (BytePerPixelY == 8 && (TilingFormat == dm_sw_64kb_s || TilingFormat == dm_sw_64kb_s_t || TilingFormat == dm_sw_64kb_s_x))
1565		horz_div_l = 0;
1566	if (BytePerPixelC == 8 && (TilingFormat == dm_sw_64kb_s || TilingFormat == dm_sw_64kb_s_t || TilingFormat == dm_sw_64kb_s_x))
1567		horz_div_c = 0;
1568
1569	if (BytePerPixelC == 0) {
1570		swath_buf_size = DETBufferSize / 2 - 2 * 256;
1571		detile_buf_vp_horz_limit = (double) swath_buf_size / ((double) RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l));
1572		detile_buf_vp_vert_limit = (double) swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l));
1573	} else {
1574		swath_buf_size = DETBufferSize / 2 - 2 * 2 * 256;
1575		detile_buf_vp_horz_limit = (double) swath_buf_size
1576				/ ((double) RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l)
1577						+ (double) RequestHeight256ByteChroma * BytePerPixelC / (1 + horz_div_c) / (1 + yuv420));
1578		detile_buf_vp_vert_limit = (double) swath_buf_size
1579				/ (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l) + 256.0 / RequestHeight256ByteChroma / (1 + vert_div_c) / (1 + yuv420));
1580	}
1581
1582	if (SourcePixelFormat == dm_420_10) {
1583		detile_buf_vp_horz_limit = 1.5 * detile_buf_vp_horz_limit;
1584		detile_buf_vp_vert_limit = 1.5 * detile_buf_vp_vert_limit;
1585	}
1586
1587	detile_buf_vp_horz_limit = dml_floor(detile_buf_vp_horz_limit - 1, 16);
1588	detile_buf_vp_vert_limit = dml_floor(detile_buf_vp_vert_limit - 1, 16);
1589
1590	MAS_vp_horz_limit = SourcePixelFormat == dm_rgbe_alpha ? 3840 : 5760;
1591	MAS_vp_vert_limit = (BytePerPixelC > 0 ? 2880 : 5760);
1592	max_vp_horz_width = dml_min((double) MAS_vp_horz_limit, detile_buf_vp_horz_limit);
1593	max_vp_vert_height = dml_min((double) MAS_vp_vert_limit, detile_buf_vp_vert_limit);
1594	eff_surf_width_l = (SurfaceWidthLuma > max_vp_horz_width ? max_vp_horz_width : SurfaceWidthLuma);
1595	eff_surf_width_c = eff_surf_width_l / (1 + yuv420);
1596	eff_surf_height_l = (SurfaceHeightLuma > max_vp_vert_height ? max_vp_vert_height : SurfaceHeightLuma);
1597	eff_surf_height_c = eff_surf_height_l / (1 + yuv420);
1598
1599	full_swath_bytes_horz_wc_l = eff_surf_width_l * RequestHeight256ByteLuma * BytePerPixelY;
1600	full_swath_bytes_vert_wc_l = eff_surf_height_l * 256 / RequestHeight256ByteLuma;
1601	if (BytePerPixelC > 0) {
1602		full_swath_bytes_horz_wc_c = eff_surf_width_c * RequestHeight256ByteChroma * BytePerPixelC;
1603		full_swath_bytes_vert_wc_c = eff_surf_height_c * 256 / RequestHeight256ByteChroma;
1604	} else {
1605		full_swath_bytes_horz_wc_c = 0;
1606		full_swath_bytes_vert_wc_c = 0;
1607	}
1608
1609	if (SourcePixelFormat == dm_420_10) {
1610		full_swath_bytes_horz_wc_l = dml_ceil(full_swath_bytes_horz_wc_l * 2 / 3, 256);
1611		full_swath_bytes_horz_wc_c = dml_ceil(full_swath_bytes_horz_wc_c * 2 / 3, 256);
1612		full_swath_bytes_vert_wc_l = dml_ceil(full_swath_bytes_vert_wc_l * 2 / 3, 256);
1613		full_swath_bytes_vert_wc_c = dml_ceil(full_swath_bytes_vert_wc_c * 2 / 3, 256);
1614	}
1615
1616	if (2 * full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSize) {
1617		req128_horz_wc_l = 0;
1618		req128_horz_wc_c = 0;
1619	} else if (full_swath_bytes_horz_wc_l < 1.5 * full_swath_bytes_horz_wc_c && 2 * full_swath_bytes_horz_wc_l + full_swath_bytes_horz_wc_c <= DETBufferSize) {
1620		req128_horz_wc_l = 0;
1621		req128_horz_wc_c = 1;
1622	} else if (full_swath_bytes_horz_wc_l >= 1.5 * full_swath_bytes_horz_wc_c && full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSize) {
1623		req128_horz_wc_l = 1;
1624		req128_horz_wc_c = 0;
1625	} else {
1626		req128_horz_wc_l = 1;
1627		req128_horz_wc_c = 1;
1628	}
1629
1630	if (2 * full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSize) {
1631		req128_vert_wc_l = 0;
1632		req128_vert_wc_c = 0;
1633	} else if (full_swath_bytes_vert_wc_l < 1.5 * full_swath_bytes_vert_wc_c && 2 * full_swath_bytes_vert_wc_l + full_swath_bytes_vert_wc_c <= DETBufferSize) {
1634		req128_vert_wc_l = 0;
1635		req128_vert_wc_c = 1;
1636	} else if (full_swath_bytes_vert_wc_l >= 1.5 * full_swath_bytes_vert_wc_c && full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSize) {
1637		req128_vert_wc_l = 1;
1638		req128_vert_wc_c = 0;
1639	} else {
1640		req128_vert_wc_l = 1;
1641		req128_vert_wc_c = 1;
1642	}
1643
1644	if (BytePerPixelY == 2 || (BytePerPixelY == 4 && TilingFormat != dm_sw_64kb_r_x)) {
1645		segment_order_horz_contiguous_luma = 0;
1646	} else {
1647		segment_order_horz_contiguous_luma = 1;
1648	}
1649	if ((BytePerPixelY == 8 && (TilingFormat == dm_sw_64kb_d || TilingFormat == dm_sw_64kb_d_x || TilingFormat == dm_sw_64kb_d_t || TilingFormat == dm_sw_64kb_r_x))
1650			|| (BytePerPixelY == 4 && TilingFormat == dm_sw_64kb_r_x)) {
1651		segment_order_vert_contiguous_luma = 0;
1652	} else {
1653		segment_order_vert_contiguous_luma = 1;
1654	}
1655	if (BytePerPixelC == 2 || (BytePerPixelC == 4 && TilingFormat != dm_sw_64kb_r_x)) {
1656		segment_order_horz_contiguous_chroma = 0;
1657	} else {
1658		segment_order_horz_contiguous_chroma = 1;
1659	}
1660	if ((BytePerPixelC == 8 && (TilingFormat == dm_sw_64kb_d || TilingFormat == dm_sw_64kb_d_x || TilingFormat == dm_sw_64kb_d_t || TilingFormat == dm_sw_64kb_r_x))
1661			|| (BytePerPixelC == 4 && TilingFormat == dm_sw_64kb_r_x)) {
1662		segment_order_vert_contiguous_chroma = 0;
1663	} else {
1664		segment_order_vert_contiguous_chroma = 1;
1665	}
1666
1667	if (DCCProgrammingAssumesScanDirectionUnknown == true) {
1668		if (req128_horz_wc_l == 0 && req128_vert_wc_l == 0) {
1669			RequestLuma = REQ_256Bytes;
1670		} else if ((req128_horz_wc_l == 1 && segment_order_horz_contiguous_luma == 0) || (req128_vert_wc_l == 1 && segment_order_vert_contiguous_luma == 0)) {
1671			RequestLuma = REQ_128BytesNonContiguous;
1672		} else {
1673			RequestLuma = REQ_128BytesContiguous;
1674		}
1675		if (req128_horz_wc_c == 0 && req128_vert_wc_c == 0) {
1676			RequestChroma = REQ_256Bytes;
1677		} else if ((req128_horz_wc_c == 1 && segment_order_horz_contiguous_chroma == 0) || (req128_vert_wc_c == 1 && segment_order_vert_contiguous_chroma == 0)) {
1678			RequestChroma = REQ_128BytesNonContiguous;
1679		} else {
1680			RequestChroma = REQ_128BytesContiguous;
1681		}
1682	} else if (ScanOrientation != dm_vert) {
1683		if (req128_horz_wc_l == 0) {
1684			RequestLuma = REQ_256Bytes;
1685		} else if (segment_order_horz_contiguous_luma == 0) {
1686			RequestLuma = REQ_128BytesNonContiguous;
1687		} else {
1688			RequestLuma = REQ_128BytesContiguous;
1689		}
1690		if (req128_horz_wc_c == 0) {
1691			RequestChroma = REQ_256Bytes;
1692		} else if (segment_order_horz_contiguous_chroma == 0) {
1693			RequestChroma = REQ_128BytesNonContiguous;
1694		} else {
1695			RequestChroma = REQ_128BytesContiguous;
1696		}
1697	} else {
1698		if (req128_vert_wc_l == 0) {
1699			RequestLuma = REQ_256Bytes;
1700		} else if (segment_order_vert_contiguous_luma == 0) {
1701			RequestLuma = REQ_128BytesNonContiguous;
1702		} else {
1703			RequestLuma = REQ_128BytesContiguous;
1704		}
1705		if (req128_vert_wc_c == 0) {
1706			RequestChroma = REQ_256Bytes;
1707		} else if (segment_order_vert_contiguous_chroma == 0) {
1708			RequestChroma = REQ_128BytesNonContiguous;
1709		} else {
1710			RequestChroma = REQ_128BytesContiguous;
1711		}
1712	}
1713
1714	if (RequestLuma == REQ_256Bytes) {
1715		*MaxUncompressedBlockLuma = 256;
1716		*MaxCompressedBlockLuma = 256;
1717		*IndependentBlockLuma = 0;
1718	} else if (RequestLuma == REQ_128BytesContiguous) {
1719		*MaxUncompressedBlockLuma = 256;
1720		*MaxCompressedBlockLuma = 128;
1721		*IndependentBlockLuma = 128;
1722	} else {
1723		*MaxUncompressedBlockLuma = 256;
1724		*MaxCompressedBlockLuma = 64;
1725		*IndependentBlockLuma = 64;
1726	}
1727
1728	if (RequestChroma == REQ_256Bytes) {
1729		*MaxUncompressedBlockChroma = 256;
1730		*MaxCompressedBlockChroma = 256;
1731		*IndependentBlockChroma = 0;
1732	} else if (RequestChroma == REQ_128BytesContiguous) {
1733		*MaxUncompressedBlockChroma = 256;
1734		*MaxCompressedBlockChroma = 128;
1735		*IndependentBlockChroma = 128;
1736	} else {
1737		*MaxUncompressedBlockChroma = 256;
1738		*MaxCompressedBlockChroma = 64;
1739		*IndependentBlockChroma = 64;
1740	}
1741
1742	if (DCCEnabled != true || BytePerPixelC == 0) {
1743		*MaxUncompressedBlockChroma = 0;
1744		*MaxCompressedBlockChroma = 0;
1745		*IndependentBlockChroma = 0;
1746	}
1747
1748	if (DCCEnabled != true) {
1749		*MaxUncompressedBlockLuma = 0;
1750		*MaxCompressedBlockLuma = 0;
1751		*IndependentBlockLuma = 0;
1752	}
1753}
1754
1755static double CalculatePrefetchSourceLines(
1756		struct display_mode_lib *mode_lib,
1757		double VRatio,
1758		double vtaps,
1759		bool Interlace,
1760		bool ProgressiveToInterlaceUnitInOPP,
1761		unsigned int SwathHeight,
1762		unsigned int ViewportYStart,
1763		double *VInitPreFill,
1764		unsigned int *MaxNumSwath)
1765{
1766	struct vba_vars_st *v = &mode_lib->vba;
1767	unsigned int MaxPartialSwath;
1768
1769	if (ProgressiveToInterlaceUnitInOPP)
1770		*VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
1771	else
1772		*VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
1773
1774	if (!v->IgnoreViewportPositioning) {
1775
1776		*MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
1777
1778		if (*VInitPreFill > 1.0)
1779			MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
1780		else
1781			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2) % SwathHeight;
1782		MaxPartialSwath = dml_max(1U, MaxPartialSwath);
1783
1784	} else {
1785
1786		if (ViewportYStart != 0)
1787			dml_print("WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
1788
1789		*MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
1790
1791		if (*VInitPreFill > 1.0)
1792			MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
1793		else
1794			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1) % SwathHeight;
1795	}
1796
1797#ifdef __DML_VBA_DEBUG__
1798	dml_print("DML::%s: VRatio = %f\n", __func__, VRatio);
1799	dml_print("DML::%s: vtaps = %f\n", __func__, vtaps);
1800	dml_print("DML::%s: VInitPreFill = %f\n", __func__, *VInitPreFill);
1801	dml_print("DML::%s: ProgressiveToInterlaceUnitInOPP = %d\n", __func__, ProgressiveToInterlaceUnitInOPP);
1802	dml_print("DML::%s: IgnoreViewportPositioning = %d\n", __func__, v->IgnoreViewportPositioning);
1803	dml_print("DML::%s: SwathHeight = %d\n", __func__, SwathHeight);
1804	dml_print("DML::%s: MaxPartialSwath = %d\n", __func__, MaxPartialSwath);
1805	dml_print("DML::%s: MaxNumSwath = %d\n", __func__, *MaxNumSwath);
1806	dml_print("DML::%s: Prefetch source lines = %d\n", __func__, *MaxNumSwath * SwathHeight + MaxPartialSwath);
1807#endif
1808	return *MaxNumSwath * SwathHeight + MaxPartialSwath;
1809}
1810
1811static unsigned int CalculateVMAndRowBytes(
1812		struct display_mode_lib *mode_lib,
1813		bool DCCEnable,
1814		unsigned int BlockHeight256Bytes,
1815		unsigned int BlockWidth256Bytes,
1816		enum source_format_class SourcePixelFormat,
1817		unsigned int SurfaceTiling,
1818		unsigned int BytePerPixel,
1819		enum scan_direction_class ScanDirection,
1820		unsigned int SwathWidth,
1821		unsigned int ViewportHeight,
1822		bool GPUVMEnable,
1823		bool HostVMEnable,
1824		unsigned int HostVMMaxNonCachedPageTableLevels,
1825		unsigned int GPUVMMinPageSize,
1826		unsigned int HostVMMinPageSize,
1827		unsigned int PTEBufferSizeInRequests,
1828		unsigned int Pitch,
1829		unsigned int DCCMetaPitch,
1830		unsigned int *MacroTileWidth,
1831		unsigned int *MetaRowByte,
1832		unsigned int *PixelPTEBytesPerRow,
1833		bool *PTEBufferSizeNotExceeded,
1834		int *dpte_row_width_ub,
1835		unsigned int *dpte_row_height,
1836		unsigned int *MetaRequestWidth,
1837		unsigned int *MetaRequestHeight,
1838		unsigned int *meta_row_width,
1839		unsigned int *meta_row_height,
1840		int *vm_group_bytes,
1841		unsigned int *dpte_group_bytes,
1842		unsigned int *PixelPTEReqWidth,
1843		unsigned int *PixelPTEReqHeight,
1844		unsigned int *PTERequestSize,
1845		int *DPDE0BytesFrame,
1846		int *MetaPTEBytesFrame)
1847{
1848	struct vba_vars_st *v = &mode_lib->vba;
1849	unsigned int MPDEBytesFrame;
1850	unsigned int DCCMetaSurfaceBytes;
1851	unsigned int MacroTileSizeBytes;
1852	unsigned int MacroTileHeight;
1853	unsigned int ExtraDPDEBytesFrame;
1854	unsigned int PDEAndMetaPTEBytesFrame;
1855	unsigned int PixelPTEReqHeightPTEs = 0;
1856	unsigned int HostVMDynamicLevels = 0;
1857	double FractionOfPTEReturnDrop;
1858
1859	if (GPUVMEnable == true && HostVMEnable == true) {
1860		if (HostVMMinPageSize < 2048) {
1861			HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
1862		} else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576) {
1863			HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 1);
1864		} else {
1865			HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 2);
1866		}
1867	}
1868
1869	*MetaRequestHeight = 8 * BlockHeight256Bytes;
1870	*MetaRequestWidth = 8 * BlockWidth256Bytes;
1871	if (ScanDirection != dm_vert) {
1872		*meta_row_height = *MetaRequestHeight;
1873		*meta_row_width = dml_ceil((double) SwathWidth - 1, *MetaRequestWidth) + *MetaRequestWidth;
1874		*MetaRowByte = *meta_row_width * *MetaRequestHeight * BytePerPixel / 256.0;
1875	} else {
1876		*meta_row_height = *MetaRequestWidth;
1877		*meta_row_width = dml_ceil((double) SwathWidth - 1, *MetaRequestHeight) + *MetaRequestHeight;
1878		*MetaRowByte = *meta_row_width * *MetaRequestWidth * BytePerPixel / 256.0;
1879	}
1880	DCCMetaSurfaceBytes = DCCMetaPitch * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes) + 64 * BlockHeight256Bytes) * BytePerPixel / 256;
1881	if (GPUVMEnable == true) {
1882		*MetaPTEBytesFrame = (dml_ceil((double) (DCCMetaSurfaceBytes - 4.0 * 1024.0) / (8 * 4.0 * 1024), 1) + 1) * 64;
1883		MPDEBytesFrame = 128 * (v->GPUVMMaxPageTableLevels - 1);
1884	} else {
1885		*MetaPTEBytesFrame = 0;
1886		MPDEBytesFrame = 0;
1887	}
1888
1889	if (DCCEnable != true) {
1890		*MetaPTEBytesFrame = 0;
1891		MPDEBytesFrame = 0;
1892		*MetaRowByte = 0;
1893	}
1894
1895	if (SurfaceTiling == dm_sw_linear) {
1896		MacroTileSizeBytes = 256;
1897		MacroTileHeight = BlockHeight256Bytes;
1898	} else {
1899		MacroTileSizeBytes = 65536;
1900		MacroTileHeight = 16 * BlockHeight256Bytes;
1901	}
1902	*MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
1903
1904	if (GPUVMEnable == true && v->GPUVMMaxPageTableLevels > 1) {
1905		if (ScanDirection != dm_vert) {
1906			*DPDE0BytesFrame = 64
1907					* (dml_ceil(
1908							((Pitch * (dml_ceil(ViewportHeight - 1, MacroTileHeight) + MacroTileHeight) * BytePerPixel) - MacroTileSizeBytes)
1909									/ (8 * 2097152),
1910							1) + 1);
1911		} else {
1912			*DPDE0BytesFrame = 64
1913					* (dml_ceil(
1914							((Pitch * (dml_ceil((double) SwathWidth - 1, MacroTileHeight) + MacroTileHeight) * BytePerPixel) - MacroTileSizeBytes)
1915									/ (8 * 2097152),
1916							1) + 1);
1917		}
1918		ExtraDPDEBytesFrame = 128 * (v->GPUVMMaxPageTableLevels - 2);
1919	} else {
1920		*DPDE0BytesFrame = 0;
1921		ExtraDPDEBytesFrame = 0;
1922	}
1923
1924	PDEAndMetaPTEBytesFrame = *MetaPTEBytesFrame + MPDEBytesFrame + *DPDE0BytesFrame + ExtraDPDEBytesFrame;
1925
1926#ifdef __DML_VBA_DEBUG__
1927	dml_print("DML::%s: MetaPTEBytesFrame = %d\n", __func__, *MetaPTEBytesFrame);
1928	dml_print("DML::%s: MPDEBytesFrame = %d\n", __func__, MPDEBytesFrame);
1929	dml_print("DML::%s: DPDE0BytesFrame = %d\n", __func__, *DPDE0BytesFrame);
1930	dml_print("DML::%s: ExtraDPDEBytesFrame= %d\n", __func__, ExtraDPDEBytesFrame);
1931	dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, PDEAndMetaPTEBytesFrame);
1932#endif
1933
1934	if (HostVMEnable == true) {
1935		PDEAndMetaPTEBytesFrame = PDEAndMetaPTEBytesFrame * (1 + 8 * HostVMDynamicLevels);
1936	}
1937#ifdef __DML_VBA_DEBUG__
1938	dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, PDEAndMetaPTEBytesFrame);
1939#endif
1940
1941	if (SurfaceTiling == dm_sw_linear) {
1942		PixelPTEReqHeightPTEs = 1;
1943		*PixelPTEReqHeight = 1;
1944		*PixelPTEReqWidth = 32768.0 / BytePerPixel;
1945		*PTERequestSize = 64;
1946		FractionOfPTEReturnDrop = 0;
1947	} else if (MacroTileSizeBytes == 4096) {
1948		PixelPTEReqHeightPTEs = 1;
1949		*PixelPTEReqHeight = MacroTileHeight;
1950		*PixelPTEReqWidth = 8 * *MacroTileWidth;
1951		*PTERequestSize = 64;
1952		if (ScanDirection != dm_vert)
1953			FractionOfPTEReturnDrop = 0;
1954		else
1955			FractionOfPTEReturnDrop = 7 / 8;
1956	} else if (GPUVMMinPageSize == 4 && MacroTileSizeBytes > 4096) {
1957		PixelPTEReqHeightPTEs = 16;
1958		*PixelPTEReqHeight = 16 * BlockHeight256Bytes;
1959		*PixelPTEReqWidth = 16 * BlockWidth256Bytes;
1960		*PTERequestSize = 128;
1961		FractionOfPTEReturnDrop = 0;
1962	} else {
1963		PixelPTEReqHeightPTEs = 1;
1964		*PixelPTEReqHeight = MacroTileHeight;
1965		*PixelPTEReqWidth = 8 * *MacroTileWidth;
1966		*PTERequestSize = 64;
1967		FractionOfPTEReturnDrop = 0;
1968	}
1969
1970	if (SurfaceTiling == dm_sw_linear) {
1971		*dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
1972		*dpte_row_width_ub = (dml_ceil((double)(Pitch * *dpte_row_height - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
1973		*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
1974	} else if (ScanDirection != dm_vert) {
1975		*dpte_row_height = *PixelPTEReqHeight;
1976		*dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
1977		*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
1978	} else {
1979		*dpte_row_height = dml_min(*PixelPTEReqWidth, *MacroTileWidth);
1980		*dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqHeight, 1) + 1) * *PixelPTEReqHeight;
1981		*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqHeight * *PTERequestSize;
1982	}
1983
1984	if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop) <= 64 * PTEBufferSizeInRequests) {
1985		*PTEBufferSizeNotExceeded = true;
1986	} else {
1987		*PTEBufferSizeNotExceeded = false;
1988	}
1989
1990	if (GPUVMEnable != true) {
1991		*PixelPTEBytesPerRow = 0;
1992		*PTEBufferSizeNotExceeded = true;
1993	}
1994
1995	dml_print("DML: vm_bytes = meta_pte_bytes_per_frame (per_pipe) = MetaPTEBytesFrame = : %i\n", *MetaPTEBytesFrame);
1996
1997	if (HostVMEnable == true) {
1998		*PixelPTEBytesPerRow = *PixelPTEBytesPerRow * (1 + 8 * HostVMDynamicLevels);
1999	}
2000
2001	if (HostVMEnable == true) {
2002		*vm_group_bytes = 512;
2003		*dpte_group_bytes = 512;
2004	} else if (GPUVMEnable == true) {
2005		*vm_group_bytes = 2048;
2006		if (SurfaceTiling != dm_sw_linear && PixelPTEReqHeightPTEs == 1 && ScanDirection == dm_vert) {
2007			*dpte_group_bytes = 512;
2008		} else {
2009			*dpte_group_bytes = 2048;
2010		}
2011	} else {
2012		*vm_group_bytes = 0;
2013		*dpte_group_bytes = 0;
2014	}
2015	return PDEAndMetaPTEBytesFrame;
2016}
2017
2018static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib)
2019{
2020	struct vba_vars_st *v = &mode_lib->vba;
2021	unsigned int j, k;
2022	double HostVMInefficiencyFactor = 1.0;
2023	bool NoChromaPlanes = true;
2024	int ReorderBytes;
2025	double VMDataOnlyReturnBW;
2026	double MaxTotalRDBandwidth = 0;
2027	int PrefetchMode = v->PrefetchModePerState[v->VoltageLevel][v->maxMpcComb];
2028
2029	v->WritebackDISPCLK = 0.0;
2030	v->DISPCLKWithRamping = 0;
2031	v->DISPCLKWithoutRamping = 0;
2032	v->GlobalDPPCLK = 0.0;
2033	/* DAL custom code: need to update ReturnBW in case min dcfclk is overridden */
2034	{
2035	double IdealFabricAndSDPPortBandwidthPerState = dml_min(
2036			v->ReturnBusWidth * v->DCFCLKState[v->VoltageLevel][v->maxMpcComb],
2037			v->FabricClockPerState[v->VoltageLevel] * v->FabricDatapathToDCNDataReturn);
2038	double IdealDRAMBandwidthPerState = v->DRAMSpeedPerState[v->VoltageLevel] * v->NumberOfChannels * v->DRAMChannelWidth;
2039
2040	if (v->HostVMEnable != true) {
2041		v->ReturnBW = dml_min(
2042				IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
2043				IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly / 100.0);
2044	} else {
2045		v->ReturnBW = dml_min(
2046				IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
2047				IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0);
2048	}
2049	}
2050	/* End DAL custom code */
2051
2052	// DISPCLK and DPPCLK Calculation
2053	//
2054	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2055		if (v->WritebackEnable[k]) {
2056			v->WritebackDISPCLK = dml_max(
2057					v->WritebackDISPCLK,
2058					dml314_CalculateWriteBackDISPCLK(
2059							v->WritebackPixelFormat[k],
2060							v->PixelClock[k],
2061							v->WritebackHRatio[k],
2062							v->WritebackVRatio[k],
2063							v->WritebackHTaps[k],
2064							v->WritebackVTaps[k],
2065							v->WritebackSourceWidth[k],
2066							v->WritebackDestinationWidth[k],
2067							v->HTotal[k],
2068							v->WritebackLineBufferSize));
2069		}
2070	}
2071
2072	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2073		if (v->HRatio[k] > 1) {
2074			v->PSCL_THROUGHPUT_LUMA[k] = dml_min(
2075					v->MaxDCHUBToPSCLThroughput,
2076					v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1));
2077		} else {
2078			v->PSCL_THROUGHPUT_LUMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
2079		}
2080
2081		v->DPPCLKUsingSingleDPPLuma = v->PixelClock[k]
2082				* dml_max(
2083						v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
2084						dml_max(v->HRatio[k] * v->VRatio[k] / v->PSCL_THROUGHPUT_LUMA[k], 1.0));
2085
2086		if ((v->htaps[k] > 6 || v->vtaps[k] > 6) && v->DPPCLKUsingSingleDPPLuma < 2 * v->PixelClock[k]) {
2087			v->DPPCLKUsingSingleDPPLuma = 2 * v->PixelClock[k];
2088		}
2089
2090		if ((v->SourcePixelFormat[k] != dm_420_8 && v->SourcePixelFormat[k] != dm_420_10 && v->SourcePixelFormat[k] != dm_420_12
2091				&& v->SourcePixelFormat[k] != dm_rgbe_alpha)) {
2092			v->PSCL_THROUGHPUT_CHROMA[k] = 0.0;
2093			v->DPPCLKUsingSingleDPP[k] = v->DPPCLKUsingSingleDPPLuma;
2094		} else {
2095			if (v->HRatioChroma[k] > 1) {
2096				v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(
2097						v->MaxDCHUBToPSCLThroughput,
2098						v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
2099			} else {
2100				v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
2101			}
2102			v->DPPCLKUsingSingleDPPChroma = v->PixelClock[k]
2103					* dml_max3(
2104							v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
2105							v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_THROUGHPUT_CHROMA[k],
2106							1.0);
2107
2108			if ((v->HTAPsChroma[k] > 6 || v->VTAPsChroma[k] > 6) && v->DPPCLKUsingSingleDPPChroma < 2 * v->PixelClock[k]) {
2109				v->DPPCLKUsingSingleDPPChroma = 2 * v->PixelClock[k];
2110			}
2111
2112			v->DPPCLKUsingSingleDPP[k] = dml_max(v->DPPCLKUsingSingleDPPLuma, v->DPPCLKUsingSingleDPPChroma);
2113		}
2114	}
2115
2116	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2117		if (v->BlendingAndTiming[k] != k)
2118			continue;
2119		if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1) {
2120			v->DISPCLKWithRamping = dml_max(
2121					v->DISPCLKWithRamping,
2122					v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
2123							* (1 + v->DISPCLKRampingMargin / 100));
2124			v->DISPCLKWithoutRamping = dml_max(
2125					v->DISPCLKWithoutRamping,
2126					v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2127		} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
2128			v->DISPCLKWithRamping = dml_max(
2129					v->DISPCLKWithRamping,
2130					v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
2131							* (1 + v->DISPCLKRampingMargin / 100));
2132			v->DISPCLKWithoutRamping = dml_max(
2133					v->DISPCLKWithoutRamping,
2134					v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2135		} else {
2136			v->DISPCLKWithRamping = dml_max(
2137					v->DISPCLKWithRamping,
2138					v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100) * (1 + v->DISPCLKRampingMargin / 100));
2139			v->DISPCLKWithoutRamping = dml_max(
2140					v->DISPCLKWithoutRamping,
2141					v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2142		}
2143	}
2144
2145	v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping, v->WritebackDISPCLK);
2146	v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping, v->WritebackDISPCLK);
2147
2148	ASSERT(v->DISPCLKDPPCLKVCOSpeed != 0);
2149	v->DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(v->DISPCLKWithRamping, v->DISPCLKDPPCLKVCOSpeed);
2150	v->DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(v->DISPCLKWithoutRamping, v->DISPCLKDPPCLKVCOSpeed);
2151	v->MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
2152			v->soc.clock_limits[v->soc.num_states - 1].dispclk_mhz,
2153			v->DISPCLKDPPCLKVCOSpeed);
2154	if (v->DISPCLKWithoutRampingRoundedToDFSGranularity > v->MaxDispclkRoundedToDFSGranularity) {
2155		v->DISPCLK_calculated = v->DISPCLKWithoutRampingRoundedToDFSGranularity;
2156	} else if (v->DISPCLKWithRampingRoundedToDFSGranularity > v->MaxDispclkRoundedToDFSGranularity) {
2157		v->DISPCLK_calculated = v->MaxDispclkRoundedToDFSGranularity;
2158	} else {
2159		v->DISPCLK_calculated = v->DISPCLKWithRampingRoundedToDFSGranularity;
2160	}
2161	v->DISPCLK = v->DISPCLK_calculated;
2162	DTRACE("   dispclk_mhz (calculated) = %f", v->DISPCLK_calculated);
2163
2164	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2165		v->DPPCLK_calculated[k] = v->DPPCLKUsingSingleDPP[k] / v->DPPPerPlane[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2166		v->GlobalDPPCLK = dml_max(v->GlobalDPPCLK, v->DPPCLK_calculated[k]);
2167	}
2168	v->GlobalDPPCLK = RoundToDFSGranularityUp(v->GlobalDPPCLK, v->DISPCLKDPPCLKVCOSpeed);
2169	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2170		v->DPPCLK_calculated[k] = v->GlobalDPPCLK / 255 * dml_ceil(v->DPPCLK_calculated[k] * 255.0 / v->GlobalDPPCLK, 1);
2171		DTRACE("   dppclk_mhz[%i] (calculated) = %f", k, v->DPPCLK_calculated[k]);
2172	}
2173
2174	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2175		v->DPPCLK[k] = v->DPPCLK_calculated[k];
2176	}
2177
2178	// Urgent and B P-State/DRAM Clock Change Watermark
2179	DTRACE("   dcfclk_mhz         = %f", v->DCFCLK);
2180	DTRACE("   return_bus_bw      = %f", v->ReturnBW);
2181
2182	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2183		CalculateBytePerPixelAnd256BBlockSizes(
2184				v->SourcePixelFormat[k],
2185				v->SurfaceTiling[k],
2186				&v->BytePerPixelY[k],
2187				&v->BytePerPixelC[k],
2188				&v->BytePerPixelDETY[k],
2189				&v->BytePerPixelDETC[k],
2190				&v->BlockHeight256BytesY[k],
2191				&v->BlockHeight256BytesC[k],
2192				&v->BlockWidth256BytesY[k],
2193				&v->BlockWidth256BytesC[k]);
2194	}
2195
2196	CalculateSwathWidth(
2197			false,
2198			v->NumberOfActivePlanes,
2199			v->SourcePixelFormat,
2200			v->SourceScan,
2201			v->ViewportWidth,
2202			v->ViewportHeight,
2203			v->SurfaceWidthY,
2204			v->SurfaceWidthC,
2205			v->SurfaceHeightY,
2206			v->SurfaceHeightC,
2207			v->ODMCombineEnabled,
2208			v->BytePerPixelY,
2209			v->BytePerPixelC,
2210			v->BlockHeight256BytesY,
2211			v->BlockHeight256BytesC,
2212			v->BlockWidth256BytesY,
2213			v->BlockWidth256BytesC,
2214			v->BlendingAndTiming,
2215			v->HActive,
2216			v->HRatio,
2217			v->DPPPerPlane,
2218			v->SwathWidthSingleDPPY,
2219			v->SwathWidthSingleDPPC,
2220			v->SwathWidthY,
2221			v->SwathWidthC,
2222			v->dummyinteger3,
2223			v->dummyinteger4,
2224			v->swath_width_luma_ub,
2225			v->swath_width_chroma_ub);
2226
2227	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2228		v->ReadBandwidthPlaneLuma[k] = v->SwathWidthSingleDPPY[k] * v->BytePerPixelY[k] / (v->HTotal[k] / v->PixelClock[k])
2229				* v->VRatio[k];
2230		v->ReadBandwidthPlaneChroma[k] = v->SwathWidthSingleDPPC[k] * v->BytePerPixelC[k] / (v->HTotal[k] / v->PixelClock[k])
2231				* v->VRatioChroma[k];
2232		DTRACE("   read_bw[%i] = %fBps", k, v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k]);
2233	}
2234
2235	// DCFCLK Deep Sleep
2236	CalculateDCFCLKDeepSleep(
2237			mode_lib,
2238			v->NumberOfActivePlanes,
2239			v->BytePerPixelY,
2240			v->BytePerPixelC,
2241			v->VRatio,
2242			v->VRatioChroma,
2243			v->SwathWidthY,
2244			v->SwathWidthC,
2245			v->DPPPerPlane,
2246			v->HRatio,
2247			v->HRatioChroma,
2248			v->PixelClock,
2249			v->PSCL_THROUGHPUT_LUMA,
2250			v->PSCL_THROUGHPUT_CHROMA,
2251			v->DPPCLK,
2252			v->ReadBandwidthPlaneLuma,
2253			v->ReadBandwidthPlaneChroma,
2254			v->ReturnBusWidth,
2255			&v->DCFCLKDeepSleep);
2256
2257	// DSCCLK
2258	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2259		if ((v->BlendingAndTiming[k] != k) || !v->DSCEnabled[k]) {
2260			v->DSCCLK_calculated[k] = 0.0;
2261		} else {
2262			if (v->OutputFormat[k] == dm_420)
2263				v->DSCFormatFactor = 2;
2264			else if (v->OutputFormat[k] == dm_444)
2265				v->DSCFormatFactor = 1;
2266			else if (v->OutputFormat[k] == dm_n422)
2267				v->DSCFormatFactor = 2;
2268			else
2269				v->DSCFormatFactor = 1;
2270			if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
2271				v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 12 / v->DSCFormatFactor
2272						/ (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2273			else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
2274				v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 6 / v->DSCFormatFactor
2275						/ (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2276			else
2277				v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 3 / v->DSCFormatFactor
2278						/ (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2279		}
2280	}
2281
2282	// DSC Delay
2283	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2284		double BPP = v->OutputBpp[k];
2285
2286		if (v->DSCEnabled[k] && BPP != 0) {
2287			if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_disabled) {
2288				v->DSCDelay[k] = dscceComputeDelay(
2289						v->DSCInputBitPerComponent[k],
2290						BPP,
2291						dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2292						v->NumberOfDSCSlices[k],
2293						v->OutputFormat[k],
2294						v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
2295			} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
2296				v->DSCDelay[k] = 2
2297						* (dscceComputeDelay(
2298								v->DSCInputBitPerComponent[k],
2299								BPP,
2300								dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2301								v->NumberOfDSCSlices[k] / 2.0,
2302								v->OutputFormat[k],
2303								v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
2304			} else {
2305				v->DSCDelay[k] = 4
2306						* (dscceComputeDelay(
2307								v->DSCInputBitPerComponent[k],
2308								BPP,
2309								dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2310								v->NumberOfDSCSlices[k] / 4.0,
2311								v->OutputFormat[k],
2312								v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
2313			}
2314			v->DSCDelay[k] = v->DSCDelay[k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
2315		} else {
2316			v->DSCDelay[k] = 0;
2317		}
2318	}
2319
2320	for (k = 0; k < v->NumberOfActivePlanes; ++k)
2321		for (j = 0; j < v->NumberOfActivePlanes; ++j) // NumberOfPlanes
2322			if (j != k && v->BlendingAndTiming[k] == j && v->DSCEnabled[j])
2323				v->DSCDelay[k] = v->DSCDelay[j];
2324
2325	// Prefetch
2326	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2327		unsigned int PDEAndMetaPTEBytesFrameY;
2328		unsigned int PixelPTEBytesPerRowY;
2329		unsigned int MetaRowByteY;
2330		unsigned int MetaRowByteC;
2331		unsigned int PDEAndMetaPTEBytesFrameC;
2332		unsigned int PixelPTEBytesPerRowC;
2333		bool PTEBufferSizeNotExceededY;
2334		bool PTEBufferSizeNotExceededC;
2335
2336		if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
2337				|| v->SourcePixelFormat[k] == dm_rgbe_alpha) {
2338			if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) && v->SourceScan[k] != dm_vert) {
2339				v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma) / 2;
2340				v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
2341			} else {
2342				v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
2343				v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
2344			}
2345
2346			PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(
2347					mode_lib,
2348					v->DCCEnable[k],
2349					v->BlockHeight256BytesC[k],
2350					v->BlockWidth256BytesC[k],
2351					v->SourcePixelFormat[k],
2352					v->SurfaceTiling[k],
2353					v->BytePerPixelC[k],
2354					v->SourceScan[k],
2355					v->SwathWidthC[k],
2356					v->ViewportHeightChroma[k],
2357					v->GPUVMEnable,
2358					v->HostVMEnable,
2359					v->HostVMMaxNonCachedPageTableLevels,
2360					v->GPUVMMinPageSize,
2361					v->HostVMMinPageSize,
2362					v->PTEBufferSizeInRequestsForChroma,
2363					v->PitchC[k],
2364					v->DCCMetaPitchC[k],
2365					&v->MacroTileWidthC[k],
2366					&MetaRowByteC,
2367					&PixelPTEBytesPerRowC,
2368					&PTEBufferSizeNotExceededC,
2369					&v->dpte_row_width_chroma_ub[k],
2370					&v->dpte_row_height_chroma[k],
2371					&v->meta_req_width_chroma[k],
2372					&v->meta_req_height_chroma[k],
2373					&v->meta_row_width_chroma[k],
2374					&v->meta_row_height_chroma[k],
2375					&v->dummyinteger1,
2376					&v->dummyinteger2,
2377					&v->PixelPTEReqWidthC[k],
2378					&v->PixelPTEReqHeightC[k],
2379					&v->PTERequestSizeC[k],
2380					&v->dpde0_bytes_per_frame_ub_c[k],
2381					&v->meta_pte_bytes_per_frame_ub_c[k]);
2382
2383			v->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
2384					mode_lib,
2385					v->VRatioChroma[k],
2386					v->VTAPsChroma[k],
2387					v->Interlace[k],
2388					v->ProgressiveToInterlaceUnitInOPP,
2389					v->SwathHeightC[k],
2390					v->ViewportYStartC[k],
2391					&v->VInitPreFillC[k],
2392					&v->MaxNumSwathC[k]);
2393		} else {
2394			v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
2395			v->PTEBufferSizeInRequestsForChroma = 0;
2396			PixelPTEBytesPerRowC = 0;
2397			PDEAndMetaPTEBytesFrameC = 0;
2398			MetaRowByteC = 0;
2399			v->MaxNumSwathC[k] = 0;
2400			v->PrefetchSourceLinesC[k] = 0;
2401		}
2402
2403		PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
2404				mode_lib,
2405				v->DCCEnable[k],
2406				v->BlockHeight256BytesY[k],
2407				v->BlockWidth256BytesY[k],
2408				v->SourcePixelFormat[k],
2409				v->SurfaceTiling[k],
2410				v->BytePerPixelY[k],
2411				v->SourceScan[k],
2412				v->SwathWidthY[k],
2413				v->ViewportHeight[k],
2414				v->GPUVMEnable,
2415				v->HostVMEnable,
2416				v->HostVMMaxNonCachedPageTableLevels,
2417				v->GPUVMMinPageSize,
2418				v->HostVMMinPageSize,
2419				v->PTEBufferSizeInRequestsForLuma,
2420				v->PitchY[k],
2421				v->DCCMetaPitchY[k],
2422				&v->MacroTileWidthY[k],
2423				&MetaRowByteY,
2424				&PixelPTEBytesPerRowY,
2425				&PTEBufferSizeNotExceededY,
2426				&v->dpte_row_width_luma_ub[k],
2427				&v->dpte_row_height[k],
2428				&v->meta_req_width[k],
2429				&v->meta_req_height[k],
2430				&v->meta_row_width[k],
2431				&v->meta_row_height[k],
2432				&v->vm_group_bytes[k],
2433				&v->dpte_group_bytes[k],
2434				&v->PixelPTEReqWidthY[k],
2435				&v->PixelPTEReqHeightY[k],
2436				&v->PTERequestSizeY[k],
2437				&v->dpde0_bytes_per_frame_ub_l[k],
2438				&v->meta_pte_bytes_per_frame_ub_l[k]);
2439
2440		v->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
2441				mode_lib,
2442				v->VRatio[k],
2443				v->vtaps[k],
2444				v->Interlace[k],
2445				v->ProgressiveToInterlaceUnitInOPP,
2446				v->SwathHeightY[k],
2447				v->ViewportYStartY[k],
2448				&v->VInitPreFillY[k],
2449				&v->MaxNumSwathY[k]);
2450		v->PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
2451		v->PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + PDEAndMetaPTEBytesFrameC;
2452		v->MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
2453
2454		CalculateRowBandwidth(
2455				v->GPUVMEnable,
2456				v->SourcePixelFormat[k],
2457				v->VRatio[k],
2458				v->VRatioChroma[k],
2459				v->DCCEnable[k],
2460				v->HTotal[k] / v->PixelClock[k],
2461				MetaRowByteY,
2462				MetaRowByteC,
2463				v->meta_row_height[k],
2464				v->meta_row_height_chroma[k],
2465				PixelPTEBytesPerRowY,
2466				PixelPTEBytesPerRowC,
2467				v->dpte_row_height[k],
2468				v->dpte_row_height_chroma[k],
2469				&v->meta_row_bw[k],
2470				&v->dpte_row_bw[k]);
2471	}
2472
2473	v->TotalDCCActiveDPP = 0;
2474	v->TotalActiveDPP = 0;
2475	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2476		v->TotalActiveDPP = v->TotalActiveDPP + v->DPPPerPlane[k];
2477		if (v->DCCEnable[k])
2478			v->TotalDCCActiveDPP = v->TotalDCCActiveDPP + v->DPPPerPlane[k];
2479		if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
2480				|| v->SourcePixelFormat[k] == dm_rgbe_alpha)
2481			NoChromaPlanes = false;
2482	}
2483
2484	ReorderBytes = v->NumberOfChannels
2485			* dml_max3(
2486					v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
2487					v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
2488					v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
2489
2490	VMDataOnlyReturnBW = dml_min(
2491			dml_min(v->ReturnBusWidth * v->DCFCLK, v->FabricClock * v->FabricDatapathToDCNDataReturn)
2492					* v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
2493			v->DRAMSpeed * v->NumberOfChannels * v->DRAMChannelWidth
2494					* v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly / 100.0);
2495
2496#ifdef __DML_VBA_DEBUG__
2497	dml_print("DML::%s: v->ReturnBusWidth = %f\n", __func__, v->ReturnBusWidth);
2498	dml_print("DML::%s: v->DCFCLK = %f\n", __func__, v->DCFCLK);
2499	dml_print("DML::%s: v->FabricClock = %f\n", __func__, v->FabricClock);
2500	dml_print("DML::%s: v->FabricDatapathToDCNDataReturn = %f\n", __func__, v->FabricDatapathToDCNDataReturn);
2501	dml_print("DML::%s: v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = %f\n", __func__, v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency);
2502	dml_print("DML::%s: v->DRAMSpeed = %f\n", __func__, v->DRAMSpeed);
2503	dml_print("DML::%s: v->NumberOfChannels = %f\n", __func__, v->NumberOfChannels);
2504	dml_print("DML::%s: v->DRAMChannelWidth = %f\n", __func__, v->DRAMChannelWidth);
2505	dml_print("DML::%s: v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = %f\n", __func__, v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly);
2506	dml_print("DML::%s: VMDataOnlyReturnBW = %f\n", __func__, VMDataOnlyReturnBW);
2507	dml_print("DML::%s: ReturnBW = %f\n", __func__, v->ReturnBW);
2508#endif
2509
2510	if (v->GPUVMEnable && v->HostVMEnable)
2511		HostVMInefficiencyFactor = v->ReturnBW / VMDataOnlyReturnBW;
2512
2513	v->UrgentExtraLatency = CalculateExtraLatency(
2514			v->RoundTripPingLatencyCycles,
2515			ReorderBytes,
2516			v->DCFCLK,
2517			v->TotalActiveDPP,
2518			v->PixelChunkSizeInKByte,
2519			v->TotalDCCActiveDPP,
2520			v->MetaChunkSize,
2521			v->ReturnBW,
2522			v->GPUVMEnable,
2523			v->HostVMEnable,
2524			v->NumberOfActivePlanes,
2525			v->DPPPerPlane,
2526			v->dpte_group_bytes,
2527			HostVMInefficiencyFactor,
2528			v->HostVMMinPageSize,
2529			v->HostVMMaxNonCachedPageTableLevels);
2530
2531	v->TCalc = 24.0 / v->DCFCLKDeepSleep;
2532
2533	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2534		if (v->BlendingAndTiming[k] == k) {
2535			if (v->WritebackEnable[k] == true) {
2536				v->WritebackDelay[v->VoltageLevel][k] = v->WritebackLatency
2537						+ CalculateWriteBackDelay(
2538								v->WritebackPixelFormat[k],
2539								v->WritebackHRatio[k],
2540								v->WritebackVRatio[k],
2541								v->WritebackVTaps[k],
2542								v->WritebackDestinationWidth[k],
2543								v->WritebackDestinationHeight[k],
2544								v->WritebackSourceHeight[k],
2545								v->HTotal[k]) / v->DISPCLK;
2546			} else
2547				v->WritebackDelay[v->VoltageLevel][k] = 0;
2548			for (j = 0; j < v->NumberOfActivePlanes; ++j) {
2549				if (v->BlendingAndTiming[j] == k && v->WritebackEnable[j] == true) {
2550					v->WritebackDelay[v->VoltageLevel][k] = dml_max(
2551							v->WritebackDelay[v->VoltageLevel][k],
2552							v->WritebackLatency
2553									+ CalculateWriteBackDelay(
2554											v->WritebackPixelFormat[j],
2555											v->WritebackHRatio[j],
2556											v->WritebackVRatio[j],
2557											v->WritebackVTaps[j],
2558											v->WritebackDestinationWidth[j],
2559											v->WritebackDestinationHeight[j],
2560											v->WritebackSourceHeight[j],
2561											v->HTotal[k]) / v->DISPCLK);
2562				}
2563			}
2564		}
2565	}
2566
2567	for (k = 0; k < v->NumberOfActivePlanes; ++k)
2568		for (j = 0; j < v->NumberOfActivePlanes; ++j)
2569			if (v->BlendingAndTiming[k] == j)
2570				v->WritebackDelay[v->VoltageLevel][k] = v->WritebackDelay[v->VoltageLevel][j];
2571
2572	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2573		v->MaxVStartupLines[k] =
2574			CalculateMaxVStartup(
2575					v->VTotal[k],
2576					v->VActive[k],
2577					v->VBlankNom[k],
2578					v->HTotal[k],
2579					v->PixelClock[k],
2580					v->ProgressiveToInterlaceUnitInOPP,
2581					v->Interlace[k],
2582					v->ip.VBlankNomDefaultUS,
2583					v->WritebackDelay[v->VoltageLevel][k]);
2584
2585#ifdef __DML_VBA_DEBUG__
2586		dml_print("DML::%s: k=%d MaxVStartupLines = %d\n", __func__, k, v->MaxVStartupLines[k]);
2587		dml_print("DML::%s: k=%d VoltageLevel = %d\n", __func__, k, v->VoltageLevel);
2588		dml_print("DML::%s: k=%d WritebackDelay = %f\n", __func__, k, v->WritebackDelay[v->VoltageLevel][k]);
2589#endif
2590	}
2591
2592	v->MaximumMaxVStartupLines = 0;
2593	for (k = 0; k < v->NumberOfActivePlanes; ++k)
2594		v->MaximumMaxVStartupLines = dml_max(v->MaximumMaxVStartupLines, v->MaxVStartupLines[k]);
2595
2596	// VBA_DELTA
2597	// We don't really care to iterate between the various prefetch modes
2598	//v->PrefetchERROR = CalculateMinAndMaxPrefetchMode(v->AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &v->MinPrefetchMode, &v->MaxPrefetchMode);
2599
2600	v->UrgentLatency = CalculateUrgentLatency(
2601			v->UrgentLatencyPixelDataOnly,
2602			v->UrgentLatencyPixelMixedWithVMData,
2603			v->UrgentLatencyVMDataOnly,
2604			v->DoUrgentLatencyAdjustment,
2605			v->UrgentLatencyAdjustmentFabricClockComponent,
2606			v->UrgentLatencyAdjustmentFabricClockReference,
2607			v->FabricClock);
2608
2609	v->FractionOfUrgentBandwidth = 0.0;
2610	v->FractionOfUrgentBandwidthImmediateFlip = 0.0;
2611
2612	v->VStartupLines = __DML_VBA_MIN_VSTARTUP__;
2613
2614	do {
2615		double MaxTotalRDBandwidthNoUrgentBurst = 0.0;
2616		bool DestinationLineTimesForPrefetchLessThan2 = false;
2617		bool VRatioPrefetchMoreThan4 = false;
2618		double TWait = CalculateTWait(PrefetchMode, v->DRAMClockChangeLatency, v->UrgentLatency, v->SREnterPlusExitTime);
2619
2620		MaxTotalRDBandwidth = 0;
2621
2622		dml_print("DML::%s: Start loop: VStartup = %d\n", __func__, v->VStartupLines);
2623
2624		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2625			Pipe myPipe;
2626
2627			myPipe.DPPCLK = v->DPPCLK[k];
2628			myPipe.DISPCLK = v->DISPCLK;
2629			myPipe.PixelClock = v->PixelClock[k];
2630			myPipe.DCFCLKDeepSleep = v->DCFCLKDeepSleep;
2631			myPipe.DPPPerPlane = v->DPPPerPlane[k];
2632			myPipe.ScalerEnabled = v->ScalerEnabled[k];
2633			myPipe.VRatio = v->VRatio[k];
2634			myPipe.VRatioChroma = v->VRatioChroma[k];
2635			myPipe.SourceScan = v->SourceScan[k];
2636			myPipe.BlockWidth256BytesY = v->BlockWidth256BytesY[k];
2637			myPipe.BlockHeight256BytesY = v->BlockHeight256BytesY[k];
2638			myPipe.BlockWidth256BytesC = v->BlockWidth256BytesC[k];
2639			myPipe.BlockHeight256BytesC = v->BlockHeight256BytesC[k];
2640			myPipe.InterlaceEnable = v->Interlace[k];
2641			myPipe.NumberOfCursors = v->NumberOfCursors[k];
2642			myPipe.VBlank = v->VTotal[k] - v->VActive[k];
2643			myPipe.HTotal = v->HTotal[k];
2644			myPipe.DCCEnable = v->DCCEnable[k];
2645			myPipe.ODMCombineIsEnabled = v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1
2646					|| v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1;
2647			myPipe.SourcePixelFormat = v->SourcePixelFormat[k];
2648			myPipe.BytePerPixelY = v->BytePerPixelY[k];
2649			myPipe.BytePerPixelC = v->BytePerPixelC[k];
2650			myPipe.ProgressiveToInterlaceUnitInOPP = v->ProgressiveToInterlaceUnitInOPP;
2651			v->ErrorResult[k] = CalculatePrefetchSchedule(
2652					mode_lib,
2653					HostVMInefficiencyFactor,
2654					&myPipe,
2655					v->DSCDelay[k],
2656					v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater,
2657					v->DPPCLKDelaySCL,
2658					v->DPPCLKDelaySCLLBOnly,
2659					v->DPPCLKDelayCNVCCursor,
2660					v->DISPCLKDelaySubtotal,
2661					(unsigned int) (v->SwathWidthY[k] / v->HRatio[k]),
2662					v->OutputFormat[k],
2663					v->MaxInterDCNTileRepeaters,
2664					dml_min(v->VStartupLines, v->MaxVStartupLines[k]),
2665					v->MaxVStartupLines[k],
2666					v->GPUVMMaxPageTableLevels,
2667					v->GPUVMEnable,
2668					v->HostVMEnable,
2669					v->HostVMMaxNonCachedPageTableLevels,
2670					v->HostVMMinPageSize,
2671					v->DynamicMetadataEnable[k],
2672					v->DynamicMetadataVMEnabled,
2673					v->DynamicMetadataLinesBeforeActiveRequired[k],
2674					v->DynamicMetadataTransmittedBytes[k],
2675					v->UrgentLatency,
2676					v->UrgentExtraLatency,
2677					v->TCalc,
2678					v->PDEAndMetaPTEBytesFrame[k],
2679					v->MetaRowByte[k],
2680					v->PixelPTEBytesPerRow[k],
2681					v->PrefetchSourceLinesY[k],
2682					v->SwathWidthY[k],
2683					v->VInitPreFillY[k],
2684					v->MaxNumSwathY[k],
2685					v->PrefetchSourceLinesC[k],
2686					v->SwathWidthC[k],
2687					v->VInitPreFillC[k],
2688					v->MaxNumSwathC[k],
2689					v->swath_width_luma_ub[k],
2690					v->swath_width_chroma_ub[k],
2691					v->SwathHeightY[k],
2692					v->SwathHeightC[k],
2693					TWait,
2694					&v->DSTXAfterScaler[k],
2695					&v->DSTYAfterScaler[k],
2696					&v->DestinationLinesForPrefetch[k],
2697					&v->PrefetchBandwidth[k],
2698					&v->DestinationLinesToRequestVMInVBlank[k],
2699					&v->DestinationLinesToRequestRowInVBlank[k],
2700					&v->VRatioPrefetchY[k],
2701					&v->VRatioPrefetchC[k],
2702					&v->RequiredPrefetchPixDataBWLuma[k],
2703					&v->RequiredPrefetchPixDataBWChroma[k],
2704					&v->NotEnoughTimeForDynamicMetadata[k],
2705					&v->Tno_bw[k],
2706					&v->prefetch_vmrow_bw[k],
2707					&v->Tdmdl_vm[k],
2708					&v->Tdmdl[k],
2709					&v->TSetup[k],
2710					&v->VUpdateOffsetPix[k],
2711					&v->VUpdateWidthPix[k],
2712					&v->VReadyOffsetPix[k]);
2713
2714#ifdef __DML_VBA_DEBUG__
2715			dml_print("DML::%s: k=%0d Prefetch cal result=%0d\n", __func__, k, v->ErrorResult[k]);
2716#endif
2717			v->VStartup[k] = dml_min(v->VStartupLines, v->MaxVStartupLines[k]);
2718		}
2719
2720		v->NoEnoughUrgentLatencyHiding = false;
2721		v->NoEnoughUrgentLatencyHidingPre = false;
2722
2723		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2724			v->cursor_bw[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
2725					/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
2726			v->cursor_bw_pre[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
2727					/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatioPrefetchY[k];
2728
2729			CalculateUrgentBurstFactor(
2730					v->swath_width_luma_ub[k],
2731					v->swath_width_chroma_ub[k],
2732					v->SwathHeightY[k],
2733					v->SwathHeightC[k],
2734					v->HTotal[k] / v->PixelClock[k],
2735					v->UrgentLatency,
2736					v->CursorBufferSize,
2737					v->CursorWidth[k][0],
2738					v->CursorBPP[k][0],
2739					v->VRatio[k],
2740					v->VRatioChroma[k],
2741					v->BytePerPixelDETY[k],
2742					v->BytePerPixelDETC[k],
2743					v->DETBufferSizeY[k],
2744					v->DETBufferSizeC[k],
2745					&v->UrgBurstFactorCursor[k],
2746					&v->UrgBurstFactorLuma[k],
2747					&v->UrgBurstFactorChroma[k],
2748					&v->NoUrgentLatencyHiding[k]);
2749
2750			CalculateUrgentBurstFactor(
2751					v->swath_width_luma_ub[k],
2752					v->swath_width_chroma_ub[k],
2753					v->SwathHeightY[k],
2754					v->SwathHeightC[k],
2755					v->HTotal[k] / v->PixelClock[k],
2756					v->UrgentLatency,
2757					v->CursorBufferSize,
2758					v->CursorWidth[k][0],
2759					v->CursorBPP[k][0],
2760					v->VRatioPrefetchY[k],
2761					v->VRatioPrefetchC[k],
2762					v->BytePerPixelDETY[k],
2763					v->BytePerPixelDETC[k],
2764					v->DETBufferSizeY[k],
2765					v->DETBufferSizeC[k],
2766					&v->UrgBurstFactorCursorPre[k],
2767					&v->UrgBurstFactorLumaPre[k],
2768					&v->UrgBurstFactorChromaPre[k],
2769					&v->NoUrgentLatencyHidingPre[k]);
2770
2771			MaxTotalRDBandwidth = MaxTotalRDBandwidth
2772					+ dml_max3(
2773							v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2774							v->ReadBandwidthPlaneLuma[k] * v->UrgBurstFactorLuma[k]
2775									+ v->ReadBandwidthPlaneChroma[k] * v->UrgBurstFactorChroma[k]
2776									+ v->cursor_bw[k] * v->UrgBurstFactorCursor[k]
2777									+ v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
2778							v->DPPPerPlane[k]
2779									* (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
2780											+ v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
2781									+ v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
2782
2783			MaxTotalRDBandwidthNoUrgentBurst = MaxTotalRDBandwidthNoUrgentBurst
2784					+ dml_max3(
2785							v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2786							v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k]
2787									+ v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
2788							v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] + v->RequiredPrefetchPixDataBWChroma[k])
2789									+ v->cursor_bw_pre[k]);
2790
2791#ifdef __DML_VBA_DEBUG__
2792			dml_print("DML::%s: k=%0d DPPPerPlane=%d\n", __func__, k, v->DPPPerPlane[k]);
2793			dml_print("DML::%s: k=%0d UrgBurstFactorLuma=%f\n", __func__, k, v->UrgBurstFactorLuma[k]);
2794			dml_print("DML::%s: k=%0d UrgBurstFactorChroma=%f\n", __func__, k, v->UrgBurstFactorChroma[k]);
2795			dml_print("DML::%s: k=%0d UrgBurstFactorLumaPre=%f\n", __func__, k, v->UrgBurstFactorLumaPre[k]);
2796			dml_print("DML::%s: k=%0d UrgBurstFactorChromaPre=%f\n", __func__, k, v->UrgBurstFactorChromaPre[k]);
2797
2798			dml_print("DML::%s: k=%0d VRatioPrefetchY=%f\n", __func__, k, v->VRatioPrefetchY[k]);
2799			dml_print("DML::%s: k=%0d VRatioY=%f\n", __func__, k, v->VRatio[k]);
2800
2801			dml_print("DML::%s: k=%0d prefetch_vmrow_bw=%f\n", __func__, k, v->prefetch_vmrow_bw[k]);
2802			dml_print("DML::%s: k=%0d ReadBandwidthPlaneLuma=%f\n", __func__, k, v->ReadBandwidthPlaneLuma[k]);
2803			dml_print("DML::%s: k=%0d ReadBandwidthPlaneChroma=%f\n", __func__, k, v->ReadBandwidthPlaneChroma[k]);
2804			dml_print("DML::%s: k=%0d cursor_bw=%f\n", __func__, k, v->cursor_bw[k]);
2805			dml_print("DML::%s: k=%0d meta_row_bw=%f\n", __func__, k, v->meta_row_bw[k]);
2806			dml_print("DML::%s: k=%0d dpte_row_bw=%f\n", __func__, k, v->dpte_row_bw[k]);
2807			dml_print("DML::%s: k=%0d RequiredPrefetchPixDataBWLuma=%f\n", __func__, k, v->RequiredPrefetchPixDataBWLuma[k]);
2808			dml_print("DML::%s: k=%0d RequiredPrefetchPixDataBWChroma=%f\n", __func__, k, v->RequiredPrefetchPixDataBWChroma[k]);
2809			dml_print("DML::%s: k=%0d cursor_bw_pre=%f\n", __func__, k, v->cursor_bw_pre[k]);
2810			dml_print("DML::%s: k=%0d MaxTotalRDBandwidthNoUrgentBurst=%f\n", __func__, k, MaxTotalRDBandwidthNoUrgentBurst);
2811#endif
2812
2813			if (v->DestinationLinesForPrefetch[k] < 2)
2814				DestinationLineTimesForPrefetchLessThan2 = true;
2815
2816			if (v->VRatioPrefetchY[k] > 4 || v->VRatioPrefetchC[k] > 4)
2817				VRatioPrefetchMoreThan4 = true;
2818
2819			if (v->NoUrgentLatencyHiding[k] == true)
2820				v->NoEnoughUrgentLatencyHiding = true;
2821
2822			if (v->NoUrgentLatencyHidingPre[k] == true)
2823				v->NoEnoughUrgentLatencyHidingPre = true;
2824		}
2825
2826		v->FractionOfUrgentBandwidth = MaxTotalRDBandwidthNoUrgentBurst / v->ReturnBW;
2827
2828#ifdef __DML_VBA_DEBUG__
2829		dml_print("DML::%s: MaxTotalRDBandwidthNoUrgentBurst=%f\n", __func__, MaxTotalRDBandwidthNoUrgentBurst);
2830		dml_print("DML::%s: ReturnBW=%f\n", __func__, v->ReturnBW);
2831		dml_print("DML::%s: FractionOfUrgentBandwidth=%f\n", __func__, v->FractionOfUrgentBandwidth);
2832#endif
2833
2834		if (MaxTotalRDBandwidth <= v->ReturnBW && v->NoEnoughUrgentLatencyHiding == 0 && v->NoEnoughUrgentLatencyHidingPre == 0
2835				&& !VRatioPrefetchMoreThan4 && !DestinationLineTimesForPrefetchLessThan2)
2836			v->PrefetchModeSupported = true;
2837		else {
2838			v->PrefetchModeSupported = false;
2839			dml_print("DML::%s: ***failed***. Bandwidth violation. Results are NOT valid\n", __func__);
2840			dml_print("DML::%s: MaxTotalRDBandwidth:%f AvailReturnBandwidth:%f\n", __func__, MaxTotalRDBandwidth, v->ReturnBW);
2841			dml_print("DML::%s: VRatioPrefetch %s more than 4\n", __func__, (VRatioPrefetchMoreThan4) ? "is" : "is not");
2842			dml_print("DML::%s: DestinationLines for Prefetch %s less than 2\n", __func__, (DestinationLineTimesForPrefetchLessThan2) ? "is" : "is not");
2843		}
2844
2845		// PREVIOUS_ERROR
2846		// This error result check was done after the PrefetchModeSupported. So we will
2847		// still try to calculate flip schedule even prefetch mode not supported
2848		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2849			if (v->ErrorResult[k] == true || v->NotEnoughTimeForDynamicMetadata[k] == true) {
2850				v->PrefetchModeSupported = false;
2851				dml_print("DML::%s: ***failed***. Prefetch schedule violation. Results are NOT valid\n", __func__);
2852			}
2853		}
2854
2855		if (v->PrefetchModeSupported == true && v->ImmediateFlipSupport == true) {
2856			v->BandwidthAvailableForImmediateFlip = v->ReturnBW;
2857			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2858				v->BandwidthAvailableForImmediateFlip = v->BandwidthAvailableForImmediateFlip
2859						- dml_max(
2860								v->ReadBandwidthPlaneLuma[k] * v->UrgBurstFactorLuma[k]
2861										+ v->ReadBandwidthPlaneChroma[k] * v->UrgBurstFactorChroma[k]
2862										+ v->cursor_bw[k] * v->UrgBurstFactorCursor[k],
2863								v->DPPPerPlane[k]
2864										* (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
2865												+ v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
2866										+ v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
2867			}
2868
2869			v->TotImmediateFlipBytes = 0;
2870			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2871				v->TotImmediateFlipBytes = v->TotImmediateFlipBytes
2872						+ v->DPPPerPlane[k] * (v->PDEAndMetaPTEBytesFrame[k] + v->MetaRowByte[k] + v->PixelPTEBytesPerRow[k]);
2873			}
2874			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2875				CalculateFlipSchedule(
2876						mode_lib,
2877						k,
2878						HostVMInefficiencyFactor,
2879						v->UrgentExtraLatency,
2880						v->UrgentLatency,
2881						v->PDEAndMetaPTEBytesFrame[k],
2882						v->MetaRowByte[k],
2883						v->PixelPTEBytesPerRow[k]);
2884			}
2885
2886			v->total_dcn_read_bw_with_flip = 0.0;
2887			v->total_dcn_read_bw_with_flip_no_urgent_burst = 0.0;
2888			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2889				v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip
2890						+ dml_max3(
2891								v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2892								v->DPPPerPlane[k] * v->final_flip_bw[k]
2893										+ v->ReadBandwidthLuma[k] * v->UrgBurstFactorLuma[k]
2894										+ v->ReadBandwidthChroma[k] * v->UrgBurstFactorChroma[k]
2895										+ v->cursor_bw[k] * v->UrgBurstFactorCursor[k],
2896								v->DPPPerPlane[k]
2897										* (v->final_flip_bw[k]
2898												+ v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
2899												+ v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
2900										+ v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
2901				v->total_dcn_read_bw_with_flip_no_urgent_burst = v->total_dcn_read_bw_with_flip_no_urgent_burst
2902						+ dml_max3(
2903								v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2904								v->DPPPerPlane[k] * v->final_flip_bw[k] + v->ReadBandwidthPlaneLuma[k]
2905										+ v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k],
2906								v->DPPPerPlane[k]
2907										* (v->final_flip_bw[k] + v->RequiredPrefetchPixDataBWLuma[k]
2908												+ v->RequiredPrefetchPixDataBWChroma[k]) + v->cursor_bw_pre[k]);
2909			}
2910			v->FractionOfUrgentBandwidthImmediateFlip = v->total_dcn_read_bw_with_flip_no_urgent_burst / v->ReturnBW;
2911
2912			v->ImmediateFlipSupported = true;
2913			if (v->total_dcn_read_bw_with_flip > v->ReturnBW) {
2914#ifdef __DML_VBA_DEBUG__
2915				dml_print("DML::%s: total_dcn_read_bw_with_flip %f (bw w/ flip too high!)\n", __func__, v->total_dcn_read_bw_with_flip);
2916#endif
2917				v->ImmediateFlipSupported = false;
2918				v->total_dcn_read_bw_with_flip = MaxTotalRDBandwidth;
2919			}
2920			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2921				if (v->ImmediateFlipSupportedForPipe[k] == false) {
2922#ifdef __DML_VBA_DEBUG__
2923					dml_print("DML::%s: Pipe %0d not supporting iflip\n", __func__, k);
2924#endif
2925					v->ImmediateFlipSupported = false;
2926				}
2927			}
2928		} else {
2929			v->ImmediateFlipSupported = false;
2930		}
2931
2932		v->PrefetchAndImmediateFlipSupported =
2933				(v->PrefetchModeSupported == true && ((!v->ImmediateFlipSupport && !v->HostVMEnable
2934				&& v->ImmediateFlipRequirement[0] != dm_immediate_flip_required) ||
2935				v->ImmediateFlipSupported)) ? true : false;
2936#ifdef __DML_VBA_DEBUG__
2937		dml_print("DML::%s: PrefetchModeSupported %d\n", __func__, v->PrefetchModeSupported);
2938		dml_print("DML::%s: ImmediateFlipRequirement %d\n", __func__, v->ImmediateFlipRequirement == dm_immediate_flip_required);
2939		dml_print("DML::%s: ImmediateFlipSupported %d\n", __func__, v->ImmediateFlipSupported);
2940		dml_print("DML::%s: ImmediateFlipSupport %d\n", __func__, v->ImmediateFlipSupport);
2941		dml_print("DML::%s: HostVMEnable %d\n", __func__, v->HostVMEnable);
2942		dml_print("DML::%s: PrefetchAndImmediateFlipSupported %d\n", __func__, v->PrefetchAndImmediateFlipSupported);
2943#endif
2944		dml_print("DML::%s: Done loop: Vstartup=%d, Max Vstartup is %d\n", __func__, v->VStartupLines, v->MaximumMaxVStartupLines);
2945
2946		v->VStartupLines = v->VStartupLines + 1;
2947	} while (!v->PrefetchAndImmediateFlipSupported && v->VStartupLines <= v->MaximumMaxVStartupLines);
2948	ASSERT(v->PrefetchAndImmediateFlipSupported);
2949
2950	// Unbounded Request Enabled
2951	CalculateUnboundedRequestAndCompressedBufferSize(
2952			v->DETBufferSizeInKByte[0],
2953			v->ConfigReturnBufferSizeInKByte,
2954			v->UseUnboundedRequesting,
2955			v->TotalActiveDPP,
2956			NoChromaPlanes,
2957			v->MaxNumDPP,
2958			v->CompressedBufferSegmentSizeInkByte,
2959			v->Output,
2960			&v->UnboundedRequestEnabled,
2961			&v->CompressedBufferSizeInkByte);
2962
2963	//Watermarks and NB P-State/DRAM Clock Change Support
2964	{
2965		enum clock_change_support DRAMClockChangeSupport; // dummy
2966
2967		CalculateWatermarksAndDRAMSpeedChangeSupport(
2968				mode_lib,
2969				PrefetchMode,
2970				v->DCFCLK,
2971				v->ReturnBW,
2972				v->UrgentLatency,
2973				v->UrgentExtraLatency,
2974				v->SOCCLK,
2975				v->DCFCLKDeepSleep,
2976				v->DETBufferSizeY,
2977				v->DETBufferSizeC,
2978				v->SwathHeightY,
2979				v->SwathHeightC,
2980				v->SwathWidthY,
2981				v->SwathWidthC,
2982				v->DPPPerPlane,
2983				v->BytePerPixelDETY,
2984				v->BytePerPixelDETC,
2985				v->UnboundedRequestEnabled,
2986				v->CompressedBufferSizeInkByte,
2987				&DRAMClockChangeSupport,
2988				&v->StutterExitWatermark,
2989				&v->StutterEnterPlusExitWatermark,
2990				&v->Z8StutterExitWatermark,
2991				&v->Z8StutterEnterPlusExitWatermark);
2992
2993		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2994			if (v->WritebackEnable[k] == true) {
2995				v->WritebackAllowDRAMClockChangeEndPosition[k] = dml_max(
2996						0,
2997						v->VStartup[k] * v->HTotal[k] / v->PixelClock[k] - v->WritebackDRAMClockChangeWatermark);
2998			} else {
2999				v->WritebackAllowDRAMClockChangeEndPosition[k] = 0;
3000			}
3001		}
3002	}
3003
3004	//Display Pipeline Delivery Time in Prefetch, Groups
3005	CalculatePixelDeliveryTimes(
3006			v->NumberOfActivePlanes,
3007			v->VRatio,
3008			v->VRatioChroma,
3009			v->VRatioPrefetchY,
3010			v->VRatioPrefetchC,
3011			v->swath_width_luma_ub,
3012			v->swath_width_chroma_ub,
3013			v->DPPPerPlane,
3014			v->HRatio,
3015			v->HRatioChroma,
3016			v->PixelClock,
3017			v->PSCL_THROUGHPUT_LUMA,
3018			v->PSCL_THROUGHPUT_CHROMA,
3019			v->DPPCLK,
3020			v->BytePerPixelC,
3021			v->SourceScan,
3022			v->NumberOfCursors,
3023			v->CursorWidth,
3024			v->CursorBPP,
3025			v->BlockWidth256BytesY,
3026			v->BlockHeight256BytesY,
3027			v->BlockWidth256BytesC,
3028			v->BlockHeight256BytesC,
3029			v->DisplayPipeLineDeliveryTimeLuma,
3030			v->DisplayPipeLineDeliveryTimeChroma,
3031			v->DisplayPipeLineDeliveryTimeLumaPrefetch,
3032			v->DisplayPipeLineDeliveryTimeChromaPrefetch,
3033			v->DisplayPipeRequestDeliveryTimeLuma,
3034			v->DisplayPipeRequestDeliveryTimeChroma,
3035			v->DisplayPipeRequestDeliveryTimeLumaPrefetch,
3036			v->DisplayPipeRequestDeliveryTimeChromaPrefetch,
3037			v->CursorRequestDeliveryTime,
3038			v->CursorRequestDeliveryTimePrefetch);
3039
3040	CalculateMetaAndPTETimes(
3041			v->NumberOfActivePlanes,
3042			v->GPUVMEnable,
3043			v->MetaChunkSize,
3044			v->MinMetaChunkSizeBytes,
3045			v->HTotal,
3046			v->VRatio,
3047			v->VRatioChroma,
3048			v->DestinationLinesToRequestRowInVBlank,
3049			v->DestinationLinesToRequestRowInImmediateFlip,
3050			v->DCCEnable,
3051			v->PixelClock,
3052			v->BytePerPixelY,
3053			v->BytePerPixelC,
3054			v->SourceScan,
3055			v->dpte_row_height,
3056			v->dpte_row_height_chroma,
3057			v->meta_row_width,
3058			v->meta_row_width_chroma,
3059			v->meta_row_height,
3060			v->meta_row_height_chroma,
3061			v->meta_req_width,
3062			v->meta_req_width_chroma,
3063			v->meta_req_height,
3064			v->meta_req_height_chroma,
3065			v->dpte_group_bytes,
3066			v->PTERequestSizeY,
3067			v->PTERequestSizeC,
3068			v->PixelPTEReqWidthY,
3069			v->PixelPTEReqHeightY,
3070			v->PixelPTEReqWidthC,
3071			v->PixelPTEReqHeightC,
3072			v->dpte_row_width_luma_ub,
3073			v->dpte_row_width_chroma_ub,
3074			v->DST_Y_PER_PTE_ROW_NOM_L,
3075			v->DST_Y_PER_PTE_ROW_NOM_C,
3076			v->DST_Y_PER_META_ROW_NOM_L,
3077			v->DST_Y_PER_META_ROW_NOM_C,
3078			v->TimePerMetaChunkNominal,
3079			v->TimePerChromaMetaChunkNominal,
3080			v->TimePerMetaChunkVBlank,
3081			v->TimePerChromaMetaChunkVBlank,
3082			v->TimePerMetaChunkFlip,
3083			v->TimePerChromaMetaChunkFlip,
3084			v->time_per_pte_group_nom_luma,
3085			v->time_per_pte_group_vblank_luma,
3086			v->time_per_pte_group_flip_luma,
3087			v->time_per_pte_group_nom_chroma,
3088			v->time_per_pte_group_vblank_chroma,
3089			v->time_per_pte_group_flip_chroma);
3090
3091	CalculateVMGroupAndRequestTimes(
3092			v->NumberOfActivePlanes,
3093			v->GPUVMEnable,
3094			v->GPUVMMaxPageTableLevels,
3095			v->HTotal,
3096			v->BytePerPixelC,
3097			v->DestinationLinesToRequestVMInVBlank,
3098			v->DestinationLinesToRequestVMInImmediateFlip,
3099			v->DCCEnable,
3100			v->PixelClock,
3101			v->dpte_row_width_luma_ub,
3102			v->dpte_row_width_chroma_ub,
3103			v->vm_group_bytes,
3104			v->dpde0_bytes_per_frame_ub_l,
3105			v->dpde0_bytes_per_frame_ub_c,
3106			v->meta_pte_bytes_per_frame_ub_l,
3107			v->meta_pte_bytes_per_frame_ub_c,
3108			v->TimePerVMGroupVBlank,
3109			v->TimePerVMGroupFlip,
3110			v->TimePerVMRequestVBlank,
3111			v->TimePerVMRequestFlip);
3112
3113	// Min TTUVBlank
3114	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3115		if (PrefetchMode == 0) {
3116			v->AllowDRAMClockChangeDuringVBlank[k] = true;
3117			v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
3118			v->MinTTUVBlank[k] = dml_max(
3119					v->DRAMClockChangeWatermark,
3120					dml_max(v->StutterEnterPlusExitWatermark, v->UrgentWatermark));
3121		} else if (PrefetchMode == 1) {
3122			v->AllowDRAMClockChangeDuringVBlank[k] = false;
3123			v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
3124			v->MinTTUVBlank[k] = dml_max(v->StutterEnterPlusExitWatermark, v->UrgentWatermark);
3125		} else {
3126			v->AllowDRAMClockChangeDuringVBlank[k] = false;
3127			v->AllowDRAMSelfRefreshDuringVBlank[k] = false;
3128			v->MinTTUVBlank[k] = v->UrgentWatermark;
3129		}
3130		if (!v->DynamicMetadataEnable[k])
3131			v->MinTTUVBlank[k] = v->TCalc + v->MinTTUVBlank[k];
3132	}
3133
3134	// DCC Configuration
3135	v->ActiveDPPs = 0;
3136	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3137		CalculateDCCConfiguration(v->DCCEnable[k], false, // We should always know the direction DCCProgrammingAssumesScanDirectionUnknown,
3138				v->SourcePixelFormat[k],
3139				v->SurfaceWidthY[k],
3140				v->SurfaceWidthC[k],
3141				v->SurfaceHeightY[k],
3142				v->SurfaceHeightC[k],
3143				v->DETBufferSizeInKByte[0] * 1024,
3144				v->BlockHeight256BytesY[k],
3145				v->BlockHeight256BytesC[k],
3146				v->SurfaceTiling[k],
3147				v->BytePerPixelY[k],
3148				v->BytePerPixelC[k],
3149				v->BytePerPixelDETY[k],
3150				v->BytePerPixelDETC[k],
3151				v->SourceScan[k],
3152				&v->DCCYMaxUncompressedBlock[k],
3153				&v->DCCCMaxUncompressedBlock[k],
3154				&v->DCCYMaxCompressedBlock[k],
3155				&v->DCCCMaxCompressedBlock[k],
3156				&v->DCCYIndependentBlock[k],
3157				&v->DCCCIndependentBlock[k]);
3158	}
3159
3160	// VStartup Adjustment
3161	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3162		bool isInterlaceTiming;
3163		double Tvstartup_margin = (v->MaxVStartupLines[k] - v->VStartup[k]) * v->HTotal[k] / v->PixelClock[k];
3164#ifdef __DML_VBA_DEBUG__
3165		dml_print("DML::%s: k=%d, MinTTUVBlank = %f (before margin)\n", __func__, k, v->MinTTUVBlank[k]);
3166#endif
3167
3168		v->MinTTUVBlank[k] = v->MinTTUVBlank[k] + Tvstartup_margin;
3169
3170#ifdef __DML_VBA_DEBUG__
3171		dml_print("DML::%s: k=%d, Tvstartup_margin = %f\n", __func__, k, Tvstartup_margin);
3172		dml_print("DML::%s: k=%d, MaxVStartupLines = %d\n", __func__, k, v->MaxVStartupLines[k]);
3173		dml_print("DML::%s: k=%d, VStartup = %d\n", __func__, k, v->VStartup[k]);
3174		dml_print("DML::%s: k=%d, MinTTUVBlank = %f\n", __func__, k, v->MinTTUVBlank[k]);
3175#endif
3176
3177		v->Tdmdl[k] = v->Tdmdl[k] + Tvstartup_margin;
3178		if (v->DynamicMetadataEnable[k] && v->DynamicMetadataVMEnabled) {
3179			v->Tdmdl_vm[k] = v->Tdmdl_vm[k] + Tvstartup_margin;
3180		}
3181
3182		isInterlaceTiming = (v->Interlace[k] && !v->ProgressiveToInterlaceUnitInOPP);
3183		v->VStartup[k] = (isInterlaceTiming ? (2 * v->MaxVStartupLines[k]) : v->MaxVStartupLines[k]);
3184		if (v->Interlace[k] && !v->ProgressiveToInterlaceUnitInOPP) {
3185			v->MIN_DST_Y_NEXT_START[k] = dml_floor((v->VTotal[k] - v->VFrontPorch[k] + v->VTotal[k] - v->VActive[k] - v->VStartup[k]) / 2.0, 1.0);
3186		} else {
3187			v->MIN_DST_Y_NEXT_START[k] = v->VTotal[k] - v->VFrontPorch[k] + v->VTotal[k] - v->VActive[k] - v->VStartup[k];
3188		}
3189		v->MIN_DST_Y_NEXT_START[k] += dml_floor(4.0 * v->TSetup[k] / ((double)v->HTotal[k] / v->PixelClock[k]), 1.0) / 4.0;
3190		if (((v->VUpdateOffsetPix[k] + v->VUpdateWidthPix[k] + v->VReadyOffsetPix[k]) / v->HTotal[k])
3191				<= (isInterlaceTiming ?
3192						dml_floor((v->VTotal[k] - v->VActive[k] - v->VFrontPorch[k] - v->VStartup[k]) / 2.0, 1.0) :
3193						(int) (v->VTotal[k] - v->VActive[k] - v->VFrontPorch[k] - v->VStartup[k]))) {
3194			v->VREADY_AT_OR_AFTER_VSYNC[k] = true;
3195		} else {
3196			v->VREADY_AT_OR_AFTER_VSYNC[k] = false;
3197		}
3198#ifdef __DML_VBA_DEBUG__
3199		dml_print("DML::%s: k=%d, VStartup = %d (max)\n", __func__, k, v->VStartup[k]);
3200		dml_print("DML::%s: k=%d, VUpdateOffsetPix = %d\n", __func__, k, v->VUpdateOffsetPix[k]);
3201		dml_print("DML::%s: k=%d, VUpdateWidthPix = %d\n", __func__, k, v->VUpdateWidthPix[k]);
3202		dml_print("DML::%s: k=%d, VReadyOffsetPix = %d\n", __func__, k, v->VReadyOffsetPix[k]);
3203		dml_print("DML::%s: k=%d, HTotal = %d\n", __func__, k, v->HTotal[k]);
3204		dml_print("DML::%s: k=%d, VTotal = %d\n", __func__, k, v->VTotal[k]);
3205		dml_print("DML::%s: k=%d, VActive = %d\n", __func__, k, v->VActive[k]);
3206		dml_print("DML::%s: k=%d, VFrontPorch = %d\n", __func__, k, v->VFrontPorch[k]);
3207		dml_print("DML::%s: k=%d, VStartup = %d\n", __func__, k, v->VStartup[k]);
3208		dml_print("DML::%s: k=%d, MIN_DST_Y_NEXT_START = %f\n", __func__, k, v->MIN_DST_Y_NEXT_START[k]);
3209		dml_print("DML::%s: k=%d, VREADY_AT_OR_AFTER_VSYNC = %d\n", __func__, k, v->VREADY_AT_OR_AFTER_VSYNC[k]);
3210#endif
3211	}
3212
3213	{
3214		//Maximum Bandwidth Used
3215		double TotalWRBandwidth = 0;
3216		double MaxPerPlaneVActiveWRBandwidth = 0;
3217		double WRBandwidth = 0;
3218
3219		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3220			if (v->WritebackEnable[k] == true && v->WritebackPixelFormat[k] == dm_444_32) {
3221				WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3222						/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 4;
3223			} else if (v->WritebackEnable[k] == true) {
3224				WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3225						/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 8;
3226			}
3227			TotalWRBandwidth = TotalWRBandwidth + WRBandwidth;
3228			MaxPerPlaneVActiveWRBandwidth = dml_max(MaxPerPlaneVActiveWRBandwidth, WRBandwidth);
3229		}
3230
3231		v->TotalDataReadBandwidth = 0;
3232		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3233			v->TotalDataReadBandwidth = v->TotalDataReadBandwidth + v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k];
3234		}
3235	}
3236	// Stutter Efficiency
3237	CalculateStutterEfficiency(
3238			mode_lib,
3239			v->CompressedBufferSizeInkByte,
3240			v->UnboundedRequestEnabled,
3241			v->ConfigReturnBufferSizeInKByte,
3242			v->MetaFIFOSizeInKEntries,
3243			v->ZeroSizeBufferEntries,
3244			v->NumberOfActivePlanes,
3245			v->ROBBufferSizeInKByte,
3246			v->TotalDataReadBandwidth,
3247			v->DCFCLK,
3248			v->ReturnBW,
3249			v->COMPBUF_RESERVED_SPACE_64B,
3250			v->COMPBUF_RESERVED_SPACE_ZS,
3251			v->SRExitTime,
3252			v->SRExitZ8Time,
3253			v->SynchronizedVBlank,
3254			v->StutterEnterPlusExitWatermark,
3255			v->Z8StutterEnterPlusExitWatermark,
3256			v->ProgressiveToInterlaceUnitInOPP,
3257			v->Interlace,
3258			v->MinTTUVBlank,
3259			v->DPPPerPlane,
3260			v->DETBufferSizeY,
3261			v->BytePerPixelY,
3262			v->BytePerPixelDETY,
3263			v->SwathWidthY,
3264			v->SwathHeightY,
3265			v->SwathHeightC,
3266			v->DCCRateLuma,
3267			v->DCCRateChroma,
3268			v->DCCFractionOfZeroSizeRequestsLuma,
3269			v->DCCFractionOfZeroSizeRequestsChroma,
3270			v->HTotal,
3271			v->VTotal,
3272			v->PixelClock,
3273			v->VRatio,
3274			v->SourceScan,
3275			v->BlockHeight256BytesY,
3276			v->BlockWidth256BytesY,
3277			v->BlockHeight256BytesC,
3278			v->BlockWidth256BytesC,
3279			v->DCCYMaxUncompressedBlock,
3280			v->DCCCMaxUncompressedBlock,
3281			v->VActive,
3282			v->DCCEnable,
3283			v->WritebackEnable,
3284			v->ReadBandwidthPlaneLuma,
3285			v->ReadBandwidthPlaneChroma,
3286			v->meta_row_bw,
3287			v->dpte_row_bw,
3288			&v->StutterEfficiencyNotIncludingVBlank,
3289			&v->StutterEfficiency,
3290			&v->NumberOfStutterBurstsPerFrame,
3291			&v->Z8StutterEfficiencyNotIncludingVBlank,
3292			&v->Z8StutterEfficiency,
3293			&v->Z8NumberOfStutterBurstsPerFrame,
3294			&v->StutterPeriod);
3295}
3296
3297static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
3298{
3299	struct vba_vars_st *v = &mode_lib->vba;
3300	// Display Pipe Configuration
3301	double BytePerPixDETY[DC__NUM_DPP__MAX];
3302	double BytePerPixDETC[DC__NUM_DPP__MAX];
3303	int BytePerPixY[DC__NUM_DPP__MAX];
3304	int BytePerPixC[DC__NUM_DPP__MAX];
3305	int Read256BytesBlockHeightY[DC__NUM_DPP__MAX];
3306	int Read256BytesBlockHeightC[DC__NUM_DPP__MAX];
3307	int Read256BytesBlockWidthY[DC__NUM_DPP__MAX];
3308	int Read256BytesBlockWidthC[DC__NUM_DPP__MAX];
3309	double dummy1[DC__NUM_DPP__MAX];
3310	double dummy2[DC__NUM_DPP__MAX];
3311	double dummy3[DC__NUM_DPP__MAX];
3312	double dummy4[DC__NUM_DPP__MAX];
3313	int dummy5[DC__NUM_DPP__MAX];
3314	int dummy6[DC__NUM_DPP__MAX];
3315	bool dummy7[DC__NUM_DPP__MAX];
3316	bool dummysinglestring;
3317
3318	unsigned int k;
3319
3320	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3321
3322		CalculateBytePerPixelAnd256BBlockSizes(
3323				v->SourcePixelFormat[k],
3324				v->SurfaceTiling[k],
3325				&BytePerPixY[k],
3326				&BytePerPixC[k],
3327				&BytePerPixDETY[k],
3328				&BytePerPixDETC[k],
3329				&Read256BytesBlockHeightY[k],
3330				&Read256BytesBlockHeightC[k],
3331				&Read256BytesBlockWidthY[k],
3332				&Read256BytesBlockWidthC[k]);
3333	}
3334
3335	CalculateSwathAndDETConfiguration(
3336			false,
3337			v->NumberOfActivePlanes,
3338			v->DETBufferSizeInKByte[0],
3339			dummy1,
3340			dummy2,
3341			v->SourceScan,
3342			v->SourcePixelFormat,
3343			v->SurfaceTiling,
3344			v->ViewportWidth,
3345			v->ViewportHeight,
3346			v->SurfaceWidthY,
3347			v->SurfaceWidthC,
3348			v->SurfaceHeightY,
3349			v->SurfaceHeightC,
3350			Read256BytesBlockHeightY,
3351			Read256BytesBlockHeightC,
3352			Read256BytesBlockWidthY,
3353			Read256BytesBlockWidthC,
3354			v->ODMCombineEnabled,
3355			v->BlendingAndTiming,
3356			BytePerPixY,
3357			BytePerPixC,
3358			BytePerPixDETY,
3359			BytePerPixDETC,
3360			v->HActive,
3361			v->HRatio,
3362			v->HRatioChroma,
3363			v->DPPPerPlane,
3364			dummy5,
3365			dummy6,
3366			dummy3,
3367			dummy4,
3368			v->SwathHeightY,
3369			v->SwathHeightC,
3370			v->DETBufferSizeY,
3371			v->DETBufferSizeC,
3372			dummy7,
3373			&dummysinglestring);
3374}
3375
3376static bool CalculateBytePerPixelAnd256BBlockSizes(
3377		enum source_format_class SourcePixelFormat,
3378		enum dm_swizzle_mode SurfaceTiling,
3379		unsigned int *BytePerPixelY,
3380		unsigned int *BytePerPixelC,
3381		double *BytePerPixelDETY,
3382		double *BytePerPixelDETC,
3383		unsigned int *BlockHeight256BytesY,
3384		unsigned int *BlockHeight256BytesC,
3385		unsigned int *BlockWidth256BytesY,
3386		unsigned int *BlockWidth256BytesC)
3387{
3388	if (SourcePixelFormat == dm_444_64) {
3389		*BytePerPixelDETY = 8;
3390		*BytePerPixelDETC = 0;
3391		*BytePerPixelY = 8;
3392		*BytePerPixelC = 0;
3393	} else if (SourcePixelFormat == dm_444_32 || SourcePixelFormat == dm_rgbe) {
3394		*BytePerPixelDETY = 4;
3395		*BytePerPixelDETC = 0;
3396		*BytePerPixelY = 4;
3397		*BytePerPixelC = 0;
3398	} else if (SourcePixelFormat == dm_444_16) {
3399		*BytePerPixelDETY = 2;
3400		*BytePerPixelDETC = 0;
3401		*BytePerPixelY = 2;
3402		*BytePerPixelC = 0;
3403	} else if (SourcePixelFormat == dm_444_8) {
3404		*BytePerPixelDETY = 1;
3405		*BytePerPixelDETC = 0;
3406		*BytePerPixelY = 1;
3407		*BytePerPixelC = 0;
3408	} else if (SourcePixelFormat == dm_rgbe_alpha) {
3409		*BytePerPixelDETY = 4;
3410		*BytePerPixelDETC = 1;
3411		*BytePerPixelY = 4;
3412		*BytePerPixelC = 1;
3413	} else if (SourcePixelFormat == dm_420_8) {
3414		*BytePerPixelDETY = 1;
3415		*BytePerPixelDETC = 2;
3416		*BytePerPixelY = 1;
3417		*BytePerPixelC = 2;
3418	} else if (SourcePixelFormat == dm_420_12) {
3419		*BytePerPixelDETY = 2;
3420		*BytePerPixelDETC = 4;
3421		*BytePerPixelY = 2;
3422		*BytePerPixelC = 4;
3423	} else {
3424		*BytePerPixelDETY = 4.0 / 3;
3425		*BytePerPixelDETC = 8.0 / 3;
3426		*BytePerPixelY = 2;
3427		*BytePerPixelC = 4;
3428	}
3429
3430	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32 || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8 || SourcePixelFormat == dm_mono_16
3431			|| SourcePixelFormat == dm_mono_8 || SourcePixelFormat == dm_rgbe)) {
3432		if (SurfaceTiling == dm_sw_linear) {
3433			*BlockHeight256BytesY = 1;
3434		} else if (SourcePixelFormat == dm_444_64) {
3435			*BlockHeight256BytesY = 4;
3436		} else if (SourcePixelFormat == dm_444_8) {
3437			*BlockHeight256BytesY = 16;
3438		} else {
3439			*BlockHeight256BytesY = 8;
3440		}
3441		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
3442		*BlockHeight256BytesC = 0;
3443		*BlockWidth256BytesC = 0;
3444	} else {
3445		if (SurfaceTiling == dm_sw_linear) {
3446			*BlockHeight256BytesY = 1;
3447			*BlockHeight256BytesC = 1;
3448		} else if (SourcePixelFormat == dm_rgbe_alpha) {
3449			*BlockHeight256BytesY = 8;
3450			*BlockHeight256BytesC = 16;
3451		} else if (SourcePixelFormat == dm_420_8) {
3452			*BlockHeight256BytesY = 16;
3453			*BlockHeight256BytesC = 8;
3454		} else {
3455			*BlockHeight256BytesY = 8;
3456			*BlockHeight256BytesC = 8;
3457		}
3458		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
3459		*BlockWidth256BytesC = 256U / *BytePerPixelC / *BlockHeight256BytesC;
3460	}
3461	return true;
3462}
3463
3464static double CalculateTWait(unsigned int PrefetchMode, double DRAMClockChangeLatency, double UrgentLatency, double SREnterPlusExitTime)
3465{
3466	if (PrefetchMode == 0) {
3467		return dml_max(DRAMClockChangeLatency + UrgentLatency, dml_max(SREnterPlusExitTime, UrgentLatency));
3468	} else if (PrefetchMode == 1) {
3469		return dml_max(SREnterPlusExitTime, UrgentLatency);
3470	} else {
3471		return UrgentLatency;
3472	}
3473}
3474
3475double dml314_CalculateWriteBackDISPCLK(
3476		enum source_format_class WritebackPixelFormat,
3477		double PixelClock,
3478		double WritebackHRatio,
3479		double WritebackVRatio,
3480		unsigned int WritebackHTaps,
3481		unsigned int WritebackVTaps,
3482		long WritebackSourceWidth,
3483		long WritebackDestinationWidth,
3484		unsigned int HTotal,
3485		unsigned int WritebackLineBufferSize)
3486{
3487	double DISPCLK_H, DISPCLK_V, DISPCLK_HB;
3488
3489	DISPCLK_H = PixelClock * dml_ceil(WritebackHTaps / 8.0, 1) / WritebackHRatio;
3490	DISPCLK_V = PixelClock * (WritebackVTaps * dml_ceil(WritebackDestinationWidth / 6.0, 1) + 8.0) / HTotal;
3491	DISPCLK_HB = PixelClock * WritebackVTaps * (WritebackDestinationWidth * WritebackVTaps - WritebackLineBufferSize / 57.0) / 6.0 / WritebackSourceWidth;
3492	return dml_max3(DISPCLK_H, DISPCLK_V, DISPCLK_HB);
3493}
3494
3495static double CalculateWriteBackDelay(
3496		enum source_format_class WritebackPixelFormat,
3497		double WritebackHRatio,
3498		double WritebackVRatio,
3499		unsigned int WritebackVTaps,
3500		int WritebackDestinationWidth,
3501		int WritebackDestinationHeight,
3502		int WritebackSourceHeight,
3503		unsigned int HTotal)
3504{
3505	double CalculateWriteBackDelay;
3506	double Line_length;
3507	double Output_lines_last_notclamped;
3508	double WritebackVInit;
3509
3510	WritebackVInit = (WritebackVRatio + WritebackVTaps + 1) / 2;
3511	Line_length = dml_max((double) WritebackDestinationWidth, dml_ceil(WritebackDestinationWidth / 6.0, 1) * WritebackVTaps);
3512	Output_lines_last_notclamped = WritebackDestinationHeight - 1 - dml_ceil((WritebackSourceHeight - WritebackVInit) / WritebackVRatio, 1);
3513	if (Output_lines_last_notclamped < 0) {
3514		CalculateWriteBackDelay = 0;
3515	} else {
3516		CalculateWriteBackDelay = Output_lines_last_notclamped * Line_length + (HTotal - WritebackDestinationWidth) + 80;
3517	}
3518	return CalculateWriteBackDelay;
3519}
3520
3521static void CalculateVupdateAndDynamicMetadataParameters(
3522		int MaxInterDCNTileRepeaters,
3523		double DPPCLK,
3524		double DISPCLK,
3525		double DCFClkDeepSleep,
3526		double PixelClock,
3527		int HTotal,
3528		int VBlank,
3529		int DynamicMetadataTransmittedBytes,
3530		int DynamicMetadataLinesBeforeActiveRequired,
3531		int InterlaceEnable,
3532		bool ProgressiveToInterlaceUnitInOPP,
3533		double *TSetup,
3534		double *Tdmbf,
3535		double *Tdmec,
3536		double *Tdmsks,
3537		int *VUpdateOffsetPix,
3538		double *VUpdateWidthPix,
3539		double *VReadyOffsetPix)
3540{
3541	double TotalRepeaterDelayTime;
3542
3543	TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2 / DPPCLK + 3 / DISPCLK);
3544	*VUpdateWidthPix = dml_ceil((14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime) * PixelClock, 1.0);
3545	*VReadyOffsetPix = dml_ceil(dml_max(150.0 / DPPCLK, TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK) * PixelClock, 1.0);
3546	*VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
3547	*TSetup = (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
3548	*Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
3549	*Tdmec = HTotal / PixelClock;
3550	if (DynamicMetadataLinesBeforeActiveRequired == 0) {
3551		*Tdmsks = VBlank * HTotal / PixelClock / 2.0;
3552	} else {
3553		*Tdmsks = DynamicMetadataLinesBeforeActiveRequired * HTotal / PixelClock;
3554	}
3555	if (InterlaceEnable == 1 && ProgressiveToInterlaceUnitInOPP == false) {
3556		*Tdmsks = *Tdmsks / 2;
3557	}
3558#ifdef __DML_VBA_DEBUG__
3559	dml_print("DML::%s: VUpdateWidthPix = %d\n", __func__, *VUpdateWidthPix);
3560	dml_print("DML::%s: VReadyOffsetPix = %d\n", __func__, *VReadyOffsetPix);
3561	dml_print("DML::%s: VUpdateOffsetPix = %d\n", __func__, *VUpdateOffsetPix);
3562#endif
3563}
3564
3565static void CalculateRowBandwidth(
3566		bool GPUVMEnable,
3567		enum source_format_class SourcePixelFormat,
3568		double VRatio,
3569		double VRatioChroma,
3570		bool DCCEnable,
3571		double LineTime,
3572		unsigned int MetaRowByteLuma,
3573		unsigned int MetaRowByteChroma,
3574		unsigned int meta_row_height_luma,
3575		unsigned int meta_row_height_chroma,
3576		unsigned int PixelPTEBytesPerRowLuma,
3577		unsigned int PixelPTEBytesPerRowChroma,
3578		unsigned int dpte_row_height_luma,
3579		unsigned int dpte_row_height_chroma,
3580		double *meta_row_bw,
3581		double *dpte_row_bw)
3582{
3583	if (DCCEnable != true) {
3584		*meta_row_bw = 0;
3585	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
3586		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime) + VRatioChroma * MetaRowByteChroma / (meta_row_height_chroma * LineTime);
3587	} else {
3588		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
3589	}
3590
3591	if (GPUVMEnable != true) {
3592		*dpte_row_bw = 0;
3593	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
3594		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
3595				+ VRatioChroma * PixelPTEBytesPerRowChroma / (dpte_row_height_chroma * LineTime);
3596	} else {
3597		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
3598	}
3599}
3600
3601static void CalculateFlipSchedule(
3602		struct display_mode_lib *mode_lib,
3603		unsigned int k,
3604		double HostVMInefficiencyFactor,
3605		double UrgentExtraLatency,
3606		double UrgentLatency,
3607		double PDEAndMetaPTEBytesPerFrame,
3608		double MetaRowBytes,
3609		double DPTEBytesPerRow)
3610{
3611	struct vba_vars_st *v = &mode_lib->vba;
3612	double min_row_time = 0.0;
3613	unsigned int HostVMDynamicLevelsTrips;
3614	double TimeForFetchingMetaPTEImmediateFlip;
3615	double TimeForFetchingRowInVBlankImmediateFlip;
3616	double ImmediateFlipBW = 1.0;
3617	double LineTime = v->HTotal[k] / v->PixelClock[k];
3618
3619	if (v->GPUVMEnable == true && v->HostVMEnable == true) {
3620		HostVMDynamicLevelsTrips = v->HostVMMaxNonCachedPageTableLevels;
3621	} else {
3622		HostVMDynamicLevelsTrips = 0;
3623	}
3624
3625	if (v->GPUVMEnable == true || v->DCCEnable[k] == true) {
3626		ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow) * v->BandwidthAvailableForImmediateFlip / v->TotImmediateFlipBytes;
3627	}
3628
3629	if (v->GPUVMEnable == true) {
3630		TimeForFetchingMetaPTEImmediateFlip = dml_max3(
3631				v->Tno_bw[k] + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW,
3632				UrgentExtraLatency + UrgentLatency * (v->GPUVMMaxPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1),
3633				LineTime / 4.0);
3634	} else {
3635		TimeForFetchingMetaPTEImmediateFlip = 0;
3636	}
3637
3638	v->DestinationLinesToRequestVMInImmediateFlip[k] = dml_ceil(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime), 1) / 4.0;
3639	if ((v->GPUVMEnable == true || v->DCCEnable[k] == true)) {
3640		TimeForFetchingRowInVBlankImmediateFlip = dml_max3(
3641				(MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / ImmediateFlipBW,
3642				UrgentLatency * (HostVMDynamicLevelsTrips + 1),
3643				LineTime / 4);
3644	} else {
3645		TimeForFetchingRowInVBlankImmediateFlip = 0;
3646	}
3647
3648	v->DestinationLinesToRequestRowInImmediateFlip[k] = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0;
3649
3650	if (v->GPUVMEnable == true) {
3651		v->final_flip_bw[k] = dml_max(
3652				PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (v->DestinationLinesToRequestVMInImmediateFlip[k] * LineTime),
3653				(MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (v->DestinationLinesToRequestRowInImmediateFlip[k] * LineTime));
3654	} else if ((v->GPUVMEnable == true || v->DCCEnable[k] == true)) {
3655		v->final_flip_bw[k] = (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (v->DestinationLinesToRequestRowInImmediateFlip[k] * LineTime);
3656	} else {
3657		v->final_flip_bw[k] = 0;
3658	}
3659
3660	if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_rgbe_alpha) {
3661		if (v->GPUVMEnable == true && v->DCCEnable[k] != true) {
3662			min_row_time = dml_min(v->dpte_row_height[k] * LineTime / v->VRatio[k], v->dpte_row_height_chroma[k] * LineTime / v->VRatioChroma[k]);
3663		} else if (v->GPUVMEnable != true && v->DCCEnable[k] == true) {
3664			min_row_time = dml_min(v->meta_row_height[k] * LineTime / v->VRatio[k], v->meta_row_height_chroma[k] * LineTime / v->VRatioChroma[k]);
3665		} else {
3666			min_row_time = dml_min4(
3667					v->dpte_row_height[k] * LineTime / v->VRatio[k],
3668					v->meta_row_height[k] * LineTime / v->VRatio[k],
3669					v->dpte_row_height_chroma[k] * LineTime / v->VRatioChroma[k],
3670					v->meta_row_height_chroma[k] * LineTime / v->VRatioChroma[k]);
3671		}
3672	} else {
3673		if (v->GPUVMEnable == true && v->DCCEnable[k] != true) {
3674			min_row_time = v->dpte_row_height[k] * LineTime / v->VRatio[k];
3675		} else if (v->GPUVMEnable != true && v->DCCEnable[k] == true) {
3676			min_row_time = v->meta_row_height[k] * LineTime / v->VRatio[k];
3677		} else {
3678			min_row_time = dml_min(v->dpte_row_height[k] * LineTime / v->VRatio[k], v->meta_row_height[k] * LineTime / v->VRatio[k]);
3679		}
3680	}
3681
3682	if (v->DestinationLinesToRequestVMInImmediateFlip[k] >= 32 || v->DestinationLinesToRequestRowInImmediateFlip[k] >= 16
3683			|| TimeForFetchingMetaPTEImmediateFlip + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) {
3684		v->ImmediateFlipSupportedForPipe[k] = false;
3685	} else {
3686		v->ImmediateFlipSupportedForPipe[k] = true;
3687	}
3688
3689#ifdef __DML_VBA_DEBUG__
3690	dml_print("DML::%s: DestinationLinesToRequestVMInImmediateFlip = %f\n", __func__, v->DestinationLinesToRequestVMInImmediateFlip[k]);
3691	dml_print("DML::%s: DestinationLinesToRequestRowInImmediateFlip = %f\n", __func__, v->DestinationLinesToRequestRowInImmediateFlip[k]);
3692	dml_print("DML::%s: TimeForFetchingMetaPTEImmediateFlip = %f\n", __func__, TimeForFetchingMetaPTEImmediateFlip);
3693	dml_print("DML::%s: TimeForFetchingRowInVBlankImmediateFlip = %f\n", __func__, TimeForFetchingRowInVBlankImmediateFlip);
3694	dml_print("DML::%s: min_row_time = %f\n", __func__, min_row_time);
3695	dml_print("DML::%s: ImmediateFlipSupportedForPipe = %d\n", __func__, v->ImmediateFlipSupportedForPipe[k]);
3696#endif
3697
3698}
3699
3700static double TruncToValidBPP(
3701		double LinkBitRate,
3702		int Lanes,
3703		int HTotal,
3704		int HActive,
3705		double PixelClock,
3706		double DesiredBPP,
3707		bool DSCEnable,
3708		enum output_encoder_class Output,
3709		enum output_format_class Format,
3710		unsigned int DSCInputBitPerComponent,
3711		int DSCSlices,
3712		int AudioRate,
3713		int AudioLayout,
3714		enum odm_combine_mode ODMCombine)
3715{
3716	double MaxLinkBPP;
3717	int MinDSCBPP;
3718	double MaxDSCBPP;
3719	int NonDSCBPP0;
3720	int NonDSCBPP1;
3721	int NonDSCBPP2;
3722
3723	if (Format == dm_420) {
3724		NonDSCBPP0 = 12;
3725		NonDSCBPP1 = 15;
3726		NonDSCBPP2 = 18;
3727		MinDSCBPP = 6;
3728		MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1 / 16;
3729	} else if (Format == dm_444) {
3730		NonDSCBPP0 = 24;
3731		NonDSCBPP1 = 30;
3732		NonDSCBPP2 = 36;
3733		MinDSCBPP = 8;
3734		MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
3735	} else {
3736
3737		NonDSCBPP0 = 16;
3738		NonDSCBPP1 = 20;
3739		NonDSCBPP2 = 24;
3740
3741		if (Format == dm_n422) {
3742			MinDSCBPP = 7;
3743			MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
3744		} else {
3745			MinDSCBPP = 8;
3746			MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
3747		}
3748	}
3749
3750	if (DSCEnable && Output == dm_dp) {
3751		MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
3752	} else {
3753		MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock;
3754	}
3755
3756	if (ODMCombine == dm_odm_combine_mode_4to1 && MaxLinkBPP > 16) {
3757		MaxLinkBPP = 16;
3758	} else if (ODMCombine == dm_odm_combine_mode_2to1 && MaxLinkBPP > 32) {
3759		MaxLinkBPP = 32;
3760	}
3761
3762	if (DesiredBPP == 0) {
3763		if (DSCEnable) {
3764			if (MaxLinkBPP < MinDSCBPP) {
3765				return BPP_INVALID;
3766			} else if (MaxLinkBPP >= MaxDSCBPP) {
3767				return MaxDSCBPP;
3768			} else {
3769				return dml_floor(16.0 * MaxLinkBPP, 1.0) / 16.0;
3770			}
3771		} else {
3772			if (MaxLinkBPP >= NonDSCBPP2) {
3773				return NonDSCBPP2;
3774			} else if (MaxLinkBPP >= NonDSCBPP1) {
3775				return NonDSCBPP1;
3776			} else if (MaxLinkBPP >= NonDSCBPP0) {
3777				return 16.0;
3778			} else {
3779				return BPP_INVALID;
3780			}
3781		}
3782	} else {
3783		if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP <= NonDSCBPP0))
3784				|| (DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
3785			return BPP_INVALID;
3786		} else {
3787			return DesiredBPP;
3788		}
3789	}
3790	return BPP_INVALID;
3791}
3792
3793static noinline void CalculatePrefetchSchedulePerPlane(
3794		struct display_mode_lib *mode_lib,
3795		double HostVMInefficiencyFactor,
3796		int i,
3797		unsigned int j,
3798		unsigned int k)
3799{
3800	struct vba_vars_st *v = &mode_lib->vba;
3801	Pipe myPipe;
3802
3803	myPipe.DPPCLK = v->RequiredDPPCLK[i][j][k];
3804	myPipe.DISPCLK = v->RequiredDISPCLK[i][j];
3805	myPipe.PixelClock = v->PixelClock[k];
3806	myPipe.DCFCLKDeepSleep = v->ProjectedDCFCLKDeepSleep[i][j];
3807	myPipe.DPPPerPlane = v->NoOfDPP[i][j][k];
3808	myPipe.ScalerEnabled = v->ScalerEnabled[k];
3809	myPipe.VRatio = mode_lib->vba.VRatio[k];
3810	myPipe.VRatioChroma = mode_lib->vba.VRatioChroma[k];
3811
3812	myPipe.SourceScan = v->SourceScan[k];
3813	myPipe.BlockWidth256BytesY = v->Read256BlockWidthY[k];
3814	myPipe.BlockHeight256BytesY = v->Read256BlockHeightY[k];
3815	myPipe.BlockWidth256BytesC = v->Read256BlockWidthC[k];
3816	myPipe.BlockHeight256BytesC = v->Read256BlockHeightC[k];
3817	myPipe.InterlaceEnable = v->Interlace[k];
3818	myPipe.NumberOfCursors = v->NumberOfCursors[k];
3819	myPipe.VBlank = v->VTotal[k] - v->VActive[k];
3820	myPipe.HTotal = v->HTotal[k];
3821	myPipe.DCCEnable = v->DCCEnable[k];
3822	myPipe.ODMCombineIsEnabled = v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1
3823		|| v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1;
3824	myPipe.SourcePixelFormat = v->SourcePixelFormat[k];
3825	myPipe.BytePerPixelY = v->BytePerPixelY[k];
3826	myPipe.BytePerPixelC = v->BytePerPixelC[k];
3827	myPipe.ProgressiveToInterlaceUnitInOPP = v->ProgressiveToInterlaceUnitInOPP;
3828	v->NoTimeForPrefetch[i][j][k] = CalculatePrefetchSchedule(
3829		mode_lib,
3830		HostVMInefficiencyFactor,
3831		&myPipe,
3832		v->DSCDelayPerState[i][k],
3833		v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater,
3834		v->DPPCLKDelaySCL,
3835		v->DPPCLKDelaySCLLBOnly,
3836		v->DPPCLKDelayCNVCCursor,
3837		v->DISPCLKDelaySubtotal,
3838		v->SwathWidthYThisState[k] / v->HRatio[k],
3839		v->OutputFormat[k],
3840		v->MaxInterDCNTileRepeaters,
3841		dml_min(v->MaxVStartup, v->MaximumVStartup[i][j][k]),
3842		v->MaximumVStartup[i][j][k],
3843		v->GPUVMMaxPageTableLevels,
3844		v->GPUVMEnable,
3845		v->HostVMEnable,
3846		v->HostVMMaxNonCachedPageTableLevels,
3847		v->HostVMMinPageSize,
3848		v->DynamicMetadataEnable[k],
3849		v->DynamicMetadataVMEnabled,
3850		v->DynamicMetadataLinesBeforeActiveRequired[k],
3851		v->DynamicMetadataTransmittedBytes[k],
3852		v->UrgLatency[i],
3853		v->ExtraLatency,
3854		v->TimeCalc,
3855		v->PDEAndMetaPTEBytesPerFrame[i][j][k],
3856		v->MetaRowBytes[i][j][k],
3857		v->DPTEBytesPerRow[i][j][k],
3858		v->PrefetchLinesY[i][j][k],
3859		v->SwathWidthYThisState[k],
3860		v->PrefillY[k],
3861		v->MaxNumSwY[k],
3862		v->PrefetchLinesC[i][j][k],
3863		v->SwathWidthCThisState[k],
3864		v->PrefillC[k],
3865		v->MaxNumSwC[k],
3866		v->swath_width_luma_ub_this_state[k],
3867		v->swath_width_chroma_ub_this_state[k],
3868		v->SwathHeightYThisState[k],
3869		v->SwathHeightCThisState[k],
3870		v->TWait,
3871		&v->DSTXAfterScaler[k],
3872		&v->DSTYAfterScaler[k],
3873		&v->LineTimesForPrefetch[k],
3874		&v->PrefetchBW[k],
3875		&v->LinesForMetaPTE[k],
3876		&v->LinesForMetaAndDPTERow[k],
3877		&v->VRatioPreY[i][j][k],
3878		&v->VRatioPreC[i][j][k],
3879		&v->RequiredPrefetchPixelDataBWLuma[i][j][k],
3880		&v->RequiredPrefetchPixelDataBWChroma[i][j][k],
3881		&v->NoTimeForDynamicMetadata[i][j][k],
3882		&v->Tno_bw[k],
3883		&v->prefetch_vmrow_bw[k],
3884		&v->dummy7[k],
3885		&v->dummy8[k],
3886		&v->dummy13[k],
3887		&v->VUpdateOffsetPix[k],
3888		&v->VUpdateWidthPix[k],
3889		&v->VReadyOffsetPix[k]);
3890}
3891
3892void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
3893{
3894	struct vba_vars_st *v = &mode_lib->vba;
3895
3896	int i, j;
3897	unsigned int k, m;
3898	int ReorderingBytes;
3899	int MinPrefetchMode = 0, MaxPrefetchMode = 2;
3900	bool NoChroma = true;
3901	bool EnoughWritebackUnits = true;
3902	bool P2IWith420 = false;
3903	bool DSCOnlyIfNecessaryWithBPP = false;
3904	bool DSC422NativeNotSupported = false;
3905	double MaxTotalVActiveRDBandwidth;
3906	bool ViewportExceedsSurface = false;
3907	bool FMTBufferExceeded = false;
3908
3909	/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
3910
3911	CalculateMinAndMaxPrefetchMode(
3912		mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
3913		&MinPrefetchMode, &MaxPrefetchMode);
3914
3915	/*Scale Ratio, taps Support Check*/
3916
3917	v->ScaleRatioAndTapsSupport = true;
3918	for (k = 0; k < v->NumberOfActivePlanes; k++) {
3919		if (v->ScalerEnabled[k] == false
3920				&& ((v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32
3921						&& v->SourcePixelFormat[k] != dm_444_16 && v->SourcePixelFormat[k] != dm_mono_16
3922						&& v->SourcePixelFormat[k] != dm_mono_8 && v->SourcePixelFormat[k] != dm_rgbe
3923						&& v->SourcePixelFormat[k] != dm_rgbe_alpha) || v->HRatio[k] != 1.0 || v->htaps[k] != 1.0
3924						|| v->VRatio[k] != 1.0 || v->vtaps[k] != 1.0)) {
3925			v->ScaleRatioAndTapsSupport = false;
3926		} else if (v->vtaps[k] < 1.0 || v->vtaps[k] > 8.0 || v->htaps[k] < 1.0 || v->htaps[k] > 8.0
3927				|| (v->htaps[k] > 1.0 && (v->htaps[k] % 2) == 1) || v->HRatio[k] > v->MaxHSCLRatio
3928				|| v->VRatio[k] > v->MaxVSCLRatio || v->HRatio[k] > v->htaps[k]
3929				|| v->VRatio[k] > v->vtaps[k]
3930				|| (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32
3931						&& v->SourcePixelFormat[k] != dm_444_16 && v->SourcePixelFormat[k] != dm_mono_16
3932						&& v->SourcePixelFormat[k] != dm_mono_8 && v->SourcePixelFormat[k] != dm_rgbe
3933						&& (v->VTAPsChroma[k] < 1 || v->VTAPsChroma[k] > 8 || v->HTAPsChroma[k] < 1
3934								|| v->HTAPsChroma[k] > 8 || (v->HTAPsChroma[k] > 1 && v->HTAPsChroma[k] % 2 == 1)
3935								|| v->HRatioChroma[k] > v->MaxHSCLRatio
3936								|| v->VRatioChroma[k] > v->MaxVSCLRatio
3937								|| v->HRatioChroma[k] > v->HTAPsChroma[k]
3938								|| v->VRatioChroma[k] > v->VTAPsChroma[k]))) {
3939			v->ScaleRatioAndTapsSupport = false;
3940		}
3941	}
3942	/*Source Format, Pixel Format and Scan Support Check*/
3943
3944	v->SourceFormatPixelAndScanSupport = true;
3945	for (k = 0; k < v->NumberOfActivePlanes; k++) {
3946		if (v->SurfaceTiling[k] == dm_sw_linear && (!(v->SourceScan[k] != dm_vert) || v->DCCEnable[k] == true)) {
3947			v->SourceFormatPixelAndScanSupport = false;
3948		}
3949	}
3950	/*Bandwidth Support Check*/
3951
3952	for (k = 0; k < v->NumberOfActivePlanes; k++) {
3953		CalculateBytePerPixelAnd256BBlockSizes(
3954				v->SourcePixelFormat[k],
3955				v->SurfaceTiling[k],
3956				&v->BytePerPixelY[k],
3957				&v->BytePerPixelC[k],
3958				&v->BytePerPixelInDETY[k],
3959				&v->BytePerPixelInDETC[k],
3960				&v->Read256BlockHeightY[k],
3961				&v->Read256BlockHeightC[k],
3962				&v->Read256BlockWidthY[k],
3963				&v->Read256BlockWidthC[k]);
3964	}
3965	for (k = 0; k < v->NumberOfActivePlanes; k++) {
3966		if (v->SourceScan[k] != dm_vert) {
3967			v->SwathWidthYSingleDPP[k] = v->ViewportWidth[k];
3968			v->SwathWidthCSingleDPP[k] = v->ViewportWidthChroma[k];
3969		} else {
3970			v->SwathWidthYSingleDPP[k] = v->ViewportHeight[k];
3971			v->SwathWidthCSingleDPP[k] = v->ViewportHeightChroma[k];
3972		}
3973	}
3974	for (k = 0; k < v->NumberOfActivePlanes; k++) {
3975		v->ReadBandwidthLuma[k] = v->SwathWidthYSingleDPP[k] * dml_ceil(v->BytePerPixelInDETY[k], 1.0)
3976				/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
3977		v->ReadBandwidthChroma[k] = v->SwathWidthYSingleDPP[k] / 2 * dml_ceil(v->BytePerPixelInDETC[k], 2.0)
3978				/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k] / 2.0;
3979	}
3980	for (k = 0; k < v->NumberOfActivePlanes; k++) {
3981		if (v->WritebackEnable[k] == true && v->WritebackPixelFormat[k] == dm_444_64) {
3982			v->WriteBandwidth[k] = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3983					/ (v->WritebackSourceHeight[k] * v->HTotal[k] / v->PixelClock[k]) * 8.0;
3984		} else if (v->WritebackEnable[k] == true) {
3985			v->WriteBandwidth[k] = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3986					/ (v->WritebackSourceHeight[k] * v->HTotal[k] / v->PixelClock[k]) * 4.0;
3987		} else {
3988			v->WriteBandwidth[k] = 0.0;
3989		}
3990	}
3991
3992	/*Writeback Latency support check*/
3993
3994	v->WritebackLatencySupport = true;
3995	for (k = 0; k < v->NumberOfActivePlanes; k++) {
3996		if (v->WritebackEnable[k] == true && (v->WriteBandwidth[k] > v->WritebackInterfaceBufferSize * 1024 / v->WritebackLatency)) {
3997			v->WritebackLatencySupport = false;
3998		}
3999	}
4000
4001	/*Writeback Mode Support Check*/
4002
4003	v->TotalNumberOfActiveWriteback = 0;
4004	for (k = 0; k < v->NumberOfActivePlanes; k++) {
4005		if (v->WritebackEnable[k] == true) {
4006			v->TotalNumberOfActiveWriteback = v->TotalNumberOfActiveWriteback + 1;
4007		}
4008	}
4009
4010	if (v->TotalNumberOfActiveWriteback > v->MaxNumWriteback) {
4011		EnoughWritebackUnits = false;
4012	}
4013
4014	/*Writeback Scale Ratio and Taps Support Check*/
4015
4016	v->WritebackScaleRatioAndTapsSupport = true;
4017	for (k = 0; k < v->NumberOfActivePlanes; k++) {
4018		if (v->WritebackEnable[k] == true) {
4019			if (v->WritebackHRatio[k] > v->WritebackMaxHSCLRatio || v->WritebackVRatio[k] > v->WritebackMaxVSCLRatio
4020					|| v->WritebackHRatio[k] < v->WritebackMinHSCLRatio
4021					|| v->WritebackVRatio[k] < v->WritebackMinVSCLRatio
4022					|| v->WritebackHTaps[k] > v->WritebackMaxHSCLTaps
4023					|| v->WritebackVTaps[k] > v->WritebackMaxVSCLTaps
4024					|| v->WritebackHRatio[k] > v->WritebackHTaps[k] || v->WritebackVRatio[k] > v->WritebackVTaps[k]
4025					|| (v->WritebackHTaps[k] > 2.0 && ((v->WritebackHTaps[k] % 2) == 1))) {
4026				v->WritebackScaleRatioAndTapsSupport = false;
4027			}
4028			if (2.0 * v->WritebackDestinationWidth[k] * (v->WritebackVTaps[k] - 1) * 57 > v->WritebackLineBufferSize) {
4029				v->WritebackScaleRatioAndTapsSupport = false;
4030			}
4031		}
4032	}
4033	/*Maximum DISPCLK/DPPCLK Support check*/
4034
4035	v->WritebackRequiredDISPCLK = 0.0;
4036	for (k = 0; k < v->NumberOfActivePlanes; k++) {
4037		if (v->WritebackEnable[k] == true) {
4038			v->WritebackRequiredDISPCLK = dml_max(
4039					v->WritebackRequiredDISPCLK,
4040					dml314_CalculateWriteBackDISPCLK(
4041							v->WritebackPixelFormat[k],
4042							v->PixelClock[k],
4043							v->WritebackHRatio[k],
4044							v->WritebackVRatio[k],
4045							v->WritebackHTaps[k],
4046							v->WritebackVTaps[k],
4047							v->WritebackSourceWidth[k],
4048							v->WritebackDestinationWidth[k],
4049							v->HTotal[k],
4050							v->WritebackLineBufferSize));
4051		}
4052	}
4053	for (k = 0; k < v->NumberOfActivePlanes; k++) {
4054		if (v->HRatio[k] > 1.0) {
4055			v->PSCL_FACTOR[k] = dml_min(
4056					v->MaxDCHUBToPSCLThroughput,
4057					v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1.0));
4058		} else {
4059			v->PSCL_FACTOR[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
4060		}
4061		if (v->BytePerPixelC[k] == 0.0) {
4062			v->PSCL_FACTOR_CHROMA[k] = 0.0;
4063			v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k]
4064					* dml_max3(
4065							v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
4066							v->HRatio[k] * v->VRatio[k] / v->PSCL_FACTOR[k],
4067							1.0);
4068			if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0) && v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
4069				v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
4070			}
4071		} else {
4072			if (v->HRatioChroma[k] > 1.0) {
4073				v->PSCL_FACTOR_CHROMA[k] = dml_min(
4074						v->MaxDCHUBToPSCLThroughput,
4075						v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
4076			} else {
4077				v->PSCL_FACTOR_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
4078			}
4079			v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k]
4080					* dml_max5(
4081							v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
4082							v->HRatio[k] * v->VRatio[k] / v->PSCL_FACTOR[k],
4083							v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
4084							v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_FACTOR_CHROMA[k],
4085							1.0);
4086			if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0 || v->HTAPsChroma[k] > 6.0 || v->VTAPsChroma[k] > 6.0)
4087					&& v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
4088				v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
4089			}
4090		}
4091	}
4092	for (k = 0; k < v->NumberOfActivePlanes; k++) {
4093		int MaximumSwathWidthSupportLuma;
4094		int MaximumSwathWidthSupportChroma;
4095
4096		if (v->SurfaceTiling[k] == dm_sw_linear) {
4097			MaximumSwathWidthSupportLuma = 8192.0;
4098		} else if (v->SourceScan[k] == dm_vert && v->BytePerPixelC[k] > 0) {
4099			MaximumSwathWidthSupportLuma = 2880.0;
4100		} else if (v->SourcePixelFormat[k] == dm_rgbe_alpha) {
4101			MaximumSwathWidthSupportLuma = 3840.0;
4102		} else {
4103			MaximumSwathWidthSupportLuma = 5760.0;
4104		}
4105
4106		if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) {
4107			MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma / 2.0;
4108		} else {
4109			MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma;
4110		}
4111		v->MaximumSwathWidthInLineBufferLuma = v->LineBufferSize * dml_max(v->HRatio[k], 1.0) / v->LBBitPerPixel[k]
4112				/ (v->vtaps[k] + dml_max(dml_ceil(v->VRatio[k], 1.0) - 2, 0.0));
4113		if (v->BytePerPixelC[k] == 0.0) {
4114			v->MaximumSwathWidthInLineBufferChroma = 0;
4115		} else {
4116			v->MaximumSwathWidthInLineBufferChroma = v->LineBufferSize * dml_max(v->HRatioChroma[k], 1.0) / v->LBBitPerPixel[k]
4117					/ (v->VTAPsChroma[k] + dml_max(dml_ceil(v->VRatioChroma[k], 1.0) - 2, 0.0));
4118		}
4119		v->MaximumSwathWidthLuma[k] = dml_min(MaximumSwathWidthSupportLuma, v->MaximumSwathWidthInLineBufferLuma);
4120		v->MaximumSwathWidthChroma[k] = dml_min(MaximumSwathWidthSupportChroma, v->MaximumSwathWidthInLineBufferChroma);
4121	}
4122
4123	CalculateSwathAndDETConfiguration(
4124			true,
4125			v->NumberOfActivePlanes,
4126			v->DETBufferSizeInKByte[0],
4127			v->MaximumSwathWidthLuma,
4128			v->MaximumSwathWidthChroma,
4129			v->SourceScan,
4130			v->SourcePixelFormat,
4131			v->SurfaceTiling,
4132			v->ViewportWidth,
4133			v->ViewportHeight,
4134			v->SurfaceWidthY,
4135			v->SurfaceWidthC,
4136			v->SurfaceHeightY,
4137			v->SurfaceHeightC,
4138			v->Read256BlockHeightY,
4139			v->Read256BlockHeightC,
4140			v->Read256BlockWidthY,
4141			v->Read256BlockWidthC,
4142			v->odm_combine_dummy,
4143			v->BlendingAndTiming,
4144			v->BytePerPixelY,
4145			v->BytePerPixelC,
4146			v->BytePerPixelInDETY,
4147			v->BytePerPixelInDETC,
4148			v->HActive,
4149			v->HRatio,
4150			v->HRatioChroma,
4151			v->NoOfDPPThisState,
4152			v->swath_width_luma_ub_this_state,
4153			v->swath_width_chroma_ub_this_state,
4154			v->SwathWidthYThisState,
4155			v->SwathWidthCThisState,
4156			v->SwathHeightYThisState,
4157			v->SwathHeightCThisState,
4158			v->DETBufferSizeYThisState,
4159			v->DETBufferSizeCThisState,
4160			v->SingleDPPViewportSizeSupportPerPlane,
4161			&v->ViewportSizeSupport[0][0]);
4162
4163	for (i = 0; i < v->soc.num_states; i++) {
4164		for (j = 0; j < 2; j++) {
4165			v->MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDispclk[i], v->DISPCLKDPPCLKVCOSpeed);
4166			v->MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDppclk[i], v->DISPCLKDPPCLKVCOSpeed);
4167			v->RequiredDISPCLK[i][j] = 0.0;
4168			v->DISPCLK_DPPCLK_Support[i][j] = true;
4169			for (k = 0; k < v->NumberOfActivePlanes; k++) {
4170				v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4171						* (1.0 + v->DISPCLKRampingMargin / 100.0);
4172				if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i]
4173						&& v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4174						&& v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4175					v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k]
4176							* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4177				}
4178				v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4179						* (1 + v->DISPCLKRampingMargin / 100.0);
4180				if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i]
4181						&& v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4182						&& v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4183					v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2
4184							* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4185				}
4186				v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4187						* (1 + v->DISPCLKRampingMargin / 100.0);
4188				if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i]
4189						&& v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4190						&& v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4191					v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4
4192							* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4193				}
4194
4195				if (v->ODMCombinePolicy == dm_odm_combine_policy_none
4196						|| !(v->Output[k] == dm_dp ||
4197						     v->Output[k] == dm_dp2p0 ||
4198						     v->Output[k] == dm_edp)) {
4199					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
4200					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
4201
4202					if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH)
4203						FMTBufferExceeded = true;
4204				} else if (v->ODMCombinePolicy == dm_odm_combine_policy_2to1) {
4205					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4206					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4207				} else if (v->ODMCombinePolicy == dm_odm_combine_policy_4to1
4208						|| v->PlaneRequiredDISPCLKWithODMCombine2To1 > v->MaxDispclkRoundedDownToDFSGranularity) {
4209					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4210					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4211				} else if (v->PlaneRequiredDISPCLKWithoutODMCombine > v->MaxDispclkRoundedDownToDFSGranularity) {
4212					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4213					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4214				} else {
4215					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
4216					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
4217				}
4218				if (v->DSCEnabled[k] && v->HActive[k] > DCN314_MAX_DSC_IMAGE_WIDTH
4219						&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
4220					if (v->HActive[k] / 2 > DCN314_MAX_DSC_IMAGE_WIDTH) {
4221						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4222						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4223					} else {
4224						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4225						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4226					}
4227				}
4228				if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN314_MAX_FMT_420_BUFFER_WIDTH
4229						&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
4230					if (v->Output[k] == dm_hdmi) {
4231						FMTBufferExceeded = true;
4232					} else if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH) {
4233						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4234						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4235
4236						if (v->HActive[k] / 4 > DCN314_MAX_FMT_420_BUFFER_WIDTH)
4237							FMTBufferExceeded = true;
4238					} else {
4239						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4240						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4241					}
4242				}
4243				if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
4244					v->MPCCombine[i][j][k] = false;
4245					v->NoOfDPP[i][j][k] = 4;
4246					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 4;
4247				} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4248					v->MPCCombine[i][j][k] = false;
4249					v->NoOfDPP[i][j][k] = 2;
4250					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2;
4251				} else if ((v->WhenToDoMPCCombine == dm_mpc_never
4252						|| (v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4253								<= v->MaxDppclkRoundedDownToDFSGranularity && v->SingleDPPViewportSizeSupportPerPlane[k] == true))) {
4254					v->MPCCombine[i][j][k] = false;
4255					v->NoOfDPP[i][j][k] = 1;
4256					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4257				} else {
4258					v->MPCCombine[i][j][k] = true;
4259					v->NoOfDPP[i][j][k] = 2;
4260					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
4261				}
4262				v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
4263				if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4264						> v->MaxDppclkRoundedDownToDFSGranularity)
4265						|| (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
4266					v->DISPCLK_DPPCLK_Support[i][j] = false;
4267				}
4268			}
4269			v->TotalNumberOfActiveDPP[i][j] = 0;
4270			v->TotalNumberOfSingleDPPPlanes[i][j] = 0;
4271			for (k = 0; k < v->NumberOfActivePlanes; k++) {
4272				v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4273				if (v->NoOfDPP[i][j][k] == 1)
4274					v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] + 1;
4275				if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10
4276						|| v->SourcePixelFormat[k] == dm_420_12 || v->SourcePixelFormat[k] == dm_rgbe_alpha)
4277					NoChroma = false;
4278			}
4279
4280			// UPTO
4281			if (j == 1 && v->WhenToDoMPCCombine != dm_mpc_never
4282					&& !UnboundedRequest(v->UseUnboundedRequesting, v->TotalNumberOfActiveDPP[i][j], NoChroma, v->Output[0])) {
4283				while (!(v->TotalNumberOfActiveDPP[i][j] >= v->MaxNumDPP || v->TotalNumberOfSingleDPPPlanes[i][j] == 0)) {
4284					double BWOfNonSplitPlaneOfMaximumBandwidth;
4285					unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
4286
4287					BWOfNonSplitPlaneOfMaximumBandwidth = 0;
4288					NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
4289					for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4290						if (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k] > BWOfNonSplitPlaneOfMaximumBandwidth
4291								&& v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled && v->MPCCombine[i][j][k] == false) {
4292							BWOfNonSplitPlaneOfMaximumBandwidth = v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
4293							NumberOfNonSplitPlaneOfMaximumBandwidth = k;
4294						}
4295					}
4296					v->MPCCombine[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = true;
4297					v->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
4298					v->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
4299							v->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
4300									* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
4301					v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + 1;
4302					v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] - 1;
4303				}
4304			}
4305			if (v->TotalNumberOfActiveDPP[i][j] > v->MaxNumDPP) {
4306				v->RequiredDISPCLK[i][j] = 0.0;
4307				v->DISPCLK_DPPCLK_Support[i][j] = true;
4308				for (k = 0; k < v->NumberOfActivePlanes; k++) {
4309					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
4310					if (v->SingleDPPViewportSizeSupportPerPlane[k] == false && v->WhenToDoMPCCombine != dm_mpc_never) {
4311						v->MPCCombine[i][j][k] = true;
4312						v->NoOfDPP[i][j][k] = 2;
4313						v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k]
4314								* (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
4315					} else {
4316						v->MPCCombine[i][j][k] = false;
4317						v->NoOfDPP[i][j][k] = 1;
4318						v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k]
4319								* (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4320					}
4321					if (!(v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4322							&& v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4323						v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4324								* (1.0 + v->DISPCLKRampingMargin / 100.0);
4325					} else {
4326						v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4327					}
4328					v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
4329					if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4330							> v->MaxDppclkRoundedDownToDFSGranularity)
4331							|| (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
4332						v->DISPCLK_DPPCLK_Support[i][j] = false;
4333					}
4334				}
4335				v->TotalNumberOfActiveDPP[i][j] = 0.0;
4336				for (k = 0; k < v->NumberOfActivePlanes; k++) {
4337					v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4338				}
4339			}
4340			v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->WritebackRequiredDISPCLK);
4341			if (v->MaxDispclkRoundedDownToDFSGranularity < v->WritebackRequiredDISPCLK) {
4342				v->DISPCLK_DPPCLK_Support[i][j] = false;
4343			}
4344		}
4345	}
4346
4347	/*Total Available Pipes Support Check*/
4348
4349	for (i = 0; i < v->soc.num_states; i++) {
4350		for (j = 0; j < 2; j++) {
4351			if (v->TotalNumberOfActiveDPP[i][j] <= v->MaxNumDPP) {
4352				v->TotalAvailablePipesSupport[i][j] = true;
4353			} else {
4354				v->TotalAvailablePipesSupport[i][j] = false;
4355			}
4356		}
4357	}
4358	/*Display IO and DSC Support Check*/
4359
4360	v->NonsupportedDSCInputBPC = false;
4361	for (k = 0; k < v->NumberOfActivePlanes; k++) {
4362		if (!(v->DSCInputBitPerComponent[k] == 12.0 || v->DSCInputBitPerComponent[k] == 10.0 || v->DSCInputBitPerComponent[k] == 8.0)
4363				|| v->DSCInputBitPerComponent[k] > v->MaximumDSCBitsPerComponent) {
4364			v->NonsupportedDSCInputBPC = true;
4365		}
4366	}
4367
4368	/*Number Of DSC Slices*/
4369	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4370		if (v->BlendingAndTiming[k] == k) {
4371			if (v->PixelClockBackEnd[k] > 3200) {
4372				v->NumberOfDSCSlices[k] = dml_ceil(v->PixelClockBackEnd[k] / 400.0, 4.0);
4373			} else if (v->PixelClockBackEnd[k] > 1360) {
4374				v->NumberOfDSCSlices[k] = 8;
4375			} else if (v->PixelClockBackEnd[k] > 680) {
4376				v->NumberOfDSCSlices[k] = 4;
4377			} else if (v->PixelClockBackEnd[k] > 340) {
4378				v->NumberOfDSCSlices[k] = 2;
4379			} else {
4380				v->NumberOfDSCSlices[k] = 1;
4381			}
4382		} else {
4383			v->NumberOfDSCSlices[k] = 0;
4384		}
4385	}
4386
4387	for (i = 0; i < v->soc.num_states; i++) {
4388		for (k = 0; k < v->NumberOfActivePlanes; k++) {
4389			v->RequiresDSC[i][k] = false;
4390			v->RequiresFEC[i][k] = false;
4391			if (v->BlendingAndTiming[k] == k) {
4392				if (v->Output[k] == dm_hdmi) {
4393					v->RequiresDSC[i][k] = false;
4394					v->RequiresFEC[i][k] = false;
4395					v->OutputBppPerState[i][k] = TruncToValidBPP(
4396							dml_min(600.0, v->PHYCLKPerState[i]) * 10,
4397							3,
4398							v->HTotal[k],
4399							v->HActive[k],
4400							v->PixelClockBackEnd[k],
4401							v->ForcedOutputLinkBPP[k],
4402							false,
4403							v->Output[k],
4404							v->OutputFormat[k],
4405							v->DSCInputBitPerComponent[k],
4406							v->NumberOfDSCSlices[k],
4407							v->AudioSampleRate[k],
4408							v->AudioSampleLayout[k],
4409							v->ODMCombineEnablePerState[i][k]);
4410				} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
4411					if (v->DSCEnable[k] == true) {
4412						v->RequiresDSC[i][k] = true;
4413						v->LinkDSCEnable = true;
4414						if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
4415							v->RequiresFEC[i][k] = true;
4416						} else {
4417							v->RequiresFEC[i][k] = false;
4418						}
4419					} else {
4420						v->RequiresDSC[i][k] = false;
4421						v->LinkDSCEnable = false;
4422						if (v->Output[k] == dm_dp2p0) {
4423							v->RequiresFEC[i][k] = true;
4424						} else {
4425							v->RequiresFEC[i][k] = false;
4426						}
4427					}
4428					if (v->Output[k] == dm_dp2p0) {
4429						v->Outbpp = BPP_INVALID;
4430						if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
4431							v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
4432							v->Outbpp = TruncToValidBPP(
4433									(1.0 - v->Downspreading / 100.0) * 10000,
4434									v->OutputLinkDPLanes[k],
4435									v->HTotal[k],
4436									v->HActive[k],
4437									v->PixelClockBackEnd[k],
4438									v->ForcedOutputLinkBPP[k],
4439									v->LinkDSCEnable,
4440									v->Output[k],
4441									v->OutputFormat[k],
4442									v->DSCInputBitPerComponent[k],
4443									v->NumberOfDSCSlices[k],
4444									v->AudioSampleRate[k],
4445									v->AudioSampleLayout[k],
4446									v->ODMCombineEnablePerState[i][k]);
4447							if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
4448								v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
4449								v->RequiresDSC[i][k] = true;
4450								v->LinkDSCEnable = true;
4451								v->Outbpp = TruncToValidBPP(
4452										(1.0 - v->Downspreading / 100.0) * 10000,
4453										v->OutputLinkDPLanes[k],
4454										v->HTotal[k],
4455										v->HActive[k],
4456										v->PixelClockBackEnd[k],
4457										v->ForcedOutputLinkBPP[k],
4458										v->LinkDSCEnable,
4459										v->Output[k],
4460										v->OutputFormat[k],
4461										v->DSCInputBitPerComponent[k],
4462										v->NumberOfDSCSlices[k],
4463										v->AudioSampleRate[k],
4464										v->AudioSampleLayout[k],
4465										v->ODMCombineEnablePerState[i][k]);
4466							}
4467							v->OutputBppPerState[i][k] = v->Outbpp;
4468							// TODO: Need some other way to handle this nonsense
4469							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
4470						}
4471						if (v->Outbpp == BPP_INVALID &&
4472							(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
4473							v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
4474							v->Outbpp = TruncToValidBPP(
4475									(1.0 - v->Downspreading / 100.0) * 13500,
4476									v->OutputLinkDPLanes[k],
4477									v->HTotal[k],
4478									v->HActive[k],
4479									v->PixelClockBackEnd[k],
4480									v->ForcedOutputLinkBPP[k],
4481									v->LinkDSCEnable,
4482									v->Output[k],
4483									v->OutputFormat[k],
4484									v->DSCInputBitPerComponent[k],
4485									v->NumberOfDSCSlices[k],
4486									v->AudioSampleRate[k],
4487									v->AudioSampleLayout[k],
4488									v->ODMCombineEnablePerState[i][k]);
4489							if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
4490								v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
4491								v->RequiresDSC[i][k] = true;
4492								v->LinkDSCEnable = true;
4493								v->Outbpp = TruncToValidBPP(
4494										(1.0 - v->Downspreading / 100.0) * 13500,
4495										v->OutputLinkDPLanes[k],
4496										v->HTotal[k],
4497										v->HActive[k],
4498										v->PixelClockBackEnd[k],
4499										v->ForcedOutputLinkBPP[k],
4500										v->LinkDSCEnable,
4501										v->Output[k],
4502										v->OutputFormat[k],
4503										v->DSCInputBitPerComponent[k],
4504										v->NumberOfDSCSlices[k],
4505										v->AudioSampleRate[k],
4506										v->AudioSampleLayout[k],
4507										v->ODMCombineEnablePerState[i][k]);
4508							}
4509							v->OutputBppPerState[i][k] = v->Outbpp;
4510							// TODO: Need some other way to handle this nonsense
4511							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
4512						}
4513						if (v->Outbpp == BPP_INVALID &&
4514							(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
4515							v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
4516							v->Outbpp = TruncToValidBPP(
4517									(1.0 - v->Downspreading / 100.0) * 20000,
4518									v->OutputLinkDPLanes[k],
4519									v->HTotal[k],
4520									v->HActive[k],
4521									v->PixelClockBackEnd[k],
4522									v->ForcedOutputLinkBPP[k],
4523									v->LinkDSCEnable,
4524									v->Output[k],
4525									v->OutputFormat[k],
4526									v->DSCInputBitPerComponent[k],
4527									v->NumberOfDSCSlices[k],
4528									v->AudioSampleRate[k],
4529									v->AudioSampleLayout[k],
4530									v->ODMCombineEnablePerState[i][k]);
4531							if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
4532								v->ForcedOutputLinkBPP[k] == 0) {
4533								v->RequiresDSC[i][k] = true;
4534								v->LinkDSCEnable = true;
4535								v->Outbpp = TruncToValidBPP(
4536										(1.0 - v->Downspreading / 100.0) * 20000,
4537										v->OutputLinkDPLanes[k],
4538										v->HTotal[k],
4539										v->HActive[k],
4540										v->PixelClockBackEnd[k],
4541										v->ForcedOutputLinkBPP[k],
4542										v->LinkDSCEnable,
4543										v->Output[k],
4544										v->OutputFormat[k],
4545										v->DSCInputBitPerComponent[k],
4546										v->NumberOfDSCSlices[k],
4547										v->AudioSampleRate[k],
4548										v->AudioSampleLayout[k],
4549										v->ODMCombineEnablePerState[i][k]);
4550							}
4551							v->OutputBppPerState[i][k] = v->Outbpp;
4552							// TODO: Need some other way to handle this nonsense
4553							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
4554						}
4555					} else {
4556						v->Outbpp = BPP_INVALID;
4557						if (v->PHYCLKPerState[i] >= 270.0) {
4558							v->Outbpp = TruncToValidBPP(
4559									(1.0 - v->Downspreading / 100.0) * 2700,
4560									v->OutputLinkDPLanes[k],
4561									v->HTotal[k],
4562									v->HActive[k],
4563									v->PixelClockBackEnd[k],
4564									v->ForcedOutputLinkBPP[k],
4565									v->LinkDSCEnable,
4566									v->Output[k],
4567									v->OutputFormat[k],
4568									v->DSCInputBitPerComponent[k],
4569									v->NumberOfDSCSlices[k],
4570									v->AudioSampleRate[k],
4571									v->AudioSampleLayout[k],
4572									v->ODMCombineEnablePerState[i][k]);
4573							v->OutputBppPerState[i][k] = v->Outbpp;
4574							// TODO: Need some other way to handle this nonsense
4575							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
4576						}
4577						if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
4578							v->Outbpp = TruncToValidBPP(
4579									(1.0 - v->Downspreading / 100.0) * 5400,
4580									v->OutputLinkDPLanes[k],
4581									v->HTotal[k],
4582									v->HActive[k],
4583									v->PixelClockBackEnd[k],
4584									v->ForcedOutputLinkBPP[k],
4585									v->LinkDSCEnable,
4586									v->Output[k],
4587									v->OutputFormat[k],
4588									v->DSCInputBitPerComponent[k],
4589									v->NumberOfDSCSlices[k],
4590									v->AudioSampleRate[k],
4591									v->AudioSampleLayout[k],
4592									v->ODMCombineEnablePerState[i][k]);
4593							v->OutputBppPerState[i][k] = v->Outbpp;
4594							// TODO: Need some other way to handle this nonsense
4595							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
4596						}
4597						if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
4598							v->Outbpp = TruncToValidBPP(
4599									(1.0 - v->Downspreading / 100.0) * 8100,
4600									v->OutputLinkDPLanes[k],
4601									v->HTotal[k],
4602									v->HActive[k],
4603									v->PixelClockBackEnd[k],
4604									v->ForcedOutputLinkBPP[k],
4605									v->LinkDSCEnable,
4606									v->Output[k],
4607									v->OutputFormat[k],
4608									v->DSCInputBitPerComponent[k],
4609									v->NumberOfDSCSlices[k],
4610									v->AudioSampleRate[k],
4611									v->AudioSampleLayout[k],
4612									v->ODMCombineEnablePerState[i][k]);
4613							v->OutputBppPerState[i][k] = v->Outbpp;
4614							// TODO: Need some other way to handle this nonsense
4615							// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
4616						}
4617					}
4618				}
4619			} else {
4620				v->OutputBppPerState[i][k] = 0;
4621			}
4622		}
4623	}
4624
4625	for (i = 0; i < v->soc.num_states; i++) {
4626		v->LinkCapacitySupport[i] = true;
4627		for (k = 0; k < v->NumberOfActivePlanes; k++) {
4628			if (v->BlendingAndTiming[k] == k
4629					&& (v->Output[k] == dm_dp ||
4630					    v->Output[k] == dm_edp ||
4631					    v->Output[k] == dm_hdmi) && v->OutputBppPerState[i][k] == 0) {
4632				v->LinkCapacitySupport[i] = false;
4633			}
4634		}
4635	}
4636
4637	// UPTO 2172
4638	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4639		if (v->BlendingAndTiming[k] == k
4640				&& (v->Output[k] == dm_dp ||
4641				    v->Output[k] == dm_edp ||
4642				    v->Output[k] == dm_hdmi)) {
4643			if (v->OutputFormat[k] == dm_420 && v->Interlace[k] == 1 && v->ProgressiveToInterlaceUnitInOPP == true) {
4644				P2IWith420 = true;
4645			}
4646			if (v->DSCEnable[k] == true && v->OutputFormat[k] == dm_n422
4647					&& !v->DSC422NativeSupport) {
4648				DSC422NativeNotSupported = true;
4649			}
4650		}
4651	}
4652
4653
4654	for (i = 0; i < v->soc.num_states; ++i) {
4655		v->ODMCombine4To1SupportCheckOK[i] = true;
4656		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4657			if (v->BlendingAndTiming[k] == k && v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1
4658					&& (v->ODMCombine4To1Supported == false || v->Output[k] == dm_dp || v->Output[k] == dm_edp
4659							|| v->Output[k] == dm_hdmi)) {
4660				v->ODMCombine4To1SupportCheckOK[i] = false;
4661			}
4662		}
4663	}
4664
4665	/* Skip dscclk validation: as long as dispclk is supported, dscclk is also implicitly supported */
4666
4667	for (i = 0; i < v->soc.num_states; i++) {
4668		v->NotEnoughDSCUnits[i] = false;
4669		v->TotalDSCUnitsRequired = 0.0;
4670		for (k = 0; k < v->NumberOfActivePlanes; k++) {
4671			if (v->RequiresDSC[i][k] == true) {
4672				if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
4673					v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 4.0;
4674				} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4675					v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 2.0;
4676				} else {
4677					v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 1.0;
4678				}
4679			}
4680		}
4681		if (v->TotalDSCUnitsRequired > v->NumberOfDSC) {
4682			v->NotEnoughDSCUnits[i] = true;
4683		}
4684	}
4685	/*DSC Delay per state*/
4686
4687	for (i = 0; i < v->soc.num_states; i++) {
4688		for (k = 0; k < v->NumberOfActivePlanes; k++) {
4689			if (v->OutputBppPerState[i][k] == BPP_INVALID) {
4690				v->BPP = 0.0;
4691			} else {
4692				v->BPP = v->OutputBppPerState[i][k];
4693			}
4694			if (v->RequiresDSC[i][k] == true && v->BPP != 0.0) {
4695				if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
4696					v->DSCDelayPerState[i][k] = dscceComputeDelay(
4697							v->DSCInputBitPerComponent[k],
4698							v->BPP,
4699							dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4700							v->NumberOfDSCSlices[k],
4701							v->OutputFormat[k],
4702							v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
4703				} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4704					v->DSCDelayPerState[i][k] = 2.0
4705							* (dscceComputeDelay(
4706									v->DSCInputBitPerComponent[k],
4707									v->BPP,
4708									dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4709									v->NumberOfDSCSlices[k] / 2,
4710									v->OutputFormat[k],
4711									v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
4712				} else {
4713					v->DSCDelayPerState[i][k] = 4.0
4714							* (dscceComputeDelay(
4715									v->DSCInputBitPerComponent[k],
4716									v->BPP,
4717									dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4718									v->NumberOfDSCSlices[k] / 4,
4719									v->OutputFormat[k],
4720									v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
4721				}
4722				v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
4723			} else {
4724				v->DSCDelayPerState[i][k] = 0.0;
4725			}
4726		}
4727		for (k = 0; k < v->NumberOfActivePlanes; k++) {
4728			for (m = 0; m < v->NumberOfActivePlanes; m++) {
4729				if (v->BlendingAndTiming[k] == m && v->RequiresDSC[i][m] == true) {
4730					v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][m];
4731				}
4732			}
4733		}
4734	}
4735
4736	//Calculate Swath, DET Configuration, DCFCLKDeepSleep
4737	//
4738	for (i = 0; i < v->soc.num_states; ++i) {
4739		for (j = 0; j <= 1; ++j) {
4740			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4741				v->RequiredDPPCLKThisState[k] = v->RequiredDPPCLK[i][j][k];
4742				v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
4743				v->ODMCombineEnableThisState[k] = v->ODMCombineEnablePerState[i][k];
4744			}
4745
4746			CalculateSwathAndDETConfiguration(
4747					false,
4748					v->NumberOfActivePlanes,
4749					v->DETBufferSizeInKByte[0],
4750					v->MaximumSwathWidthLuma,
4751					v->MaximumSwathWidthChroma,
4752					v->SourceScan,
4753					v->SourcePixelFormat,
4754					v->SurfaceTiling,
4755					v->ViewportWidth,
4756					v->ViewportHeight,
4757					v->SurfaceWidthY,
4758					v->SurfaceWidthC,
4759					v->SurfaceHeightY,
4760					v->SurfaceHeightC,
4761					v->Read256BlockHeightY,
4762					v->Read256BlockHeightC,
4763					v->Read256BlockWidthY,
4764					v->Read256BlockWidthC,
4765					v->ODMCombineEnableThisState,
4766					v->BlendingAndTiming,
4767					v->BytePerPixelY,
4768					v->BytePerPixelC,
4769					v->BytePerPixelInDETY,
4770					v->BytePerPixelInDETC,
4771					v->HActive,
4772					v->HRatio,
4773					v->HRatioChroma,
4774					v->NoOfDPPThisState,
4775					v->swath_width_luma_ub_this_state,
4776					v->swath_width_chroma_ub_this_state,
4777					v->SwathWidthYThisState,
4778					v->SwathWidthCThisState,
4779					v->SwathHeightYThisState,
4780					v->SwathHeightCThisState,
4781					v->DETBufferSizeYThisState,
4782					v->DETBufferSizeCThisState,
4783					v->dummystring,
4784					&v->ViewportSizeSupport[i][j]);
4785
4786			CalculateDCFCLKDeepSleep(
4787					mode_lib,
4788					v->NumberOfActivePlanes,
4789					v->BytePerPixelY,
4790					v->BytePerPixelC,
4791					v->VRatio,
4792					v->VRatioChroma,
4793					v->SwathWidthYThisState,
4794					v->SwathWidthCThisState,
4795					v->NoOfDPPThisState,
4796					v->HRatio,
4797					v->HRatioChroma,
4798					v->PixelClock,
4799					v->PSCL_FACTOR,
4800					v->PSCL_FACTOR_CHROMA,
4801					v->RequiredDPPCLKThisState,
4802					v->ReadBandwidthLuma,
4803					v->ReadBandwidthChroma,
4804					v->ReturnBusWidth,
4805					&v->ProjectedDCFCLKDeepSleep[i][j]);
4806
4807			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4808				v->swath_width_luma_ub_all_states[i][j][k] = v->swath_width_luma_ub_this_state[k];
4809				v->swath_width_chroma_ub_all_states[i][j][k] = v->swath_width_chroma_ub_this_state[k];
4810				v->SwathWidthYAllStates[i][j][k] = v->SwathWidthYThisState[k];
4811				v->SwathWidthCAllStates[i][j][k] = v->SwathWidthCThisState[k];
4812				v->SwathHeightYAllStates[i][j][k] = v->SwathHeightYThisState[k];
4813				v->SwathHeightCAllStates[i][j][k] = v->SwathHeightCThisState[k];
4814				v->DETBufferSizeYAllStates[i][j][k] = v->DETBufferSizeYThisState[k];
4815				v->DETBufferSizeCAllStates[i][j][k] = v->DETBufferSizeCThisState[k];
4816			}
4817		}
4818	}
4819
4820	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4821		v->cursor_bw[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
4822				/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
4823	}
4824
4825	for (i = 0; i < v->soc.num_states; i++) {
4826		for (j = 0; j < 2; j++) {
4827			bool NotUrgentLatencyHiding[DC__NUM_DPP__MAX];
4828
4829			for (k = 0; k < v->NumberOfActivePlanes; k++) {
4830				v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
4831				v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
4832				v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
4833				v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
4834				v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
4835				v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
4836				v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
4837				v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
4838			}
4839
4840			v->TotalNumberOfDCCActiveDPP[i][j] = 0;
4841			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4842				if (v->DCCEnable[k] == true) {
4843					v->TotalNumberOfDCCActiveDPP[i][j] = v->TotalNumberOfDCCActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4844				}
4845			}
4846
4847			for (k = 0; k < v->NumberOfActivePlanes; k++) {
4848				if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10
4849						|| v->SourcePixelFormat[k] == dm_420_12 || v->SourcePixelFormat[k] == dm_rgbe_alpha) {
4850
4851					if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12)
4852							&& v->SourceScan[k] != dm_vert) {
4853						v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma)
4854								/ 2;
4855						v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
4856					} else {
4857						v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
4858						v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
4859					}
4860
4861					v->PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
4862							mode_lib,
4863							v->DCCEnable[k],
4864							v->Read256BlockHeightC[k],
4865							v->Read256BlockWidthC[k],
4866							v->SourcePixelFormat[k],
4867							v->SurfaceTiling[k],
4868							v->BytePerPixelC[k],
4869							v->SourceScan[k],
4870							v->SwathWidthCThisState[k],
4871							v->ViewportHeightChroma[k],
4872							v->GPUVMEnable,
4873							v->HostVMEnable,
4874							v->HostVMMaxNonCachedPageTableLevels,
4875							v->GPUVMMinPageSize,
4876							v->HostVMMinPageSize,
4877							v->PTEBufferSizeInRequestsForChroma,
4878							v->PitchC[k],
4879							0.0,
4880							&v->MacroTileWidthC[k],
4881							&v->MetaRowBytesC,
4882							&v->DPTEBytesPerRowC,
4883							&v->PTEBufferSizeNotExceededC[i][j][k],
4884							&v->dummyinteger7,
4885							&v->dpte_row_height_chroma[k],
4886							&v->dummyinteger28,
4887							&v->dummyinteger26,
4888							&v->dummyinteger23,
4889							&v->meta_row_height_chroma[k],
4890							&v->dummyinteger8,
4891							&v->dummyinteger9,
4892							&v->dummyinteger19,
4893							&v->dummyinteger20,
4894							&v->dummyinteger17,
4895							&v->dummyinteger10,
4896							&v->dummyinteger11);
4897
4898					v->PrefetchLinesC[i][j][k] = CalculatePrefetchSourceLines(
4899							mode_lib,
4900							v->VRatioChroma[k],
4901							v->VTAPsChroma[k],
4902							v->Interlace[k],
4903							v->ProgressiveToInterlaceUnitInOPP,
4904							v->SwathHeightCThisState[k],
4905							v->ViewportYStartC[k],
4906							&v->PrefillC[k],
4907							&v->MaxNumSwC[k]);
4908				} else {
4909					v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
4910					v->PTEBufferSizeInRequestsForChroma = 0;
4911					v->PDEAndMetaPTEBytesPerFrameC = 0.0;
4912					v->MetaRowBytesC = 0.0;
4913					v->DPTEBytesPerRowC = 0.0;
4914					v->PrefetchLinesC[i][j][k] = 0.0;
4915					v->PTEBufferSizeNotExceededC[i][j][k] = true;
4916				}
4917				v->PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
4918						mode_lib,
4919						v->DCCEnable[k],
4920						v->Read256BlockHeightY[k],
4921						v->Read256BlockWidthY[k],
4922						v->SourcePixelFormat[k],
4923						v->SurfaceTiling[k],
4924						v->BytePerPixelY[k],
4925						v->SourceScan[k],
4926						v->SwathWidthYThisState[k],
4927						v->ViewportHeight[k],
4928						v->GPUVMEnable,
4929						v->HostVMEnable,
4930						v->HostVMMaxNonCachedPageTableLevels,
4931						v->GPUVMMinPageSize,
4932						v->HostVMMinPageSize,
4933						v->PTEBufferSizeInRequestsForLuma,
4934						v->PitchY[k],
4935						v->DCCMetaPitchY[k],
4936						&v->MacroTileWidthY[k],
4937						&v->MetaRowBytesY,
4938						&v->DPTEBytesPerRowY,
4939						&v->PTEBufferSizeNotExceededY[i][j][k],
4940						&v->dummyinteger7,
4941						&v->dpte_row_height[k],
4942						&v->dummyinteger29,
4943						&v->dummyinteger27,
4944						&v->dummyinteger24,
4945						&v->meta_row_height[k],
4946						&v->dummyinteger25,
4947						&v->dpte_group_bytes[k],
4948						&v->dummyinteger21,
4949						&v->dummyinteger22,
4950						&v->dummyinteger18,
4951						&v->dummyinteger5,
4952						&v->dummyinteger6);
4953				v->PrefetchLinesY[i][j][k] = CalculatePrefetchSourceLines(
4954						mode_lib,
4955						v->VRatio[k],
4956						v->vtaps[k],
4957						v->Interlace[k],
4958						v->ProgressiveToInterlaceUnitInOPP,
4959						v->SwathHeightYThisState[k],
4960						v->ViewportYStartY[k],
4961						&v->PrefillY[k],
4962						&v->MaxNumSwY[k]);
4963				v->PDEAndMetaPTEBytesPerFrame[i][j][k] = v->PDEAndMetaPTEBytesPerFrameY + v->PDEAndMetaPTEBytesPerFrameC;
4964				v->MetaRowBytes[i][j][k] = v->MetaRowBytesY + v->MetaRowBytesC;
4965				v->DPTEBytesPerRow[i][j][k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC;
4966
4967				CalculateRowBandwidth(
4968						v->GPUVMEnable,
4969						v->SourcePixelFormat[k],
4970						v->VRatio[k],
4971						v->VRatioChroma[k],
4972						v->DCCEnable[k],
4973						v->HTotal[k] / v->PixelClock[k],
4974						v->MetaRowBytesY,
4975						v->MetaRowBytesC,
4976						v->meta_row_height[k],
4977						v->meta_row_height_chroma[k],
4978						v->DPTEBytesPerRowY,
4979						v->DPTEBytesPerRowC,
4980						v->dpte_row_height[k],
4981						v->dpte_row_height_chroma[k],
4982						&v->meta_row_bandwidth[i][j][k],
4983						&v->dpte_row_bandwidth[i][j][k]);
4984			}
4985			/*
4986			 * DCCMetaBufferSizeSupport(i, j) = True
4987			 * For k = 0 To NumberOfActivePlanes - 1
4988			 * If MetaRowBytes(i, j, k) > 24064 Then
4989			 * DCCMetaBufferSizeSupport(i, j) = False
4990			 * End If
4991			 * Next k
4992			 */
4993			v->DCCMetaBufferSizeSupport[i][j] = true;
4994			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4995				if (v->MetaRowBytes[i][j][k] > 24064)
4996					v->DCCMetaBufferSizeSupport[i][j] = false;
4997			}
4998			v->UrgLatency[i] = CalculateUrgentLatency(
4999					v->UrgentLatencyPixelDataOnly,
5000					v->UrgentLatencyPixelMixedWithVMData,
5001					v->UrgentLatencyVMDataOnly,
5002					v->DoUrgentLatencyAdjustment,
5003					v->UrgentLatencyAdjustmentFabricClockComponent,
5004					v->UrgentLatencyAdjustmentFabricClockReference,
5005					v->FabricClockPerState[i]);
5006
5007			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5008				CalculateUrgentBurstFactor(
5009						v->swath_width_luma_ub_this_state[k],
5010						v->swath_width_chroma_ub_this_state[k],
5011						v->SwathHeightYThisState[k],
5012						v->SwathHeightCThisState[k],
5013						v->HTotal[k] / v->PixelClock[k],
5014						v->UrgLatency[i],
5015						v->CursorBufferSize,
5016						v->CursorWidth[k][0],
5017						v->CursorBPP[k][0],
5018						v->VRatio[k],
5019						v->VRatioChroma[k],
5020						v->BytePerPixelInDETY[k],
5021						v->BytePerPixelInDETC[k],
5022						v->DETBufferSizeYThisState[k],
5023						v->DETBufferSizeCThisState[k],
5024						&v->UrgentBurstFactorCursor[k],
5025						&v->UrgentBurstFactorLuma[k],
5026						&v->UrgentBurstFactorChroma[k],
5027						&NotUrgentLatencyHiding[k]);
5028			}
5029
5030			v->NotEnoughUrgentLatencyHidingA[i][j] = false;
5031			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5032				if (NotUrgentLatencyHiding[k]) {
5033					v->NotEnoughUrgentLatencyHidingA[i][j] = true;
5034				}
5035			}
5036
5037			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5038				v->VActivePixelBandwidth[i][j][k] = v->ReadBandwidthLuma[k] * v->UrgentBurstFactorLuma[k]
5039						+ v->ReadBandwidthChroma[k] * v->UrgentBurstFactorChroma[k];
5040				v->VActiveCursorBandwidth[i][j][k] = v->cursor_bw[k] * v->UrgentBurstFactorCursor[k];
5041			}
5042
5043			v->TotalVActivePixelBandwidth[i][j] = 0;
5044			v->TotalVActiveCursorBandwidth[i][j] = 0;
5045			v->TotalMetaRowBandwidth[i][j] = 0;
5046			v->TotalDPTERowBandwidth[i][j] = 0;
5047			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5048				v->TotalVActivePixelBandwidth[i][j] = v->TotalVActivePixelBandwidth[i][j] + v->VActivePixelBandwidth[i][j][k];
5049				v->TotalVActiveCursorBandwidth[i][j] = v->TotalVActiveCursorBandwidth[i][j] + v->VActiveCursorBandwidth[i][j][k];
5050				v->TotalMetaRowBandwidth[i][j] = v->TotalMetaRowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->meta_row_bandwidth[i][j][k];
5051				v->TotalDPTERowBandwidth[i][j] = v->TotalDPTERowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->dpte_row_bandwidth[i][j][k];
5052			}
5053		}
5054	}
5055
5056	//Calculate Return BW
5057	for (i = 0; i < v->soc.num_states; ++i) {
5058		for (j = 0; j <= 1; ++j) {
5059			for (k = 0; k < v->NumberOfActivePlanes; k++) {
5060				if (v->BlendingAndTiming[k] == k) {
5061					if (v->WritebackEnable[k] == true) {
5062						v->WritebackDelayTime[k] = v->WritebackLatency
5063								+ CalculateWriteBackDelay(
5064										v->WritebackPixelFormat[k],
5065										v->WritebackHRatio[k],
5066										v->WritebackVRatio[k],
5067										v->WritebackVTaps[k],
5068										v->WritebackDestinationWidth[k],
5069										v->WritebackDestinationHeight[k],
5070										v->WritebackSourceHeight[k],
5071										v->HTotal[k]) / v->RequiredDISPCLK[i][j];
5072					} else {
5073						v->WritebackDelayTime[k] = 0.0;
5074					}
5075					for (m = 0; m < v->NumberOfActivePlanes; m++) {
5076						if (v->BlendingAndTiming[m] == k && v->WritebackEnable[m] == true) {
5077							v->WritebackDelayTime[k] = dml_max(
5078									v->WritebackDelayTime[k],
5079									v->WritebackLatency
5080											+ CalculateWriteBackDelay(
5081													v->WritebackPixelFormat[m],
5082													v->WritebackHRatio[m],
5083													v->WritebackVRatio[m],
5084													v->WritebackVTaps[m],
5085													v->WritebackDestinationWidth[m],
5086													v->WritebackDestinationHeight[m],
5087													v->WritebackSourceHeight[m],
5088													v->HTotal[m]) / v->RequiredDISPCLK[i][j]);
5089						}
5090					}
5091				}
5092			}
5093			for (k = 0; k < v->NumberOfActivePlanes; k++) {
5094				for (m = 0; m < v->NumberOfActivePlanes; m++) {
5095					if (v->BlendingAndTiming[k] == m) {
5096						v->WritebackDelayTime[k] = v->WritebackDelayTime[m];
5097					}
5098				}
5099			}
5100			v->MaxMaxVStartup[i][j] = 0;
5101			for (k = 0; k < v->NumberOfActivePlanes; k++) {
5102				v->MaximumVStartup[i][j][k] =
5103					CalculateMaxVStartup(
5104						v->VTotal[k],
5105						v->VActive[k],
5106						v->VBlankNom[k],
5107						v->HTotal[k],
5108						v->PixelClock[k],
5109						v->ProgressiveToInterlaceUnitInOPP,
5110						v->Interlace[k],
5111						v->ip.VBlankNomDefaultUS,
5112						v->WritebackDelayTime[k]);
5113				v->MaxMaxVStartup[i][j] = dml_max(v->MaxMaxVStartup[i][j], v->MaximumVStartup[i][j][k]);
5114				}
5115		}
5116	}
5117
5118	ReorderingBytes = v->NumberOfChannels
5119			* dml_max3(
5120					v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
5121					v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
5122					v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
5123
5124	for (i = 0; i < v->soc.num_states; ++i) {
5125		for (j = 0; j <= 1; ++j) {
5126			v->DCFCLKState[i][j] = v->DCFCLKPerState[i];
5127		}
5128	}
5129
5130	if (v->UseMinimumRequiredDCFCLK == true)
5131		UseMinimumDCFCLK(mode_lib, MaxPrefetchMode, ReorderingBytes);
5132
5133	for (i = 0; i < v->soc.num_states; ++i) {
5134		for (j = 0; j <= 1; ++j) {
5135			double IdealFabricAndSDPPortBandwidthPerState = dml_min(
5136					v->ReturnBusWidth * v->DCFCLKState[i][j],
5137					v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn);
5138			double IdealDRAMBandwidthPerState = v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth;
5139			double PixelDataOnlyReturnBWPerState = dml_min(
5140					IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
5141					IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly / 100.0);
5142			double PixelMixedWithVMDataReturnBWPerState = dml_min(
5143					IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
5144					IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0);
5145
5146			if (v->HostVMEnable != true) {
5147				v->ReturnBWPerState[i][j] = PixelDataOnlyReturnBWPerState;
5148			} else {
5149				v->ReturnBWPerState[i][j] = PixelMixedWithVMDataReturnBWPerState;
5150			}
5151		}
5152	}
5153
5154	//Re-ordering Buffer Support Check
5155	for (i = 0; i < v->soc.num_states; ++i) {
5156		for (j = 0; j <= 1; ++j) {
5157			if ((v->ROBBufferSizeInKByte - v->PixelChunkSizeInKByte) * 1024 / v->ReturnBWPerState[i][j]
5158					> (v->RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__) / v->DCFCLKState[i][j] + ReorderingBytes / v->ReturnBWPerState[i][j]) {
5159				v->ROBSupport[i][j] = true;
5160			} else {
5161				v->ROBSupport[i][j] = false;
5162			}
5163		}
5164	}
5165
5166	//Vertical Active BW support check
5167
5168	MaxTotalVActiveRDBandwidth = 0;
5169	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5170		MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
5171	}
5172
5173	for (i = 0; i < v->soc.num_states; ++i) {
5174		for (j = 0; j <= 1; ++j) {
5175			v->MaxTotalVerticalActiveAvailableBandwidth[i][j] = dml_min(
5176					dml_min(
5177							v->ReturnBusWidth * v->DCFCLKState[i][j],
5178							v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn)
5179							* v->MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation / 100,
5180					v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth
5181							* v->MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100);
5182
5183			if (MaxTotalVActiveRDBandwidth <= v->MaxTotalVerticalActiveAvailableBandwidth[i][j]) {
5184				v->TotalVerticalActiveBandwidthSupport[i][j] = true;
5185			} else {
5186				v->TotalVerticalActiveBandwidthSupport[i][j] = false;
5187			}
5188		}
5189	}
5190
5191	v->UrgentLatency = CalculateUrgentLatency(
5192			v->UrgentLatencyPixelDataOnly,
5193			v->UrgentLatencyPixelMixedWithVMData,
5194			v->UrgentLatencyVMDataOnly,
5195			v->DoUrgentLatencyAdjustment,
5196			v->UrgentLatencyAdjustmentFabricClockComponent,
5197			v->UrgentLatencyAdjustmentFabricClockReference,
5198			v->FabricClock);
5199	//Prefetch Check
5200	for (i = 0; i < v->soc.num_states; ++i) {
5201		for (j = 0; j <= 1; ++j) {
5202			double VMDataOnlyReturnBWPerState;
5203			double HostVMInefficiencyFactor = 1;
5204			int NextPrefetchModeState = MinPrefetchMode;
5205			bool UnboundedRequestEnabledThisState = false;
5206			int CompressedBufferSizeInkByteThisState = 0;
5207			double dummy;
5208
5209			v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep[i][j];
5210
5211			v->BandwidthWithoutPrefetchSupported[i][j] = true;
5212			if (v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j]
5213					+ v->TotalDPTERowBandwidth[i][j] > v->ReturnBWPerState[i][j] || v->NotEnoughUrgentLatencyHidingA[i][j]) {
5214				v->BandwidthWithoutPrefetchSupported[i][j] = false;
5215			}
5216
5217			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5218				v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
5219				v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
5220				v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
5221				v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
5222				v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
5223				v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
5224				v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
5225				v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
5226				v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
5227			}
5228
5229			VMDataOnlyReturnBWPerState = dml_min(
5230					dml_min(
5231							v->ReturnBusWidth * v->DCFCLKState[i][j],
5232							v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn)
5233							* v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
5234					v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth
5235							* v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly / 100.0);
5236			if (v->GPUVMEnable && v->HostVMEnable)
5237				HostVMInefficiencyFactor = v->ReturnBWPerState[i][j] / VMDataOnlyReturnBWPerState;
5238
5239			v->ExtraLatency = CalculateExtraLatency(
5240					v->RoundTripPingLatencyCycles,
5241					ReorderingBytes,
5242					v->DCFCLKState[i][j],
5243					v->TotalNumberOfActiveDPP[i][j],
5244					v->PixelChunkSizeInKByte,
5245					v->TotalNumberOfDCCActiveDPP[i][j],
5246					v->MetaChunkSize,
5247					v->ReturnBWPerState[i][j],
5248					v->GPUVMEnable,
5249					v->HostVMEnable,
5250					v->NumberOfActivePlanes,
5251					v->NoOfDPPThisState,
5252					v->dpte_group_bytes,
5253					HostVMInefficiencyFactor,
5254					v->HostVMMinPageSize,
5255					v->HostVMMaxNonCachedPageTableLevels);
5256
5257			v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
5258			do {
5259				v->PrefetchModePerState[i][j] = NextPrefetchModeState;
5260				v->MaxVStartup = v->NextMaxVStartup;
5261
5262				v->TWait = CalculateTWait(
5263						v->PrefetchModePerState[i][j],
5264						v->DRAMClockChangeLatency,
5265						v->UrgLatency[i],
5266						v->SREnterPlusExitTime);
5267
5268				for (k = 0; k < v->NumberOfActivePlanes; k++) {
5269					CalculatePrefetchSchedulePerPlane(mode_lib,
5270									  HostVMInefficiencyFactor,
5271									  i, j,	k);
5272				}
5273
5274				for (k = 0; k < v->NumberOfActivePlanes; k++) {
5275					CalculateUrgentBurstFactor(
5276							v->swath_width_luma_ub_this_state[k],
5277							v->swath_width_chroma_ub_this_state[k],
5278							v->SwathHeightYThisState[k],
5279							v->SwathHeightCThisState[k],
5280							v->HTotal[k] / v->PixelClock[k],
5281							v->UrgLatency[i],
5282							v->CursorBufferSize,
5283							v->CursorWidth[k][0],
5284							v->CursorBPP[k][0],
5285							v->VRatioPreY[i][j][k],
5286							v->VRatioPreC[i][j][k],
5287							v->BytePerPixelInDETY[k],
5288							v->BytePerPixelInDETC[k],
5289							v->DETBufferSizeYThisState[k],
5290							v->DETBufferSizeCThisState[k],
5291							&v->UrgentBurstFactorCursorPre[k],
5292							&v->UrgentBurstFactorLumaPre[k],
5293							&v->UrgentBurstFactorChromaPre[k],
5294							&v->NotUrgentLatencyHidingPre[k]);
5295				}
5296
5297				v->MaximumReadBandwidthWithPrefetch = 0.0;
5298				for (k = 0; k < v->NumberOfActivePlanes; k++) {
5299					v->cursor_bw_pre[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
5300							/ (v->HTotal[k] / v->PixelClock[k]) * v->VRatioPreY[i][j][k];
5301
5302					v->MaximumReadBandwidthWithPrefetch =
5303							v->MaximumReadBandwidthWithPrefetch
5304									+ dml_max3(
5305											v->VActivePixelBandwidth[i][j][k]
5306													+ v->VActiveCursorBandwidth[i][j][k]
5307													+ v->NoOfDPP[i][j][k]
5308															* (v->meta_row_bandwidth[i][j][k]
5309																	+ v->dpte_row_bandwidth[i][j][k]),
5310											v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
5311											v->NoOfDPP[i][j][k]
5312													* (v->RequiredPrefetchPixelDataBWLuma[i][j][k]
5313															* v->UrgentBurstFactorLumaPre[k]
5314															+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5315																	* v->UrgentBurstFactorChromaPre[k])
5316													+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5317				}
5318
5319				v->NotEnoughUrgentLatencyHidingPre = false;
5320				for (k = 0; k < v->NumberOfActivePlanes; k++) {
5321					if (v->NotUrgentLatencyHidingPre[k] == true) {
5322						v->NotEnoughUrgentLatencyHidingPre = true;
5323					}
5324				}
5325
5326				v->PrefetchSupported[i][j] = true;
5327				if (v->BandwidthWithoutPrefetchSupported[i][j] == false || v->MaximumReadBandwidthWithPrefetch > v->ReturnBWPerState[i][j]
5328						|| v->NotEnoughUrgentLatencyHidingPre == 1) {
5329					v->PrefetchSupported[i][j] = false;
5330				}
5331				for (k = 0; k < v->NumberOfActivePlanes; k++) {
5332					if (v->LineTimesForPrefetch[k] < 2.0 || v->LinesForMetaPTE[k] >= 32.0 || v->LinesForMetaAndDPTERow[k] >= 16.0
5333							|| v->NoTimeForPrefetch[i][j][k] == true) {
5334						v->PrefetchSupported[i][j] = false;
5335					}
5336				}
5337
5338				v->DynamicMetadataSupported[i][j] = true;
5339				for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5340					if (v->NoTimeForDynamicMetadata[i][j][k] == true) {
5341						v->DynamicMetadataSupported[i][j] = false;
5342					}
5343				}
5344
5345				v->VRatioInPrefetchSupported[i][j] = true;
5346				for (k = 0; k < v->NumberOfActivePlanes; k++) {
5347					if (v->VRatioPreY[i][j][k] > 4.0 || v->VRatioPreC[i][j][k] > 4.0 || v->NoTimeForPrefetch[i][j][k] == true) {
5348						v->VRatioInPrefetchSupported[i][j] = false;
5349					}
5350				}
5351				v->AnyLinesForVMOrRowTooLarge = false;
5352				for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5353					if (v->LinesForMetaAndDPTERow[k] >= 16 || v->LinesForMetaPTE[k] >= 32) {
5354						v->AnyLinesForVMOrRowTooLarge = true;
5355					}
5356				}
5357
5358				v->NextPrefetchMode = v->NextPrefetchMode + 1;
5359
5360				if (v->PrefetchSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true) {
5361					v->BandwidthAvailableForImmediateFlip = v->ReturnBWPerState[i][j];
5362					for (k = 0; k < v->NumberOfActivePlanes; k++) {
5363						v->BandwidthAvailableForImmediateFlip = v->BandwidthAvailableForImmediateFlip
5364								- dml_max(
5365										v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k],
5366										v->NoOfDPP[i][j][k]
5367												* (v->RequiredPrefetchPixelDataBWLuma[i][j][k]
5368														* v->UrgentBurstFactorLumaPre[k]
5369														+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5370																* v->UrgentBurstFactorChromaPre[k])
5371												+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5372					}
5373					v->TotImmediateFlipBytes = 0.0;
5374					for (k = 0; k < v->NumberOfActivePlanes; k++) {
5375						v->TotImmediateFlipBytes = v->TotImmediateFlipBytes
5376								+ v->NoOfDPP[i][j][k] * (v->PDEAndMetaPTEBytesPerFrame[i][j][k] + v->MetaRowBytes[i][j][k]
5377								+ v->DPTEBytesPerRow[i][j][k]);
5378					}
5379
5380					for (k = 0; k < v->NumberOfActivePlanes; k++) {
5381						CalculateFlipSchedule(
5382								mode_lib,
5383								k,
5384								HostVMInefficiencyFactor,
5385								v->ExtraLatency,
5386								v->UrgLatency[i],
5387								v->PDEAndMetaPTEBytesPerFrame[i][j][k],
5388								v->MetaRowBytes[i][j][k],
5389								v->DPTEBytesPerRow[i][j][k]);
5390					}
5391					v->total_dcn_read_bw_with_flip = 0.0;
5392					for (k = 0; k < v->NumberOfActivePlanes; k++) {
5393						v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip
5394								+ dml_max3(
5395										v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
5396										v->NoOfDPP[i][j][k] * v->final_flip_bw[k] + v->VActivePixelBandwidth[i][j][k]
5397												+ v->VActiveCursorBandwidth[i][j][k],
5398										v->NoOfDPP[i][j][k]
5399												* (v->final_flip_bw[k]
5400														+ v->RequiredPrefetchPixelDataBWLuma[i][j][k]
5401																* v->UrgentBurstFactorLumaPre[k]
5402														+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5403																* v->UrgentBurstFactorChromaPre[k])
5404												+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5405					}
5406					v->ImmediateFlipSupportedForState[i][j] = true;
5407					if (v->total_dcn_read_bw_with_flip > v->ReturnBWPerState[i][j]) {
5408						v->ImmediateFlipSupportedForState[i][j] = false;
5409					}
5410					for (k = 0; k < v->NumberOfActivePlanes; k++) {
5411						if (v->ImmediateFlipSupportedForPipe[k] == false) {
5412							v->ImmediateFlipSupportedForState[i][j] = false;
5413						}
5414					}
5415				} else {
5416					v->ImmediateFlipSupportedForState[i][j] = false;
5417				}
5418
5419				if (v->MaxVStartup <= __DML_VBA_MIN_VSTARTUP__ || v->AnyLinesForVMOrRowTooLarge == false) {
5420					v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
5421					NextPrefetchModeState = NextPrefetchModeState + 1;
5422				} else {
5423					v->NextMaxVStartup = v->NextMaxVStartup - 1;
5424				}
5425				v->NextPrefetchMode = v->NextPrefetchMode + 1;
5426			} while (!((v->PrefetchSupported[i][j] == true && v->DynamicMetadataSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true
5427					&& ((v->HostVMEnable == false &&
5428							v->ImmediateFlipRequirement[0] != dm_immediate_flip_required)
5429							|| v->ImmediateFlipSupportedForState[i][j] == true))
5430					|| (v->NextMaxVStartup == v->MaxMaxVStartup[i][j] && NextPrefetchModeState > MaxPrefetchMode)));
5431
5432			CalculateUnboundedRequestAndCompressedBufferSize(
5433					v->DETBufferSizeInKByte[0],
5434					v->ConfigReturnBufferSizeInKByte,
5435					v->UseUnboundedRequesting,
5436					v->TotalNumberOfActiveDPP[i][j],
5437					NoChroma,
5438					v->MaxNumDPP,
5439					v->CompressedBufferSegmentSizeInkByte,
5440					v->Output,
5441					&UnboundedRequestEnabledThisState,
5442					&CompressedBufferSizeInkByteThisState);
5443
5444			CalculateWatermarksAndDRAMSpeedChangeSupport(
5445					mode_lib,
5446					v->PrefetchModePerState[i][j],
5447					v->DCFCLKState[i][j],
5448					v->ReturnBWPerState[i][j],
5449					v->UrgLatency[i],
5450					v->ExtraLatency,
5451					v->SOCCLKPerState[i],
5452					v->ProjectedDCFCLKDeepSleep[i][j],
5453					v->DETBufferSizeYThisState,
5454					v->DETBufferSizeCThisState,
5455					v->SwathHeightYThisState,
5456					v->SwathHeightCThisState,
5457					v->SwathWidthYThisState,
5458					v->SwathWidthCThisState,
5459					v->NoOfDPPThisState,
5460					v->BytePerPixelInDETY,
5461					v->BytePerPixelInDETC,
5462					UnboundedRequestEnabledThisState,
5463					CompressedBufferSizeInkByteThisState,
5464					&v->DRAMClockChangeSupport[i][j],
5465					&dummy,
5466					&dummy,
5467					&dummy,
5468					&dummy);
5469		}
5470	}
5471
5472	/*PTE Buffer Size Check*/
5473	for (i = 0; i < v->soc.num_states; i++) {
5474		for (j = 0; j < 2; j++) {
5475			v->PTEBufferSizeNotExceeded[i][j] = true;
5476			for (k = 0; k < v->NumberOfActivePlanes; k++) {
5477				if (v->PTEBufferSizeNotExceededY[i][j][k] == false || v->PTEBufferSizeNotExceededC[i][j][k] == false) {
5478					v->PTEBufferSizeNotExceeded[i][j] = false;
5479				}
5480			}
5481		}
5482	}
5483
5484	/*Cursor Support Check*/
5485	v->CursorSupport = true;
5486	for (k = 0; k < v->NumberOfActivePlanes; k++) {
5487		if (v->CursorWidth[k][0] > 0.0) {
5488			if (v->CursorBPP[k][0] == 64 && v->Cursor64BppSupport == false) {
5489				v->CursorSupport = false;
5490			}
5491		}
5492	}
5493
5494	/*Valid Pitch Check*/
5495	v->PitchSupport = true;
5496	for (k = 0; k < v->NumberOfActivePlanes; k++) {
5497		v->AlignedYPitch[k] = dml_ceil(dml_max(v->PitchY[k], v->SurfaceWidthY[k]), v->MacroTileWidthY[k]);
5498		if (v->DCCEnable[k] == true) {
5499			v->AlignedDCCMetaPitchY[k] = dml_ceil(dml_max(v->DCCMetaPitchY[k], v->SurfaceWidthY[k]), 64.0 * v->Read256BlockWidthY[k]);
5500		} else {
5501			v->AlignedDCCMetaPitchY[k] = v->DCCMetaPitchY[k];
5502		}
5503		if (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32 && v->SourcePixelFormat[k] != dm_444_16
5504				&& v->SourcePixelFormat[k] != dm_mono_16 && v->SourcePixelFormat[k] != dm_rgbe
5505				&& v->SourcePixelFormat[k] != dm_mono_8) {
5506			v->AlignedCPitch[k] = dml_ceil(dml_max(v->PitchC[k], v->SurfaceWidthC[k]), v->MacroTileWidthC[k]);
5507			if (v->DCCEnable[k] == true) {
5508				v->AlignedDCCMetaPitchC[k] = dml_ceil(
5509						dml_max(v->DCCMetaPitchC[k], v->SurfaceWidthC[k]),
5510						64.0 * v->Read256BlockWidthC[k]);
5511			} else {
5512				v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
5513			}
5514		} else {
5515			v->AlignedCPitch[k] = v->PitchC[k];
5516			v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
5517		}
5518		if (v->AlignedYPitch[k] > v->PitchY[k] || v->AlignedCPitch[k] > v->PitchC[k]
5519				|| v->AlignedDCCMetaPitchY[k] > v->DCCMetaPitchY[k] || v->AlignedDCCMetaPitchC[k] > v->DCCMetaPitchC[k]) {
5520			v->PitchSupport = false;
5521		}
5522	}
5523
5524	for (k = 0; k < v->NumberOfActivePlanes; k++) {
5525		if (v->ViewportWidth[k] > v->SurfaceWidthY[k] || v->ViewportHeight[k] > v->SurfaceHeightY[k]) {
5526			ViewportExceedsSurface = true;
5527			if (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32
5528					&& v->SourcePixelFormat[k] != dm_444_16 && v->SourcePixelFormat[k] != dm_444_8
5529					&& v->SourcePixelFormat[k] != dm_rgbe) {
5530				if (v->ViewportWidthChroma[k] > v->SurfaceWidthC[k]
5531						|| v->ViewportHeightChroma[k] > v->SurfaceHeightC[k]) {
5532					ViewportExceedsSurface = true;
5533				}
5534			}
5535		}
5536	}
5537
5538	/*Mode Support, Voltage State and SOC Configuration*/
5539	for (i = v->soc.num_states - 1; i >= 0; i--) {
5540		for (j = 0; j < 2; j++) {
5541			if (v->ScaleRatioAndTapsSupport == true && v->SourceFormatPixelAndScanSupport == true && v->ViewportSizeSupport[i][j] == true
5542					&& v->LinkCapacitySupport[i] == true && !P2IWith420 && !DSCOnlyIfNecessaryWithBPP
5543					&& !DSC422NativeNotSupported && v->ODMCombine4To1SupportCheckOK[i] == true && v->NotEnoughDSCUnits[i] == false
5544					&& v->DTBCLKRequiredMoreThanSupported[i] == false
5545					&& v->ROBSupport[i][j] == true && v->DISPCLK_DPPCLK_Support[i][j] == true
5546					&& v->TotalAvailablePipesSupport[i][j] == true && EnoughWritebackUnits == true
5547					&& v->WritebackLatencySupport == true && v->WritebackScaleRatioAndTapsSupport == true
5548					&& v->CursorSupport == true && v->PitchSupport == true && ViewportExceedsSurface == false
5549					&& v->PrefetchSupported[i][j] == true && v->DynamicMetadataSupported[i][j] == true
5550					&& v->TotalVerticalActiveBandwidthSupport[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true
5551					&& v->PTEBufferSizeNotExceeded[i][j] == true && v->NonsupportedDSCInputBPC == false
5552					&& ((v->HostVMEnable == false
5553					&& v->ImmediateFlipRequirement[0] != dm_immediate_flip_required)
5554							|| v->ImmediateFlipSupportedForState[i][j] == true)
5555					&& FMTBufferExceeded == false) {
5556				v->ModeSupport[i][j] = true;
5557			} else {
5558				v->ModeSupport[i][j] = false;
5559			}
5560		}
5561	}
5562	for (i = v->soc.num_states; i >= 0; i--) {
5563		for (j = 0; j < 2; j++) {
5564			enum dm_validation_status status = DML_VALIDATION_OK;
5565
5566			if (!v->ScaleRatioAndTapsSupport) {
5567				status = DML_FAIL_SCALE_RATIO_TAP;
5568			} else if (!v->SourceFormatPixelAndScanSupport) {
5569				status = DML_FAIL_SOURCE_PIXEL_FORMAT;
5570			} else if (!v->ViewportSizeSupport[i][j]) {
5571				status = DML_FAIL_VIEWPORT_SIZE;
5572			} else if (P2IWith420) {
5573				status = DML_FAIL_P2I_WITH_420;
5574			} else if (DSCOnlyIfNecessaryWithBPP) {
5575				status = DML_FAIL_DSC_ONLY_IF_NECESSARY_WITH_BPP;
5576			} else if (DSC422NativeNotSupported) {
5577				status = DML_FAIL_NOT_DSC422_NATIVE;
5578			} else if (!v->ODMCombine4To1SupportCheckOK[i]) {
5579				status = DML_FAIL_ODM_COMBINE4TO1;
5580			} else if (v->NotEnoughDSCUnits[i]) {
5581				status = DML_FAIL_NOT_ENOUGH_DSC;
5582			} else if (!v->ROBSupport[i][j]) {
5583				status = DML_FAIL_REORDERING_BUFFER;
5584			} else if (!v->DISPCLK_DPPCLK_Support[i][j]) {
5585				status = DML_FAIL_DISPCLK_DPPCLK;
5586			} else if (!v->TotalAvailablePipesSupport[i][j]) {
5587				status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
5588			} else if (!EnoughWritebackUnits) {
5589				status = DML_FAIL_ENOUGH_WRITEBACK_UNITS;
5590			} else if (!v->WritebackLatencySupport) {
5591				status = DML_FAIL_WRITEBACK_LATENCY;
5592			} else if (!v->WritebackScaleRatioAndTapsSupport) {
5593				status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
5594			} else if (!v->CursorSupport) {
5595				status = DML_FAIL_CURSOR_SUPPORT;
5596			} else if (!v->PitchSupport) {
5597				status = DML_FAIL_PITCH_SUPPORT;
5598			} else if (ViewportExceedsSurface) {
5599				status = DML_FAIL_VIEWPORT_EXCEEDS_SURFACE;
5600			} else if (!v->PrefetchSupported[i][j]) {
5601				status = DML_FAIL_PREFETCH_SUPPORT;
5602			} else if (!v->DynamicMetadataSupported[i][j]) {
5603				status = DML_FAIL_DYNAMIC_METADATA;
5604			} else if (!v->TotalVerticalActiveBandwidthSupport[i][j]) {
5605				status = DML_FAIL_TOTAL_V_ACTIVE_BW;
5606			} else if (!v->VRatioInPrefetchSupported[i][j]) {
5607				status = DML_FAIL_V_RATIO_PREFETCH;
5608			} else if (!v->PTEBufferSizeNotExceeded[i][j]) {
5609				status = DML_FAIL_PTE_BUFFER_SIZE;
5610			} else if (v->NonsupportedDSCInputBPC) {
5611				status = DML_FAIL_DSC_INPUT_BPC;
5612			} else if ((v->HostVMEnable
5613					&& !v->ImmediateFlipSupportedForState[i][j])) {
5614				status = DML_FAIL_HOST_VM_IMMEDIATE_FLIP;
5615			} else if (FMTBufferExceeded) {
5616				status = DML_FAIL_FMT_BUFFER_EXCEEDED;
5617			}
5618			mode_lib->vba.ValidationStatus[i] = status;
5619		}
5620	}
5621
5622	{
5623		unsigned int MaximumMPCCombine = 0;
5624
5625		for (i = v->soc.num_states; i >= 0; i--) {
5626			if (i == v->soc.num_states || v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true) {
5627				v->VoltageLevel = i;
5628				v->ModeIsSupported = v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true;
5629				if (v->ModeSupport[i][0] == true) {
5630					MaximumMPCCombine = 0;
5631				} else {
5632					MaximumMPCCombine = 1;
5633				}
5634			}
5635		}
5636		v->ImmediateFlipSupport = v->ImmediateFlipSupportedForState[v->VoltageLevel][MaximumMPCCombine];
5637		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5638			v->MPCCombineEnable[k] = v->MPCCombine[v->VoltageLevel][MaximumMPCCombine][k];
5639			v->DPPPerPlane[k] = v->NoOfDPP[v->VoltageLevel][MaximumMPCCombine][k];
5640		}
5641		v->DCFCLK = v->DCFCLKState[v->VoltageLevel][MaximumMPCCombine];
5642		v->DRAMSpeed = v->DRAMSpeedPerState[v->VoltageLevel];
5643		v->FabricClock = v->FabricClockPerState[v->VoltageLevel];
5644		v->SOCCLK = v->SOCCLKPerState[v->VoltageLevel];
5645		v->ReturnBW = v->ReturnBWPerState[v->VoltageLevel][MaximumMPCCombine];
5646		v->maxMpcComb = MaximumMPCCombine;
5647	}
5648}
5649
5650static void CalculateWatermarksAndDRAMSpeedChangeSupport(
5651		struct display_mode_lib *mode_lib,
5652		unsigned int PrefetchMode,
5653		double DCFCLK,
5654		double ReturnBW,
5655		double UrgentLatency,
5656		double ExtraLatency,
5657		double SOCCLK,
5658		double DCFCLKDeepSleep,
5659		unsigned int DETBufferSizeY[],
5660		unsigned int DETBufferSizeC[],
5661		unsigned int SwathHeightY[],
5662		unsigned int SwathHeightC[],
5663		double SwathWidthY[],
5664		double SwathWidthC[],
5665		unsigned int DPPPerPlane[],
5666		double BytePerPixelDETY[],
5667		double BytePerPixelDETC[],
5668		bool UnboundedRequestEnabled,
5669		unsigned int CompressedBufferSizeInkByte,
5670		enum clock_change_support *DRAMClockChangeSupport,
5671		double *StutterExitWatermark,
5672		double *StutterEnterPlusExitWatermark,
5673		double *Z8StutterExitWatermark,
5674		double *Z8StutterEnterPlusExitWatermark)
5675{
5676	struct vba_vars_st *v = &mode_lib->vba;
5677	double EffectiveLBLatencyHidingY;
5678	double EffectiveLBLatencyHidingC;
5679	double LinesInDETY[DC__NUM_DPP__MAX];
5680	double LinesInDETC;
5681	unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX];
5682	unsigned int LinesInDETCRoundedDownToSwath;
5683	double FullDETBufferingTimeY;
5684	double FullDETBufferingTimeC;
5685	double ActiveDRAMClockChangeLatencyMarginY;
5686	double ActiveDRAMClockChangeLatencyMarginC;
5687	double WritebackDRAMClockChangeLatencyMargin;
5688	double PlaneWithMinActiveDRAMClockChangeMargin;
5689	double SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank;
5690	double WritebackDRAMClockChangeLatencyHiding;
5691	double TotalPixelBW = 0.0;
5692	int k, j;
5693
5694	v->UrgentWatermark = UrgentLatency + ExtraLatency;
5695
5696#ifdef __DML_VBA_DEBUG__
5697	dml_print("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency);
5698	dml_print("DML::%s: ExtraLatency = %f\n", __func__, ExtraLatency);
5699	dml_print("DML::%s: UrgentWatermark = %f\n", __func__, v->UrgentWatermark);
5700#endif
5701
5702	v->DRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->UrgentWatermark;
5703
5704#ifdef __DML_VBA_DEBUG__
5705	dml_print("DML::%s: v->DRAMClockChangeLatency = %f\n", __func__, v->DRAMClockChangeLatency);
5706	dml_print("DML::%s: DRAMClockChangeWatermark = %f\n", __func__, v->DRAMClockChangeWatermark);
5707#endif
5708
5709	v->TotalActiveWriteback = 0;
5710	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5711		if (v->WritebackEnable[k] == true) {
5712			v->TotalActiveWriteback = v->TotalActiveWriteback + 1;
5713		}
5714	}
5715
5716	if (v->TotalActiveWriteback <= 1) {
5717		v->WritebackUrgentWatermark = v->WritebackLatency;
5718	} else {
5719		v->WritebackUrgentWatermark = v->WritebackLatency + v->WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
5720	}
5721
5722	if (v->TotalActiveWriteback <= 1) {
5723		v->WritebackDRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->WritebackLatency;
5724	} else {
5725		v->WritebackDRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->WritebackLatency + v->WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
5726	}
5727
5728	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5729		TotalPixelBW = TotalPixelBW
5730				+ DPPPerPlane[k] * (SwathWidthY[k] * BytePerPixelDETY[k] * v->VRatio[k] + SwathWidthC[k] * BytePerPixelDETC[k] * v->VRatioChroma[k])
5731						/ (v->HTotal[k] / v->PixelClock[k]);
5732	}
5733
5734	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5735		double EffectiveDETBufferSizeY = DETBufferSizeY[k];
5736
5737		v->LBLatencyHidingSourceLinesY = dml_min(
5738				(double) v->MaxLineBufferLines,
5739				dml_floor(v->LineBufferSize / v->LBBitPerPixel[k] / (SwathWidthY[k] / dml_max(v->HRatio[k], 1.0)), 1)) - (v->vtaps[k] - 1);
5740
5741		v->LBLatencyHidingSourceLinesC = dml_min(
5742				(double) v->MaxLineBufferLines,
5743				dml_floor(v->LineBufferSize / v->LBBitPerPixel[k] / (SwathWidthC[k] / dml_max(v->HRatioChroma[k], 1.0)), 1)) - (v->VTAPsChroma[k] - 1);
5744
5745		EffectiveLBLatencyHidingY = v->LBLatencyHidingSourceLinesY / v->VRatio[k] * (v->HTotal[k] / v->PixelClock[k]);
5746
5747		EffectiveLBLatencyHidingC = v->LBLatencyHidingSourceLinesC / v->VRatioChroma[k] * (v->HTotal[k] / v->PixelClock[k]);
5748
5749		if (UnboundedRequestEnabled) {
5750			EffectiveDETBufferSizeY = EffectiveDETBufferSizeY
5751					+ CompressedBufferSizeInkByte * 1024 * SwathWidthY[k] * BytePerPixelDETY[k] * v->VRatio[k] / (v->HTotal[k] / v->PixelClock[k]) / TotalPixelBW;
5752		}
5753
5754		LinesInDETY[k] = (double) EffectiveDETBufferSizeY / BytePerPixelDETY[k] / SwathWidthY[k];
5755		LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]);
5756		FullDETBufferingTimeY = LinesInDETYRoundedDownToSwath[k] * (v->HTotal[k] / v->PixelClock[k]) / v->VRatio[k];
5757		if (BytePerPixelDETC[k] > 0) {
5758			LinesInDETC = v->DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k];
5759			LinesInDETCRoundedDownToSwath = dml_floor(LinesInDETC, SwathHeightC[k]);
5760			FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath * (v->HTotal[k] / v->PixelClock[k]) / v->VRatioChroma[k];
5761		} else {
5762			LinesInDETC = 0;
5763			FullDETBufferingTimeC = 999999;
5764		}
5765
5766		ActiveDRAMClockChangeLatencyMarginY = EffectiveLBLatencyHidingY + FullDETBufferingTimeY
5767				- ((double) v->DSTXAfterScaler[k] / v->HTotal[k] + v->DSTYAfterScaler[k]) * v->HTotal[k] / v->PixelClock[k] - v->UrgentWatermark - v->DRAMClockChangeWatermark;
5768
5769		if (v->NumberOfActivePlanes > 1) {
5770			ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY
5771					- (1 - 1.0 / v->NumberOfActivePlanes) * SwathHeightY[k] * v->HTotal[k] / v->PixelClock[k] / v->VRatio[k];
5772		}
5773
5774		if (BytePerPixelDETC[k] > 0) {
5775			ActiveDRAMClockChangeLatencyMarginC = EffectiveLBLatencyHidingC + FullDETBufferingTimeC
5776					- ((double) v->DSTXAfterScaler[k] / v->HTotal[k] + v->DSTYAfterScaler[k]) * v->HTotal[k] / v->PixelClock[k] - v->UrgentWatermark - v->DRAMClockChangeWatermark;
5777
5778			if (v->NumberOfActivePlanes > 1) {
5779				ActiveDRAMClockChangeLatencyMarginC = ActiveDRAMClockChangeLatencyMarginC
5780						- (1 - 1.0 / v->NumberOfActivePlanes) * SwathHeightC[k] * v->HTotal[k] / v->PixelClock[k] / v->VRatioChroma[k];
5781			}
5782			v->ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, ActiveDRAMClockChangeLatencyMarginC);
5783		} else {
5784			v->ActiveDRAMClockChangeLatencyMargin[k] = ActiveDRAMClockChangeLatencyMarginY;
5785		}
5786
5787		if (v->WritebackEnable[k] == true) {
5788			WritebackDRAMClockChangeLatencyHiding = v->WritebackInterfaceBufferSize * 1024
5789					/ (v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k] / (v->WritebackSourceHeight[k] * v->HTotal[k] / v->PixelClock[k]) * 4);
5790			if (v->WritebackPixelFormat[k] == dm_444_64) {
5791				WritebackDRAMClockChangeLatencyHiding = WritebackDRAMClockChangeLatencyHiding / 2;
5792			}
5793			WritebackDRAMClockChangeLatencyMargin = WritebackDRAMClockChangeLatencyHiding - v->WritebackDRAMClockChangeWatermark;
5794			v->ActiveDRAMClockChangeLatencyMargin[k] = dml_min(v->ActiveDRAMClockChangeLatencyMargin[k], WritebackDRAMClockChangeLatencyMargin);
5795		}
5796	}
5797
5798	v->MinActiveDRAMClockChangeMargin = 999999;
5799	PlaneWithMinActiveDRAMClockChangeMargin = 0;
5800	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5801		if (v->ActiveDRAMClockChangeLatencyMargin[k] < v->MinActiveDRAMClockChangeMargin) {
5802			v->MinActiveDRAMClockChangeMargin = v->ActiveDRAMClockChangeLatencyMargin[k];
5803			if (v->BlendingAndTiming[k] == k) {
5804				PlaneWithMinActiveDRAMClockChangeMargin = k;
5805			} else {
5806				for (j = 0; j < v->NumberOfActivePlanes; ++j) {
5807					if (v->BlendingAndTiming[k] == j) {
5808						PlaneWithMinActiveDRAMClockChangeMargin = j;
5809					}
5810				}
5811			}
5812		}
5813	}
5814
5815	v->MinActiveDRAMClockChangeLatencySupported = v->MinActiveDRAMClockChangeMargin + v->DRAMClockChangeLatency ;
5816
5817	SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999;
5818	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5819		if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (v->BlendingAndTiming[k] == k)) && !(v->BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin)
5820				&& v->ActiveDRAMClockChangeLatencyMargin[k] < SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) {
5821			SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = v->ActiveDRAMClockChangeLatencyMargin[k];
5822		}
5823	}
5824
5825	v->TotalNumberOfActiveOTG = 0;
5826
5827	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5828		if (v->BlendingAndTiming[k] == k) {
5829			v->TotalNumberOfActiveOTG = v->TotalNumberOfActiveOTG + 1;
5830		}
5831	}
5832
5833	if (v->MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) {
5834		*DRAMClockChangeSupport = dm_dram_clock_change_vactive;
5835	} else if ((v->SynchronizedVBlank == true || v->TotalNumberOfActiveOTG == 1
5836			|| SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0) && PrefetchMode == 0) {
5837		*DRAMClockChangeSupport = dm_dram_clock_change_vblank;
5838	} else {
5839		*DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
5840	}
5841
5842	*StutterExitWatermark = v->SRExitTime + ExtraLatency + 10 / DCFCLKDeepSleep;
5843	*StutterEnterPlusExitWatermark = (v->SREnterPlusExitTime + ExtraLatency + 10 / DCFCLKDeepSleep);
5844	*Z8StutterExitWatermark = v->SRExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep;
5845	*Z8StutterEnterPlusExitWatermark = v->SREnterPlusExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep;
5846
5847#ifdef __DML_VBA_DEBUG__
5848	dml_print("DML::%s: StutterExitWatermark = %f\n", __func__, *StutterExitWatermark);
5849	dml_print("DML::%s: StutterEnterPlusExitWatermark = %f\n", __func__, *StutterEnterPlusExitWatermark);
5850	dml_print("DML::%s: Z8StutterExitWatermark = %f\n", __func__, *Z8StutterExitWatermark);
5851	dml_print("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, *Z8StutterEnterPlusExitWatermark);
5852#endif
5853}
5854
5855static void CalculateDCFCLKDeepSleep(
5856		struct display_mode_lib *mode_lib,
5857		unsigned int NumberOfActivePlanes,
5858		int BytePerPixelY[],
5859		int BytePerPixelC[],
5860		double VRatio[],
5861		double VRatioChroma[],
5862		double SwathWidthY[],
5863		double SwathWidthC[],
5864		unsigned int DPPPerPlane[],
5865		double HRatio[],
5866		double HRatioChroma[],
5867		double PixelClock[],
5868		double PSCL_THROUGHPUT[],
5869		double PSCL_THROUGHPUT_CHROMA[],
5870		double DPPCLK[],
5871		double ReadBandwidthLuma[],
5872		double ReadBandwidthChroma[],
5873		int ReturnBusWidth,
5874		double *DCFCLKDeepSleep)
5875{
5876	struct vba_vars_st *v = &mode_lib->vba;
5877	double DisplayPipeLineDeliveryTimeLuma;
5878	double DisplayPipeLineDeliveryTimeChroma;
5879	double ReadBandwidth = 0.0;
5880	int k;
5881
5882	for (k = 0; k < NumberOfActivePlanes; ++k) {
5883
5884		if (VRatio[k] <= 1) {
5885			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
5886		} else {
5887			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
5888		}
5889		if (BytePerPixelC[k] == 0) {
5890			DisplayPipeLineDeliveryTimeChroma = 0;
5891		} else {
5892			if (VRatioChroma[k] <= 1) {
5893				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
5894			} else {
5895				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
5896			}
5897		}
5898
5899		if (BytePerPixelC[k] > 0) {
5900			v->DCFCLKDeepSleepPerPlane[k] = dml_max(__DML_MIN_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 32.0 / DisplayPipeLineDeliveryTimeLuma,
5901			__DML_MIN_DCFCLK_FACTOR__ * SwathWidthC[k] * BytePerPixelC[k] / 32.0 / DisplayPipeLineDeliveryTimeChroma);
5902		} else {
5903			v->DCFCLKDeepSleepPerPlane[k] = __DML_MIN_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 64.0 / DisplayPipeLineDeliveryTimeLuma;
5904		}
5905		v->DCFCLKDeepSleepPerPlane[k] = dml_max(v->DCFCLKDeepSleepPerPlane[k], PixelClock[k] / 16);
5906
5907	}
5908
5909	for (k = 0; k < NumberOfActivePlanes; ++k) {
5910		ReadBandwidth = ReadBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
5911	}
5912
5913	*DCFCLKDeepSleep = dml_max(8.0, __DML_MIN_DCFCLK_FACTOR__ * ReadBandwidth / ReturnBusWidth);
5914
5915	for (k = 0; k < NumberOfActivePlanes; ++k) {
5916		*DCFCLKDeepSleep = dml_max(*DCFCLKDeepSleep, v->DCFCLKDeepSleepPerPlane[k]);
5917	}
5918}
5919
5920static void CalculateUrgentBurstFactor(
5921		int swath_width_luma_ub,
5922		int swath_width_chroma_ub,
5923		unsigned int SwathHeightY,
5924		unsigned int SwathHeightC,
5925		double LineTime,
5926		double UrgentLatency,
5927		double CursorBufferSize,
5928		unsigned int CursorWidth,
5929		unsigned int CursorBPP,
5930		double VRatio,
5931		double VRatioC,
5932		double BytePerPixelInDETY,
5933		double BytePerPixelInDETC,
5934		double DETBufferSizeY,
5935		double DETBufferSizeC,
5936		double *UrgentBurstFactorCursor,
5937		double *UrgentBurstFactorLuma,
5938		double *UrgentBurstFactorChroma,
5939		bool *NotEnoughUrgentLatencyHiding)
5940{
5941	double LinesInDETLuma;
5942	double LinesInDETChroma;
5943	unsigned int LinesInCursorBuffer;
5944	double CursorBufferSizeInTime;
5945	double DETBufferSizeInTimeLuma;
5946	double DETBufferSizeInTimeChroma;
5947
5948	*NotEnoughUrgentLatencyHiding = 0;
5949
5950	if (CursorWidth > 0) {
5951		LinesInCursorBuffer = 1 << (unsigned int) dml_floor(dml_log2(CursorBufferSize * 1024.0 / (CursorWidth * CursorBPP / 8.0)), 1.0);
5952		if (VRatio > 0) {
5953			CursorBufferSizeInTime = LinesInCursorBuffer * LineTime / VRatio;
5954			if (CursorBufferSizeInTime - UrgentLatency <= 0) {
5955				*NotEnoughUrgentLatencyHiding = 1;
5956				*UrgentBurstFactorCursor = 0;
5957			} else {
5958				*UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency);
5959			}
5960		} else {
5961			*UrgentBurstFactorCursor = 1;
5962		}
5963	}
5964
5965	LinesInDETLuma = DETBufferSizeY / BytePerPixelInDETY / swath_width_luma_ub;
5966	if (VRatio > 0) {
5967		DETBufferSizeInTimeLuma = dml_floor(LinesInDETLuma, SwathHeightY) * LineTime / VRatio;
5968		if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) {
5969			*NotEnoughUrgentLatencyHiding = 1;
5970			*UrgentBurstFactorLuma = 0;
5971		} else {
5972			*UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency);
5973		}
5974	} else {
5975		*UrgentBurstFactorLuma = 1;
5976	}
5977
5978	if (BytePerPixelInDETC > 0) {
5979		LinesInDETChroma = DETBufferSizeC / BytePerPixelInDETC / swath_width_chroma_ub;
5980		if (VRatio > 0) {
5981			DETBufferSizeInTimeChroma = dml_floor(LinesInDETChroma, SwathHeightC) * LineTime / VRatio;
5982			if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) {
5983				*NotEnoughUrgentLatencyHiding = 1;
5984				*UrgentBurstFactorChroma = 0;
5985			} else {
5986				*UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency);
5987			}
5988		} else {
5989			*UrgentBurstFactorChroma = 1;
5990		}
5991	}
5992}
5993
5994static void CalculatePixelDeliveryTimes(
5995		unsigned int NumberOfActivePlanes,
5996		double VRatio[],
5997		double VRatioChroma[],
5998		double VRatioPrefetchY[],
5999		double VRatioPrefetchC[],
6000		unsigned int swath_width_luma_ub[],
6001		unsigned int swath_width_chroma_ub[],
6002		unsigned int DPPPerPlane[],
6003		double HRatio[],
6004		double HRatioChroma[],
6005		double PixelClock[],
6006		double PSCL_THROUGHPUT[],
6007		double PSCL_THROUGHPUT_CHROMA[],
6008		double DPPCLK[],
6009		int BytePerPixelC[],
6010		enum scan_direction_class SourceScan[],
6011		unsigned int NumberOfCursors[],
6012		unsigned int CursorWidth[][DC__NUM_CURSOR__MAX],
6013		unsigned int CursorBPP[][DC__NUM_CURSOR__MAX],
6014		unsigned int BlockWidth256BytesY[],
6015		unsigned int BlockHeight256BytesY[],
6016		unsigned int BlockWidth256BytesC[],
6017		unsigned int BlockHeight256BytesC[],
6018		double DisplayPipeLineDeliveryTimeLuma[],
6019		double DisplayPipeLineDeliveryTimeChroma[],
6020		double DisplayPipeLineDeliveryTimeLumaPrefetch[],
6021		double DisplayPipeLineDeliveryTimeChromaPrefetch[],
6022		double DisplayPipeRequestDeliveryTimeLuma[],
6023		double DisplayPipeRequestDeliveryTimeChroma[],
6024		double DisplayPipeRequestDeliveryTimeLumaPrefetch[],
6025		double DisplayPipeRequestDeliveryTimeChromaPrefetch[],
6026		double CursorRequestDeliveryTime[],
6027		double CursorRequestDeliveryTimePrefetch[])
6028{
6029	double req_per_swath_ub;
6030	int k;
6031
6032	for (k = 0; k < NumberOfActivePlanes; ++k) {
6033		if (VRatio[k] <= 1) {
6034			DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
6035		} else {
6036			DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
6037		}
6038
6039		if (BytePerPixelC[k] == 0) {
6040			DisplayPipeLineDeliveryTimeChroma[k] = 0;
6041		} else {
6042			if (VRatioChroma[k] <= 1) {
6043				DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
6044			} else {
6045				DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
6046			}
6047		}
6048
6049		if (VRatioPrefetchY[k] <= 1) {
6050			DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
6051		} else {
6052			DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
6053		}
6054
6055		if (BytePerPixelC[k] == 0) {
6056			DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
6057		} else {
6058			if (VRatioPrefetchC[k] <= 1) {
6059				DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
6060			} else {
6061				DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
6062			}
6063		}
6064	}
6065
6066	for (k = 0; k < NumberOfActivePlanes; ++k) {
6067		if (SourceScan[k] != dm_vert) {
6068			req_per_swath_ub = swath_width_luma_ub[k] / BlockWidth256BytesY[k];
6069		} else {
6070			req_per_swath_ub = swath_width_luma_ub[k] / BlockHeight256BytesY[k];
6071		}
6072		DisplayPipeRequestDeliveryTimeLuma[k] = DisplayPipeLineDeliveryTimeLuma[k] / req_per_swath_ub;
6073		DisplayPipeRequestDeliveryTimeLumaPrefetch[k] = DisplayPipeLineDeliveryTimeLumaPrefetch[k] / req_per_swath_ub;
6074		if (BytePerPixelC[k] == 0) {
6075			DisplayPipeRequestDeliveryTimeChroma[k] = 0;
6076			DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = 0;
6077		} else {
6078			if (SourceScan[k] != dm_vert) {
6079				req_per_swath_ub = swath_width_chroma_ub[k] / BlockWidth256BytesC[k];
6080			} else {
6081				req_per_swath_ub = swath_width_chroma_ub[k] / BlockHeight256BytesC[k];
6082			}
6083			DisplayPipeRequestDeliveryTimeChroma[k] = DisplayPipeLineDeliveryTimeChroma[k] / req_per_swath_ub;
6084			DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = DisplayPipeLineDeliveryTimeChromaPrefetch[k] / req_per_swath_ub;
6085		}
6086#ifdef __DML_VBA_DEBUG__
6087		dml_print("DML::%s: k=%d : HRatio = %f\n", __func__, k, HRatio[k]);
6088		dml_print("DML::%s: k=%d : VRatio = %f\n", __func__, k, VRatio[k]);
6089		dml_print("DML::%s: k=%d : HRatioChroma = %f\n", __func__, k, HRatioChroma[k]);
6090		dml_print("DML::%s: k=%d : VRatioChroma = %f\n", __func__, k, VRatioChroma[k]);
6091		dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLuma[k]);
6092		dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLumaPrefetch[k]);
6093		dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChroma[k]);
6094		dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChromaPrefetch[k]);
6095		dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLuma[k]);
6096		dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLumaPrefetch[k]);
6097		dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChroma[k]);
6098		dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChromaPrefetch[k]);
6099#endif
6100	}
6101
6102	for (k = 0; k < NumberOfActivePlanes; ++k) {
6103		int cursor_req_per_width;
6104
6105		cursor_req_per_width = dml_ceil(CursorWidth[k][0] * CursorBPP[k][0] / 256 / 8, 1);
6106		if (NumberOfCursors[k] > 0) {
6107			if (VRatio[k] <= 1) {
6108				CursorRequestDeliveryTime[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
6109			} else {
6110				CursorRequestDeliveryTime[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
6111			}
6112			if (VRatioPrefetchY[k] <= 1) {
6113				CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
6114			} else {
6115				CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
6116			}
6117		} else {
6118			CursorRequestDeliveryTime[k] = 0;
6119			CursorRequestDeliveryTimePrefetch[k] = 0;
6120		}
6121#ifdef __DML_VBA_DEBUG__
6122		dml_print("DML::%s: k=%d : NumberOfCursors = %d\n", __func__, k, NumberOfCursors[k]);
6123		dml_print("DML::%s: k=%d : CursorRequestDeliveryTime = %f\n", __func__, k, CursorRequestDeliveryTime[k]);
6124		dml_print("DML::%s: k=%d : CursorRequestDeliveryTimePrefetch = %f\n", __func__, k, CursorRequestDeliveryTimePrefetch[k]);
6125#endif
6126	}
6127}
6128
6129static void CalculateMetaAndPTETimes(
6130		int NumberOfActivePlanes,
6131		bool GPUVMEnable,
6132		int MetaChunkSize,
6133		int MinMetaChunkSizeBytes,
6134		int HTotal[],
6135		double VRatio[],
6136		double VRatioChroma[],
6137		double DestinationLinesToRequestRowInVBlank[],
6138		double DestinationLinesToRequestRowInImmediateFlip[],
6139		bool DCCEnable[],
6140		double PixelClock[],
6141		int BytePerPixelY[],
6142		int BytePerPixelC[],
6143		enum scan_direction_class SourceScan[],
6144		int dpte_row_height[],
6145		int dpte_row_height_chroma[],
6146		int meta_row_width[],
6147		int meta_row_width_chroma[],
6148		int meta_row_height[],
6149		int meta_row_height_chroma[],
6150		int meta_req_width[],
6151		int meta_req_width_chroma[],
6152		int meta_req_height[],
6153		int meta_req_height_chroma[],
6154		int dpte_group_bytes[],
6155		int PTERequestSizeY[],
6156		int PTERequestSizeC[],
6157		int PixelPTEReqWidthY[],
6158		int PixelPTEReqHeightY[],
6159		int PixelPTEReqWidthC[],
6160		int PixelPTEReqHeightC[],
6161		int dpte_row_width_luma_ub[],
6162		int dpte_row_width_chroma_ub[],
6163		double DST_Y_PER_PTE_ROW_NOM_L[],
6164		double DST_Y_PER_PTE_ROW_NOM_C[],
6165		double DST_Y_PER_META_ROW_NOM_L[],
6166		double DST_Y_PER_META_ROW_NOM_C[],
6167		double TimePerMetaChunkNominal[],
6168		double TimePerChromaMetaChunkNominal[],
6169		double TimePerMetaChunkVBlank[],
6170		double TimePerChromaMetaChunkVBlank[],
6171		double TimePerMetaChunkFlip[],
6172		double TimePerChromaMetaChunkFlip[],
6173		double time_per_pte_group_nom_luma[],
6174		double time_per_pte_group_vblank_luma[],
6175		double time_per_pte_group_flip_luma[],
6176		double time_per_pte_group_nom_chroma[],
6177		double time_per_pte_group_vblank_chroma[],
6178		double time_per_pte_group_flip_chroma[])
6179{
6180	unsigned int meta_chunk_width;
6181	unsigned int min_meta_chunk_width;
6182	unsigned int meta_chunk_per_row_int;
6183	unsigned int meta_row_remainder;
6184	unsigned int meta_chunk_threshold;
6185	unsigned int meta_chunks_per_row_ub;
6186	unsigned int meta_chunk_width_chroma;
6187	unsigned int min_meta_chunk_width_chroma;
6188	unsigned int meta_chunk_per_row_int_chroma;
6189	unsigned int meta_row_remainder_chroma;
6190	unsigned int meta_chunk_threshold_chroma;
6191	unsigned int meta_chunks_per_row_ub_chroma;
6192	unsigned int dpte_group_width_luma;
6193	unsigned int dpte_groups_per_row_luma_ub;
6194	unsigned int dpte_group_width_chroma;
6195	unsigned int dpte_groups_per_row_chroma_ub;
6196	int k;
6197
6198	for (k = 0; k < NumberOfActivePlanes; ++k) {
6199		DST_Y_PER_PTE_ROW_NOM_L[k] = dpte_row_height[k] / VRatio[k];
6200		if (BytePerPixelC[k] == 0) {
6201			DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
6202		} else {
6203			DST_Y_PER_PTE_ROW_NOM_C[k] = dpte_row_height_chroma[k] / VRatioChroma[k];
6204		}
6205		DST_Y_PER_META_ROW_NOM_L[k] = meta_row_height[k] / VRatio[k];
6206		if (BytePerPixelC[k] == 0) {
6207			DST_Y_PER_META_ROW_NOM_C[k] = 0;
6208		} else {
6209			DST_Y_PER_META_ROW_NOM_C[k] = meta_row_height_chroma[k] / VRatioChroma[k];
6210		}
6211	}
6212
6213	for (k = 0; k < NumberOfActivePlanes; ++k) {
6214		if (DCCEnable[k] == true) {
6215			meta_chunk_width = MetaChunkSize * 1024 * 256 / BytePerPixelY[k] / meta_row_height[k];
6216			min_meta_chunk_width = MinMetaChunkSizeBytes * 256 / BytePerPixelY[k] / meta_row_height[k];
6217			meta_chunk_per_row_int = meta_row_width[k] / meta_chunk_width;
6218			meta_row_remainder = meta_row_width[k] % meta_chunk_width;
6219			if (SourceScan[k] != dm_vert) {
6220				meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width[k];
6221			} else {
6222				meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height[k];
6223			}
6224			if (meta_row_remainder <= meta_chunk_threshold) {
6225				meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
6226			} else {
6227				meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
6228			}
6229			TimePerMetaChunkNominal[k] = meta_row_height[k] / VRatio[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
6230			TimePerMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
6231			TimePerMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
6232			if (BytePerPixelC[k] == 0) {
6233				TimePerChromaMetaChunkNominal[k] = 0;
6234				TimePerChromaMetaChunkVBlank[k] = 0;
6235				TimePerChromaMetaChunkFlip[k] = 0;
6236			} else {
6237				meta_chunk_width_chroma = MetaChunkSize * 1024 * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
6238				min_meta_chunk_width_chroma = MinMetaChunkSizeBytes * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
6239				meta_chunk_per_row_int_chroma = (double) meta_row_width_chroma[k] / meta_chunk_width_chroma;
6240				meta_row_remainder_chroma = meta_row_width_chroma[k] % meta_chunk_width_chroma;
6241				if (SourceScan[k] != dm_vert) {
6242					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_width_chroma[k];
6243				} else {
6244					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_height_chroma[k];
6245				}
6246				if (meta_row_remainder_chroma <= meta_chunk_threshold_chroma) {
6247					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 1;
6248				} else {
6249					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 2;
6250				}
6251				TimePerChromaMetaChunkNominal[k] = meta_row_height_chroma[k] / VRatioChroma[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
6252				TimePerChromaMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
6253				TimePerChromaMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
6254			}
6255		} else {
6256			TimePerMetaChunkNominal[k] = 0;
6257			TimePerMetaChunkVBlank[k] = 0;
6258			TimePerMetaChunkFlip[k] = 0;
6259			TimePerChromaMetaChunkNominal[k] = 0;
6260			TimePerChromaMetaChunkVBlank[k] = 0;
6261			TimePerChromaMetaChunkFlip[k] = 0;
6262		}
6263	}
6264
6265	for (k = 0; k < NumberOfActivePlanes; ++k) {
6266		if (GPUVMEnable == true) {
6267			if (SourceScan[k] != dm_vert) {
6268				dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k] * PixelPTEReqWidthY[k];
6269			} else {
6270				dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k] * PixelPTEReqHeightY[k];
6271			}
6272			dpte_groups_per_row_luma_ub = dml_ceil(1.0 * dpte_row_width_luma_ub[k] / dpte_group_width_luma, 1);
6273			time_per_pte_group_nom_luma[k] = DST_Y_PER_PTE_ROW_NOM_L[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
6274			time_per_pte_group_vblank_luma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
6275			time_per_pte_group_flip_luma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
6276			if (BytePerPixelC[k] == 0) {
6277				time_per_pte_group_nom_chroma[k] = 0;
6278				time_per_pte_group_vblank_chroma[k] = 0;
6279				time_per_pte_group_flip_chroma[k] = 0;
6280			} else {
6281				if (SourceScan[k] != dm_vert) {
6282					dpte_group_width_chroma = dpte_group_bytes[k] / PTERequestSizeC[k] * PixelPTEReqWidthC[k];
6283				} else {
6284					dpte_group_width_chroma = dpte_group_bytes[k] / PTERequestSizeC[k] * PixelPTEReqHeightC[k];
6285				}
6286				dpte_groups_per_row_chroma_ub = dml_ceil(1.0 * dpte_row_width_chroma_ub[k] / dpte_group_width_chroma, 1);
6287				time_per_pte_group_nom_chroma[k] = DST_Y_PER_PTE_ROW_NOM_C[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
6288				time_per_pte_group_vblank_chroma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
6289				time_per_pte_group_flip_chroma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
6290			}
6291		} else {
6292			time_per_pte_group_nom_luma[k] = 0;
6293			time_per_pte_group_vblank_luma[k] = 0;
6294			time_per_pte_group_flip_luma[k] = 0;
6295			time_per_pte_group_nom_chroma[k] = 0;
6296			time_per_pte_group_vblank_chroma[k] = 0;
6297			time_per_pte_group_flip_chroma[k] = 0;
6298		}
6299	}
6300}
6301
6302static void CalculateVMGroupAndRequestTimes(
6303		unsigned int NumberOfActivePlanes,
6304		bool GPUVMEnable,
6305		unsigned int GPUVMMaxPageTableLevels,
6306		unsigned int HTotal[],
6307		int BytePerPixelC[],
6308		double DestinationLinesToRequestVMInVBlank[],
6309		double DestinationLinesToRequestVMInImmediateFlip[],
6310		bool DCCEnable[],
6311		double PixelClock[],
6312		int dpte_row_width_luma_ub[],
6313		int dpte_row_width_chroma_ub[],
6314		int vm_group_bytes[],
6315		unsigned int dpde0_bytes_per_frame_ub_l[],
6316		unsigned int dpde0_bytes_per_frame_ub_c[],
6317		int meta_pte_bytes_per_frame_ub_l[],
6318		int meta_pte_bytes_per_frame_ub_c[],
6319		double TimePerVMGroupVBlank[],
6320		double TimePerVMGroupFlip[],
6321		double TimePerVMRequestVBlank[],
6322		double TimePerVMRequestFlip[])
6323{
6324	int num_group_per_lower_vm_stage;
6325	int num_req_per_lower_vm_stage;
6326	int k;
6327
6328	for (k = 0; k < NumberOfActivePlanes; ++k) {
6329		if (GPUVMEnable == true && (DCCEnable[k] == true || GPUVMMaxPageTableLevels > 1)) {
6330			if (DCCEnable[k] == false) {
6331				if (BytePerPixelC[k] > 0) {
6332					num_group_per_lower_vm_stage = dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6333							+ dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
6334				} else {
6335					num_group_per_lower_vm_stage = dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
6336				}
6337			} else {
6338				if (GPUVMMaxPageTableLevels == 1) {
6339					if (BytePerPixelC[k] > 0) {
6340						num_group_per_lower_vm_stage = dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6341								+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
6342					} else {
6343						num_group_per_lower_vm_stage = dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
6344					}
6345				} else {
6346					if (BytePerPixelC[k] > 0) {
6347						num_group_per_lower_vm_stage = 2 + dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6348								+ dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1)
6349								+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6350								+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
6351					} else {
6352						num_group_per_lower_vm_stage = 1 + dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6353								+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
6354					}
6355				}
6356			}
6357
6358			if (DCCEnable[k] == false) {
6359				if (BytePerPixelC[k] > 0) {
6360					num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + dpde0_bytes_per_frame_ub_c[k] / 64;
6361				} else {
6362					num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64;
6363				}
6364			} else {
6365				if (GPUVMMaxPageTableLevels == 1) {
6366					if (BytePerPixelC[k] > 0) {
6367						num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_c[k] / 64;
6368					} else {
6369						num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64;
6370					}
6371				} else {
6372					if (BytePerPixelC[k] > 0) {
6373						num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + dpde0_bytes_per_frame_ub_c[k] / 64
6374								+ meta_pte_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_c[k] / 64;
6375					} else {
6376						num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_l[k] / 64;
6377					}
6378				}
6379			}
6380
6381			TimePerVMGroupVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k] / num_group_per_lower_vm_stage;
6382			TimePerVMGroupFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k] / num_group_per_lower_vm_stage;
6383			TimePerVMRequestVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
6384			TimePerVMRequestFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
6385
6386			if (GPUVMMaxPageTableLevels > 2) {
6387				TimePerVMGroupVBlank[k] = TimePerVMGroupVBlank[k] / 2;
6388				TimePerVMGroupFlip[k] = TimePerVMGroupFlip[k] / 2;
6389				TimePerVMRequestVBlank[k] = TimePerVMRequestVBlank[k] / 2;
6390				TimePerVMRequestFlip[k] = TimePerVMRequestFlip[k] / 2;
6391			}
6392
6393		} else {
6394			TimePerVMGroupVBlank[k] = 0;
6395			TimePerVMGroupFlip[k] = 0;
6396			TimePerVMRequestVBlank[k] = 0;
6397			TimePerVMRequestFlip[k] = 0;
6398		}
6399	}
6400}
6401
6402static void CalculateStutterEfficiency(
6403		struct display_mode_lib *mode_lib,
6404		int CompressedBufferSizeInkByte,
6405		bool UnboundedRequestEnabled,
6406		int ConfigReturnBufferSizeInKByte,
6407		int MetaFIFOSizeInKEntries,
6408		int ZeroSizeBufferEntries,
6409		int NumberOfActivePlanes,
6410		int ROBBufferSizeInKByte,
6411		double TotalDataReadBandwidth,
6412		double DCFCLK,
6413		double ReturnBW,
6414		double COMPBUF_RESERVED_SPACE_64B,
6415		double COMPBUF_RESERVED_SPACE_ZS,
6416		double SRExitTime,
6417		double SRExitZ8Time,
6418		bool SynchronizedVBlank,
6419		double Z8StutterEnterPlusExitWatermark,
6420		double StutterEnterPlusExitWatermark,
6421		bool ProgressiveToInterlaceUnitInOPP,
6422		bool Interlace[],
6423		double MinTTUVBlank[],
6424		int DPPPerPlane[],
6425		unsigned int DETBufferSizeY[],
6426		int BytePerPixelY[],
6427		double BytePerPixelDETY[],
6428		double SwathWidthY[],
6429		int SwathHeightY[],
6430		int SwathHeightC[],
6431		double NetDCCRateLuma[],
6432		double NetDCCRateChroma[],
6433		double DCCFractionOfZeroSizeRequestsLuma[],
6434		double DCCFractionOfZeroSizeRequestsChroma[],
6435		int HTotal[],
6436		int VTotal[],
6437		double PixelClock[],
6438		double VRatio[],
6439		enum scan_direction_class SourceScan[],
6440		int BlockHeight256BytesY[],
6441		int BlockWidth256BytesY[],
6442		int BlockHeight256BytesC[],
6443		int BlockWidth256BytesC[],
6444		int DCCYMaxUncompressedBlock[],
6445		int DCCCMaxUncompressedBlock[],
6446		int VActive[],
6447		bool DCCEnable[],
6448		bool WritebackEnable[],
6449		double ReadBandwidthPlaneLuma[],
6450		double ReadBandwidthPlaneChroma[],
6451		double meta_row_bw[],
6452		double dpte_row_bw[],
6453		double *StutterEfficiencyNotIncludingVBlank,
6454		double *StutterEfficiency,
6455		int *NumberOfStutterBurstsPerFrame,
6456		double *Z8StutterEfficiencyNotIncludingVBlank,
6457		double *Z8StutterEfficiency,
6458		int *Z8NumberOfStutterBurstsPerFrame,
6459		double *StutterPeriod)
6460{
6461	struct vba_vars_st *v = &mode_lib->vba;
6462
6463	double DETBufferingTimeY;
6464	double SwathWidthYCriticalPlane = 0;
6465	double VActiveTimeCriticalPlane = 0;
6466	double FrameTimeCriticalPlane = 0;
6467	int BytePerPixelYCriticalPlane = 0;
6468	double LinesToFinishSwathTransferStutterCriticalPlane = 0;
6469	double MinTTUVBlankCriticalPlane = 0;
6470	double TotalCompressedReadBandwidth;
6471	double TotalRowReadBandwidth;
6472	double AverageDCCCompressionRate;
6473	double EffectiveCompressedBufferSize;
6474	double PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer;
6475	double StutterBurstTime;
6476	int TotalActiveWriteback;
6477	double LinesInDETY;
6478	double LinesInDETYRoundedDownToSwath;
6479	double MaximumEffectiveCompressionLuma;
6480	double MaximumEffectiveCompressionChroma;
6481	double TotalZeroSizeRequestReadBandwidth;
6482	double TotalZeroSizeCompressedReadBandwidth;
6483	double AverageDCCZeroSizeFraction;
6484	double AverageZeroSizeCompressionRate;
6485	int TotalNumberOfActiveOTG = 0;
6486	double LastStutterPeriod = 0.0;
6487	double LastZ8StutterPeriod = 0.0;
6488	int k;
6489
6490	TotalZeroSizeRequestReadBandwidth = 0;
6491	TotalZeroSizeCompressedReadBandwidth = 0;
6492	TotalRowReadBandwidth = 0;
6493	TotalCompressedReadBandwidth = 0;
6494
6495	for (k = 0; k < NumberOfActivePlanes; ++k) {
6496		if (DCCEnable[k] == true) {
6497			if ((SourceScan[k] == dm_vert && BlockWidth256BytesY[k] > SwathHeightY[k]) || (SourceScan[k] != dm_vert && BlockHeight256BytesY[k] > SwathHeightY[k])
6498					|| DCCYMaxUncompressedBlock[k] < 256) {
6499				MaximumEffectiveCompressionLuma = 2;
6500			} else {
6501				MaximumEffectiveCompressionLuma = 4;
6502			}
6503			TotalCompressedReadBandwidth = TotalCompressedReadBandwidth + ReadBandwidthPlaneLuma[k] / dml_min(NetDCCRateLuma[k], MaximumEffectiveCompressionLuma);
6504			TotalZeroSizeRequestReadBandwidth = TotalZeroSizeRequestReadBandwidth + ReadBandwidthPlaneLuma[k] * DCCFractionOfZeroSizeRequestsLuma[k];
6505			TotalZeroSizeCompressedReadBandwidth = TotalZeroSizeCompressedReadBandwidth
6506					+ ReadBandwidthPlaneLuma[k] * DCCFractionOfZeroSizeRequestsLuma[k] / MaximumEffectiveCompressionLuma;
6507			if (ReadBandwidthPlaneChroma[k] > 0) {
6508				if ((SourceScan[k] == dm_vert && BlockWidth256BytesC[k] > SwathHeightC[k])
6509						|| (SourceScan[k] != dm_vert && BlockHeight256BytesC[k] > SwathHeightC[k]) || DCCCMaxUncompressedBlock[k] < 256) {
6510					MaximumEffectiveCompressionChroma = 2;
6511				} else {
6512					MaximumEffectiveCompressionChroma = 4;
6513				}
6514				TotalCompressedReadBandwidth = TotalCompressedReadBandwidth
6515						+ ReadBandwidthPlaneChroma[k] / dml_min(NetDCCRateChroma[k], MaximumEffectiveCompressionChroma);
6516				TotalZeroSizeRequestReadBandwidth = TotalZeroSizeRequestReadBandwidth + ReadBandwidthPlaneChroma[k] * DCCFractionOfZeroSizeRequestsChroma[k];
6517				TotalZeroSizeCompressedReadBandwidth = TotalZeroSizeCompressedReadBandwidth
6518						+ ReadBandwidthPlaneChroma[k] * DCCFractionOfZeroSizeRequestsChroma[k] / MaximumEffectiveCompressionChroma;
6519			}
6520		} else {
6521			TotalCompressedReadBandwidth = TotalCompressedReadBandwidth + ReadBandwidthPlaneLuma[k] + ReadBandwidthPlaneChroma[k];
6522		}
6523		TotalRowReadBandwidth = TotalRowReadBandwidth + DPPPerPlane[k] * (meta_row_bw[k] + dpte_row_bw[k]);
6524	}
6525
6526	AverageDCCCompressionRate = TotalDataReadBandwidth / TotalCompressedReadBandwidth;
6527	AverageDCCZeroSizeFraction = TotalZeroSizeRequestReadBandwidth / TotalDataReadBandwidth;
6528
6529#ifdef __DML_VBA_DEBUG__
6530	dml_print("DML::%s: TotalCompressedReadBandwidth = %f\n", __func__, TotalCompressedReadBandwidth);
6531	dml_print("DML::%s: TotalZeroSizeRequestReadBandwidth = %f\n", __func__, TotalZeroSizeRequestReadBandwidth);
6532	dml_print("DML::%s: TotalZeroSizeCompressedReadBandwidth = %f\n", __func__, TotalZeroSizeCompressedReadBandwidth);
6533	dml_print("DML::%s: MaximumEffectiveCompressionLuma = %f\n", __func__, MaximumEffectiveCompressionLuma);
6534	dml_print("DML::%s: MaximumEffectiveCompressionChroma = %f\n", __func__, MaximumEffectiveCompressionChroma);
6535	dml_print("DML::%s: AverageDCCCompressionRate = %f\n", __func__, AverageDCCCompressionRate);
6536	dml_print("DML::%s: AverageDCCZeroSizeFraction = %f\n", __func__, AverageDCCZeroSizeFraction);
6537	dml_print("DML::%s: CompressedBufferSizeInkByte = %d\n", __func__, CompressedBufferSizeInkByte);
6538#endif
6539
6540	if (AverageDCCZeroSizeFraction == 1) {
6541		AverageZeroSizeCompressionRate = TotalZeroSizeRequestReadBandwidth / TotalZeroSizeCompressedReadBandwidth;
6542		EffectiveCompressedBufferSize = MetaFIFOSizeInKEntries * 1024 * 64 * AverageZeroSizeCompressionRate + (ZeroSizeBufferEntries - COMPBUF_RESERVED_SPACE_ZS) * 64 * AverageZeroSizeCompressionRate;
6543	} else if (AverageDCCZeroSizeFraction > 0) {
6544		AverageZeroSizeCompressionRate = TotalZeroSizeRequestReadBandwidth / TotalZeroSizeCompressedReadBandwidth;
6545		EffectiveCompressedBufferSize = dml_min(
6546				CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate,
6547				MetaFIFOSizeInKEntries * 1024 * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate + 1 / AverageDCCCompressionRate))
6548					+ dml_min((ROBBufferSizeInKByte * 1024 - COMPBUF_RESERVED_SPACE_64B * 64) * AverageDCCCompressionRate,
6549						(ZeroSizeBufferEntries - COMPBUF_RESERVED_SPACE_ZS) * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate));
6550		dml_print("DML::%s: min 1 = %f\n", __func__, CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate);
6551		dml_print(
6552				"DML::%s: min 2 = %f\n",
6553				__func__,
6554				MetaFIFOSizeInKEntries * 1024 * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate + 1 / AverageDCCCompressionRate));
6555		dml_print("DML::%s: min 3 = %f\n", __func__, ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate);
6556		dml_print("DML::%s: min 4 = %f\n", __func__, ZeroSizeBufferEntries * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate));
6557	} else {
6558		EffectiveCompressedBufferSize = dml_min(
6559				CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate,
6560				MetaFIFOSizeInKEntries * 1024 * 64 * AverageDCCCompressionRate) + (ROBBufferSizeInKByte * 1024 - COMPBUF_RESERVED_SPACE_64B * 64) * AverageDCCCompressionRate;
6561		dml_print("DML::%s: min 1 = %f\n", __func__, CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate);
6562		dml_print("DML::%s: min 2 = %f\n", __func__, MetaFIFOSizeInKEntries * 1024 * 64 * AverageDCCCompressionRate);
6563	}
6564
6565#ifdef __DML_VBA_DEBUG__
6566	dml_print("DML::%s: MetaFIFOSizeInKEntries = %d\n", __func__, MetaFIFOSizeInKEntries);
6567	dml_print("DML::%s: AverageZeroSizeCompressionRate = %f\n", __func__, AverageZeroSizeCompressionRate);
6568	dml_print("DML::%s: EffectiveCompressedBufferSize = %f\n", __func__, EffectiveCompressedBufferSize);
6569#endif
6570
6571	*StutterPeriod = 0;
6572	for (k = 0; k < NumberOfActivePlanes; ++k) {
6573		LinesInDETY = (DETBufferSizeY[k] + (UnboundedRequestEnabled == true ? EffectiveCompressedBufferSize : 0) * ReadBandwidthPlaneLuma[k] / TotalDataReadBandwidth)
6574				/ BytePerPixelDETY[k] / SwathWidthY[k];
6575		LinesInDETYRoundedDownToSwath = dml_floor(LinesInDETY, SwathHeightY[k]);
6576		DETBufferingTimeY = LinesInDETYRoundedDownToSwath * (HTotal[k] / PixelClock[k]) / VRatio[k];
6577#ifdef __DML_VBA_DEBUG__
6578		dml_print("DML::%s: k=%0d DETBufferSizeY = %f\n", __func__, k, DETBufferSizeY[k]);
6579		dml_print("DML::%s: k=%0d BytePerPixelDETY = %f\n", __func__, k, BytePerPixelDETY[k]);
6580		dml_print("DML::%s: k=%0d SwathWidthY = %f\n", __func__, k, SwathWidthY[k]);
6581		dml_print("DML::%s: k=%0d ReadBandwidthPlaneLuma = %f\n", __func__, k, ReadBandwidthPlaneLuma[k]);
6582		dml_print("DML::%s: k=%0d TotalDataReadBandwidth = %f\n", __func__, k, TotalDataReadBandwidth);
6583		dml_print("DML::%s: k=%0d LinesInDETY = %f\n", __func__, k, LinesInDETY);
6584		dml_print("DML::%s: k=%0d LinesInDETYRoundedDownToSwath = %f\n", __func__, k, LinesInDETYRoundedDownToSwath);
6585		dml_print("DML::%s: k=%0d HTotal = %d\n", __func__, k, HTotal[k]);
6586		dml_print("DML::%s: k=%0d PixelClock = %f\n", __func__, k, PixelClock[k]);
6587		dml_print("DML::%s: k=%0d VRatio = %f\n", __func__, k, VRatio[k]);
6588		dml_print("DML::%s: k=%0d DETBufferingTimeY = %f\n", __func__, k, DETBufferingTimeY);
6589		dml_print("DML::%s: k=%0d PixelClock = %f\n", __func__, k, PixelClock[k]);
6590#endif
6591
6592		if (k == 0 || DETBufferingTimeY < *StutterPeriod) {
6593			bool isInterlaceTiming = Interlace[k] && !ProgressiveToInterlaceUnitInOPP;
6594
6595			*StutterPeriod = DETBufferingTimeY;
6596			FrameTimeCriticalPlane = (isInterlaceTiming ? dml_floor(VTotal[k] / 2.0, 1.0) : VTotal[k]) * HTotal[k] / PixelClock[k];
6597			VActiveTimeCriticalPlane = (isInterlaceTiming ? dml_floor(VActive[k] / 2.0, 1.0) : VActive[k]) * HTotal[k] / PixelClock[k];
6598			BytePerPixelYCriticalPlane = BytePerPixelY[k];
6599			SwathWidthYCriticalPlane = SwathWidthY[k];
6600			LinesToFinishSwathTransferStutterCriticalPlane = SwathHeightY[k] - (LinesInDETY - LinesInDETYRoundedDownToSwath);
6601			MinTTUVBlankCriticalPlane = MinTTUVBlank[k];
6602
6603#ifdef __DML_VBA_DEBUG__
6604			dml_print("DML::%s: StutterPeriod = %f\n", __func__, *StutterPeriod);
6605			dml_print("DML::%s: MinTTUVBlankCriticalPlane = %f\n", __func__, MinTTUVBlankCriticalPlane);
6606			dml_print("DML::%s: FrameTimeCriticalPlane = %f\n", __func__, FrameTimeCriticalPlane);
6607			dml_print("DML::%s: VActiveTimeCriticalPlane = %f\n", __func__, VActiveTimeCriticalPlane);
6608			dml_print("DML::%s: BytePerPixelYCriticalPlane = %d\n", __func__, BytePerPixelYCriticalPlane);
6609			dml_print("DML::%s: SwathWidthYCriticalPlane = %f\n", __func__, SwathWidthYCriticalPlane);
6610			dml_print("DML::%s: LinesToFinishSwathTransferStutterCriticalPlane = %f\n", __func__, LinesToFinishSwathTransferStutterCriticalPlane);
6611#endif
6612		}
6613	}
6614
6615	PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = dml_min(*StutterPeriod * TotalDataReadBandwidth, EffectiveCompressedBufferSize);
6616#ifdef __DML_VBA_DEBUG__
6617	dml_print("DML::%s: ROBBufferSizeInKByte = %d\n", __func__, ROBBufferSizeInKByte);
6618	dml_print("DML::%s: AverageDCCCompressionRate = %f\n", __func__, AverageDCCCompressionRate);
6619	dml_print("DML::%s: StutterPeriod * TotalDataReadBandwidth = %f\n", __func__, *StutterPeriod * TotalDataReadBandwidth);
6620	dml_print("DML::%s: ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate + EffectiveCompressedBufferSize = %f\n", __func__, ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate + EffectiveCompressedBufferSize);
6621	dml_print("DML::%s: EffectiveCompressedBufferSize = %f\n", __func__, EffectiveCompressedBufferSize);
6622	dml_print("DML::%s: PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = %f\n", __func__, PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer);
6623	dml_print("DML::%s: ReturnBW = %f\n", __func__, ReturnBW);
6624	dml_print("DML::%s: TotalDataReadBandwidth = %f\n", __func__, TotalDataReadBandwidth);
6625	dml_print("DML::%s: TotalRowReadBandwidth = %f\n", __func__, TotalRowReadBandwidth);
6626	dml_print("DML::%s: DCFCLK = %f\n", __func__, DCFCLK);
6627#endif
6628
6629	StutterBurstTime = PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / AverageDCCCompressionRate / ReturnBW
6630			+ (*StutterPeriod * TotalDataReadBandwidth - PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (DCFCLK * 64)
6631			+ *StutterPeriod * TotalRowReadBandwidth / ReturnBW;
6632#ifdef __DML_VBA_DEBUG__
6633	dml_print("DML::%s: Part 1 = %f\n", __func__, PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / AverageDCCCompressionRate / ReturnBW);
6634	dml_print("DML::%s: StutterPeriod * TotalDataReadBandwidth = %f\n", __func__, (*StutterPeriod * TotalDataReadBandwidth));
6635	dml_print("DML::%s: Part 2 = %f\n", __func__, (*StutterPeriod * TotalDataReadBandwidth - PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (DCFCLK * 64));
6636	dml_print("DML::%s: Part 3 = %f\n", __func__, *StutterPeriod * TotalRowReadBandwidth / ReturnBW);
6637	dml_print("DML::%s: StutterBurstTime = %f\n", __func__, StutterBurstTime);
6638#endif
6639	StutterBurstTime = dml_max(StutterBurstTime, LinesToFinishSwathTransferStutterCriticalPlane * BytePerPixelYCriticalPlane * SwathWidthYCriticalPlane / ReturnBW);
6640
6641	dml_print(
6642			"DML::%s: Time to finish residue swath=%f\n",
6643			__func__,
6644			LinesToFinishSwathTransferStutterCriticalPlane * BytePerPixelYCriticalPlane * SwathWidthYCriticalPlane / ReturnBW);
6645
6646	TotalActiveWriteback = 0;
6647	for (k = 0; k < NumberOfActivePlanes; ++k) {
6648		if (WritebackEnable[k]) {
6649			TotalActiveWriteback = TotalActiveWriteback + 1;
6650		}
6651	}
6652
6653	if (TotalActiveWriteback == 0) {
6654#ifdef __DML_VBA_DEBUG__
6655		dml_print("DML::%s: SRExitTime = %f\n", __func__, SRExitTime);
6656		dml_print("DML::%s: SRExitZ8Time = %f\n", __func__, SRExitZ8Time);
6657		dml_print("DML::%s: StutterBurstTime = %f (final)\n", __func__, StutterBurstTime);
6658		dml_print("DML::%s: StutterPeriod = %f\n", __func__, *StutterPeriod);
6659#endif
6660		*StutterEfficiencyNotIncludingVBlank = dml_max(0., 1 - (SRExitTime + StutterBurstTime) / *StutterPeriod) * 100;
6661		*Z8StutterEfficiencyNotIncludingVBlank = dml_max(0., 1 - (SRExitZ8Time + StutterBurstTime) / *StutterPeriod) * 100;
6662		*NumberOfStutterBurstsPerFrame = (*StutterEfficiencyNotIncludingVBlank > 0 ? dml_ceil(VActiveTimeCriticalPlane / *StutterPeriod, 1) : 0);
6663		*Z8NumberOfStutterBurstsPerFrame = (*Z8StutterEfficiencyNotIncludingVBlank > 0 ? dml_ceil(VActiveTimeCriticalPlane / *StutterPeriod, 1) : 0);
6664	} else {
6665		*StutterEfficiencyNotIncludingVBlank = 0.;
6666		*Z8StutterEfficiencyNotIncludingVBlank = 0.;
6667		*NumberOfStutterBurstsPerFrame = 0;
6668		*Z8NumberOfStutterBurstsPerFrame = 0;
6669	}
6670#ifdef __DML_VBA_DEBUG__
6671	dml_print("DML::%s: VActiveTimeCriticalPlane = %f\n", __func__, VActiveTimeCriticalPlane);
6672	dml_print("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *StutterEfficiencyNotIncludingVBlank);
6673	dml_print("DML::%s: Z8StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *Z8StutterEfficiencyNotIncludingVBlank);
6674	dml_print("DML::%s: NumberOfStutterBurstsPerFrame = %d\n", __func__, *NumberOfStutterBurstsPerFrame);
6675	dml_print("DML::%s: Z8NumberOfStutterBurstsPerFrame = %d\n", __func__, *Z8NumberOfStutterBurstsPerFrame);
6676#endif
6677
6678	for (k = 0; k < NumberOfActivePlanes; ++k) {
6679		if (v->BlendingAndTiming[k] == k) {
6680			TotalNumberOfActiveOTG = TotalNumberOfActiveOTG + 1;
6681		}
6682	}
6683
6684	if (*StutterEfficiencyNotIncludingVBlank > 0) {
6685		LastStutterPeriod = VActiveTimeCriticalPlane - (*NumberOfStutterBurstsPerFrame - 1) * *StutterPeriod;
6686
6687		if ((SynchronizedVBlank || TotalNumberOfActiveOTG == 1) && LastStutterPeriod + MinTTUVBlankCriticalPlane > StutterEnterPlusExitWatermark) {
6688			*StutterEfficiency = (1 - (*NumberOfStutterBurstsPerFrame * SRExitTime + StutterBurstTime * VActiveTimeCriticalPlane
6689					/ *StutterPeriod) / FrameTimeCriticalPlane) * 100;
6690		} else {
6691			*StutterEfficiency = *StutterEfficiencyNotIncludingVBlank;
6692		}
6693	} else {
6694		*StutterEfficiency = 0;
6695	}
6696
6697	if (*Z8StutterEfficiencyNotIncludingVBlank > 0) {
6698		LastZ8StutterPeriod = VActiveTimeCriticalPlane - (*NumberOfStutterBurstsPerFrame - 1) * *StutterPeriod;
6699		if ((SynchronizedVBlank || TotalNumberOfActiveOTG == 1) && LastZ8StutterPeriod + MinTTUVBlankCriticalPlane > Z8StutterEnterPlusExitWatermark) {
6700			*Z8StutterEfficiency = (1 - (*NumberOfStutterBurstsPerFrame * SRExitZ8Time + StutterBurstTime * VActiveTimeCriticalPlane
6701					/ *StutterPeriod) / FrameTimeCriticalPlane) * 100;
6702		} else {
6703			*Z8StutterEfficiency = *Z8StutterEfficiencyNotIncludingVBlank;
6704		}
6705	} else {
6706		*Z8StutterEfficiency = 0.;
6707	}
6708
6709	dml_print("DML::%s: LastZ8StutterPeriod = %f\n", __func__, LastZ8StutterPeriod);
6710	dml_print("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, Z8StutterEnterPlusExitWatermark);
6711	dml_print("DML::%s: StutterBurstTime = %f\n", __func__, StutterBurstTime);
6712	dml_print("DML::%s: StutterPeriod = %f\n", __func__, *StutterPeriod);
6713	dml_print("DML::%s: StutterEfficiency = %f\n", __func__, *StutterEfficiency);
6714	dml_print("DML::%s: Z8StutterEfficiency = %f\n", __func__, *Z8StutterEfficiency);
6715	dml_print("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *StutterEfficiencyNotIncludingVBlank);
6716	dml_print("DML::%s: Z8NumberOfStutterBurstsPerFrame = %d\n", __func__, *Z8NumberOfStutterBurstsPerFrame);
6717}
6718
6719static void CalculateSwathAndDETConfiguration(
6720		bool ForceSingleDPP,
6721		int NumberOfActivePlanes,
6722		unsigned int DETBufferSizeInKByte,
6723		double MaximumSwathWidthLuma[],
6724		double MaximumSwathWidthChroma[],
6725		enum scan_direction_class SourceScan[],
6726		enum source_format_class SourcePixelFormat[],
6727		enum dm_swizzle_mode SurfaceTiling[],
6728		int ViewportWidth[],
6729		int ViewportHeight[],
6730		int SurfaceWidthY[],
6731		int SurfaceWidthC[],
6732		int SurfaceHeightY[],
6733		int SurfaceHeightC[],
6734		int Read256BytesBlockHeightY[],
6735		int Read256BytesBlockHeightC[],
6736		int Read256BytesBlockWidthY[],
6737		int Read256BytesBlockWidthC[],
6738		enum odm_combine_mode ODMCombineEnabled[],
6739		int BlendingAndTiming[],
6740		int BytePerPixY[],
6741		int BytePerPixC[],
6742		double BytePerPixDETY[],
6743		double BytePerPixDETC[],
6744		int HActive[],
6745		double HRatio[],
6746		double HRatioChroma[],
6747		int DPPPerPlane[],
6748		int swath_width_luma_ub[],
6749		int swath_width_chroma_ub[],
6750		double SwathWidth[],
6751		double SwathWidthChroma[],
6752		int SwathHeightY[],
6753		int SwathHeightC[],
6754		unsigned int DETBufferSizeY[],
6755		unsigned int DETBufferSizeC[],
6756		bool ViewportSizeSupportPerPlane[],
6757		bool *ViewportSizeSupport)
6758{
6759	int MaximumSwathHeightY[DC__NUM_DPP__MAX];
6760	int MaximumSwathHeightC[DC__NUM_DPP__MAX];
6761	int MinimumSwathHeightY;
6762	int MinimumSwathHeightC;
6763	int RoundedUpMaxSwathSizeBytesY;
6764	int RoundedUpMaxSwathSizeBytesC;
6765	int RoundedUpMinSwathSizeBytesY;
6766	int RoundedUpMinSwathSizeBytesC;
6767	int RoundedUpSwathSizeBytesY;
6768	int RoundedUpSwathSizeBytesC;
6769	double SwathWidthSingleDPP[DC__NUM_DPP__MAX];
6770	double SwathWidthSingleDPPChroma[DC__NUM_DPP__MAX];
6771	int k;
6772
6773	CalculateSwathWidth(
6774			ForceSingleDPP,
6775			NumberOfActivePlanes,
6776			SourcePixelFormat,
6777			SourceScan,
6778			ViewportWidth,
6779			ViewportHeight,
6780			SurfaceWidthY,
6781			SurfaceWidthC,
6782			SurfaceHeightY,
6783			SurfaceHeightC,
6784			ODMCombineEnabled,
6785			BytePerPixY,
6786			BytePerPixC,
6787			Read256BytesBlockHeightY,
6788			Read256BytesBlockHeightC,
6789			Read256BytesBlockWidthY,
6790			Read256BytesBlockWidthC,
6791			BlendingAndTiming,
6792			HActive,
6793			HRatio,
6794			DPPPerPlane,
6795			SwathWidthSingleDPP,
6796			SwathWidthSingleDPPChroma,
6797			SwathWidth,
6798			SwathWidthChroma,
6799			MaximumSwathHeightY,
6800			MaximumSwathHeightC,
6801			swath_width_luma_ub,
6802			swath_width_chroma_ub);
6803
6804	*ViewportSizeSupport = true;
6805	for (k = 0; k < NumberOfActivePlanes; ++k) {
6806		if ((SourcePixelFormat[k] == dm_444_64 || SourcePixelFormat[k] == dm_444_32 || SourcePixelFormat[k] == dm_444_16 || SourcePixelFormat[k] == dm_mono_16
6807				|| SourcePixelFormat[k] == dm_mono_8 || SourcePixelFormat[k] == dm_rgbe)) {
6808			if (SurfaceTiling[k] == dm_sw_linear
6809					|| (SourcePixelFormat[k] == dm_444_64
6810							&& (SurfaceTiling[k] == dm_sw_64kb_s || SurfaceTiling[k] == dm_sw_64kb_s_t || SurfaceTiling[k] == dm_sw_64kb_s_x)
6811							&& SourceScan[k] != dm_vert)) {
6812				MinimumSwathHeightY = MaximumSwathHeightY[k];
6813			} else if (SourcePixelFormat[k] == dm_444_8 && SourceScan[k] == dm_vert) {
6814				MinimumSwathHeightY = MaximumSwathHeightY[k];
6815			} else {
6816				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6817			}
6818			MinimumSwathHeightC = MaximumSwathHeightC[k];
6819		} else {
6820			if (SurfaceTiling[k] == dm_sw_linear) {
6821				MinimumSwathHeightY = MaximumSwathHeightY[k];
6822				MinimumSwathHeightC = MaximumSwathHeightC[k];
6823			} else if (SourcePixelFormat[k] == dm_rgbe_alpha && SourceScan[k] == dm_vert) {
6824				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6825				MinimumSwathHeightC = MaximumSwathHeightC[k];
6826			} else if (SourcePixelFormat[k] == dm_rgbe_alpha) {
6827				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6828				MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6829			} else if (SourcePixelFormat[k] == dm_420_8 && SourceScan[k] == dm_vert) {
6830				MinimumSwathHeightY = MaximumSwathHeightY[k];
6831				MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6832			} else {
6833				MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6834				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6835			}
6836		}
6837
6838		RoundedUpMaxSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k] * MaximumSwathHeightY[k];
6839		RoundedUpMinSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k] * MinimumSwathHeightY;
6840		if (SourcePixelFormat[k] == dm_420_10) {
6841			RoundedUpMaxSwathSizeBytesY = dml_ceil((double) RoundedUpMaxSwathSizeBytesY, 256);
6842			RoundedUpMinSwathSizeBytesY = dml_ceil((double) RoundedUpMinSwathSizeBytesY, 256);
6843		}
6844		RoundedUpMaxSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k] * MaximumSwathHeightC[k];
6845		RoundedUpMinSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k] * MinimumSwathHeightC;
6846		if (SourcePixelFormat[k] == dm_420_10) {
6847			RoundedUpMaxSwathSizeBytesC = dml_ceil(RoundedUpMaxSwathSizeBytesC, 256);
6848			RoundedUpMinSwathSizeBytesC = dml_ceil(RoundedUpMinSwathSizeBytesC, 256);
6849		}
6850
6851		if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC <= DETBufferSizeInKByte * 1024 / 2) {
6852			SwathHeightY[k] = MaximumSwathHeightY[k];
6853			SwathHeightC[k] = MaximumSwathHeightC[k];
6854			RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
6855			RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
6856		} else if (RoundedUpMaxSwathSizeBytesY >= 1.5 * RoundedUpMaxSwathSizeBytesC
6857				&& RoundedUpMinSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC <= DETBufferSizeInKByte * 1024 / 2) {
6858			SwathHeightY[k] = MinimumSwathHeightY;
6859			SwathHeightC[k] = MaximumSwathHeightC[k];
6860			RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
6861			RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
6862		} else if (RoundedUpMaxSwathSizeBytesY < 1.5 * RoundedUpMaxSwathSizeBytesC
6863				&& RoundedUpMaxSwathSizeBytesY + RoundedUpMinSwathSizeBytesC <= DETBufferSizeInKByte * 1024 / 2) {
6864			SwathHeightY[k] = MaximumSwathHeightY[k];
6865			SwathHeightC[k] = MinimumSwathHeightC;
6866			RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
6867			RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
6868		} else {
6869			SwathHeightY[k] = MinimumSwathHeightY;
6870			SwathHeightC[k] = MinimumSwathHeightC;
6871			RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
6872			RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
6873		}
6874		{
6875		double actDETBufferSizeInKByte = dml_ceil(DETBufferSizeInKByte, 64);
6876
6877		if (SwathHeightC[k] == 0) {
6878			DETBufferSizeY[k] = actDETBufferSizeInKByte * 1024;
6879			DETBufferSizeC[k] = 0;
6880		} else if (RoundedUpSwathSizeBytesY <= 1.5 * RoundedUpSwathSizeBytesC) {
6881			DETBufferSizeY[k] = actDETBufferSizeInKByte * 1024 / 2;
6882			DETBufferSizeC[k] = actDETBufferSizeInKByte * 1024 / 2;
6883		} else {
6884			DETBufferSizeY[k] = dml_floor(actDETBufferSizeInKByte * 1024 * 2 / 3, 1024);
6885			DETBufferSizeC[k] = actDETBufferSizeInKByte * 1024 / 3;
6886		}
6887
6888		if (RoundedUpMinSwathSizeBytesY + RoundedUpMinSwathSizeBytesC > actDETBufferSizeInKByte * 1024 / 2 || SwathWidth[k] > MaximumSwathWidthLuma[k]
6889				|| (SwathHeightC[k] > 0 && SwathWidthChroma[k] > MaximumSwathWidthChroma[k])) {
6890			*ViewportSizeSupport = false;
6891			ViewportSizeSupportPerPlane[k] = false;
6892		} else {
6893			ViewportSizeSupportPerPlane[k] = true;
6894		}
6895		}
6896	}
6897}
6898
6899static void CalculateSwathWidth(
6900		bool ForceSingleDPP,
6901		int NumberOfActivePlanes,
6902		enum source_format_class SourcePixelFormat[],
6903		enum scan_direction_class SourceScan[],
6904		int ViewportWidth[],
6905		int ViewportHeight[],
6906		int SurfaceWidthY[],
6907		int SurfaceWidthC[],
6908		int SurfaceHeightY[],
6909		int SurfaceHeightC[],
6910		enum odm_combine_mode ODMCombineEnabled[],
6911		int BytePerPixY[],
6912		int BytePerPixC[],
6913		int Read256BytesBlockHeightY[],
6914		int Read256BytesBlockHeightC[],
6915		int Read256BytesBlockWidthY[],
6916		int Read256BytesBlockWidthC[],
6917		int BlendingAndTiming[],
6918		int HActive[],
6919		double HRatio[],
6920		int DPPPerPlane[],
6921		double SwathWidthSingleDPPY[],
6922		double SwathWidthSingleDPPC[],
6923		double SwathWidthY[],
6924		double SwathWidthC[],
6925		int MaximumSwathHeightY[],
6926		int MaximumSwathHeightC[],
6927		int swath_width_luma_ub[],
6928		int swath_width_chroma_ub[])
6929{
6930	enum odm_combine_mode MainPlaneODMCombine;
6931	int j, k;
6932
6933#ifdef __DML_VBA_DEBUG__
6934	dml_print("DML::%s: NumberOfActivePlanes = %d\n", __func__, NumberOfActivePlanes);
6935#endif
6936
6937	for (k = 0; k < NumberOfActivePlanes; ++k) {
6938		if (SourceScan[k] != dm_vert) {
6939			SwathWidthSingleDPPY[k] = ViewportWidth[k];
6940		} else {
6941			SwathWidthSingleDPPY[k] = ViewportHeight[k];
6942		}
6943
6944#ifdef __DML_VBA_DEBUG__
6945		dml_print("DML::%s: k=%d ViewportWidth=%d\n", __func__, k, ViewportWidth[k]);
6946		dml_print("DML::%s: k=%d ViewportHeight=%d\n", __func__, k, ViewportHeight[k]);
6947#endif
6948
6949		MainPlaneODMCombine = ODMCombineEnabled[k];
6950		for (j = 0; j < NumberOfActivePlanes; ++j) {
6951			if (BlendingAndTiming[k] == j) {
6952				MainPlaneODMCombine = ODMCombineEnabled[j];
6953			}
6954		}
6955
6956		if (MainPlaneODMCombine == dm_odm_combine_mode_4to1)
6957			SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 4.0 * HRatio[k]));
6958		else if (MainPlaneODMCombine == dm_odm_combine_mode_2to1)
6959			SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 2.0 * HRatio[k]));
6960		else if (DPPPerPlane[k] == 2)
6961			SwathWidthY[k] = SwathWidthSingleDPPY[k] / 2;
6962		else
6963			SwathWidthY[k] = SwathWidthSingleDPPY[k];
6964
6965#ifdef __DML_VBA_DEBUG__
6966		dml_print("DML::%s: k=%d SwathWidthSingleDPPY=%f\n", __func__, k, SwathWidthSingleDPPY[k]);
6967		dml_print("DML::%s: k=%d SwathWidthY=%f\n", __func__, k, SwathWidthY[k]);
6968#endif
6969
6970		if (SourcePixelFormat[k] == dm_420_8 || SourcePixelFormat[k] == dm_420_10 || SourcePixelFormat[k] == dm_420_12) {
6971			SwathWidthC[k] = SwathWidthY[k] / 2;
6972			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k] / 2;
6973		} else {
6974			SwathWidthC[k] = SwathWidthY[k];
6975			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k];
6976		}
6977
6978		if (ForceSingleDPP == true) {
6979			SwathWidthY[k] = SwathWidthSingleDPPY[k];
6980			SwathWidthC[k] = SwathWidthSingleDPPC[k];
6981		}
6982		{
6983		int surface_width_ub_l = dml_ceil(SurfaceWidthY[k], Read256BytesBlockWidthY[k]);
6984		int surface_height_ub_l = dml_ceil(SurfaceHeightY[k], Read256BytesBlockHeightY[k]);
6985
6986#ifdef __DML_VBA_DEBUG__
6987		dml_print("DML::%s: k=%d surface_width_ub_l=%0d\n", __func__, k, surface_width_ub_l);
6988#endif
6989
6990		if (SourceScan[k] != dm_vert) {
6991			MaximumSwathHeightY[k] = Read256BytesBlockHeightY[k];
6992			MaximumSwathHeightC[k] = Read256BytesBlockHeightC[k];
6993			swath_width_luma_ub[k] = dml_min(surface_width_ub_l, (int) dml_ceil(SwathWidthY[k] - 1, Read256BytesBlockWidthY[k]) + Read256BytesBlockWidthY[k]);
6994			if (BytePerPixC[k] > 0) {
6995				int surface_width_ub_c = dml_ceil(SurfaceWidthC[k], Read256BytesBlockWidthC[k]);
6996
6997				swath_width_chroma_ub[k] = dml_min(
6998						surface_width_ub_c,
6999						(int) dml_ceil(SwathWidthC[k] - 1, Read256BytesBlockWidthC[k]) + Read256BytesBlockWidthC[k]);
7000			} else {
7001				swath_width_chroma_ub[k] = 0;
7002			}
7003		} else {
7004			MaximumSwathHeightY[k] = Read256BytesBlockWidthY[k];
7005			MaximumSwathHeightC[k] = Read256BytesBlockWidthC[k];
7006			swath_width_luma_ub[k] = dml_min(surface_height_ub_l, (int) dml_ceil(SwathWidthY[k] - 1, Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k]);
7007			if (BytePerPixC[k] > 0) {
7008				int surface_height_ub_c = dml_ceil(SurfaceHeightC[k], Read256BytesBlockHeightC[k]);
7009
7010				swath_width_chroma_ub[k] = dml_min(
7011						surface_height_ub_c,
7012						(int) dml_ceil(SwathWidthC[k] - 1, Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k]);
7013			} else {
7014				swath_width_chroma_ub[k] = 0;
7015			}
7016		}
7017		}
7018	}
7019}
7020
7021static double CalculateExtraLatency(
7022		int RoundTripPingLatencyCycles,
7023		int ReorderingBytes,
7024		double DCFCLK,
7025		int TotalNumberOfActiveDPP,
7026		int PixelChunkSizeInKByte,
7027		int TotalNumberOfDCCActiveDPP,
7028		int MetaChunkSize,
7029		double ReturnBW,
7030		bool GPUVMEnable,
7031		bool HostVMEnable,
7032		int NumberOfActivePlanes,
7033		int NumberOfDPP[],
7034		int dpte_group_bytes[],
7035		double HostVMInefficiencyFactor,
7036		double HostVMMinPageSize,
7037		int HostVMMaxNonCachedPageTableLevels)
7038{
7039	double ExtraLatencyBytes;
7040	double ExtraLatency;
7041
7042	ExtraLatencyBytes = CalculateExtraLatencyBytes(
7043			ReorderingBytes,
7044			TotalNumberOfActiveDPP,
7045			PixelChunkSizeInKByte,
7046			TotalNumberOfDCCActiveDPP,
7047			MetaChunkSize,
7048			GPUVMEnable,
7049			HostVMEnable,
7050			NumberOfActivePlanes,
7051			NumberOfDPP,
7052			dpte_group_bytes,
7053			HostVMInefficiencyFactor,
7054			HostVMMinPageSize,
7055			HostVMMaxNonCachedPageTableLevels);
7056
7057	ExtraLatency = (RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__) / DCFCLK + ExtraLatencyBytes / ReturnBW;
7058
7059#ifdef __DML_VBA_DEBUG__
7060	dml_print("DML::%s: RoundTripPingLatencyCycles=%d\n", __func__, RoundTripPingLatencyCycles);
7061	dml_print("DML::%s: DCFCLK=%f\n", __func__, DCFCLK);
7062	dml_print("DML::%s: ExtraLatencyBytes=%f\n", __func__, ExtraLatencyBytes);
7063	dml_print("DML::%s: ReturnBW=%f\n", __func__, ReturnBW);
7064	dml_print("DML::%s: ExtraLatency=%f\n", __func__, ExtraLatency);
7065#endif
7066
7067	return ExtraLatency;
7068}
7069
7070static double CalculateExtraLatencyBytes(
7071		int ReorderingBytes,
7072		int TotalNumberOfActiveDPP,
7073		int PixelChunkSizeInKByte,
7074		int TotalNumberOfDCCActiveDPP,
7075		int MetaChunkSize,
7076		bool GPUVMEnable,
7077		bool HostVMEnable,
7078		int NumberOfActivePlanes,
7079		int NumberOfDPP[],
7080		int dpte_group_bytes[],
7081		double HostVMInefficiencyFactor,
7082		double HostVMMinPageSize,
7083		int HostVMMaxNonCachedPageTableLevels)
7084{
7085	double ret;
7086	int HostVMDynamicLevels = 0, k;
7087
7088	if (GPUVMEnable == true && HostVMEnable == true) {
7089		if (HostVMMinPageSize < 2048)
7090			HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
7091		else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576)
7092			HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 1);
7093		else
7094			HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 2);
7095	} else {
7096		HostVMDynamicLevels = 0;
7097	}
7098
7099	ret = ReorderingBytes + (TotalNumberOfActiveDPP * PixelChunkSizeInKByte + TotalNumberOfDCCActiveDPP * MetaChunkSize) * 1024.0;
7100
7101	if (GPUVMEnable == true) {
7102		for (k = 0; k < NumberOfActivePlanes; ++k)
7103			ret = ret + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactor;
7104	}
7105	return ret;
7106}
7107
7108static double CalculateUrgentLatency(
7109		double UrgentLatencyPixelDataOnly,
7110		double UrgentLatencyPixelMixedWithVMData,
7111		double UrgentLatencyVMDataOnly,
7112		bool DoUrgentLatencyAdjustment,
7113		double UrgentLatencyAdjustmentFabricClockComponent,
7114		double UrgentLatencyAdjustmentFabricClockReference,
7115		double FabricClock)
7116{
7117	double ret;
7118
7119	ret = dml_max3(UrgentLatencyPixelDataOnly, UrgentLatencyPixelMixedWithVMData, UrgentLatencyVMDataOnly);
7120	if (DoUrgentLatencyAdjustment == true)
7121		ret = ret + UrgentLatencyAdjustmentFabricClockComponent * (UrgentLatencyAdjustmentFabricClockReference / FabricClock - 1);
7122	return ret;
7123}
7124
7125static noinline_for_stack void UseMinimumDCFCLK(
7126		struct display_mode_lib *mode_lib,
7127		int MaxPrefetchMode,
7128		int ReorderingBytes)
7129{
7130	struct vba_vars_st *v = &mode_lib->vba;
7131	int dummy1, i, j, k;
7132	double NormalEfficiency,  dummy2, dummy3;
7133	double TotalMaxPrefetchFlipDPTERowBandwidth[DC__VOLTAGE_STATES][2];
7134
7135	NormalEfficiency = v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0;
7136	for (i = 0; i < v->soc.num_states; ++i) {
7137		for (j = 0; j <= 1; ++j) {
7138			double PixelDCFCLKCyclesRequiredInPrefetch[DC__NUM_DPP__MAX];
7139			double PrefetchPixelLinesTime[DC__NUM_DPP__MAX];
7140			double DCFCLKRequiredForPeakBandwidthPerPlane[DC__NUM_DPP__MAX];
7141			double DynamicMetadataVMExtraLatency[DC__NUM_DPP__MAX];
7142			double MinimumTWait;
7143			double NonDPTEBandwidth;
7144			double DPTEBandwidth;
7145			double DCFCLKRequiredForAverageBandwidth;
7146			double ExtraLatencyBytes;
7147			double ExtraLatencyCycles;
7148			double DCFCLKRequiredForPeakBandwidth;
7149			int NoOfDPPState[DC__NUM_DPP__MAX];
7150			double MinimumTvmPlus2Tr0;
7151
7152			TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = 0;
7153			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
7154				TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = TotalMaxPrefetchFlipDPTERowBandwidth[i][j]
7155						+ v->NoOfDPP[i][j][k] * v->DPTEBytesPerRow[i][j][k] / (15.75 * v->HTotal[k] / v->PixelClock[k]);
7156			}
7157
7158			for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k)
7159				NoOfDPPState[k] = v->NoOfDPP[i][j][k];
7160
7161			MinimumTWait = CalculateTWait(MaxPrefetchMode, v->FinalDRAMClockChangeLatency, v->UrgLatency[i], v->SREnterPlusExitTime);
7162			NonDPTEBandwidth = v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j];
7163			DPTEBandwidth = (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) ?
7164					TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : v->TotalDPTERowBandwidth[i][j];
7165			DCFCLKRequiredForAverageBandwidth = dml_max3(
7166					v->ProjectedDCFCLKDeepSleep[i][j],
7167					(NonDPTEBandwidth + v->TotalDPTERowBandwidth[i][j]) / v->ReturnBusWidth
7168							/ (v->MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation / 100),
7169					(NonDPTEBandwidth + DPTEBandwidth / NormalEfficiency) / NormalEfficiency / v->ReturnBusWidth);
7170
7171			ExtraLatencyBytes = CalculateExtraLatencyBytes(
7172					ReorderingBytes,
7173					v->TotalNumberOfActiveDPP[i][j],
7174					v->PixelChunkSizeInKByte,
7175					v->TotalNumberOfDCCActiveDPP[i][j],
7176					v->MetaChunkSize,
7177					v->GPUVMEnable,
7178					v->HostVMEnable,
7179					v->NumberOfActivePlanes,
7180					NoOfDPPState,
7181					v->dpte_group_bytes,
7182					1,
7183					v->HostVMMinPageSize,
7184					v->HostVMMaxNonCachedPageTableLevels);
7185			ExtraLatencyCycles = v->RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__ + ExtraLatencyBytes / NormalEfficiency / v->ReturnBusWidth;
7186			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
7187				double DCFCLKCyclesRequiredInPrefetch;
7188				double ExpectedPrefetchBWAcceleration;
7189				double PrefetchTime;
7190
7191				PixelDCFCLKCyclesRequiredInPrefetch[k] = (v->PrefetchLinesY[i][j][k] * v->swath_width_luma_ub_all_states[i][j][k] * v->BytePerPixelY[k]
7192						+ v->PrefetchLinesC[i][j][k] * v->swath_width_chroma_ub_all_states[i][j][k] * v->BytePerPixelC[k]) / NormalEfficiency / v->ReturnBusWidth;
7193				DCFCLKCyclesRequiredInPrefetch = 2 * ExtraLatencyCycles / NoOfDPPState[k]
7194						+ v->PDEAndMetaPTEBytesPerFrame[i][j][k] / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth * (v->GPUVMMaxPageTableLevels > 2 ? 1 : 0)
7195						+ 2 * v->DPTEBytesPerRow[i][j][k] / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth
7196						+ 2 * v->MetaRowBytes[i][j][k] / NormalEfficiency / v->ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k];
7197				PrefetchPixelLinesTime[k] = dml_max(v->PrefetchLinesY[i][j][k], v->PrefetchLinesC[i][j][k]) * v->HTotal[k] / v->PixelClock[k];
7198				ExpectedPrefetchBWAcceleration = (v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k])
7199						/ (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k]);
7200				DynamicMetadataVMExtraLatency[k] =
7201						(v->GPUVMEnable == true && v->DynamicMetadataEnable[k] == true && v->DynamicMetadataVMEnabled == true) ?
7202								v->UrgLatency[i] * v->GPUVMMaxPageTableLevels * (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0;
7203				PrefetchTime = (v->MaximumVStartup[i][j][k] - 1) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait
7204						- v->UrgLatency[i]
7205								* ((v->GPUVMMaxPageTableLevels <= 2 ? v->GPUVMMaxPageTableLevels : v->GPUVMMaxPageTableLevels - 2)
7206										* (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1)
7207						- DynamicMetadataVMExtraLatency[k];
7208
7209				if (PrefetchTime > 0) {
7210					double ExpectedVRatioPrefetch;
7211
7212					ExpectedVRatioPrefetch = PrefetchPixelLinesTime[k]
7213							/ (PrefetchTime * PixelDCFCLKCyclesRequiredInPrefetch[k] / DCFCLKCyclesRequiredInPrefetch);
7214					DCFCLKRequiredForPeakBandwidthPerPlane[k] = NoOfDPPState[k] * PixelDCFCLKCyclesRequiredInPrefetch[k] / PrefetchPixelLinesTime[k]
7215							* dml_max(1.0, ExpectedVRatioPrefetch) * dml_max(1.0, ExpectedVRatioPrefetch / 4) * ExpectedPrefetchBWAcceleration;
7216					if (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) {
7217						DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKRequiredForPeakBandwidthPerPlane[k]
7218								+ NoOfDPPState[k] * DPTEBandwidth / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth;
7219					}
7220				} else {
7221					DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i];
7222				}
7223				if (v->DynamicMetadataEnable[k] == true) {
7224					double TSetupPipe;
7225					double TdmbfPipe;
7226					double TdmsksPipe;
7227					double TdmecPipe;
7228					double AllowedTimeForUrgentExtraLatency;
7229
7230					CalculateVupdateAndDynamicMetadataParameters(
7231							v->MaxInterDCNTileRepeaters,
7232							v->RequiredDPPCLK[i][j][k],
7233							v->RequiredDISPCLK[i][j],
7234							v->ProjectedDCFCLKDeepSleep[i][j],
7235							v->PixelClock[k],
7236							v->HTotal[k],
7237							v->VTotal[k] - v->VActive[k],
7238							v->DynamicMetadataTransmittedBytes[k],
7239							v->DynamicMetadataLinesBeforeActiveRequired[k],
7240							v->Interlace[k],
7241							v->ProgressiveToInterlaceUnitInOPP,
7242							&TSetupPipe,
7243							&TdmbfPipe,
7244							&TdmecPipe,
7245							&TdmsksPipe,
7246							&dummy1,
7247							&dummy2,
7248							&dummy3);
7249					AllowedTimeForUrgentExtraLatency = v->MaximumVStartup[i][j][k] * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - TSetupPipe - TdmbfPipe - TdmecPipe
7250							- TdmsksPipe - DynamicMetadataVMExtraLatency[k];
7251					if (AllowedTimeForUrgentExtraLatency > 0) {
7252						DCFCLKRequiredForPeakBandwidthPerPlane[k] = dml_max(
7253								DCFCLKRequiredForPeakBandwidthPerPlane[k],
7254								ExtraLatencyCycles / AllowedTimeForUrgentExtraLatency);
7255					} else {
7256						DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i];
7257					}
7258				}
7259			}
7260			DCFCLKRequiredForPeakBandwidth = 0;
7261			for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k)
7262				DCFCLKRequiredForPeakBandwidth = DCFCLKRequiredForPeakBandwidth + DCFCLKRequiredForPeakBandwidthPerPlane[k];
7263
7264			MinimumTvmPlus2Tr0 = v->UrgLatency[i]
7265					* (v->GPUVMEnable == true ?
7266							(v->HostVMEnable == true ?
7267									(v->GPUVMMaxPageTableLevels + 2) * (v->HostVMMaxNonCachedPageTableLevels + 1) - 1 : v->GPUVMMaxPageTableLevels + 1) :
7268							0);
7269			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
7270				double MaximumTvmPlus2Tr0PlusTsw;
7271
7272				MaximumTvmPlus2Tr0PlusTsw = (v->MaximumVStartup[i][j][k] - 2) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k];
7273				if (MaximumTvmPlus2Tr0PlusTsw <= MinimumTvmPlus2Tr0 + PrefetchPixelLinesTime[k] / 4) {
7274					DCFCLKRequiredForPeakBandwidth = v->DCFCLKPerState[i];
7275				} else {
7276					DCFCLKRequiredForPeakBandwidth = dml_max3(
7277							DCFCLKRequiredForPeakBandwidth,
7278							2 * ExtraLatencyCycles / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0 - PrefetchPixelLinesTime[k] / 4),
7279							(2 * ExtraLatencyCycles + PixelDCFCLKCyclesRequiredInPrefetch[k]) / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0));
7280				}
7281			}
7282			v->DCFCLKState[i][j] = dml_min(v->DCFCLKPerState[i], 1.05 * dml_max(DCFCLKRequiredForAverageBandwidth, DCFCLKRequiredForPeakBandwidth));
7283		}
7284	}
7285}
7286
7287static void CalculateUnboundedRequestAndCompressedBufferSize(
7288		unsigned int DETBufferSizeInKByte,
7289		int ConfigReturnBufferSizeInKByte,
7290		enum unbounded_requesting_policy UseUnboundedRequestingFinal,
7291		int TotalActiveDPP,
7292		bool NoChromaPlanes,
7293		int MaxNumDPP,
7294		int CompressedBufferSegmentSizeInkByteFinal,
7295		enum output_encoder_class *Output,
7296		bool *UnboundedRequestEnabled,
7297		int *CompressedBufferSizeInkByte)
7298{
7299	double actDETBufferSizeInKByte = dml_ceil(DETBufferSizeInKByte, 64);
7300
7301	*UnboundedRequestEnabled = UnboundedRequest(UseUnboundedRequestingFinal, TotalActiveDPP, NoChromaPlanes, Output[0]);
7302	*CompressedBufferSizeInkByte = (
7303			*UnboundedRequestEnabled == true ?
7304					ConfigReturnBufferSizeInKByte - TotalActiveDPP * actDETBufferSizeInKByte :
7305					ConfigReturnBufferSizeInKByte - MaxNumDPP * actDETBufferSizeInKByte);
7306	*CompressedBufferSizeInkByte = *CompressedBufferSizeInkByte * CompressedBufferSegmentSizeInkByteFinal / 64;
7307
7308#ifdef __DML_VBA_DEBUG__
7309	dml_print("DML::%s: TotalActiveDPP = %d\n", __func__, TotalActiveDPP);
7310	dml_print("DML::%s: DETBufferSizeInKByte = %d\n", __func__, DETBufferSizeInKByte);
7311	dml_print("DML::%s: ConfigReturnBufferSizeInKByte = %d\n", __func__, ConfigReturnBufferSizeInKByte);
7312	dml_print("DML::%s: UseUnboundedRequestingFinal = %d\n", __func__, UseUnboundedRequestingFinal);
7313	dml_print("DML::%s: actDETBufferSizeInKByte = %f\n", __func__, actDETBufferSizeInKByte);
7314	dml_print("DML::%s: UnboundedRequestEnabled = %d\n", __func__, *UnboundedRequestEnabled);
7315	dml_print("DML::%s: CompressedBufferSizeInkByte = %d\n", __func__, *CompressedBufferSizeInkByte);
7316#endif
7317}
7318
7319static bool UnboundedRequest(enum unbounded_requesting_policy UseUnboundedRequestingFinal, int TotalNumberOfActiveDPP, bool NoChroma, enum output_encoder_class Output)
7320{
7321	bool ret_val = false;
7322
7323	ret_val = (UseUnboundedRequestingFinal != dm_unbounded_requesting_disable && TotalNumberOfActiveDPP == 1 && NoChroma);
7324	if (UseUnboundedRequestingFinal == dm_unbounded_requesting_edp_only && Output != dm_edp)
7325		ret_val = false;
7326	return ret_val;
7327}
7328
7329static unsigned int CalculateMaxVStartup(
7330		unsigned int VTotal,
7331		unsigned int VActive,
7332		unsigned int VBlankNom,
7333		unsigned int HTotal,
7334		double PixelClock,
7335		bool ProgressiveTointerlaceUnitinOPP,
7336		bool Interlace,
7337		unsigned int VBlankNomDefaultUS,
7338		double WritebackDelayTime)
7339{
7340	unsigned int MaxVStartup = 0;
7341	unsigned int vblank_size = 0;
7342	double line_time_us = HTotal / PixelClock;
7343	unsigned int vblank_actual = VTotal - VActive;
7344	unsigned int vblank_nom_default_in_line = dml_floor(VBlankNomDefaultUS / line_time_us, 1.0);
7345	unsigned int vblank_nom_input = VBlankNom; //dml_min(VBlankNom, vblank_nom_default_in_line);
7346	unsigned int vblank_avail = vblank_nom_input == 0 ? vblank_nom_default_in_line : vblank_nom_input;
7347
7348	vblank_size = (unsigned int) dml_min(vblank_actual, vblank_avail);
7349	if (Interlace && !ProgressiveTointerlaceUnitinOPP)
7350		MaxVStartup = dml_floor(vblank_size / 2.0, 1.0);
7351	else
7352		MaxVStartup = vblank_size - dml_max(1.0, dml_ceil(WritebackDelayTime / line_time_us, 1.0));
7353	if (MaxVStartup > 1023)
7354		MaxVStartup = 1023;
7355	return MaxVStartup;
7356}
7357