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