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