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