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