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