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_DCN
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 		unsigned int DETBufferSizeInKByte,
304 		unsigned int WritebackInterfaceBufferSize,
305 		double DCFCLK,
306 		double ReturnBW,
307 		bool GPUVMEnable,
308 		unsigned int dpte_group_bytes[],
309 		unsigned int MetaChunkSize,
310 		double UrgentLatency,
311 		double ExtraLatency,
312 		double WritebackLatency,
313 		double WritebackChunkSize,
314 		double SOCCLK,
315 		double DRAMClockChangeLatency,
316 		double SRExitTime,
317 		double SREnterPlusExitTime,
318 		double DCFCLKDeepSleep,
319 		unsigned int DPPPerPlane[],
320 		bool DCCEnable[],
321 		double DPPCLK[],
322 		unsigned int DETBufferSizeY[],
323 		unsigned int DETBufferSizeC[],
324 		unsigned int SwathHeightY[],
325 		unsigned int SwathHeightC[],
326 		unsigned int LBBitPerPixel[],
327 		double SwathWidthY[],
328 		double SwathWidthC[],
329 		double HRatio[],
330 		double HRatioChroma[],
331 		unsigned int vtaps[],
332 		unsigned int VTAPsChroma[],
333 		double VRatio[],
334 		double VRatioChroma[],
335 		unsigned int HTotal[],
336 		double PixelClock[],
337 		unsigned int BlendingAndTiming[],
338 		double BytePerPixelDETY[],
339 		double BytePerPixelDETC[],
340 		double DSTXAfterScaler[],
341 		double DSTYAfterScaler[],
342 		bool WritebackEnable[],
343 		enum source_format_class WritebackPixelFormat[],
344 		double WritebackDestinationWidth[],
345 		double WritebackDestinationHeight[],
346 		double WritebackSourceHeight[],
347 		enum clock_change_support *DRAMClockChangeSupport,
348 		double *UrgentWatermark,
349 		double *WritebackUrgentWatermark,
350 		double *DRAMClockChangeWatermark,
351 		double *WritebackDRAMClockChangeWatermark,
352 		double *StutterExitWatermark,
353 		double *StutterEnterPlusExitWatermark,
354 		double *MinActiveDRAMClockChangeLatencySupported);
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 		unsigned int 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 		unsigned int 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 		unsigned int DETBufferSizeY[],
640 		unsigned int 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) {
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 || myPipe->DCCEnable)) {
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 		*dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
1872 		*dpte_row_width_ub = (dml_ceil(((double) SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
1873 		*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
1874 	} else if (ScanDirection != dm_vert) {
1875 		*dpte_row_height = *PixelPTEReqHeight;
1876 		*dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
1877 		*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
1878 	} else {
1879 		*dpte_row_height = dml_min(*PixelPTEReqWidth, *MacroTileWidth);
1880 		*dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqHeight, 1) + 1) * *PixelPTEReqHeight;
1881 		*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqHeight * *PTERequestSize;
1882 	}
1883 	if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
1884 			<= 64 * PTEBufferSizeInRequests) {
1885 		*PTEBufferSizeNotExceeded = true;
1886 	} else {
1887 		*PTEBufferSizeNotExceeded = false;
1888 	}
1889 
1890 	if (GPUVMEnable != true) {
1891 		*PixelPTEBytesPerRow = 0;
1892 		*PTEBufferSizeNotExceeded = true;
1893 	}
1894 	dml_print("DML: vm_bytes = meta_pte_bytes_per_frame (per_pipe) = MetaPTEBytesFrame = : %i\n", *MetaPTEBytesFrame);
1895 
1896 	if (HostVMEnable == true) {
1897 		*PixelPTEBytesPerRow = *PixelPTEBytesPerRow * (1 + 8 * HostVMDynamicLevels);
1898 	}
1899 
1900 	if (HostVMEnable == true) {
1901 		*vm_group_bytes = 512;
1902 		*dpte_group_bytes = 512;
1903 	} else if (GPUVMEnable == true) {
1904 		*vm_group_bytes = 2048;
1905 		if (SurfaceTiling != dm_sw_linear && PixelPTEReqHeightPTEs == 1 && ScanDirection == dm_vert) {
1906 			*dpte_group_bytes = 512;
1907 		} else {
1908 			*dpte_group_bytes = 2048;
1909 		}
1910 	} else {
1911 		*vm_group_bytes = 0;
1912 		*dpte_group_bytes = 0;
1913 	}
1914 
1915 	return PDEAndMetaPTEBytesFrame;
1916 }
1917 
DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib * mode_lib)1918 static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
1919 		struct display_mode_lib *mode_lib)
1920 {
1921 	struct vba_vars_st *v = &mode_lib->vba;
1922 	unsigned int j, k;
1923 	long ReorderBytes = 0;
1924 	unsigned int PrefetchMode = v->PrefetchModePerState[v->VoltageLevel][v->maxMpcComb];
1925 	double MaxTotalRDBandwidth = 0;
1926 	double MaxTotalRDBandwidthNoUrgentBurst = 0;
1927 	bool DestinationLineTimesForPrefetchLessThan2 = false;
1928 	bool VRatioPrefetchMoreThan4 = false;
1929 	double TWait;
1930 
1931 	v->WritebackDISPCLK = 0.0;
1932 	v->DISPCLKWithRamping = 0;
1933 	v->DISPCLKWithoutRamping = 0;
1934 	v->GlobalDPPCLK = 0.0;
1935 	/* DAL custom code: need to update ReturnBW in case min dcfclk is overriden */
1936 	v->IdealSDPPortBandwidthPerState[v->VoltageLevel][v->maxMpcComb] = dml_min3(
1937 			v->ReturnBusWidth * v->DCFCLK,
1938 			v->DRAMSpeedPerState[v->VoltageLevel] * v->NumberOfChannels * v->DRAMChannelWidth,
1939 			v->FabricClockPerState[v->VoltageLevel] * v->FabricDatapathToDCNDataReturn);
1940 	if (v->HostVMEnable != true) {
1941 		v->ReturnBW = v->IdealSDPPortBandwidthPerState[v->VoltageLevel][v->maxMpcComb] * v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
1942 	} else {
1943 		v->ReturnBW = v->IdealSDPPortBandwidthPerState[v->VoltageLevel][v->maxMpcComb] * v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100;
1944 	}
1945 	/* End DAL custom code */
1946 
1947 	// DISPCLK and DPPCLK Calculation
1948 	//
1949 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
1950 		if (v->WritebackEnable[k]) {
1951 			v->WritebackDISPCLK = dml_max(v->WritebackDISPCLK,
1952 				dml30_CalculateWriteBackDISPCLK(
1953 						v->WritebackPixelFormat[k],
1954 						v->PixelClock[k],
1955 						v->WritebackHRatio[k],
1956 						v->WritebackVRatio[k],
1957 						v->WritebackHTaps[k],
1958 						v->WritebackVTaps[k],
1959 						v->WritebackSourceWidth[k],
1960 						v->WritebackDestinationWidth[k],
1961 						v->HTotal[k],
1962 						v->WritebackLineBufferSize));
1963 		}
1964 	}
1965 
1966 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
1967 		if (v->HRatio[k] > 1) {
1968 			v->PSCL_THROUGHPUT_LUMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput,
1969 				v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1));
1970 		} else {
1971 			v->PSCL_THROUGHPUT_LUMA[k] = dml_min(
1972 					v->MaxDCHUBToPSCLThroughput,
1973 					v->MaxPSCLToLBThroughput);
1974 		}
1975 
1976 		v->DPPCLKUsingSingleDPPLuma = v->PixelClock[k]
1977 			* dml_max(v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
1978 				dml_max(v->HRatio[k] * v->VRatio[k] / v->PSCL_THROUGHPUT_LUMA[k], 1.0));
1979 
1980 		if ((v->htaps[k] > 6 || v->vtaps[k] > 6)
1981 				&& v->DPPCLKUsingSingleDPPLuma < 2 * v->PixelClock[k]) {
1982 			v->DPPCLKUsingSingleDPPLuma = 2 * v->PixelClock[k];
1983 		}
1984 
1985 		if ((v->SourcePixelFormat[k] != dm_420_8
1986 				&& v->SourcePixelFormat[k] != dm_420_10
1987 				&& v->SourcePixelFormat[k] != dm_420_12
1988 				&& v->SourcePixelFormat[k] != dm_rgbe_alpha)) {
1989 			v->PSCL_THROUGHPUT_CHROMA[k] = 0.0;
1990 			v->DPPCLKUsingSingleDPP[k] = v->DPPCLKUsingSingleDPPLuma;
1991 		} else {
1992 			if (v->HRatioChroma[k] > 1) {
1993 				v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput,
1994 					v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
1995 			} else {
1996 				v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(
1997 						v->MaxDCHUBToPSCLThroughput,
1998 						v->MaxPSCLToLBThroughput);
1999 			}
2000 			v->DPPCLKUsingSingleDPPChroma = v->PixelClock[k]
2001 				* dml_max3(v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
2002 					v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_THROUGHPUT_CHROMA[k], 1.0);
2003 
2004 			if ((v->HTAPsChroma[k] > 6 || v->VTAPsChroma[k] > 6)
2005 					&& v->DPPCLKUsingSingleDPPChroma
2006 							< 2 * v->PixelClock[k]) {
2007 				v->DPPCLKUsingSingleDPPChroma = 2
2008 						* v->PixelClock[k];
2009 			}
2010 
2011 			v->DPPCLKUsingSingleDPP[k] = dml_max(
2012 					v->DPPCLKUsingSingleDPPLuma,
2013 					v->DPPCLKUsingSingleDPPChroma);
2014 		}
2015 	}
2016 
2017 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2018 		if (v->BlendingAndTiming[k] != k)
2019 			continue;
2020 		if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1) {
2021 			v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping,
2022 				v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
2023 					* (1 + v->DISPCLKRampingMargin / 100));
2024 			v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping,
2025 				v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2026 		} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
2027 			v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping,
2028 				v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
2029 					* (1 + v->DISPCLKRampingMargin / 100));
2030 			v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping,
2031 				v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2032 		} else {
2033 			v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping,
2034 				v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
2035 									* (1 + v->DISPCLKRampingMargin / 100));
2036 			v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping,
2037 				v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2038 		}
2039 	}
2040 
2041 	v->DISPCLKWithRamping = dml_max(
2042 			v->DISPCLKWithRamping,
2043 			v->WritebackDISPCLK);
2044 	v->DISPCLKWithoutRamping = dml_max(
2045 			v->DISPCLKWithoutRamping,
2046 			v->WritebackDISPCLK);
2047 
2048 	ASSERT(v->DISPCLKDPPCLKVCOSpeed != 0);
2049 	v->DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
2050 			v->DISPCLKWithRamping,
2051 			v->DISPCLKDPPCLKVCOSpeed);
2052 	v->DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
2053 			v->DISPCLKWithoutRamping,
2054 			v->DISPCLKDPPCLKVCOSpeed);
2055 	v->MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
2056 			v->soc.clock_limits[mode_lib->soc.num_states - 1].dispclk_mhz,
2057 			v->DISPCLKDPPCLKVCOSpeed);
2058 	if (v->DISPCLKWithoutRampingRoundedToDFSGranularity
2059 			> v->MaxDispclkRoundedToDFSGranularity) {
2060 		v->DISPCLK_calculated =
2061 				v->DISPCLKWithoutRampingRoundedToDFSGranularity;
2062 	} else if (v->DISPCLKWithRampingRoundedToDFSGranularity
2063 			> v->MaxDispclkRoundedToDFSGranularity) {
2064 		v->DISPCLK_calculated = v->MaxDispclkRoundedToDFSGranularity;
2065 	} else {
2066 		v->DISPCLK_calculated =
2067 				v->DISPCLKWithRampingRoundedToDFSGranularity;
2068 	}
2069 	v->DISPCLK = v->DISPCLK_calculated;
2070 	DTRACE("   dispclk_mhz (calculated) = %f", v->DISPCLK_calculated);
2071 
2072 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2073 		v->DPPCLK_calculated[k] = v->DPPCLKUsingSingleDPP[k]
2074 				/ v->DPPPerPlane[k]
2075 				* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2076 		v->GlobalDPPCLK = dml_max(
2077 				v->GlobalDPPCLK,
2078 				v->DPPCLK_calculated[k]);
2079 	}
2080 	v->GlobalDPPCLK = RoundToDFSGranularityUp(
2081 			v->GlobalDPPCLK,
2082 			v->DISPCLKDPPCLKVCOSpeed);
2083 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2084 		v->DPPCLK_calculated[k] = v->GlobalDPPCLK / 255
2085 				* dml_ceil(
2086 						v->DPPCLK_calculated[k] * 255.0
2087 								/ v->GlobalDPPCLK,
2088 						1);
2089 		DTRACE("   dppclk_mhz[%i] (calculated) = %f", k, v->DPPCLK_calculated[k]);
2090 		v->DPPCLK[k] = v->DPPCLK_calculated[k];
2091 	}
2092 
2093 	// Urgent and B P-State/DRAM Clock Change Watermark
2094 	DTRACE("   dcfclk_mhz         = %f", v->DCFCLK);
2095 	DTRACE("   return_bus_bw      = %f", v->ReturnBW);
2096 
2097 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2098 		CalculateBytePerPixelAnd256BBlockSizes(
2099 				v->SourcePixelFormat[k],
2100 				v->SurfaceTiling[k],
2101 				&v->BytePerPixelY[k],
2102 				&v->BytePerPixelC[k],
2103 				&v->BytePerPixelDETY[k],
2104 				&v->BytePerPixelDETC[k],
2105 				&v->BlockHeight256BytesY[k],
2106 				&v->BlockHeight256BytesC[k],
2107 				&v->BlockWidth256BytesY[k],
2108 				&v->BlockWidth256BytesC[k]);
2109 	}
2110 
2111 	CalculateSwathWidth(
2112 			false,
2113 			v->NumberOfActivePlanes,
2114 			v->SourcePixelFormat,
2115 			v->SourceScan,
2116 			v->ViewportWidth,
2117 			v->ViewportHeight,
2118 			v->SurfaceWidthY,
2119 			v->SurfaceWidthC,
2120 			v->SurfaceHeightY,
2121 			v->SurfaceHeightC,
2122 			v->ODMCombineEnabled,
2123 			v->BytePerPixelY,
2124 			v->BytePerPixelC,
2125 			v->BlockHeight256BytesY,
2126 			v->BlockHeight256BytesC,
2127 			v->BlockWidth256BytesY,
2128 			v->BlockWidth256BytesC,
2129 			v->BlendingAndTiming,
2130 			v->HActive,
2131 			v->HRatio,
2132 			v->DPPPerPlane,
2133 			v->SwathWidthSingleDPPY,
2134 			v->SwathWidthSingleDPPC,
2135 			v->SwathWidthY,
2136 			v->SwathWidthC,
2137 			v->dummyinteger3,
2138 			v->dummyinteger4,
2139 			v->swath_width_luma_ub,
2140 			v->swath_width_chroma_ub);
2141 
2142 
2143 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2144 		v->ReadBandwidthPlaneLuma[k] = v->SwathWidthSingleDPPY[k] * v->BytePerPixelY[k] / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
2145 		v->ReadBandwidthPlaneChroma[k] = v->SwathWidthSingleDPPC[k] * v->BytePerPixelC[k] / (v->HTotal[k] / v->PixelClock[k]) * v->VRatioChroma[k];
2146 		DTRACE("read_bw[%i] = %fBps", k, v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k]);
2147 	}
2148 
2149 
2150 	// DCFCLK Deep Sleep
2151 	CalculateDCFCLKDeepSleep(
2152 			mode_lib,
2153 			v->NumberOfActivePlanes,
2154 			v->BytePerPixelY,
2155 			v->BytePerPixelC,
2156 			v->VRatio,
2157 			v->VRatioChroma,
2158 			v->SwathWidthY,
2159 			v->SwathWidthC,
2160 			v->DPPPerPlane,
2161 			v->HRatio,
2162 			v->HRatioChroma,
2163 			v->PixelClock,
2164 			v->PSCL_THROUGHPUT_LUMA,
2165 			v->PSCL_THROUGHPUT_CHROMA,
2166 			v->DPPCLK,
2167 			v->ReadBandwidthPlaneLuma,
2168 			v->ReadBandwidthPlaneChroma,
2169 			v->ReturnBusWidth,
2170 			&v->DCFCLKDeepSleep);
2171 
2172 	// DSCCLK
2173 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2174 		if ((v->BlendingAndTiming[k] != k) || !v->DSCEnabled[k]) {
2175 			v->DSCCLK_calculated[k] = 0.0;
2176 		} else {
2177 			if (v->OutputFormat[k] == dm_420)
2178 				v->DSCFormatFactor = 2;
2179 			else if (v->OutputFormat[k] == dm_444)
2180 				v->DSCFormatFactor = 1;
2181 			else if (v->OutputFormat[k] == dm_n422)
2182 				v->DSCFormatFactor = 2;
2183 			else
2184 				v->DSCFormatFactor = 1;
2185 			if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
2186 				v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 12
2187 					/ v->DSCFormatFactor / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2188 			else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
2189 				v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 6
2190 					/ v->DSCFormatFactor / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2191 			else
2192 				v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 3
2193 					/ v->DSCFormatFactor / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2194 		}
2195 	}
2196 
2197 	// DSC Delay
2198 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2199 		double BPP = v->OutputBppPerState[k][v->VoltageLevel];
2200 
2201 		if (v->DSCEnabled[k] && BPP != 0) {
2202 			if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_disabled) {
2203 				v->DSCDelay[k] = dscceComputeDelay(v->DSCInputBitPerComponent[k],
2204 						BPP,
2205 						dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2206 						v->NumberOfDSCSlices[k],
2207 						v->OutputFormat[k],
2208 						v->Output[k])
2209 					+ dscComputeDelay(v->OutputFormat[k], v->Output[k]);
2210 			} else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
2211 				v->DSCDelay[k] = 2 * dscceComputeDelay(v->DSCInputBitPerComponent[k],
2212 						BPP,
2213 						dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2214 						v->NumberOfDSCSlices[k] / 2.0,
2215 						v->OutputFormat[k],
2216 						v->Output[k])
2217 					+ dscComputeDelay(v->OutputFormat[k], v->Output[k]);
2218 			} else {
2219 				v->DSCDelay[k] = 4 * dscceComputeDelay(v->DSCInputBitPerComponent[k],
2220 						BPP,
2221 						dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2222 						v->NumberOfDSCSlices[k] / 4.0,
2223 						v->OutputFormat[k],
2224 						v->Output[k])
2225 					+ dscComputeDelay(v->OutputFormat[k], v->Output[k]);
2226 			}
2227 			v->DSCDelay[k] = v->DSCDelay[k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
2228 		} else {
2229 			v->DSCDelay[k] = 0;
2230 		}
2231 	}
2232 
2233 	for (k = 0; k < v->NumberOfActivePlanes; ++k)
2234 		for (j = 0; j < v->NumberOfActivePlanes; ++j) // NumberOfPlanes
2235 			if (j != k && v->BlendingAndTiming[k] == j
2236 					&& v->DSCEnabled[j])
2237 				v->DSCDelay[k] = v->DSCDelay[j];
2238 
2239 	// Prefetch
2240 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2241 		unsigned int PDEAndMetaPTEBytesFrameY = 0;
2242 		unsigned int PixelPTEBytesPerRowY = 0;
2243 		unsigned int MetaRowByteY = 0;
2244 		unsigned int MetaRowByteC = 0;
2245 		unsigned int PDEAndMetaPTEBytesFrameC = 0;
2246 		unsigned int PixelPTEBytesPerRowC = 0;
2247 		bool         PTEBufferSizeNotExceededY = 0;
2248 		bool         PTEBufferSizeNotExceededC = 0;
2249 
2250 
2251 		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) {
2252 			if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) && v->SourceScan[k] != dm_vert) {
2253 				v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma) / 2;
2254 				v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
2255 			} else {
2256 				v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
2257 				v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
2258 
2259 			}
2260 			PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(
2261 					mode_lib,
2262 					v->DCCEnable[k],
2263 					v->BlockHeight256BytesC[k],
2264 					v->BlockWidth256BytesC[k],
2265 					v->SourcePixelFormat[k],
2266 					v->SurfaceTiling[k],
2267 					v->BytePerPixelC[k],
2268 					v->SourceScan[k],
2269 					v->SwathWidthC[k],
2270 					v->ViewportHeightChroma[k],
2271 					v->GPUVMEnable,
2272 					v->HostVMEnable,
2273 					v->HostVMMaxNonCachedPageTableLevels,
2274 					v->GPUVMMinPageSize,
2275 					v->HostVMMinPageSize,
2276 					v->PTEBufferSizeInRequestsForChroma,
2277 					v->PitchC[k],
2278 					v->DCCMetaPitchC[k],
2279 					&v->MacroTileWidthC[k],
2280 					&MetaRowByteC,
2281 					&PixelPTEBytesPerRowC,
2282 					&PTEBufferSizeNotExceededC,
2283 					&v->dpte_row_width_chroma_ub[k],
2284 					&v->dpte_row_height_chroma[k],
2285 					&v->meta_req_width_chroma[k],
2286 					&v->meta_req_height_chroma[k],
2287 					&v->meta_row_width_chroma[k],
2288 					&v->meta_row_height_chroma[k],
2289 					&v->dummyinteger1,
2290 					&v->dummyinteger2,
2291 					&v->PixelPTEReqWidthC[k],
2292 					&v->PixelPTEReqHeightC[k],
2293 					&v->PTERequestSizeC[k],
2294 					&v->dpde0_bytes_per_frame_ub_c[k],
2295 					&v->meta_pte_bytes_per_frame_ub_c[k]);
2296 
2297 			v->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
2298 					mode_lib,
2299 					v->VRatioChroma[k],
2300 					v->VTAPsChroma[k],
2301 					v->Interlace[k],
2302 					v->ProgressiveToInterlaceUnitInOPP,
2303 					v->SwathHeightC[k],
2304 					v->ViewportYStartC[k],
2305 					&v->VInitPreFillC[k],
2306 					&v->MaxNumSwathC[k]);
2307 		} else {
2308 			v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
2309 			v->PTEBufferSizeInRequestsForChroma = 0;
2310 			PixelPTEBytesPerRowC = 0;
2311 			PDEAndMetaPTEBytesFrameC = 0;
2312 			MetaRowByteC = 0;
2313 			v->MaxNumSwathC[k] = 0;
2314 			v->PrefetchSourceLinesC[k] = 0;
2315 		}
2316 
2317 		PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
2318 				mode_lib,
2319 				v->DCCEnable[k],
2320 				v->BlockHeight256BytesY[k],
2321 				v->BlockWidth256BytesY[k],
2322 				v->SourcePixelFormat[k],
2323 				v->SurfaceTiling[k],
2324 				v->BytePerPixelY[k],
2325 				v->SourceScan[k],
2326 				v->SwathWidthY[k],
2327 				v->ViewportHeight[k],
2328 				v->GPUVMEnable,
2329 				v->HostVMEnable,
2330 				v->HostVMMaxNonCachedPageTableLevels,
2331 				v->GPUVMMinPageSize,
2332 				v->HostVMMinPageSize,
2333 				v->PTEBufferSizeInRequestsForLuma,
2334 				v->PitchY[k],
2335 				v->DCCMetaPitchY[k],
2336 				&v->MacroTileWidthY[k],
2337 				&MetaRowByteY,
2338 				&PixelPTEBytesPerRowY,
2339 				&PTEBufferSizeNotExceededY,
2340 				&v->dpte_row_width_luma_ub[k],
2341 				&v->dpte_row_height[k],
2342 				&v->meta_req_width[k],
2343 				&v->meta_req_height[k],
2344 				&v->meta_row_width[k],
2345 				&v->meta_row_height[k],
2346 				&v->vm_group_bytes[k],
2347 				&v->dpte_group_bytes[k],
2348 				&v->PixelPTEReqWidthY[k],
2349 				&v->PixelPTEReqHeightY[k],
2350 				&v->PTERequestSizeY[k],
2351 				&v->dpde0_bytes_per_frame_ub_l[k],
2352 				&v->meta_pte_bytes_per_frame_ub_l[k]);
2353 
2354 		v->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
2355 				mode_lib,
2356 				v->VRatio[k],
2357 				v->vtaps[k],
2358 				v->Interlace[k],
2359 				v->ProgressiveToInterlaceUnitInOPP,
2360 				v->SwathHeightY[k],
2361 				v->ViewportYStartY[k],
2362 				&v->VInitPreFillY[k],
2363 				&v->MaxNumSwathY[k]);
2364 		v->PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
2365 		v->PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
2366 				+ PDEAndMetaPTEBytesFrameC;
2367 		v->MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
2368 
2369 		CalculateRowBandwidth(
2370 				v->GPUVMEnable,
2371 				v->SourcePixelFormat[k],
2372 				v->VRatio[k],
2373 				v->VRatioChroma[k],
2374 				v->DCCEnable[k],
2375 				v->HTotal[k] / v->PixelClock[k],
2376 				MetaRowByteY,
2377 				MetaRowByteC,
2378 				v->meta_row_height[k],
2379 				v->meta_row_height_chroma[k],
2380 				PixelPTEBytesPerRowY,
2381 				PixelPTEBytesPerRowC,
2382 				v->dpte_row_height[k],
2383 				v->dpte_row_height_chroma[k],
2384 				&v->meta_row_bw[k],
2385 				&v->dpte_row_bw[k]);
2386 	}
2387 
2388 	v->TotalDCCActiveDPP = 0;
2389 	v->TotalActiveDPP = 0;
2390 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2391 		v->TotalActiveDPP = v->TotalActiveDPP
2392 				+ v->DPPPerPlane[k];
2393 		if (v->DCCEnable[k])
2394 			v->TotalDCCActiveDPP = v->TotalDCCActiveDPP
2395 					+ v->DPPPerPlane[k];
2396 	}
2397 
2398 
2399 	ReorderBytes = v->NumberOfChannels * dml_max3(
2400 		v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
2401 		v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
2402 		v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
2403 
2404 	v->UrgentExtraLatency = CalculateExtraLatency(
2405 		v->RoundTripPingLatencyCycles,
2406 		ReorderBytes,
2407 		v->DCFCLK,
2408 		v->TotalActiveDPP,
2409 		v->PixelChunkSizeInKByte,
2410 		v->TotalDCCActiveDPP,
2411 		v->MetaChunkSize,
2412 		v->ReturnBW,
2413 		v->GPUVMEnable,
2414 		v->HostVMEnable,
2415 		v->NumberOfActivePlanes,
2416 		v->DPPPerPlane,
2417 		v->dpte_group_bytes,
2418 		v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
2419 		v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
2420 		v->HostVMMinPageSize,
2421 		v->HostVMMaxNonCachedPageTableLevels);
2422 
2423 	v->TCalc = 24.0 / v->DCFCLKDeepSleep;
2424 
2425 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2426 		if (v->BlendingAndTiming[k] == k) {
2427 			if (v->WritebackEnable[k] == true) {
2428 				v->WritebackDelay[v->VoltageLevel][k] = v->WritebackLatency +
2429 						CalculateWriteBackDelay(v->WritebackPixelFormat[k],
2430 									v->WritebackHRatio[k],
2431 									v->WritebackVRatio[k],
2432 									v->WritebackVTaps[k],
2433 									v->WritebackDestinationWidth[k],
2434 									v->WritebackDestinationHeight[k],
2435 									v->WritebackSourceHeight[k],
2436 									v->HTotal[k]) / v->DISPCLK;
2437 			} else
2438 				v->WritebackDelay[v->VoltageLevel][k] = 0;
2439 			for (j = 0; j < v->NumberOfActivePlanes; ++j) {
2440 				if (v->BlendingAndTiming[j] == k
2441 						&& v->WritebackEnable[j] == true) {
2442 					v->WritebackDelay[v->VoltageLevel][k] = dml_max(v->WritebackDelay[v->VoltageLevel][k],
2443 							v->WritebackLatency + CalculateWriteBackDelay(
2444 											v->WritebackPixelFormat[j],
2445 											v->WritebackHRatio[j],
2446 											v->WritebackVRatio[j],
2447 											v->WritebackVTaps[j],
2448 											v->WritebackDestinationWidth[j],
2449 											v->WritebackDestinationHeight[j],
2450 											v->WritebackSourceHeight[j],
2451 											v->HTotal[k]) / v->DISPCLK);
2452 				}
2453 			}
2454 		}
2455 	}
2456 
2457 	for (k = 0; k < v->NumberOfActivePlanes; ++k)
2458 		for (j = 0; j < v->NumberOfActivePlanes; ++j)
2459 			if (v->BlendingAndTiming[k] == j)
2460 				v->WritebackDelay[v->VoltageLevel][k] = v->WritebackDelay[v->VoltageLevel][j];
2461 
2462 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2463 		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));
2464 	}
2465 
2466 	v->MaximumMaxVStartupLines = 0;
2467 	for (k = 0; k < v->NumberOfActivePlanes; ++k)
2468 		v->MaximumMaxVStartupLines = dml_max(v->MaximumMaxVStartupLines, v->MaxVStartupLines[k]);
2469 
2470 	if (v->DRAMClockChangeLatencyOverride > 0.0) {
2471 		v->FinalDRAMClockChangeLatency = v->DRAMClockChangeLatencyOverride;
2472 	} else {
2473 		v->FinalDRAMClockChangeLatency = v->DRAMClockChangeLatency;
2474 	}
2475 	v->UrgentLatency = CalculateUrgentLatency(v->UrgentLatencyPixelDataOnly, v->UrgentLatencyPixelMixedWithVMData, v->UrgentLatencyVMDataOnly, v->DoUrgentLatencyAdjustment, v->UrgentLatencyAdjustmentFabricClockComponent, v->UrgentLatencyAdjustmentFabricClockReference, v->FabricClock);
2476 
2477 
2478 	v->FractionOfUrgentBandwidth = 0.0;
2479 	v->FractionOfUrgentBandwidthImmediateFlip = 0.0;
2480 
2481 	v->VStartupLines = 13;
2482 
2483 	do {
2484 		MaxTotalRDBandwidth = 0;
2485 		MaxTotalRDBandwidthNoUrgentBurst = 0;
2486 		DestinationLineTimesForPrefetchLessThan2 = false;
2487 		VRatioPrefetchMoreThan4 = false;
2488 		TWait = CalculateTWait(
2489 				PrefetchMode,
2490 				v->FinalDRAMClockChangeLatency,
2491 				v->UrgentLatency,
2492 				v->SREnterPlusExitTime);
2493 
2494 		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2495 			Pipe myPipe = { 0 };
2496 
2497 			myPipe.DPPCLK = v->DPPCLK[k];
2498 			myPipe.DISPCLK = v->DISPCLK;
2499 			myPipe.PixelClock = v->PixelClock[k];
2500 			myPipe.DCFCLKDeepSleep = v->DCFCLKDeepSleep;
2501 			myPipe.DPPPerPlane = v->DPPPerPlane[k];
2502 			myPipe.ScalerEnabled = v->ScalerEnabled[k];
2503 			myPipe.SourceScan = v->SourceScan[k];
2504 			myPipe.BlockWidth256BytesY = v->BlockWidth256BytesY[k];
2505 			myPipe.BlockHeight256BytesY = v->BlockHeight256BytesY[k];
2506 			myPipe.BlockWidth256BytesC = v->BlockWidth256BytesC[k];
2507 			myPipe.BlockHeight256BytesC = v->BlockHeight256BytesC[k];
2508 			myPipe.InterlaceEnable = v->Interlace[k];
2509 			myPipe.NumberOfCursors = v->NumberOfCursors[k];
2510 			myPipe.VBlank = v->VTotal[k] - v->VActive[k];
2511 			myPipe.HTotal = v->HTotal[k];
2512 			myPipe.DCCEnable = v->DCCEnable[k];
2513 			myPipe.ODMCombineEnabled = !!v->ODMCombineEnabled[k];
2514 
2515 			v->ErrorResult[k] = CalculatePrefetchSchedule(
2516 					mode_lib,
2517 					v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
2518 					v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
2519 					&myPipe,
2520 					v->DSCDelay[k],
2521 					v->DPPCLKDelaySubtotal
2522 							+ v->DPPCLKDelayCNVCFormater,
2523 					v->DPPCLKDelaySCL,
2524 					v->DPPCLKDelaySCLLBOnly,
2525 					v->DPPCLKDelayCNVCCursor,
2526 					v->DISPCLKDelaySubtotal,
2527 					(unsigned int) (v->SwathWidthY[k] / v->HRatio[k]),
2528 					v->OutputFormat[k],
2529 					v->MaxInterDCNTileRepeaters,
2530 					dml_min(v->VStartupLines, v->MaxVStartupLines[k]),
2531 					v->MaxVStartupLines[k],
2532 					v->GPUVMMaxPageTableLevels,
2533 					v->GPUVMEnable,
2534 					v->HostVMEnable,
2535 					v->HostVMMaxNonCachedPageTableLevels,
2536 					v->HostVMMinPageSize,
2537 					v->DynamicMetadataEnable[k],
2538 					v->DynamicMetadataVMEnabled,
2539 					v->DynamicMetadataLinesBeforeActiveRequired[k],
2540 					v->DynamicMetadataTransmittedBytes[k],
2541 					v->UrgentLatency,
2542 					v->UrgentExtraLatency,
2543 					v->TCalc,
2544 					v->PDEAndMetaPTEBytesFrame[k],
2545 					v->MetaRowByte[k],
2546 					v->PixelPTEBytesPerRow[k],
2547 					v->PrefetchSourceLinesY[k],
2548 					v->SwathWidthY[k],
2549 					v->BytePerPixelY[k],
2550 					v->VInitPreFillY[k],
2551 					v->MaxNumSwathY[k],
2552 					v->PrefetchSourceLinesC[k],
2553 					v->SwathWidthC[k],
2554 					v->BytePerPixelC[k],
2555 					v->VInitPreFillC[k],
2556 					v->MaxNumSwathC[k],
2557 					v->swath_width_luma_ub[k],
2558 					v->swath_width_chroma_ub[k],
2559 					v->SwathHeightY[k],
2560 					v->SwathHeightC[k],
2561 					TWait,
2562 					v->ProgressiveToInterlaceUnitInOPP,
2563 					&v->DSTXAfterScaler[k],
2564 					&v->DSTYAfterScaler[k],
2565 					&v->DestinationLinesForPrefetch[k],
2566 					&v->PrefetchBandwidth[k],
2567 					&v->DestinationLinesToRequestVMInVBlank[k],
2568 					&v->DestinationLinesToRequestRowInVBlank[k],
2569 					&v->VRatioPrefetchY[k],
2570 					&v->VRatioPrefetchC[k],
2571 					&v->RequiredPrefetchPixDataBWLuma[k],
2572 					&v->RequiredPrefetchPixDataBWChroma[k],
2573 					&v->NotEnoughTimeForDynamicMetadata[k],
2574 					&v->Tno_bw[k],
2575 					&v->prefetch_vmrow_bw[k],
2576 					&v->Tdmdl_vm[k],
2577 					&v->Tdmdl[k],
2578 					&v->VUpdateOffsetPix[k],
2579 					&v->VUpdateWidthPix[k],
2580 					&v->VReadyOffsetPix[k]);
2581 			if (v->BlendingAndTiming[k] == k) {
2582 				double TotalRepeaterDelayTime = v->MaxInterDCNTileRepeaters * (2 / v->DPPCLK[k] + 3 / v->DISPCLK);
2583 				v->VUpdateWidthPix[k] = (14 / v->DCFCLKDeepSleep + 12 / v->DPPCLK[k] + TotalRepeaterDelayTime) * v->PixelClock[k];
2584 				v->VReadyOffsetPix[k] = dml_max(150.0 / v->DPPCLK[k], TotalRepeaterDelayTime + 20 / v->DCFCLKDeepSleep + 10 / v->DPPCLK[k]) * v->PixelClock[k];
2585 				v->VUpdateOffsetPix[k] = dml_ceil(v->HTotal[k] / 4.0, 1);
2586 				v->VStartup[k] = dml_min(v->VStartupLines, v->MaxVStartupLines[k]);
2587 			} else {
2588 				int x = v->BlendingAndTiming[k];
2589 				double TotalRepeaterDelayTime = v->MaxInterDCNTileRepeaters * (2 / v->DPPCLK[k] + 3 / v->DISPCLK);
2590 				v->VUpdateWidthPix[k] = (14 / v->DCFCLKDeepSleep + 12 / v->DPPCLK[k] + TotalRepeaterDelayTime) * v->PixelClock[x];
2591 				v->VReadyOffsetPix[k] = dml_max(150.0 / v->DPPCLK[k], TotalRepeaterDelayTime + 20 / v->DCFCLKDeepSleep + 10 / v->DPPCLK[k]) * v->PixelClock[x];
2592 				v->VUpdateOffsetPix[k] = dml_ceil(v->HTotal[x] / 4.0, 1);
2593 				if (!v->MaxVStartupLines[x])
2594 					v->MaxVStartupLines[x] = v->MaxVStartupLines[k];
2595 				v->VStartup[k] = dml_min(v->VStartupLines, v->MaxVStartupLines[x]);
2596 			}
2597 		}
2598 
2599 		v->NotEnoughUrgentLatencyHiding[0][0] = false;
2600 		v->NotEnoughUrgentLatencyHidingPre = false;
2601 
2602 		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2603 			v->cursor_bw[k] = v->NumberOfCursors[k]
2604 					* v->CursorWidth[k][0] * v->CursorBPP[k][0]
2605 					/ 8.0
2606 					/ (v->HTotal[k] / v->PixelClock[k])
2607 					* v->VRatio[k];
2608 			v->cursor_bw_pre[k] = v->NumberOfCursors[k]
2609 					* v->CursorWidth[k][0] * v->CursorBPP[k][0]
2610 					/ 8.0
2611 					/ (v->HTotal[k] / v->PixelClock[k])
2612 					* v->VRatioPrefetchY[k];
2613 
2614 			CalculateUrgentBurstFactor(
2615 					v->swath_width_luma_ub[k],
2616 					v->swath_width_chroma_ub[k],
2617 					v->DETBufferSizeInKByte[0],
2618 					v->SwathHeightY[k],
2619 					v->SwathHeightC[k],
2620 					v->HTotal[k] / v->PixelClock[k],
2621 					v->UrgentLatency,
2622 					v->CursorBufferSize,
2623 					v->CursorWidth[k][0],
2624 					v->CursorBPP[k][0],
2625 					v->VRatio[k],
2626 					v->VRatioChroma[k],
2627 					v->BytePerPixelDETY[k],
2628 					v->BytePerPixelDETC[k],
2629 					v->DETBufferSizeY[k],
2630 					v->DETBufferSizeC[k],
2631 					&v->UrgentBurstFactorCursor[k],
2632 					&v->UrgentBurstFactorLuma[k],
2633 					&v->UrgentBurstFactorChroma[k],
2634 					&v->NoUrgentLatencyHiding[k]);
2635 
2636 			CalculateUrgentBurstFactor(
2637 					v->swath_width_luma_ub[k],
2638 					v->swath_width_chroma_ub[k],
2639 					v->DETBufferSizeInKByte[0],
2640 					v->SwathHeightY[k],
2641 					v->SwathHeightC[k],
2642 					v->HTotal[k] / v->PixelClock[k],
2643 					v->UrgentLatency,
2644 					v->CursorBufferSize,
2645 					v->CursorWidth[k][0],
2646 					v->CursorBPP[k][0],
2647 					v->VRatioPrefetchY[k],
2648 					v->VRatioPrefetchC[k],
2649 					v->BytePerPixelDETY[k],
2650 					v->BytePerPixelDETC[k],
2651 					v->DETBufferSizeY[k],
2652 					v->DETBufferSizeC[k],
2653 					&v->UrgentBurstFactorCursorPre[k],
2654 					&v->UrgentBurstFactorLumaPre[k],
2655 					&v->UrgentBurstFactorChromaPre[k],
2656 					&v->NoUrgentLatencyHidingPre[k]);
2657 
2658 			MaxTotalRDBandwidth = MaxTotalRDBandwidth +
2659 				dml_max3(v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2660 					v->ReadBandwidthPlaneLuma[k] *
2661 					v->UrgentBurstFactorLuma[k] +
2662 					v->ReadBandwidthPlaneChroma[k] *
2663 					v->UrgentBurstFactorChroma[k] +
2664 					v->cursor_bw[k] *
2665 					v->UrgentBurstFactorCursor[k] +
2666 					v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
2667 					v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgentBurstFactorLumaPre[k] +
2668 						v->RequiredPrefetchPixDataBWChroma[k] * v->UrgentBurstFactorChromaPre[k]) + v->cursor_bw_pre[k] *
2669 					v->UrgentBurstFactorCursorPre[k]);
2670 
2671 			MaxTotalRDBandwidthNoUrgentBurst = MaxTotalRDBandwidthNoUrgentBurst +
2672 				dml_max3(v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2673 					v->ReadBandwidthPlaneLuma[k] +
2674 					v->ReadBandwidthPlaneChroma[k] +
2675 					v->cursor_bw[k] +
2676 					v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
2677 					v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] + v->RequiredPrefetchPixDataBWChroma[k]) + v->cursor_bw_pre[k]);
2678 
2679 			if (v->DestinationLinesForPrefetch[k] < 2)
2680 				DestinationLineTimesForPrefetchLessThan2 = true;
2681 			if (v->VRatioPrefetchY[k] > 4 || v->VRatioPrefetchC[k] > 4)
2682 				VRatioPrefetchMoreThan4 = true;
2683 			if (v->NoUrgentLatencyHiding[k] == true)
2684 				v->NotEnoughUrgentLatencyHiding[0][0] = true;
2685 
2686 			if (v->NoUrgentLatencyHidingPre[k] == true)
2687 				v->NotEnoughUrgentLatencyHidingPre = true;
2688 		}
2689 		v->FractionOfUrgentBandwidth = MaxTotalRDBandwidthNoUrgentBurst / v->ReturnBW;
2690 
2691 
2692 		if (MaxTotalRDBandwidth <= v->ReturnBW && v->NotEnoughUrgentLatencyHiding[0][0] == 0
2693 				&& v->NotEnoughUrgentLatencyHidingPre == 0 && !VRatioPrefetchMoreThan4
2694 				&& !DestinationLineTimesForPrefetchLessThan2)
2695 			v->PrefetchModeSupported = true;
2696 		else {
2697 			v->PrefetchModeSupported = false;
2698 			dml_print("DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
2699 			dml_print("DML: MaxTotalRDBandwidth:%f AvailReturnBandwidth:%f\n", MaxTotalRDBandwidth, v->ReturnBW);
2700 			dml_print("DML: VRatioPrefetch %s more than 4\n", (VRatioPrefetchMoreThan4) ? "is" : "is not");
2701 			dml_print("DML: DestinationLines for Prefetch %s less than 2\n", (DestinationLineTimesForPrefetchLessThan2) ? "is" : "is not");
2702 		}
2703 
2704 		if (v->PrefetchModeSupported == true && v->ImmediateFlipSupport == true) {
2705 			v->BandwidthAvailableForImmediateFlip = v->ReturnBW;
2706 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2707 				v->BandwidthAvailableForImmediateFlip =
2708 						v->BandwidthAvailableForImmediateFlip
2709 								- dml_max(
2710 										v->ReadBandwidthPlaneLuma[k] * v->UrgentBurstFactorLuma[k]
2711 												+ v->ReadBandwidthPlaneChroma[k] * v->UrgentBurstFactorChroma[k]
2712 												+ v->cursor_bw[k] * v->UrgentBurstFactorCursor[k],
2713 										v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgentBurstFactorLumaPre[k] +
2714 										v->RequiredPrefetchPixDataBWChroma[k] * v->UrgentBurstFactorChromaPre[k]) +
2715 										v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
2716 			}
2717 
2718 			v->TotImmediateFlipBytes = 0;
2719 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2720 				v->TotImmediateFlipBytes = v->TotImmediateFlipBytes + v->DPPPerPlane[k] * (v->PDEAndMetaPTEBytesFrame[k] + v->MetaRowByte[k] + v->PixelPTEBytesPerRow[k]);
2721 			}
2722 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2723 				CalculateFlipSchedule(
2724 						mode_lib,
2725 						v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
2726 						v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
2727 						v->UrgentExtraLatency,
2728 						v->UrgentLatency,
2729 						v->GPUVMMaxPageTableLevels,
2730 						v->HostVMEnable,
2731 						v->HostVMMaxNonCachedPageTableLevels,
2732 						v->GPUVMEnable,
2733 						v->HostVMMinPageSize,
2734 						v->PDEAndMetaPTEBytesFrame[k],
2735 						v->MetaRowByte[k],
2736 						v->PixelPTEBytesPerRow[k],
2737 						v->BandwidthAvailableForImmediateFlip,
2738 						v->TotImmediateFlipBytes,
2739 						v->SourcePixelFormat[k],
2740 						v->HTotal[k] / v->PixelClock[k],
2741 						v->VRatio[k],
2742 						v->VRatioChroma[k],
2743 						v->Tno_bw[k],
2744 						v->DCCEnable[k],
2745 						v->dpte_row_height[k],
2746 						v->meta_row_height[k],
2747 						v->dpte_row_height_chroma[k],
2748 						v->meta_row_height_chroma[k],
2749 						&v->DestinationLinesToRequestVMInImmediateFlip[k],
2750 						&v->DestinationLinesToRequestRowInImmediateFlip[k],
2751 						&v->final_flip_bw[k],
2752 						&v->ImmediateFlipSupportedForPipe[k]);
2753 			}
2754 			v->total_dcn_read_bw_with_flip = 0.0;
2755 			v->total_dcn_read_bw_with_flip_no_urgent_burst = 0.0;
2756 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2757 				v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip + dml_max3(
2758 					v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2759 					v->DPPPerPlane[k] * v->final_flip_bw[k] +
2760 					v->ReadBandwidthLuma[k] * v->UrgentBurstFactorLuma[k] +
2761 					v->ReadBandwidthChroma[k] * v->UrgentBurstFactorChroma[k] +
2762 					v->cursor_bw[k] * v->UrgentBurstFactorCursor[k],
2763 					v->DPPPerPlane[k] * (v->final_flip_bw[k] +
2764 					v->RequiredPrefetchPixDataBWLuma[k] * v->UrgentBurstFactorLumaPre[k] +
2765 					v->RequiredPrefetchPixDataBWChroma[k] * v->UrgentBurstFactorChromaPre[k]) +
2766 					v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
2767 				v->total_dcn_read_bw_with_flip_no_urgent_burst =
2768 					v->total_dcn_read_bw_with_flip_no_urgent_burst +
2769 						dml_max3(v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2770 							v->DPPPerPlane[k] * v->final_flip_bw[k] + v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k],
2771 							v->DPPPerPlane[k] * (v->final_flip_bw[k] + v->RequiredPrefetchPixDataBWLuma[k] + v->RequiredPrefetchPixDataBWChroma[k]) + v->cursor_bw_pre[k]);
2772 
2773 			}
2774 			v->FractionOfUrgentBandwidthImmediateFlip = v->total_dcn_read_bw_with_flip_no_urgent_burst / v->ReturnBW;
2775 
2776 			v->ImmediateFlipSupported = true;
2777 			if (v->total_dcn_read_bw_with_flip > v->ReturnBW) {
2778 				v->ImmediateFlipSupported = false;
2779 				v->total_dcn_read_bw_with_flip = MaxTotalRDBandwidth;
2780 			}
2781 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2782 				if (v->ImmediateFlipSupportedForPipe[k] == false) {
2783 					v->ImmediateFlipSupported = false;
2784 				}
2785 			}
2786 		} else {
2787 			v->ImmediateFlipSupported = false;
2788 		}
2789 
2790 		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2791 			if (v->ErrorResult[k] || v->NotEnoughTimeForDynamicMetadata[k]) {
2792 				v->PrefetchModeSupported = false;
2793 				dml_print("DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
2794 			}
2795 		}
2796 
2797 		v->VStartupLines = v->VStartupLines + 1;
2798 		v->PrefetchModeSupported = (v->PrefetchModeSupported == true && ((!v->ImmediateFlipSupport &&
2799 				!v->HostVMEnable && v->ImmediateFlipRequirement[0] != dm_immediate_flip_required) ||
2800 				v->ImmediateFlipSupported)) ? true : false;
2801 	} while (!v->PrefetchModeSupported && v->VStartupLines <= v->MaximumMaxVStartupLines);
2802 	ASSERT(v->PrefetchModeSupported);
2803 
2804 	//Watermarks and NB P-State/DRAM Clock Change Support
2805 	{
2806 		enum clock_change_support   DRAMClockChangeSupport = 0; // dummy
2807 		CalculateWatermarksAndDRAMSpeedChangeSupport(
2808 			mode_lib,
2809 			PrefetchMode,
2810 			v->NumberOfActivePlanes,
2811 			v->MaxLineBufferLines,
2812 			v->LineBufferSize,
2813 			v->DPPOutputBufferPixels,
2814 			v->DETBufferSizeInKByte[0],
2815 			v->WritebackInterfaceBufferSize,
2816 			v->DCFCLK,
2817 			v->ReturnBW,
2818 			v->GPUVMEnable,
2819 			v->dpte_group_bytes,
2820 			v->MetaChunkSize,
2821 			v->UrgentLatency,
2822 			v->UrgentExtraLatency,
2823 			v->WritebackLatency,
2824 			v->WritebackChunkSize,
2825 			v->SOCCLK,
2826 			v->FinalDRAMClockChangeLatency,
2827 			v->SRExitTime,
2828 			v->SREnterPlusExitTime,
2829 			v->DCFCLKDeepSleep,
2830 			v->DPPPerPlane,
2831 			v->DCCEnable,
2832 			v->DPPCLK,
2833 			v->DETBufferSizeY,
2834 			v->DETBufferSizeC,
2835 			v->SwathHeightY,
2836 			v->SwathHeightC,
2837 			v->LBBitPerPixel,
2838 			v->SwathWidthY,
2839 			v->SwathWidthC,
2840 			v->HRatio,
2841 			v->HRatioChroma,
2842 			v->vtaps,
2843 			v->VTAPsChroma,
2844 			v->VRatio,
2845 			v->VRatioChroma,
2846 			v->HTotal,
2847 			v->PixelClock,
2848 			v->BlendingAndTiming,
2849 			v->BytePerPixelDETY,
2850 			v->BytePerPixelDETC,
2851 			v->DSTXAfterScaler,
2852 			v->DSTYAfterScaler,
2853 			v->WritebackEnable,
2854 			v->WritebackPixelFormat,
2855 			v->WritebackDestinationWidth,
2856 			v->WritebackDestinationHeight,
2857 			v->WritebackSourceHeight,
2858 			&DRAMClockChangeSupport,
2859 			&v->UrgentWatermark,
2860 			&v->WritebackUrgentWatermark,
2861 			&v->DRAMClockChangeWatermark,
2862 			&v->WritebackDRAMClockChangeWatermark,
2863 			&v->StutterExitWatermark,
2864 			&v->StutterEnterPlusExitWatermark,
2865 			&v->MinActiveDRAMClockChangeLatencySupported);
2866 
2867 		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2868 			if (v->WritebackEnable[k] == true) {
2869 				if (v->BlendingAndTiming[k] == k) {
2870 					v->ThisVStartup = v->VStartup[k];
2871 				} else {
2872 					for (j = 0; j < v->NumberOfActivePlanes; ++j) {
2873 						if (v->BlendingAndTiming[k] == j) {
2874 							v->ThisVStartup = v->VStartup[j];
2875 						}
2876 					}
2877 				}
2878 				v->WritebackAllowDRAMClockChangeEndPosition[k] = dml_max(0,
2879 					v->ThisVStartup * v->HTotal[k] / v->PixelClock[k] - v->WritebackDRAMClockChangeWatermark);
2880 			} else {
2881 				v->WritebackAllowDRAMClockChangeEndPosition[k] = 0;
2882 			}
2883 		}
2884 
2885 	}
2886 
2887 
2888 	//Display Pipeline Delivery Time in Prefetch, Groups
2889 	CalculatePixelDeliveryTimes(
2890 			v->NumberOfActivePlanes,
2891 			v->VRatio,
2892 			v->VRatioChroma,
2893 			v->VRatioPrefetchY,
2894 			v->VRatioPrefetchC,
2895 			v->swath_width_luma_ub,
2896 			v->swath_width_chroma_ub,
2897 			v->DPPPerPlane,
2898 			v->HRatio,
2899 			v->HRatioChroma,
2900 			v->PixelClock,
2901 			v->PSCL_THROUGHPUT_LUMA,
2902 			v->PSCL_THROUGHPUT_CHROMA,
2903 			v->DPPCLK,
2904 			v->BytePerPixelC,
2905 			v->SourceScan,
2906 			v->NumberOfCursors,
2907 			v->CursorWidth,
2908 			v->CursorBPP,
2909 			v->BlockWidth256BytesY,
2910 			v->BlockHeight256BytesY,
2911 			v->BlockWidth256BytesC,
2912 			v->BlockHeight256BytesC,
2913 			v->DisplayPipeLineDeliveryTimeLuma,
2914 			v->DisplayPipeLineDeliveryTimeChroma,
2915 			v->DisplayPipeLineDeliveryTimeLumaPrefetch,
2916 			v->DisplayPipeLineDeliveryTimeChromaPrefetch,
2917 			v->DisplayPipeRequestDeliveryTimeLuma,
2918 			v->DisplayPipeRequestDeliveryTimeChroma,
2919 			v->DisplayPipeRequestDeliveryTimeLumaPrefetch,
2920 			v->DisplayPipeRequestDeliveryTimeChromaPrefetch,
2921 			v->CursorRequestDeliveryTime,
2922 			v->CursorRequestDeliveryTimePrefetch);
2923 
2924 	CalculateMetaAndPTETimes(
2925 			v->NumberOfActivePlanes,
2926 			v->GPUVMEnable,
2927 			v->MetaChunkSize,
2928 			v->MinMetaChunkSizeBytes,
2929 			v->HTotal,
2930 			v->VRatio,
2931 			v->VRatioChroma,
2932 			v->DestinationLinesToRequestRowInVBlank,
2933 			v->DestinationLinesToRequestRowInImmediateFlip,
2934 			v->DCCEnable,
2935 			v->PixelClock,
2936 			v->BytePerPixelY,
2937 			v->BytePerPixelC,
2938 			v->SourceScan,
2939 			v->dpte_row_height,
2940 			v->dpte_row_height_chroma,
2941 			v->meta_row_width,
2942 			v->meta_row_width_chroma,
2943 			v->meta_row_height,
2944 			v->meta_row_height_chroma,
2945 			v->meta_req_width,
2946 			v->meta_req_width_chroma,
2947 			v->meta_req_height,
2948 			v->meta_req_height_chroma,
2949 			v->dpte_group_bytes,
2950 			v->PTERequestSizeY,
2951 			v->PTERequestSizeC,
2952 			v->PixelPTEReqWidthY,
2953 			v->PixelPTEReqHeightY,
2954 			v->PixelPTEReqWidthC,
2955 			v->PixelPTEReqHeightC,
2956 			v->dpte_row_width_luma_ub,
2957 			v->dpte_row_width_chroma_ub,
2958 			v->DST_Y_PER_PTE_ROW_NOM_L,
2959 			v->DST_Y_PER_PTE_ROW_NOM_C,
2960 			v->DST_Y_PER_META_ROW_NOM_L,
2961 			v->DST_Y_PER_META_ROW_NOM_C,
2962 			v->TimePerMetaChunkNominal,
2963 			v->TimePerChromaMetaChunkNominal,
2964 			v->TimePerMetaChunkVBlank,
2965 			v->TimePerChromaMetaChunkVBlank,
2966 			v->TimePerMetaChunkFlip,
2967 			v->TimePerChromaMetaChunkFlip,
2968 			v->time_per_pte_group_nom_luma,
2969 			v->time_per_pte_group_vblank_luma,
2970 			v->time_per_pte_group_flip_luma,
2971 			v->time_per_pte_group_nom_chroma,
2972 			v->time_per_pte_group_vblank_chroma,
2973 			v->time_per_pte_group_flip_chroma);
2974 
2975 	CalculateVMGroupAndRequestTimes(
2976 			v->NumberOfActivePlanes,
2977 			v->GPUVMEnable,
2978 			v->GPUVMMaxPageTableLevels,
2979 			v->HTotal,
2980 			v->BytePerPixelC,
2981 			v->DestinationLinesToRequestVMInVBlank,
2982 			v->DestinationLinesToRequestVMInImmediateFlip,
2983 			v->DCCEnable,
2984 			v->PixelClock,
2985 			v->dpte_row_width_luma_ub,
2986 			v->dpte_row_width_chroma_ub,
2987 			v->vm_group_bytes,
2988 			v->dpde0_bytes_per_frame_ub_l,
2989 			v->dpde0_bytes_per_frame_ub_c,
2990 			v->meta_pte_bytes_per_frame_ub_l,
2991 			v->meta_pte_bytes_per_frame_ub_c,
2992 			v->TimePerVMGroupVBlank,
2993 			v->TimePerVMGroupFlip,
2994 			v->TimePerVMRequestVBlank,
2995 			v->TimePerVMRequestFlip);
2996 
2997 
2998 	// Min TTUVBlank
2999 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3000 		if (PrefetchMode == 0) {
3001 			v->AllowDRAMClockChangeDuringVBlank[k] = true;
3002 			v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
3003 			v->MinTTUVBlank[k] = dml_max(
3004 					v->DRAMClockChangeWatermark,
3005 					dml_max(
3006 							v->StutterEnterPlusExitWatermark,
3007 							v->UrgentWatermark));
3008 		} else if (PrefetchMode == 1) {
3009 			v->AllowDRAMClockChangeDuringVBlank[k] = false;
3010 			v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
3011 			v->MinTTUVBlank[k] = dml_max(
3012 					v->StutterEnterPlusExitWatermark,
3013 					v->UrgentWatermark);
3014 		} else {
3015 			v->AllowDRAMClockChangeDuringVBlank[k] = false;
3016 			v->AllowDRAMSelfRefreshDuringVBlank[k] = false;
3017 			v->MinTTUVBlank[k] = v->UrgentWatermark;
3018 		}
3019 		if (!v->DynamicMetadataEnable[k])
3020 			v->MinTTUVBlank[k] = v->TCalc
3021 					+ v->MinTTUVBlank[k];
3022 	}
3023 
3024 	// DCC Configuration
3025 	v->ActiveDPPs = 0;
3026 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3027 		CalculateDCCConfiguration(v->DCCEnable[k], false, // We should always know the direction DCCProgrammingAssumesScanDirectionUnknown,
3028 				v->SourcePixelFormat[k],
3029 				v->SurfaceWidthY[k],
3030 				v->SurfaceWidthC[k],
3031 				v->SurfaceHeightY[k],
3032 				v->SurfaceHeightC[k],
3033 				v->DETBufferSizeInKByte[0] * 1024,
3034 				v->BlockHeight256BytesY[k],
3035 				v->BlockHeight256BytesC[k],
3036 				v->SurfaceTiling[k],
3037 				v->BytePerPixelY[k],
3038 				v->BytePerPixelC[k],
3039 				v->BytePerPixelDETY[k],
3040 				v->BytePerPixelDETC[k],
3041 				v->SourceScan[k],
3042 				&v->DCCYMaxUncompressedBlock[k],
3043 				&v->DCCCMaxUncompressedBlock[k],
3044 				&v->DCCYMaxCompressedBlock[k],
3045 				&v->DCCCMaxCompressedBlock[k],
3046 				&v->DCCYIndependentBlock[k],
3047 				&v->DCCCIndependentBlock[k]);
3048 	}
3049 
3050 	{
3051 		//Maximum Bandwidth Used
3052 		double TotalWRBandwidth = 0;
3053 		double MaxPerPlaneVActiveWRBandwidth = 0;
3054 		double WRBandwidth = 0;
3055 		double MaxUsedBW = 0;
3056 		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3057 			if (v->WritebackEnable[k] == true
3058 					&& v->WritebackPixelFormat[k] == dm_444_32) {
3059 				WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3060 						/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 4;
3061 			} else if (v->WritebackEnable[k] == true) {
3062 				WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3063 						/ (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 8;
3064 			}
3065 			TotalWRBandwidth = TotalWRBandwidth + WRBandwidth;
3066 			MaxPerPlaneVActiveWRBandwidth = dml_max(MaxPerPlaneVActiveWRBandwidth, WRBandwidth);
3067 		}
3068 
3069 		v->TotalDataReadBandwidth = 0;
3070 		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3071 			v->TotalDataReadBandwidth = v->TotalDataReadBandwidth
3072 					+ v->ReadBandwidthPlaneLuma[k]
3073 					+ v->ReadBandwidthPlaneChroma[k];
3074 		}
3075 
3076 		{
3077 			double MaxPerPlaneVActiveRDBandwidth = 0;
3078 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3079 				MaxPerPlaneVActiveRDBandwidth = dml_max(MaxPerPlaneVActiveRDBandwidth,
3080 						v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k]);
3081 
3082 			}
3083 		}
3084 
3085 		MaxUsedBW = MaxTotalRDBandwidth + TotalWRBandwidth;
3086 	}
3087 
3088 	// VStartup Margin
3089 	v->VStartupMargin = 0;
3090 	v->FirstMainPlane = true;
3091 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3092 		if (v->BlendingAndTiming[k] == k) {
3093 			double margin = (v->MaxVStartupLines[k] - v->VStartup[k]) * v->HTotal[k]
3094 					/ v->PixelClock[k];
3095 			if (v->FirstMainPlane == true) {
3096 				v->VStartupMargin = margin;
3097 				v->FirstMainPlane = false;
3098 			} else {
3099 				v->VStartupMargin = dml_min(v->VStartupMargin, margin);
3100 			}
3101 		}
3102 	}
3103 
3104 	// Stutter Efficiency
3105 	CalculateStutterEfficiency(
3106 			v->NumberOfActivePlanes,
3107 			v->ROBBufferSizeInKByte,
3108 			v->TotalDataReadBandwidth,
3109 			v->DCFCLK,
3110 			v->ReturnBW,
3111 			v->SRExitTime,
3112 			v->SynchronizedVBlank,
3113 			v->DPPPerPlane,
3114 			v->DETBufferSizeY,
3115 			v->BytePerPixelY,
3116 			v->BytePerPixelDETY,
3117 			v->SwathWidthY,
3118 			v->SwathHeightY,
3119 			v->SwathHeightC,
3120 			v->DCCRateLuma,
3121 			v->DCCRateChroma,
3122 			v->HTotal,
3123 			v->VTotal,
3124 			v->PixelClock,
3125 			v->VRatio,
3126 			v->SourceScan,
3127 			v->BlockHeight256BytesY,
3128 			v->BlockWidth256BytesY,
3129 			v->BlockHeight256BytesC,
3130 			v->BlockWidth256BytesC,
3131 			v->DCCYMaxUncompressedBlock,
3132 			v->DCCCMaxUncompressedBlock,
3133 			v->VActive,
3134 			v->DCCEnable,
3135 			v->WritebackEnable,
3136 			v->ReadBandwidthPlaneLuma,
3137 			v->ReadBandwidthPlaneChroma,
3138 			v->meta_row_bw,
3139 			v->dpte_row_bw,
3140 			&v->StutterEfficiencyNotIncludingVBlank,
3141 			&v->StutterEfficiency,
3142 			&v->StutterPeriod);
3143 }
3144 
DisplayPipeConfiguration(struct display_mode_lib * mode_lib)3145 static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
3146 {
3147 	// Display Pipe Configuration
3148 	double BytePerPixDETY[DC__NUM_DPP__MAX] = { 0 };
3149 	double BytePerPixDETC[DC__NUM_DPP__MAX] = { 0 };
3150 	int BytePerPixY[DC__NUM_DPP__MAX] = { 0 };
3151 	int BytePerPixC[DC__NUM_DPP__MAX] = { 0 };
3152 	int Read256BytesBlockHeightY[DC__NUM_DPP__MAX] = { 0 };
3153 	int Read256BytesBlockHeightC[DC__NUM_DPP__MAX] = { 0 };
3154 	int Read256BytesBlockWidthY[DC__NUM_DPP__MAX] = { 0 };
3155 	int Read256BytesBlockWidthC[DC__NUM_DPP__MAX] = { 0 };
3156 	double dummy1[DC__NUM_DPP__MAX] = { 0 };
3157 	double dummy2[DC__NUM_DPP__MAX] = { 0 };
3158 	double dummy3[DC__NUM_DPP__MAX] = { 0 };
3159 	double dummy4[DC__NUM_DPP__MAX] = { 0 };
3160 	int dummy5[DC__NUM_DPP__MAX] = { 0 };
3161 	int dummy6[DC__NUM_DPP__MAX] = { 0 };
3162 	bool dummy7[DC__NUM_DPP__MAX] = { 0 };
3163 	bool dummysinglestring = 0;
3164 	unsigned int k;
3165 
3166 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3167 
3168 		CalculateBytePerPixelAnd256BBlockSizes(
3169 				mode_lib->vba.SourcePixelFormat[k],
3170 				mode_lib->vba.SurfaceTiling[k],
3171 				&BytePerPixY[k],
3172 				&BytePerPixC[k],
3173 				&BytePerPixDETY[k],
3174 				&BytePerPixDETC[k],
3175 				&Read256BytesBlockHeightY[k],
3176 				&Read256BytesBlockHeightC[k],
3177 				&Read256BytesBlockWidthY[k],
3178 				&Read256BytesBlockWidthC[k]);
3179 	}
3180 	CalculateSwathAndDETConfiguration(
3181 			false,
3182 			mode_lib->vba.NumberOfActivePlanes,
3183 			mode_lib->vba.DETBufferSizeInKByte[0],
3184 			dummy1,
3185 			dummy2,
3186 			mode_lib->vba.SourceScan,
3187 			mode_lib->vba.SourcePixelFormat,
3188 			mode_lib->vba.SurfaceTiling,
3189 			mode_lib->vba.ViewportWidth,
3190 			mode_lib->vba.ViewportHeight,
3191 			mode_lib->vba.SurfaceWidthY,
3192 			mode_lib->vba.SurfaceWidthC,
3193 			mode_lib->vba.SurfaceHeightY,
3194 			mode_lib->vba.SurfaceHeightC,
3195 			Read256BytesBlockHeightY,
3196 			Read256BytesBlockHeightC,
3197 			Read256BytesBlockWidthY,
3198 			Read256BytesBlockWidthC,
3199 			mode_lib->vba.ODMCombineEnabled,
3200 			mode_lib->vba.BlendingAndTiming,
3201 			BytePerPixY,
3202 			BytePerPixC,
3203 			BytePerPixDETY,
3204 			BytePerPixDETC,
3205 			mode_lib->vba.HActive,
3206 			mode_lib->vba.HRatio,
3207 			mode_lib->vba.HRatioChroma,
3208 			mode_lib->vba.DPPPerPlane,
3209 			dummy5,
3210 			dummy6,
3211 			dummy3,
3212 			dummy4,
3213 			mode_lib->vba.SwathHeightY,
3214 			mode_lib->vba.SwathHeightC,
3215 			mode_lib->vba.DETBufferSizeY,
3216 			mode_lib->vba.DETBufferSizeC,
3217 			dummy7,
3218 			&dummysinglestring);
3219 }
3220 
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)3221 static bool CalculateBytePerPixelAnd256BBlockSizes(
3222 		enum source_format_class SourcePixelFormat,
3223 		enum dm_swizzle_mode SurfaceTiling,
3224 		unsigned int *BytePerPixelY,
3225 		unsigned int *BytePerPixelC,
3226 		double       *BytePerPixelDETY,
3227 		double       *BytePerPixelDETC,
3228 		unsigned int *BlockHeight256BytesY,
3229 		unsigned int *BlockHeight256BytesC,
3230 		unsigned int *BlockWidth256BytesY,
3231 		unsigned int *BlockWidth256BytesC)
3232 {
3233 	if (SourcePixelFormat == dm_444_64) {
3234 		*BytePerPixelDETY = 8;
3235 		*BytePerPixelDETC = 0;
3236 		*BytePerPixelY = 8;
3237 		*BytePerPixelC = 0;
3238 	} else if (SourcePixelFormat == dm_444_32 || SourcePixelFormat == dm_rgbe) {
3239 		*BytePerPixelDETY = 4;
3240 		*BytePerPixelDETC = 0;
3241 		*BytePerPixelY = 4;
3242 		*BytePerPixelC = 0;
3243 	} else if (SourcePixelFormat == dm_444_16) {
3244 		*BytePerPixelDETY = 2;
3245 		*BytePerPixelDETC = 0;
3246 		*BytePerPixelY = 2;
3247 		*BytePerPixelC = 0;
3248 	} else if (SourcePixelFormat == dm_444_8) {
3249 		*BytePerPixelDETY = 1;
3250 		*BytePerPixelDETC = 0;
3251 		*BytePerPixelY = 1;
3252 		*BytePerPixelC = 0;
3253 	} else if (SourcePixelFormat == dm_rgbe_alpha) {
3254 		*BytePerPixelDETY = 4;
3255 		*BytePerPixelDETC = 1;
3256 		*BytePerPixelY = 4;
3257 		*BytePerPixelC = 1;
3258 	} else if (SourcePixelFormat == dm_420_8) {
3259 		*BytePerPixelDETY = 1;
3260 		*BytePerPixelDETC = 2;
3261 		*BytePerPixelY = 1;
3262 		*BytePerPixelC = 2;
3263 	} else if (SourcePixelFormat == dm_420_12) {
3264 		*BytePerPixelDETY = 2;
3265 		*BytePerPixelDETC = 4;
3266 		*BytePerPixelY = 2;
3267 		*BytePerPixelC = 4;
3268 	} else {
3269 		*BytePerPixelDETY = 4.0 / 3;
3270 		*BytePerPixelDETC = 8.0 / 3;
3271 		*BytePerPixelY = 2;
3272 		*BytePerPixelC = 4;
3273 	}
3274 
3275 	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
3276 			|| SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8
3277 			|| SourcePixelFormat == dm_mono_16 || SourcePixelFormat == dm_mono_8
3278 			|| SourcePixelFormat == dm_rgbe)) {
3279 		if (SurfaceTiling == dm_sw_linear) {
3280 			*BlockHeight256BytesY = 1;
3281 		} else if (SourcePixelFormat == dm_444_64) {
3282 			*BlockHeight256BytesY = 4;
3283 		} else if (SourcePixelFormat == dm_444_8) {
3284 			*BlockHeight256BytesY = 16;
3285 		} else {
3286 			*BlockHeight256BytesY = 8;
3287 		}
3288 		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
3289 		*BlockHeight256BytesC = 0;
3290 		*BlockWidth256BytesC = 0;
3291 	} else {
3292 		if (SurfaceTiling == dm_sw_linear) {
3293 			*BlockHeight256BytesY = 1;
3294 			*BlockHeight256BytesC = 1;
3295 		} else if (SourcePixelFormat == dm_rgbe_alpha) {
3296 			*BlockHeight256BytesY = 8;
3297 			*BlockHeight256BytesC = 16;
3298 		} else if (SourcePixelFormat == dm_420_8) {
3299 			*BlockHeight256BytesY = 16;
3300 			*BlockHeight256BytesC = 8;
3301 		} else {
3302 			*BlockHeight256BytesY = 8;
3303 			*BlockHeight256BytesC = 8;
3304 		}
3305 		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
3306 		*BlockWidth256BytesC = 256U / *BytePerPixelC / *BlockHeight256BytesC;
3307 	}
3308 	return true;
3309 }
3310 
CalculateTWait(unsigned int PrefetchMode,double DRAMClockChangeLatency,double UrgentLatency,double SREnterPlusExitTime)3311 static double CalculateTWait(
3312 		unsigned int PrefetchMode,
3313 		double DRAMClockChangeLatency,
3314 		double UrgentLatency,
3315 		double SREnterPlusExitTime)
3316 {
3317 	if (PrefetchMode == 0) {
3318 		return dml_max(DRAMClockChangeLatency + UrgentLatency,
3319 				dml_max(SREnterPlusExitTime, UrgentLatency));
3320 	} else if (PrefetchMode == 1) {
3321 		return dml_max(SREnterPlusExitTime, UrgentLatency);
3322 	} else {
3323 		return UrgentLatency;
3324 	}
3325 }
3326 
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)3327 double dml30_CalculateWriteBackDISPCLK(
3328 		enum source_format_class WritebackPixelFormat,
3329 		double PixelClock,
3330 		double WritebackHRatio,
3331 		double WritebackVRatio,
3332 		unsigned int WritebackHTaps,
3333 		unsigned int WritebackVTaps,
3334 		long   WritebackSourceWidth,
3335 		long   WritebackDestinationWidth,
3336 		unsigned int HTotal,
3337 		unsigned int WritebackLineBufferSize)
3338 {
3339 	double DISPCLK_H = 0, DISPCLK_V = 0, DISPCLK_HB = 0;
3340 
3341 	DISPCLK_H = PixelClock * dml_ceil(WritebackHTaps / 8.0, 1) / WritebackHRatio;
3342 	DISPCLK_V = PixelClock * (WritebackVTaps * dml_ceil(WritebackDestinationWidth / 6.0, 1) + 8.0) / HTotal;
3343 	DISPCLK_HB = PixelClock * WritebackVTaps * (WritebackDestinationWidth * WritebackVTaps - WritebackLineBufferSize / 57.0) / 6.0 / WritebackSourceWidth;
3344 	return dml_max3(DISPCLK_H, DISPCLK_V, DISPCLK_HB);
3345 }
3346 
CalculateWriteBackDelay(enum source_format_class WritebackPixelFormat,double WritebackHRatio,double WritebackVRatio,unsigned int WritebackVTaps,long WritebackDestinationWidth,long WritebackDestinationHeight,long WritebackSourceHeight,unsigned int HTotal)3347 static double CalculateWriteBackDelay(
3348 		enum source_format_class WritebackPixelFormat,
3349 		double WritebackHRatio,
3350 		double WritebackVRatio,
3351 		unsigned int WritebackVTaps,
3352 		long         WritebackDestinationWidth,
3353 		long         WritebackDestinationHeight,
3354 		long         WritebackSourceHeight,
3355 		unsigned int HTotal)
3356 {
3357 	double CalculateWriteBackDelay = 0;
3358 	double Line_length = 0;
3359 	double Output_lines_last_notclamped = 0;
3360 	double WritebackVInit = 0;
3361 
3362 	WritebackVInit = (WritebackVRatio + WritebackVTaps + 1) / 2;
3363 	Line_length = dml_max((double) WritebackDestinationWidth, dml_ceil(WritebackDestinationWidth / 6.0, 1) * WritebackVTaps);
3364 	Output_lines_last_notclamped = WritebackDestinationHeight - 1 - dml_ceil((WritebackSourceHeight - WritebackVInit) / WritebackVRatio, 1);
3365 	if (Output_lines_last_notclamped < 0) {
3366 		CalculateWriteBackDelay = 0;
3367 	} else {
3368 		CalculateWriteBackDelay = Output_lines_last_notclamped * Line_length + (HTotal - WritebackDestinationWidth) + 80;
3369 	}
3370 	return CalculateWriteBackDelay;
3371 }
3372 
3373 
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)3374 static void CalculateDynamicMetadataParameters(int MaxInterDCNTileRepeaters, double DPPCLK, double DISPCLK,
3375 		double DCFClkDeepSleep, double PixelClock, long HTotal, long VBlank, long DynamicMetadataTransmittedBytes,
3376 		long DynamicMetadataLinesBeforeActiveRequired, int InterlaceEnable, bool ProgressiveToInterlaceUnitInOPP,
3377 		double *Tsetup, double *Tdmbf, double *Tdmec, double *Tdmsks)
3378 {
3379 	double TotalRepeaterDelayTime = 0;
3380 	double VUpdateWidthPix = 0;
3381 	double VReadyOffsetPix = 0;
3382 	double VUpdateOffsetPix = 0;
3383 	TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2 / DPPCLK + 3 / DISPCLK);
3384 	VUpdateWidthPix = (14 / DCFClkDeepSleep + 12 / DPPCLK + TotalRepeaterDelayTime) * PixelClock;
3385 	VReadyOffsetPix = dml_max(150.0 / DPPCLK, TotalRepeaterDelayTime + 20 / DCFClkDeepSleep + 10 / DPPCLK) * PixelClock;
3386 	VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
3387 	*Tsetup = (VUpdateOffsetPix + VUpdateWidthPix + VReadyOffsetPix) / PixelClock;
3388 	*Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
3389 	*Tdmec = HTotal / PixelClock;
3390 	if (DynamicMetadataLinesBeforeActiveRequired == 0) {
3391 		*Tdmsks = VBlank * HTotal / PixelClock / 2.0;
3392 	} else {
3393 		*Tdmsks = DynamicMetadataLinesBeforeActiveRequired * HTotal / PixelClock;
3394 	}
3395 	if (InterlaceEnable == 1 && ProgressiveToInterlaceUnitInOPP == false) {
3396 		*Tdmsks = *Tdmsks / 2;
3397 	}
3398 }
3399 
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)3400 static void CalculateRowBandwidth(
3401 		bool GPUVMEnable,
3402 		enum source_format_class SourcePixelFormat,
3403 		double VRatio,
3404 		double VRatioChroma,
3405 		bool DCCEnable,
3406 		double LineTime,
3407 		unsigned int MetaRowByteLuma,
3408 		unsigned int MetaRowByteChroma,
3409 		unsigned int meta_row_height_luma,
3410 		unsigned int meta_row_height_chroma,
3411 		unsigned int PixelPTEBytesPerRowLuma,
3412 		unsigned int PixelPTEBytesPerRowChroma,
3413 		unsigned int dpte_row_height_luma,
3414 		unsigned int dpte_row_height_chroma,
3415 		double *meta_row_bw,
3416 		double *dpte_row_bw)
3417 {
3418 	if (DCCEnable != true) {
3419 		*meta_row_bw = 0;
3420 	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
3421 		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
3422 				+ VRatioChroma * MetaRowByteChroma
3423 						/ (meta_row_height_chroma * LineTime);
3424 	} else {
3425 		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
3426 	}
3427 
3428 	if (GPUVMEnable != true) {
3429 		*dpte_row_bw = 0;
3430 	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
3431 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
3432 				+ VRatioChroma * PixelPTEBytesPerRowChroma
3433 						/ (dpte_row_height_chroma * LineTime);
3434 	} else {
3435 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
3436 	}
3437 }
3438 
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)3439 static void CalculateFlipSchedule(
3440 		struct display_mode_lib *mode_lib,
3441 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
3442 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
3443 		double UrgentExtraLatency,
3444 		double UrgentLatency,
3445 		unsigned int GPUVMMaxPageTableLevels,
3446 		bool HostVMEnable,
3447 		unsigned int HostVMMaxNonCachedPageTableLevels,
3448 		bool GPUVMEnable,
3449 		double HostVMMinPageSize,
3450 		double PDEAndMetaPTEBytesPerFrame,
3451 		double MetaRowBytes,
3452 		double DPTEBytesPerRow,
3453 		double BandwidthAvailableForImmediateFlip,
3454 		unsigned int TotImmediateFlipBytes,
3455 		enum source_format_class SourcePixelFormat,
3456 		double LineTime,
3457 		double VRatio,
3458 		double VRatioChroma,
3459 		double Tno_bw,
3460 		bool DCCEnable,
3461 		unsigned int dpte_row_height,
3462 		unsigned int meta_row_height,
3463 		unsigned int dpte_row_height_chroma,
3464 		unsigned int meta_row_height_chroma,
3465 		double *DestinationLinesToRequestVMInImmediateFlip,
3466 		double *DestinationLinesToRequestRowInImmediateFlip,
3467 		double *final_flip_bw,
3468 		bool *ImmediateFlipSupportedForPipe)
3469 {
3470 	double min_row_time = 0.0;
3471 	unsigned int HostVMDynamicLevelsTrips = 0;
3472 	double TimeForFetchingMetaPTEImmediateFlip = 0;
3473 	double TimeForFetchingRowInVBlankImmediateFlip = 0;
3474 	double ImmediateFlipBW = 0;
3475 	double HostVMInefficiencyFactor = 0;
3476 
3477 	if (GPUVMEnable == true && HostVMEnable == true) {
3478 		HostVMInefficiencyFactor = PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
3479 		HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
3480 	} else {
3481 		HostVMInefficiencyFactor = 1;
3482 		HostVMDynamicLevelsTrips = 0;
3483 	}
3484 
3485 	if (GPUVMEnable == true || DCCEnable == true) {
3486 		ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow) * BandwidthAvailableForImmediateFlip / TotImmediateFlipBytes;
3487 	}
3488 
3489 	if (GPUVMEnable == true) {
3490 		TimeForFetchingMetaPTEImmediateFlip = dml_max3(Tno_bw + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW,
3491 				UrgentExtraLatency + UrgentLatency * (GPUVMMaxPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1), LineTime / 4.0);
3492 	} else {
3493 		TimeForFetchingMetaPTEImmediateFlip = 0;
3494 	}
3495 
3496 	*DestinationLinesToRequestVMInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime), 1) / 4.0;
3497 	if ((GPUVMEnable == true || DCCEnable == true)) {
3498 		TimeForFetchingRowInVBlankImmediateFlip = dml_max3((MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / ImmediateFlipBW,
3499 				UrgentLatency * (HostVMDynamicLevelsTrips + 1), LineTime / 4);
3500 	} else {
3501 		TimeForFetchingRowInVBlankImmediateFlip = 0;
3502 	}
3503 
3504 	*DestinationLinesToRequestRowInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0;
3505 
3506 	if (GPUVMEnable == true) {
3507 		*final_flip_bw = dml_max(PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInImmediateFlip * LineTime),
3508 				(MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime));
3509 	} else if ((GPUVMEnable == true || DCCEnable == true)) {
3510 		*final_flip_bw = (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime);
3511 	} else {
3512 		*final_flip_bw = 0;
3513 	}
3514 
3515 
3516 	if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_rgbe_alpha) {
3517 		if (GPUVMEnable == true && DCCEnable != true) {
3518 			min_row_time = dml_min(dpte_row_height * LineTime / VRatio, dpte_row_height_chroma * LineTime / VRatioChroma);
3519 		} else if (GPUVMEnable != true && DCCEnable == true) {
3520 			min_row_time = dml_min(meta_row_height * LineTime / VRatio, meta_row_height_chroma * LineTime / VRatioChroma);
3521 		} else {
3522 			min_row_time = dml_min4(dpte_row_height * LineTime / VRatio, meta_row_height * LineTime / VRatio,
3523 					dpte_row_height_chroma * LineTime / VRatioChroma, meta_row_height_chroma * LineTime / VRatioChroma);
3524 		}
3525 	} else {
3526 		if (GPUVMEnable == true && DCCEnable != true) {
3527 			min_row_time = dpte_row_height * LineTime / VRatio;
3528 		} else if (GPUVMEnable != true && DCCEnable == true) {
3529 			min_row_time = meta_row_height * LineTime / VRatio;
3530 		} else {
3531 			min_row_time = dml_min(dpte_row_height * LineTime / VRatio, meta_row_height * LineTime / VRatio);
3532 		}
3533 	}
3534 
3535 	if (*DestinationLinesToRequestVMInImmediateFlip >= 32 || *DestinationLinesToRequestRowInImmediateFlip >= 16
3536 			|| TimeForFetchingMetaPTEImmediateFlip + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) {
3537 		*ImmediateFlipSupportedForPipe = false;
3538 	} else {
3539 		*ImmediateFlipSupportedForPipe = true;
3540 	}
3541 }
3542 
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)3543 static double TruncToValidBPP(
3544 		double LinkBitRate,
3545 		int Lanes,
3546 		long HTotal,
3547 		long HActive,
3548 		double PixelClock,
3549 		double DesiredBPP,
3550 		bool DSCEnable,
3551 		enum output_encoder_class Output,
3552 		enum output_format_class Format,
3553 		unsigned int DSCInputBitPerComponent,
3554 		int DSCSlices,
3555 		int AudioRate,
3556 		int AudioLayout,
3557 		enum odm_combine_mode ODMCombine)
3558 {
3559 	double MaxLinkBPP = 0;
3560 	int MinDSCBPP = 0;
3561 	double MaxDSCBPP = 0;
3562 	int NonDSCBPP0 = 0;
3563 	int NonDSCBPP1 = 0;
3564 	int NonDSCBPP2 = 0;
3565 
3566 	if (Format == dm_420) {
3567 		NonDSCBPP0 = 12;
3568 		NonDSCBPP1 = 15;
3569 		NonDSCBPP2 = 18;
3570 		MinDSCBPP = 6;
3571 		MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1.0 / 16;
3572 	} else if (Format == dm_444) {
3573 		NonDSCBPP0 = 24;
3574 		NonDSCBPP1 = 30;
3575 		NonDSCBPP2 = 36;
3576 		MinDSCBPP = 8;
3577 		MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
3578 	} else {
3579 		if (Output == dm_hdmi) {
3580 			NonDSCBPP0 = 24;
3581 			NonDSCBPP1 = 24;
3582 			NonDSCBPP2 = 24;
3583 		}
3584 		else {
3585 			NonDSCBPP0 = 16;
3586 			NonDSCBPP1 = 20;
3587 			NonDSCBPP2 = 24;
3588 		}
3589 
3590 		if (Format == dm_n422) {
3591 			MinDSCBPP = 7;
3592 			MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
3593 		}
3594 		else {
3595 			MinDSCBPP = 8;
3596 			MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
3597 		}
3598 	}
3599 
3600 	if (DSCEnable && Output == dm_dp) {
3601 		MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
3602 	} else {
3603 		MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock;
3604 	}
3605 
3606 	if (ODMCombine == dm_odm_combine_mode_4to1 && MaxLinkBPP > 16) {
3607 		MaxLinkBPP = 16;
3608 	} else if (ODMCombine == dm_odm_combine_mode_2to1 && MaxLinkBPP > 32) {
3609 		MaxLinkBPP = 32;
3610 	}
3611 
3612 
3613 	if (DesiredBPP == 0) {
3614 		if (DSCEnable) {
3615 			if (MaxLinkBPP < MinDSCBPP) {
3616 				return BPP_INVALID;
3617 			} else if (MaxLinkBPP >= MaxDSCBPP) {
3618 				return MaxDSCBPP;
3619 			} else {
3620 				return dml_floor(16.0 * MaxLinkBPP, 1.0) / 16.0;
3621 			}
3622 		} else {
3623 			if (MaxLinkBPP >= NonDSCBPP2) {
3624 				return NonDSCBPP2;
3625 			} else if (MaxLinkBPP >= NonDSCBPP1) {
3626 				return NonDSCBPP1;
3627 			} else if (MaxLinkBPP >= NonDSCBPP0) {
3628 				return NonDSCBPP0;
3629 			} else {
3630 				return BPP_INVALID;
3631 			}
3632 		}
3633 	} else {
3634 		if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP == NonDSCBPP0 || DesiredBPP == 18)) ||
3635 				(DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
3636 			return BPP_INVALID;
3637 		} else {
3638 			return DesiredBPP;
3639 		}
3640 	}
3641 	return BPP_INVALID;
3642 }
3643 
dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib * mode_lib)3644 void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
3645 {
3646 	struct vba_vars_st *v = &mode_lib->vba;
3647 	int MinPrefetchMode, MaxPrefetchMode;
3648 	int i;
3649 	unsigned int j, k, m;
3650 	bool   EnoughWritebackUnits = true;
3651 	bool   WritebackModeSupport = true;
3652 	bool   ViewportExceedsSurface = false;
3653 	double MaxTotalVActiveRDBandwidth = 0;
3654 	long ReorderingBytes = 0;
3655 	bool NotUrgentLatencyHiding[DC__NUM_DPP__MAX] = { 0 };
3656 
3657 	/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
3658 
3659 	CalculateMinAndMaxPrefetchMode(
3660 		mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
3661 		&MinPrefetchMode, &MaxPrefetchMode);
3662 
3663 	/*Scale Ratio, taps Support Check*/
3664 
3665 	v->ScaleRatioAndTapsSupport = true;
3666 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3667 		if (v->ScalerEnabled[k] == false
3668 				&& ((v->SourcePixelFormat[k] != dm_444_64
3669 						&& v->SourcePixelFormat[k] != dm_444_32
3670 						&& v->SourcePixelFormat[k] != dm_444_16
3671 						&& v->SourcePixelFormat[k] != dm_mono_16
3672 						&& v->SourcePixelFormat[k] != dm_mono_8
3673 						&& v->SourcePixelFormat[k] != dm_rgbe
3674 						&& v->SourcePixelFormat[k] != dm_rgbe_alpha)
3675 						|| v->HRatio[k] != 1.0
3676 						|| v->htaps[k] != 1.0
3677 						|| v->VRatio[k] != 1.0
3678 						|| v->vtaps[k] != 1.0)) {
3679 			v->ScaleRatioAndTapsSupport = false;
3680 		} else if (v->vtaps[k] < 1.0 || v->vtaps[k] > 8.0
3681 				|| v->htaps[k] < 1.0 || v->htaps[k] > 8.0
3682 				|| (v->htaps[k] > 1.0
3683 						&& (v->htaps[k] % 2) == 1)
3684 				|| v->HRatio[k] > v->MaxHSCLRatio
3685 				|| v->VRatio[k] > v->MaxVSCLRatio
3686 				|| v->HRatio[k] > v->htaps[k]
3687 				|| v->VRatio[k] > v->vtaps[k]
3688 				|| (v->SourcePixelFormat[k] != dm_444_64
3689 						&& v->SourcePixelFormat[k] != dm_444_32
3690 						&& v->SourcePixelFormat[k] != dm_444_16
3691 						&& v->SourcePixelFormat[k] != dm_mono_16
3692 						&& v->SourcePixelFormat[k] != dm_mono_8
3693 						&& v->SourcePixelFormat[k] != dm_rgbe
3694 						&& (v->VTAPsChroma[k] < 1
3695 							|| v->VTAPsChroma[k] > 8
3696 							|| v->HTAPsChroma[k] < 1
3697 							|| v->HTAPsChroma[k] > 8
3698 							|| (v->HTAPsChroma[k] > 1 && v->HTAPsChroma[k] % 2 == 1)
3699 							|| v->HRatioChroma[k] > v->MaxHSCLRatio
3700 							|| v->VRatioChroma[k] > v->MaxVSCLRatio
3701 							|| v->HRatioChroma[k] > v->HTAPsChroma[k]
3702 							|| v->VRatioChroma[k] > v->VTAPsChroma[k]))) {
3703 			v->ScaleRatioAndTapsSupport = false;
3704 		}
3705 	}
3706 	/*Source Format, Pixel Format and Scan Support Check*/
3707 
3708 	v->SourceFormatPixelAndScanSupport = true;
3709 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3710 		if ((v->SurfaceTiling[k] == dm_sw_linear && (!(v->SourceScan[k] != dm_vert) || v->DCCEnable[k] == true))
3711 				|| ((v->SurfaceTiling[k] == dm_sw_64kb_d || v->SurfaceTiling[k] == dm_sw_64kb_d_t || v->SurfaceTiling[k] == dm_sw_64kb_d_x)
3712 						&& !(v->SourcePixelFormat[k] == dm_444_64))) {
3713 			v->SourceFormatPixelAndScanSupport = false;
3714 		}
3715 	}
3716 	/*Bandwidth Support Check*/
3717 
3718 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3719 		CalculateBytePerPixelAnd256BBlockSizes(
3720 				v->SourcePixelFormat[k],
3721 				v->SurfaceTiling[k],
3722 				&v->BytePerPixelY[k],
3723 				&v->BytePerPixelC[k],
3724 				&v->BytePerPixelInDETY[k],
3725 				&v->BytePerPixelInDETC[k],
3726 				&v->Read256BlockHeightY[k],
3727 				&v->Read256BlockHeightC[k],
3728 				&v->Read256BlockWidthY[k],
3729 				&v->Read256BlockWidthC[k]);
3730 	}
3731 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3732 		if (v->SourceScan[k] != dm_vert) {
3733 			v->SwathWidthYSingleDPP[k] = v->ViewportWidth[k];
3734 			v->SwathWidthCSingleDPP[k] = v->ViewportWidthChroma[k];
3735 		} else {
3736 			v->SwathWidthYSingleDPP[k] = v->ViewportHeight[k];
3737 			v->SwathWidthCSingleDPP[k] = v->ViewportHeightChroma[k];
3738 		}
3739 	}
3740 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3741 		v->ReadBandwidthLuma[k] = v->SwathWidthYSingleDPP[k] * dml_ceil(v->BytePerPixelInDETY[k], 1.0) / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
3742 		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;
3743 	}
3744 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3745 		if (v->WritebackEnable[k] == true
3746 				&& v->WritebackPixelFormat[k] == dm_444_64) {
3747 			v->WriteBandwidth[k] = v->WritebackDestinationWidth[k]
3748 					* v->WritebackDestinationHeight[k]
3749 					/ (v->WritebackSourceHeight[k]
3750 							* v->HTotal[k]
3751 							/ v->PixelClock[k]) * 8.0;
3752 		} else if (v->WritebackEnable[k] == true) {
3753 			v->WriteBandwidth[k] = v->WritebackDestinationWidth[k]
3754 					* v->WritebackDestinationHeight[k]
3755 					/ (v->WritebackSourceHeight[k]
3756 							* v->HTotal[k]
3757 							/ v->PixelClock[k]) * 4.0;
3758 		} else {
3759 			v->WriteBandwidth[k] = 0.0;
3760 		}
3761 	}
3762 
3763 	/*Writeback Latency support check*/
3764 
3765 	v->WritebackLatencySupport = true;
3766 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3767 		if (v->WritebackEnable[k] == true) {
3768 			if (v->WritebackConfiguration == dm_whole_buffer_for_single_stream_no_interleave ||
3769 			    v->WritebackConfiguration == dm_whole_buffer_for_single_stream_interleave) {
3770 				if (v->WriteBandwidth[k]
3771 						> 2.0 * v->WritebackInterfaceBufferSize * 1024
3772 								/ v->WritebackLatency) {
3773 					v->WritebackLatencySupport = false;
3774 				}
3775 			} else {
3776 				if (v->WriteBandwidth[k]
3777 						> v->WritebackInterfaceBufferSize * 1024
3778 								/ v->WritebackLatency) {
3779 					v->WritebackLatencySupport = false;
3780 				}
3781 			}
3782 		}
3783 	}
3784 
3785 	/*Writeback Mode Support Check*/
3786 
3787 	v->TotalNumberOfActiveWriteback = 0;
3788 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3789 		if (v->WritebackEnable[k] == true) {
3790 			v->TotalNumberOfActiveWriteback =
3791 					v->TotalNumberOfActiveWriteback + 1;
3792 		}
3793 	}
3794 
3795 	if (v->TotalNumberOfActiveWriteback > v->MaxNumWriteback) {
3796 		EnoughWritebackUnits = false;
3797 	}
3798 	if (!v->WritebackSupportInterleaveAndUsingWholeBufferForASingleStream
3799 			&& (v->WritebackConfiguration == dm_whole_buffer_for_single_stream_no_interleave
3800 					|| v->WritebackConfiguration == dm_whole_buffer_for_single_stream_interleave)) {
3801 
3802 		WritebackModeSupport = false;
3803 	}
3804 	if (v->WritebackConfiguration == dm_whole_buffer_for_single_stream_no_interleave && v->TotalNumberOfActiveWriteback > 1) {
3805 		WritebackModeSupport = false;
3806 	}
3807 
3808 	/*Writeback Scale Ratio and Taps Support Check*/
3809 
3810 	v->WritebackScaleRatioAndTapsSupport = true;
3811 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3812 		if (v->WritebackEnable[k] == true) {
3813 			if (v->WritebackHRatio[k] > v->WritebackMaxHSCLRatio
3814 					|| v->WritebackVRatio[k]
3815 							> v->WritebackMaxVSCLRatio
3816 					|| v->WritebackHRatio[k]
3817 							< v->WritebackMinHSCLRatio
3818 					|| v->WritebackVRatio[k]
3819 							< v->WritebackMinVSCLRatio
3820 					|| v->WritebackHTaps[k]
3821 							> v->WritebackMaxHSCLTaps
3822 					|| v->WritebackVTaps[k]
3823 							> v->WritebackMaxVSCLTaps
3824 					|| v->WritebackHRatio[k]
3825 							> v->WritebackHTaps[k]
3826 					|| v->WritebackVRatio[k]
3827 							> v->WritebackVTaps[k]
3828 					|| (v->WritebackHTaps[k] > 2.0
3829 							&& ((v->WritebackHTaps[k] % 2)
3830 									== 1))) {
3831 				v->WritebackScaleRatioAndTapsSupport = false;
3832 			}
3833 			if (2.0 * v->WritebackDestinationWidth[k] * (v->WritebackVTaps[k] - 1) * 57 > v->WritebackLineBufferSize) {
3834 				v->WritebackScaleRatioAndTapsSupport = false;
3835 			}
3836 		}
3837 	}
3838 	/*Maximum DISPCLK/DPPCLK Support check*/
3839 
3840 	v->WritebackRequiredDISPCLK = 0.0;
3841 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3842 		if (v->WritebackEnable[k] == true) {
3843 			v->WritebackRequiredDISPCLK = dml_max(v->WritebackRequiredDISPCLK,
3844 					dml30_CalculateWriteBackDISPCLK(
3845 							v->WritebackPixelFormat[k],
3846 							v->PixelClock[k],
3847 							v->WritebackHRatio[k],
3848 							v->WritebackVRatio[k],
3849 							v->WritebackHTaps[k],
3850 							v->WritebackVTaps[k],
3851 							v->WritebackSourceWidth[k],
3852 							v->WritebackDestinationWidth[k],
3853 							v->HTotal[k],
3854 							v->WritebackLineBufferSize));
3855 		}
3856 	}
3857 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3858 		if (v->HRatio[k] > 1.0) {
3859 			v->PSCL_FACTOR[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1.0));
3860 		} else {
3861 			v->PSCL_FACTOR[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
3862 		}
3863 		if (v->BytePerPixelC[k] == 0.0) {
3864 			v->PSCL_FACTOR_CHROMA[k] = 0.0;
3865 			v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k]
3866 					* 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);
3867 			if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0) && v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
3868 				v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
3869 			}
3870 		} else {
3871 			if (v->HRatioChroma[k] > 1.0) {
3872 				v->PSCL_FACTOR_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput,
3873 						v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
3874 			} else {
3875 				v->PSCL_FACTOR_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
3876 			}
3877 			v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k] * dml_max5(v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
3878 							v->HRatio[k] * v->VRatio[k] / v->PSCL_FACTOR[k],
3879 							v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
3880 							v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_FACTOR_CHROMA[k],
3881 							1.0);
3882 			if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0 || v->HTAPsChroma[k] > 6.0 || v->VTAPsChroma[k] > 6.0)
3883 					&& v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
3884 				v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
3885 			}
3886 		}
3887 	}
3888 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3889 		int MaximumSwathWidthSupportLuma = 0;
3890 		int MaximumSwathWidthSupportChroma = 0;
3891 
3892 		if (v->SurfaceTiling[k] == dm_sw_linear) {
3893 			MaximumSwathWidthSupportLuma = 8192.0;
3894 		} else if (v->SourceScan[k] == dm_vert && v->BytePerPixelC[k] > 0) {
3895 			MaximumSwathWidthSupportLuma = 2880.0;
3896 		} else {
3897 			MaximumSwathWidthSupportLuma = 5760.0;
3898 		}
3899 
3900 		if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) {
3901 			MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma / 2.0;
3902 		} else {
3903 			MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma;
3904 		}
3905 		v->MaximumSwathWidthInLineBufferLuma = v->LineBufferSize * dml_max(v->HRatio[k], 1.0) / v->LBBitPerPixel[k]
3906 				/ (v->vtaps[k] + dml_max(dml_ceil(v->VRatio[k], 1.0) - 2, 0.0));
3907 		if (v->BytePerPixelC[k] == 0.0) {
3908 			v->MaximumSwathWidthInLineBufferChroma = 0;
3909 		} else {
3910 			v->MaximumSwathWidthInLineBufferChroma = v->LineBufferSize * dml_max(v->HRatioChroma[k], 1.0) / v->LBBitPerPixel[k]
3911 					/ (v->VTAPsChroma[k] + dml_max(dml_ceil(v->VRatioChroma[k], 1.0) - 2, 0.0));
3912 		}
3913 		v->MaximumSwathWidthLuma[k] = dml_min(MaximumSwathWidthSupportLuma, v->MaximumSwathWidthInLineBufferLuma);
3914 		v->MaximumSwathWidthChroma[k] = dml_min(MaximumSwathWidthSupportChroma, v->MaximumSwathWidthInLineBufferChroma);
3915 	}
3916 
3917 	CalculateSwathAndDETConfiguration(
3918 			true,
3919 			v->NumberOfActivePlanes,
3920 			v->DETBufferSizeInKByte[0],
3921 			v->MaximumSwathWidthLuma,
3922 			v->MaximumSwathWidthChroma,
3923 			v->SourceScan,
3924 			v->SourcePixelFormat,
3925 			v->SurfaceTiling,
3926 			v->ViewportWidth,
3927 			v->ViewportHeight,
3928 			v->SurfaceWidthY,
3929 			v->SurfaceWidthC,
3930 			v->SurfaceHeightY,
3931 			v->SurfaceHeightC,
3932 			v->Read256BlockHeightY,
3933 			v->Read256BlockHeightC,
3934 			v->Read256BlockWidthY,
3935 			v->Read256BlockWidthC,
3936 			v->odm_combine_dummy,
3937 			v->BlendingAndTiming,
3938 			v->BytePerPixelY,
3939 			v->BytePerPixelC,
3940 			v->BytePerPixelInDETY,
3941 			v->BytePerPixelInDETC,
3942 			v->HActive,
3943 			v->HRatio,
3944 			v->HRatioChroma,
3945 			v->DPPPerPlane,
3946 			v->swath_width_luma_ub,
3947 			v->swath_width_chroma_ub,
3948 			v->SwathWidthY,
3949 			v->SwathWidthC,
3950 			v->SwathHeightY,
3951 			v->SwathHeightC,
3952 			v->DETBufferSizeY,
3953 			v->DETBufferSizeC,
3954 			v->SingleDPPViewportSizeSupportPerPlane,
3955 			&v->ViewportSizeSupport[0][0]);
3956 
3957 	for (i = 0; i < v->soc.num_states; i++) {
3958 		for (j = 0; j < 2; j++) {
3959 			v->MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDispclk[i], v->DISPCLKDPPCLKVCOSpeed);
3960 			v->MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDppclk[i], v->DISPCLKDPPCLKVCOSpeed);
3961 			v->RequiredDISPCLK[i][j] = 0.0;
3962 			v->DISPCLK_DPPCLK_Support[i][j] = true;
3963 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
3964 				v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
3965 						* (1.0 + v->DISPCLKRampingMargin / 100.0);
3966 				if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
3967 						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
3968 					v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
3969 				}
3970 				v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
3971 						* (1 + v->DISPCLKRampingMargin / 100.0);
3972 				if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
3973 						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
3974 					v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
3975 				}
3976 				v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
3977 						* (1 + v->DISPCLKRampingMargin / 100.0);
3978 				if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1]
3979 						&& v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) {
3980 					v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
3981 				}
3982 
3983 				if (v->ODMCombinePolicy == dm_odm_combine_policy_none) {
3984 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
3985 					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
3986 				} else if (v->ODMCombinePolicy == dm_odm_combine_policy_2to1) {
3987 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
3988 					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
3989 				} else if (v->ODMCombinePolicy == dm_odm_combine_policy_4to1
3990 						|| v->PlaneRequiredDISPCLKWithODMCombine2To1 > v->MaxDispclkRoundedDownToDFSGranularity) {
3991 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
3992 					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
3993 				} else if (v->PlaneRequiredDISPCLKWithoutODMCombine > v->MaxDispclkRoundedDownToDFSGranularity) {
3994 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
3995 					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
3996 				} else {
3997 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
3998 					v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
3999 				}
4000 				if (v->DSCEnabled[k] && v->HActive[k] > DCN30_MAX_DSC_IMAGE_WIDTH
4001 						&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
4002 					if (v->HActive[k] / 2 > DCN30_MAX_DSC_IMAGE_WIDTH) {
4003 						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4004 						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4005 					} else {
4006 						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4007 						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4008 					}
4009 				}
4010 				if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN30_MAX_FMT_420_BUFFER_WIDTH
4011 						&& v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
4012 					if (v->HActive[k] / 2 > DCN30_MAX_FMT_420_BUFFER_WIDTH) {
4013 						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4014 						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4015 					} else {
4016 						v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4017 						v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4018 					}
4019 				}
4020 				if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
4021 					v->MPCCombine[i][j][k] = false;
4022 					v->NoOfDPP[i][j][k] = 4;
4023 					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 4;
4024 				} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4025 					v->MPCCombine[i][j][k] = false;
4026 					v->NoOfDPP[i][j][k] = 2;
4027 					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2;
4028 				} else if ((v->WhenToDoMPCCombine == dm_mpc_never
4029 						|| (v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= v->MaxDppclkRoundedDownToDFSGranularity
4030 								&& v->SingleDPPViewportSizeSupportPerPlane[k] == true))) {
4031 					v->MPCCombine[i][j][k] = false;
4032 					v->NoOfDPP[i][j][k] = 1;
4033 					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4034 				} else {
4035 					v->MPCCombine[i][j][k] = true;
4036 					v->NoOfDPP[i][j][k] = 2;
4037 					v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
4038 				}
4039 				v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
4040 				if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4041 						> v->MaxDppclkRoundedDownToDFSGranularity) || (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
4042 					v->DISPCLK_DPPCLK_Support[i][j] = false;
4043 				}
4044 			}
4045 			v->TotalNumberOfActiveDPP[i][j] = 0;
4046 			v->TotalNumberOfSingleDPPPlanes[i][j] = 0;
4047 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4048 				v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4049 				if (v->NoOfDPP[i][j][k] == 1)
4050 					v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] + 1;
4051 			}
4052 			if (j == 1 && v->WhenToDoMPCCombine != dm_mpc_never) {
4053 				while (!(v->TotalNumberOfActiveDPP[i][j] >= v->MaxNumDPP || v->TotalNumberOfSingleDPPPlanes[i][j] == 0)) {
4054 					double BWOfNonSplitPlaneOfMaximumBandwidth = 0;
4055 					unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
4056 					BWOfNonSplitPlaneOfMaximumBandwidth = 0;
4057 					NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
4058 					for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4059 						if (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k] > BWOfNonSplitPlaneOfMaximumBandwidth
4060 								&& v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled && v->MPCCombine[i][j][k] == false) {
4061 							BWOfNonSplitPlaneOfMaximumBandwidth = v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
4062 							NumberOfNonSplitPlaneOfMaximumBandwidth = k;
4063 						}
4064 					}
4065 					v->MPCCombine[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = true;
4066 					v->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
4067 					v->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = v->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
4068 							* (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
4069 					v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + 1;
4070 					v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] - 1;
4071 				}
4072 			}
4073 			if (v->TotalNumberOfActiveDPP[i][j] > v->MaxNumDPP) {
4074 				v->RequiredDISPCLK[i][j] = 0.0;
4075 				v->DISPCLK_DPPCLK_Support[i][j] = true;
4076 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4077 					v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
4078 					if (v->SingleDPPViewportSizeSupportPerPlane[k] == false && v->WhenToDoMPCCombine != dm_mpc_never) {
4079 						v->MPCCombine[i][j][k] = true;
4080 						v->NoOfDPP[i][j][k] = 2;
4081 						v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
4082 					} else {
4083 						v->MPCCombine[i][j][k] = false;
4084 						v->NoOfDPP[i][j][k] = 1;
4085 						v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4086 					}
4087 					if (!(v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1] && v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4088 						v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4089 								* (1.0 + v->DISPCLKRampingMargin / 100.0);
4090 					} else {
4091 						v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4092 					}
4093 					v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
4094 					if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4095 							> v->MaxDppclkRoundedDownToDFSGranularity) || (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
4096 						v->DISPCLK_DPPCLK_Support[i][j] = false;
4097 					}
4098 				}
4099 				v->TotalNumberOfActiveDPP[i][j] = 0.0;
4100 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4101 					v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4102 				}
4103 			}
4104 			v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->WritebackRequiredDISPCLK);
4105 			if (v->MaxDispclkRoundedDownToDFSGranularity < v->WritebackRequiredDISPCLK) {
4106 				v->DISPCLK_DPPCLK_Support[i][j] = false;
4107 			}
4108 		}
4109 	}
4110 
4111 	/*Total Available Pipes Support Check*/
4112 
4113 	for (i = 0; i < v->soc.num_states; i++) {
4114 		for (j = 0; j < 2; j++) {
4115 			if (v->TotalNumberOfActiveDPP[i][j] <= v->MaxNumDPP) {
4116 				v->TotalAvailablePipesSupport[i][j] = true;
4117 			} else {
4118 				v->TotalAvailablePipesSupport[i][j] = false;
4119 			}
4120 		}
4121 	}
4122 	/*Display IO and DSC Support Check*/
4123 
4124 	v->NonsupportedDSCInputBPC = false;
4125 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4126 		if (!(v->DSCInputBitPerComponent[k] == 12.0
4127 				|| v->DSCInputBitPerComponent[k] == 10.0
4128 				|| v->DSCInputBitPerComponent[k] == 8.0)) {
4129 			v->NonsupportedDSCInputBPC = true;
4130 		}
4131 	}
4132 
4133 	/*Number Of DSC Slices*/
4134 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4135 		if (v->BlendingAndTiming[k] == k) {
4136 			if (v->PixelClockBackEnd[k] > 3200) {
4137 				v->NumberOfDSCSlices[k] = dml_ceil(v->PixelClockBackEnd[k] / 400.0, 4.0);
4138 			} else if (v->PixelClockBackEnd[k] > 1360) {
4139 				v->NumberOfDSCSlices[k] = 8;
4140 			} else if (v->PixelClockBackEnd[k] > 680) {
4141 				v->NumberOfDSCSlices[k] = 4;
4142 			} else if (v->PixelClockBackEnd[k] > 340) {
4143 				v->NumberOfDSCSlices[k] = 2;
4144 			} else {
4145 				v->NumberOfDSCSlices[k] = 1;
4146 			}
4147 		} else {
4148 			v->NumberOfDSCSlices[k] = 0;
4149 		}
4150 	}
4151 
4152 	for (i = 0; i < v->soc.num_states; i++) {
4153 		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4154 			v->RequiresDSC[i][k] = false;
4155 			v->RequiresFEC[i][k] = false;
4156 			if (v->BlendingAndTiming[k] == k) {
4157 				if (v->Output[k] == dm_hdmi) {
4158 					v->RequiresDSC[i][k] = false;
4159 					v->RequiresFEC[i][k] = false;
4160 					v->OutputBppPerState[i][k] = TruncToValidBPP(
4161 							dml_min(600.0, v->PHYCLKPerState[i]) * 10,
4162 							3,
4163 							v->HTotal[k],
4164 							v->HActive[k],
4165 							v->PixelClockBackEnd[k],
4166 							v->ForcedOutputLinkBPP[k],
4167 							false,
4168 							v->Output[k],
4169 							v->OutputFormat[k],
4170 							v->DSCInputBitPerComponent[k],
4171 							v->NumberOfDSCSlices[k],
4172 							v->AudioSampleRate[k],
4173 							v->AudioSampleLayout[k],
4174 							v->ODMCombineEnablePerState[i][k]);
4175 				} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
4176 					if (v->DSCEnable[k] == true) {
4177 						v->RequiresDSC[i][k] = true;
4178 						v->LinkDSCEnable = true;
4179 						if (v->Output[k] == dm_dp) {
4180 							v->RequiresFEC[i][k] = true;
4181 						} else {
4182 							v->RequiresFEC[i][k] = false;
4183 						}
4184 					} else {
4185 						v->RequiresDSC[i][k] = false;
4186 						v->LinkDSCEnable = false;
4187 						v->RequiresFEC[i][k] = false;
4188 					}
4189 
4190 					v->Outbpp = BPP_INVALID;
4191 					if (v->PHYCLKPerState[i] >= 270.0) {
4192 						v->Outbpp = TruncToValidBPP(
4193 								(1.0 - v->Downspreading / 100.0) * 2700,
4194 								v->OutputLinkDPLanes[k],
4195 								v->HTotal[k],
4196 								v->HActive[k],
4197 								v->PixelClockBackEnd[k],
4198 								v->ForcedOutputLinkBPP[k],
4199 								v->LinkDSCEnable,
4200 								v->Output[k],
4201 								v->OutputFormat[k],
4202 								v->DSCInputBitPerComponent[k],
4203 								v->NumberOfDSCSlices[k],
4204 								v->AudioSampleRate[k],
4205 								v->AudioSampleLayout[k],
4206 								v->ODMCombineEnablePerState[i][k]);
4207 						v->OutputBppPerState[i][k] = v->Outbpp;
4208 						// TODO: Need some other way to handle this nonsense
4209 						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
4210 					}
4211 					if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
4212 						v->Outbpp = TruncToValidBPP(
4213 								(1.0 - v->Downspreading / 100.0) * 5400,
4214 								v->OutputLinkDPLanes[k],
4215 								v->HTotal[k],
4216 								v->HActive[k],
4217 								v->PixelClockBackEnd[k],
4218 								v->ForcedOutputLinkBPP[k],
4219 								v->LinkDSCEnable,
4220 								v->Output[k],
4221 								v->OutputFormat[k],
4222 								v->DSCInputBitPerComponent[k],
4223 								v->NumberOfDSCSlices[k],
4224 								v->AudioSampleRate[k],
4225 								v->AudioSampleLayout[k],
4226 								v->ODMCombineEnablePerState[i][k]);
4227 						v->OutputBppPerState[i][k] = v->Outbpp;
4228 						// TODO: Need some other way to handle this nonsense
4229 						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
4230 					}
4231 					if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
4232 						v->Outbpp = TruncToValidBPP(
4233 								(1.0 - v->Downspreading / 100.0) * 8100,
4234 								v->OutputLinkDPLanes[k],
4235 								v->HTotal[k],
4236 								v->HActive[k],
4237 								v->PixelClockBackEnd[k],
4238 								v->ForcedOutputLinkBPP[k],
4239 								v->LinkDSCEnable,
4240 								v->Output[k],
4241 								v->OutputFormat[k],
4242 								v->DSCInputBitPerComponent[k],
4243 								v->NumberOfDSCSlices[k],
4244 								v->AudioSampleRate[k],
4245 								v->AudioSampleLayout[k],
4246 								v->ODMCombineEnablePerState[i][k]);
4247 						if (v->Outbpp == BPP_INVALID && v->ForcedOutputLinkBPP[k] == 0) {
4248 							//if (v->Outbpp == BPP_INVALID && v->DSCEnabled[k] == dm_dsc_enable_only_if_necessary && v->ForcedOutputLinkBPP[k] == 0) {
4249 							v->RequiresDSC[i][k] = true;
4250 							v->LinkDSCEnable = true;
4251 							if (v->Output[k] == dm_dp) {
4252 								v->RequiresFEC[i][k] = true;
4253 							}
4254 							v->Outbpp = TruncToValidBPP(
4255 									(1.0 - v->Downspreading / 100.0) * 8100,
4256 									v->OutputLinkDPLanes[k],
4257 									v->HTotal[k],
4258 									v->HActive[k],
4259 									v->PixelClockBackEnd[k],
4260 									v->ForcedOutputLinkBPP[k],
4261 									v->LinkDSCEnable,
4262 									v->Output[k],
4263 									v->OutputFormat[k],
4264 									v->DSCInputBitPerComponent[k],
4265 									v->NumberOfDSCSlices[k],
4266 									v->AudioSampleRate[k],
4267 									v->AudioSampleLayout[k],
4268 									v->ODMCombineEnablePerState[i][k]);
4269 						}
4270 						v->OutputBppPerState[i][k] = v->Outbpp;
4271 						// TODO: Need some other way to handle this nonsense
4272 						// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
4273 					}
4274 				}
4275 			} else {
4276 				v->OutputBppPerState[i][k] = 0;
4277 			}
4278 		}
4279 	}
4280 	for (i = 0; i < v->soc.num_states; i++) {
4281 		v->DIOSupport[i] = true;
4282 		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4283 			if (!v->skip_dio_check[k] && v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi)
4284 					&& (v->OutputBppPerState[i][k] == 0
4285 							|| (v->OutputFormat[k] == dm_420 && v->Interlace[k] == true && v->ProgressiveToInterlaceUnitInOPP == true))) {
4286 				v->DIOSupport[i] = false;
4287 			}
4288 		}
4289 	}
4290 
4291 	for (i = 0; i < v->soc.num_states; ++i) {
4292 		v->ODMCombine4To1SupportCheckOK[i] = true;
4293 		for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4294 			if (v->BlendingAndTiming[k] == k && v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1
4295 					&& (v->ODMCombine4To1Supported == false || v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi)) {
4296 				v->ODMCombine4To1SupportCheckOK[i] = false;
4297 			}
4298 		}
4299 	}
4300 
4301 	/* Skip dscclk validation: as long as dispclk is supported, dscclk is also implicitly supported */
4302 
4303 	for (i = 0; i < v->soc.num_states; i++) {
4304 		v->NotEnoughDSCUnits[i] = false;
4305 		v->TotalDSCUnitsRequired = 0.0;
4306 		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4307 			if (v->RequiresDSC[i][k] == true) {
4308 				if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
4309 					v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 4.0;
4310 				} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4311 					v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 2.0;
4312 				} else {
4313 					v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 1.0;
4314 				}
4315 			}
4316 		}
4317 		if (v->TotalDSCUnitsRequired > v->NumberOfDSC) {
4318 			v->NotEnoughDSCUnits[i] = true;
4319 		}
4320 	}
4321 	/*DSC Delay per state*/
4322 
4323 	for (i = 0; i < v->soc.num_states; i++) {
4324 		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4325 			if (v->OutputBppPerState[i][k] == BPP_INVALID) {
4326 				v->BPP = 0.0;
4327 			} else {
4328 				v->BPP = v->OutputBppPerState[i][k];
4329 			}
4330 			if (v->RequiresDSC[i][k] == true && v->BPP != 0.0) {
4331 				if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
4332 					v->DSCDelayPerState[i][k] = dscceComputeDelay(
4333 							v->DSCInputBitPerComponent[k],
4334 							v->BPP,
4335 							dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4336 							v->NumberOfDSCSlices[k],
4337 							v->OutputFormat[k],
4338 							v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
4339 				} else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4340 					v->DSCDelayPerState[i][k] = 2.0
4341 							* dscceComputeDelay(
4342 									v->DSCInputBitPerComponent[k],
4343 									v->BPP,
4344 									dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4345 									v->NumberOfDSCSlices[k] / 2,
4346 									v->OutputFormat[k],
4347 									v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
4348 				} else {
4349 					v->DSCDelayPerState[i][k] = 4.0
4350 							* (dscceComputeDelay(
4351 									v->DSCInputBitPerComponent[k],
4352 									v->BPP,
4353 									dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4354 									v->NumberOfDSCSlices[k] / 4,
4355 									v->OutputFormat[k],
4356 									v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
4357 				}
4358 				v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
4359 			} else {
4360 				v->DSCDelayPerState[i][k] = 0.0;
4361 			}
4362 		}
4363 		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4364 			for (m = 0; m <= v->NumberOfActivePlanes - 1; m++) {
4365 				if (v->BlendingAndTiming[k] == m && v->RequiresDSC[i][m] == true) {
4366 					v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][m];
4367 				}
4368 			}
4369 		}
4370 	}
4371 
4372 	//Calculate Swath, DET Configuration, DCFCLKDeepSleep
4373 	//
4374 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
4375 		for (j = 0; j <= 1; ++j) {
4376 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4377 				v->RequiredDPPCLKThisState[k] = v->RequiredDPPCLK[i][j][k];
4378 				v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
4379 				v->ODMCombineEnableThisState[k] = v->ODMCombineEnablePerState[i][k];
4380 			}
4381 
4382 			CalculateSwathAndDETConfiguration(
4383 					false,
4384 					v->NumberOfActivePlanes,
4385 					v->DETBufferSizeInKByte[0],
4386 					v->MaximumSwathWidthLuma,
4387 					v->MaximumSwathWidthChroma,
4388 					v->SourceScan,
4389 					v->SourcePixelFormat,
4390 					v->SurfaceTiling,
4391 					v->ViewportWidth,
4392 					v->ViewportHeight,
4393 					v->SurfaceWidthY,
4394 					v->SurfaceWidthC,
4395 					v->SurfaceHeightY,
4396 					v->SurfaceHeightC,
4397 					v->Read256BlockHeightY,
4398 					v->Read256BlockHeightC,
4399 					v->Read256BlockWidthY,
4400 					v->Read256BlockWidthC,
4401 					v->ODMCombineEnableThisState,
4402 					v->BlendingAndTiming,
4403 					v->BytePerPixelY,
4404 					v->BytePerPixelC,
4405 					v->BytePerPixelInDETY,
4406 					v->BytePerPixelInDETC,
4407 					v->HActive,
4408 					v->HRatio,
4409 					v->HRatioChroma,
4410 					v->NoOfDPPThisState,
4411 					v->swath_width_luma_ub_this_state,
4412 					v->swath_width_chroma_ub_this_state,
4413 					v->SwathWidthYThisState,
4414 					v->SwathWidthCThisState,
4415 					v->SwathHeightYThisState,
4416 					v->SwathHeightCThisState,
4417 					v->DETBufferSizeYThisState,
4418 					v->DETBufferSizeCThisState,
4419 					v->dummystring,
4420 					&v->ViewportSizeSupport[i][j]);
4421 
4422 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4423 				v->swath_width_luma_ub_all_states[i][j][k] = v->swath_width_luma_ub_this_state[k];
4424 				v->swath_width_chroma_ub_all_states[i][j][k] = v->swath_width_chroma_ub_this_state[k];
4425 				v->SwathWidthYAllStates[i][j][k] = v->SwathWidthYThisState[k];
4426 				v->SwathWidthCAllStates[i][j][k] = v->SwathWidthCThisState[k];
4427 				v->SwathHeightYAllStates[i][j][k] = v->SwathHeightYThisState[k];
4428 				v->SwathHeightCAllStates[i][j][k] = v->SwathHeightCThisState[k];
4429 				v->DETBufferSizeYAllStates[i][j][k] = v->DETBufferSizeYThisState[k];
4430 				v->DETBufferSizeCAllStates[i][j][k] = v->DETBufferSizeCThisState[k];
4431 			}
4432 
4433 		}
4434 	}
4435 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4436 		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];
4437 	}
4438 
4439 	for (i = 0; i < v->soc.num_states; i++) {
4440 		for (j = 0; j < 2; j++) {
4441 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4442 				v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
4443 				v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
4444 				v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
4445 				v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
4446 				v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
4447 				v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
4448 				v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
4449 				v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
4450 			}
4451 
4452 			v->TotalNumberOfDCCActiveDPP[i][j] = 0;
4453 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4454 				if (v->DCCEnable[k] == true) {
4455 					v->TotalNumberOfDCCActiveDPP[i][j] = v->TotalNumberOfDCCActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4456 				}
4457 			}
4458 
4459 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4460 				if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
4461 						|| v->SourcePixelFormat[k] == dm_rgbe_alpha) {
4462 
4463 					if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) && v->SourceScan[k] != dm_vert) {
4464 						v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma) / 2;
4465 						v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
4466 					} else {
4467 						v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
4468 						v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
4469 					}
4470 
4471 					v->PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
4472 							mode_lib,
4473 							v->DCCEnable[k],
4474 							v->Read256BlockHeightC[k],
4475 							v->Read256BlockWidthY[k],
4476 							v->SourcePixelFormat[k],
4477 							v->SurfaceTiling[k],
4478 							v->BytePerPixelC[k],
4479 							v->SourceScan[k],
4480 							v->SwathWidthCThisState[k],
4481 							v->ViewportHeightChroma[k],
4482 							v->GPUVMEnable,
4483 							v->HostVMEnable,
4484 							v->HostVMMaxNonCachedPageTableLevels,
4485 							v->GPUVMMinPageSize,
4486 							v->HostVMMinPageSize,
4487 							v->PTEBufferSizeInRequestsForChroma,
4488 							v->PitchC[k],
4489 							0.0,
4490 							&v->MacroTileWidthC[k],
4491 							&v->MetaRowBytesC,
4492 							&v->DPTEBytesPerRowC,
4493 							&v->PTEBufferSizeNotExceededC[i][j][k],
4494 							&v->dummyinteger7,
4495 							&v->dpte_row_height_chroma[k],
4496 							&v->dummyinteger28,
4497 							&v->dummyinteger26,
4498 							&v->dummyinteger23,
4499 							&v->meta_row_height_chroma[k],
4500 							&v->dummyinteger8,
4501 							&v->dummyinteger9,
4502 							&v->dummyinteger19,
4503 							&v->dummyinteger20,
4504 							&v->dummyinteger17,
4505 							&v->dummyinteger10,
4506 							&v->dummyinteger11);
4507 
4508 					v->PrefetchLinesC[i][j][k] = CalculatePrefetchSourceLines(
4509 							mode_lib,
4510 							v->VRatioChroma[k],
4511 							v->VTAPsChroma[k],
4512 							v->Interlace[k],
4513 							v->ProgressiveToInterlaceUnitInOPP,
4514 							v->SwathHeightCThisState[k],
4515 							v->ViewportYStartC[k],
4516 							&v->PrefillC[k],
4517 							&v->MaxNumSwC[k]);
4518 				} else {
4519 					v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
4520 					v->PTEBufferSizeInRequestsForChroma = 0;
4521 					v->PDEAndMetaPTEBytesPerFrameC = 0.0;
4522 					v->MetaRowBytesC = 0.0;
4523 					v->DPTEBytesPerRowC = 0.0;
4524 					v->PrefetchLinesC[i][j][k] = 0.0;
4525 					v->PTEBufferSizeNotExceededC[i][j][k] = true;
4526 				}
4527 				v->PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
4528 						mode_lib,
4529 						v->DCCEnable[k],
4530 						v->Read256BlockHeightY[k],
4531 						v->Read256BlockWidthY[k],
4532 						v->SourcePixelFormat[k],
4533 						v->SurfaceTiling[k],
4534 						v->BytePerPixelY[k],
4535 						v->SourceScan[k],
4536 						v->SwathWidthYThisState[k],
4537 						v->ViewportHeight[k],
4538 						v->GPUVMEnable,
4539 						v->HostVMEnable,
4540 						v->HostVMMaxNonCachedPageTableLevels,
4541 						v->GPUVMMinPageSize,
4542 						v->HostVMMinPageSize,
4543 						v->PTEBufferSizeInRequestsForLuma,
4544 						v->PitchY[k],
4545 						v->DCCMetaPitchY[k],
4546 						&v->MacroTileWidthY[k],
4547 						&v->MetaRowBytesY,
4548 						&v->DPTEBytesPerRowY,
4549 						&v->PTEBufferSizeNotExceededY[i][j][k],
4550 						v->dummyinteger4,
4551 						&v->dpte_row_height[k],
4552 						&v->dummyinteger29,
4553 						&v->dummyinteger27,
4554 						&v->dummyinteger24,
4555 						&v->meta_row_height[k],
4556 						&v->dummyinteger25,
4557 						&v->dpte_group_bytes[k],
4558 						&v->dummyinteger21,
4559 						&v->dummyinteger22,
4560 						&v->dummyinteger18,
4561 						&v->dummyinteger5,
4562 						&v->dummyinteger6);
4563 				v->PrefetchLinesY[i][j][k] = CalculatePrefetchSourceLines(
4564 						mode_lib,
4565 						v->VRatio[k],
4566 						v->vtaps[k],
4567 						v->Interlace[k],
4568 						v->ProgressiveToInterlaceUnitInOPP,
4569 						v->SwathHeightYThisState[k],
4570 						v->ViewportYStartY[k],
4571 						&v->PrefillY[k],
4572 						&v->MaxNumSwY[k]);
4573 				v->PDEAndMetaPTEBytesPerFrame[i][j][k] = v->PDEAndMetaPTEBytesPerFrameY + v->PDEAndMetaPTEBytesPerFrameC;
4574 				v->MetaRowBytes[i][j][k] = v->MetaRowBytesY + v->MetaRowBytesC;
4575 				v->DPTEBytesPerRow[i][j][k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC;
4576 
4577 				CalculateRowBandwidth(
4578 						v->GPUVMEnable,
4579 						v->SourcePixelFormat[k],
4580 						v->VRatio[k],
4581 						v->VRatioChroma[k],
4582 						v->DCCEnable[k],
4583 						v->HTotal[k] / v->PixelClock[k],
4584 						v->MetaRowBytesY,
4585 						v->MetaRowBytesC,
4586 						v->meta_row_height[k],
4587 						v->meta_row_height_chroma[k],
4588 						v->DPTEBytesPerRowY,
4589 						v->DPTEBytesPerRowC,
4590 						v->dpte_row_height[k],
4591 						v->dpte_row_height_chroma[k],
4592 						&v->meta_row_bandwidth[i][j][k],
4593 						&v->dpte_row_bandwidth[i][j][k]);
4594 			}
4595 			v->UrgLatency[i] = CalculateUrgentLatency(
4596 					v->UrgentLatencyPixelDataOnly,
4597 					v->UrgentLatencyPixelMixedWithVMData,
4598 					v->UrgentLatencyVMDataOnly,
4599 					v->DoUrgentLatencyAdjustment,
4600 					v->UrgentLatencyAdjustmentFabricClockComponent,
4601 					v->UrgentLatencyAdjustmentFabricClockReference,
4602 					v->FabricClockPerState[i]);
4603 
4604 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4605 				CalculateUrgentBurstFactor(
4606 						v->swath_width_luma_ub_this_state[k],
4607 						v->swath_width_chroma_ub_this_state[k],
4608 						v->DETBufferSizeInKByte[0],
4609 						v->SwathHeightYThisState[k],
4610 						v->SwathHeightCThisState[k],
4611 						v->HTotal[k] / v->PixelClock[k],
4612 						v->UrgLatency[i],
4613 						v->CursorBufferSize,
4614 						v->CursorWidth[k][0],
4615 						v->CursorBPP[k][0],
4616 						v->VRatio[k],
4617 						v->VRatioChroma[k],
4618 						v->BytePerPixelInDETY[k],
4619 						v->BytePerPixelInDETC[k],
4620 						v->DETBufferSizeYThisState[k],
4621 						v->DETBufferSizeCThisState[k],
4622 						&v->UrgentBurstFactorCursor[k],
4623 						&v->UrgentBurstFactorLuma[k],
4624 						&v->UrgentBurstFactorChroma[k],
4625 						&NotUrgentLatencyHiding[k]);
4626 			}
4627 
4628 			v->NotUrgentLatencyHiding[i][j] = false;
4629 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4630 				if (NotUrgentLatencyHiding[k]) {
4631 					v->NotUrgentLatencyHiding[i][j] = true;
4632 				}
4633 			}
4634 
4635 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4636 				v->VActivePixelBandwidth[i][j][k] = v->ReadBandwidthLuma[k] * v->UrgentBurstFactorLuma[k]
4637 						+ v->ReadBandwidthChroma[k] * v->UrgentBurstFactorChroma[k];
4638 				v->VActiveCursorBandwidth[i][j][k] = v->cursor_bw[k] * v->UrgentBurstFactorCursor[k];
4639 			}
4640 
4641 			v->TotalVActivePixelBandwidth[i][j] = 0;
4642 			v->TotalVActiveCursorBandwidth[i][j] = 0;
4643 			v->TotalMetaRowBandwidth[i][j] = 0;
4644 			v->TotalDPTERowBandwidth[i][j] = 0;
4645 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4646 				v->TotalVActivePixelBandwidth[i][j] = v->TotalVActivePixelBandwidth[i][j] + v->VActivePixelBandwidth[i][j][k];
4647 				v->TotalVActiveCursorBandwidth[i][j] = v->TotalVActiveCursorBandwidth[i][j] + v->VActiveCursorBandwidth[i][j][k];
4648 				v->TotalMetaRowBandwidth[i][j] = v->TotalMetaRowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->meta_row_bandwidth[i][j][k];
4649 				v->TotalDPTERowBandwidth[i][j] = v->TotalDPTERowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->dpte_row_bandwidth[i][j][k];
4650 			}
4651 
4652 			CalculateDCFCLKDeepSleep(
4653 					mode_lib,
4654 					v->NumberOfActivePlanes,
4655 					v->BytePerPixelY,
4656 					v->BytePerPixelC,
4657 					v->VRatio,
4658 					v->VRatioChroma,
4659 					v->SwathWidthYThisState,
4660 					v->SwathWidthCThisState,
4661 					v->NoOfDPPThisState,
4662 					v->HRatio,
4663 					v->HRatioChroma,
4664 					v->PixelClock,
4665 					v->PSCL_FACTOR,
4666 					v->PSCL_FACTOR_CHROMA,
4667 					v->RequiredDPPCLKThisState,
4668 					v->ReadBandwidthLuma,
4669 					v->ReadBandwidthChroma,
4670 					v->ReturnBusWidth,
4671 					&v->ProjectedDCFCLKDeepSleep[i][j]);
4672 		}
4673 	}
4674 
4675 	//Calculate Return BW
4676 
4677 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
4678 		for (j = 0; j <= 1; ++j) {
4679 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4680 				if (v->BlendingAndTiming[k] == k) {
4681 					if (v->WritebackEnable[k] == true) {
4682 						v->WritebackDelayTime[k] = v->WritebackLatency
4683 								+ CalculateWriteBackDelay(
4684 										v->WritebackPixelFormat[k],
4685 										v->WritebackHRatio[k],
4686 										v->WritebackVRatio[k],
4687 										v->WritebackVTaps[k],
4688 										v->WritebackDestinationWidth[k],
4689 										v->WritebackDestinationHeight[k],
4690 										v->WritebackSourceHeight[k],
4691 										v->HTotal[k]) / v->RequiredDISPCLK[i][j];
4692 					} else {
4693 						v->WritebackDelayTime[k] = 0.0;
4694 					}
4695 					for (m = 0; m <= v->NumberOfActivePlanes - 1; m++) {
4696 						if (v->BlendingAndTiming[m] == k && v->WritebackEnable[m] == true) {
4697 							v->WritebackDelayTime[k] = dml_max(
4698 									v->WritebackDelayTime[k],
4699 									v->WritebackLatency
4700 											+ CalculateWriteBackDelay(
4701 													v->WritebackPixelFormat[m],
4702 													v->WritebackHRatio[m],
4703 													v->WritebackVRatio[m],
4704 													v->WritebackVTaps[m],
4705 													v->WritebackDestinationWidth[m],
4706 													v->WritebackDestinationHeight[m],
4707 													v->WritebackSourceHeight[m],
4708 													v->HTotal[m]) / v->RequiredDISPCLK[i][j]);
4709 						}
4710 					}
4711 				}
4712 			}
4713 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4714 				for (m = 0; m <= v->NumberOfActivePlanes - 1; m++) {
4715 					if (v->BlendingAndTiming[k] == m) {
4716 						v->WritebackDelayTime[k] = v->WritebackDelayTime[m];
4717 					}
4718 				}
4719 			}
4720 			v->MaxMaxVStartup[i][j] = 0;
4721 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4722 				v->MaximumVStartup[i][j][k] = v->VTotal[k] - v->VActive[k]
4723 						- dml_max(1.0, dml_ceil(1.0 * v->WritebackDelayTime[k] / (v->HTotal[k] / v->PixelClock[k]), 1.0));
4724 				v->MaxMaxVStartup[i][j] = dml_max(v->MaxMaxVStartup[i][j], v->MaximumVStartup[i][j][k]);
4725 			}
4726 		}
4727 	}
4728 
4729 	ReorderingBytes = v->NumberOfChannels
4730 			* dml_max3(
4731 					v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
4732 					v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
4733 					v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
4734 	v->FinalDRAMClockChangeLatency = (v->DRAMClockChangeLatencyOverride > 0 ? v->DRAMClockChangeLatencyOverride : v->DRAMClockChangeLatency);
4735 
4736 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
4737 		for (j = 0; j <= 1; ++j) {
4738 			v->DCFCLKState[i][j] = v->DCFCLKPerState[i];
4739 		}
4740 	}
4741 
4742 	if (v->UseMinimumRequiredDCFCLK == true) {
4743 		UseMinimumDCFCLK(
4744 				mode_lib,
4745 				v->MaxInterDCNTileRepeaters,
4746 				MaxPrefetchMode,
4747 				v->FinalDRAMClockChangeLatency,
4748 				v->SREnterPlusExitTime,
4749 				v->ReturnBusWidth,
4750 				v->RoundTripPingLatencyCycles,
4751 				ReorderingBytes,
4752 				v->PixelChunkSizeInKByte,
4753 				v->MetaChunkSize,
4754 				v->GPUVMEnable,
4755 				v->GPUVMMaxPageTableLevels,
4756 				v->HostVMEnable,
4757 				v->NumberOfActivePlanes,
4758 				v->HostVMMinPageSize,
4759 				v->HostVMMaxNonCachedPageTableLevels,
4760 				v->DynamicMetadataVMEnabled,
4761 				v->ImmediateFlipRequirement[0],
4762 				v->ProgressiveToInterlaceUnitInOPP,
4763 				v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation,
4764 				v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
4765 				v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
4766 				v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly,
4767 				v->VTotal,
4768 				v->VActive,
4769 				v->DynamicMetadataTransmittedBytes,
4770 				v->DynamicMetadataLinesBeforeActiveRequired,
4771 				v->Interlace,
4772 				v->RequiredDPPCLK,
4773 				v->RequiredDISPCLK,
4774 				v->UrgLatency,
4775 				v->NoOfDPP,
4776 				v->ProjectedDCFCLKDeepSleep,
4777 				v->MaximumVStartup,
4778 				v->TotalVActivePixelBandwidth,
4779 				v->TotalVActiveCursorBandwidth,
4780 				v->TotalMetaRowBandwidth,
4781 				v->TotalDPTERowBandwidth,
4782 				v->TotalNumberOfActiveDPP,
4783 				v->TotalNumberOfDCCActiveDPP,
4784 				v->dpte_group_bytes,
4785 				v->PrefetchLinesY,
4786 				v->PrefetchLinesC,
4787 				v->swath_width_luma_ub_all_states,
4788 				v->swath_width_chroma_ub_all_states,
4789 				v->BytePerPixelY,
4790 				v->BytePerPixelC,
4791 				v->HTotal,
4792 				v->PixelClock,
4793 				v->PDEAndMetaPTEBytesPerFrame,
4794 				v->DPTEBytesPerRow,
4795 				v->MetaRowBytes,
4796 				v->DynamicMetadataEnable,
4797 				v->VActivePixelBandwidth,
4798 				v->VActiveCursorBandwidth,
4799 				v->ReadBandwidthLuma,
4800 				v->ReadBandwidthChroma,
4801 				v->DCFCLKPerState,
4802 				v->DCFCLKState);
4803 
4804 		if (v->ClampMinDCFCLK) {
4805 			/* Clamp calculated values to actual minimum */
4806 			for (i = 0; i < mode_lib->soc.num_states; ++i) {
4807 				for (j = 0; j <= 1; ++j) {
4808 					if (v->DCFCLKState[i][j] < mode_lib->soc.min_dcfclk) {
4809 						v->DCFCLKState[i][j] = mode_lib->soc.min_dcfclk;
4810 					}
4811 				}
4812 			}
4813 		}
4814 	}
4815 
4816 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
4817 		for (j = 0; j <= 1; ++j) {
4818 			v->IdealSDPPortBandwidthPerState[i][j] = dml_min3(
4819 					v->ReturnBusWidth * v->DCFCLKState[i][j],
4820 					v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth,
4821 					v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn);
4822 			if (v->HostVMEnable != true) {
4823 				v->ReturnBWPerState[i][j] = v->IdealSDPPortBandwidthPerState[i][j] * v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly
4824 						/ 100;
4825 			} else {
4826 				v->ReturnBWPerState[i][j] = v->IdealSDPPortBandwidthPerState[i][j]
4827 						* v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100;
4828 			}
4829 		}
4830 	}
4831 
4832 	//Re-ordering Buffer Support Check
4833 
4834 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
4835 		for (j = 0; j <= 1; ++j) {
4836 			if ((v->ROBBufferSizeInKByte - v->PixelChunkSizeInKByte) * 1024 / v->ReturnBWPerState[i][j]
4837 					> (v->RoundTripPingLatencyCycles + 32) / v->DCFCLKState[i][j] + ReorderingBytes / v->ReturnBWPerState[i][j]) {
4838 				v->ROBSupport[i][j] = true;
4839 			} else {
4840 				v->ROBSupport[i][j] = false;
4841 			}
4842 		}
4843 	}
4844 
4845 	//Vertical Active BW support check
4846 
4847 	MaxTotalVActiveRDBandwidth = 0;
4848 	for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4849 		MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
4850 	}
4851 
4852 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
4853 		for (j = 0; j <= 1; ++j) {
4854 			v->MaxTotalVerticalActiveAvailableBandwidth[i][j] = dml_min(
4855 					v->IdealSDPPortBandwidthPerState[i][j] * v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100,
4856 					v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth * v->MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation
4857 							/ 100);
4858 			if (MaxTotalVActiveRDBandwidth <= v->MaxTotalVerticalActiveAvailableBandwidth[i][j]) {
4859 				v->TotalVerticalActiveBandwidthSupport[i][j] = true;
4860 			} else {
4861 				v->TotalVerticalActiveBandwidthSupport[i][j] = false;
4862 			}
4863 		}
4864 	}
4865 
4866 	//Prefetch Check
4867 
4868 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
4869 		for (j = 0; j <= 1; ++j) {
4870 			int NextPrefetchModeState = MinPrefetchMode;
4871 
4872 			v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep[i][j];
4873 
4874 			v->BandwidthWithoutPrefetchSupported[i][j] = true;
4875 			if (v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j] + v->TotalDPTERowBandwidth[i][j]
4876 					> v->ReturnBWPerState[i][j] || v->NotUrgentLatencyHiding[i][j]) {
4877 				v->BandwidthWithoutPrefetchSupported[i][j] = false;
4878 			}
4879 
4880 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4881 				v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
4882 				v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
4883 				v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
4884 				v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
4885 				v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
4886 				v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
4887 				v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
4888 				v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
4889 				v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
4890 				v->ODMCombineEnabled[k] = v->ODMCombineEnablePerState[i][k];
4891 			}
4892 
4893 			v->ExtraLatency = CalculateExtraLatency(
4894 					v->RoundTripPingLatencyCycles,
4895 					ReorderingBytes,
4896 					v->DCFCLKState[i][j],
4897 					v->TotalNumberOfActiveDPP[i][j],
4898 					v->PixelChunkSizeInKByte,
4899 					v->TotalNumberOfDCCActiveDPP[i][j],
4900 					v->MetaChunkSize,
4901 					v->ReturnBWPerState[i][j],
4902 					v->GPUVMEnable,
4903 					v->HostVMEnable,
4904 					v->NumberOfActivePlanes,
4905 					v->NoOfDPPThisState,
4906 					v->dpte_group_bytes,
4907 					v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
4908 					v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
4909 					v->HostVMMinPageSize,
4910 					v->HostVMMaxNonCachedPageTableLevels);
4911 
4912 			v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
4913 			do {
4914 				v->PrefetchModePerState[i][j] = NextPrefetchModeState;
4915 				v->MaxVStartup = v->NextMaxVStartup;
4916 
4917 				v->TWait = CalculateTWait(v->PrefetchModePerState[i][j], v->FinalDRAMClockChangeLatency, v->UrgLatency[i], v->SREnterPlusExitTime);
4918 
4919 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
4920 					Pipe myPipe = { 0 };
4921 
4922 					myPipe.DPPCLK = v->RequiredDPPCLK[i][j][k];
4923 					myPipe.DISPCLK = v->RequiredDISPCLK[i][j];
4924 					myPipe.PixelClock = v->PixelClock[k];
4925 					myPipe.DCFCLKDeepSleep = v->ProjectedDCFCLKDeepSleep[i][j];
4926 					myPipe.DPPPerPlane = v->NoOfDPP[i][j][k];
4927 					myPipe.ScalerEnabled = v->ScalerEnabled[k];
4928 					myPipe.SourceScan = v->SourceScan[k];
4929 					myPipe.BlockWidth256BytesY = v->Read256BlockWidthY[k];
4930 					myPipe.BlockHeight256BytesY = v->Read256BlockHeightY[k];
4931 					myPipe.BlockWidth256BytesC = v->Read256BlockWidthC[k];
4932 					myPipe.BlockHeight256BytesC = v->Read256BlockHeightC[k];
4933 					myPipe.InterlaceEnable = v->Interlace[k];
4934 					myPipe.NumberOfCursors = v->NumberOfCursors[k];
4935 					myPipe.VBlank = v->VTotal[k] - v->VActive[k];
4936 					myPipe.HTotal = v->HTotal[k];
4937 					myPipe.DCCEnable = v->DCCEnable[k];
4938 					myPipe.ODMCombineEnabled = !!v->ODMCombineEnabled[k];
4939 
4940 					v->NoTimeForPrefetch[i][j][k] = CalculatePrefetchSchedule(
4941 							mode_lib,
4942 							v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
4943 							v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
4944 							&myPipe,
4945 							v->DSCDelayPerState[i][k],
4946 							v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater,
4947 							v->DPPCLKDelaySCL,
4948 							v->DPPCLKDelaySCLLBOnly,
4949 							v->DPPCLKDelayCNVCCursor,
4950 							v->DISPCLKDelaySubtotal,
4951 							v->SwathWidthYThisState[k] / v->HRatio[k],
4952 							v->OutputFormat[k],
4953 							v->MaxInterDCNTileRepeaters,
4954 							dml_min(v->MaxVStartup, v->MaximumVStartup[i][j][k]),
4955 							v->MaximumVStartup[i][j][k],
4956 							v->GPUVMMaxPageTableLevels,
4957 							v->GPUVMEnable,
4958 							v->HostVMEnable,
4959 							v->HostVMMaxNonCachedPageTableLevels,
4960 							v->HostVMMinPageSize,
4961 							v->DynamicMetadataEnable[k],
4962 							v->DynamicMetadataVMEnabled,
4963 							v->DynamicMetadataLinesBeforeActiveRequired[k],
4964 							v->DynamicMetadataTransmittedBytes[k],
4965 							v->UrgLatency[i],
4966 							v->ExtraLatency,
4967 							v->TimeCalc,
4968 							v->PDEAndMetaPTEBytesPerFrame[i][j][k],
4969 							v->MetaRowBytes[i][j][k],
4970 							v->DPTEBytesPerRow[i][j][k],
4971 							v->PrefetchLinesY[i][j][k],
4972 							v->SwathWidthYThisState[k],
4973 							v->BytePerPixelY[k],
4974 							v->PrefillY[k],
4975 							v->MaxNumSwY[k],
4976 							v->PrefetchLinesC[i][j][k],
4977 							v->SwathWidthCThisState[k],
4978 							v->BytePerPixelC[k],
4979 							v->PrefillC[k],
4980 							v->MaxNumSwC[k],
4981 							v->swath_width_luma_ub_this_state[k],
4982 							v->swath_width_chroma_ub_this_state[k],
4983 							v->SwathHeightYThisState[k],
4984 							v->SwathHeightCThisState[k],
4985 							v->TWait,
4986 							v->ProgressiveToInterlaceUnitInOPP,
4987 							&v->DSTXAfterScaler[k],
4988 							&v->DSTYAfterScaler[k],
4989 							&v->LineTimesForPrefetch[k],
4990 							&v->PrefetchBW[k],
4991 							&v->LinesForMetaPTE[k],
4992 							&v->LinesForMetaAndDPTERow[k],
4993 							&v->VRatioPreY[i][j][k],
4994 							&v->VRatioPreC[i][j][k],
4995 							&v->RequiredPrefetchPixelDataBWLuma[i][j][k],
4996 							&v->RequiredPrefetchPixelDataBWChroma[i][j][k],
4997 							&v->NoTimeForDynamicMetadata[i][j][k],
4998 							&v->Tno_bw[k],
4999 							&v->prefetch_vmrow_bw[k],
5000 							&v->Tdmdl_vm[k],
5001 							&v->Tdmdl[k],
5002 							&v->VUpdateOffsetPix[k],
5003 							&v->VUpdateWidthPix[k],
5004 							&v->VReadyOffsetPix[k]);
5005 				}
5006 
5007 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5008 					CalculateUrgentBurstFactor(
5009 							v->swath_width_luma_ub_this_state[k],
5010 							v->swath_width_chroma_ub_this_state[k],
5011 							v->DETBufferSizeInKByte[0],
5012 							v->SwathHeightYThisState[k],
5013 							v->SwathHeightCThisState[k],
5014 							v->HTotal[k] / v->PixelClock[k],
5015 							v->UrgentLatency,
5016 							v->CursorBufferSize,
5017 							v->CursorWidth[k][0],
5018 							v->CursorBPP[k][0],
5019 							v->VRatioPreY[i][j][k],
5020 							v->VRatioPreC[i][j][k],
5021 							v->BytePerPixelInDETY[k],
5022 							v->BytePerPixelInDETC[k],
5023 							v->DETBufferSizeYThisState[k],
5024 							v->DETBufferSizeCThisState[k],
5025 							&v->UrgentBurstFactorCursorPre[k],
5026 							&v->UrgentBurstFactorLumaPre[k],
5027 							&v->UrgentBurstFactorChroma[k],
5028 							&v->NoUrgentLatencyHidingPre[k]);
5029 				}
5030 
5031 				v->MaximumReadBandwidthWithPrefetch = 0.0;
5032 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5033 					v->cursor_bw_pre[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0 / (v->HTotal[k] / v->PixelClock[k])
5034 							* v->VRatioPreY[i][j][k];
5035 
5036 					v->MaximumReadBandwidthWithPrefetch = v->MaximumReadBandwidthWithPrefetch
5037 							+ dml_max4(
5038 									v->VActivePixelBandwidth[i][j][k],
5039 									v->VActiveCursorBandwidth[i][j][k]
5040 											+ v->NoOfDPP[i][j][k] * (v->meta_row_bandwidth[i][j][k] + v->dpte_row_bandwidth[i][j][k]),
5041 									v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
5042 									v->NoOfDPP[i][j][k]
5043 											* (v->RequiredPrefetchPixelDataBWLuma[i][j][k] * v->UrgentBurstFactorLumaPre[k]
5044 													+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5045 															* v->UrgentBurstFactorChromaPre[k])
5046 											+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5047 				}
5048 
5049 				v->NotEnoughUrgentLatencyHidingPre = false;
5050 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5051 					if (v->NoUrgentLatencyHidingPre[k] == true) {
5052 						v->NotEnoughUrgentLatencyHidingPre = true;
5053 					}
5054 				}
5055 
5056 				v->PrefetchSupported[i][j] = true;
5057 				if (v->BandwidthWithoutPrefetchSupported[i][j] == false || v->MaximumReadBandwidthWithPrefetch > v->ReturnBWPerState[i][j]
5058 						|| v->NotEnoughUrgentLatencyHidingPre == 1) {
5059 					v->PrefetchSupported[i][j] = false;
5060 				}
5061 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5062 					if (v->LineTimesForPrefetch[k] < 2.0 || v->LinesForMetaPTE[k] >= 32.0 || v->LinesForMetaAndDPTERow[k] >= 16.0
5063 							|| v->NoTimeForPrefetch[i][j][k] == true) {
5064 						v->PrefetchSupported[i][j] = false;
5065 					}
5066 				}
5067 
5068 				v->DynamicMetadataSupported[i][j] = true;
5069 				for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5070 					if (v->NoTimeForDynamicMetadata[i][j][k] == true) {
5071 						v->DynamicMetadataSupported[i][j] = false;
5072 					}
5073 				}
5074 
5075 				v->VRatioInPrefetchSupported[i][j] = true;
5076 				for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5077 					if (v->VRatioPreY[i][j][k] > 4.0 || v->VRatioPreC[i][j][k] > 4.0 || v->NoTimeForPrefetch[i][j][k] == true) {
5078 						v->VRatioInPrefetchSupported[i][j] = false;
5079 					}
5080 				}
5081 				v->AnyLinesForVMOrRowTooLarge = false;
5082 				for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5083 					if (v->LinesForMetaAndDPTERow[k] >= 16 || v->LinesForMetaPTE[k] >= 32) {
5084 						v->AnyLinesForVMOrRowTooLarge = true;
5085 					}
5086 				}
5087 
5088 				if (v->PrefetchSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true) {
5089 					v->BandwidthAvailableForImmediateFlip = v->ReturnBWPerState[i][j];
5090 					for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5091 						v->BandwidthAvailableForImmediateFlip = v->BandwidthAvailableForImmediateFlip
5092 								- dml_max(
5093 										v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k],
5094 										v->NoOfDPP[i][j][k]
5095 												* (v->RequiredPrefetchPixelDataBWLuma[i][j][k] * v->UrgentBurstFactorLumaPre[k]
5096 														+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5097 																* v->UrgentBurstFactorChromaPre[k])
5098 												+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5099 					}
5100 					v->TotImmediateFlipBytes = 0.0;
5101 					for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5102 						v->TotImmediateFlipBytes = v->TotImmediateFlipBytes + v->NoOfDPP[i][j][k] * v->PDEAndMetaPTEBytesPerFrame[i][j][k]
5103 								+ v->MetaRowBytes[i][j][k] + v->DPTEBytesPerRow[i][j][k];
5104 					}
5105 
5106 					for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5107 						CalculateFlipSchedule(
5108 								mode_lib,
5109 								v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
5110 								v->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
5111 								v->ExtraLatency,
5112 								v->UrgLatency[i],
5113 								v->GPUVMMaxPageTableLevels,
5114 								v->HostVMEnable,
5115 								v->HostVMMaxNonCachedPageTableLevels,
5116 								v->GPUVMEnable,
5117 								v->HostVMMinPageSize,
5118 								v->PDEAndMetaPTEBytesPerFrame[i][j][k],
5119 								v->MetaRowBytes[i][j][k],
5120 								v->DPTEBytesPerRow[i][j][k],
5121 								v->BandwidthAvailableForImmediateFlip,
5122 								v->TotImmediateFlipBytes,
5123 								v->SourcePixelFormat[k],
5124 								v->HTotal[k] / v->PixelClock[k],
5125 								v->VRatio[k],
5126 								v->VRatioChroma[k],
5127 								v->Tno_bw[k],
5128 								v->DCCEnable[k],
5129 								v->dpte_row_height[k],
5130 								v->meta_row_height[k],
5131 								v->dpte_row_height_chroma[k],
5132 								v->meta_row_height_chroma[k],
5133 								&v->DestinationLinesToRequestVMInImmediateFlip[k],
5134 								&v->DestinationLinesToRequestRowInImmediateFlip[k],
5135 								&v->final_flip_bw[k],
5136 								&v->ImmediateFlipSupportedForPipe[k]);
5137 					}
5138 					v->total_dcn_read_bw_with_flip = 0.0;
5139 					for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5140 						v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip
5141 								+ dml_max3(
5142 										v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
5143 										v->NoOfDPP[i][j][k] * v->final_flip_bw[k] + v->VActivePixelBandwidth[i][j][k]
5144 												+ v->VActiveCursorBandwidth[i][j][k],
5145 										v->NoOfDPP[i][j][k]
5146 												* (v->final_flip_bw[k]
5147 														+ v->RequiredPrefetchPixelDataBWLuma[i][j][k]
5148 																* v->UrgentBurstFactorLumaPre[k]
5149 														+ v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5150 																* v->UrgentBurstFactorChromaPre[k])
5151 												+ v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5152 					}
5153 					v->ImmediateFlipSupportedForState[i][j] = true;
5154 					if (v->total_dcn_read_bw_with_flip > v->ReturnBWPerState[i][j]) {
5155 						v->ImmediateFlipSupportedForState[i][j] = false;
5156 					}
5157 					for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5158 						if (v->ImmediateFlipSupportedForPipe[k] == false) {
5159 							v->ImmediateFlipSupportedForState[i][j] = false;
5160 						}
5161 					}
5162 				} else {
5163 					v->ImmediateFlipSupportedForState[i][j] = false;
5164 				}
5165 				if (v->MaxVStartup <= 13 || v->AnyLinesForVMOrRowTooLarge == false) {
5166 					v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
5167 					NextPrefetchModeState = NextPrefetchModeState + 1;
5168 				} else {
5169 					v->NextMaxVStartup = v->NextMaxVStartup - 1;
5170 				}
5171 			} while (!((v->PrefetchSupported[i][j] == true && v->DynamicMetadataSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true
5172 					&& ((v->HostVMEnable == false && v->ImmediateFlipRequirement[0] != dm_immediate_flip_required)
5173 							|| v->ImmediateFlipSupportedForState[i][j] == true))
5174 					|| (v->NextMaxVStartup == v->MaxMaxVStartup[i][j] && NextPrefetchModeState > MaxPrefetchMode)));
5175 
5176 			CalculateWatermarksAndDRAMSpeedChangeSupport(
5177 					mode_lib,
5178 					v->PrefetchModePerState[i][j],
5179 					v->NumberOfActivePlanes,
5180 					v->MaxLineBufferLines,
5181 					v->LineBufferSize,
5182 					v->DPPOutputBufferPixels,
5183 					v->DETBufferSizeInKByte[0],
5184 					v->WritebackInterfaceBufferSize,
5185 					v->DCFCLKState[i][j],
5186 					v->ReturnBWPerState[i][j],
5187 					v->GPUVMEnable,
5188 					v->dpte_group_bytes,
5189 					v->MetaChunkSize,
5190 					v->UrgLatency[i],
5191 					v->ExtraLatency,
5192 					v->WritebackLatency,
5193 					v->WritebackChunkSize,
5194 					v->SOCCLKPerState[i],
5195 					v->FinalDRAMClockChangeLatency,
5196 					v->SRExitTime,
5197 					v->SREnterPlusExitTime,
5198 					v->ProjectedDCFCLKDeepSleep[i][j],
5199 					v->NoOfDPPThisState,
5200 					v->DCCEnable,
5201 					v->RequiredDPPCLKThisState,
5202 					v->DETBufferSizeYThisState,
5203 					v->DETBufferSizeCThisState,
5204 					v->SwathHeightYThisState,
5205 					v->SwathHeightCThisState,
5206 					v->LBBitPerPixel,
5207 					v->SwathWidthYThisState,
5208 					v->SwathWidthCThisState,
5209 					v->HRatio,
5210 					v->HRatioChroma,
5211 					v->vtaps,
5212 					v->VTAPsChroma,
5213 					v->VRatio,
5214 					v->VRatioChroma,
5215 					v->HTotal,
5216 					v->PixelClock,
5217 					v->BlendingAndTiming,
5218 					v->BytePerPixelInDETY,
5219 					v->BytePerPixelInDETC,
5220 					v->DSTXAfterScaler,
5221 					v->DSTYAfterScaler,
5222 					v->WritebackEnable,
5223 					v->WritebackPixelFormat,
5224 					v->WritebackDestinationWidth,
5225 					v->WritebackDestinationHeight,
5226 					v->WritebackSourceHeight,
5227 					&v->DRAMClockChangeSupport[i][j],
5228 					&v->UrgentWatermark,
5229 					&v->WritebackUrgentWatermark,
5230 					&v->DRAMClockChangeWatermark,
5231 					&v->WritebackDRAMClockChangeWatermark,
5232 					&v->StutterExitWatermark,
5233 					&v->StutterEnterPlusExitWatermark,
5234 					&v->MinActiveDRAMClockChangeLatencySupported);
5235 		}
5236 	}
5237 
5238 	/*PTE Buffer Size Check*/
5239 
5240 	for (i = 0; i < v->soc.num_states; i++) {
5241 		for (j = 0; j < 2; j++) {
5242 			v->PTEBufferSizeNotExceeded[i][j] = true;
5243 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5244 				if (v->PTEBufferSizeNotExceededY[i][j][k] == false || v->PTEBufferSizeNotExceededC[i][j][k] == false) {
5245 					v->PTEBufferSizeNotExceeded[i][j] = false;
5246 				}
5247 			}
5248 		}
5249 	}
5250 	/*Cursor Support Check*/
5251 
5252 	v->CursorSupport = true;
5253 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5254 		if (v->CursorWidth[k][0] > 0.0) {
5255 			if (v->CursorBPP[k][0] == 64 && v->Cursor64BppSupport == false) {
5256 				v->CursorSupport = false;
5257 			}
5258 		}
5259 	}
5260 	/*Valid Pitch Check*/
5261 
5262 	v->PitchSupport = true;
5263 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5264 		v->AlignedYPitch[k] = dml_ceil(dml_max(v->PitchY[k], v->SurfaceWidthY[k]), v->MacroTileWidthY[k]);
5265 		if (v->DCCEnable[k] == true) {
5266 			v->AlignedDCCMetaPitchY[k] = dml_ceil(dml_max(v->DCCMetaPitchY[k], v->SurfaceWidthY[k]), 64.0 * v->Read256BlockWidthY[k]);
5267 		} else {
5268 			v->AlignedDCCMetaPitchY[k] = v->DCCMetaPitchY[k];
5269 		}
5270 		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
5271 				&& v->SourcePixelFormat[k] != dm_rgbe && v->SourcePixelFormat[k] != dm_mono_8) {
5272 			v->AlignedCPitch[k] = dml_ceil(dml_max(v->PitchC[k], v->SurfaceWidthC[k]), v->MacroTileWidthC[k]);
5273 			if (v->DCCEnable[k] == true) {
5274 				v->AlignedDCCMetaPitchC[k] = dml_ceil(dml_max(v->DCCMetaPitchC[k], v->SurfaceWidthC[k]), 64.0 * v->Read256BlockWidthC[k]);
5275 			} else {
5276 				v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
5277 			}
5278 		} else {
5279 			v->AlignedCPitch[k] = v->PitchC[k];
5280 			v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
5281 		}
5282 		if (v->AlignedYPitch[k] > v->PitchY[k] || v->AlignedCPitch[k] > v->PitchC[k] || v->AlignedDCCMetaPitchY[k] > v->DCCMetaPitchY[k]
5283 				|| v->AlignedDCCMetaPitchC[k] > v->DCCMetaPitchC[k]) {
5284 			v->PitchSupport = false;
5285 		}
5286 	}
5287 
5288 	for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5289 		if (v->ViewportWidth[k] > v->SurfaceWidthY[k] || v->ViewportHeight[k] > v->SurfaceHeightY[k])
5290 			ViewportExceedsSurface = true;
5291 
5292 		if (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32 && v->SourcePixelFormat[k] != dm_444_16
5293 				&& v->SourcePixelFormat[k] != dm_444_8 && v->SourcePixelFormat[k] != dm_rgbe) {
5294 			if (v->ViewportWidthChroma[k] > v->SurfaceWidthC[k] || v->ViewportHeightChroma[k] > v->SurfaceHeightC[k]) {
5295 				ViewportExceedsSurface = true;
5296 			}
5297 		}
5298 	}
5299 	/*Mode Support, Voltage State and SOC Configuration*/
5300 
5301 	for (i = v->soc.num_states - 1; i >= 0; i--) {
5302 		for (j = 0; j < 2; j++) {
5303 			if (v->ScaleRatioAndTapsSupport == 1 && v->SourceFormatPixelAndScanSupport == 1 && v->ViewportSizeSupport[i][j] == 1
5304 					&& v->DIOSupport[i] == 1 && v->ODMCombine4To1SupportCheckOK[i] == 1
5305 					&& v->NotEnoughDSCUnits[i] == 0
5306 					&& v->DTBCLKRequiredMoreThanSupported[i] == 0
5307 					&& v->ROBSupport[i][j] == 1 && v->DISPCLK_DPPCLK_Support[i][j] == 1 && v->TotalAvailablePipesSupport[i][j] == 1
5308 					&& EnoughWritebackUnits == 1 && WritebackModeSupport == 1
5309 					&& v->WritebackLatencySupport == 1 && v->WritebackScaleRatioAndTapsSupport == 1 && v->CursorSupport == 1 && v->PitchSupport == 1
5310 					&& ViewportExceedsSurface == 0 && v->PrefetchSupported[i][j] == 1 && v->DynamicMetadataSupported[i][j] == 1
5311 					&& v->TotalVerticalActiveBandwidthSupport[i][j] == 1 && v->VRatioInPrefetchSupported[i][j] == 1
5312 					&& v->PTEBufferSizeNotExceeded[i][j] == 1 && v->NonsupportedDSCInputBPC == 0
5313 					&& ((v->HostVMEnable == 0 && v->ImmediateFlipRequirement[0] != dm_immediate_flip_required)
5314 							|| v->ImmediateFlipSupportedForState[i][j] == true)) {
5315 				v->ModeSupport[i][j] = true;
5316 			} else {
5317 				v->ModeSupport[i][j] = false;
5318 			}
5319 		}
5320 	}
5321 	{
5322 		unsigned int MaximumMPCCombine = 0;
5323 		for (i = v->soc.num_states; i >= 0; i--) {
5324 			if (i == v->soc.num_states || v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true) {
5325 				v->VoltageLevel = i;
5326 				v->ModeIsSupported = v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true;
5327 				if (v->ModeSupport[i][1] == true) {
5328 					MaximumMPCCombine = 1;
5329 				} else {
5330 					MaximumMPCCombine = 0;
5331 				}
5332 			}
5333 		}
5334 		v->ImmediateFlipSupport = v->ImmediateFlipSupportedForState[v->VoltageLevel][MaximumMPCCombine];
5335 		for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5336 			v->MPCCombineEnable[k] = v->MPCCombine[v->VoltageLevel][MaximumMPCCombine][k];
5337 			v->DPPPerPlane[k] = v->NoOfDPP[v->VoltageLevel][MaximumMPCCombine][k];
5338 		}
5339 		v->DCFCLK = v->DCFCLKState[v->VoltageLevel][MaximumMPCCombine];
5340 		v->DRAMSpeed = v->DRAMSpeedPerState[v->VoltageLevel];
5341 		v->FabricClock = v->FabricClockPerState[v->VoltageLevel];
5342 		v->SOCCLK = v->SOCCLKPerState[v->VoltageLevel];
5343 		v->ReturnBW = v->ReturnBWPerState[v->VoltageLevel][MaximumMPCCombine];
5344 		v->maxMpcComb = MaximumMPCCombine;
5345 	}
5346 }
5347 
CalculateWatermarksAndDRAMSpeedChangeSupport(struct display_mode_lib * mode_lib,unsigned int PrefetchMode,unsigned int NumberOfActivePlanes,unsigned int MaxLineBufferLines,unsigned int LineBufferSize,unsigned int DPPOutputBufferPixels,unsigned int 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[],unsigned int DETBufferSizeY[],unsigned int 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)5348 static void CalculateWatermarksAndDRAMSpeedChangeSupport(
5349 		struct display_mode_lib *mode_lib,
5350 		unsigned int PrefetchMode,
5351 		unsigned int NumberOfActivePlanes,
5352 		unsigned int MaxLineBufferLines,
5353 		unsigned int LineBufferSize,
5354 		unsigned int DPPOutputBufferPixels,
5355 		unsigned int DETBufferSizeInKByte,
5356 		unsigned int WritebackInterfaceBufferSize,
5357 		double DCFCLK,
5358 		double ReturnBW,
5359 		bool GPUVMEnable,
5360 		unsigned int dpte_group_bytes[],
5361 		unsigned int MetaChunkSize,
5362 		double UrgentLatency,
5363 		double ExtraLatency,
5364 		double WritebackLatency,
5365 		double WritebackChunkSize,
5366 		double SOCCLK,
5367 		double DRAMClockChangeLatency,
5368 		double SRExitTime,
5369 		double SREnterPlusExitTime,
5370 		double DCFCLKDeepSleep,
5371 		unsigned int DPPPerPlane[],
5372 		bool DCCEnable[],
5373 		double DPPCLK[],
5374 		unsigned int DETBufferSizeY[],
5375 		unsigned int DETBufferSizeC[],
5376 		unsigned int SwathHeightY[],
5377 		unsigned int SwathHeightC[],
5378 		unsigned int LBBitPerPixel[],
5379 		double SwathWidthY[],
5380 		double SwathWidthC[],
5381 		double HRatio[],
5382 		double HRatioChroma[],
5383 		unsigned int vtaps[],
5384 		unsigned int VTAPsChroma[],
5385 		double VRatio[],
5386 		double VRatioChroma[],
5387 		unsigned int HTotal[],
5388 		double PixelClock[],
5389 		unsigned int BlendingAndTiming[],
5390 		double BytePerPixelDETY[],
5391 		double BytePerPixelDETC[],
5392 		double DSTXAfterScaler[],
5393 		double DSTYAfterScaler[],
5394 		bool WritebackEnable[],
5395 		enum source_format_class WritebackPixelFormat[],
5396 		double WritebackDestinationWidth[],
5397 		double WritebackDestinationHeight[],
5398 		double WritebackSourceHeight[],
5399 		enum clock_change_support *DRAMClockChangeSupport,
5400 		double *UrgentWatermark,
5401 		double *WritebackUrgentWatermark,
5402 		double *DRAMClockChangeWatermark,
5403 		double *WritebackDRAMClockChangeWatermark,
5404 		double *StutterExitWatermark,
5405 		double *StutterEnterPlusExitWatermark,
5406 		double *MinActiveDRAMClockChangeLatencySupported)
5407 {
5408 	double EffectiveLBLatencyHidingY = 0;
5409 	double EffectiveLBLatencyHidingC = 0;
5410 	double LinesInDETY[DC__NUM_DPP__MAX] = { 0 };
5411 	double LinesInDETC = 0;
5412 	unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX] = { 0 };
5413 	unsigned int LinesInDETCRoundedDownToSwath = 0;
5414 	double FullDETBufferingTimeY[DC__NUM_DPP__MAX] = { 0 };
5415 	double FullDETBufferingTimeC = 0;
5416 	double ActiveDRAMClockChangeLatencyMarginY = 0;
5417 	double ActiveDRAMClockChangeLatencyMarginC = 0;
5418 	double WritebackDRAMClockChangeLatencyMargin = 0;
5419 	double PlaneWithMinActiveDRAMClockChangeMargin = 0;
5420 	double SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 0;
5421 	double FullDETBufferingTimeYStutterCriticalPlane = 0;
5422 	double TimeToFinishSwathTransferStutterCriticalPlane = 0;
5423 	double WritebackDRAMClockChangeLatencyHiding = 0;
5424 	unsigned int k, j;
5425 
5426 	mode_lib->vba.TotalActiveDPP = 0;
5427 	mode_lib->vba.TotalDCCActiveDPP = 0;
5428 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5429 		mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP + DPPPerPlane[k];
5430 		if (DCCEnable[k] == true) {
5431 			mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP + DPPPerPlane[k];
5432 		}
5433 	}
5434 
5435 	*UrgentWatermark = UrgentLatency + ExtraLatency;
5436 
5437 	*DRAMClockChangeWatermark = DRAMClockChangeLatency + *UrgentWatermark;
5438 
5439 	mode_lib->vba.TotalActiveWriteback = 0;
5440 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5441 		if (WritebackEnable[k] == true) {
5442 			mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1;
5443 		}
5444 	}
5445 
5446 	if (mode_lib->vba.TotalActiveWriteback <= 1) {
5447 		*WritebackUrgentWatermark = WritebackLatency;
5448 	} else {
5449 		*WritebackUrgentWatermark = WritebackLatency + WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
5450 	}
5451 
5452 	if (mode_lib->vba.TotalActiveWriteback <= 1) {
5453 		*WritebackDRAMClockChangeWatermark = DRAMClockChangeLatency + WritebackLatency;
5454 	} else {
5455 		*WritebackDRAMClockChangeWatermark = DRAMClockChangeLatency + WritebackLatency + WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
5456 	}
5457 
5458 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5459 
5460 		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);
5461 
5462 		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);
5463 
5464 		EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY / VRatio[k] * (HTotal[k] / PixelClock[k]);
5465 
5466 		EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC / VRatioChroma[k] * (HTotal[k] / PixelClock[k]);
5467 
5468 		LinesInDETY[k] = (double) DETBufferSizeY[k] / BytePerPixelDETY[k] / SwathWidthY[k];
5469 		LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]);
5470 		FullDETBufferingTimeY[k] = LinesInDETYRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k]) / VRatio[k];
5471 		if (BytePerPixelDETC[k] > 0) {
5472 			LinesInDETC = mode_lib->vba.DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k];
5473 			LinesInDETCRoundedDownToSwath = dml_floor(LinesInDETC, SwathHeightC[k]);
5474 			FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath * (HTotal[k] / PixelClock[k]) / VRatioChroma[k];
5475 		} else {
5476 			LinesInDETC = 0;
5477 			FullDETBufferingTimeC = 999999;
5478 		}
5479 
5480 		ActiveDRAMClockChangeLatencyMarginY = EffectiveLBLatencyHidingY + FullDETBufferingTimeY[k] - *UrgentWatermark - (HTotal[k] / PixelClock[k]) * (DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) - *DRAMClockChangeWatermark;
5481 
5482 		if (NumberOfActivePlanes > 1) {
5483 			ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY - (1 - 1.0 / NumberOfActivePlanes) * SwathHeightY[k] * HTotal[k] / PixelClock[k] / VRatio[k];
5484 		}
5485 
5486 		if (BytePerPixelDETC[k] > 0) {
5487 			ActiveDRAMClockChangeLatencyMarginC = EffectiveLBLatencyHidingC + FullDETBufferingTimeC - *UrgentWatermark - (HTotal[k] / PixelClock[k]) * (DSTXAfterScaler[k] / HTotal[k] + DSTYAfterScaler[k]) - *DRAMClockChangeWatermark;
5488 
5489 			if (NumberOfActivePlanes > 1) {
5490 				ActiveDRAMClockChangeLatencyMarginC = ActiveDRAMClockChangeLatencyMarginC - (1 - 1.0 / NumberOfActivePlanes) * SwathHeightC[k] * HTotal[k] / PixelClock[k] / VRatioChroma[k];
5491 			}
5492 			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, ActiveDRAMClockChangeLatencyMarginC);
5493 		} else {
5494 			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = ActiveDRAMClockChangeLatencyMarginY;
5495 		}
5496 
5497 		if (WritebackEnable[k] == true) {
5498 
5499 			WritebackDRAMClockChangeLatencyHiding = WritebackInterfaceBufferSize * 1024 / (WritebackDestinationWidth[k] * WritebackDestinationHeight[k] / (WritebackSourceHeight[k] * HTotal[k] / PixelClock[k]) * 4);
5500 			if (WritebackPixelFormat[k] == dm_444_64) {
5501 				WritebackDRAMClockChangeLatencyHiding = WritebackDRAMClockChangeLatencyHiding / 2;
5502 			}
5503 			if (mode_lib->vba.WritebackConfiguration == dm_whole_buffer_for_single_stream_interleave) {
5504 				WritebackDRAMClockChangeLatencyHiding = WritebackDRAMClockChangeLatencyHiding * 2;
5505 			}
5506 			WritebackDRAMClockChangeLatencyMargin = WritebackDRAMClockChangeLatencyHiding - mode_lib->vba.WritebackDRAMClockChangeWatermark;
5507 			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k], WritebackDRAMClockChangeLatencyMargin);
5508 		}
5509 	}
5510 
5511 	mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
5512 	PlaneWithMinActiveDRAMClockChangeMargin = 0;
5513 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5514 		if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] < mode_lib->vba.MinActiveDRAMClockChangeMargin) {
5515 			mode_lib->vba.MinActiveDRAMClockChangeMargin = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
5516 			if (BlendingAndTiming[k] == k) {
5517 				PlaneWithMinActiveDRAMClockChangeMargin = k;
5518 			} else {
5519 				for (j = 0; j < NumberOfActivePlanes; ++j) {
5520 					if (BlendingAndTiming[k] == j) {
5521 						PlaneWithMinActiveDRAMClockChangeMargin = j;
5522 					}
5523 				}
5524 			}
5525 		}
5526 	}
5527 
5528 	*MinActiveDRAMClockChangeLatencySupported = mode_lib->vba.MinActiveDRAMClockChangeMargin + DRAMClockChangeLatency;
5529 
5530 	SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999;
5531 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5532 		if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (BlendingAndTiming[k] == k)) && !(BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin) && mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] < SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) {
5533 			SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
5534 		}
5535 	}
5536 
5537 	mode_lib->vba.TotalNumberOfActiveOTG = 0;
5538 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5539 		if (BlendingAndTiming[k] == k) {
5540 			mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG + 1;
5541 		}
5542 	}
5543 
5544 	if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
5545 		*DRAMClockChangeSupport = dm_dram_clock_change_vactive;
5546 	} else if (((mode_lib->vba.SynchronizedVBlank == true || mode_lib->vba.TotalNumberOfActiveOTG == 1 || SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0) && PrefetchMode == 0)) {
5547 		*DRAMClockChangeSupport = dm_dram_clock_change_vblank;
5548 	} else {
5549 		*DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
5550 	}
5551 
5552 	FullDETBufferingTimeYStutterCriticalPlane = FullDETBufferingTimeY[0];
5553 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5554 		if (FullDETBufferingTimeY[k] <= FullDETBufferingTimeYStutterCriticalPlane) {
5555 			FullDETBufferingTimeYStutterCriticalPlane = FullDETBufferingTimeY[k];
5556 			TimeToFinishSwathTransferStutterCriticalPlane = (SwathHeightY[k] - (LinesInDETY[k] - LinesInDETYRoundedDownToSwath[k])) * (HTotal[k] / PixelClock[k]) / VRatio[k];
5557 		}
5558 	}
5559 
5560 	*StutterExitWatermark = SRExitTime +  ExtraLatency + 10 / DCFCLKDeepSleep;
5561 	*StutterEnterPlusExitWatermark = dml_max(SREnterPlusExitTime + ExtraLatency + 10 / DCFCLKDeepSleep, TimeToFinishSwathTransferStutterCriticalPlane);
5562 
5563 }
5564 
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)5565 static void CalculateDCFCLKDeepSleep(
5566 		struct display_mode_lib *mode_lib,
5567 		unsigned int NumberOfActivePlanes,
5568 		int BytePerPixelY[],
5569 		int BytePerPixelC[],
5570 		double VRatio[],
5571 		double VRatioChroma[],
5572 		double SwathWidthY[],
5573 		double SwathWidthC[],
5574 		unsigned int DPPPerPlane[],
5575 		double HRatio[],
5576 		double HRatioChroma[],
5577 		double PixelClock[],
5578 		double PSCL_THROUGHPUT[],
5579 		double PSCL_THROUGHPUT_CHROMA[],
5580 		double DPPCLK[],
5581 		double ReadBandwidthLuma[],
5582 		double ReadBandwidthChroma[],
5583 		int ReturnBusWidth,
5584 		double *DCFCLKDeepSleep)
5585 {
5586 	double DisplayPipeLineDeliveryTimeLuma = 0;
5587 	double DisplayPipeLineDeliveryTimeChroma = 0;
5588 	unsigned int k;
5589 	double ReadBandwidth = 0.0;
5590 
5591 	//double   DCFCLKDeepSleepPerPlane[DC__NUM_DPP__MAX];
5592 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5593 
5594 		if (VRatio[k] <= 1) {
5595 			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
5596 		} else {
5597 			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
5598 		}
5599 		if (BytePerPixelC[k] == 0) {
5600 			DisplayPipeLineDeliveryTimeChroma = 0;
5601 		} else {
5602 			if (VRatioChroma[k] <= 1) {
5603 				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
5604 			} else {
5605 				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
5606 			}
5607 		}
5608 
5609 		if (BytePerPixelC[k] > 0) {
5610 			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);
5611 		} else {
5612 			mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = 1.1 * SwathWidthY[k] * BytePerPixelY[k] / 64.0 / DisplayPipeLineDeliveryTimeLuma;
5613 		}
5614 		mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(mode_lib->vba.DCFCLKDeepSleepPerPlane[k], PixelClock[k] / 16);
5615 
5616 	}
5617 
5618 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5619 		ReadBandwidth = ReadBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
5620 	}
5621 
5622 	*DCFCLKDeepSleep = dml_max(8.0, ReadBandwidth / ReturnBusWidth);
5623 
5624 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5625 		*DCFCLKDeepSleep = dml_max(*DCFCLKDeepSleep, mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
5626 	}
5627 }
5628 
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)5629 static void CalculateUrgentBurstFactor(
5630 		long swath_width_luma_ub,
5631 		long swath_width_chroma_ub,
5632 		unsigned int DETBufferSizeInKByte,
5633 		unsigned int SwathHeightY,
5634 		unsigned int SwathHeightC,
5635 		double LineTime,
5636 		double UrgentLatency,
5637 		double CursorBufferSize,
5638 		unsigned int CursorWidth,
5639 		unsigned int CursorBPP,
5640 		double VRatio,
5641 		double VRatioC,
5642 		double BytePerPixelInDETY,
5643 		double BytePerPixelInDETC,
5644 		double DETBufferSizeY,
5645 		double DETBufferSizeC,
5646 		double *UrgentBurstFactorCursor,
5647 		double *UrgentBurstFactorLuma,
5648 		double *UrgentBurstFactorChroma,
5649 		bool *NotEnoughUrgentLatencyHiding)
5650 {
5651 	double LinesInDETLuma = 0;
5652 	double LinesInDETChroma = 0;
5653 	unsigned int LinesInCursorBuffer = 0;
5654 	double CursorBufferSizeInTime = 0;
5655 	double DETBufferSizeInTimeLuma = 0;
5656 	double DETBufferSizeInTimeChroma = 0;
5657 
5658 	*NotEnoughUrgentLatencyHiding = 0;
5659 
5660 	if (CursorWidth > 0) {
5661 		LinesInCursorBuffer = 1 << (unsigned int) dml_floor(dml_log2(CursorBufferSize * 1024.0 / (CursorWidth * CursorBPP / 8.0)), 1.0);
5662 		if (VRatio > 0) {
5663 			CursorBufferSizeInTime = LinesInCursorBuffer * LineTime / VRatio;
5664 			if (CursorBufferSizeInTime - UrgentLatency <= 0) {
5665 				*NotEnoughUrgentLatencyHiding = 1;
5666 				*UrgentBurstFactorCursor = 0;
5667 			} else {
5668 				*UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency);
5669 			}
5670 		} else {
5671 			*UrgentBurstFactorCursor = 1;
5672 		}
5673 	}
5674 
5675 	LinesInDETLuma = DETBufferSizeY / BytePerPixelInDETY / swath_width_luma_ub;
5676 	if (VRatio > 0) {
5677 		DETBufferSizeInTimeLuma = dml_floor(LinesInDETLuma, SwathHeightY) * LineTime / VRatio;
5678 		if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) {
5679 			*NotEnoughUrgentLatencyHiding = 1;
5680 			*UrgentBurstFactorLuma = 0;
5681 		} else {
5682 			*UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency);
5683 		}
5684 	} else {
5685 		*UrgentBurstFactorLuma = 1;
5686 	}
5687 
5688 	if (BytePerPixelInDETC > 0) {
5689 		LinesInDETChroma = DETBufferSizeC / BytePerPixelInDETC / swath_width_chroma_ub;
5690 		if (VRatio > 0) {
5691 			DETBufferSizeInTimeChroma = dml_floor(LinesInDETChroma, SwathHeightC) * LineTime / VRatio;
5692 			if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) {
5693 				*NotEnoughUrgentLatencyHiding = 1;
5694 				*UrgentBurstFactorChroma = 0;
5695 			} else {
5696 				*UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency);
5697 			}
5698 		} else {
5699 			*UrgentBurstFactorChroma = 1;
5700 		}
5701 	}
5702 }
5703 
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[])5704 static void CalculatePixelDeliveryTimes(
5705 		unsigned int NumberOfActivePlanes,
5706 		double VRatio[],
5707 		double VRatioChroma[],
5708 		double VRatioPrefetchY[],
5709 		double VRatioPrefetchC[],
5710 		unsigned int swath_width_luma_ub[],
5711 		unsigned int swath_width_chroma_ub[],
5712 		unsigned int DPPPerPlane[],
5713 		double HRatio[],
5714 		double HRatioChroma[],
5715 		double PixelClock[],
5716 		double PSCL_THROUGHPUT[],
5717 		double PSCL_THROUGHPUT_CHROMA[],
5718 		double DPPCLK[],
5719 		int BytePerPixelC[],
5720 		enum scan_direction_class SourceScan[],
5721 		unsigned int NumberOfCursors[],
5722 		unsigned int CursorWidth[][2],
5723 		unsigned int CursorBPP[][2],
5724 		unsigned int BlockWidth256BytesY[],
5725 		unsigned int BlockHeight256BytesY[],
5726 		unsigned int BlockWidth256BytesC[],
5727 		unsigned int BlockHeight256BytesC[],
5728 		double DisplayPipeLineDeliveryTimeLuma[],
5729 		double DisplayPipeLineDeliveryTimeChroma[],
5730 		double DisplayPipeLineDeliveryTimeLumaPrefetch[],
5731 		double DisplayPipeLineDeliveryTimeChromaPrefetch[],
5732 		double DisplayPipeRequestDeliveryTimeLuma[],
5733 		double DisplayPipeRequestDeliveryTimeChroma[],
5734 		double DisplayPipeRequestDeliveryTimeLumaPrefetch[],
5735 		double DisplayPipeRequestDeliveryTimeChromaPrefetch[],
5736 		double CursorRequestDeliveryTime[],
5737 		double CursorRequestDeliveryTimePrefetch[])
5738 {
5739 	double req_per_swath_ub = 0;
5740 	unsigned int k;
5741 
5742 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5743 		if (VRatio[k] <= 1) {
5744 			DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
5745 		} else {
5746 			DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
5747 		}
5748 
5749 		if (BytePerPixelC[k] == 0) {
5750 			DisplayPipeLineDeliveryTimeChroma[k] = 0;
5751 		} else {
5752 			if (VRatioChroma[k] <= 1) {
5753 				DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
5754 			} else {
5755 				DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
5756 			}
5757 		}
5758 
5759 		if (VRatioPrefetchY[k] <= 1) {
5760 			DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
5761 		} else {
5762 			DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
5763 		}
5764 
5765 		if (BytePerPixelC[k] == 0) {
5766 			DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
5767 		} else {
5768 			if (VRatioPrefetchC[k] <= 1) {
5769 				DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
5770 			} else {
5771 				DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
5772 			}
5773 		}
5774 	}
5775 
5776 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5777 		if (SourceScan[k] != dm_vert) {
5778 			req_per_swath_ub = swath_width_luma_ub[k] / BlockWidth256BytesY[k];
5779 		} else {
5780 			req_per_swath_ub = swath_width_luma_ub[k] / BlockHeight256BytesY[k];
5781 		}
5782 		DisplayPipeRequestDeliveryTimeLuma[k] = DisplayPipeLineDeliveryTimeLuma[k] / req_per_swath_ub;
5783 		DisplayPipeRequestDeliveryTimeLumaPrefetch[k] = DisplayPipeLineDeliveryTimeLumaPrefetch[k] / req_per_swath_ub;
5784 		if (BytePerPixelC[k] == 0) {
5785 			DisplayPipeRequestDeliveryTimeChroma[k] = 0;
5786 			DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = 0;
5787 		} else {
5788 			if (SourceScan[k] != dm_vert) {
5789 				req_per_swath_ub = swath_width_chroma_ub[k] / BlockWidth256BytesC[k];
5790 			} else {
5791 				req_per_swath_ub = swath_width_chroma_ub[k] / BlockHeight256BytesC[k];
5792 			}
5793 			DisplayPipeRequestDeliveryTimeChroma[k] = DisplayPipeLineDeliveryTimeChroma[k] / req_per_swath_ub;
5794 			DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = DisplayPipeLineDeliveryTimeChromaPrefetch[k] / req_per_swath_ub;
5795 		}
5796 	}
5797 
5798 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5799 		int cursor_req_per_width = 0;
5800 		cursor_req_per_width = dml_ceil(CursorWidth[k][0] * CursorBPP[k][0] / 256 / 8, 1);
5801 		if (NumberOfCursors[k] > 0) {
5802 			if (VRatio[k] <= 1) {
5803 				CursorRequestDeliveryTime[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
5804 			} else {
5805 				CursorRequestDeliveryTime[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
5806 			}
5807 			if (VRatioPrefetchY[k] <= 1) {
5808 				CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
5809 			} else {
5810 				CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
5811 			}
5812 		} else {
5813 			CursorRequestDeliveryTime[k] = 0;
5814 			CursorRequestDeliveryTimePrefetch[k] = 0;
5815 		}
5816 	}
5817 }
5818 
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[])5819 static void CalculateMetaAndPTETimes(
5820 		int NumberOfActivePlanes,
5821 		bool GPUVMEnable,
5822 		int MetaChunkSize,
5823 		int MinMetaChunkSizeBytes,
5824 		int HTotal[],
5825 		double VRatio[],
5826 		double VRatioChroma[],
5827 		double DestinationLinesToRequestRowInVBlank[],
5828 		double DestinationLinesToRequestRowInImmediateFlip[],
5829 		bool DCCEnable[],
5830 		double PixelClock[],
5831 		int BytePerPixelY[],
5832 		int BytePerPixelC[],
5833 		enum scan_direction_class SourceScan[],
5834 		int dpte_row_height[],
5835 		int dpte_row_height_chroma[],
5836 		int meta_row_width[],
5837 		int meta_row_width_chroma[],
5838 		int meta_row_height[],
5839 		int meta_row_height_chroma[],
5840 		int meta_req_width[],
5841 		int meta_req_width_chroma[],
5842 		int meta_req_height[],
5843 		int meta_req_height_chroma[],
5844 		int dpte_group_bytes[],
5845 		int PTERequestSizeY[],
5846 		int PTERequestSizeC[],
5847 		int PixelPTEReqWidthY[],
5848 		int PixelPTEReqHeightY[],
5849 		int PixelPTEReqWidthC[],
5850 		int PixelPTEReqHeightC[],
5851 		int dpte_row_width_luma_ub[],
5852 		int dpte_row_width_chroma_ub[],
5853 		double DST_Y_PER_PTE_ROW_NOM_L[],
5854 		double DST_Y_PER_PTE_ROW_NOM_C[],
5855 		double DST_Y_PER_META_ROW_NOM_L[],
5856 		double DST_Y_PER_META_ROW_NOM_C[],
5857 		double TimePerMetaChunkNominal[],
5858 		double TimePerChromaMetaChunkNominal[],
5859 		double TimePerMetaChunkVBlank[],
5860 		double TimePerChromaMetaChunkVBlank[],
5861 		double TimePerMetaChunkFlip[],
5862 		double TimePerChromaMetaChunkFlip[],
5863 		double time_per_pte_group_nom_luma[],
5864 		double time_per_pte_group_vblank_luma[],
5865 		double time_per_pte_group_flip_luma[],
5866 		double time_per_pte_group_nom_chroma[],
5867 		double time_per_pte_group_vblank_chroma[],
5868 		double time_per_pte_group_flip_chroma[])
5869 {
5870 	unsigned int meta_chunk_width = 0;
5871 	unsigned int min_meta_chunk_width = 0;
5872 	unsigned int meta_chunk_per_row_int = 0;
5873 	unsigned int meta_row_remainder = 0;
5874 	unsigned int meta_chunk_threshold = 0;
5875 	unsigned int meta_chunks_per_row_ub = 0;
5876 	unsigned int meta_chunk_width_chroma = 0;
5877 	unsigned int min_meta_chunk_width_chroma = 0;
5878 	unsigned int meta_chunk_per_row_int_chroma = 0;
5879 	unsigned int meta_row_remainder_chroma = 0;
5880 	unsigned int meta_chunk_threshold_chroma = 0;
5881 	unsigned int meta_chunks_per_row_ub_chroma = 0;
5882 	unsigned int dpte_group_width_luma = 0;
5883 	unsigned int dpte_groups_per_row_luma_ub = 0;
5884 	unsigned int dpte_group_width_chroma = 0;
5885 	unsigned int dpte_groups_per_row_chroma_ub = 0;
5886 	unsigned int k;
5887 
5888 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5889 		DST_Y_PER_PTE_ROW_NOM_L[k] = dpte_row_height[k] / VRatio[k];
5890 		if (BytePerPixelC[k] == 0) {
5891 			DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
5892 		} else {
5893 			DST_Y_PER_PTE_ROW_NOM_C[k] = dpte_row_height_chroma[k] / VRatioChroma[k];
5894 		}
5895 		DST_Y_PER_META_ROW_NOM_L[k] = meta_row_height[k] / VRatio[k];
5896 		if (BytePerPixelC[k] == 0) {
5897 			DST_Y_PER_META_ROW_NOM_C[k] = 0;
5898 		} else {
5899 			DST_Y_PER_META_ROW_NOM_C[k] = meta_row_height_chroma[k] / VRatioChroma[k];
5900 		}
5901 	}
5902 
5903 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5904 		if (DCCEnable[k] == true) {
5905 			meta_chunk_width = MetaChunkSize * 1024 * 256 / BytePerPixelY[k] / meta_row_height[k];
5906 			min_meta_chunk_width = MinMetaChunkSizeBytes * 256 / BytePerPixelY[k] / meta_row_height[k];
5907 			meta_chunk_per_row_int = meta_row_width[k] / meta_chunk_width;
5908 			meta_row_remainder = meta_row_width[k] % meta_chunk_width;
5909 			if (SourceScan[k] != dm_vert) {
5910 				meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width[k];
5911 			} else {
5912 				meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height[k];
5913 			}
5914 			if (meta_row_remainder <= meta_chunk_threshold) {
5915 				meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
5916 			} else {
5917 				meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
5918 			}
5919 			TimePerMetaChunkNominal[k] = meta_row_height[k] / VRatio[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
5920 			TimePerMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
5921 			TimePerMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
5922 			if (BytePerPixelC[k] == 0) {
5923 				TimePerChromaMetaChunkNominal[k] = 0;
5924 				TimePerChromaMetaChunkVBlank[k] = 0;
5925 				TimePerChromaMetaChunkFlip[k] = 0;
5926 			} else {
5927 				meta_chunk_width_chroma = MetaChunkSize * 1024 * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
5928 				min_meta_chunk_width_chroma = MinMetaChunkSizeBytes * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
5929 				meta_chunk_per_row_int_chroma = (double) meta_row_width_chroma[k] / meta_chunk_width_chroma;
5930 				meta_row_remainder_chroma = meta_row_width_chroma[k] % meta_chunk_width_chroma;
5931 				if (SourceScan[k] != dm_vert) {
5932 					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_width_chroma[k];
5933 				} else {
5934 					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_height_chroma[k];
5935 				}
5936 				if (meta_row_remainder_chroma <= meta_chunk_threshold_chroma) {
5937 					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 1;
5938 				} else {
5939 					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 2;
5940 				}
5941 				TimePerChromaMetaChunkNominal[k] = meta_row_height_chroma[k] / VRatioChroma[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
5942 				TimePerChromaMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
5943 				TimePerChromaMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
5944 			}
5945 		} else {
5946 			TimePerMetaChunkNominal[k] = 0;
5947 			TimePerMetaChunkVBlank[k] = 0;
5948 			TimePerMetaChunkFlip[k] = 0;
5949 			TimePerChromaMetaChunkNominal[k] = 0;
5950 			TimePerChromaMetaChunkVBlank[k] = 0;
5951 			TimePerChromaMetaChunkFlip[k] = 0;
5952 		}
5953 	}
5954 
5955 	for (k = 0; k < NumberOfActivePlanes; ++k) {
5956 		if (GPUVMEnable == true) {
5957 			if (SourceScan[k] != dm_vert) {
5958 				dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k] * PixelPTEReqWidthY[k];
5959 			} else {
5960 				dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k] * PixelPTEReqHeightY[k];
5961 			}
5962 			dpte_groups_per_row_luma_ub = dml_ceil(1.0 * dpte_row_width_luma_ub[k] / dpte_group_width_luma, 1);
5963 			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;
5964 			time_per_pte_group_vblank_luma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
5965 			time_per_pte_group_flip_luma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
5966 			if (BytePerPixelC[k] == 0) {
5967 				time_per_pte_group_nom_chroma[k] = 0;
5968 				time_per_pte_group_vblank_chroma[k] = 0;
5969 				time_per_pte_group_flip_chroma[k] = 0;
5970 			} else {
5971 				if (SourceScan[k] != dm_vert) {
5972 					dpte_group_width_chroma = dpte_group_bytes[k] / PTERequestSizeC[k] * PixelPTEReqWidthC[k];
5973 				} else {
5974 					dpte_group_width_chroma = dpte_group_bytes[k] / PTERequestSizeC[k] * PixelPTEReqHeightC[k];
5975 				}
5976 				dpte_groups_per_row_chroma_ub = dml_ceil(1.0 * dpte_row_width_chroma_ub[k] / dpte_group_width_chroma, 1);
5977 				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;
5978 				time_per_pte_group_vblank_chroma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
5979 				time_per_pte_group_flip_chroma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
5980 			}
5981 		} else {
5982 			time_per_pte_group_nom_luma[k] = 0;
5983 			time_per_pte_group_vblank_luma[k] = 0;
5984 			time_per_pte_group_flip_luma[k] = 0;
5985 			time_per_pte_group_nom_chroma[k] = 0;
5986 			time_per_pte_group_vblank_chroma[k] = 0;
5987 			time_per_pte_group_flip_chroma[k] = 0;
5988 		}
5989 	}
5990 }
5991 
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[])5992 static void CalculateVMGroupAndRequestTimes(
5993 		unsigned int NumberOfActivePlanes,
5994 		bool GPUVMEnable,
5995 		unsigned int GPUVMMaxPageTableLevels,
5996 		unsigned int HTotal[],
5997 		int BytePerPixelC[],
5998 		double DestinationLinesToRequestVMInVBlank[],
5999 		double DestinationLinesToRequestVMInImmediateFlip[],
6000 		bool DCCEnable[],
6001 		double PixelClock[],
6002 		int dpte_row_width_luma_ub[],
6003 		int dpte_row_width_chroma_ub[],
6004 		int vm_group_bytes[],
6005 		unsigned int dpde0_bytes_per_frame_ub_l[],
6006 		unsigned int dpde0_bytes_per_frame_ub_c[],
6007 		int meta_pte_bytes_per_frame_ub_l[],
6008 		int meta_pte_bytes_per_frame_ub_c[],
6009 		double TimePerVMGroupVBlank[],
6010 		double TimePerVMGroupFlip[],
6011 		double TimePerVMRequestVBlank[],
6012 		double TimePerVMRequestFlip[])
6013 {
6014 	int num_group_per_lower_vm_stage = 0;
6015 	int num_req_per_lower_vm_stage = 0;
6016 	unsigned int k;
6017 
6018 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6019 		if (GPUVMEnable == true && (DCCEnable[k] == true || GPUVMMaxPageTableLevels > 1)) {
6020 			if (DCCEnable[k] == false) {
6021 				if (BytePerPixelC[k] > 0) {
6022 					num_group_per_lower_vm_stage = dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k])
6023 						/ (double) (vm_group_bytes[k]), 1) + dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k])
6024 									/ (double) (vm_group_bytes[k]), 1);
6025 				} else {
6026 					num_group_per_lower_vm_stage = dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k])
6027 							/ (double) (vm_group_bytes[k]), 1);
6028 				}
6029 			} else {
6030 				if (GPUVMMaxPageTableLevels == 1) {
6031 					if (BytePerPixelC[k] > 0) {
6032 						num_group_per_lower_vm_stage = dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k])
6033 							/ (double) (vm_group_bytes[k]), 1) + dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k])
6034 									/ (double) (vm_group_bytes[k]), 1);
6035 					} else {
6036 						num_group_per_lower_vm_stage = dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k])
6037 							/ (double) (vm_group_bytes[k]), 1);
6038 					}
6039 				} else {
6040 					if (BytePerPixelC[k] > 0) {
6041 						num_group_per_lower_vm_stage = 2 + dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6042 								+ dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1)
6043 								+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6044 								+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
6045 					} else {
6046 						num_group_per_lower_vm_stage = 1 + dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6047 								+ dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
6048 					}
6049 				}
6050 			}
6051 
6052 			if (DCCEnable[k] == false) {
6053 				if (BytePerPixelC[k] > 0) {
6054 					num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + dpde0_bytes_per_frame_ub_c[k] / 64;
6055 				} else {
6056 					num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64;
6057 				}
6058 			} else {
6059 				if (GPUVMMaxPageTableLevels == 1) {
6060 					if (BytePerPixelC[k] > 0) {
6061 						num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64
6062 								+ meta_pte_bytes_per_frame_ub_c[k] / 64;
6063 					} else {
6064 						num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64;
6065 					}
6066 				} else {
6067 					if (BytePerPixelC[k] > 0) {
6068 						num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64
6069 							+ dpde0_bytes_per_frame_ub_c[k] / 64 + meta_pte_bytes_per_frame_ub_l[k]
6070 									/ 64 + meta_pte_bytes_per_frame_ub_c[k] / 64;
6071 					} else {
6072 						num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64
6073 								+ meta_pte_bytes_per_frame_ub_l[k] / 64;
6074 					}
6075 				}
6076 			}
6077 
6078 			TimePerVMGroupVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k]
6079 					/ num_group_per_lower_vm_stage;
6080 			TimePerVMGroupFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k]
6081 					/ num_group_per_lower_vm_stage;
6082 			TimePerVMRequestVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k]
6083 					/ num_req_per_lower_vm_stage;
6084 			TimePerVMRequestFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k]
6085 					/ num_req_per_lower_vm_stage;
6086 
6087 			if (GPUVMMaxPageTableLevels > 2) {
6088 				TimePerVMGroupVBlank[k] = TimePerVMGroupVBlank[k] / 2;
6089 				TimePerVMGroupFlip[k] = TimePerVMGroupFlip[k] / 2;
6090 				TimePerVMRequestVBlank[k] = TimePerVMRequestVBlank[k] / 2;
6091 				TimePerVMRequestFlip[k] = TimePerVMRequestFlip[k] / 2;
6092 			}
6093 
6094 		} else {
6095 			TimePerVMGroupVBlank[k] = 0;
6096 			TimePerVMGroupFlip[k] = 0;
6097 			TimePerVMRequestVBlank[k] = 0;
6098 			TimePerVMRequestFlip[k] = 0;
6099 		}
6100 	}
6101 }
6102 
CalculateStutterEfficiency(int NumberOfActivePlanes,long ROBBufferSizeInKByte,double TotalDataReadBandwidth,double DCFCLK,double ReturnBW,double SRExitTime,bool SynchronizedVBlank,int DPPPerPlane[],unsigned int 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)6103 static void CalculateStutterEfficiency(
6104 		int NumberOfActivePlanes,
6105 		long ROBBufferSizeInKByte,
6106 		double TotalDataReadBandwidth,
6107 		double DCFCLK,
6108 		double ReturnBW,
6109 		double SRExitTime,
6110 		bool SynchronizedVBlank,
6111 		int DPPPerPlane[],
6112 		unsigned int DETBufferSizeY[],
6113 		int BytePerPixelY[],
6114 		double BytePerPixelDETY[],
6115 		double SwathWidthY[],
6116 		int SwathHeightY[],
6117 		int SwathHeightC[],
6118 		double DCCRateLuma[],
6119 		double DCCRateChroma[],
6120 		int HTotal[],
6121 		int VTotal[],
6122 		double PixelClock[],
6123 		double VRatio[],
6124 		enum scan_direction_class SourceScan[],
6125 		int BlockHeight256BytesY[],
6126 		int BlockWidth256BytesY[],
6127 		int BlockHeight256BytesC[],
6128 		int BlockWidth256BytesC[],
6129 		int DCCYMaxUncompressedBlock[],
6130 		int DCCCMaxUncompressedBlock[],
6131 		int VActive[],
6132 		bool DCCEnable[],
6133 		bool WritebackEnable[],
6134 		double ReadBandwidthPlaneLuma[],
6135 		double ReadBandwidthPlaneChroma[],
6136 		double meta_row_bw[],
6137 		double dpte_row_bw[],
6138 		double *StutterEfficiencyNotIncludingVBlank,
6139 		double *StutterEfficiency,
6140 		double *StutterPeriodOut)
6141 {
6142 	double FullDETBufferingTimeY[DC__NUM_DPP__MAX] = { 0 };
6143 	double FrameTimeForMinFullDETBufferingTime = 0;
6144 	double StutterPeriod = 0;
6145 	double AverageReadBandwidth = 0;
6146 	double TotalRowReadBandwidth = 0;
6147 	double AverageDCCCompressionRate = 0;
6148 	double PartOfBurstThatFitsInROB = 0;
6149 	double StutterBurstTime = 0;
6150 	int TotalActiveWriteback = 0;
6151 	double VBlankTime = 0;
6152 	double SmallestVBlank = 0;
6153 	int BytePerPixelYCriticalPlane = 0;
6154 	double SwathWidthYCriticalPlane = 0;
6155 	double LinesInDETY[DC__NUM_DPP__MAX] = { 0 };
6156 	double LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX] = { 0 };
6157 	double LinesToFinishSwathTransferStutterCriticalPlane = 0;
6158 	double MaximumEffectiveCompressionLuma = 0;
6159 	double    MaximumEffectiveCompressionChroma = 0;
6160 	unsigned int k;
6161 
6162 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6163 		LinesInDETY[k] = DETBufferSizeY[k] / BytePerPixelDETY[k] / SwathWidthY[k];
6164 		LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]);
6165 		FullDETBufferingTimeY[k] = LinesInDETYRoundedDownToSwath[k] * (HTotal[k] / PixelClock[k]) / VRatio[k];
6166 	}
6167 
6168 	StutterPeriod = FullDETBufferingTimeY[0];
6169 	FrameTimeForMinFullDETBufferingTime = VTotal[0] * HTotal[0] / PixelClock[0];
6170 	BytePerPixelYCriticalPlane = BytePerPixelY[0];
6171 	SwathWidthYCriticalPlane = SwathWidthY[0];
6172 	LinesToFinishSwathTransferStutterCriticalPlane = SwathHeightY[0]
6173 			- (LinesInDETY[0] - LinesInDETYRoundedDownToSwath[0]);
6174 
6175 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6176 		if (FullDETBufferingTimeY[k] < StutterPeriod) {
6177 			StutterPeriod = FullDETBufferingTimeY[k];
6178 			FrameTimeForMinFullDETBufferingTime = VTotal[k] * HTotal[k] / PixelClock[k];
6179 			BytePerPixelYCriticalPlane = BytePerPixelY[k];
6180 			SwathWidthYCriticalPlane = SwathWidthY[k];
6181 			LinesToFinishSwathTransferStutterCriticalPlane = SwathHeightY[k]
6182 					- (LinesInDETY[k] - LinesInDETYRoundedDownToSwath[k]);
6183 		}
6184 	}
6185 
6186 	AverageReadBandwidth = 0;
6187 	TotalRowReadBandwidth = 0;
6188 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6189 		if (DCCEnable[k] == true) {
6190 			if ((SourceScan[k] == dm_vert && BlockWidth256BytesY[k] > SwathHeightY[k])
6191 					|| (SourceScan[k] != dm_vert
6192 							&& BlockHeight256BytesY[k] > SwathHeightY[k])
6193 					|| DCCYMaxUncompressedBlock[k] < 256) {
6194 				MaximumEffectiveCompressionLuma = 2;
6195 			} else {
6196 				MaximumEffectiveCompressionLuma = 4;
6197 			}
6198 			AverageReadBandwidth = AverageReadBandwidth + ReadBandwidthPlaneLuma[k] / dml_min(DCCRateLuma[k], MaximumEffectiveCompressionLuma);
6199 
6200 			if (ReadBandwidthPlaneChroma[k] > 0) {
6201 				if ((SourceScan[k] == dm_vert && BlockWidth256BytesC[k] > SwathHeightC[k])
6202 						|| (SourceScan[k] != dm_vert && BlockHeight256BytesC[k] > SwathHeightC[k])
6203 						|| DCCCMaxUncompressedBlock[k] < 256) {
6204 					MaximumEffectiveCompressionChroma = 2;
6205 				} else {
6206 					MaximumEffectiveCompressionChroma = 4;
6207 				}
6208 				AverageReadBandwidth = AverageReadBandwidth + ReadBandwidthPlaneChroma[k] / dml_min(DCCRateChroma[k], MaximumEffectiveCompressionChroma);
6209 			}
6210 		} else {
6211 			AverageReadBandwidth = AverageReadBandwidth + ReadBandwidthPlaneLuma[k] + ReadBandwidthPlaneChroma[k];
6212 		}
6213 		TotalRowReadBandwidth = TotalRowReadBandwidth + DPPPerPlane[k] * (meta_row_bw[k] + dpte_row_bw[k]);
6214 	}
6215 
6216 	AverageDCCCompressionRate = TotalDataReadBandwidth / AverageReadBandwidth;
6217 	PartOfBurstThatFitsInROB = dml_min(StutterPeriod * TotalDataReadBandwidth, ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate);
6218 	StutterBurstTime = PartOfBurstThatFitsInROB / AverageDCCCompressionRate / ReturnBW + (StutterPeriod * TotalDataReadBandwidth
6219 			- PartOfBurstThatFitsInROB) / (DCFCLK * 64) + StutterPeriod * TotalRowReadBandwidth / ReturnBW;
6220 	StutterBurstTime = dml_max(StutterBurstTime, LinesToFinishSwathTransferStutterCriticalPlane * BytePerPixelYCriticalPlane * SwathWidthYCriticalPlane / ReturnBW);
6221 
6222 	TotalActiveWriteback = 0;
6223 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6224 		if (WritebackEnable[k] == true) {
6225 			TotalActiveWriteback = TotalActiveWriteback + 1;
6226 		}
6227 	}
6228 
6229 	if (TotalActiveWriteback == 0) {
6230 		*StutterEfficiencyNotIncludingVBlank = (1
6231 				- (SRExitTime + StutterBurstTime) / StutterPeriod) * 100;
6232 	} else {
6233 		*StutterEfficiencyNotIncludingVBlank = 0;
6234 	}
6235 
6236 	if (SynchronizedVBlank == true || NumberOfActivePlanes == 1) {
6237 		SmallestVBlank = (VTotal[0] - VActive[0]) * HTotal[0] / PixelClock[0];
6238 	} else {
6239 		SmallestVBlank = 0;
6240 	}
6241 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6242 		if (SynchronizedVBlank == true || NumberOfActivePlanes == 1) {
6243 			VBlankTime = (VTotal[k] - VActive[k]) * HTotal[k] / PixelClock[k];
6244 		} else {
6245 			VBlankTime = 0;
6246 		}
6247 		SmallestVBlank = dml_min(SmallestVBlank, VBlankTime);
6248 	}
6249 
6250 	*StutterEfficiency =  (*StutterEfficiencyNotIncludingVBlank / 100.0 * (FrameTimeForMinFullDETBufferingTime - SmallestVBlank) + SmallestVBlank) / FrameTimeForMinFullDETBufferingTime * 100;
6251 
6252 	if (StutterPeriodOut)
6253 		*StutterPeriodOut = StutterPeriod;
6254 }
6255 
CalculateSwathAndDETConfiguration(bool ForceSingleDPP,int NumberOfActivePlanes,unsigned int 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[],unsigned int DETBufferSizeY[],unsigned int DETBufferSizeC[],bool ViewportSizeSupportPerPlane[],bool * ViewportSizeSupport)6256 static void CalculateSwathAndDETConfiguration(
6257 		bool ForceSingleDPP,
6258 		int NumberOfActivePlanes,
6259 		unsigned int DETBufferSizeInKByte,
6260 		double MaximumSwathWidthLuma[],
6261 		double MaximumSwathWidthChroma[],
6262 		enum scan_direction_class SourceScan[],
6263 		enum source_format_class SourcePixelFormat[],
6264 		enum dm_swizzle_mode SurfaceTiling[],
6265 		int ViewportWidth[],
6266 		int ViewportHeight[],
6267 		int SurfaceWidthY[],
6268 		int SurfaceWidthC[],
6269 		int SurfaceHeightY[],
6270 		int SurfaceHeightC[],
6271 		int Read256BytesBlockHeightY[],
6272 		int Read256BytesBlockHeightC[],
6273 		int Read256BytesBlockWidthY[],
6274 		int Read256BytesBlockWidthC[],
6275 		enum odm_combine_mode ODMCombineEnabled[],
6276 		int BlendingAndTiming[],
6277 		int BytePerPixY[],
6278 		int BytePerPixC[],
6279 		double BytePerPixDETY[],
6280 		double BytePerPixDETC[],
6281 		int HActive[],
6282 		double HRatio[],
6283 		double HRatioChroma[],
6284 		int DPPPerPlane[],
6285 		int swath_width_luma_ub[],
6286 		int swath_width_chroma_ub[],
6287 		double SwathWidth[],
6288 		double SwathWidthChroma[],
6289 		int SwathHeightY[],
6290 		int SwathHeightC[],
6291 		unsigned int DETBufferSizeY[],
6292 		unsigned int DETBufferSizeC[],
6293 		bool ViewportSizeSupportPerPlane[],
6294 		bool *ViewportSizeSupport)
6295 {
6296 	int MaximumSwathHeightY[DC__NUM_DPP__MAX] = { 0 };
6297 	int MaximumSwathHeightC[DC__NUM_DPP__MAX] = { 0 };
6298 	int MinimumSwathHeightY = 0;
6299 	int MinimumSwathHeightC = 0;
6300 	long RoundedUpMaxSwathSizeBytesY = 0;
6301 	long RoundedUpMaxSwathSizeBytesC = 0;
6302 	long RoundedUpMinSwathSizeBytesY = 0;
6303 	long RoundedUpMinSwathSizeBytesC = 0;
6304 	long RoundedUpSwathSizeBytesY = 0;
6305 	long RoundedUpSwathSizeBytesC = 0;
6306 	double SwathWidthSingleDPP[DC__NUM_DPP__MAX] = { 0 };
6307 	double SwathWidthSingleDPPChroma[DC__NUM_DPP__MAX] = { 0 };
6308 	int k;
6309 
6310 	CalculateSwathWidth(
6311 			ForceSingleDPP,
6312 			NumberOfActivePlanes,
6313 			SourcePixelFormat,
6314 			SourceScan,
6315 			ViewportWidth,
6316 			ViewportHeight,
6317 			SurfaceWidthY,
6318 			SurfaceWidthC,
6319 			SurfaceHeightY,
6320 			SurfaceHeightC,
6321 			ODMCombineEnabled,
6322 			BytePerPixY,
6323 			BytePerPixC,
6324 			Read256BytesBlockHeightY,
6325 			Read256BytesBlockHeightC,
6326 			Read256BytesBlockWidthY,
6327 			Read256BytesBlockWidthC,
6328 			BlendingAndTiming,
6329 			HActive,
6330 			HRatio,
6331 			DPPPerPlane,
6332 			SwathWidthSingleDPP,
6333 			SwathWidthSingleDPPChroma,
6334 			SwathWidth,
6335 			SwathWidthChroma,
6336 			MaximumSwathHeightY,
6337 			MaximumSwathHeightC,
6338 			swath_width_luma_ub,
6339 			swath_width_chroma_ub);
6340 
6341 	*ViewportSizeSupport = true;
6342 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6343 		if ((SourcePixelFormat[k] == dm_444_64 || SourcePixelFormat[k] == dm_444_32
6344 				|| SourcePixelFormat[k] == dm_444_16
6345 				|| SourcePixelFormat[k] == dm_mono_16
6346 				|| SourcePixelFormat[k] == dm_mono_8
6347 				|| SourcePixelFormat[k] == dm_rgbe)) {
6348 			if (SurfaceTiling[k] == dm_sw_linear
6349 				|| (SourcePixelFormat[k] == dm_444_64
6350 					&& (SurfaceTiling[k] == dm_sw_64kb_s || SurfaceTiling[k] == dm_sw_64kb_s_t || SurfaceTiling[k] == dm_sw_64kb_s_x)
6351 					&& SourceScan[k] != dm_vert)) {
6352 				MinimumSwathHeightY = MaximumSwathHeightY[k];
6353 			} else if (SourcePixelFormat[k] == dm_444_8 && SourceScan[k] == dm_vert) {
6354 				MinimumSwathHeightY = MaximumSwathHeightY[k];
6355 			} else {
6356 				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6357 			}
6358 			MinimumSwathHeightC = MaximumSwathHeightC[k];
6359 		} else {
6360 			if (SurfaceTiling[k] == dm_sw_linear) {
6361 				MinimumSwathHeightY = MaximumSwathHeightY[k];
6362 				MinimumSwathHeightC = MaximumSwathHeightC[k];
6363 			} else if (SourcePixelFormat[k] == dm_rgbe_alpha
6364 					&& SourceScan[k] == dm_vert) {
6365 				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6366 				MinimumSwathHeightC = MaximumSwathHeightC[k];
6367 			} else if (SourcePixelFormat[k] == dm_rgbe_alpha) {
6368 				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6369 				MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6370 			} else if (SourcePixelFormat[k] == dm_420_8 && SourceScan[k] == dm_vert) {
6371 				MinimumSwathHeightY = MaximumSwathHeightY[k];
6372 				MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6373 			} else {
6374 				MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6375 				MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6376 			}
6377 		}
6378 
6379 		RoundedUpMaxSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k]
6380 				* MaximumSwathHeightY[k];
6381 		RoundedUpMinSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k]
6382 				* MinimumSwathHeightY;
6383 		if (SourcePixelFormat[k] == dm_420_10) {
6384 			RoundedUpMaxSwathSizeBytesY = dml_ceil((double) RoundedUpMaxSwathSizeBytesY, 256);
6385 			RoundedUpMinSwathSizeBytesY = dml_ceil((double) RoundedUpMinSwathSizeBytesY, 256);
6386 		}
6387 		RoundedUpMaxSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k]
6388 				* MaximumSwathHeightC[k];
6389 		RoundedUpMinSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k]
6390 				* MinimumSwathHeightC;
6391 		if (SourcePixelFormat[k] == dm_420_10) {
6392 			RoundedUpMaxSwathSizeBytesC = dml_ceil(RoundedUpMaxSwathSizeBytesC, 256);
6393 			RoundedUpMinSwathSizeBytesC = dml_ceil(RoundedUpMinSwathSizeBytesC, 256);
6394 		}
6395 
6396 		if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
6397 				<= DETBufferSizeInKByte * 1024 / 2) {
6398 			SwathHeightY[k] = MaximumSwathHeightY[k];
6399 			SwathHeightC[k] = MaximumSwathHeightC[k];
6400 			RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
6401 			RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
6402 		} else if (RoundedUpMaxSwathSizeBytesY >= 1.5 * RoundedUpMaxSwathSizeBytesC
6403 				&& RoundedUpMinSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
6404 						<= DETBufferSizeInKByte * 1024 / 2) {
6405 			SwathHeightY[k] = MinimumSwathHeightY;
6406 			SwathHeightC[k] = MaximumSwathHeightC[k];
6407 			RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
6408 			RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
6409 		} else if (RoundedUpMaxSwathSizeBytesY < 1.5 * RoundedUpMaxSwathSizeBytesC
6410 				&& RoundedUpMaxSwathSizeBytesY + RoundedUpMinSwathSizeBytesC
6411 						<= DETBufferSizeInKByte * 1024 / 2) {
6412 			SwathHeightY[k] = MaximumSwathHeightY[k];
6413 			SwathHeightC[k] = MinimumSwathHeightC;
6414 			RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
6415 			RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
6416 		} else {
6417 			SwathHeightY[k] = MinimumSwathHeightY;
6418 			SwathHeightC[k] = MinimumSwathHeightC;
6419 			RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
6420 			RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
6421 		}
6422 
6423 		if (SwathHeightC[k] == 0) {
6424 			DETBufferSizeY[k] = DETBufferSizeInKByte * 1024;
6425 			DETBufferSizeC[k] = 0;
6426 		} else if (RoundedUpSwathSizeBytesY <= 1.5 * RoundedUpSwathSizeBytesC) {
6427 			DETBufferSizeY[k] = DETBufferSizeInKByte * 1024 / 2;
6428 			DETBufferSizeC[k] = DETBufferSizeInKByte * 1024 / 2;
6429 		} else {
6430 			DETBufferSizeY[k] = DETBufferSizeInKByte * 1024 * 2 / 3;
6431 			DETBufferSizeC[k] = DETBufferSizeInKByte * 1024 / 3;
6432 		}
6433 
6434 		if (RoundedUpMinSwathSizeBytesY + RoundedUpMinSwathSizeBytesC
6435 				> DETBufferSizeInKByte * 1024 / 2
6436 				|| SwathWidth[k] > MaximumSwathWidthLuma[k]
6437 				|| (SwathHeightC[k] > 0
6438 						&& SwathWidthChroma[k] > MaximumSwathWidthChroma[k])) {
6439 			*ViewportSizeSupport = false;
6440 			ViewportSizeSupportPerPlane[k] = false;
6441 		} else {
6442 			ViewportSizeSupportPerPlane[k] = true;
6443 		}
6444 	}
6445 }
6446 
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[])6447 static void CalculateSwathWidth(
6448 		bool ForceSingleDPP,
6449 		int NumberOfActivePlanes,
6450 		enum source_format_class SourcePixelFormat[],
6451 		enum scan_direction_class SourceScan[],
6452 		unsigned int ViewportWidth[],
6453 		unsigned int ViewportHeight[],
6454 		unsigned int SurfaceWidthY[],
6455 		unsigned int SurfaceWidthC[],
6456 		unsigned int SurfaceHeightY[],
6457 		unsigned int SurfaceHeightC[],
6458 		enum odm_combine_mode ODMCombineEnabled[],
6459 		int BytePerPixY[],
6460 		int BytePerPixC[],
6461 		int Read256BytesBlockHeightY[],
6462 		int Read256BytesBlockHeightC[],
6463 		int Read256BytesBlockWidthY[],
6464 		int Read256BytesBlockWidthC[],
6465 		int BlendingAndTiming[],
6466 		unsigned int HActive[],
6467 		double HRatio[],
6468 		int DPPPerPlane[],
6469 		double SwathWidthSingleDPPY[],
6470 		double SwathWidthSingleDPPC[],
6471 		double SwathWidthY[],
6472 		double SwathWidthC[],
6473 		int MaximumSwathHeightY[],
6474 		int MaximumSwathHeightC[],
6475 		unsigned int swath_width_luma_ub[],
6476 		unsigned int swath_width_chroma_ub[])
6477 {
6478 	unsigned int k, j;
6479 	long surface_width_ub_l;
6480 	long surface_height_ub_l;
6481 	long surface_width_ub_c;
6482 	long surface_height_ub_c;
6483 
6484 	for (k = 0; k < NumberOfActivePlanes; ++k) {
6485 		enum odm_combine_mode MainPlaneODMCombine = 0;
6486 		surface_width_ub_l = dml_ceil(SurfaceWidthY[k], Read256BytesBlockWidthY[k]);
6487 		surface_height_ub_l = dml_ceil(SurfaceHeightY[k], Read256BytesBlockHeightY[k]);
6488 		surface_width_ub_c = dml_ceil(SurfaceWidthC[k], Read256BytesBlockWidthC[k]);
6489 		surface_height_ub_c = dml_ceil(SurfaceHeightC[k], Read256BytesBlockHeightC[k]);
6490 
6491 		if (SourceScan[k] != dm_vert) {
6492 			SwathWidthSingleDPPY[k] = ViewportWidth[k];
6493 		} else {
6494 			SwathWidthSingleDPPY[k] = ViewportHeight[k];
6495 		}
6496 
6497 		MainPlaneODMCombine = ODMCombineEnabled[k];
6498 		for (j = 0; j < NumberOfActivePlanes; ++j) {
6499 			if (BlendingAndTiming[k] == j) {
6500 				MainPlaneODMCombine = ODMCombineEnabled[j];
6501 			}
6502 		}
6503 
6504 		if (MainPlaneODMCombine == dm_odm_combine_mode_4to1) {
6505 			SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 4.0 * HRatio[k]));
6506 		} else if (MainPlaneODMCombine == dm_odm_combine_mode_2to1) {
6507 			SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 2.0 * HRatio[k]));
6508 		} else if (DPPPerPlane[k] == 2) {
6509 			SwathWidthY[k] = SwathWidthSingleDPPY[k] / 2;
6510 		} else {
6511 			SwathWidthY[k] = SwathWidthSingleDPPY[k];
6512 		}
6513 
6514 		if (SourcePixelFormat[k] == dm_420_8 || SourcePixelFormat[k] == dm_420_10 || SourcePixelFormat[k] == dm_420_12) {
6515 			SwathWidthC[k] = SwathWidthY[k] / 2;
6516 			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k] / 2;
6517 		} else {
6518 			SwathWidthC[k] = SwathWidthY[k];
6519 			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k];
6520 		}
6521 
6522 		if (ForceSingleDPP == true) {
6523 			SwathWidthY[k] = SwathWidthSingleDPPY[k];
6524 			SwathWidthC[k] = SwathWidthSingleDPPC[k];
6525 		}
6526 
6527 		surface_width_ub_l  = dml_ceil(SurfaceWidthY[k], Read256BytesBlockWidthY[k]);
6528 		surface_height_ub_l = dml_ceil(SurfaceHeightY[k], Read256BytesBlockHeightY[k]);
6529 		surface_width_ub_c  = dml_ceil(SurfaceWidthC[k], Read256BytesBlockWidthC[k]);
6530 		surface_height_ub_c = dml_ceil(SurfaceHeightC[k], Read256BytesBlockHeightC[k]);
6531 
6532 		if (SourceScan[k] != dm_vert) {
6533 			MaximumSwathHeightY[k] = Read256BytesBlockHeightY[k];
6534 			MaximumSwathHeightC[k] = Read256BytesBlockHeightC[k];
6535 			swath_width_luma_ub[k] = dml_min(surface_width_ub_l, (long) dml_ceil(SwathWidthY[k] - 1,
6536 					Read256BytesBlockWidthY[k]) + Read256BytesBlockWidthY[k]);
6537 			if (BytePerPixC[k] > 0) {
6538 				swath_width_chroma_ub[k] = dml_min(surface_width_ub_c, (long) dml_ceil(SwathWidthC[k] - 1,
6539 						Read256BytesBlockWidthC[k]) + Read256BytesBlockWidthC[k]);
6540 			} else {
6541 				swath_width_chroma_ub[k] = 0;
6542 			}
6543 		} else {
6544 			MaximumSwathHeightY[k] = Read256BytesBlockWidthY[k];
6545 			MaximumSwathHeightC[k] = Read256BytesBlockWidthC[k];
6546 			swath_width_luma_ub[k] = dml_min(surface_height_ub_l, (long) dml_ceil(SwathWidthY[k] - 1,
6547 					Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k]);
6548 			if (BytePerPixC[k] > 0) {
6549 				swath_width_chroma_ub[k] = dml_min(surface_height_ub_c, (long) dml_ceil(SwathWidthC[k] - 1,
6550 						Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k]);
6551 			} else {
6552 				swath_width_chroma_ub[k] = 0;
6553 			}
6554 		}
6555 	}
6556 }
6557 
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)6558 static double CalculateExtraLatency(
6559 		long RoundTripPingLatencyCycles,
6560 		long ReorderingBytes,
6561 		double DCFCLK,
6562 		int TotalNumberOfActiveDPP,
6563 		int PixelChunkSizeInKByte,
6564 		int TotalNumberOfDCCActiveDPP,
6565 		int MetaChunkSize,
6566 		double ReturnBW,
6567 		bool GPUVMEnable,
6568 		bool HostVMEnable,
6569 		int NumberOfActivePlanes,
6570 		int NumberOfDPP[],
6571 		int dpte_group_bytes[],
6572 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
6573 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
6574 		double HostVMMinPageSize,
6575 		int HostVMMaxNonCachedPageTableLevels)
6576 {
6577 	double ExtraLatencyBytes = 0;
6578 	ExtraLatencyBytes = CalculateExtraLatencyBytes(
6579 					ReorderingBytes,
6580 					TotalNumberOfActiveDPP,
6581 					PixelChunkSizeInKByte,
6582 					TotalNumberOfDCCActiveDPP,
6583 					MetaChunkSize,
6584 					GPUVMEnable,
6585 					HostVMEnable,
6586 					NumberOfActivePlanes,
6587 					NumberOfDPP,
6588 					dpte_group_bytes,
6589 					PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
6590 					PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
6591 					HostVMMinPageSize,
6592 					HostVMMaxNonCachedPageTableLevels);
6593 
6594 	return (RoundTripPingLatencyCycles + 32) / DCFCLK + ExtraLatencyBytes / ReturnBW;
6595 }
6596 
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)6597 static double CalculateExtraLatencyBytes(
6598 		long ReorderingBytes,
6599 		int TotalNumberOfActiveDPP,
6600 		int PixelChunkSizeInKByte,
6601 		int TotalNumberOfDCCActiveDPP,
6602 		int MetaChunkSize,
6603 		bool GPUVMEnable,
6604 		bool HostVMEnable,
6605 		int NumberOfActivePlanes,
6606 		int NumberOfDPP[],
6607 		int dpte_group_bytes[],
6608 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
6609 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
6610 		double HostVMMinPageSize,
6611 		int HostVMMaxNonCachedPageTableLevels)
6612 {
6613 	double ret = 0;
6614 	double HostVMInefficiencyFactor = 0;
6615 	int HostVMDynamicLevels = 0;
6616 	unsigned int k;
6617 
6618 	if (GPUVMEnable == true && HostVMEnable == true) {
6619 		HostVMInefficiencyFactor = PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly;
6620 		if (HostVMMinPageSize < 2048) {
6621 			HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
6622 		} else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576) {
6623 			HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 1);
6624 		} else {
6625 			HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 2);
6626 		}
6627 	} else {
6628 		HostVMInefficiencyFactor = 1;
6629 		HostVMDynamicLevels = 0;
6630 	}
6631 
6632 	ret = ReorderingBytes + (TotalNumberOfActiveDPP * PixelChunkSizeInKByte + TotalNumberOfDCCActiveDPP * MetaChunkSize) * 1024.0;
6633 
6634 	if (GPUVMEnable == true) {
6635 		for (k = 0; k < NumberOfActivePlanes; ++k) {
6636 			ret = ret + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactor;
6637 		}
6638 	}
6639 	return ret;
6640 }
6641 
6642 
CalculateUrgentLatency(double UrgentLatencyPixelDataOnly,double UrgentLatencyPixelMixedWithVMData,double UrgentLatencyVMDataOnly,bool DoUrgentLatencyAdjustment,double UrgentLatencyAdjustmentFabricClockComponent,double UrgentLatencyAdjustmentFabricClockReference,double FabricClock)6643 static double CalculateUrgentLatency(
6644 		double UrgentLatencyPixelDataOnly,
6645 		double UrgentLatencyPixelMixedWithVMData,
6646 		double UrgentLatencyVMDataOnly,
6647 		bool DoUrgentLatencyAdjustment,
6648 		double UrgentLatencyAdjustmentFabricClockComponent,
6649 		double UrgentLatencyAdjustmentFabricClockReference,
6650 		double FabricClock)
6651 {
6652 	double ret;
6653 
6654 	ret = dml_max3(UrgentLatencyPixelDataOnly, UrgentLatencyPixelMixedWithVMData, UrgentLatencyVMDataOnly);
6655 	if (DoUrgentLatencyAdjustment == true) {
6656 		ret = ret + UrgentLatencyAdjustmentFabricClockComponent * (UrgentLatencyAdjustmentFabricClockReference / FabricClock - 1);
6657 	}
6658 	return ret;
6659 }
6660 
6661 
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])6662 static void UseMinimumDCFCLK(
6663 		struct display_mode_lib *mode_lib,
6664 		int MaxInterDCNTileRepeaters,
6665 		int MaxPrefetchMode,
6666 		double FinalDRAMClockChangeLatency,
6667 		double SREnterPlusExitTime,
6668 		int ReturnBusWidth,
6669 		int RoundTripPingLatencyCycles,
6670 		int ReorderingBytes,
6671 		int PixelChunkSizeInKByte,
6672 		int MetaChunkSize,
6673 		bool GPUVMEnable,
6674 		int GPUVMMaxPageTableLevels,
6675 		bool HostVMEnable,
6676 		int NumberOfActivePlanes,
6677 		double HostVMMinPageSize,
6678 		int HostVMMaxNonCachedPageTableLevels,
6679 		bool DynamicMetadataVMEnabled,
6680 		enum immediate_flip_requirement ImmediateFlipRequirement,
6681 		bool ProgressiveToInterlaceUnitInOPP,
6682 		double MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation,
6683 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
6684 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
6685 		double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly,
6686 		int VTotal[],
6687 		int VActive[],
6688 		int DynamicMetadataTransmittedBytes[],
6689 		int DynamicMetadataLinesBeforeActiveRequired[],
6690 		bool Interlace[],
6691 		double RequiredDPPCLK[][2][DC__NUM_DPP__MAX],
6692 		double RequiredDISPCLK[][2],
6693 		double UrgLatency[],
6694 		unsigned int NoOfDPP[][2][DC__NUM_DPP__MAX],
6695 		double ProjectedDCFCLKDeepSleep[][2],
6696 		double MaximumVStartup[][2][DC__NUM_DPP__MAX],
6697 		double TotalVActivePixelBandwidth[][2],
6698 		double TotalVActiveCursorBandwidth[][2],
6699 		double TotalMetaRowBandwidth[][2],
6700 		double TotalDPTERowBandwidth[][2],
6701 		unsigned int TotalNumberOfActiveDPP[][2],
6702 		unsigned int TotalNumberOfDCCActiveDPP[][2],
6703 		int dpte_group_bytes[],
6704 		double PrefetchLinesY[][2][DC__NUM_DPP__MAX],
6705 		double PrefetchLinesC[][2][DC__NUM_DPP__MAX],
6706 		int swath_width_luma_ub_all_states[][2][DC__NUM_DPP__MAX],
6707 		int swath_width_chroma_ub_all_states[][2][DC__NUM_DPP__MAX],
6708 		int BytePerPixelY[],
6709 		int BytePerPixelC[],
6710 		int HTotal[],
6711 		double PixelClock[],
6712 		double PDEAndMetaPTEBytesPerFrame[][2][DC__NUM_DPP__MAX],
6713 		double DPTEBytesPerRow[][2][DC__NUM_DPP__MAX],
6714 		double MetaRowBytes[][2][DC__NUM_DPP__MAX],
6715 		bool DynamicMetadataEnable[],
6716 		double VActivePixelBandwidth[][2][DC__NUM_DPP__MAX],
6717 		double VActiveCursorBandwidth[][2][DC__NUM_DPP__MAX],
6718 		double ReadBandwidthLuma[],
6719 		double ReadBandwidthChroma[],
6720 		double DCFCLKPerState[],
6721 		double DCFCLKState[][2])
6722 {
6723 	double   NormalEfficiency = 0;
6724 	double   PTEEfficiency = 0;
6725 	double   TotalMaxPrefetchFlipDPTERowBandwidth[DC__VOLTAGE_STATES][2] = { { 0 } };
6726 	unsigned int i, j, k;
6727 
6728 	NormalEfficiency =  (HostVMEnable == true ? PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData
6729 			: PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly) / 100.0;
6730 	PTEEfficiency =  (HostVMEnable == true ? PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly
6731 			/ PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData : 1.0);
6732 	for (i = 0; i < mode_lib->soc.num_states; ++i) {
6733 		for (j = 0; j <= 1; ++j) {
6734 			double PixelDCFCLKCyclesRequiredInPrefetch[DC__NUM_DPP__MAX] = { 0 };
6735 			double PrefetchPixelLinesTime[DC__NUM_DPP__MAX] = { 0 };
6736 			double DCFCLKRequiredForPeakBandwidthPerPlane[DC__NUM_DPP__MAX] = { 0 };
6737 			double DynamicMetadataVMExtraLatency[DC__NUM_DPP__MAX] = { 0 };
6738 			double MinimumTWait = 0;
6739 			double NonDPTEBandwidth = 0;
6740 			double DPTEBandwidth = 0;
6741 			double DCFCLKRequiredForAverageBandwidth = 0;
6742 			double ExtraLatencyBytes = 0;
6743 			double ExtraLatencyCycles = 0;
6744 			double DCFCLKRequiredForPeakBandwidth = 0;
6745 			int NoOfDPPState[DC__NUM_DPP__MAX] = { 0 };
6746 			double MinimumTvmPlus2Tr0 = 0;
6747 
6748 			TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = 0;
6749 			for (k = 0; k < NumberOfActivePlanes; ++k) {
6750 				TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = TotalMaxPrefetchFlipDPTERowBandwidth[i][j]
6751 					+ NoOfDPP[i][j][k] * DPTEBytesPerRow[i][j][k] / (15.75 * HTotal[k] / PixelClock[k]);
6752 			}
6753 
6754 			for (k = 0; k <= NumberOfActivePlanes - 1; ++k) {
6755 				NoOfDPPState[k] = NoOfDPP[i][j][k];
6756 			}
6757 
6758 			MinimumTWait = CalculateTWait(MaxPrefetchMode, FinalDRAMClockChangeLatency, UrgLatency[i], SREnterPlusExitTime);
6759 			NonDPTEBandwidth = TotalVActivePixelBandwidth[i][j] + TotalVActiveCursorBandwidth[i][j] + TotalMetaRowBandwidth[i][j];
6760 			DPTEBandwidth =  (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) ?
6761 					TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : TotalDPTERowBandwidth[i][j];
6762 			DCFCLKRequiredForAverageBandwidth = dml_max3(ProjectedDCFCLKDeepSleep[i][j],
6763 					(NonDPTEBandwidth + TotalDPTERowBandwidth[i][j]) / ReturnBusWidth / (MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100),
6764 					(NonDPTEBandwidth + DPTEBandwidth / PTEEfficiency) / NormalEfficiency / ReturnBusWidth);
6765 
6766 			ExtraLatencyBytes = CalculateExtraLatencyBytes(ReorderingBytes, TotalNumberOfActiveDPP[i][j], PixelChunkSizeInKByte, TotalNumberOfDCCActiveDPP[i][j],
6767 					MetaChunkSize, GPUVMEnable, HostVMEnable, NumberOfActivePlanes, NoOfDPPState, dpte_group_bytes,
6768 					PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
6769 					HostVMMinPageSize, HostVMMaxNonCachedPageTableLevels);
6770 			ExtraLatencyCycles = RoundTripPingLatencyCycles + 32 + ExtraLatencyBytes / NormalEfficiency / ReturnBusWidth;
6771 			for (k = 0; k < NumberOfActivePlanes; ++k) {
6772 				double DCFCLKCyclesRequiredInPrefetch = { 0 };
6773 				double ExpectedPrefetchBWAcceleration = { 0 };
6774 				double PrefetchTime = { 0 };
6775 
6776 				PixelDCFCLKCyclesRequiredInPrefetch[k] = (PrefetchLinesY[i][j][k] * swath_width_luma_ub_all_states[i][j][k] * BytePerPixelY[k]
6777 					+ PrefetchLinesC[i][j][k] * swath_width_chroma_ub_all_states[i][j][k] * BytePerPixelC[k]) / NormalEfficiency / ReturnBusWidth;
6778 				DCFCLKCyclesRequiredInPrefetch = 2 * ExtraLatencyCycles / NoOfDPPState[k] + PDEAndMetaPTEBytesPerFrame[i][j][k] / PTEEfficiency
6779 					/ NormalEfficiency / ReturnBusWidth *  (GPUVMMaxPageTableLevels > 2 ? 1 : 0) + 2 * DPTEBytesPerRow[i][j][k] / PTEEfficiency
6780 					/ NormalEfficiency / ReturnBusWidth + 2 * MetaRowBytes[i][j][k] / NormalEfficiency / ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k];
6781 				PrefetchPixelLinesTime[k] = dml_max(PrefetchLinesY[i][j][k], PrefetchLinesC[i][j][k]) * HTotal[k] / PixelClock[k];
6782 				ExpectedPrefetchBWAcceleration = (VActivePixelBandwidth[i][j][k] + VActiveCursorBandwidth[i][j][k]) / (ReadBandwidthLuma[k] + ReadBandwidthChroma[k]);
6783 				DynamicMetadataVMExtraLatency[k] = (GPUVMEnable == true && DynamicMetadataEnable[k] == true && DynamicMetadataVMEnabled == true) ?
6784 						UrgLatency[i] * GPUVMMaxPageTableLevels *  (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0;
6785 				PrefetchTime = (MaximumVStartup[i][j][k] - 1) * HTotal[k] / PixelClock[k] - MinimumTWait - UrgLatency[i] * ((GPUVMMaxPageTableLevels <= 2 ? GPUVMMaxPageTableLevels
6786 						: GPUVMMaxPageTableLevels - 2) * (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1) - DynamicMetadataVMExtraLatency[k];
6787 
6788 				if (PrefetchTime > 0) {
6789 					double ExpectedVRatioPrefetch = { 0 };
6790 					ExpectedVRatioPrefetch = PrefetchPixelLinesTime[k] / (PrefetchTime * PixelDCFCLKCyclesRequiredInPrefetch[k] / DCFCLKCyclesRequiredInPrefetch);
6791 					DCFCLKRequiredForPeakBandwidthPerPlane[k] = NoOfDPPState[k] * PixelDCFCLKCyclesRequiredInPrefetch[k] / PrefetchPixelLinesTime[k]
6792 						* dml_max(1.0, ExpectedVRatioPrefetch) * dml_max(1.0, ExpectedVRatioPrefetch / 4) * ExpectedPrefetchBWAcceleration;
6793 					if (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) {
6794 						DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKRequiredForPeakBandwidthPerPlane[k]
6795 							+ NoOfDPPState[k] * DPTEBandwidth / PTEEfficiency / NormalEfficiency / ReturnBusWidth;
6796 					}
6797 				} else {
6798 					DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i];
6799 				}
6800 				if (DynamicMetadataEnable[k] == true) {
6801 					double TsetupPipe = { 0 };
6802 					double TdmbfPipe = { 0 };
6803 					double TdmsksPipe = { 0 };
6804 					double TdmecPipe = { 0 };
6805 					double AllowedTimeForUrgentExtraLatency = { 0 };
6806 
6807 					CalculateDynamicMetadataParameters(
6808 							MaxInterDCNTileRepeaters,
6809 							RequiredDPPCLK[i][j][k],
6810 							RequiredDISPCLK[i][j],
6811 							ProjectedDCFCLKDeepSleep[i][j],
6812 							PixelClock[k],
6813 							HTotal[k],
6814 							VTotal[k] - VActive[k],
6815 							DynamicMetadataTransmittedBytes[k],
6816 							DynamicMetadataLinesBeforeActiveRequired[k],
6817 							Interlace[k],
6818 							ProgressiveToInterlaceUnitInOPP,
6819 							&TsetupPipe,
6820 							&TdmbfPipe,
6821 							&TdmecPipe,
6822 							&TdmsksPipe);
6823 					AllowedTimeForUrgentExtraLatency = MaximumVStartup[i][j][k] * HTotal[k] / PixelClock[k] - MinimumTWait - TsetupPipe
6824 							- TdmbfPipe - TdmecPipe - TdmsksPipe - DynamicMetadataVMExtraLatency[k];
6825 					if (AllowedTimeForUrgentExtraLatency > 0) {
6826 						DCFCLKRequiredForPeakBandwidthPerPlane[k] = dml_max(DCFCLKRequiredForPeakBandwidthPerPlane[k],
6827 								ExtraLatencyCycles / AllowedTimeForUrgentExtraLatency);
6828 					} else {
6829 						DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i];
6830 					}
6831 				}
6832 			}
6833 			DCFCLKRequiredForPeakBandwidth = 0;
6834 			for (k = 0; k <= NumberOfActivePlanes - 1; ++k) {
6835 				DCFCLKRequiredForPeakBandwidth = DCFCLKRequiredForPeakBandwidth + DCFCLKRequiredForPeakBandwidthPerPlane[k];
6836 			}
6837 			MinimumTvmPlus2Tr0 = UrgLatency[i] * (GPUVMEnable == true ? (HostVMEnable == true ?
6838 					(GPUVMMaxPageTableLevels + 2) * (HostVMMaxNonCachedPageTableLevels + 1) - 1 : GPUVMMaxPageTableLevels + 1) : 0);
6839 			for (k = 0; k < NumberOfActivePlanes; ++k) {
6840 				double MaximumTvmPlus2Tr0PlusTsw = { 0 };
6841 				MaximumTvmPlus2Tr0PlusTsw = (MaximumVStartup[i][j][k] - 2) * HTotal[k] / PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k];
6842 				if (MaximumTvmPlus2Tr0PlusTsw <= MinimumTvmPlus2Tr0 + PrefetchPixelLinesTime[k] / 4) {
6843 					DCFCLKRequiredForPeakBandwidth = DCFCLKPerState[i];
6844 				} else {
6845 					DCFCLKRequiredForPeakBandwidth = dml_max3(DCFCLKRequiredForPeakBandwidth, 2 * ExtraLatencyCycles
6846 							/ (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0 - PrefetchPixelLinesTime[k] / 4),
6847 						(2 * ExtraLatencyCycles + PixelDCFCLKCyclesRequiredInPrefetch[k]) / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0));
6848 				}
6849 			}
6850 			DCFCLKState[i][j] = dml_min(DCFCLKPerState[i], 1.05 * (1 + mode_lib->vba.PercentMarginOverMinimumRequiredDCFCLK / 100)
6851 					* dml_max(DCFCLKRequiredForAverageBandwidth, DCFCLKRequiredForPeakBandwidth));
6852 		}
6853 	}
6854 }
6855 
6856 #endif /* CONFIG_DRM_AMD_DC_DCN */
6857