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