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