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