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