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