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