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