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