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