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