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