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