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