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