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