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