xref: /linux/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_core.c (revision 237f1bbfe3d84a74ad8e6e207660bdb3e6d9a84d)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright 2023 Advanced Micro Devices, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Authors: AMD
24  *
25  */
26 
27 #include "display_mode_core.h"
28 #include "display_mode_util.h"
29 #include "display_mode_lib_defines.h"
30 
31 #include "dml_assert.h"
32 
33 #define DML2_MAX_FMT_420_BUFFER_WIDTH 4096
34 #define TB_BORROWED_MAX 400
35 #define DML_MAX_VSTARTUP_START 1023
36 
37 // ---------------------------
38 //  Declaration Begins
39 // ---------------------------
40 static void CalculateBytePerPixelAndBlockSizes(
41 	enum dml_source_format_class SourcePixelFormat,
42 	enum dml_swizzle_mode SurfaceTiling,
43 	// Output
44 	dml_uint_t *BytePerPixelY,
45 	dml_uint_t *BytePerPixelC,
46 	dml_float_t *BytePerPixelDETY,
47 	dml_float_t *BytePerPixelDETC,
48 	dml_uint_t *BlockHeight256BytesY,
49 	dml_uint_t *BlockHeight256BytesC,
50 	dml_uint_t *BlockWidth256BytesY,
51 	dml_uint_t *BlockWidth256BytesC,
52 	dml_uint_t *MacroTileHeightY,
53 	dml_uint_t *MacroTileHeightC,
54 	dml_uint_t *MacroTileWidthY,
55 	dml_uint_t *MacroTileWidthC);
56 
57 static dml_float_t CalculateWriteBackDISPCLK(
58 	enum dml_source_format_class WritebackPixelFormat,
59 	dml_float_t PixelClock,
60 	dml_float_t WritebackHRatio,
61 	dml_float_t WritebackVRatio,
62 	dml_uint_t WritebackHTaps,
63 	dml_uint_t WritebackVTaps,
64 	dml_uint_t WritebackSourceWidth,
65 	dml_uint_t WritebackDestinationWidth,
66 	dml_uint_t HTotal,
67 	dml_uint_t WritebackLineBufferSize,
68 	dml_float_t DISPCLKDPPCLKVCOSpeed);
69 
70 static void CalculateVMRowAndSwath(
71 	struct display_mode_lib_scratch_st *s,
72 	struct CalculateVMRowAndSwath_params_st *p);
73 
74 static void CalculateOutputLink(
75 	dml_float_t PHYCLKPerState,
76 	dml_float_t PHYCLKD18PerState,
77 	dml_float_t PHYCLKD32PerState,
78 	dml_float_t Downspreading,
79 	dml_bool_t IsMainSurfaceUsingTheIndicatedTiming,
80 	enum dml_output_encoder_class Output,
81 	enum dml_output_format_class OutputFormat,
82 	dml_uint_t HTotal,
83 	dml_uint_t HActive,
84 	dml_float_t PixelClockBackEnd,
85 	dml_float_t ForcedOutputLinkBPP,
86 	dml_uint_t DSCInputBitPerComponent,
87 	dml_uint_t NumberOfDSCSlices,
88 	dml_float_t AudioSampleRate,
89 	dml_uint_t AudioSampleLayout,
90 	enum dml_odm_mode ODMModeNoDSC,
91 	enum dml_odm_mode ODMModeDSC,
92 	enum dml_dsc_enable DSCEnable,
93 	dml_uint_t OutputLinkDPLanes,
94 	enum dml_output_link_dp_rate OutputLinkDPRate,
95 
96 	// Output
97 	dml_bool_t *RequiresDSC,
98 	dml_bool_t *RequiresFEC,
99 	dml_float_t *OutBpp,
100 	enum dml_output_type_and_rate__type *OutputType,
101 	enum dml_output_type_and_rate__rate *OutputRate,
102 	dml_uint_t *RequiredSlots);
103 
104 static void CalculateODMMode(
105 	dml_uint_t MaximumPixelsPerLinePerDSCUnit,
106 	dml_uint_t HActive,
107 	enum dml_output_encoder_class Output,
108 	enum dml_output_format_class OutputFormat,
109 	enum dml_odm_use_policy ODMUse,
110 	dml_float_t StateDispclk,
111 	dml_float_t MaxDispclk,
112 	dml_bool_t DSCEnable,
113 	dml_uint_t TotalNumberOfActiveDPP,
114 	dml_uint_t MaxNumDPP,
115 	dml_float_t PixelClock,
116 	dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,
117 	dml_float_t DISPCLKRampingMargin,
118 	dml_float_t DISPCLKDPPCLKVCOSpeed,
119 	dml_uint_t NumberOfDSCSlices,
120 
121 	// Output
122 	dml_bool_t *TotalAvailablePipesSupport,
123 	dml_uint_t *NumberOfDPP,
124 	enum dml_odm_mode *ODMMode,
125 	dml_float_t *RequiredDISPCLKPerSurface);
126 
127 static dml_float_t CalculateRequiredDispclk(
128 	enum dml_odm_mode ODMMode,
129 	dml_float_t PixelClock,
130 	dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,
131 	dml_float_t DISPCLKRampingMargin,
132 	dml_float_t DISPCLKDPPCLKVCOSpeed,
133 	dml_float_t MaxDispclkSingle);
134 
135 static void CalculateSinglePipeDPPCLKAndSCLThroughput(
136 	dml_float_t HRatio,
137 	dml_float_t HRatioChroma,
138 	dml_float_t VRatio,
139 	dml_float_t VRatioChroma,
140 	dml_float_t MaxDCHUBToPSCLThroughput,
141 	dml_float_t MaxPSCLToLBThroughput,
142 	dml_float_t PixelClock,
143 	enum dml_source_format_class SourcePixelFormat,
144 	dml_uint_t HTaps,
145 	dml_uint_t HTapsChroma,
146 	dml_uint_t VTaps,
147 	dml_uint_t VTapsChroma,
148 
149 	// Output
150 	dml_float_t *PSCL_THROUGHPUT,
151 	dml_float_t *PSCL_THROUGHPUT_CHROMA,
152 	dml_float_t *DPPCLKUsingSingleDPP);
153 
154 static void CalculateDPPCLK(
155 	dml_uint_t NumberOfActiveSurfaces,
156 	dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,
157 	dml_float_t DISPCLKDPPCLKVCOSpeed,
158 	dml_float_t DPPCLKUsingSingleDPP[],
159 	dml_uint_t DPPPerSurface[],
160 
161 	// Output
162 	dml_float_t *GlobalDPPCLK,
163 	dml_float_t Dppclk[]);
164 
165 static void CalculateMALLUseForStaticScreen(
166 	dml_uint_t NumberOfActiveSurfaces,
167 	dml_uint_t MALLAllocatedForDCNFinal,
168 	enum dml_use_mall_for_static_screen_mode *UseMALLForStaticScreen,
169 	dml_uint_t SurfaceSizeInMALL[],
170 	dml_bool_t one_row_per_frame_fits_in_buffer[],
171 
172 	// Output
173 	dml_bool_t UsesMALLForStaticScreen[]);
174 
175 static dml_uint_t dscceComputeDelay(
176 	dml_uint_t bpc,
177 	dml_float_t BPP,
178 	dml_uint_t sliceWidth,
179 	dml_uint_t numSlices,
180 	enum dml_output_format_class pixelFormat,
181 	enum dml_output_encoder_class Output);
182 
183 static dml_uint_t dscComputeDelay(enum dml_output_format_class pixelFormat,
184 	enum dml_output_encoder_class Output);
185 
186 static dml_bool_t CalculatePrefetchSchedule(struct display_mode_lib_scratch_st *scratch,
187 	struct CalculatePrefetchSchedule_params_st *p);
188 
189 static dml_float_t RoundToDFSGranularity(dml_float_t Clock, dml_bool_t round_up, dml_float_t VCOSpeed);
190 
191 static void CalculateDCCConfiguration(
192 	dml_bool_t DCCEnabled,
193 	dml_bool_t DCCProgrammingAssumesScanDirectionUnknown,
194 	enum dml_source_format_class SourcePixelFormat,
195 	dml_uint_t SurfaceWidthLuma,
196 	dml_uint_t SurfaceWidthChroma,
197 	dml_uint_t SurfaceHeightLuma,
198 	dml_uint_t SurfaceHeightChroma,
199 	dml_uint_t nomDETInKByte,
200 	dml_uint_t RequestHeight256ByteLuma,
201 	dml_uint_t RequestHeight256ByteChroma,
202 	enum dml_swizzle_mode TilingFormat,
203 	dml_uint_t BytePerPixelY,
204 	dml_uint_t BytePerPixelC,
205 	dml_float_t BytePerPixelDETY,
206 	dml_float_t BytePerPixelDETC,
207 	enum dml_rotation_angle SourceScan,
208 	// Output
209 	dml_uint_t *MaxUncompressedBlockLuma,
210 	dml_uint_t *MaxUncompressedBlockChroma,
211 	dml_uint_t *MaxCompressedBlockLuma,
212 	dml_uint_t *MaxCompressedBlockChroma,
213 	dml_uint_t *IndependentBlockLuma,
214 	dml_uint_t *IndependentBlockChroma);
215 
216 static dml_uint_t CalculatePrefetchSourceLines(
217 	dml_float_t VRatio,
218 	dml_uint_t VTaps,
219 	dml_bool_t Interlace,
220 	dml_bool_t ProgressiveToInterlaceUnitInOPP,
221 	dml_uint_t SwathHeight,
222 	enum dml_rotation_angle SourceScan,
223 	dml_bool_t ViewportStationary,
224 	dml_uint_t SwathWidth,
225 	dml_uint_t ViewportHeight,
226 	dml_uint_t ViewportXStart,
227 	dml_uint_t ViewportYStart,
228 
229 	// Output
230 	dml_uint_t *VInitPreFill,
231 	dml_uint_t *MaxNumSwath);
232 
233 static dml_uint_t CalculateVMAndRowBytes(
234 	dml_bool_t ViewportStationary,
235 	dml_bool_t DCCEnable,
236 	dml_uint_t NumberOfDPPs,
237 	dml_uint_t BlockHeight256Bytes,
238 	dml_uint_t BlockWidth256Bytes,
239 	enum dml_source_format_class SourcePixelFormat,
240 	dml_uint_t SurfaceTiling,
241 	dml_uint_t BytePerPixel,
242 	enum dml_rotation_angle SourceScan,
243 	dml_uint_t SwathWidth,
244 	dml_uint_t ViewportHeight,
245 	dml_uint_t ViewportXStart,
246 	dml_uint_t ViewportYStart,
247 	dml_bool_t GPUVMEnable,
248 	dml_uint_t GPUVMMaxPageTableLevels,
249 	dml_uint_t GPUVMMinPageSizeKBytes,
250 	dml_uint_t PTEBufferSizeInRequests,
251 	dml_uint_t Pitch,
252 	dml_uint_t DCCMetaPitch,
253 	dml_uint_t MacroTileWidth,
254 	dml_uint_t MacroTileHeight,
255 
256 	// Output
257 	dml_uint_t *MetaRowByte,
258 	dml_uint_t *PixelPTEBytesPerRow,
259 	dml_uint_t *PixelPTEBytesPerRowStorage, // for PTE buffer size check
260 	dml_uint_t *dpte_row_width_ub,
261 	dml_uint_t *dpte_row_height,
262 	dml_uint_t *dpte_row_height_linear,
263 	dml_uint_t *PixelPTEBytesPerRow_one_row_per_frame,
264 	dml_uint_t *dpte_row_width_ub_one_row_per_frame,
265 	dml_uint_t *dpte_row_height_one_row_per_frame,
266 	dml_uint_t *MetaRequestWidth,
267 	dml_uint_t *MetaRequestHeight,
268 	dml_uint_t *meta_row_width,
269 	dml_uint_t *meta_row_height,
270 	dml_uint_t *PixelPTEReqWidth,
271 	dml_uint_t *PixelPTEReqHeight,
272 	dml_uint_t *PTERequestSize,
273 	dml_uint_t *DPDE0BytesFrame,
274 	dml_uint_t *MetaPTEBytesFrame);
275 
276 static dml_float_t CalculateTWait(
277 	dml_uint_t PrefetchMode,
278 	enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange,
279 	dml_bool_t SynchronizeDRRDisplaysForUCLKPStateChangeFinal,
280 	dml_bool_t DRRDisplay,
281 	dml_float_t DRAMClockChangeLatency,
282 	dml_float_t FCLKChangeLatency,
283 	dml_float_t UrgentLatency,
284 	dml_float_t SREnterPlusExitTime);
285 
286 static void CalculatePrefetchMode(
287 	enum dml_prefetch_modes AllowForPStateChangeOrStutterInVBlank,
288 	dml_uint_t *MinPrefetchMode,
289 	dml_uint_t *MaxPrefetchMode);
290 
291 static void CalculateRowBandwidth(
292 	dml_bool_t GPUVMEnable,
293 	enum dml_source_format_class SourcePixelFormat,
294 	dml_float_t VRatio,
295 	dml_float_t VRatioChroma,
296 	dml_bool_t DCCEnable,
297 	dml_float_t LineTime,
298 	dml_uint_t MetaRowByteLuma,
299 	dml_uint_t MetaRowByteChroma,
300 	dml_uint_t meta_row_height_luma,
301 	dml_uint_t meta_row_height_chroma,
302 	dml_uint_t PixelPTEBytesPerRowLuma,
303 	dml_uint_t PixelPTEBytesPerRowChroma,
304 	dml_uint_t dpte_row_height_luma,
305 	dml_uint_t dpte_row_height_chroma,
306 	// Output
307 	dml_float_t *meta_row_bw,
308 	dml_float_t *dpte_row_bw);
309 
310 static void CalculateFlipSchedule(
311 	dml_float_t HostVMInefficiencyFactor,
312 	dml_float_t UrgentExtraLatency,
313 	dml_float_t UrgentLatency,
314 	dml_uint_t GPUVMMaxPageTableLevels,
315 	dml_bool_t HostVMEnable,
316 	dml_uint_t HostVMMaxNonCachedPageTableLevels,
317 	dml_bool_t GPUVMEnable,
318 	dml_uint_t HostVMMinPageSize,
319 	dml_float_t PDEAndMetaPTEBytesPerFrame,
320 	dml_float_t MetaRowBytes,
321 	dml_float_t DPTEBytesPerRow,
322 	dml_float_t BandwidthAvailableForImmediateFlip,
323 	dml_uint_t TotImmediateFlipBytes,
324 	enum dml_source_format_class SourcePixelFormat,
325 	dml_float_t LineTime,
326 	dml_float_t VRatio,
327 	dml_float_t VRatioChroma,
328 	dml_float_t Tno_bw,
329 	dml_bool_t DCCEnable,
330 	dml_uint_t dpte_row_height,
331 	dml_uint_t meta_row_height,
332 	dml_uint_t dpte_row_height_chroma,
333 	dml_uint_t meta_row_height_chroma,
334 	dml_bool_t use_one_row_for_frame_flip,
335 
336 	// Output
337 	dml_float_t *DestinationLinesToRequestVMInImmediateFlip,
338 	dml_float_t *DestinationLinesToRequestRowInImmediateFlip,
339 	dml_float_t *final_flip_bw,
340 	dml_bool_t *ImmediateFlipSupportedForPipe);
341 
342 static dml_float_t CalculateWriteBackDelay(
343 	enum dml_source_format_class WritebackPixelFormat,
344 	dml_float_t WritebackHRatio,
345 	dml_float_t WritebackVRatio,
346 	dml_uint_t WritebackVTaps,
347 	dml_uint_t WritebackDestinationWidth,
348 	dml_uint_t WritebackDestinationHeight,
349 	dml_uint_t WritebackSourceHeight,
350 	dml_uint_t HTotal);
351 
352 static void CalculateVUpdateAndDynamicMetadataParameters(
353 	dml_uint_t MaxInterDCNTileRepeaters,
354 	dml_float_t Dppclk,
355 	dml_float_t DISPCLK,
356 	dml_float_t DCFClkDeepSleep,
357 	dml_float_t PixelClock,
358 	dml_uint_t HTotal,
359 	dml_uint_t VBlank,
360 	dml_uint_t DynamicMetadataTransmittedBytes,
361 	dml_uint_t DynamicMetadataLinesBeforeActiveRequired,
362 	dml_uint_t InterlaceEnable,
363 	dml_bool_t ProgressiveToInterlaceUnitInOPP,
364 	dml_float_t *TSetup,
365 	dml_float_t *Tdmbf,
366 	dml_float_t *Tdmec,
367 	dml_float_t *Tdmsks,
368 	dml_uint_t *VUpdateOffsetPix,
369 	dml_uint_t *VUpdateWidthPix,
370 	dml_uint_t *VReadyOffsetPix);
371 
372 static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct dml_display_cfg_st *display_cfg, dml_bool_t ptoi_supported);
373 
374 static dml_float_t TruncToValidBPP(
375 	dml_float_t LinkBitRate,
376 	dml_uint_t Lanes,
377 	dml_uint_t HTotal,
378 	dml_uint_t HActive,
379 	dml_float_t PixelClock,
380 	dml_float_t DesiredBPP,
381 	dml_bool_t DSCEnable,
382 	enum dml_output_encoder_class Output,
383 	enum dml_output_format_class Format,
384 	dml_uint_t DSCInputBitPerComponent,
385 	dml_uint_t DSCSlices,
386 	dml_uint_t AudioRate,
387 	dml_uint_t AudioLayout,
388 	enum dml_odm_mode ODMModeNoDSC,
389 	enum dml_odm_mode ODMModeDSC,
390 	// Output
391 	dml_uint_t *RequiredSlotsSingle);
392 
393 static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
394 	struct display_mode_lib_scratch_st *s,
395 	struct CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params_st *p);
396 
397 static void CalculateDCFCLKDeepSleep(
398 	dml_uint_t NumberOfActiveSurfaces,
399 	dml_uint_t BytePerPixelY[],
400 	dml_uint_t BytePerPixelC[],
401 	dml_float_t VRatio[],
402 	dml_float_t VRatioChroma[],
403 	dml_uint_t SwathWidthY[],
404 	dml_uint_t SwathWidthC[],
405 	dml_uint_t DPPPerSurface[],
406 	dml_float_t HRatio[],
407 	dml_float_t HRatioChroma[],
408 	dml_float_t PixelClock[],
409 	dml_float_t PSCL_THROUGHPUT[],
410 	dml_float_t PSCL_THROUGHPUT_CHROMA[],
411 	dml_float_t Dppclk[],
412 	dml_float_t ReadBandwidthLuma[],
413 	dml_float_t ReadBandwidthChroma[],
414 	dml_uint_t ReturnBusWidth,
415 
416 	// Output
417 	dml_float_t *DCFCLKDeepSleep);
418 
419 static void CalculateUrgentBurstFactor(
420 	enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange,
421 	dml_uint_t swath_width_luma_ub,
422 	dml_uint_t swath_width_chroma_ub,
423 	dml_uint_t SwathHeightY,
424 	dml_uint_t SwathHeightC,
425 	dml_float_t LineTime,
426 	dml_float_t UrgentLatency,
427 	dml_float_t CursorBufferSize,
428 	dml_uint_t CursorWidth,
429 	dml_uint_t CursorBPP,
430 	dml_float_t VRatio,
431 	dml_float_t VRatioC,
432 	dml_float_t BytePerPixelInDETY,
433 	dml_float_t BytePerPixelInDETC,
434 	dml_uint_t DETBufferSizeY,
435 	dml_uint_t DETBufferSizeC,
436 	// Output
437 	dml_float_t *UrgentBurstFactorCursor,
438 	dml_float_t *UrgentBurstFactorLuma,
439 	dml_float_t *UrgentBurstFactorChroma,
440 	dml_bool_t *NotEnoughUrgentLatencyHiding);
441 
442 static dml_float_t RequiredDTBCLK(
443 	dml_bool_t DSCEnable,
444 	dml_float_t PixelClock,
445 	enum dml_output_format_class OutputFormat,
446 	dml_float_t OutputBpp,
447 	dml_uint_t DSCSlices,
448 	dml_uint_t HTotal,
449 	dml_uint_t HActive,
450 	dml_uint_t AudioRate,
451 	dml_uint_t AudioLayoutSingle);
452 
453 static void UseMinimumDCFCLK(
454 	struct display_mode_lib_scratch_st *scratch,
455 	struct UseMinimumDCFCLK_params_st *p);
456 
457 static void CalculatePixelDeliveryTimes(
458 	dml_uint_t NumberOfActiveSurfaces,
459 	dml_float_t VRatio[],
460 	dml_float_t VRatioChroma[],
461 	dml_float_t VRatioPrefetchY[],
462 	dml_float_t VRatioPrefetchC[],
463 	dml_uint_t swath_width_luma_ub[],
464 	dml_uint_t swath_width_chroma_ub[],
465 	dml_uint_t DPPPerSurface[],
466 	dml_float_t HRatio[],
467 	dml_float_t HRatioChroma[],
468 	dml_float_t PixelClock[],
469 	dml_float_t PSCL_THROUGHPUT[],
470 	dml_float_t PSCL_THROUGHPUT_CHROMA[],
471 	dml_float_t Dppclk[],
472 	dml_uint_t BytePerPixelC[],
473 	enum dml_rotation_angle SourceScan[],
474 	dml_uint_t NumberOfCursors[],
475 	dml_uint_t CursorWidth[],
476 	dml_uint_t CursorBPP[],
477 	dml_uint_t BlockWidth256BytesY[],
478 	dml_uint_t BlockHeight256BytesY[],
479 	dml_uint_t BlockWidth256BytesC[],
480 	dml_uint_t BlockHeight256BytesC[],
481 
482 	// Output
483 	dml_float_t DisplayPipeLineDeliveryTimeLuma[],
484 	dml_float_t DisplayPipeLineDeliveryTimeChroma[],
485 	dml_float_t DisplayPipeLineDeliveryTimeLumaPrefetch[],
486 	dml_float_t DisplayPipeLineDeliveryTimeChromaPrefetch[],
487 	dml_float_t DisplayPipeRequestDeliveryTimeLuma[],
488 	dml_float_t DisplayPipeRequestDeliveryTimeChroma[],
489 	dml_float_t DisplayPipeRequestDeliveryTimeLumaPrefetch[],
490 	dml_float_t DisplayPipeRequestDeliveryTimeChromaPrefetch[],
491 	dml_float_t CursorRequestDeliveryTime[],
492 	dml_float_t CursorRequestDeliveryTimePrefetch[]);
493 
494 static void CalculateMetaAndPTETimes(
495 	dml_bool_t use_one_row_for_frame[],
496 	dml_uint_t NumberOfActiveSurfaces,
497 	dml_bool_t GPUVMEnable,
498 	dml_uint_t MetaChunkSize,
499 	dml_uint_t MinMetaChunkSizeBytes,
500 	dml_uint_t HTotal[],
501 	dml_float_t VRatio[],
502 	dml_float_t VRatioChroma[],
503 	dml_float_t DestinationLinesToRequestRowInVBlank[],
504 	dml_float_t DestinationLinesToRequestRowInImmediateFlip[],
505 	dml_bool_t DCCEnable[],
506 	dml_float_t PixelClock[],
507 	dml_uint_t BytePerPixelY[],
508 	dml_uint_t BytePerPixelC[],
509 	enum dml_rotation_angle SourceScan[],
510 	dml_uint_t dpte_row_height[],
511 	dml_uint_t dpte_row_height_chroma[],
512 	dml_uint_t meta_row_width[],
513 	dml_uint_t meta_row_width_chroma[],
514 	dml_uint_t meta_row_height[],
515 	dml_uint_t meta_row_height_chroma[],
516 	dml_uint_t meta_req_width[],
517 	dml_uint_t meta_req_width_chroma[],
518 	dml_uint_t meta_req_height[],
519 	dml_uint_t meta_req_height_chroma[],
520 	dml_uint_t dpte_group_bytes[],
521 	dml_uint_t PTERequestSizeY[],
522 	dml_uint_t PTERequestSizeC[],
523 	dml_uint_t PixelPTEReqWidthY[],
524 	dml_uint_t PixelPTEReqHeightY[],
525 	dml_uint_t PixelPTEReqWidthC[],
526 	dml_uint_t PixelPTEReqHeightC[],
527 	dml_uint_t dpte_row_width_luma_ub[],
528 	dml_uint_t dpte_row_width_chroma_ub[],
529 
530 	// Output
531 	dml_float_t DST_Y_PER_PTE_ROW_NOM_L[],
532 	dml_float_t DST_Y_PER_PTE_ROW_NOM_C[],
533 	dml_float_t DST_Y_PER_META_ROW_NOM_L[],
534 	dml_float_t DST_Y_PER_META_ROW_NOM_C[],
535 	dml_float_t TimePerMetaChunkNominal[],
536 	dml_float_t TimePerChromaMetaChunkNominal[],
537 	dml_float_t TimePerMetaChunkVBlank[],
538 	dml_float_t TimePerChromaMetaChunkVBlank[],
539 	dml_float_t TimePerMetaChunkFlip[],
540 	dml_float_t TimePerChromaMetaChunkFlip[],
541 	dml_float_t time_per_pte_group_nom_luma[],
542 	dml_float_t time_per_pte_group_vblank_luma[],
543 	dml_float_t time_per_pte_group_flip_luma[],
544 	dml_float_t time_per_pte_group_nom_chroma[],
545 	dml_float_t time_per_pte_group_vblank_chroma[],
546 	dml_float_t time_per_pte_group_flip_chroma[]);
547 
548 static void CalculateVMGroupAndRequestTimes(
549 	dml_uint_t NumberOfActiveSurfaces,
550 	dml_bool_t GPUVMEnable,
551 	dml_uint_t GPUVMMaxPageTableLevels,
552 	dml_uint_t HTotal[],
553 	dml_uint_t BytePerPixelC[],
554 	dml_float_t DestinationLinesToRequestVMInVBlank[],
555 	dml_float_t DestinationLinesToRequestVMInImmediateFlip[],
556 	dml_bool_t DCCEnable[],
557 	dml_float_t PixelClock[],
558 	dml_uint_t dpte_row_width_luma_ub[],
559 	dml_uint_t dpte_row_width_chroma_ub[],
560 	dml_uint_t vm_group_bytes[],
561 	dml_uint_t dpde0_bytes_per_frame_ub_l[],
562 	dml_uint_t dpde0_bytes_per_frame_ub_c[],
563 	dml_uint_t meta_pte_bytes_per_frame_ub_l[],
564 	dml_uint_t meta_pte_bytes_per_frame_ub_c[],
565 
566 	// Output
567 	dml_float_t TimePerVMGroupVBlank[],
568 	dml_float_t TimePerVMGroupFlip[],
569 	dml_float_t TimePerVMRequestVBlank[],
570 	dml_float_t TimePerVMRequestFlip[]);
571 
572 static void CalculateStutterEfficiency(
573 	struct display_mode_lib_scratch_st *scratch,
574 	struct CalculateStutterEfficiency_params_st *p);
575 
576 static void CalculateSwathAndDETConfiguration(
577 	struct display_mode_lib_scratch_st *scratch,
578 	struct CalculateSwathAndDETConfiguration_params_st *p);
579 
580 static void CalculateSwathWidth(
581 	dml_bool_t ForceSingleDPP,
582 	dml_uint_t NumberOfActiveSurfaces,
583 	enum dml_source_format_class SourcePixelFormat[],
584 	enum dml_rotation_angle SourceScan[],
585 	dml_bool_t ViewportStationary[],
586 	dml_uint_t ViewportWidth[],
587 	dml_uint_t ViewportHeight[],
588 	dml_uint_t ViewportXStart[],
589 	dml_uint_t ViewportYStart[],
590 	dml_uint_t ViewportXStartC[],
591 	dml_uint_t ViewportYStartC[],
592 	dml_uint_t SurfaceWidthY[],
593 	dml_uint_t SurfaceWidthC[],
594 	dml_uint_t SurfaceHeightY[],
595 	dml_uint_t SurfaceHeightC[],
596 	enum dml_odm_mode ODMMode[],
597 	dml_uint_t BytePerPixY[],
598 	dml_uint_t BytePerPixC[],
599 	dml_uint_t Read256BytesBlockHeightY[],
600 	dml_uint_t Read256BytesBlockHeightC[],
601 	dml_uint_t Read256BytesBlockWidthY[],
602 	dml_uint_t Read256BytesBlockWidthC[],
603 	dml_uint_t BlendingAndTiming[],
604 	dml_uint_t HActive[],
605 	dml_float_t HRatio[],
606 	dml_uint_t DPPPerSurface[],
607 
608 	// Output
609 	dml_uint_t SwathWidthSingleDPPY[],
610 	dml_uint_t SwathWidthSingleDPPC[],
611 	dml_uint_t SwathWidthY[],
612 	dml_uint_t SwathWidthC[],
613 	dml_uint_t MaximumSwathHeightY[],
614 	dml_uint_t MaximumSwathHeightC[],
615 	dml_uint_t swath_width_luma_ub[],
616 	dml_uint_t swath_width_chroma_ub[]);
617 
618 static dml_float_t CalculateExtraLatency(
619 	dml_uint_t RoundTripPingLatencyCycles,
620 	dml_uint_t ReorderingBytes,
621 	dml_float_t DCFCLK,
622 	dml_uint_t TotalNumberOfActiveDPP,
623 	dml_uint_t PixelChunkSizeInKByte,
624 	dml_uint_t TotalNumberOfDCCActiveDPP,
625 	dml_uint_t MetaChunkSize,
626 	dml_float_t ReturnBW,
627 	dml_bool_t GPUVMEnable,
628 	dml_bool_t HostVMEnable,
629 	dml_uint_t NumberOfActiveSurfaces,
630 	dml_uint_t NumberOfDPP[],
631 	dml_uint_t dpte_group_bytes[],
632 	dml_float_t HostVMInefficiencyFactor,
633 	dml_uint_t HostVMMinPageSize,
634 	dml_uint_t HostVMMaxNonCachedPageTableLevels);
635 
636 static dml_uint_t CalculateExtraLatencyBytes(
637 	dml_uint_t ReorderingBytes,
638 	dml_uint_t TotalNumberOfActiveDPP,
639 	dml_uint_t PixelChunkSizeInKByte,
640 	dml_uint_t TotalNumberOfDCCActiveDPP,
641 	dml_uint_t MetaChunkSize,
642 	dml_bool_t GPUVMEnable,
643 	dml_bool_t HostVMEnable,
644 	dml_uint_t NumberOfActiveSurfaces,
645 	dml_uint_t NumberOfDPP[],
646 	dml_uint_t dpte_group_bytes[],
647 	dml_float_t HostVMInefficiencyFactor,
648 	dml_uint_t HostVMMinPageSize,
649 	dml_uint_t HostVMMaxNonCachedPageTableLevels);
650 
651 static dml_float_t CalculateUrgentLatency(
652 	dml_float_t UrgentLatencyPixelDataOnly,
653 	dml_float_t UrgentLatencyPixelMixedWithVMData,
654 	dml_float_t UrgentLatencyVMDataOnly,
655 	dml_bool_t DoUrgentLatencyAdjustment,
656 	dml_float_t UrgentLatencyAdjustmentFabricClockComponent,
657 	dml_float_t UrgentLatencyAdjustmentFabricClockReference,
658 	dml_float_t FabricClockSingle);
659 
660 static dml_bool_t UnboundedRequest(
661 	enum dml_unbounded_requesting_policy UseUnboundedRequestingFinal,
662 	dml_uint_t TotalNumberOfActiveDPP,
663 	dml_bool_t NoChromaOrLinear,
664 	enum dml_output_encoder_class Output);
665 
666 static void CalculateSurfaceSizeInMall(
667 	dml_uint_t NumberOfActiveSurfaces,
668 	dml_uint_t MALLAllocatedForDCN,
669 	enum dml_use_mall_for_static_screen_mode UseMALLForStaticScreen[],
670 	dml_bool_t DCCEnable[],
671 	dml_bool_t ViewportStationary[],
672 	dml_uint_t ViewportXStartY[],
673 	dml_uint_t ViewportYStartY[],
674 	dml_uint_t ViewportXStartC[],
675 	dml_uint_t ViewportYStartC[],
676 	dml_uint_t ViewportWidthY[],
677 	dml_uint_t ViewportHeightY[],
678 	dml_uint_t BytesPerPixelY[],
679 	dml_uint_t ViewportWidthC[],
680 	dml_uint_t ViewportHeightC[],
681 	dml_uint_t BytesPerPixelC[],
682 	dml_uint_t SurfaceWidthY[],
683 	dml_uint_t SurfaceWidthC[],
684 	dml_uint_t SurfaceHeightY[],
685 	dml_uint_t SurfaceHeightC[],
686 	dml_uint_t Read256BytesBlockWidthY[],
687 	dml_uint_t Read256BytesBlockWidthC[],
688 	dml_uint_t Read256BytesBlockHeightY[],
689 	dml_uint_t Read256BytesBlockHeightC[],
690 	dml_uint_t ReadBlockWidthY[],
691 	dml_uint_t ReadBlockWidthC[],
692 	dml_uint_t ReadBlockHeightY[],
693 	dml_uint_t ReadBlockHeightC[],
694 
695 	// Output
696 	dml_uint_t SurfaceSizeInMALL[],
697 	dml_bool_t *ExceededMALLSize);
698 
699 static void CalculateDETBufferSize(
700 	dml_uint_t DETSizeOverride[],
701 	enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
702 	dml_bool_t ForceSingleDPP,
703 	dml_uint_t NumberOfActiveSurfaces,
704 	dml_bool_t UnboundedRequestEnabled,
705 	dml_uint_t nomDETInKByte,
706 	dml_uint_t MaxTotalDETInKByte,
707 	dml_uint_t ConfigReturnBufferSizeInKByte,
708 	dml_uint_t MinCompressedBufferSizeInKByte,
709 	dml_uint_t ConfigReturnBufferSegmentSizeInkByte,
710 	dml_uint_t CompressedBufferSegmentSizeInkByteFinal,
711 	enum dml_source_format_class SourcePixelFormat[],
712 	dml_float_t ReadBandwidthLuma[],
713 	dml_float_t ReadBandwidthChroma[],
714 	dml_uint_t RotesY[],
715 	dml_uint_t RoundedUpMaxSwathSizeBytesC[],
716 	dml_uint_t DPPPerSurface[],
717 	// Output
718 	dml_uint_t DETBufferSizeInKByte[],
719 	dml_uint_t *CompressedBufferSizeInkByte);
720 
721 static void CalculateMaxDETAndMinCompressedBufferSize(
722 	dml_uint_t ConfigReturnBufferSizeInKByte,
723 	dml_uint_t ConfigReturnBufferSegmentSizeInKByte,
724 	dml_uint_t ROBBufferSizeInKByte,
725 	dml_uint_t MaxNumDPP,
726 	dml_bool_t nomDETInKByteOverrideEnable,
727 	dml_uint_t nomDETInKByteOverrideValue,
728 
729 	// Output
730 	dml_uint_t *MaxTotalDETInKByte,
731 	dml_uint_t *nomDETInKByte,
732 	dml_uint_t *MinCompressedBufferSizeInKByte);
733 
734 static dml_uint_t DSCDelayRequirement(
735 	dml_bool_t DSCEnabled,
736 	enum dml_odm_mode ODMMode,
737 	dml_uint_t DSCInputBitPerComponent,
738 	dml_float_t OutputBpp,
739 	dml_uint_t HActive,
740 	dml_uint_t HTotal,
741 	dml_uint_t NumberOfDSCSlices,
742 	enum dml_output_format_class OutputFormat,
743 	enum dml_output_encoder_class Output,
744 	dml_float_t PixelClock,
745 	dml_float_t PixelClockBackEnd);
746 
747 static dml_bool_t CalculateVActiveBandwithSupport(
748 	dml_uint_t NumberOfActiveSurfaces,
749 	dml_float_t ReturnBW,
750 	dml_bool_t NotUrgentLatencyHiding[],
751 	dml_float_t ReadBandwidthLuma[],
752 	dml_float_t ReadBandwidthChroma[],
753 	dml_float_t cursor_bw[],
754 	dml_float_t meta_row_bandwidth[],
755 	dml_float_t dpte_row_bandwidth[],
756 	dml_uint_t NumberOfDPP[],
757 	dml_float_t UrgentBurstFactorLuma[],
758 	dml_float_t UrgentBurstFactorChroma[],
759 	dml_float_t UrgentBurstFactorCursor[]);
760 
761 static void CalculatePrefetchBandwithSupport(
762 	dml_uint_t NumberOfActiveSurfaces,
763 	dml_float_t ReturnBW,
764 	enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
765 	dml_bool_t NotUrgentLatencyHiding[],
766 	dml_float_t ReadBandwidthLuma[],
767 	dml_float_t ReadBandwidthChroma[],
768 	dml_float_t PrefetchBandwidthLuma[],
769 	dml_float_t PrefetchBandwidthChroma[],
770 	dml_float_t cursor_bw[],
771 	dml_float_t meta_row_bandwidth[],
772 	dml_float_t dpte_row_bandwidth[],
773 	dml_float_t cursor_bw_pre[],
774 	dml_float_t prefetch_vmrow_bw[],
775 	dml_uint_t NumberOfDPP[],
776 	dml_float_t UrgentBurstFactorLuma[],
777 	dml_float_t UrgentBurstFactorChroma[],
778 	dml_float_t UrgentBurstFactorCursor[],
779 	dml_float_t UrgentBurstFactorLumaPre[],
780 	dml_float_t UrgentBurstFactorChromaPre[],
781 	dml_float_t UrgentBurstFactorCursorPre[],
782 
783 	// Output
784 	dml_float_t *PrefetchBandwidth,
785 	dml_float_t *PrefetchBandwidthNotIncludingMALLPrefetch,
786 	dml_float_t *FractionOfUrgentBandwidth,
787 	dml_bool_t *PrefetchBandwidthSupport);
788 
789 static dml_float_t CalculateBandwidthAvailableForImmediateFlip(
790 	dml_uint_t NumberOfActiveSurfaces,
791 	dml_float_t ReturnBW,
792 	dml_float_t ReadBandwidthLuma[],
793 	dml_float_t ReadBandwidthChroma[],
794 	dml_float_t PrefetchBandwidthLuma[],
795 	dml_float_t PrefetchBandwidthChroma[],
796 	dml_float_t cursor_bw[],
797 	dml_float_t cursor_bw_pre[],
798 	dml_uint_t NumberOfDPP[],
799 	dml_float_t UrgentBurstFactorLuma[],
800 	dml_float_t UrgentBurstFactorChroma[],
801 	dml_float_t UrgentBurstFactorCursor[],
802 	dml_float_t UrgentBurstFactorLumaPre[],
803 	dml_float_t UrgentBurstFactorChromaPre[],
804 	dml_float_t UrgentBurstFactorCursorPre[]);
805 
806 static void CalculateImmediateFlipBandwithSupport(
807 	dml_uint_t NumberOfActiveSurfaces,
808 	dml_float_t ReturnBW,
809 	enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
810 	enum dml_immediate_flip_requirement ImmediateFlipRequirement[],
811 	dml_float_t final_flip_bw[],
812 	dml_float_t ReadBandwidthLuma[],
813 	dml_float_t ReadBandwidthChroma[],
814 	dml_float_t PrefetchBandwidthLuma[],
815 	dml_float_t PrefetchBandwidthChroma[],
816 	dml_float_t cursor_bw[],
817 	dml_float_t meta_row_bandwidth[],
818 	dml_float_t dpte_row_bandwidth[],
819 	dml_float_t cursor_bw_pre[],
820 	dml_float_t prefetch_vmrow_bw[],
821 	dml_uint_t NumberOfDPP[],
822 	dml_float_t UrgentBurstFactorLuma[],
823 	dml_float_t UrgentBurstFactorChroma[],
824 	dml_float_t UrgentBurstFactorCursor[],
825 	dml_float_t UrgentBurstFactorLumaPre[],
826 	dml_float_t UrgentBurstFactorChromaPre[],
827 	dml_float_t UrgentBurstFactorCursorPre[],
828 
829 	// Output
830 	dml_float_t *TotalBandwidth,
831 	dml_float_t *TotalBandwidthNotIncludingMALLPrefetch,
832 	dml_float_t *FractionOfUrgentBandwidth,
833 	dml_bool_t *ImmediateFlipBandwidthSupport);
834 
835 // ---------------------------
836 //  Declaration Ends
837 // ---------------------------
838 
dscceComputeDelay(dml_uint_t bpc,dml_float_t BPP,dml_uint_t sliceWidth,dml_uint_t numSlices,enum dml_output_format_class pixelFormat,enum dml_output_encoder_class Output)839 static dml_uint_t dscceComputeDelay(
840 	dml_uint_t bpc,
841 	dml_float_t BPP,
842 	dml_uint_t sliceWidth,
843 	dml_uint_t numSlices,
844 	enum dml_output_format_class pixelFormat,
845 	enum dml_output_encoder_class Output)
846 {
847 	// valid bpc = source bits per component in the set of {8, 10, 12}
848 	// valid bpp = increments of 1/16 of a bit
849 	// min = 6/7/8 in N420/N422/444, respectively
850 	// max = such that compression is 1:1
851 	//valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
852 	//valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
853 	//valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
854 
855 	// fixed value
856 	dml_uint_t rcModelSize = 8192;
857 
858 	// N422/N420 operate at 2 pixels per clock
859 	dml_uint_t pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, L,
860 		Delay, pixels;
861 
862 	if (pixelFormat == dml_420)
863 		pixelsPerClock = 2;
864 	// #all other modes operate at 1 pixel per clock
865 	else if (pixelFormat == dml_444)
866 		pixelsPerClock = 1;
867 	else if (pixelFormat == dml_n422)
868 		pixelsPerClock = 2;
869 	else
870 		pixelsPerClock = 1;
871 
872 	//initial transmit delay as per PPS
873 	initalXmitDelay = (dml_uint_t)(dml_round(rcModelSize / 2.0 / BPP / pixelsPerClock, 1));
874 
875 	//compute ssm delay
876 	if (bpc == 8)
877 		D = 81;
878 	else if (bpc == 10)
879 		D = 89;
880 	else
881 		D = 113;
882 
883 	//divide by pixel per cycle to compute slice width as seen by DSC
884 	w = sliceWidth / pixelsPerClock;
885 
886 	//422 mode has an additional cycle of delay
887 	if (pixelFormat == dml_420 || pixelFormat == dml_444 || pixelFormat == dml_n422)
888 		s = 0;
889 	else
890 		s = 1;
891 
892 	//main calculation for the dscce
893 	ix = initalXmitDelay + 45;
894 	wx = (w + 2) / 3;
895 	p = 3 * wx - w;
896 	l0 = ix / w;
897 	a = ix + p * l0;
898 	ax = (a + 2) / 3 + D + 6 + 1;
899 	L = (ax + wx - 1) / wx;
900 	if ((ix % w) == 0 && p != 0)
901 		lstall = 1;
902 	else
903 		lstall = 0;
904 	Delay = L * wx * (numSlices - 1) + ax + s + lstall + 22;
905 
906 	//dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
907 	pixels = Delay * 3 * pixelsPerClock;
908 
909 #ifdef __DML_VBA_DEBUG__
910 	dml_print("DML::%s: bpc: %u\n", __func__, bpc);
911 	dml_print("DML::%s: BPP: %f\n", __func__, BPP);
912 	dml_print("DML::%s: sliceWidth: %u\n", __func__, sliceWidth);
913 	dml_print("DML::%s: numSlices: %u\n", __func__, numSlices);
914 	dml_print("DML::%s: pixelFormat: %u\n", __func__, pixelFormat);
915 	dml_print("DML::%s: Output: %u\n", __func__, Output);
916 	dml_print("DML::%s: pixels: %u\n", __func__, pixels);
917 #endif
918 	return pixels;
919 }
920 
dscComputeDelay(enum dml_output_format_class pixelFormat,enum dml_output_encoder_class Output)921 static dml_uint_t dscComputeDelay(enum dml_output_format_class pixelFormat, enum dml_output_encoder_class Output)
922 {
923 	dml_uint_t Delay = 0;
924 
925 	if (pixelFormat == dml_420) {
926 		// sfr
927 		Delay = Delay + 2;
928 		// dsccif
929 		Delay = Delay + 0;
930 		// dscc - input deserializer
931 		Delay = Delay + 3;
932 		// dscc gets pixels every other cycle
933 		Delay = Delay + 2;
934 		// dscc - input cdc fifo
935 		Delay = Delay + 12;
936 		// dscc gets pixels every other cycle
937 		Delay = Delay + 13;
938 		// dscc - cdc uncertainty
939 		Delay = Delay + 2;
940 		// dscc - output cdc fifo
941 		Delay = Delay + 7;
942 		// dscc gets pixels every other cycle
943 		Delay = Delay + 3;
944 		// dscc - cdc uncertainty
945 		Delay = Delay + 2;
946 		// dscc - output serializer
947 		Delay = Delay + 1;
948 		// sft
949 		Delay = Delay + 1;
950 	} else if (pixelFormat == dml_n422) {
951 	// sfr
952 	Delay = Delay + 2;
953 	// dsccif
954 	Delay = Delay + 1;
955 	// dscc - input deserializer
956 	Delay = Delay + 5;
957 	// dscc - input cdc fifo
958 	Delay = Delay + 25;
959 	// dscc - cdc uncertainty
960 	Delay = Delay + 2;
961 	// dscc - output cdc fifo
962 	Delay = Delay + 10;
963 	// dscc - cdc uncertainty
964 	Delay = Delay + 2;
965 	// dscc - output serializer
966 	Delay = Delay + 1;
967 	// sft
968 	Delay = Delay + 1;
969 	} else {
970 	// sfr
971 	Delay = Delay + 2;
972 	// dsccif
973 	Delay = Delay + 0;
974 	// dscc - input deserializer
975 	Delay = Delay + 3;
976 	// dscc - input cdc fifo
977 	Delay = Delay + 12;
978 	// dscc - cdc uncertainty
979 	Delay = Delay + 2;
980 	// dscc - output cdc fifo
981 	Delay = Delay + 7;
982 	// dscc - output serializer
983 	Delay = Delay + 1;
984 	// dscc - cdc uncertainty
985 	Delay = Delay + 2;
986 	// sft
987 	Delay = Delay + 1;
988 	}
989 #ifdef __DML_VBA_DEBUG__
990 	dml_print("DML::%s: pixelFormat = %u\n", __func__, pixelFormat);
991 	dml_print("DML::%s: Delay = %u\n", __func__, Delay);
992 #endif
993 
994 	return Delay;
995 }
996 
CalculatePrefetchSchedule(struct display_mode_lib_scratch_st * scratch,struct CalculatePrefetchSchedule_params_st * p)997 static dml_bool_t CalculatePrefetchSchedule(struct display_mode_lib_scratch_st *scratch,
998 	struct CalculatePrefetchSchedule_params_st *p)
999 {
1000 	struct CalculatePrefetchSchedule_locals_st *s = &scratch->CalculatePrefetchSchedule_locals;
1001 
1002 	s->MyError = false;
1003 	s->DPPCycles = 0;
1004 	s->DISPCLKCycles = 0;
1005 	s->DSTTotalPixelsAfterScaler = 0.0;
1006 	s->LineTime = 0.0;
1007 	s->dst_y_prefetch_equ = 0.0;
1008 	s->prefetch_bw_oto = 0.0;
1009 	s->Tvm_oto = 0.0;
1010 	s->Tr0_oto = 0.0;
1011 	s->Tvm_oto_lines = 0.0;
1012 	s->Tr0_oto_lines = 0.0;
1013 	s->dst_y_prefetch_oto = 0.0;
1014 	s->TimeForFetchingMetaPTE = 0.0;
1015 	s->TimeForFetchingRowInVBlank = 0.0;
1016 	s->LinesToRequestPrefetchPixelData = 0.0;
1017 	s->HostVMDynamicLevelsTrips = 0;
1018 	s->trip_to_mem = 0.0;
1019 	s->Tvm_trips = 0.0;
1020 	s->Tr0_trips = 0.0;
1021 	s->Tvm_trips_rounded = 0.0;
1022 	s->Tr0_trips_rounded = 0.0;
1023 	s->max_Tsw = 0.0;
1024 	s->Lsw_oto = 0.0;
1025 	s->Tpre_rounded = 0.0;
1026 	s->prefetch_bw_equ = 0.0;
1027 	s->Tvm_equ = 0.0;
1028 	s->Tr0_equ = 0.0;
1029 	s->Tdmbf = 0.0;
1030 	s->Tdmec = 0.0;
1031 	s->Tdmsks = 0.0;
1032 	s->prefetch_sw_bytes = 0.0;
1033 	s->prefetch_bw_pr = 0.0;
1034 	s->bytes_pp = 0.0;
1035 	s->dep_bytes = 0.0;
1036 	s->min_Lsw_oto = 0.0;
1037 	s->Tsw_est1 = 0.0;
1038 	s->Tsw_est3 = 0.0;
1039 
1040 	if (p->GPUVMEnable == true && p->HostVMEnable == true) {
1041 		s->HostVMDynamicLevelsTrips = p->HostVMMaxNonCachedPageTableLevels;
1042 	} else {
1043 		s->HostVMDynamicLevelsTrips = 0;
1044 	}
1045 #ifdef __DML_VBA_DEBUG__
1046 	dml_print("DML::%s: GPUVMEnable = %u\n", __func__, p->GPUVMEnable);
1047 	dml_print("DML::%s: GPUVMPageTableLevels = %u\n", __func__, p->GPUVMPageTableLevels);
1048 	dml_print("DML::%s: DCCEnable = %u\n", __func__, p->myPipe->DCCEnable);
1049 	dml_print("DML::%s: VStartup = %u\n", __func__, p->VStartup);
1050 	dml_print("DML::%s: MaxVStartup = %u\n", __func__, p->MaxVStartup);
1051 	dml_print("DML::%s: HostVMEnable = %u\n", __func__, p->HostVMEnable);
1052 	dml_print("DML::%s: HostVMInefficiencyFactor= %f\n", __func__, p->HostVMInefficiencyFactor);
1053 	dml_print("DML::%s: myPipe->Dppclk = %f\n", __func__, p->myPipe->Dppclk);
1054 #endif
1055 	CalculateVUpdateAndDynamicMetadataParameters(
1056 	p->MaxInterDCNTileRepeaters,
1057 	p->myPipe->Dppclk,
1058 	p->myPipe->Dispclk,
1059 	p->myPipe->DCFClkDeepSleep,
1060 	p->myPipe->PixelClock,
1061 	p->myPipe->HTotal,
1062 	p->myPipe->VBlank,
1063 	p->DynamicMetadataTransmittedBytes,
1064 	p->DynamicMetadataLinesBeforeActiveRequired,
1065 	p->myPipe->InterlaceEnable,
1066 	p->myPipe->ProgressiveToInterlaceUnitInOPP,
1067 	p->TSetup,
1068 
1069 	// Output
1070 	&s->Tdmbf,
1071 	&s->Tdmec,
1072 	&s->Tdmsks,
1073 	p->VUpdateOffsetPix,
1074 	p->VUpdateWidthPix,
1075 	p->VReadyOffsetPix);
1076 
1077 	s->LineTime = p->myPipe->HTotal / p->myPipe->PixelClock;
1078 	s->trip_to_mem = p->UrgentLatency;
1079 	s->Tvm_trips = p->UrgentExtraLatency + s->trip_to_mem * (p->GPUVMPageTableLevels * (s->HostVMDynamicLevelsTrips + 1) - 1);
1080 
1081 	if (p->DynamicMetadataVMEnabled == true) {
1082 		*p->Tdmdl = p->TWait + s->Tvm_trips + s->trip_to_mem;
1083 	} else {
1084 		*p->Tdmdl = p->TWait + p->UrgentExtraLatency;
1085 	}
1086 
1087 #ifdef __DML_VBA_ALLOW_DELTA__
1088 	if (DynamicMetadataEnable == false) {
1089 		*Tdmdl = 0.0;
1090 	}
1091 #endif
1092 
1093 	if (p->DynamicMetadataEnable == true) {
1094 		if (p->VStartup * s->LineTime < *p->TSetup + *p->Tdmdl + s->Tdmbf + s->Tdmec + s->Tdmsks) {
1095 			*p->NotEnoughTimeForDynamicMetadata = true;
1096 			dml_print("DML::%s: Not Enough Time for Dynamic Meta!\n", __func__);
1097 			dml_print("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, s->Tdmbf);
1098 			dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, s->Tdmec);
1099 			dml_print("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, s->Tdmsks);
1100 			dml_print("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", __func__, *p->Tdmdl);
1101 		} else {
1102 			*p->NotEnoughTimeForDynamicMetadata = false;
1103 		}
1104 	} else {
1105 		*p->NotEnoughTimeForDynamicMetadata = false;
1106 	}
1107 
1108 	*p->Tdmdl_vm = (p->DynamicMetadataEnable == true && p->DynamicMetadataVMEnabled == true && p->GPUVMEnable == true ? p->TWait + s->Tvm_trips : 0);
1109 
1110 	if (p->myPipe->ScalerEnabled)
1111 		s->DPPCycles = (dml_uint_t)(p->DPPCLKDelaySubtotalPlusCNVCFormater + p->DPPCLKDelaySCL);
1112 	else
1113 		s->DPPCycles = (dml_uint_t)(p->DPPCLKDelaySubtotalPlusCNVCFormater + p->DPPCLKDelaySCLLBOnly);
1114 
1115 	s->DPPCycles = (dml_uint_t)(s->DPPCycles + p->myPipe->NumberOfCursors * p->DPPCLKDelayCNVCCursor);
1116 
1117 	s->DISPCLKCycles = (dml_uint_t)p->DISPCLKDelaySubtotal;
1118 
1119 	if (p->myPipe->Dppclk == 0.0 || p->myPipe->Dispclk == 0.0)
1120 		return true;
1121 
1122 	*p->DSTXAfterScaler = (dml_uint_t) dml_round(s->DPPCycles * p->myPipe->PixelClock / p->myPipe->Dppclk + s->DISPCLKCycles * p->myPipe->PixelClock / p->myPipe->Dispclk + p->DSCDelay, 1.0);
1123 	*p->DSTXAfterScaler = (dml_uint_t) dml_round(*p->DSTXAfterScaler + (p->myPipe->ODMMode != dml_odm_mode_bypass ? 18 : 0) + (p->myPipe->DPPPerSurface - 1) * p->DPP_RECOUT_WIDTH +
1124 						((p->myPipe->ODMMode == dml_odm_mode_split_1to2 || p->myPipe->ODMMode == dml_odm_mode_mso_1to2) ? (dml_float_t)p->myPipe->HActive / 2.0 : 0) +
1125 						((p->myPipe->ODMMode == dml_odm_mode_mso_1to4) ? (dml_float_t)p->myPipe->HActive * 3.0 / 4.0 : 0), 1.0);
1126 
1127 #ifdef __DML_VBA_DEBUG__
1128 	dml_print("DML::%s: DPPCycles = %u\n", __func__, s->DPPCycles);
1129 	dml_print("DML::%s: PixelClock = %f\n", __func__, p->myPipe->PixelClock);
1130 	dml_print("DML::%s: Dppclk = %f\n", __func__, p->myPipe->Dppclk);
1131 	dml_print("DML::%s: DISPCLKCycles = %u\n", __func__, s->DISPCLKCycles);
1132 	dml_print("DML::%s: DISPCLK = %f\n", __func__, p->myPipe->Dispclk);
1133 	dml_print("DML::%s: DSCDelay = %u\n", __func__, p->DSCDelay);
1134 	dml_print("DML::%s: ODMMode = %u\n", __func__, p->myPipe->ODMMode);
1135 	dml_print("DML::%s: DPP_RECOUT_WIDTH = %u\n", __func__, p->DPP_RECOUT_WIDTH);
1136 	dml_print("DML::%s: DSTXAfterScaler = %u\n", __func__, *p->DSTXAfterScaler);
1137 #endif
1138 
1139 	if (p->OutputFormat == dml_420 || (p->myPipe->InterlaceEnable && p->myPipe->ProgressiveToInterlaceUnitInOPP))
1140 		*p->DSTYAfterScaler = 1;
1141 	else
1142 		*p->DSTYAfterScaler = 0;
1143 
1144 	s->DSTTotalPixelsAfterScaler = *p->DSTYAfterScaler * p->myPipe->HTotal + *p->DSTXAfterScaler;
1145 	*p->DSTYAfterScaler = (dml_uint_t)(dml_floor(s->DSTTotalPixelsAfterScaler / p->myPipe->HTotal, 1));
1146 	*p->DSTXAfterScaler = (dml_uint_t)(s->DSTTotalPixelsAfterScaler - ((dml_float_t) (*p->DSTYAfterScaler * p->myPipe->HTotal)));
1147 #ifdef __DML_VBA_DEBUG__
1148 	dml_print("DML::%s: DSTXAfterScaler = %u (final)\n", __func__,  *p->DSTXAfterScaler);
1149 	dml_print("DML::%s: DSTYAfterScaler = %u (final)\n", __func__, *p->DSTYAfterScaler);
1150 #endif
1151 
1152 	s->MyError = false;
1153 
1154 	s->Tr0_trips = s->trip_to_mem * (s->HostVMDynamicLevelsTrips + 1);
1155 
1156 	if (p->GPUVMEnable == true) {
1157 		s->Tvm_trips_rounded = dml_ceil(4.0 * s->Tvm_trips / s->LineTime, 1.0) / 4.0 * s->LineTime;
1158 		s->Tr0_trips_rounded = dml_ceil(4.0 * s->Tr0_trips / s->LineTime, 1.0) / 4.0 * s->LineTime;
1159 		if (p->GPUVMPageTableLevels >= 3) {
1160 			*p->Tno_bw = p->UrgentExtraLatency + s->trip_to_mem * (dml_float_t) ((p->GPUVMPageTableLevels - 2) * (s->HostVMDynamicLevelsTrips + 1) - 1);
1161 	} else if (p->GPUVMPageTableLevels == 1 && p->myPipe->DCCEnable != true) {
1162 			s->Tr0_trips_rounded = dml_ceil(4.0 * p->UrgentExtraLatency / s->LineTime, 1.0) / 4.0 * s->LineTime;
1163 			*p->Tno_bw = p->UrgentExtraLatency;
1164 		} else {
1165 			*p->Tno_bw = 0;
1166 		}
1167 	} else if (p->myPipe->DCCEnable == true) {
1168 		s->Tvm_trips_rounded = s->LineTime / 4.0;
1169 		s->Tr0_trips_rounded = dml_ceil(4.0 * s->Tr0_trips / s->LineTime, 1.0) / 4.0 * s->LineTime;
1170 		*p->Tno_bw = 0;
1171 	} else {
1172 		s->Tvm_trips_rounded = s->LineTime / 4.0;
1173 		s->Tr0_trips_rounded = s->LineTime / 2.0;
1174 		*p->Tno_bw = 0;
1175 	}
1176 	s->Tvm_trips_rounded = dml_max(s->Tvm_trips_rounded, s->LineTime / 4.0);
1177 	s->Tr0_trips_rounded = dml_max(s->Tr0_trips_rounded, s->LineTime / 4.0);
1178 
1179 	if (p->myPipe->SourcePixelFormat == dml_420_8 || p->myPipe->SourcePixelFormat == dml_420_10 || p->myPipe->SourcePixelFormat == dml_420_12) {
1180 		s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC / 4;
1181 	} else {
1182 		s->bytes_pp = p->myPipe->BytePerPixelY + p->myPipe->BytePerPixelC;
1183 	}
1184 
1185 	s->prefetch_bw_pr = s->bytes_pp * p->myPipe->PixelClock / (dml_float_t)p->myPipe->DPPPerSurface;
1186 	if (p->myPipe->VRatio < 1.0)
1187 		s->prefetch_bw_pr = p->myPipe->VRatio * s->prefetch_bw_pr;
1188 
1189 	s->max_Tsw = (dml_max(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) * s->LineTime);
1190 
1191 	s->prefetch_sw_bytes = p->PrefetchSourceLinesY * p->swath_width_luma_ub * p->myPipe->BytePerPixelY + p->PrefetchSourceLinesC * p->swath_width_chroma_ub * p->myPipe->BytePerPixelC;
1192 	s->prefetch_bw_oto = dml_max(s->prefetch_bw_pr, s->prefetch_sw_bytes / s->max_Tsw);
1193 
1194 	s->min_Lsw_oto = dml_max(p->PrefetchSourceLinesY, p->PrefetchSourceLinesC) / __DML_MAX_VRATIO_PRE_OTO__;
1195 	s->min_Lsw_oto = dml_max(s->min_Lsw_oto, 1.0);
1196 	s->Lsw_oto = dml_ceil(4.0 * dml_max(s->prefetch_sw_bytes / s->prefetch_bw_oto / s->LineTime, s->min_Lsw_oto), 1.0) / 4.0;
1197 
1198 	if (p->GPUVMEnable == true) {
1199 		s->Tvm_oto = dml_max3(
1200 			s->Tvm_trips,
1201 			*p->Tno_bw + p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor / s->prefetch_bw_oto,
1202 			s->LineTime / 4.0);
1203 	} else
1204 		s->Tvm_oto = s->LineTime / 4.0;
1205 
1206 	if ((p->GPUVMEnable == true || p->myPipe->DCCEnable == true)) {
1207 		s->Tr0_oto = dml_max4(
1208 			s->Tr0_trips,
1209 			(p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / s->prefetch_bw_oto,
1210 			(s->LineTime - s->Tvm_oto)/2.0,
1211 			s->LineTime / 4.0);
1212 #ifdef __DML_VBA_DEBUG__
1213 	dml_print("DML::%s: Tr0_oto max0 = %f\n", __func__, (p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / s->prefetch_bw_oto);
1214 	dml_print("DML::%s: Tr0_oto max1 = %f\n", __func__, s->Tr0_trips);
1215 	dml_print("DML::%s: Tr0_oto max2 = %f\n", __func__, s->LineTime - s->Tvm_oto);
1216 	dml_print("DML::%s: Tr0_oto max3 = %f\n", __func__, s->LineTime / 4);
1217 #endif
1218 	} else
1219 		s->Tr0_oto = (s->LineTime - s->Tvm_oto) / 2.0;
1220 
1221 	s->Tvm_oto_lines = dml_ceil(4.0 * s->Tvm_oto / s->LineTime, 1) / 4.0;
1222 	s->Tr0_oto_lines = dml_ceil(4.0 * s->Tr0_oto / s->LineTime, 1) / 4.0;
1223 	s->dst_y_prefetch_oto = s->Tvm_oto_lines + 2 * s->Tr0_oto_lines + s->Lsw_oto;
1224 
1225 	s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + dml_max(p->TWait + p->TCalc, *p->Tdmdl)) / s->LineTime - (*p->DSTYAfterScaler + (dml_float_t) *p->DSTXAfterScaler / (dml_float_t)p->myPipe->HTotal);
1226 	s->dst_y_prefetch_equ = dml_min(s->dst_y_prefetch_equ, 63.75); // limit to the reg limit of U6.2 for DST_Y_PREFETCH
1227 
1228 #ifdef __DML_VBA_DEBUG__
1229 	dml_print("DML::%s: HTotal = %u\n", __func__, p->myPipe->HTotal);
1230 	dml_print("DML::%s: min_Lsw_oto = %f\n", __func__, s->min_Lsw_oto);
1231 	dml_print("DML::%s: *Tno_bw = %f\n", __func__, *p->Tno_bw);
1232 	dml_print("DML::%s: UrgentExtraLatency = %f\n", __func__, p->UrgentExtraLatency);
1233 	dml_print("DML::%s: trip_to_mem = %f\n", __func__, s->trip_to_mem);
1234 	dml_print("DML::%s: BytePerPixelY = %u\n", __func__, p->myPipe->BytePerPixelY);
1235 	dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY);
1236 	dml_print("DML::%s: swath_width_luma_ub = %u\n", __func__, p->swath_width_luma_ub);
1237 	dml_print("DML::%s: BytePerPixelC = %u\n", __func__, p->myPipe->BytePerPixelC);
1238 	dml_print("DML::%s: PrefetchSourceLinesC = %f\n", __func__, p->PrefetchSourceLinesC);
1239 	dml_print("DML::%s: swath_width_chroma_ub = %u\n", __func__, p->swath_width_chroma_ub);
1240 	dml_print("DML::%s: prefetch_sw_bytes = %f\n", __func__, s->prefetch_sw_bytes);
1241 	dml_print("DML::%s: bytes_pp = %f\n", __func__, s->bytes_pp);
1242 	dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %u\n", __func__, p->PDEAndMetaPTEBytesFrame);
1243 	dml_print("DML::%s: MetaRowByte = %u\n", __func__, p->MetaRowByte);
1244 	dml_print("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow);
1245 	dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
1246 	dml_print("DML::%s: Tvm_trips = %f\n", __func__, s->Tvm_trips);
1247 	dml_print("DML::%s: Tr0_trips = %f\n", __func__, s->Tr0_trips);
1248 	dml_print("DML::%s: prefetch_bw_oto = %f\n", __func__, s->prefetch_bw_oto);
1249 	dml_print("DML::%s: Tr0_oto = %f\n", __func__, s->Tr0_oto);
1250 	dml_print("DML::%s: Tvm_oto = %f\n", __func__, s->Tvm_oto);
1251 	dml_print("DML::%s: Tvm_oto_lines = %f\n", __func__, s->Tvm_oto_lines);
1252 	dml_print("DML::%s: Tr0_oto_lines = %f\n", __func__, s->Tr0_oto_lines);
1253 	dml_print("DML::%s: Lsw_oto = %f\n", __func__, s->Lsw_oto);
1254 	dml_print("DML::%s: dst_y_prefetch_oto = %f\n", __func__, s->dst_y_prefetch_oto);
1255 	dml_print("DML::%s: dst_y_prefetch_equ = %f\n", __func__, s->dst_y_prefetch_equ);
1256 #endif
1257 
1258 	s->dst_y_prefetch_equ = dml_floor(4.0 * (s->dst_y_prefetch_equ + 0.125), 1) / 4.0;
1259 	s->Tpre_rounded = s->dst_y_prefetch_equ * s->LineTime;
1260 
1261 	dml_print("DML::%s: dst_y_prefetch_equ: %f (after round)\n", __func__, s->dst_y_prefetch_equ);
1262 
1263 	dml_print("DML::%s: LineTime: %f\n", __func__, s->LineTime);
1264 	dml_print("DML::%s: VStartup: %u\n", __func__, p->VStartup);
1265 	dml_print("DML::%s: Tvstartup: %fus - time between vstartup and first pixel of active\n", __func__, p->VStartup * s->LineTime);
1266 	dml_print("DML::%s: TSetup: %fus - time from vstartup to vready\n", __func__, *p->TSetup);
1267 	dml_print("DML::%s: TCalc: %fus - time for calculations in dchub starting at vready\n", __func__, p->TCalc);
1268 	dml_print("DML::%s: TWait: %fus - time for fabric to become ready max(pstate exit,cstate enter/exit, urgent latency) after TCalc\n", __func__, p->TWait);
1269 	dml_print("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, s->Tdmbf);
1270 	dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, s->Tdmec);
1271 	dml_print("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, s->Tdmsks);
1272 	dml_print("DML::%s: Tdmdl_vm: %fus - time for vm stages of dmd \n", __func__, *p->Tdmdl_vm);
1273 	dml_print("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", __func__, *p->Tdmdl);
1274 	dml_print("DML::%s: DSTXAfterScaler: %u pixels - number of pixel clocks pipeline and buffer delay after scaler \n", __func__, *p->DSTXAfterScaler);
1275 	dml_print("DML::%s: DSTYAfterScaler: %u lines - number of lines of pipeline and buffer delay after scaler \n", __func__, *p->DSTYAfterScaler);
1276 
1277 	s->dep_bytes = dml_max(p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor, p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor);
1278 
1279 	if (s->prefetch_sw_bytes < s->dep_bytes) {
1280 		s->prefetch_sw_bytes = 2 * s->dep_bytes;
1281 	}
1282 
1283 	*p->DestinationLinesToRequestVMInVBlank = 0;
1284 	*p->DestinationLinesToRequestRowInVBlank = 0;
1285 	*p->VRatioPrefetchY = 0;
1286 	*p->VRatioPrefetchC = 0;
1287 	*p->RequiredPrefetchPixDataBWLuma = 0;
1288 	if (s->dst_y_prefetch_equ > 1) {
1289 
1290 		if (s->Tpre_rounded - *p->Tno_bw > 0) {
1291 		s->PrefetchBandwidth1 = (p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor + 2 * p->MetaRowByte
1292 					+ 2 * p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor
1293 					+ s->prefetch_sw_bytes)
1294 					/ (s->Tpre_rounded - *p->Tno_bw);
1295 			s->Tsw_est1 = s->prefetch_sw_bytes / s->PrefetchBandwidth1;
1296 		} else
1297 			s->PrefetchBandwidth1 = 0;
1298 
1299 		if (p->VStartup == p->MaxVStartup && (s->Tsw_est1 / s->LineTime < s->min_Lsw_oto) && s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw > 0) {
1300 			s->PrefetchBandwidth1 = (p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor + 2 * p->MetaRowByte + 2 * p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) /
1301 								(s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.75 * s->LineTime - *p->Tno_bw);
1302 		}
1303 
1304 		if (s->Tpre_rounded - *p->Tno_bw - 2 * s->Tr0_trips_rounded > 0)
1305 			s->PrefetchBandwidth2 = (p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor + s->prefetch_sw_bytes) /
1306 									(s->Tpre_rounded - *p->Tno_bw - 2 * s->Tr0_trips_rounded);
1307 		else
1308 			s->PrefetchBandwidth2 = 0;
1309 
1310 		if (s->Tpre_rounded - s->Tvm_trips_rounded > 0) {
1311 			s->PrefetchBandwidth3 = (2 * p->MetaRowByte + 2 * p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor + s->prefetch_sw_bytes) /
1312 									(s->Tpre_rounded - s->Tvm_trips_rounded);
1313 			s->Tsw_est3 = s->prefetch_sw_bytes / s->PrefetchBandwidth3;
1314 	}
1315 		else
1316 			s->PrefetchBandwidth3 = 0;
1317 
1318 
1319 		if (p->VStartup == p->MaxVStartup && (s->Tsw_est3 / s->LineTime < s->min_Lsw_oto) && s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded > 0) {
1320 			s->PrefetchBandwidth3 = (2 * p->MetaRowByte + 2 * p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / (s->Tpre_rounded - s->min_Lsw_oto * s->LineTime - 0.5 * s->LineTime - s->Tvm_trips_rounded);
1321 		}
1322 
1323 		if (s->Tpre_rounded - s->Tvm_trips_rounded - 2 * s->Tr0_trips_rounded > 0)
1324 			s->PrefetchBandwidth4 = s->prefetch_sw_bytes / (s->Tpre_rounded - s->Tvm_trips_rounded - 2 * s->Tr0_trips_rounded);
1325 		else
1326 			s->PrefetchBandwidth4 = 0;
1327 
1328 #ifdef __DML_VBA_DEBUG__
1329 		dml_print("DML::%s: Tpre_rounded: %f\n", __func__, s->Tpre_rounded);
1330 		dml_print("DML::%s: Tno_bw: %f\n", __func__, *p->Tno_bw);
1331 		dml_print("DML::%s: Tvm_trips_rounded: %f\n", __func__, s->Tvm_trips_rounded);
1332 		dml_print("DML::%s: Tsw_est1: %f\n", __func__, s->Tsw_est1);
1333 		dml_print("DML::%s: Tsw_est3: %f\n", __func__, s->Tsw_est3);
1334 		dml_print("DML::%s: PrefetchBandwidth1: %f\n", __func__, s->PrefetchBandwidth1);
1335 		dml_print("DML::%s: PrefetchBandwidth2: %f\n", __func__, s->PrefetchBandwidth2);
1336 		dml_print("DML::%s: PrefetchBandwidth3: %f\n", __func__, s->PrefetchBandwidth3);
1337 		dml_print("DML::%s: PrefetchBandwidth4: %f\n", __func__, s->PrefetchBandwidth4);
1338 #endif
1339 		{
1340 			dml_bool_t Case1OK;
1341 			dml_bool_t Case2OK;
1342 			dml_bool_t Case3OK;
1343 
1344 			if (s->PrefetchBandwidth1 > 0) {
1345 				if (*p->Tno_bw + p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor / s->PrefetchBandwidth1 >= s->Tvm_trips_rounded && (p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / s->PrefetchBandwidth1 >= s->Tr0_trips_rounded) {
1346 					Case1OK = true;
1347 				} else {
1348 					Case1OK = false;
1349 				}
1350 			} else {
1351 				Case1OK = false;
1352 			}
1353 
1354 			if (s->PrefetchBandwidth2 > 0) {
1355 				if (*p->Tno_bw + p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor / s->PrefetchBandwidth2 >= s->Tvm_trips_rounded && (p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / s->PrefetchBandwidth2 < s->Tr0_trips_rounded) {
1356 					Case2OK = true;
1357 				} else {
1358 					Case2OK = false;
1359 				}
1360 			} else {
1361 				Case2OK = false;
1362 			}
1363 
1364 			if (s->PrefetchBandwidth3 > 0) {
1365 				if (*p->Tno_bw + p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor / s->PrefetchBandwidth3 < s->Tvm_trips_rounded && (p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / s->PrefetchBandwidth3 >= s->Tr0_trips_rounded) {
1366 					Case3OK = true;
1367 				} else {
1368 					Case3OK = false;
1369 				}
1370 			} else {
1371 				Case3OK = false;
1372 			}
1373 
1374 			if (Case1OK) {
1375 				s->prefetch_bw_equ = s->PrefetchBandwidth1;
1376 			} else if (Case2OK) {
1377 				s->prefetch_bw_equ = s->PrefetchBandwidth2;
1378 			} else if (Case3OK) {
1379 				s->prefetch_bw_equ = s->PrefetchBandwidth3;
1380 			} else {
1381 				s->prefetch_bw_equ = s->PrefetchBandwidth4;
1382 			}
1383 
1384 #ifdef __DML_VBA_DEBUG__
1385 			dml_print("DML::%s: Case1OK: %u\n", __func__, Case1OK);
1386 			dml_print("DML::%s: Case2OK: %u\n", __func__, Case2OK);
1387 			dml_print("DML::%s: Case3OK: %u\n", __func__, Case3OK);
1388 			dml_print("DML::%s: prefetch_bw_equ: %f\n", __func__, s->prefetch_bw_equ);
1389 #endif
1390 
1391 			if (s->prefetch_bw_equ > 0) {
1392 				if (p->GPUVMEnable == true) {
1393 					s->Tvm_equ = dml_max3(*p->Tno_bw + p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor / s->prefetch_bw_equ, s->Tvm_trips, s->LineTime / 4);
1394 				} else {
1395 					s->Tvm_equ = s->LineTime / 4;
1396 				}
1397 
1398 				if ((p->GPUVMEnable == true || p->myPipe->DCCEnable == true)) {
1399 					s->Tr0_equ = dml_max4((p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / s->prefetch_bw_equ, s->Tr0_trips, (s->LineTime - s->Tvm_equ) / 2, s->LineTime / 4);
1400 				} else {
1401 					s->Tr0_equ = (s->LineTime - s->Tvm_equ) / 2;
1402 				}
1403 			} else {
1404 				s->Tvm_equ = 0;
1405 				s->Tr0_equ = 0;
1406 				dml_print("DML::%s: prefetch_bw_equ equals 0!\n", __func__);
1407 			}
1408 		}
1409 
1410 
1411 		if (s->dst_y_prefetch_oto < s->dst_y_prefetch_equ) {
1412 			*p->DestinationLinesForPrefetch = s->dst_y_prefetch_oto;
1413 			s->TimeForFetchingMetaPTE = s->Tvm_oto;
1414 			s->TimeForFetchingRowInVBlank = s->Tr0_oto;
1415 
1416 			*p->DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * s->TimeForFetchingMetaPTE / s->LineTime, 1.0) / 4.0;
1417 			*p->DestinationLinesToRequestRowInVBlank = dml_ceil(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
1418 		} else {
1419 			*p->DestinationLinesForPrefetch = s->dst_y_prefetch_equ;
1420 			s->TimeForFetchingMetaPTE = s->Tvm_equ;
1421 			s->TimeForFetchingRowInVBlank = s->Tr0_equ;
1422 
1423 			if (p->VStartup == p->MaxVStartup && p->EnhancedPrefetchScheduleAccelerationFinal != 0) {
1424 				*p->DestinationLinesToRequestVMInVBlank = dml_floor(4.0 * s->TimeForFetchingMetaPTE / s->LineTime, 1.0) / 4.0;
1425 				*p->DestinationLinesToRequestRowInVBlank = dml_floor(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
1426 			} else {
1427 				*p->DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * s->TimeForFetchingMetaPTE / s->LineTime, 1.0) / 4.0;
1428 				*p->DestinationLinesToRequestRowInVBlank = dml_ceil(4.0 * s->TimeForFetchingRowInVBlank / s->LineTime, 1.0) / 4.0;
1429 			}
1430 		}
1431 
1432 		s->LinesToRequestPrefetchPixelData = *p->DestinationLinesForPrefetch - *p->DestinationLinesToRequestVMInVBlank - 2 * *p->DestinationLinesToRequestRowInVBlank;
1433 
1434 #ifdef __DML_VBA_DEBUG__
1435 		dml_print("DML::%s: DestinationLinesForPrefetch = %f\n", __func__, *p->DestinationLinesForPrefetch);
1436 		dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n", __func__, *p->DestinationLinesToRequestVMInVBlank);
1437 		dml_print("DML::%s: TimeForFetchingRowInVBlank = %f\n", __func__, s->TimeForFetchingRowInVBlank);
1438 		dml_print("DML::%s: LineTime = %f\n", __func__, s->LineTime);
1439 		dml_print("DML::%s: DestinationLinesToRequestRowInVBlank = %f\n", __func__, *p->DestinationLinesToRequestRowInVBlank);
1440 		dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY);
1441 		dml_print("DML::%s: LinesToRequestPrefetchPixelData = %f\n", __func__, s->LinesToRequestPrefetchPixelData);
1442 #endif
1443 
1444 		if (s->LinesToRequestPrefetchPixelData >= 1 && s->prefetch_bw_equ > 0) {
1445 			*p->VRatioPrefetchY = (dml_float_t)p->PrefetchSourceLinesY / s->LinesToRequestPrefetchPixelData;
1446 			*p->VRatioPrefetchY = dml_max(*p->VRatioPrefetchY, 1.0);
1447 #ifdef __DML_VBA_DEBUG__
1448 			dml_print("DML::%s: VRatioPrefetchY = %f\n", __func__, *p->VRatioPrefetchY);
1449 			dml_print("DML::%s: SwathHeightY = %u\n", __func__, p->SwathHeightY);
1450 			dml_print("DML::%s: VInitPreFillY = %u\n", __func__, p->VInitPreFillY);
1451 #endif
1452 			if ((p->SwathHeightY > 4) && (p->VInitPreFillY > 3)) {
1453 				if (s->LinesToRequestPrefetchPixelData > (p->VInitPreFillY - 3.0) / 2.0) {
1454 					*p->VRatioPrefetchY = dml_max(*p->VRatioPrefetchY,
1455 										(dml_float_t)p->MaxNumSwathY * p->SwathHeightY / (s->LinesToRequestPrefetchPixelData - (p->VInitPreFillY - 3.0) / 2.0));
1456 			} else {
1457 				s->MyError = true;
1458 				dml_print("DML::%s: MyErr set. LinesToRequestPrefetchPixelData=%f VinitPreFillY=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillY);
1459 				*p->VRatioPrefetchY = 0;
1460 			}
1461 #ifdef __DML_VBA_DEBUG__
1462 			dml_print("DML::%s: VRatioPrefetchY = %f\n", __func__, *p->VRatioPrefetchY);
1463 			dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, p->PrefetchSourceLinesY);
1464 			dml_print("DML::%s: MaxNumSwathY = %u\n", __func__, p->MaxNumSwathY);
1465 #endif
1466 			}
1467 
1468 			*p->VRatioPrefetchC = (dml_float_t)p->PrefetchSourceLinesC / s->LinesToRequestPrefetchPixelData;
1469 			*p->VRatioPrefetchC = dml_max(*p->VRatioPrefetchC, 1.0);
1470 
1471 #ifdef __DML_VBA_DEBUG__
1472 			dml_print("DML::%s: VRatioPrefetchC = %f\n", __func__, *p->VRatioPrefetchC);
1473 			dml_print("DML::%s: SwathHeightC = %u\n", __func__, p->SwathHeightC);
1474 			dml_print("DML::%s: VInitPreFillC = %u\n", __func__, p->VInitPreFillC);
1475 #endif
1476 			if ((p->SwathHeightC > 4) && (p->VInitPreFillC > 3)) {
1477 				if (s->LinesToRequestPrefetchPixelData > (p->VInitPreFillC - 3.0) / 2.0) {
1478 					*p->VRatioPrefetchC = dml_max(*p->VRatioPrefetchC, (dml_float_t)p->MaxNumSwathC * p->SwathHeightC / (s->LinesToRequestPrefetchPixelData - (p->VInitPreFillC - 3.0) / 2.0));
1479 				} else {
1480 					s->MyError = true;
1481 					dml_print("DML::%s: MyErr set. LinesToRequestPrefetchPixelData=%f VInitPreFillC=%u\n", __func__, s->LinesToRequestPrefetchPixelData, p->VInitPreFillC);
1482 					*p->VRatioPrefetchC = 0;
1483 				}
1484 #ifdef __DML_VBA_DEBUG__
1485 				dml_print("DML::%s: VRatioPrefetchC = %f\n", __func__, *p->VRatioPrefetchC);
1486 				dml_print("DML::%s: PrefetchSourceLinesC = %f\n", __func__, p->PrefetchSourceLinesC);
1487 				dml_print("DML::%s: MaxNumSwathC = %u\n", __func__, p->MaxNumSwathC);
1488 #endif
1489 			}
1490 
1491 			*p->RequiredPrefetchPixDataBWLuma = (dml_float_t)p->PrefetchSourceLinesY / s->LinesToRequestPrefetchPixelData
1492 				* p->myPipe->BytePerPixelY
1493 				* p->swath_width_luma_ub / s->LineTime;
1494 
1495 #ifdef __DML_VBA_DEBUG__
1496 			dml_print("DML::%s: BytePerPixelY = %u\n", __func__, p->myPipe->BytePerPixelY);
1497 			dml_print("DML::%s: swath_width_luma_ub = %u\n", __func__, p->swath_width_luma_ub);
1498 			dml_print("DML::%s: LineTime = %f\n", __func__, s->LineTime);
1499 			dml_print("DML::%s: RequiredPrefetchPixDataBWLuma = %f\n", __func__, *p->RequiredPrefetchPixDataBWLuma);
1500 #endif
1501 			*p->RequiredPrefetchPixDataBWChroma = (dml_float_t)p->PrefetchSourceLinesC / s->LinesToRequestPrefetchPixelData
1502 				*p->myPipe->BytePerPixelC
1503 				*p->swath_width_chroma_ub / s->LineTime;
1504 		} else {
1505 			s->MyError = true;
1506 			dml_print("DML:%s: MyErr set. LinesToRequestPrefetchPixelData: %f, should be > 0\n", __func__, s->LinesToRequestPrefetchPixelData);
1507 			*p->VRatioPrefetchY = 0;
1508 			*p->VRatioPrefetchC = 0;
1509 			*p->RequiredPrefetchPixDataBWLuma = 0;
1510 			*p->RequiredPrefetchPixDataBWChroma = 0;
1511 		}
1512 
1513 		dml_print("DML: Tpre: %fus - sum of time to request meta pte, 2 x data pte + meta data, swaths\n", (dml_float_t)s->LinesToRequestPrefetchPixelData * s->LineTime + 2.0 * s->TimeForFetchingRowInVBlank + s->TimeForFetchingMetaPTE);
1514 		dml_print("DML: Tvm: %fus - time to fetch page tables for meta surface\n", s->TimeForFetchingMetaPTE);
1515 		dml_print("DML: Tr0: %fus - time to fetch first row of data pagetables and first row of meta data (done in parallel)\n", s->TimeForFetchingRowInVBlank);
1516 		dml_print("DML: Tsw: %fus = time to fetch enough pixel data and cursor data to feed the scalers init position and detile\n", (dml_float_t)s->LinesToRequestPrefetchPixelData * s->LineTime);
1517 		dml_print("DML: To: %fus - time for propagation from scaler to optc\n", (*p->DSTYAfterScaler + ((dml_float_t) (*p->DSTXAfterScaler) / (dml_float_t)p->myPipe->HTotal)) * s->LineTime);
1518 		dml_print("DML: Tvstartup - TSetup - Tcalc - Twait - Tpre - To > 0\n");
1519 		dml_print("DML: Tslack(pre): %fus - time left over in schedule\n", p->VStartup * s->LineTime - s->TimeForFetchingMetaPTE - 2 * s->TimeForFetchingRowInVBlank - (*p->DSTYAfterScaler + ((dml_float_t) (*p->DSTXAfterScaler) / (dml_float_t)p->myPipe->HTotal)) * s->LineTime - p->TWait - p->TCalc - *p->TSetup);
1520 		dml_print("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %u\n", p->PixelPTEBytesPerRow);
1521 
1522 	} else {
1523 		s->MyError = true;
1524 		dml_print("DML::%s: MyErr set, dst_y_prefetch_equ = %f (should be > 1)\n", __func__, s->dst_y_prefetch_equ);
1525 		s->TimeForFetchingMetaPTE = 0;
1526 		s->TimeForFetchingRowInVBlank = 0;
1527 		*p->DestinationLinesToRequestVMInVBlank = 0;
1528 		*p->DestinationLinesToRequestRowInVBlank = 0;
1529 		s->LinesToRequestPrefetchPixelData = 0;
1530 		*p->VRatioPrefetchY = 0;
1531 		*p->VRatioPrefetchC = 0;
1532 		*p->RequiredPrefetchPixDataBWLuma = 0;
1533 		*p->RequiredPrefetchPixDataBWChroma = 0;
1534 	}
1535 
1536 	{
1537 		dml_float_t prefetch_vm_bw;
1538 		dml_float_t prefetch_row_bw;
1539 
1540 		if (p->PDEAndMetaPTEBytesFrame == 0) {
1541 			prefetch_vm_bw = 0;
1542 		} else if (*p->DestinationLinesToRequestVMInVBlank > 0) {
1543 #ifdef __DML_VBA_DEBUG__
1544 			dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %u\n", __func__, p->PDEAndMetaPTEBytesFrame);
1545 			dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, p->HostVMInefficiencyFactor);
1546 			dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n", __func__, *p->DestinationLinesToRequestVMInVBlank);
1547 			dml_print("DML::%s: LineTime = %f\n", __func__, s->LineTime);
1548 #endif
1549 		prefetch_vm_bw = p->PDEAndMetaPTEBytesFrame * p->HostVMInefficiencyFactor / (*p->DestinationLinesToRequestVMInVBlank * s->LineTime);
1550 #ifdef __DML_VBA_DEBUG__
1551 			dml_print("DML::%s: prefetch_vm_bw = %f\n", __func__, prefetch_vm_bw);
1552 #endif
1553 		} else {
1554 			prefetch_vm_bw = 0;
1555 			s->MyError = true;
1556 			dml_print("DML::%s: MyErr set. DestinationLinesToRequestVMInVBlank=%f (should be > 0)\n", __func__, *p->DestinationLinesToRequestVMInVBlank);
1557 		}
1558 
1559 		if (p->MetaRowByte + p->PixelPTEBytesPerRow == 0) {
1560 			prefetch_row_bw = 0;
1561 		} else if (*p->DestinationLinesToRequestRowInVBlank > 0) {
1562 			prefetch_row_bw = (p->MetaRowByte + p->PixelPTEBytesPerRow * p->HostVMInefficiencyFactor) / (*p->DestinationLinesToRequestRowInVBlank * s->LineTime);
1563 
1564 #ifdef __DML_VBA_DEBUG__
1565 		dml_print("DML::%s: MetaRowByte = %u\n", __func__, p->MetaRowByte);
1566 		dml_print("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, p->PixelPTEBytesPerRow);
1567 		dml_print("DML::%s: DestinationLinesToRequestRowInVBlank = %f\n", __func__, *p->DestinationLinesToRequestRowInVBlank);
1568 		dml_print("DML::%s: prefetch_row_bw = %f\n", __func__, prefetch_row_bw);
1569 #endif
1570 		} else {
1571 			prefetch_row_bw = 0;
1572 			s->MyError = true;
1573 			dml_print("DML::%s: MyErr set. DestinationLinesToRequestRowInVBlank=%f (should be > 0)\n", __func__, *p->DestinationLinesToRequestRowInVBlank);
1574 		}
1575 
1576 		*p->prefetch_vmrow_bw = dml_max(prefetch_vm_bw, prefetch_row_bw);
1577 	}
1578 
1579 	if (s->MyError) {
1580 		s->TimeForFetchingMetaPTE = 0;
1581 		s->TimeForFetchingRowInVBlank = 0;
1582 		*p->DestinationLinesToRequestVMInVBlank = 0;
1583 		*p->DestinationLinesToRequestRowInVBlank = 0;
1584 		*p->DestinationLinesForPrefetch = 0;
1585 		s->LinesToRequestPrefetchPixelData = 0;
1586 		*p->VRatioPrefetchY = 0;
1587 		*p->VRatioPrefetchC = 0;
1588 		*p->RequiredPrefetchPixDataBWLuma = 0;
1589 		*p->RequiredPrefetchPixDataBWChroma = 0;
1590 	}
1591 
1592 	return s->MyError;
1593 } // CalculatePrefetchSchedule
1594 
CalculateBytePerPixelAndBlockSizes(enum dml_source_format_class SourcePixelFormat,enum dml_swizzle_mode SurfaceTiling,dml_uint_t * BytePerPixelY,dml_uint_t * BytePerPixelC,dml_float_t * BytePerPixelDETY,dml_float_t * BytePerPixelDETC,dml_uint_t * BlockHeight256BytesY,dml_uint_t * BlockHeight256BytesC,dml_uint_t * BlockWidth256BytesY,dml_uint_t * BlockWidth256BytesC,dml_uint_t * MacroTileHeightY,dml_uint_t * MacroTileHeightC,dml_uint_t * MacroTileWidthY,dml_uint_t * MacroTileWidthC)1595 static void CalculateBytePerPixelAndBlockSizes(
1596 	enum dml_source_format_class SourcePixelFormat,
1597 	enum dml_swizzle_mode SurfaceTiling,
1598 
1599 	// Output
1600 	dml_uint_t *BytePerPixelY,
1601 	dml_uint_t *BytePerPixelC,
1602 	dml_float_t *BytePerPixelDETY,
1603 	dml_float_t *BytePerPixelDETC,
1604 	dml_uint_t *BlockHeight256BytesY,
1605 	dml_uint_t *BlockHeight256BytesC,
1606 	dml_uint_t *BlockWidth256BytesY,
1607 	dml_uint_t *BlockWidth256BytesC,
1608 	dml_uint_t *MacroTileHeightY,
1609 	dml_uint_t *MacroTileHeightC,
1610 	dml_uint_t *MacroTileWidthY,
1611 	dml_uint_t *MacroTileWidthC)
1612 {
1613 	if (SourcePixelFormat == dml_444_64) {
1614 		*BytePerPixelDETY = 8;
1615 		*BytePerPixelDETC = 0;
1616 		*BytePerPixelY = 8;
1617 		*BytePerPixelC = 0;
1618 	} else if (SourcePixelFormat == dml_444_32 || SourcePixelFormat == dml_rgbe) {
1619 		*BytePerPixelDETY = 4;
1620 		*BytePerPixelDETC = 0;
1621 		*BytePerPixelY = 4;
1622 		*BytePerPixelC = 0;
1623 	} else if (SourcePixelFormat == dml_444_16 || SourcePixelFormat == dml_mono_16) {
1624 		*BytePerPixelDETY = 2;
1625 		*BytePerPixelDETC = 0;
1626 		*BytePerPixelY = 2;
1627 		*BytePerPixelC = 0;
1628 	} else if (SourcePixelFormat == dml_444_8 || SourcePixelFormat == dml_mono_8) {
1629 		*BytePerPixelDETY = 1;
1630 		*BytePerPixelDETC = 0;
1631 		*BytePerPixelY = 1;
1632 		*BytePerPixelC = 0;
1633 	} else if (SourcePixelFormat == dml_rgbe_alpha) {
1634 		*BytePerPixelDETY = 4;
1635 		*BytePerPixelDETC = 1;
1636 		*BytePerPixelY = 4;
1637 		*BytePerPixelC = 1;
1638 	} else if (SourcePixelFormat == dml_420_8) {
1639 		*BytePerPixelDETY = 1;
1640 		*BytePerPixelDETC = 2;
1641 		*BytePerPixelY = 1;
1642 		*BytePerPixelC = 2;
1643 	} else if (SourcePixelFormat == dml_420_12) {
1644 		*BytePerPixelDETY = 2;
1645 		*BytePerPixelDETC = 4;
1646 		*BytePerPixelY = 2;
1647 		*BytePerPixelC = 4;
1648 	} else {
1649 		*BytePerPixelDETY = (dml_float_t) (4.0 / 3);
1650 		*BytePerPixelDETC = (dml_float_t) (8.0 / 3);
1651 		*BytePerPixelY = 2;
1652 		*BytePerPixelC = 4;
1653 	}
1654 #ifdef __DML_VBA_DEBUG__
1655 	dml_print("DML::%s: SourcePixelFormat = %u\n", __func__, SourcePixelFormat);
1656 	dml_print("DML::%s: BytePerPixelDETY = %f\n", __func__, *BytePerPixelDETY);
1657 	dml_print("DML::%s: BytePerPixelDETC = %f\n", __func__, *BytePerPixelDETC);
1658 	dml_print("DML::%s: BytePerPixelY = %u\n", __func__, *BytePerPixelY);
1659 	dml_print("DML::%s: BytePerPixelC = %u\n", __func__, *BytePerPixelC);
1660 #endif
1661 	if ((SourcePixelFormat == dml_444_64 || SourcePixelFormat == dml_444_32
1662 		|| SourcePixelFormat == dml_444_16
1663 		|| SourcePixelFormat == dml_444_8
1664 		|| SourcePixelFormat == dml_mono_16
1665 		|| SourcePixelFormat == dml_mono_8
1666 		|| SourcePixelFormat == dml_rgbe)) {
1667 		if (SurfaceTiling == dml_sw_linear) {
1668 			*BlockHeight256BytesY = 1;
1669 		} else if (SourcePixelFormat == dml_444_64) {
1670 			*BlockHeight256BytesY = 4;
1671 		} else if (SourcePixelFormat == dml_444_8) {
1672 			*BlockHeight256BytesY = 16;
1673 		} else {
1674 			*BlockHeight256BytesY = 8;
1675 		}
1676 		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
1677 		*BlockHeight256BytesC = 0;
1678 		*BlockWidth256BytesC = 0;
1679 	} else {
1680 		if (SurfaceTiling == dml_sw_linear) {
1681 			*BlockHeight256BytesY = 1;
1682 			*BlockHeight256BytesC = 1;
1683 		} else if (SourcePixelFormat == dml_rgbe_alpha) {
1684 			*BlockHeight256BytesY = 8;
1685 			*BlockHeight256BytesC = 16;
1686 		} else if (SourcePixelFormat == dml_420_8) {
1687 			*BlockHeight256BytesY = 16;
1688 			*BlockHeight256BytesC = 8;
1689 		} else {
1690 			*BlockHeight256BytesY = 8;
1691 			*BlockHeight256BytesC = 8;
1692 		}
1693 		*BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
1694 		*BlockWidth256BytesC = 256U / *BytePerPixelC / *BlockHeight256BytesC;
1695 	}
1696 #ifdef __DML_VBA_DEBUG__
1697 	dml_print("DML::%s: BlockWidth256BytesY = %u\n", __func__, *BlockWidth256BytesY);
1698 	dml_print("DML::%s: BlockHeight256BytesY = %u\n", __func__, *BlockHeight256BytesY);
1699 	dml_print("DML::%s: BlockWidth256BytesC = %u\n", __func__, *BlockWidth256BytesC);
1700 	dml_print("DML::%s: BlockHeight256BytesC = %u\n", __func__, *BlockHeight256BytesC);
1701 #endif
1702 
1703 	if (SurfaceTiling == dml_sw_linear) {
1704 		*MacroTileHeightY = *BlockHeight256BytesY;
1705 		*MacroTileWidthY = 256 / *BytePerPixelY / *MacroTileHeightY;
1706 		*MacroTileHeightC = *BlockHeight256BytesC;
1707 		if (*MacroTileHeightC == 0) {
1708 			*MacroTileWidthC = 0;
1709 		} else {
1710 			*MacroTileWidthC = 256 / *BytePerPixelC / *MacroTileHeightC;
1711 	}
1712 	} else if (SurfaceTiling == dml_sw_64kb_d || SurfaceTiling == dml_sw_64kb_d_t || SurfaceTiling == dml_sw_64kb_d_x || SurfaceTiling == dml_sw_64kb_r_x) {
1713 		*MacroTileHeightY = 16 * *BlockHeight256BytesY;
1714 		*MacroTileWidthY = 65536 / *BytePerPixelY / *MacroTileHeightY;
1715 		*MacroTileHeightC = 16 * *BlockHeight256BytesC;
1716 		if (*MacroTileHeightC == 0) {
1717 			*MacroTileWidthC = 0;
1718 		} else {
1719 			*MacroTileWidthC = 65536 / *BytePerPixelC / *MacroTileHeightC;
1720 		}
1721 	} else {
1722 		*MacroTileHeightY = 32 * *BlockHeight256BytesY;
1723 		*MacroTileWidthY = 65536 * 4 / *BytePerPixelY / *MacroTileHeightY;
1724 		*MacroTileHeightC = 32 * *BlockHeight256BytesC;
1725 		if (*MacroTileHeightC == 0) {
1726 			*MacroTileWidthC = 0;
1727 		} else {
1728 			*MacroTileWidthC = 65536 * 4 / *BytePerPixelC / *MacroTileHeightC;
1729 		}
1730 	}
1731 
1732 #ifdef __DML_VBA_DEBUG__
1733 	dml_print("DML::%s: MacroTileWidthY = %u\n", __func__, *MacroTileWidthY);
1734 	dml_print("DML::%s: MacroTileHeightY = %u\n", __func__, *MacroTileHeightY);
1735 	dml_print("DML::%s: MacroTileWidthC = %u\n", __func__, *MacroTileWidthC);
1736 	dml_print("DML::%s: MacroTileHeightC = %u\n", __func__, *MacroTileHeightC);
1737 #endif
1738 } // CalculateBytePerPixelAndBlockSizes
1739 
CalculateTWait(dml_uint_t PrefetchMode,enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange,dml_bool_t SynchronizeDRRDisplaysForUCLKPStateChangeFinal,dml_bool_t DRRDisplay,dml_float_t DRAMClockChangeLatency,dml_float_t FCLKChangeLatency,dml_float_t UrgentLatency,dml_float_t SREnterPlusExitTime)1740 static noinline_for_stack dml_float_t CalculateTWait(
1741 		dml_uint_t PrefetchMode,
1742 		enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange,
1743 		dml_bool_t SynchronizeDRRDisplaysForUCLKPStateChangeFinal,
1744 		dml_bool_t DRRDisplay,
1745 		dml_float_t DRAMClockChangeLatency,
1746 		dml_float_t FCLKChangeLatency,
1747 		dml_float_t UrgentLatency,
1748 		dml_float_t SREnterPlusExitTime)
1749 {
1750 	dml_float_t TWait = 0.0;
1751 
1752 	if (PrefetchMode == 0 &&
1753 			!(UseMALLForPStateChange == dml_use_mall_pstate_change_full_frame) && !(UseMALLForPStateChange == dml_use_mall_pstate_change_sub_viewport) &&
1754 			!(UseMALLForPStateChange == dml_use_mall_pstate_change_phantom_pipe) && !(SynchronizeDRRDisplaysForUCLKPStateChangeFinal && DRRDisplay)) {
1755 		TWait = dml_max3(DRAMClockChangeLatency + UrgentLatency, SREnterPlusExitTime, UrgentLatency);
1756 	} else if (PrefetchMode <= 1 && !(UseMALLForPStateChange == dml_use_mall_pstate_change_phantom_pipe)) {
1757 		TWait = dml_max3(FCLKChangeLatency + UrgentLatency, SREnterPlusExitTime, UrgentLatency);
1758 	} else if (PrefetchMode <= 2 && !(UseMALLForPStateChange == dml_use_mall_pstate_change_phantom_pipe)) {
1759 		TWait = dml_max(SREnterPlusExitTime, UrgentLatency);
1760 	} else {
1761 		TWait = UrgentLatency;
1762 	}
1763 
1764 #ifdef __DML_VBA_DEBUG__
1765 	dml_print("DML::%s: PrefetchMode = %u\n", __func__, PrefetchMode);
1766 	dml_print("DML::%s: TWait = %f\n", __func__, TWait);
1767 #endif
1768 	return TWait;
1769 } // CalculateTWait
1770 
1771 
1772 /// @brief Calculate the "starting point" for prefetch calculation
1773 ///  if AllowForPStateChangeOrStutterInVBlank is set as a particular requirement, then the mode evalulation
1774 ///  will only be done at the given mode. If no specific requirement (i.e. *_if_possible), then will just go from
1775 ///  try all the prefetch mode in decreasing order of "difficulty" (start from 0 which means all power saving
1776 ///  features).
CalculatePrefetchMode(enum dml_prefetch_modes AllowForPStateChangeOrStutterInVBlank,dml_uint_t * MinPrefetchMode,dml_uint_t * MaxPrefetchMode)1777 static void CalculatePrefetchMode(
1778 		enum dml_prefetch_modes AllowForPStateChangeOrStutterInVBlank,
1779 		dml_uint_t *MinPrefetchMode,
1780 		dml_uint_t *MaxPrefetchMode)
1781 {
1782 	if (AllowForPStateChangeOrStutterInVBlank == dml_prefetch_support_uclk_fclk_and_stutter_if_possible) {
1783 		*MinPrefetchMode = 0;   // consider all pwr saving features
1784 		*MaxPrefetchMode = 3;   // consider just urgent latency
1785 	} else {
1786 		if (AllowForPStateChangeOrStutterInVBlank == dml_prefetch_support_none) {
1787 			*MinPrefetchMode = 3;
1788 		} else if (AllowForPStateChangeOrStutterInVBlank == dml_prefetch_support_stutter) {
1789 			*MinPrefetchMode = 2;
1790 		} else if (AllowForPStateChangeOrStutterInVBlank == dml_prefetch_support_fclk_and_stutter) {
1791 			*MinPrefetchMode = 1;
1792 		} else if (AllowForPStateChangeOrStutterInVBlank == dml_prefetch_support_uclk_fclk_and_stutter) {
1793 			*MinPrefetchMode = 0;
1794 		} else {
1795 			dml_print("ERROR: Invalid AllowForPStateChangeOrStutterInVBlank setting! val=%u\n", AllowForPStateChangeOrStutterInVBlank);
1796 			ASSERT(0);
1797 		}
1798 		*MaxPrefetchMode = *MinPrefetchMode;
1799 	}
1800 } // CalculatePrefetchMode
1801 
CalculateWriteBackDISPCLK(enum dml_source_format_class WritebackPixelFormat,dml_float_t PixelClock,dml_float_t WritebackHRatio,dml_float_t WritebackVRatio,dml_uint_t WritebackHTaps,dml_uint_t WritebackVTaps,dml_uint_t WritebackSourceWidth,dml_uint_t WritebackDestinationWidth,dml_uint_t HTotal,dml_uint_t WritebackLineBufferSize,dml_float_t DISPCLKDPPCLKVCOSpeed)1802 static dml_float_t CalculateWriteBackDISPCLK(
1803 		enum dml_source_format_class WritebackPixelFormat,
1804 		dml_float_t PixelClock,
1805 		dml_float_t WritebackHRatio,
1806 		dml_float_t WritebackVRatio,
1807 		dml_uint_t WritebackHTaps,
1808 		dml_uint_t WritebackVTaps,
1809 		dml_uint_t WritebackSourceWidth,
1810 		dml_uint_t WritebackDestinationWidth,
1811 		dml_uint_t HTotal,
1812 		dml_uint_t WritebackLineBufferSize,
1813 		dml_float_t DISPCLKDPPCLKVCOSpeed)
1814 {
1815 	dml_float_t DISPCLK_H, DISPCLK_V, DISPCLK_HB;
1816 
1817 	DISPCLK_H = PixelClock * dml_ceil(WritebackHTaps / 8.0, 1) / WritebackHRatio;
1818 	DISPCLK_V = PixelClock * (WritebackVTaps * dml_ceil(WritebackDestinationWidth / 6.0, 1) + 8.0) / (dml_float_t) HTotal;
1819 	DISPCLK_HB = PixelClock * WritebackVTaps * (WritebackDestinationWidth * WritebackVTaps - WritebackLineBufferSize / 57.0) / 6.0 / (dml_float_t) WritebackSourceWidth;
1820 	return RoundToDFSGranularity(dml_max3(DISPCLK_H, DISPCLK_V, DISPCLK_HB), 1, DISPCLKDPPCLKVCOSpeed);
1821 }
1822 
CalculateWriteBackDelay(enum dml_source_format_class WritebackPixelFormat,dml_float_t WritebackHRatio,dml_float_t WritebackVRatio,dml_uint_t WritebackVTaps,dml_uint_t WritebackDestinationWidth,dml_uint_t WritebackDestinationHeight,dml_uint_t WritebackSourceHeight,dml_uint_t HTotal)1823 static dml_float_t CalculateWriteBackDelay(
1824 		enum dml_source_format_class WritebackPixelFormat,
1825 		dml_float_t WritebackHRatio,
1826 		dml_float_t WritebackVRatio,
1827 		dml_uint_t WritebackVTaps,
1828 		dml_uint_t WritebackDestinationWidth,
1829 		dml_uint_t WritebackDestinationHeight,
1830 		dml_uint_t WritebackSourceHeight,
1831 		dml_uint_t HTotal)
1832 {
1833 	dml_float_t CalculateWriteBackDelay;
1834 	dml_float_t Line_length;
1835 	dml_float_t Output_lines_last_notclamped;
1836 	dml_float_t WritebackVInit;
1837 
1838 	WritebackVInit = (WritebackVRatio + WritebackVTaps + 1) / 2;
1839 	Line_length = dml_max((dml_float_t) WritebackDestinationWidth, dml_ceil((dml_float_t)WritebackDestinationWidth / 6.0, 1.0) * WritebackVTaps);
1840 	Output_lines_last_notclamped = WritebackDestinationHeight - 1 - dml_ceil(((dml_float_t)WritebackSourceHeight - (dml_float_t) WritebackVInit) / (dml_float_t)WritebackVRatio, 1.0);
1841 	if (Output_lines_last_notclamped < 0) {
1842 		CalculateWriteBackDelay = 0;
1843 	} else {
1844 		CalculateWriteBackDelay = Output_lines_last_notclamped * Line_length + (HTotal - WritebackDestinationWidth) + 80;
1845 	}
1846 	return CalculateWriteBackDelay;
1847 }
1848 
CalculateVUpdateAndDynamicMetadataParameters(dml_uint_t MaxInterDCNTileRepeaters,dml_float_t Dppclk,dml_float_t Dispclk,dml_float_t DCFClkDeepSleep,dml_float_t PixelClock,dml_uint_t HTotal,dml_uint_t VBlank,dml_uint_t DynamicMetadataTransmittedBytes,dml_uint_t DynamicMetadataLinesBeforeActiveRequired,dml_uint_t InterlaceEnable,dml_bool_t ProgressiveToInterlaceUnitInOPP,dml_float_t * TSetup,dml_float_t * Tdmbf,dml_float_t * Tdmec,dml_float_t * Tdmsks,dml_uint_t * VUpdateOffsetPix,dml_uint_t * VUpdateWidthPix,dml_uint_t * VReadyOffsetPix)1849 static void CalculateVUpdateAndDynamicMetadataParameters(
1850 		dml_uint_t MaxInterDCNTileRepeaters,
1851 		dml_float_t Dppclk,
1852 		dml_float_t Dispclk,
1853 		dml_float_t DCFClkDeepSleep,
1854 		dml_float_t PixelClock,
1855 		dml_uint_t HTotal,
1856 		dml_uint_t VBlank,
1857 		dml_uint_t DynamicMetadataTransmittedBytes,
1858 		dml_uint_t DynamicMetadataLinesBeforeActiveRequired,
1859 		dml_uint_t InterlaceEnable,
1860 		dml_bool_t ProgressiveToInterlaceUnitInOPP,
1861 
1862 		// Output
1863 		dml_float_t *TSetup,
1864 		dml_float_t *Tdmbf,
1865 		dml_float_t *Tdmec,
1866 		dml_float_t *Tdmsks,
1867 		dml_uint_t *VUpdateOffsetPix,
1868 		dml_uint_t *VUpdateWidthPix,
1869 		dml_uint_t *VReadyOffsetPix)
1870 {
1871 	dml_float_t TotalRepeaterDelayTime;
1872 	TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2 / Dppclk + 3 / Dispclk);
1873 	*VUpdateWidthPix = (dml_uint_t)(dml_ceil((14.0 / DCFClkDeepSleep + 12.0 / Dppclk + TotalRepeaterDelayTime) * PixelClock, 1.0));
1874 	*VReadyOffsetPix = (dml_uint_t)(dml_ceil(dml_max(150.0 / Dppclk, TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / Dppclk) * PixelClock, 1.0));
1875 	*VUpdateOffsetPix = (dml_uint_t)(dml_ceil(HTotal / 4.0, 1.0));
1876 	*TSetup = (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
1877 	*Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / Dispclk;
1878 	*Tdmec = HTotal / PixelClock;
1879 
1880 	if (DynamicMetadataLinesBeforeActiveRequired == 0) {
1881 		*Tdmsks = VBlank * HTotal / PixelClock / 2.0;
1882 	} else {
1883 		*Tdmsks = DynamicMetadataLinesBeforeActiveRequired * HTotal / PixelClock;
1884 	}
1885 	if (InterlaceEnable == 1 && ProgressiveToInterlaceUnitInOPP == false) {
1886 		*Tdmsks = *Tdmsks / 2;
1887 	}
1888 #ifdef __DML_VBA_DEBUG__
1889 	dml_print("DML::%s: DynamicMetadataLinesBeforeActiveRequired = %u\n", __func__, DynamicMetadataLinesBeforeActiveRequired);
1890 	dml_print("DML::%s: VBlank = %u\n", __func__, VBlank);
1891 	dml_print("DML::%s: HTotal = %u\n", __func__, HTotal);
1892 	dml_print("DML::%s: PixelClock = %f\n", __func__, PixelClock);
1893 	dml_print("DML::%s: Dppclk = %f\n", __func__, Dppclk);
1894 	dml_print("DML::%s: DCFClkDeepSleep = %f\n", __func__, DCFClkDeepSleep);
1895 	dml_print("DML::%s: MaxInterDCNTileRepeaters = %u\n", __func__, MaxInterDCNTileRepeaters);
1896 	dml_print("DML::%s: TotalRepeaterDelayTime = %f\n", __func__, TotalRepeaterDelayTime);
1897 
1898 	dml_print("DML::%s: VUpdateWidthPix = %u\n", __func__, *VUpdateWidthPix);
1899 	dml_print("DML::%s: VReadyOffsetPix = %u\n", __func__, *VReadyOffsetPix);
1900 	dml_print("DML::%s: VUpdateOffsetPix = %u\n", __func__, *VUpdateOffsetPix);
1901 
1902 	dml_print("DML::%s: Tdmsks = %f\n", __func__, *Tdmsks);
1903 #endif
1904 }
1905 
CalculateRowBandwidth(dml_bool_t GPUVMEnable,enum dml_source_format_class SourcePixelFormat,dml_float_t VRatio,dml_float_t VRatioChroma,dml_bool_t DCCEnable,dml_float_t LineTime,dml_uint_t MetaRowByteLuma,dml_uint_t MetaRowByteChroma,dml_uint_t meta_row_height_luma,dml_uint_t meta_row_height_chroma,dml_uint_t PixelPTEBytesPerRowLuma,dml_uint_t PixelPTEBytesPerRowChroma,dml_uint_t dpte_row_height_luma,dml_uint_t dpte_row_height_chroma,dml_float_t * meta_row_bw,dml_float_t * dpte_row_bw)1906 static void CalculateRowBandwidth(
1907 		dml_bool_t GPUVMEnable,
1908 		enum dml_source_format_class SourcePixelFormat,
1909 		dml_float_t VRatio,
1910 		dml_float_t VRatioChroma,
1911 		dml_bool_t DCCEnable,
1912 		dml_float_t LineTime,
1913 		dml_uint_t MetaRowByteLuma,
1914 		dml_uint_t MetaRowByteChroma,
1915 		dml_uint_t meta_row_height_luma,
1916 		dml_uint_t meta_row_height_chroma,
1917 		dml_uint_t PixelPTEBytesPerRowLuma,
1918 		dml_uint_t PixelPTEBytesPerRowChroma,
1919 		dml_uint_t dpte_row_height_luma,
1920 		dml_uint_t dpte_row_height_chroma,
1921 		// Output
1922 		dml_float_t *meta_row_bw,
1923 		dml_float_t *dpte_row_bw)
1924 {
1925 	if (DCCEnable != true) {
1926 		*meta_row_bw = 0;
1927 	} else if (SourcePixelFormat == dml_420_8 || SourcePixelFormat == dml_420_10 || SourcePixelFormat == dml_420_12 || SourcePixelFormat == dml_rgbe_alpha) {
1928 		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
1929 				+ VRatioChroma * MetaRowByteChroma
1930 					/ (meta_row_height_chroma * LineTime);
1931 	} else {
1932 		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
1933 	}
1934 
1935 	if (GPUVMEnable != true) {
1936 		*dpte_row_bw = 0;
1937 	} else if (SourcePixelFormat == dml_420_8 || SourcePixelFormat == dml_420_10 || SourcePixelFormat == dml_420_12 || SourcePixelFormat == dml_rgbe_alpha) {
1938 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
1939 				+ VRatioChroma * PixelPTEBytesPerRowChroma
1940 					/ (dpte_row_height_chroma * LineTime);
1941 	} else {
1942 		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
1943 	}
1944 }
1945 
1946 /// @brief Determine immediate flip schedule given bw remaining after considering the prefetch schedule
1947 /// @param BandwidthAvailableForImmediateFlip Bandwidth available for iflip for all planes
CalculateFlipSchedule(dml_float_t HostVMInefficiencyFactor,dml_float_t UrgentExtraLatency,dml_float_t UrgentLatency,dml_uint_t GPUVMMaxPageTableLevels,dml_bool_t HostVMEnable,dml_uint_t HostVMMaxNonCachedPageTableLevels,dml_bool_t GPUVMEnable,dml_uint_t HostVMMinPageSize,dml_float_t PDEAndMetaPTEBytesPerFrame,dml_float_t MetaRowBytes,dml_float_t DPTEBytesPerRow,dml_float_t BandwidthAvailableForImmediateFlip,dml_uint_t TotImmediateFlipBytes,enum dml_source_format_class SourcePixelFormat,dml_float_t LineTime,dml_float_t VRatio,dml_float_t VRatioChroma,dml_float_t Tno_bw,dml_bool_t DCCEnable,dml_uint_t dpte_row_height,dml_uint_t meta_row_height,dml_uint_t dpte_row_height_chroma,dml_uint_t meta_row_height_chroma,dml_bool_t use_one_row_for_frame_flip,dml_float_t * DestinationLinesToRequestVMInImmediateFlip,dml_float_t * DestinationLinesToRequestRowInImmediateFlip,dml_float_t * final_flip_bw,dml_bool_t * ImmediateFlipSupportedForPipe)1948 static void CalculateFlipSchedule(
1949 		dml_float_t HostVMInefficiencyFactor,
1950 		dml_float_t UrgentExtraLatency,
1951 		dml_float_t UrgentLatency,
1952 		dml_uint_t GPUVMMaxPageTableLevels,
1953 		dml_bool_t HostVMEnable,
1954 		dml_uint_t HostVMMaxNonCachedPageTableLevels,
1955 		dml_bool_t GPUVMEnable,
1956 		dml_uint_t HostVMMinPageSize,
1957 		dml_float_t PDEAndMetaPTEBytesPerFrame,
1958 		dml_float_t MetaRowBytes,
1959 		dml_float_t DPTEBytesPerRow,
1960 		dml_float_t BandwidthAvailableForImmediateFlip,
1961 		dml_uint_t TotImmediateFlipBytes,
1962 		enum dml_source_format_class SourcePixelFormat,
1963 		dml_float_t LineTime,
1964 		dml_float_t VRatio,
1965 		dml_float_t VRatioChroma,
1966 		dml_float_t Tno_bw,
1967 		dml_bool_t DCCEnable,
1968 		dml_uint_t dpte_row_height,
1969 		dml_uint_t meta_row_height,
1970 		dml_uint_t dpte_row_height_chroma,
1971 		dml_uint_t meta_row_height_chroma,
1972 		dml_bool_t use_one_row_for_frame_flip,
1973 
1974 		// Output
1975 		dml_float_t *DestinationLinesToRequestVMInImmediateFlip,
1976 		dml_float_t *DestinationLinesToRequestRowInImmediateFlip,
1977 		dml_float_t *final_flip_bw,
1978 		dml_bool_t *ImmediateFlipSupportedForPipe)
1979 {
1980 	dml_float_t min_row_time = 0.0;
1981 	dml_uint_t HostVMDynamicLevelsTrips = 0;
1982 	dml_float_t TimeForFetchingMetaPTEImmediateFlip = 0;
1983 	dml_float_t TimeForFetchingRowInVBlankImmediateFlip = 0;
1984 	dml_float_t ImmediateFlipBW = 0; // @brief The immediate flip bandwidth for this pipe
1985 
1986 	if (GPUVMEnable == true && HostVMEnable == true) {
1987 		HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
1988 	} else {
1989 		HostVMDynamicLevelsTrips = 0;
1990 	}
1991 
1992 #ifdef __DML_VBA_DEBUG__
1993 	dml_print("DML::%s: TotImmediateFlipBytes = %u\n", __func__, TotImmediateFlipBytes);
1994 	dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
1995 	dml_print("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency);
1996 	dml_print("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip);
1997 #endif
1998 
1999 	if (TotImmediateFlipBytes > 0) {
2000 		if (use_one_row_for_frame_flip) {
2001 			ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + 2.0 * DPTEBytesPerRow) * BandwidthAvailableForImmediateFlip / (dml_float_t) TotImmediateFlipBytes;
2002 		} else {
2003 			ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow) * BandwidthAvailableForImmediateFlip / (dml_float_t) TotImmediateFlipBytes;
2004 		}
2005 		if (GPUVMEnable == true) {
2006 			TimeForFetchingMetaPTEImmediateFlip = dml_max3(Tno_bw + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW,
2007 														UrgentExtraLatency + UrgentLatency * (GPUVMMaxPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1),
2008 														LineTime / 4.0);
2009 		} else {
2010 			TimeForFetchingMetaPTEImmediateFlip = 0;
2011 		}
2012 		if ((GPUVMEnable == true || DCCEnable == true)) {
2013 			TimeForFetchingRowInVBlankImmediateFlip = dml_max3((MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / ImmediateFlipBW, UrgentLatency * (HostVMDynamicLevelsTrips + 1), LineTime / 4.0);
2014 		} else {
2015 			TimeForFetchingRowInVBlankImmediateFlip = 0;
2016 		}
2017 
2018 		*DestinationLinesToRequestVMInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime), 1.0) / 4.0;
2019 		*DestinationLinesToRequestRowInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1.0) / 4.0;
2020 
2021 		if (GPUVMEnable == true) {
2022 			*final_flip_bw = dml_max(PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInImmediateFlip * LineTime),
2023 								(MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime));
2024 		} else if ((GPUVMEnable == true || DCCEnable == true)) {
2025 			*final_flip_bw = (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInImmediateFlip * LineTime);
2026 		} else {
2027 			*final_flip_bw = 0;
2028 		}
2029 	} else {
2030 		TimeForFetchingMetaPTEImmediateFlip = 0;
2031 		TimeForFetchingRowInVBlankImmediateFlip = 0;
2032 		*DestinationLinesToRequestVMInImmediateFlip = 0;
2033 		*DestinationLinesToRequestRowInImmediateFlip = 0;
2034 		*final_flip_bw = 0;
2035 	}
2036 
2037 	if (SourcePixelFormat == dml_420_8 || SourcePixelFormat == dml_420_10 || SourcePixelFormat == dml_rgbe_alpha) {
2038 		if (GPUVMEnable == true && DCCEnable != true) {
2039 			min_row_time = dml_min(dpte_row_height * LineTime / VRatio, dpte_row_height_chroma * LineTime / VRatioChroma);
2040 		} else if (GPUVMEnable != true && DCCEnable == true) {
2041 			min_row_time = dml_min(meta_row_height * LineTime / VRatio, meta_row_height_chroma * LineTime / VRatioChroma);
2042 		} else {
2043 			min_row_time = dml_min4(dpte_row_height * LineTime / VRatio, meta_row_height * LineTime / VRatio, dpte_row_height_chroma * LineTime / VRatioChroma, meta_row_height_chroma * LineTime / VRatioChroma);
2044 		}
2045 	} else {
2046 		if (GPUVMEnable == true && DCCEnable != true) {
2047 			min_row_time = dpte_row_height * LineTime / VRatio;
2048 		} else if (GPUVMEnable != true && DCCEnable == true) {
2049 			min_row_time = meta_row_height * LineTime / VRatio;
2050 		} else {
2051 			min_row_time = dml_min(dpte_row_height * LineTime / VRatio, meta_row_height * LineTime / VRatio);
2052 		}
2053 	}
2054 
2055 	if (*DestinationLinesToRequestVMInImmediateFlip >= 32 || *DestinationLinesToRequestRowInImmediateFlip >= 16 || TimeForFetchingMetaPTEImmediateFlip + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) {
2056 		*ImmediateFlipSupportedForPipe = false;
2057 	} else {
2058 		*ImmediateFlipSupportedForPipe = true;
2059 	}
2060 
2061 #ifdef __DML_VBA_DEBUG__
2062 	dml_print("DML::%s: GPUVMEnable = %u\n", __func__, GPUVMEnable);
2063 	dml_print("DML::%s: DCCEnable = %u\n", __func__, DCCEnable);
2064 
2065 	dml_print("DML::%s: MetaRowBytes = %f\n", __func__, MetaRowBytes);
2066 	dml_print("DML::%s: DPTEBytesPerRow = %f\n", __func__, DPTEBytesPerRow);
2067 	dml_print("DML::%s: BandwidthAvailableForImmediateFlip = %f\n", __func__, BandwidthAvailableForImmediateFlip);
2068 	dml_print("DML::%s: TotImmediateFlipBytes = %u\n", __func__, TotImmediateFlipBytes);
2069 	dml_print("DML::%s: ImmediateFlipBW = %f\n", __func__, ImmediateFlipBW);
2070 	dml_print("DML::%s: PDEAndMetaPTEBytesPerFrame = %f\n", __func__, PDEAndMetaPTEBytesPerFrame);
2071 	dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
2072 	dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
2073 	dml_print("DML::%s: final_flip_bw = %f\n", __func__, *final_flip_bw);
2074 
2075 	dml_print("DML::%s: DestinationLinesToRequestVMInImmediateFlip = %f\n", __func__, *DestinationLinesToRequestVMInImmediateFlip);
2076 	dml_print("DML::%s: DestinationLinesToRequestRowInImmediateFlip = %f\n", __func__, *DestinationLinesToRequestRowInImmediateFlip);
2077 	dml_print("DML::%s: TimeForFetchingMetaPTEImmediateFlip = %f\n", __func__, TimeForFetchingMetaPTEImmediateFlip);
2078 	dml_print("DML::%s: TimeForFetchingRowInVBlankImmediateFlip = %f\n", __func__, TimeForFetchingRowInVBlankImmediateFlip);
2079 	dml_print("DML::%s: min_row_time = %f\n", __func__, min_row_time);
2080 	dml_print("DML::%s: ImmediateFlipSupportedForPipe = %u\n", __func__, *ImmediateFlipSupportedForPipe);
2081 #endif
2082 } // CalculateFlipSchedule
2083 
RoundToDFSGranularity(dml_float_t Clock,dml_bool_t round_up,dml_float_t VCOSpeed)2084 static dml_float_t RoundToDFSGranularity(dml_float_t Clock, dml_bool_t round_up, dml_float_t VCOSpeed)
2085 {
2086 	if (Clock <= 0.0)
2087 		return 0.0;
2088 	else {
2089 		if (round_up)
2090 			return VCOSpeed * 4.0 / dml_floor(VCOSpeed * 4.0 / Clock, 1.0);
2091 		else
2092 			return VCOSpeed * 4.0 / dml_ceil(VCOSpeed * 4.0 / Clock, 1.0);
2093 	}
2094 }
2095 
CalculateDCCConfiguration(dml_bool_t DCCEnabled,dml_bool_t DCCProgrammingAssumesScanDirectionUnknown,enum dml_source_format_class SourcePixelFormat,dml_uint_t SurfaceWidthLuma,dml_uint_t SurfaceWidthChroma,dml_uint_t SurfaceHeightLuma,dml_uint_t SurfaceHeightChroma,dml_uint_t nomDETInKByte,dml_uint_t RequestHeight256ByteLuma,dml_uint_t RequestHeight256ByteChroma,enum dml_swizzle_mode TilingFormat,dml_uint_t BytePerPixelY,dml_uint_t BytePerPixelC,dml_float_t BytePerPixelDETY,dml_float_t BytePerPixelDETC,enum dml_rotation_angle SourceScan,dml_uint_t * MaxUncompressedBlockLuma,dml_uint_t * MaxUncompressedBlockChroma,dml_uint_t * MaxCompressedBlockLuma,dml_uint_t * MaxCompressedBlockChroma,dml_uint_t * IndependentBlockLuma,dml_uint_t * IndependentBlockChroma)2096 static void CalculateDCCConfiguration(
2097 		dml_bool_t DCCEnabled,
2098 		dml_bool_t DCCProgrammingAssumesScanDirectionUnknown,
2099 		enum dml_source_format_class SourcePixelFormat,
2100 		dml_uint_t SurfaceWidthLuma,
2101 		dml_uint_t SurfaceWidthChroma,
2102 		dml_uint_t SurfaceHeightLuma,
2103 		dml_uint_t SurfaceHeightChroma,
2104 		dml_uint_t nomDETInKByte,
2105 		dml_uint_t RequestHeight256ByteLuma,
2106 		dml_uint_t RequestHeight256ByteChroma,
2107 		enum dml_swizzle_mode TilingFormat,
2108 		dml_uint_t BytePerPixelY,
2109 		dml_uint_t BytePerPixelC,
2110 		dml_float_t BytePerPixelDETY,
2111 		dml_float_t BytePerPixelDETC,
2112 		enum dml_rotation_angle SourceScan,
2113 		// Output
2114 		dml_uint_t *MaxUncompressedBlockLuma,
2115 		dml_uint_t *MaxUncompressedBlockChroma,
2116 		dml_uint_t *MaxCompressedBlockLuma,
2117 		dml_uint_t *MaxCompressedBlockChroma,
2118 		dml_uint_t *IndependentBlockLuma,
2119 		dml_uint_t *IndependentBlockChroma)
2120 {
2121 	dml_uint_t DETBufferSizeForDCC = nomDETInKByte * 1024;
2122 
2123 	dml_uint_t yuv420;
2124 	dml_uint_t horz_div_l;
2125 	dml_uint_t horz_div_c;
2126 	dml_uint_t vert_div_l;
2127 	dml_uint_t vert_div_c;
2128 
2129 	dml_uint_t swath_buf_size;
2130 	dml_float_t detile_buf_vp_horz_limit;
2131 	dml_float_t detile_buf_vp_vert_limit;
2132 
2133 	dml_uint_t MAS_vp_horz_limit;
2134 	dml_uint_t MAS_vp_vert_limit;
2135 	dml_uint_t max_vp_horz_width;
2136 	dml_uint_t max_vp_vert_height;
2137 	dml_uint_t eff_surf_width_l;
2138 	dml_uint_t eff_surf_width_c;
2139 	dml_uint_t eff_surf_height_l;
2140 	dml_uint_t eff_surf_height_c;
2141 
2142 	dml_uint_t full_swath_bytes_horz_wc_l;
2143 	dml_uint_t full_swath_bytes_horz_wc_c;
2144 	dml_uint_t full_swath_bytes_vert_wc_l;
2145 	dml_uint_t full_swath_bytes_vert_wc_c;
2146 
2147 	dml_uint_t req128_horz_wc_l;
2148 	dml_uint_t req128_horz_wc_c;
2149 	dml_uint_t req128_vert_wc_l;
2150 	dml_uint_t req128_vert_wc_c;
2151 
2152 	dml_uint_t   segment_order_horz_contiguous_luma;
2153 	dml_uint_t   segment_order_horz_contiguous_chroma;
2154 	dml_uint_t   segment_order_vert_contiguous_luma;
2155 	dml_uint_t   segment_order_vert_contiguous_chroma;
2156 
2157 	typedef enum{
2158 		REQ_256Bytes,
2159 		REQ_128BytesNonContiguous,
2160 		REQ_128BytesContiguous,
2161 		REQ_NA
2162 	} RequestType;
2163 
2164 	RequestType   RequestLuma;
2165 	RequestType   RequestChroma;
2166 
2167 	yuv420 = ((SourcePixelFormat == dml_420_8 || SourcePixelFormat == dml_420_10 || SourcePixelFormat == dml_420_12) ? 1 : 0);
2168 	horz_div_l = 1;
2169 	horz_div_c = 1;
2170 	vert_div_l = 1;
2171 	vert_div_c = 1;
2172 
2173 	if (BytePerPixelY == 1)
2174 		vert_div_l = 0;
2175 	if (BytePerPixelC == 1)
2176 		vert_div_c = 0;
2177 
2178 	if (BytePerPixelC == 0) {
2179 		swath_buf_size = DETBufferSizeForDCC / 2 - 2 * 256;
2180 		detile_buf_vp_horz_limit = (dml_float_t) swath_buf_size / ((dml_float_t) RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l));
2181 		detile_buf_vp_vert_limit = (dml_float_t) swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l));
2182 	} else {
2183 		swath_buf_size = DETBufferSizeForDCC / 2 - 2 * 2 * 256;
2184 		detile_buf_vp_horz_limit = (dml_float_t) swath_buf_size / ((dml_float_t) RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l) + (dml_float_t) RequestHeight256ByteChroma * BytePerPixelC / (1 + horz_div_c) / (1 + yuv420));
2185 		detile_buf_vp_vert_limit = (dml_float_t) swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l) + 256.0 / RequestHeight256ByteChroma / (1 + vert_div_c) / (1 + yuv420));
2186 	}
2187 
2188 	if (SourcePixelFormat == dml_420_10) {
2189 		detile_buf_vp_horz_limit = 1.5 * detile_buf_vp_horz_limit;
2190 		detile_buf_vp_vert_limit = 1.5 * detile_buf_vp_vert_limit;
2191 	}
2192 
2193 	detile_buf_vp_horz_limit = dml_floor(detile_buf_vp_horz_limit - 1, 16);
2194 	detile_buf_vp_vert_limit = dml_floor(detile_buf_vp_vert_limit - 1, 16);
2195 
2196 	MAS_vp_horz_limit = SourcePixelFormat == dml_rgbe_alpha ? 3840 : 6144;
2197 	MAS_vp_vert_limit = SourcePixelFormat == dml_rgbe_alpha ? 3840 : (BytePerPixelY == 8 ? 3072 : 6144);
2198 	max_vp_horz_width = (dml_uint_t)(dml_min((dml_float_t) MAS_vp_horz_limit, detile_buf_vp_horz_limit));
2199 	max_vp_vert_height = (dml_uint_t)(dml_min((dml_float_t) MAS_vp_vert_limit, detile_buf_vp_vert_limit));
2200 	eff_surf_width_l = (SurfaceWidthLuma > max_vp_horz_width ? max_vp_horz_width : SurfaceWidthLuma);
2201 	eff_surf_width_c = eff_surf_width_l / (1 + yuv420);
2202 	eff_surf_height_l = (SurfaceHeightLuma > max_vp_vert_height ? max_vp_vert_height : SurfaceHeightLuma);
2203 	eff_surf_height_c = eff_surf_height_l / (1 + yuv420);
2204 
2205 	full_swath_bytes_horz_wc_l = eff_surf_width_l * RequestHeight256ByteLuma * BytePerPixelY;
2206 	full_swath_bytes_vert_wc_l = eff_surf_height_l * 256 / RequestHeight256ByteLuma;
2207 	if (BytePerPixelC > 0) {
2208 		full_swath_bytes_horz_wc_c = eff_surf_width_c * RequestHeight256ByteChroma * BytePerPixelC;
2209 		full_swath_bytes_vert_wc_c = eff_surf_height_c * 256 / RequestHeight256ByteChroma;
2210 	} else {
2211 		full_swath_bytes_horz_wc_c = 0;
2212 		full_swath_bytes_vert_wc_c = 0;
2213 	}
2214 
2215 	if (SourcePixelFormat == dml_420_10) {
2216 		full_swath_bytes_horz_wc_l = (dml_uint_t)(dml_ceil((dml_float_t) full_swath_bytes_horz_wc_l * 2.0 / 3.0, 256.0));
2217 		full_swath_bytes_horz_wc_c = (dml_uint_t)(dml_ceil((dml_float_t) full_swath_bytes_horz_wc_c * 2.0 / 3.0, 256.0));
2218 		full_swath_bytes_vert_wc_l = (dml_uint_t)(dml_ceil((dml_float_t) full_swath_bytes_vert_wc_l * 2.0 / 3.0, 256.0));
2219 		full_swath_bytes_vert_wc_c = (dml_uint_t)(dml_ceil((dml_float_t) full_swath_bytes_vert_wc_c * 2.0 / 3.0, 256.0));
2220 	}
2221 
2222 	if (2 * full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) {
2223 		req128_horz_wc_l = 0;
2224 		req128_horz_wc_c = 0;
2225 	} else if (full_swath_bytes_horz_wc_l < 1.5 * full_swath_bytes_horz_wc_c && 2 * full_swath_bytes_horz_wc_l + full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) {
2226 		req128_horz_wc_l = 0;
2227 		req128_horz_wc_c = 1;
2228 	} else if (full_swath_bytes_horz_wc_l >= 1.5 * full_swath_bytes_horz_wc_c && full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSizeForDCC) {
2229 		req128_horz_wc_l = 1;
2230 		req128_horz_wc_c = 0;
2231 	} else {
2232 		req128_horz_wc_l = 1;
2233 		req128_horz_wc_c = 1;
2234 	}
2235 
2236 	if (2 * full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) {
2237 		req128_vert_wc_l = 0;
2238 		req128_vert_wc_c = 0;
2239 	} else if (full_swath_bytes_vert_wc_l < 1.5 * full_swath_bytes_vert_wc_c && 2 * full_swath_bytes_vert_wc_l + full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) {
2240 		req128_vert_wc_l = 0;
2241 		req128_vert_wc_c = 1;
2242 	} else if (full_swath_bytes_vert_wc_l >= 1.5 * full_swath_bytes_vert_wc_c && full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSizeForDCC) {
2243 		req128_vert_wc_l = 1;
2244 		req128_vert_wc_c = 0;
2245 	} else {
2246 		req128_vert_wc_l = 1;
2247 		req128_vert_wc_c = 1;
2248 	}
2249 
2250 	if (BytePerPixelY == 2) {
2251 		segment_order_horz_contiguous_luma = 0;
2252 		segment_order_vert_contiguous_luma = 1;
2253 	} else {
2254 		segment_order_horz_contiguous_luma = 1;
2255 		segment_order_vert_contiguous_luma = 0;
2256 	}
2257 
2258 	if (BytePerPixelC == 2) {
2259 		segment_order_horz_contiguous_chroma = 0;
2260 		segment_order_vert_contiguous_chroma = 1;
2261 	} else {
2262 		segment_order_horz_contiguous_chroma = 1;
2263 		segment_order_vert_contiguous_chroma = 0;
2264 	}
2265 #ifdef __DML_VBA_DEBUG__
2266 	dml_print("DML::%s: DCCEnabled = %u\n", __func__, DCCEnabled);
2267 	dml_print("DML::%s: nomDETInKByte = %u\n", __func__, nomDETInKByte);
2268 	dml_print("DML::%s: DETBufferSizeForDCC = %u\n", __func__, DETBufferSizeForDCC);
2269 	dml_print("DML::%s: req128_horz_wc_l = %u\n", __func__, req128_horz_wc_l);
2270 	dml_print("DML::%s: req128_horz_wc_c = %u\n", __func__, req128_horz_wc_c);
2271 	dml_print("DML::%s: full_swath_bytes_horz_wc_l = %u\n", __func__, full_swath_bytes_horz_wc_l);
2272 	dml_print("DML::%s: full_swath_bytes_vert_wc_c = %u\n", __func__, full_swath_bytes_vert_wc_c);
2273 	dml_print("DML::%s: segment_order_horz_contiguous_luma = %u\n", __func__, segment_order_horz_contiguous_luma);
2274 	dml_print("DML::%s: segment_order_horz_contiguous_chroma = %u\n", __func__, segment_order_horz_contiguous_chroma);
2275 #endif
2276 
2277 	if (DCCProgrammingAssumesScanDirectionUnknown == true) {
2278 		if (req128_horz_wc_l == 0 && req128_vert_wc_l == 0) {
2279 			RequestLuma = REQ_256Bytes;
2280 		} else if ((req128_horz_wc_l == 1 && segment_order_horz_contiguous_luma == 0) || (req128_vert_wc_l == 1 && segment_order_vert_contiguous_luma == 0)) {
2281 			RequestLuma = REQ_128BytesNonContiguous;
2282 		} else {
2283 			RequestLuma = REQ_128BytesContiguous;
2284 		}
2285 		if (req128_horz_wc_c == 0 && req128_vert_wc_c == 0) {
2286 			RequestChroma = REQ_256Bytes;
2287 		} else if ((req128_horz_wc_c == 1 && segment_order_horz_contiguous_chroma == 0) || (req128_vert_wc_c == 1 && segment_order_vert_contiguous_chroma == 0)) {
2288 			RequestChroma = REQ_128BytesNonContiguous;
2289 		} else {
2290 			RequestChroma = REQ_128BytesContiguous;
2291 		}
2292 	} else if (!dml_is_vertical_rotation(SourceScan)) {
2293 		if (req128_horz_wc_l == 0) {
2294 			RequestLuma = REQ_256Bytes;
2295 		} else if (segment_order_horz_contiguous_luma == 0) {
2296 			RequestLuma = REQ_128BytesNonContiguous;
2297 		} else {
2298 			RequestLuma = REQ_128BytesContiguous;
2299 		}
2300 		if (req128_horz_wc_c == 0) {
2301 			RequestChroma = REQ_256Bytes;
2302 		} else if (segment_order_horz_contiguous_chroma == 0) {
2303 			RequestChroma = REQ_128BytesNonContiguous;
2304 		} else {
2305 			RequestChroma = REQ_128BytesContiguous;
2306 		}
2307 	} else {
2308 		if (req128_vert_wc_l == 0) {
2309 			RequestLuma = REQ_256Bytes;
2310 		} else if (segment_order_vert_contiguous_luma == 0) {
2311 			RequestLuma = REQ_128BytesNonContiguous;
2312 		} else {
2313 			RequestLuma = REQ_128BytesContiguous;
2314 		}
2315 		if (req128_vert_wc_c == 0) {
2316 			RequestChroma = REQ_256Bytes;
2317 		} else if (segment_order_vert_contiguous_chroma == 0) {
2318 			RequestChroma = REQ_128BytesNonContiguous;
2319 		} else {
2320 			RequestChroma = REQ_128BytesContiguous;
2321 		}
2322 	}
2323 
2324 	if (RequestLuma == REQ_256Bytes) {
2325 		*MaxUncompressedBlockLuma = 256;
2326 		*MaxCompressedBlockLuma = 256;
2327 		*IndependentBlockLuma = 0;
2328 	} else if (RequestLuma == REQ_128BytesContiguous) {
2329 		*MaxUncompressedBlockLuma = 256;
2330 		*MaxCompressedBlockLuma = 128;
2331 		*IndependentBlockLuma = 128;
2332 	} else {
2333 		*MaxUncompressedBlockLuma = 256;
2334 		*MaxCompressedBlockLuma = 64;
2335 		*IndependentBlockLuma = 64;
2336 	}
2337 
2338 	if (RequestChroma == REQ_256Bytes) {
2339 		*MaxUncompressedBlockChroma = 256;
2340 		*MaxCompressedBlockChroma = 256;
2341 		*IndependentBlockChroma = 0;
2342 	} else if (RequestChroma == REQ_128BytesContiguous) {
2343 		*MaxUncompressedBlockChroma = 256;
2344 		*MaxCompressedBlockChroma = 128;
2345 		*IndependentBlockChroma = 128;
2346 	} else {
2347 		*MaxUncompressedBlockChroma = 256;
2348 		*MaxCompressedBlockChroma = 64;
2349 		*IndependentBlockChroma = 64;
2350 	}
2351 
2352 	if (DCCEnabled != true || BytePerPixelC == 0) {
2353 		*MaxUncompressedBlockChroma = 0;
2354 		*MaxCompressedBlockChroma = 0;
2355 		*IndependentBlockChroma = 0;
2356 	}
2357 
2358 	if (DCCEnabled != true) {
2359 		*MaxUncompressedBlockLuma = 0;
2360 		*MaxCompressedBlockLuma = 0;
2361 		*IndependentBlockLuma = 0;
2362 	}
2363 
2364 #ifdef __DML_VBA_DEBUG__
2365 	dml_print("DML::%s: MaxUncompressedBlockLuma = %u\n", __func__, *MaxUncompressedBlockLuma);
2366 	dml_print("DML::%s: MaxCompressedBlockLuma = %u\n", __func__, *MaxCompressedBlockLuma);
2367 	dml_print("DML::%s: IndependentBlockLuma = %u\n", __func__, *IndependentBlockLuma);
2368 	dml_print("DML::%s: MaxUncompressedBlockChroma = %u\n", __func__, *MaxUncompressedBlockChroma);
2369 	dml_print("DML::%s: MaxCompressedBlockChroma = %u\n", __func__, *MaxCompressedBlockChroma);
2370 	dml_print("DML::%s: IndependentBlockChroma = %u\n", __func__, *IndependentBlockChroma);
2371 #endif
2372 
2373 } // CalculateDCCConfiguration
2374 
CalculatePrefetchSourceLines(dml_float_t VRatio,dml_uint_t VTaps,dml_bool_t Interlace,dml_bool_t ProgressiveToInterlaceUnitInOPP,dml_uint_t SwathHeight,enum dml_rotation_angle SourceScan,dml_bool_t ViewportStationary,dml_uint_t SwathWidth,dml_uint_t ViewportHeight,dml_uint_t ViewportXStart,dml_uint_t ViewportYStart,dml_uint_t * VInitPreFill,dml_uint_t * MaxNumSwath)2375 static dml_uint_t CalculatePrefetchSourceLines(
2376 		dml_float_t VRatio,
2377 		dml_uint_t VTaps,
2378 		dml_bool_t Interlace,
2379 		dml_bool_t ProgressiveToInterlaceUnitInOPP,
2380 		dml_uint_t SwathHeight,
2381 		enum dml_rotation_angle SourceScan,
2382 		dml_bool_t ViewportStationary,
2383 		dml_uint_t SwathWidth,
2384 		dml_uint_t ViewportHeight,
2385 		dml_uint_t ViewportXStart,
2386 		dml_uint_t ViewportYStart,
2387 
2388 		// Output
2389 		dml_uint_t *VInitPreFill,
2390 		dml_uint_t *MaxNumSwath)
2391 {
2392 
2393 	dml_uint_t vp_start_rot = 0;
2394 	dml_uint_t sw0_tmp = 0;
2395 	dml_uint_t MaxPartialSwath = 0;
2396 	dml_float_t numLines = 0;
2397 
2398 #ifdef __DML_VBA_DEBUG__
2399 	dml_print("DML::%s: VRatio = %f\n", __func__, VRatio);
2400 	dml_print("DML::%s: VTaps = %u\n", __func__, VTaps);
2401 	dml_print("DML::%s: ViewportXStart = %u\n", __func__, ViewportXStart);
2402 	dml_print("DML::%s: ViewportYStart = %u\n", __func__, ViewportYStart);
2403 	dml_print("DML::%s: ViewportStationary = %u\n", __func__, ViewportStationary);
2404 	dml_print("DML::%s: SwathHeight = %u\n", __func__, SwathHeight);
2405 #endif
2406 	if (ProgressiveToInterlaceUnitInOPP)
2407 		*VInitPreFill = (dml_uint_t)(dml_floor((VRatio + (dml_float_t) VTaps + 1) / 2.0, 1));
2408 	else
2409 		*VInitPreFill = (dml_uint_t)(dml_floor((VRatio + (dml_float_t) VTaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1));
2410 
2411 	if (ViewportStationary) {
2412 		if (SourceScan == dml_rotation_180 || SourceScan == dml_rotation_180m) {
2413 			vp_start_rot = SwathHeight - (((dml_uint_t) (ViewportYStart + ViewportHeight - 1) % SwathHeight) + 1);
2414 		} else if (SourceScan == dml_rotation_270 || SourceScan == dml_rotation_90m) {
2415 			vp_start_rot = ViewportXStart;
2416 		} else if (SourceScan == dml_rotation_90 || SourceScan == dml_rotation_270m) {
2417 			vp_start_rot = SwathHeight - (((dml_uint_t)(ViewportYStart + SwathWidth - 1) % SwathHeight) + 1);
2418 		} else {
2419 			vp_start_rot = ViewportYStart;
2420 		}
2421 		sw0_tmp = SwathHeight - (vp_start_rot % SwathHeight);
2422 		if (sw0_tmp < *VInitPreFill) {
2423 			*MaxNumSwath = (dml_uint_t)(dml_ceil((*VInitPreFill - sw0_tmp) / (dml_float_t) SwathHeight, 1) + 1);
2424 		} else {
2425 			*MaxNumSwath = 1;
2426 		}
2427 		MaxPartialSwath = (dml_uint_t)(dml_max(1, (dml_uint_t) (vp_start_rot + *VInitPreFill - 1) % SwathHeight));
2428 	} else {
2429 		*MaxNumSwath = (dml_uint_t)(dml_ceil((*VInitPreFill - 1.0) / (dml_float_t) SwathHeight, 1) + 1);
2430 		if (*VInitPreFill > 1) {
2431 			MaxPartialSwath = (dml_uint_t)(dml_max(1, (dml_uint_t) (*VInitPreFill - 2) % SwathHeight));
2432 		} else {
2433 			MaxPartialSwath = (dml_uint_t)(dml_max(1, (dml_uint_t) (*VInitPreFill + SwathHeight - 2) % SwathHeight));
2434 		}
2435 	}
2436 	numLines = *MaxNumSwath * SwathHeight + MaxPartialSwath;
2437 
2438 #ifdef __DML_VBA_DEBUG__
2439 	dml_print("DML::%s: vp_start_rot = %u\n", __func__, vp_start_rot);
2440 	dml_print("DML::%s: VInitPreFill = %u\n", __func__, *VInitPreFill);
2441 	dml_print("DML::%s: MaxPartialSwath = %u\n", __func__, MaxPartialSwath);
2442 	dml_print("DML::%s: MaxNumSwath = %u\n", __func__, *MaxNumSwath);
2443 	dml_print("DML::%s: Prefetch source lines = %3.2f\n", __func__, numLines);
2444 #endif
2445 	return (dml_uint_t)(numLines);
2446 
2447 } // CalculatePrefetchSourceLines
2448 
CalculateVMAndRowBytes(dml_bool_t ViewportStationary,dml_bool_t DCCEnable,dml_uint_t NumberOfDPPs,dml_uint_t BlockHeight256Bytes,dml_uint_t BlockWidth256Bytes,enum dml_source_format_class SourcePixelFormat,dml_uint_t SurfaceTiling,dml_uint_t BytePerPixel,enum dml_rotation_angle SourceScan,dml_uint_t SwathWidth,dml_uint_t ViewportHeight,dml_uint_t ViewportXStart,dml_uint_t ViewportYStart,dml_bool_t GPUVMEnable,dml_uint_t GPUVMMaxPageTableLevels,dml_uint_t GPUVMMinPageSizeKBytes,dml_uint_t PTEBufferSizeInRequests,dml_uint_t Pitch,dml_uint_t DCCMetaPitch,dml_uint_t MacroTileWidth,dml_uint_t MacroTileHeight,dml_uint_t * MetaRowByte,dml_uint_t * PixelPTEBytesPerRow,dml_uint_t * PixelPTEBytesPerRowStorage,dml_uint_t * dpte_row_width_ub,dml_uint_t * dpte_row_height,dml_uint_t * dpte_row_height_linear,dml_uint_t * PixelPTEBytesPerRow_one_row_per_frame,dml_uint_t * dpte_row_width_ub_one_row_per_frame,dml_uint_t * dpte_row_height_one_row_per_frame,dml_uint_t * MetaRequestWidth,dml_uint_t * MetaRequestHeight,dml_uint_t * meta_row_width,dml_uint_t * meta_row_height,dml_uint_t * PixelPTEReqWidth,dml_uint_t * PixelPTEReqHeight,dml_uint_t * PTERequestSize,dml_uint_t * DPDE0BytesFrame,dml_uint_t * MetaPTEBytesFrame)2449 static dml_uint_t CalculateVMAndRowBytes(
2450 		dml_bool_t ViewportStationary,
2451 		dml_bool_t DCCEnable,
2452 		dml_uint_t NumberOfDPPs,
2453 		dml_uint_t BlockHeight256Bytes,
2454 		dml_uint_t BlockWidth256Bytes,
2455 		enum dml_source_format_class SourcePixelFormat,
2456 		dml_uint_t SurfaceTiling,
2457 		dml_uint_t BytePerPixel,
2458 		enum dml_rotation_angle SourceScan,
2459 		dml_uint_t SwathWidth,
2460 		dml_uint_t ViewportHeight,
2461 		dml_uint_t ViewportXStart,
2462 		dml_uint_t ViewportYStart,
2463 		dml_bool_t GPUVMEnable,
2464 		dml_uint_t GPUVMMaxPageTableLevels,
2465 		dml_uint_t GPUVMMinPageSizeKBytes,
2466 		dml_uint_t PTEBufferSizeInRequests,
2467 		dml_uint_t Pitch,
2468 		dml_uint_t DCCMetaPitch,
2469 		dml_uint_t MacroTileWidth,
2470 		dml_uint_t MacroTileHeight,
2471 
2472 		// Output
2473 		dml_uint_t *MetaRowByte,
2474 		dml_uint_t *PixelPTEBytesPerRow, // for bandwidth calculation
2475 		dml_uint_t *PixelPTEBytesPerRowStorage, // for PTE buffer size check
2476 		dml_uint_t *dpte_row_width_ub,
2477 		dml_uint_t *dpte_row_height,
2478 		dml_uint_t *dpte_row_height_linear,
2479 		dml_uint_t *PixelPTEBytesPerRow_one_row_per_frame,
2480 		dml_uint_t *dpte_row_width_ub_one_row_per_frame,
2481 		dml_uint_t *dpte_row_height_one_row_per_frame,
2482 		dml_uint_t *MetaRequestWidth,
2483 		dml_uint_t *MetaRequestHeight,
2484 		dml_uint_t *meta_row_width,
2485 		dml_uint_t *meta_row_height,
2486 		dml_uint_t *PixelPTEReqWidth,
2487 		dml_uint_t *PixelPTEReqHeight,
2488 		dml_uint_t *PTERequestSize,
2489 		dml_uint_t *DPDE0BytesFrame,
2490 		dml_uint_t *MetaPTEBytesFrame)
2491 {
2492 	dml_uint_t MPDEBytesFrame;
2493 	dml_uint_t DCCMetaSurfaceBytes;
2494 	dml_uint_t ExtraDPDEBytesFrame;
2495 	dml_uint_t PDEAndMetaPTEBytesFrame;
2496 	dml_uint_t MacroTileSizeBytes;
2497 	dml_uint_t vp_height_meta_ub;
2498 	dml_uint_t vp_height_dpte_ub;
2499 
2500 	dml_uint_t PixelPTEReqWidth_linear = 0; // VBA_DELTA. VBA doesn't calculate this
2501 
2502 	*MetaRequestHeight = 8 * BlockHeight256Bytes;
2503 	*MetaRequestWidth = 8 * BlockWidth256Bytes;
2504 	if (SurfaceTiling == dml_sw_linear) {
2505 		*meta_row_height = 32;
2506 		*meta_row_width = (dml_uint_t)(dml_floor(ViewportXStart + SwathWidth + *MetaRequestWidth - 1, *MetaRequestWidth) - dml_floor(ViewportXStart, *MetaRequestWidth));
2507 	} else if (!dml_is_vertical_rotation(SourceScan)) {
2508 		*meta_row_height = *MetaRequestHeight;
2509 		if (ViewportStationary && NumberOfDPPs == 1) {
2510 			*meta_row_width = (dml_uint_t)(dml_floor(ViewportXStart + SwathWidth + *MetaRequestWidth - 1, *MetaRequestWidth) - dml_floor(ViewportXStart, *MetaRequestWidth));
2511 		} else {
2512 			*meta_row_width = (dml_uint_t)(dml_ceil(SwathWidth - 1, *MetaRequestWidth) + *MetaRequestWidth);
2513 		}
2514 		*MetaRowByte = (dml_uint_t)(*meta_row_width * *MetaRequestHeight * BytePerPixel / 256.0);
2515 	} else {
2516 		*meta_row_height = *MetaRequestWidth;
2517 		if (ViewportStationary && NumberOfDPPs == 1) {
2518 			*meta_row_width = (dml_uint_t)(dml_floor(ViewportYStart + ViewportHeight + *MetaRequestHeight - 1, *MetaRequestHeight) - dml_floor(ViewportYStart, *MetaRequestHeight));
2519 		} else {
2520 			*meta_row_width = (dml_uint_t)(dml_ceil(SwathWidth - 1, *MetaRequestHeight) + *MetaRequestHeight);
2521 		}
2522 		*MetaRowByte = (dml_uint_t)(*meta_row_width * *MetaRequestWidth * BytePerPixel / 256.0);
2523 	}
2524 
2525 	if (ViewportStationary && (NumberOfDPPs == 1 || !dml_is_vertical_rotation(SourceScan))) {
2526 		vp_height_meta_ub = (dml_uint_t)(dml_floor(ViewportYStart + ViewportHeight + 64 * BlockHeight256Bytes - 1, 64 * BlockHeight256Bytes) - dml_floor(ViewportYStart, 64 * BlockHeight256Bytes));
2527 	} else if (!dml_is_vertical_rotation(SourceScan)) {
2528 		vp_height_meta_ub = (dml_uint_t)(dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes) + 64 * BlockHeight256Bytes);
2529 	} else {
2530 		vp_height_meta_ub = (dml_uint_t)(dml_ceil(SwathWidth - 1, 64 * BlockHeight256Bytes) + 64 * BlockHeight256Bytes);
2531 	}
2532 
2533 	DCCMetaSurfaceBytes = (dml_uint_t)(DCCMetaPitch * vp_height_meta_ub * BytePerPixel / 256.0);
2534 
2535 	if (GPUVMEnable == true) {
2536 		*MetaPTEBytesFrame = (dml_uint_t)((dml_ceil((dml_float_t) (DCCMetaSurfaceBytes - 4.0 * 1024.0) / (8 * 4.0 * 1024), 1) + 1) * 64);
2537 		MPDEBytesFrame = 128 * (GPUVMMaxPageTableLevels - 1);
2538 	} else {
2539 		*MetaPTEBytesFrame = 0;
2540 		MPDEBytesFrame = 0;
2541 	}
2542 
2543 	if (DCCEnable != true) {
2544 		*MetaPTEBytesFrame = 0;
2545 		MPDEBytesFrame = 0;
2546 		*MetaRowByte = 0;
2547 	}
2548 
2549 	MacroTileSizeBytes = MacroTileWidth * BytePerPixel * MacroTileHeight;
2550 
2551 	if (ViewportStationary && (NumberOfDPPs == 1 || !dml_is_vertical_rotation(SourceScan))) {
2552 		vp_height_dpte_ub = (dml_uint_t)(dml_floor(ViewportYStart + ViewportHeight + MacroTileHeight - 1, MacroTileHeight) - dml_floor(ViewportYStart, MacroTileHeight));
2553 	} else if (!dml_is_vertical_rotation(SourceScan)) {
2554 		vp_height_dpte_ub = (dml_uint_t)(dml_ceil(ViewportHeight - 1, MacroTileHeight) + MacroTileHeight);
2555 	} else {
2556 		vp_height_dpte_ub = (dml_uint_t)(dml_ceil(SwathWidth - 1, MacroTileHeight) + MacroTileHeight);
2557 	}
2558 
2559 	if (GPUVMEnable == true && GPUVMMaxPageTableLevels > 1) {
2560 		*DPDE0BytesFrame = (dml_uint_t)(64 * (dml_ceil((dml_float_t) (Pitch * vp_height_dpte_ub * BytePerPixel - MacroTileSizeBytes) / (dml_float_t) (8 * 2097152), 1) + 1));
2561 		ExtraDPDEBytesFrame = 128 * (GPUVMMaxPageTableLevels - 2);
2562 	} else {
2563 		*DPDE0BytesFrame = 0;
2564 		ExtraDPDEBytesFrame = 0;
2565 	}
2566 
2567 	PDEAndMetaPTEBytesFrame = *MetaPTEBytesFrame + MPDEBytesFrame + *DPDE0BytesFrame + ExtraDPDEBytesFrame;
2568 
2569 #ifdef __DML_VBA_DEBUG__
2570 	dml_print("DML::%s: DCCEnable = %u\n", __func__, DCCEnable);
2571 	dml_print("DML::%s: GPUVMEnable = %u\n", __func__, GPUVMEnable);
2572 	dml_print("DML::%s: SwModeLinear = %u\n", __func__, SurfaceTiling == dml_sw_linear);
2573 	dml_print("DML::%s: BytePerPixel = %u\n", __func__, BytePerPixel);
2574 	dml_print("DML::%s: GPUVMMaxPageTableLevels = %u\n", __func__, GPUVMMaxPageTableLevels);
2575 	dml_print("DML::%s: BlockHeight256Bytes = %u\n", __func__, BlockHeight256Bytes);
2576 	dml_print("DML::%s: BlockWidth256Bytes = %u\n", __func__, BlockWidth256Bytes);
2577 	dml_print("DML::%s: MacroTileHeight = %u\n", __func__, MacroTileHeight);
2578 	dml_print("DML::%s: MacroTileWidth = %u\n", __func__, MacroTileWidth);
2579 	dml_print("DML::%s: MetaPTEBytesFrame = %u\n", __func__, *MetaPTEBytesFrame);
2580 	dml_print("DML::%s: MPDEBytesFrame = %u\n", __func__, MPDEBytesFrame);
2581 	dml_print("DML::%s: DPDE0BytesFrame = %u\n", __func__, *DPDE0BytesFrame);
2582 	dml_print("DML::%s: ExtraDPDEBytesFrame= %u\n", __func__, ExtraDPDEBytesFrame);
2583 	dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %u\n", __func__, PDEAndMetaPTEBytesFrame);
2584 	dml_print("DML::%s: ViewportHeight = %u\n", __func__, ViewportHeight);
2585 	dml_print("DML::%s: SwathWidth = %u\n", __func__, SwathWidth);
2586 	dml_print("DML::%s: vp_height_dpte_ub = %u\n", __func__, vp_height_dpte_ub);
2587 #endif
2588 
2589 	if (SurfaceTiling == dml_sw_linear) {
2590 		*PixelPTEReqHeight = 1;
2591 		*PixelPTEReqWidth = GPUVMMinPageSizeKBytes * 1024 * 8 / BytePerPixel;
2592 		PixelPTEReqWidth_linear = GPUVMMinPageSizeKBytes * 1024 * 8 / BytePerPixel;
2593 		*PTERequestSize = 64;
2594 	} else if (GPUVMMinPageSizeKBytes == 4) {
2595 		*PixelPTEReqHeight = 16 * BlockHeight256Bytes;
2596 		*PixelPTEReqWidth = 16 * BlockWidth256Bytes;
2597 		*PTERequestSize = 128;
2598 	} else {
2599 		*PixelPTEReqHeight = MacroTileHeight;
2600 		*PixelPTEReqWidth = 8 *  1024 * GPUVMMinPageSizeKBytes / (MacroTileHeight * BytePerPixel);
2601 		*PTERequestSize = 64;
2602 	}
2603 #ifdef __DML_VBA_DEBUG__
2604 	dml_print("DML::%s: GPUVMMinPageSizeKBytes = %u\n", __func__, GPUVMMinPageSizeKBytes);
2605 	dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %u (after HostVM factor)\n", __func__, PDEAndMetaPTEBytesFrame);
2606 	dml_print("DML::%s: PixelPTEReqHeight = %u\n", __func__, *PixelPTEReqHeight);
2607 	dml_print("DML::%s: PixelPTEReqWidth = %u\n", __func__, *PixelPTEReqWidth);
2608 	dml_print("DML::%s: PixelPTEReqWidth_linear = %u\n", __func__, PixelPTEReqWidth_linear);
2609 	dml_print("DML::%s: PTERequestSize = %u\n", __func__, *PTERequestSize);
2610 	dml_print("DML::%s: Pitch = %u\n", __func__, Pitch);
2611 #endif
2612 
2613 	*dpte_row_height_one_row_per_frame = vp_height_dpte_ub;
2614 	*dpte_row_width_ub_one_row_per_frame = (dml_uint_t)((dml_ceil(((dml_float_t)Pitch * (dml_float_t) *dpte_row_height_one_row_per_frame / (dml_float_t) *PixelPTEReqHeight - 1) / (dml_float_t) *PixelPTEReqWidth, 1) + 1) * (dml_float_t) *PixelPTEReqWidth);
2615 	*PixelPTEBytesPerRow_one_row_per_frame = (dml_uint_t)((dml_float_t) *dpte_row_width_ub_one_row_per_frame / (dml_float_t) *PixelPTEReqWidth * *PTERequestSize);
2616 
2617 	if (SurfaceTiling == dml_sw_linear) {
2618 		*dpte_row_height = (dml_uint_t)(dml_min(128, 1 << (dml_uint_t) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1)));
2619 		dml_print("DML::%s: dpte_row_height term 1 = %u\n", __func__, PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch);
2620 		dml_print("DML::%s: dpte_row_height term 2 = %f\n", __func__, dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch));
2621 		dml_print("DML::%s: dpte_row_height term 3 = %f\n", __func__, dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
2622 		dml_print("DML::%s: dpte_row_height term 4 = %u\n", __func__, 1 << (dml_uint_t) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
2623 		dml_print("DML::%s: dpte_row_height = %u\n", __func__, *dpte_row_height);
2624 
2625 		*dpte_row_width_ub = (dml_uint_t)(dml_ceil(((dml_float_t) Pitch * (dml_float_t) *dpte_row_height - 1), (dml_float_t) *PixelPTEReqWidth) + *PixelPTEReqWidth);
2626 		*PixelPTEBytesPerRow = (dml_uint_t)((dml_float_t) *dpte_row_width_ub / (dml_float_t) *PixelPTEReqWidth * *PTERequestSize);
2627 
2628 		// VBA_DELTA, VBA doesn't have programming value for pte row height linear.
2629 		*dpte_row_height_linear = 1 << (dml_uint_t) dml_floor(dml_log2(PTEBufferSizeInRequests * PixelPTEReqWidth_linear / Pitch), 1);
2630 		if (*dpte_row_height_linear > 128)
2631 			*dpte_row_height_linear = 128;
2632 
2633 #ifdef __DML_VBA_DEBUG__
2634 		dml_print("DML::%s: dpte_row_width_ub = %u (linear)\n", __func__, *dpte_row_width_ub);
2635 #endif
2636 
2637 	} else if (!dml_is_vertical_rotation(SourceScan)) {
2638 		*dpte_row_height = *PixelPTEReqHeight;
2639 
2640 		if (GPUVMMinPageSizeKBytes > 64) {
2641 			*dpte_row_width_ub = (dml_uint_t)((dml_ceil(((dml_float_t) Pitch * (dml_float_t) *dpte_row_height / (dml_float_t) *PixelPTEReqHeight - 1) / (dml_float_t) *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth);
2642 		} else if (ViewportStationary && (NumberOfDPPs == 1)) {
2643 			*dpte_row_width_ub = (dml_uint_t)(dml_floor(ViewportXStart + SwathWidth + *PixelPTEReqWidth - 1, *PixelPTEReqWidth) - dml_floor(ViewportXStart, *PixelPTEReqWidth));
2644 		} else {
2645 			*dpte_row_width_ub = (dml_uint_t)((dml_ceil((dml_float_t) (SwathWidth - 1) / (dml_float_t)*PixelPTEReqWidth, 1) + 1.0) * *PixelPTEReqWidth);
2646 		}
2647 #ifdef __DML_VBA_DEBUG__
2648 		dml_print("DML::%s: dpte_row_width_ub = %u (tiled horz)\n", __func__, *dpte_row_width_ub);
2649 #endif
2650 
2651 		ASSERT(*PixelPTEReqWidth);
2652 		if (*PixelPTEReqWidth != 0)
2653 			*PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
2654 	} else {
2655 		*dpte_row_height = (dml_uint_t)(dml_min(*PixelPTEReqWidth, MacroTileWidth));
2656 
2657 		if (ViewportStationary && (NumberOfDPPs == 1)) {
2658 			*dpte_row_width_ub = (dml_uint_t)(dml_floor(ViewportYStart + ViewportHeight + *PixelPTEReqHeight - 1, *PixelPTEReqHeight) - dml_floor(ViewportYStart, *PixelPTEReqHeight));
2659 		} else {
2660 			*dpte_row_width_ub = (dml_uint_t)((dml_ceil((dml_float_t) (SwathWidth - 1) / (dml_float_t) *PixelPTEReqHeight, 1) + 1) * *PixelPTEReqHeight);
2661 		}
2662 
2663 		*PixelPTEBytesPerRow = (dml_uint_t)((dml_float_t) *dpte_row_width_ub / (dml_float_t) *PixelPTEReqHeight * *PTERequestSize);
2664 #ifdef __DML_VBA_DEBUG__
2665 		dml_print("DML::%s: dpte_row_width_ub = %u (tiled vert)\n", __func__, *dpte_row_width_ub);
2666 #endif
2667 	}
2668 
2669 	if (GPUVMEnable != true)
2670 		*PixelPTEBytesPerRow = 0;
2671 
2672 	*PixelPTEBytesPerRowStorage = *PixelPTEBytesPerRow;
2673 
2674 #ifdef __DML_VBA_DEBUG__
2675 	dml_print("DML::%s: GPUVMMinPageSizeKBytes = %u\n", __func__, GPUVMMinPageSizeKBytes);
2676 	dml_print("DML::%s: GPUVMEnable = %u\n", __func__, GPUVMEnable);
2677 	dml_print("DML::%s: dpte_row_height = %u\n", __func__, *dpte_row_height);
2678 	dml_print("DML::%s: dpte_row_height_linear = %u\n", __func__, *dpte_row_height_linear);
2679 	dml_print("DML::%s: dpte_row_width_ub = %u\n", __func__, *dpte_row_width_ub);
2680 	dml_print("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, *PixelPTEBytesPerRow);
2681 	dml_print("DML::%s: PixelPTEBytesPerRowStorage = %u\n", __func__, *PixelPTEBytesPerRowStorage);
2682 	dml_print("DML::%s: PTEBufferSizeInRequests = %u\n", __func__, PTEBufferSizeInRequests);
2683 	dml_print("DML::%s: dpte_row_height_one_row_per_frame = %u\n", __func__, *dpte_row_height_one_row_per_frame);
2684 	dml_print("DML::%s: dpte_row_width_ub_one_row_per_frame = %u\n", __func__, *dpte_row_width_ub_one_row_per_frame);
2685 	dml_print("DML::%s: PixelPTEBytesPerRow_one_row_per_frame = %u\n", __func__, *PixelPTEBytesPerRow_one_row_per_frame);
2686 #endif
2687 
2688 	dml_print("DML: vm_bytes = meta_pte_bytes_per_frame (per_pipe) = MetaPTEBytesFrame = : %i\n", *MetaPTEBytesFrame);
2689 
2690 	return PDEAndMetaPTEBytesFrame;
2691 } // CalculateVMAndRowBytes
2692 
PixelClockAdjustmentForProgressiveToInterlaceUnit(struct dml_display_cfg_st * display_cfg,dml_bool_t ptoi_supported)2693 static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct dml_display_cfg_st *display_cfg, dml_bool_t ptoi_supported)
2694 {
2695 	dml_uint_t num_active_planes = dml_get_num_active_planes(display_cfg);
2696 
2697 	//Progressive To Interlace Unit Effect
2698 	for (dml_uint_t k = 0; k < num_active_planes; ++k) {
2699 		display_cfg->output.PixelClockBackEnd[k] = display_cfg->timing.PixelClock[k];
2700 		if (display_cfg->timing.Interlace[k] == 1 && ptoi_supported == true) {
2701 			display_cfg->timing.PixelClock[k] = 2 * display_cfg->timing.PixelClock[k];
2702 		}
2703 	}
2704 }
2705 
TruncToValidBPP(dml_float_t LinkBitRate,dml_uint_t Lanes,dml_uint_t HTotal,dml_uint_t HActive,dml_float_t PixelClock,dml_float_t DesiredBPP,dml_bool_t DSCEnable,enum dml_output_encoder_class Output,enum dml_output_format_class Format,dml_uint_t DSCInputBitPerComponent,dml_uint_t DSCSlices,dml_uint_t AudioRate,dml_uint_t AudioLayout,enum dml_odm_mode ODMModeNoDSC,enum dml_odm_mode ODMModeDSC,dml_uint_t * RequiredSlots)2706 static dml_float_t TruncToValidBPP(
2707 		dml_float_t LinkBitRate,
2708 		dml_uint_t Lanes,
2709 		dml_uint_t HTotal,
2710 		dml_uint_t HActive,
2711 		dml_float_t PixelClock,
2712 		dml_float_t DesiredBPP,
2713 		dml_bool_t DSCEnable,
2714 		enum dml_output_encoder_class Output,
2715 		enum dml_output_format_class Format,
2716 		dml_uint_t DSCInputBitPerComponent,
2717 		dml_uint_t DSCSlices,
2718 		dml_uint_t AudioRate,
2719 		dml_uint_t AudioLayout,
2720 		enum dml_odm_mode ODMModeNoDSC,
2721 		enum dml_odm_mode ODMModeDSC,
2722 
2723 		// Output
2724 		dml_uint_t *RequiredSlots)
2725 {
2726 	dml_float_t MaxLinkBPP;
2727 	dml_uint_t MinDSCBPP;
2728 	dml_float_t MaxDSCBPP;
2729 	dml_uint_t NonDSCBPP0;
2730 	dml_uint_t NonDSCBPP1;
2731 	dml_uint_t NonDSCBPP2;
2732 
2733 	if (Format == dml_420) {
2734 		NonDSCBPP0 = 12;
2735 		NonDSCBPP1 = 15;
2736 		NonDSCBPP2 = 18;
2737 		MinDSCBPP = 6;
2738 		MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1.0 / 16;
2739 	} else if (Format == dml_444) {
2740 		NonDSCBPP0 = 24;
2741 		NonDSCBPP1 = 30;
2742 		NonDSCBPP2 = 36;
2743 		MinDSCBPP = 8;
2744 		MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
2745 	} else {
2746 		if (Output == dml_hdmi) {
2747 			NonDSCBPP0 = 24;
2748 			NonDSCBPP1 = 24;
2749 			NonDSCBPP2 = 24;
2750 		} else {
2751 			NonDSCBPP0 = 16;
2752 			NonDSCBPP1 = 20;
2753 			NonDSCBPP2 = 24;
2754 	}
2755 	if (Format == dml_n422) {
2756 		MinDSCBPP = 7;
2757 			MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
2758 		} else {
2759 			MinDSCBPP = 8;
2760 			MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
2761 		}
2762 	}
2763 
2764 	if (Output == dml_dp2p0) {
2765 		MaxLinkBPP = LinkBitRate * Lanes / PixelClock * 128.0 / 132.0 * 383.0 / 384.0 * 65536.0 / 65540.0;
2766 	} else if (DSCEnable && Output == dml_dp) {
2767 		MaxLinkBPP = LinkBitRate / 10.0 * 8.0 * Lanes / PixelClock * (1 - 2.4 / 100);
2768 	} else {
2769 		MaxLinkBPP = LinkBitRate / 10.0 * 8.0 * Lanes / PixelClock;
2770 	}
2771 
2772 	if (DSCEnable) {
2773 		if (ODMModeDSC == dml_odm_mode_combine_4to1) {
2774 			MaxLinkBPP = dml_min(MaxLinkBPP, 16);
2775 		} else if (ODMModeDSC == dml_odm_mode_combine_2to1) {
2776 			MaxLinkBPP = dml_min(MaxLinkBPP, 32);
2777 		} else if (ODMModeDSC == dml_odm_mode_split_1to2) {
2778 			MaxLinkBPP = 2 * MaxLinkBPP;
2779 		}
2780 	} else {
2781 		if (ODMModeNoDSC == dml_odm_mode_combine_4to1) {
2782 			MaxLinkBPP = dml_min(MaxLinkBPP, 16);
2783 		} else if (ODMModeNoDSC == dml_odm_mode_combine_2to1) {
2784 			MaxLinkBPP = dml_min(MaxLinkBPP, 32);
2785 		} else if (ODMModeNoDSC == dml_odm_mode_split_1to2) {
2786 			MaxLinkBPP = 2 * MaxLinkBPP;
2787 		}
2788 	}
2789 
2790 	*RequiredSlots = (dml_uint_t)(dml_ceil(DesiredBPP / MaxLinkBPP * 64, 1));
2791 
2792 	if (DesiredBPP == 0) {
2793 		if (DSCEnable) {
2794 			if (MaxLinkBPP < MinDSCBPP) {
2795 				return __DML_DPP_INVALID__;
2796 			} else if (MaxLinkBPP >= MaxDSCBPP) {
2797 				return MaxDSCBPP;
2798 			} else {
2799 				return dml_floor(16.0 * MaxLinkBPP, 1.0) / 16.0;
2800 			}
2801 		} else {
2802 			if (MaxLinkBPP >= NonDSCBPP2) {
2803 				return NonDSCBPP2;
2804 			} else if (MaxLinkBPP >= NonDSCBPP1) {
2805 				return NonDSCBPP1;
2806 			} else if (MaxLinkBPP >= NonDSCBPP0) {
2807 				return NonDSCBPP0;
2808 			} else {
2809 				return __DML_DPP_INVALID__;
2810 			}
2811 		}
2812 	} else {
2813 		if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP == NonDSCBPP0)) ||
2814 				(DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
2815 			return __DML_DPP_INVALID__;
2816 		} else {
2817 			return DesiredBPP;
2818 		}
2819 	}
2820 } // TruncToValidBPP
2821 
CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(struct display_mode_lib_scratch_st * scratch,struct CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params_st * p)2822 static void CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
2823 		struct display_mode_lib_scratch_st *scratch,
2824 		struct CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params_st *p)
2825 {
2826 	struct CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals_st *s = &scratch->CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_locals;
2827 
2828 	s->TotalActiveWriteback = 0;
2829 	p->Watermark->UrgentWatermark = p->mmSOCParameters.UrgentLatency + p->mmSOCParameters.ExtraLatency;
2830 	p->Watermark->USRRetrainingWatermark = p->mmSOCParameters.UrgentLatency + p->mmSOCParameters.ExtraLatency + p->mmSOCParameters.USRRetrainingLatency + p->mmSOCParameters.SMNLatency;
2831 	p->Watermark->DRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->Watermark->UrgentWatermark;
2832 	p->Watermark->FCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->Watermark->UrgentWatermark;
2833 	p->Watermark->StutterExitWatermark = p->mmSOCParameters.SRExitTime + p->mmSOCParameters.ExtraLatency + 10 / p->DCFClkDeepSleep;
2834 	p->Watermark->StutterEnterPlusExitWatermark = p->mmSOCParameters.SREnterPlusExitTime + p->mmSOCParameters.ExtraLatency + 10 / p->DCFClkDeepSleep;
2835 	p->Watermark->Z8StutterExitWatermark = p->mmSOCParameters.SRExitZ8Time + p->mmSOCParameters.ExtraLatency + 10 / p->DCFClkDeepSleep;
2836 	p->Watermark->Z8StutterEnterPlusExitWatermark = p->mmSOCParameters.SREnterPlusExitZ8Time + p->mmSOCParameters.ExtraLatency + 10 / p->DCFClkDeepSleep;
2837 
2838 #ifdef __DML_VBA_DEBUG__
2839 	dml_print("DML::%s: UrgentLatency = %f\n", __func__, p->mmSOCParameters.UrgentLatency);
2840 	dml_print("DML::%s: ExtraLatency = %f\n", __func__, p->mmSOCParameters.ExtraLatency);
2841 	dml_print("DML::%s: DRAMClockChangeLatency = %f\n", __func__, p->mmSOCParameters.DRAMClockChangeLatency);
2842 	dml_print("DML::%s: UrgentWatermark = %f\n", __func__, p->Watermark->UrgentWatermark);
2843 	dml_print("DML::%s: USRRetrainingWatermark = %f\n", __func__, p->Watermark->USRRetrainingWatermark);
2844 	dml_print("DML::%s: DRAMClockChangeWatermark = %f\n", __func__, p->Watermark->DRAMClockChangeWatermark);
2845 	dml_print("DML::%s: FCLKChangeWatermark = %f\n", __func__, p->Watermark->FCLKChangeWatermark);
2846 	dml_print("DML::%s: StutterExitWatermark = %f\n", __func__, p->Watermark->StutterExitWatermark);
2847 	dml_print("DML::%s: StutterEnterPlusExitWatermark = %f\n", __func__, p->Watermark->StutterEnterPlusExitWatermark);
2848 	dml_print("DML::%s: Z8StutterExitWatermark = %f\n", __func__, p->Watermark->Z8StutterExitWatermark);
2849 	dml_print("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, p->Watermark->Z8StutterEnterPlusExitWatermark);
2850 #endif
2851 
2852 	s->TotalActiveWriteback = 0;
2853 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
2854 		if (p->WritebackEnable[k] == true) {
2855 			s->TotalActiveWriteback = s->TotalActiveWriteback + 1;
2856 		}
2857 	}
2858 
2859 	if (s->TotalActiveWriteback <= 1) {
2860 		p->Watermark->WritebackUrgentWatermark = p->mmSOCParameters.WritebackLatency;
2861 	} else {
2862 		p->Watermark->WritebackUrgentWatermark = p->mmSOCParameters.WritebackLatency + p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK;
2863 	}
2864 	if (p->USRRetrainingRequiredFinal)
2865 		p->Watermark->WritebackUrgentWatermark = p->Watermark->WritebackUrgentWatermark + p->mmSOCParameters.USRRetrainingLatency;
2866 
2867 	if (s->TotalActiveWriteback <= 1) {
2868 		p->Watermark->WritebackDRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.WritebackLatency;
2869 		p->Watermark->WritebackFCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->mmSOCParameters.WritebackLatency;
2870 	} else {
2871 		p->Watermark->WritebackDRAMClockChangeWatermark = p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.WritebackLatency + p->WritebackChunkSize * 1024.0 / 32.0 / p->SOCCLK;
2872 		p->Watermark->WritebackFCLKChangeWatermark = p->mmSOCParameters.FCLKChangeLatency + p->mmSOCParameters.WritebackLatency + p->WritebackChunkSize * 1024 / 32 / p->SOCCLK;
2873 	}
2874 
2875 	if (p->USRRetrainingRequiredFinal)
2876 		p->Watermark->WritebackDRAMClockChangeWatermark = p->Watermark->WritebackDRAMClockChangeWatermark + p->mmSOCParameters.USRRetrainingLatency;
2877 
2878 	if (p->USRRetrainingRequiredFinal)
2879 		p->Watermark->WritebackFCLKChangeWatermark = p->Watermark->WritebackFCLKChangeWatermark + p->mmSOCParameters.USRRetrainingLatency;
2880 
2881 #ifdef __DML_VBA_DEBUG__
2882 	dml_print("DML::%s: WritebackDRAMClockChangeWatermark = %f\n", __func__, p->Watermark->WritebackDRAMClockChangeWatermark);
2883 	dml_print("DML::%s: WritebackFCLKChangeWatermark = %f\n", __func__, p->Watermark->WritebackFCLKChangeWatermark);
2884 	dml_print("DML::%s: WritebackUrgentWatermark = %f\n", __func__, p->Watermark->WritebackUrgentWatermark);
2885 	dml_print("DML::%s: USRRetrainingRequiredFinal = %u\n", __func__, p->USRRetrainingRequiredFinal);
2886 	dml_print("DML::%s: USRRetrainingLatency = %f\n", __func__, p->mmSOCParameters.USRRetrainingLatency);
2887 #endif
2888 
2889 	s->TotalPixelBW = 0.0;
2890 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
2891 		s->TotalPixelBW = s->TotalPixelBW + p->DPPPerSurface[k]
2892 					* (p->SwathWidthY[k] * p->BytePerPixelDETY[k] * p->VRatio[k] + p->SwathWidthC[k] * p->BytePerPixelDETC[k] * p->VRatioChroma[k]) / (p->HTotal[k] / p->PixelClock[k]);
2893 	}
2894 
2895 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
2896 
2897 		s->LBLatencyHidingSourceLinesY[k] = (dml_uint_t)(dml_min((dml_float_t)p->MaxLineBufferLines, dml_floor((dml_float_t)p->LineBufferSize / (dml_float_t)p->LBBitPerPixel[k] / ((dml_float_t)p->SwathWidthY[k] / dml_max(p->HRatio[k], 1.0)), 1)) - (p->VTaps[k] - 1));
2898 		s->LBLatencyHidingSourceLinesC[k] = (dml_uint_t)(dml_min((dml_float_t)p->MaxLineBufferLines, dml_floor((dml_float_t)p->LineBufferSize / (dml_float_t)p->LBBitPerPixel[k] / ((dml_float_t)p->SwathWidthC[k] / dml_max(p->HRatioChroma[k], 1.0)), 1)) - (p->VTapsChroma[k] - 1));
2899 
2900 
2901 #ifdef __DML_VBA_DEBUG__
2902 		dml_print("DML::%s: k=%u, MaxLineBufferLines = %u\n", __func__, k, p->MaxLineBufferLines);
2903 		dml_print("DML::%s: k=%u, LineBufferSize = %u\n", __func__, k, p->LineBufferSize);
2904 		dml_print("DML::%s: k=%u, LBBitPerPixel = %u\n", __func__, k, p->LBBitPerPixel[k]);
2905 		dml_print("DML::%s: k=%u, HRatio = %f\n", __func__, k, p->HRatio[k]);
2906 		dml_print("DML::%s: k=%u, VTaps              = %u\n", __func__, k, p->VTaps[k]);
2907 #endif
2908 
2909 		s->EffectiveLBLatencyHidingY = s->LBLatencyHidingSourceLinesY[k] / p->VRatio[k] * (p->HTotal[k] / p->PixelClock[k]);
2910 		s->EffectiveLBLatencyHidingC = s->LBLatencyHidingSourceLinesC[k] / p->VRatioChroma[k] * (p->HTotal[k] / p->PixelClock[k]);
2911 
2912 		s->EffectiveDETBufferSizeY = p->DETBufferSizeY[k];
2913 		if (p->UnboundedRequestEnabled) {
2914 			s->EffectiveDETBufferSizeY = s->EffectiveDETBufferSizeY + p->CompressedBufferSizeInkByte * 1024 * (p->SwathWidthY[k] * p->BytePerPixelDETY[k] * p->VRatio[k]) / (p->HTotal[k] / p->PixelClock[k]) / s->TotalPixelBW;
2915 		}
2916 
2917 		s->LinesInDETY[k] = (dml_float_t)s->EffectiveDETBufferSizeY / p->BytePerPixelDETY[k] / p->SwathWidthY[k];
2918 		s->LinesInDETYRoundedDownToSwath[k] = (dml_uint_t)(dml_floor(s->LinesInDETY[k], p->SwathHeightY[k]));
2919 		s->FullDETBufferingTimeY = s->LinesInDETYRoundedDownToSwath[k] * (p->HTotal[k] / p->PixelClock[k]) / p->VRatio[k];
2920 
2921 		s->ActiveClockChangeLatencyHidingY = s->EffectiveLBLatencyHidingY + s->FullDETBufferingTimeY - ((dml_float_t)p->DSTXAfterScaler[k] / (dml_float_t)p->HTotal[k] + (dml_float_t)p->DSTYAfterScaler[k]) * (dml_float_t)p->HTotal[k] / p->PixelClock[k];
2922 
2923 		if (p->NumberOfActiveSurfaces > 1) {
2924 			s->ActiveClockChangeLatencyHidingY = s->ActiveClockChangeLatencyHidingY - (1.0 - 1.0 / (dml_float_t)p->NumberOfActiveSurfaces) * (dml_float_t)p->SwathHeightY[k] * (dml_float_t)p->HTotal[k] / p->PixelClock[k] / p->VRatio[k];
2925 	}
2926 
2927 		if (p->BytePerPixelDETC[k] > 0) {
2928 			s->LinesInDETC[k] = p->DETBufferSizeC[k] / p->BytePerPixelDETC[k] / p->SwathWidthC[k];
2929 			s->LinesInDETCRoundedDownToSwath[k] = (dml_uint_t)(dml_floor(s->LinesInDETC[k], p->SwathHeightC[k]));
2930 			s->FullDETBufferingTimeC = s->LinesInDETCRoundedDownToSwath[k] * (p->HTotal[k] / p->PixelClock[k]) / p->VRatioChroma[k];
2931 			s->ActiveClockChangeLatencyHidingC = s->EffectiveLBLatencyHidingC + s->FullDETBufferingTimeC - ((dml_float_t)p->DSTXAfterScaler[k] / (dml_float_t)p->HTotal[k] + (dml_float_t)p->DSTYAfterScaler[k]) * (dml_float_t)p->HTotal[k] / p->PixelClock[k];
2932 			if (p->NumberOfActiveSurfaces > 1) {
2933 			s->ActiveClockChangeLatencyHidingC = s->ActiveClockChangeLatencyHidingC - (1.0 - 1.0 / (dml_float_t)p->NumberOfActiveSurfaces) * (dml_float_t)p->SwathHeightC[k] * (dml_float_t)p->HTotal[k] / p->PixelClock[k] / p->VRatioChroma[k];
2934 			}
2935 			s->ActiveClockChangeLatencyHiding = dml_min(s->ActiveClockChangeLatencyHidingY, s->ActiveClockChangeLatencyHidingC);
2936 		} else {
2937 			s->ActiveClockChangeLatencyHiding = s->ActiveClockChangeLatencyHidingY;
2938 		}
2939 
2940 		s->ActiveDRAMClockChangeLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->UrgentWatermark - p->Watermark->DRAMClockChangeWatermark;
2941 		s->ActiveFCLKChangeLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->UrgentWatermark - p->Watermark->FCLKChangeWatermark;
2942 		s->USRRetrainingLatencyMargin[k] = s->ActiveClockChangeLatencyHiding - p->Watermark->USRRetrainingWatermark;
2943 
2944 		if (p->WritebackEnable[k]) {
2945 			s->WritebackLatencyHiding = (dml_float_t)p->WritebackInterfaceBufferSize * 1024.0 / ((dml_float_t)p->WritebackDestinationWidth[k] * (dml_float_t)p->WritebackDestinationHeight[k] / ((dml_float_t)p->WritebackSourceHeight[k] * (dml_float_t)p->HTotal[k] / p->PixelClock[k]) * 4.0);
2946 			if (p->WritebackPixelFormat[k] == dml_444_64) {
2947 				s->WritebackLatencyHiding = s->WritebackLatencyHiding / 2;
2948 			}
2949 			s->WritebackDRAMClockChangeLatencyMargin = s->WritebackLatencyHiding - p->Watermark->WritebackDRAMClockChangeWatermark;
2950 
2951 			s->WritebackFCLKChangeLatencyMargin = s->WritebackLatencyHiding - p->Watermark->WritebackFCLKChangeWatermark;
2952 
2953 			s->ActiveDRAMClockChangeLatencyMargin[k] = dml_min(s->ActiveDRAMClockChangeLatencyMargin[k], s->WritebackFCLKChangeLatencyMargin);
2954 			s->ActiveFCLKChangeLatencyMargin[k] = dml_min(s->ActiveFCLKChangeLatencyMargin[k], s->WritebackDRAMClockChangeLatencyMargin);
2955 		}
2956 		p->MaxActiveDRAMClockChangeLatencySupported[k] =  (p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe) ? 0 : (s->ActiveDRAMClockChangeLatencyMargin[k] + p->mmSOCParameters.DRAMClockChangeLatency);
2957 		p->ActiveDRAMClockChangeLatencyMargin[k] = s->ActiveDRAMClockChangeLatencyMargin[k];
2958 	}
2959 
2960 	*p->USRRetrainingSupport = true;
2961 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
2962 		if ((p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) && (s->USRRetrainingLatencyMargin[k] < 0)) {
2963 			*p->USRRetrainingSupport = false;
2964 		}
2965 	}
2966 
2967 	s->FoundCriticalSurface = false;
2968 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
2969 		if ((p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) && ((!s->FoundCriticalSurface)
2970 			|| ((s->ActiveFCLKChangeLatencyMargin[k] + p->mmSOCParameters.FCLKChangeLatency) < *p->MaxActiveFCLKChangeLatencySupported))) {
2971 			s->FoundCriticalSurface = true;
2972 			*p->MaxActiveFCLKChangeLatencySupported = s->ActiveFCLKChangeLatencyMargin[k] + p->mmSOCParameters.FCLKChangeLatency;
2973 		}
2974 	}
2975 
2976 	for (dml_uint_t i = 0; i < p->NumberOfActiveSurfaces; ++i) {
2977 		for (dml_uint_t j = 0; j < p->NumberOfActiveSurfaces; ++j) {
2978 			if (i == j ||
2979 				(p->BlendingAndTiming[i] == i && p->BlendingAndTiming[j] == i) ||
2980 				(p->BlendingAndTiming[j] == j && p->BlendingAndTiming[i] == j) ||
2981 				(p->BlendingAndTiming[i] == p->BlendingAndTiming[j] && p->BlendingAndTiming[i] != i) ||
2982 				(p->SynchronizeTimingsFinal && p->PixelClock[i] == p->PixelClock[j] && p->HTotal[i] == p->HTotal[j] && p->VTotal[i] == p->VTotal[j] && p->VActive[i] == p->VActive[j]) ||
2983 				(p->SynchronizeDRRDisplaysForUCLKPStateChangeFinal && (p->DRRDisplay[i] || p->DRRDisplay[j]))) {
2984 				s->SynchronizedSurfaces[i][j] = true;
2985 			} else {
2986 				s->SynchronizedSurfaces[i][j] = false;
2987 			}
2988 		}
2989 	}
2990 
2991 	s->FCLKChangeSupportNumber = 0;
2992 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
2993 		if ((p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) &&  (s->ActiveFCLKChangeLatencyMargin[k] < 0)) {
2994 			if (!(p->PrefetchMode[k] <= 1)) {
2995 				s->FCLKChangeSupportNumber = 3;
2996 			} else if (s->FCLKChangeSupportNumber == 0) {
2997 				s->FCLKChangeSupportNumber = ((p->SynchronizeDRRDisplaysForUCLKPStateChangeFinal && p->DRRDisplay[k]) ? 2 : 1);
2998 				s->LastSurfaceWithoutMargin = k;
2999 			} else if (((s->FCLKChangeSupportNumber == 1) && (p->DRRDisplay[k] || (!s->SynchronizedSurfaces[s->LastSurfaceWithoutMargin][k]))) || (s->FCLKChangeSupportNumber == 2))
3000 				s->FCLKChangeSupportNumber = 3;
3001 		}
3002 	}
3003 
3004 	if (s->FCLKChangeSupportNumber == 0) {
3005 		*p->FCLKChangeSupport = dml_fclock_change_vactive;
3006 	} else if ((s->FCLKChangeSupportNumber == 1) || (s->FCLKChangeSupportNumber == 2)) {
3007 		*p->FCLKChangeSupport = dml_fclock_change_vblank;
3008 	} else {
3009 		*p->FCLKChangeSupport = dml_fclock_change_unsupported;
3010 	}
3011 
3012 	s->DRAMClockChangeMethod = 0;
3013 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
3014 		if (p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_full_frame)
3015 			s->DRAMClockChangeMethod = 1;
3016 		else if (p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_sub_viewport)
3017 			s->DRAMClockChangeMethod = 2;
3018 	}
3019 
3020 	s->DRAMClockChangeSupportNumber = 0;
3021 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
3022 		if (((s->DRAMClockChangeMethod == 0) && (s->ActiveDRAMClockChangeLatencyMargin[k] < 0)) ||
3023 			((s->DRAMClockChangeMethod == 1) && (p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_full_frame)) ||
3024 			((s->DRAMClockChangeMethod == 2) && (p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_sub_viewport) && (p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe))) {
3025 			if (p->PrefetchMode[k] != 0) { // Don't need to support DRAM clock change, PrefetchMode 0 means needs DRAM clock change support
3026 				s->DRAMClockChangeSupportNumber = 3;
3027 			} else if (s->DRAMClockChangeSupportNumber == 0) {
3028 				s->DRAMClockChangeSupportNumber =  (p->SynchronizeDRRDisplaysForUCLKPStateChangeFinal && p->DRRDisplay[k]) ? 2 : 1;
3029 				s->LastSurfaceWithoutMargin = k;
3030 			} else if (((s->DRAMClockChangeSupportNumber == 1) && (p->DRRDisplay[k] || !s->SynchronizedSurfaces[s->LastSurfaceWithoutMargin][k])) || (s->DRAMClockChangeSupportNumber == 2)) {
3031 				s->DRAMClockChangeSupportNumber = 3;
3032 			}
3033 		}
3034 	}
3035 
3036 	if (s->DRAMClockChangeMethod == 0) { // No MALL usage
3037 		if (s->DRAMClockChangeSupportNumber == 0) {
3038 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vactive;
3039 		} else if (s->DRAMClockChangeSupportNumber == 1) {
3040 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vblank;
3041 		} else if (s->DRAMClockChangeSupportNumber == 2) {
3042 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vblank_drr;
3043 		} else {
3044 			*p->DRAMClockChangeSupport = dml_dram_clock_change_unsupported;
3045 		}
3046 	} else if (s->DRAMClockChangeMethod == 1) { // Any pipe using MALL full frame
3047 		if (s->DRAMClockChangeSupportNumber == 0) {
3048 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vactive_w_mall_full_frame;
3049 		} else if (s->DRAMClockChangeSupportNumber == 1) {
3050 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vblank_w_mall_full_frame;
3051 		} else if (s->DRAMClockChangeSupportNumber == 2) {
3052 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vblank_drr_w_mall_full_frame;
3053 		} else {
3054 			*p->DRAMClockChangeSupport = dml_dram_clock_change_unsupported;
3055 		}
3056 	} else { // Any pipe using MALL subviewport
3057 		if (s->DRAMClockChangeSupportNumber == 0) {
3058 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vactive_w_mall_sub_vp;
3059 		} else if (s->DRAMClockChangeSupportNumber == 1) {
3060 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vblank_w_mall_sub_vp;
3061 		} else if (s->DRAMClockChangeSupportNumber == 2) {
3062 			*p->DRAMClockChangeSupport = dml_dram_clock_change_vblank_drr_w_mall_sub_vp;
3063 		} else {
3064 			*p->DRAMClockChangeSupport = dml_dram_clock_change_unsupported;
3065 		}
3066 	}
3067 
3068 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
3069 		s->dst_y_pstate = (dml_uint_t)(dml_ceil((p->mmSOCParameters.DRAMClockChangeLatency + p->mmSOCParameters.UrgentLatency) / (p->HTotal[k] / p->PixelClock[k]), 1));
3070 		s->src_y_pstate_l = (dml_uint_t)(dml_ceil(s->dst_y_pstate * p->VRatio[k], p->SwathHeightY[k]));
3071 		s->src_y_ahead_l = (dml_uint_t)(dml_floor(p->DETBufferSizeY[k] / p->BytePerPixelDETY[k] / p->SwathWidthY[k], p->SwathHeightY[k]) + s->LBLatencyHidingSourceLinesY[k]);
3072 		s->sub_vp_lines_l = s->src_y_pstate_l + s->src_y_ahead_l + p->meta_row_height[k];
3073 
3074 #ifdef __DML_VBA_DEBUG__
3075 		dml_print("DML::%s: k=%u, DETBufferSizeY = %u\n", __func__, k, p->DETBufferSizeY[k]);
3076 		dml_print("DML::%s: k=%u, BytePerPixelDETY = %f\n", __func__, k, p->BytePerPixelDETY[k]);
3077 		dml_print("DML::%s: k=%u, SwathWidthY = %u\n", __func__, k, p->SwathWidthY[k]);
3078 		dml_print("DML::%s: k=%u, SwathHeightY = %u\n", __func__, k, p->SwathHeightY[k]);
3079 		dml_print("DML::%s: k=%u, LBLatencyHidingSourceLinesY = %u\n", __func__, k, s->LBLatencyHidingSourceLinesY[k]);
3080 		dml_print("DML::%s: k=%u, dst_y_pstate = %u\n", __func__, k, s->dst_y_pstate);
3081 		dml_print("DML::%s: k=%u, src_y_pstate_l = %u\n", __func__, k, s->src_y_pstate_l);
3082 		dml_print("DML::%s: k=%u, src_y_ahead_l = %u\n", __func__, k, s->src_y_ahead_l);
3083 		dml_print("DML::%s: k=%u, meta_row_height = %u\n", __func__, k, p->meta_row_height[k]);
3084 		dml_print("DML::%s: k=%u, sub_vp_lines_l  = %u\n", __func__, k, s->sub_vp_lines_l);
3085 #endif
3086 		p->SubViewportLinesNeededInMALL[k] = s->sub_vp_lines_l;
3087 
3088 		if (p->BytePerPixelDETC[k] > 0) {
3089 		s->src_y_pstate_c = (dml_uint_t)(dml_ceil(s->dst_y_pstate * p->VRatioChroma[k], p->SwathHeightC[k]));
3090 		s->src_y_ahead_c = (dml_uint_t)(dml_floor(p->DETBufferSizeC[k] / p->BytePerPixelDETC[k] / p->SwathWidthC[k], p->SwathHeightC[k]) + s->LBLatencyHidingSourceLinesC[k]);
3091 		s->sub_vp_lines_c = s->src_y_pstate_c + s->src_y_ahead_c + p->meta_row_height_chroma[k];
3092 		p->SubViewportLinesNeededInMALL[k] = (dml_uint_t)(dml_max(s->sub_vp_lines_l, s->sub_vp_lines_c));
3093 
3094 #ifdef __DML_VBA_DEBUG__
3095 		dml_print("DML::%s: k=%u, src_y_pstate_c = %u\n", __func__, k, s->src_y_pstate_c);
3096 		dml_print("DML::%s: k=%u, src_y_ahead_c = %u\n", __func__, k, s->src_y_ahead_c);
3097 		dml_print("DML::%s: k=%u, meta_row_height_chroma = %u\n", __func__, k, p->meta_row_height_chroma[k]);
3098 		dml_print("DML::%s: k=%u, sub_vp_lines_c            = %u\n", __func__, k, s->sub_vp_lines_c);
3099 #endif
3100 		}
3101 	}
3102 
3103 #ifdef __DML_VBA_DEBUG__
3104 	dml_print("DML::%s: DRAMClockChangeSupport = %u\n", __func__, *p->DRAMClockChangeSupport);
3105 	dml_print("DML::%s: FCLKChangeSupport = %u\n", __func__, *p->FCLKChangeSupport);
3106 	dml_print("DML::%s: MaxActiveFCLKChangeLatencySupported = %f\n", __func__, *p->MaxActiveFCLKChangeLatencySupported);
3107 	dml_print("DML::%s: USRRetrainingSupport                        = %u\n", __func__, *p->USRRetrainingSupport);
3108 #endif
3109 } // CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport
3110 
CalculateDCFCLKDeepSleep(dml_uint_t NumberOfActiveSurfaces,dml_uint_t BytePerPixelY[],dml_uint_t BytePerPixelC[],dml_float_t VRatio[],dml_float_t VRatioChroma[],dml_uint_t SwathWidthY[],dml_uint_t SwathWidthC[],dml_uint_t DPPPerSurface[],dml_float_t HRatio[],dml_float_t HRatioChroma[],dml_float_t PixelClock[],dml_float_t PSCL_THROUGHPUT[],dml_float_t PSCL_THROUGHPUT_CHROMA[],dml_float_t Dppclk[],dml_float_t ReadBandwidthLuma[],dml_float_t ReadBandwidthChroma[],dml_uint_t ReturnBusWidth,dml_float_t * DCFClkDeepSleep)3111 static void CalculateDCFCLKDeepSleep(
3112 		dml_uint_t NumberOfActiveSurfaces,
3113 		dml_uint_t BytePerPixelY[],
3114 		dml_uint_t BytePerPixelC[],
3115 		dml_float_t VRatio[],
3116 		dml_float_t VRatioChroma[],
3117 		dml_uint_t SwathWidthY[],
3118 		dml_uint_t SwathWidthC[],
3119 		dml_uint_t DPPPerSurface[],
3120 		dml_float_t HRatio[],
3121 		dml_float_t HRatioChroma[],
3122 		dml_float_t PixelClock[],
3123 		dml_float_t PSCL_THROUGHPUT[],
3124 		dml_float_t PSCL_THROUGHPUT_CHROMA[],
3125 		dml_float_t Dppclk[],
3126 		dml_float_t ReadBandwidthLuma[],
3127 		dml_float_t ReadBandwidthChroma[],
3128 		dml_uint_t ReturnBusWidth,
3129 
3130 		// Output
3131 		dml_float_t *DCFClkDeepSleep)
3132 {
3133 	dml_float_t DisplayPipeLineDeliveryTimeLuma;
3134 	dml_float_t DisplayPipeLineDeliveryTimeChroma;
3135 	dml_float_t DCFClkDeepSleepPerSurface[__DML_NUM_PLANES__];
3136 	dml_float_t ReadBandwidth = 0.0;
3137 
3138 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3139 
3140 		if (VRatio[k] <= 1) {
3141 			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] * DPPPerSurface[k] / HRatio[k] / PixelClock[k];
3142 		} else {
3143 			DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] / PSCL_THROUGHPUT[k] / Dppclk[k];
3144 		}
3145 		if (BytePerPixelC[k] == 0) {
3146 			DisplayPipeLineDeliveryTimeChroma = 0;
3147 		} else {
3148 			if (VRatioChroma[k] <= 1) {
3149 				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] * DPPPerSurface[k] / HRatioChroma[k] / PixelClock[k];
3150 			} else {
3151 				DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] / PSCL_THROUGHPUT_CHROMA[k] / Dppclk[k];
3152 			}
3153 		}
3154 
3155 		if (BytePerPixelC[k] > 0) {
3156 			DCFClkDeepSleepPerSurface[k] = dml_max(__DML_MIN_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 32.0 / DisplayPipeLineDeliveryTimeLuma,
3157 														__DML_MIN_DCFCLK_FACTOR__ * SwathWidthC[k] * BytePerPixelC[k] / 32.0 / DisplayPipeLineDeliveryTimeChroma);
3158 		} else {
3159 			DCFClkDeepSleepPerSurface[k] = __DML_MIN_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 64.0 / DisplayPipeLineDeliveryTimeLuma;
3160 		}
3161 		DCFClkDeepSleepPerSurface[k] = dml_max(DCFClkDeepSleepPerSurface[k], PixelClock[k] / 16);
3162 
3163 #ifdef __DML_VBA_DEBUG__
3164 		dml_print("DML::%s: k=%u, PixelClock = %f\n", __func__, k, PixelClock[k]);
3165 		dml_print("DML::%s: k=%u, DCFClkDeepSleepPerSurface = %f\n", __func__, k, DCFClkDeepSleepPerSurface[k]);
3166 #endif
3167 	}
3168 
3169 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3170 		ReadBandwidth = ReadBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
3171 	}
3172 
3173 	*DCFClkDeepSleep = dml_max(8.0, __DML_MIN_DCFCLK_FACTOR__ * ReadBandwidth / (dml_float_t) ReturnBusWidth);
3174 
3175 #ifdef __DML_VBA_DEBUG__
3176 		dml_print("DML::%s: __DML_MIN_DCFCLK_FACTOR__ = %f\n", __func__, __DML_MIN_DCFCLK_FACTOR__);
3177 		dml_print("DML::%s: ReadBandwidth = %f\n", __func__, ReadBandwidth);
3178 		dml_print("DML::%s: ReturnBusWidth = %u\n", __func__, ReturnBusWidth);
3179 		dml_print("DML::%s: DCFClkDeepSleep = %f\n", __func__, *DCFClkDeepSleep);
3180 #endif
3181 
3182 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3183 		*DCFClkDeepSleep = dml_max(*DCFClkDeepSleep, DCFClkDeepSleepPerSurface[k]);
3184 	}
3185 	dml_print("DML::%s: DCFClkDeepSleep = %f (final)\n", __func__, *DCFClkDeepSleep);
3186 } // CalculateDCFCLKDeepSleep
3187 
CalculateUrgentBurstFactor(enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange,dml_uint_t swath_width_luma_ub,dml_uint_t swath_width_chroma_ub,dml_uint_t SwathHeightY,dml_uint_t SwathHeightC,dml_float_t LineTime,dml_float_t UrgentLatency,dml_float_t CursorBufferSize,dml_uint_t CursorWidth,dml_uint_t CursorBPP,dml_float_t VRatio,dml_float_t VRatioC,dml_float_t BytePerPixelInDETY,dml_float_t BytePerPixelInDETC,dml_uint_t DETBufferSizeY,dml_uint_t DETBufferSizeC,dml_float_t * UrgentBurstFactorCursor,dml_float_t * UrgentBurstFactorLuma,dml_float_t * UrgentBurstFactorChroma,dml_bool_t * NotEnoughUrgentLatencyHiding)3188 static void CalculateUrgentBurstFactor(
3189 		enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange,
3190 		dml_uint_t swath_width_luma_ub,
3191 		dml_uint_t swath_width_chroma_ub,
3192 		dml_uint_t SwathHeightY,
3193 		dml_uint_t SwathHeightC,
3194 		dml_float_t LineTime,
3195 		dml_float_t UrgentLatency,
3196 		dml_float_t CursorBufferSize,
3197 		dml_uint_t CursorWidth,
3198 		dml_uint_t CursorBPP,
3199 		dml_float_t VRatio,
3200 		dml_float_t VRatioC,
3201 		dml_float_t BytePerPixelInDETY,
3202 		dml_float_t BytePerPixelInDETC,
3203 		dml_uint_t DETBufferSizeY,
3204 		dml_uint_t DETBufferSizeC,
3205 		// Output
3206 		dml_float_t *UrgentBurstFactorCursor,
3207 		dml_float_t *UrgentBurstFactorLuma,
3208 		dml_float_t *UrgentBurstFactorChroma,
3209 		dml_bool_t *NotEnoughUrgentLatencyHiding)
3210 {
3211 	dml_float_t LinesInDETLuma;
3212 	dml_float_t LinesInDETChroma;
3213 	dml_uint_t LinesInCursorBuffer;
3214 	dml_float_t CursorBufferSizeInTime;
3215 	dml_float_t DETBufferSizeInTimeLuma;
3216 	dml_float_t DETBufferSizeInTimeChroma;
3217 
3218 	*NotEnoughUrgentLatencyHiding = 0;
3219 
3220 	if (CursorWidth > 0) {
3221 		LinesInCursorBuffer = 1 << (dml_uint_t) dml_floor(dml_log2(CursorBufferSize * 1024.0 / (CursorWidth * CursorBPP / 8.0)), 1.0);
3222 		if (VRatio > 0) {
3223 			CursorBufferSizeInTime = LinesInCursorBuffer * LineTime / VRatio;
3224 			if (CursorBufferSizeInTime - UrgentLatency <= 0) {
3225 				*NotEnoughUrgentLatencyHiding = 1;
3226 				*UrgentBurstFactorCursor = 0;
3227 			} else {
3228 				*UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency);
3229 			}
3230 		} else {
3231 			*UrgentBurstFactorCursor = 1;
3232 		}
3233 	}
3234 
3235 	LinesInDETLuma = (UseMALLForPStateChange == dml_use_mall_pstate_change_phantom_pipe ? 1024*1024 : DETBufferSizeY) / BytePerPixelInDETY / swath_width_luma_ub;
3236 
3237 	if (VRatio > 0) {
3238 		DETBufferSizeInTimeLuma = dml_floor(LinesInDETLuma, SwathHeightY) * LineTime / VRatio;
3239 		if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) {
3240 			*NotEnoughUrgentLatencyHiding = 1;
3241 			*UrgentBurstFactorLuma = 0;
3242 		} else {
3243 			*UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency);
3244 		}
3245 	} else {
3246 		*UrgentBurstFactorLuma = 1;
3247 	}
3248 
3249 	if (BytePerPixelInDETC > 0) {
3250 		LinesInDETChroma = (UseMALLForPStateChange == dml_use_mall_pstate_change_phantom_pipe ? 1024*1024 : DETBufferSizeC) / BytePerPixelInDETC / swath_width_chroma_ub;
3251 
3252 		if (VRatioC > 0) {
3253 			DETBufferSizeInTimeChroma = dml_floor(LinesInDETChroma, SwathHeightC) * LineTime / VRatioC;
3254 			if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) {
3255 				*NotEnoughUrgentLatencyHiding = 1;
3256 				*UrgentBurstFactorChroma = 0;
3257 			} else {
3258 				*UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency);
3259 			}
3260 		} else {
3261 			*UrgentBurstFactorChroma = 1;
3262 		}
3263 	}
3264 } // CalculateUrgentBurstFactor
3265 
CalculatePixelDeliveryTimes(dml_uint_t NumberOfActiveSurfaces,dml_float_t VRatio[],dml_float_t VRatioChroma[],dml_float_t VRatioPrefetchY[],dml_float_t VRatioPrefetchC[],dml_uint_t swath_width_luma_ub[],dml_uint_t swath_width_chroma_ub[],dml_uint_t DPPPerSurface[],dml_float_t HRatio[],dml_float_t HRatioChroma[],dml_float_t PixelClock[],dml_float_t PSCL_THROUGHPUT[],dml_float_t PSCL_THROUGHPUT_CHROMA[],dml_float_t Dppclk[],dml_uint_t BytePerPixelC[],enum dml_rotation_angle SourceScan[],dml_uint_t NumberOfCursors[],dml_uint_t CursorWidth[],dml_uint_t CursorBPP[],dml_uint_t BlockWidth256BytesY[],dml_uint_t BlockHeight256BytesY[],dml_uint_t BlockWidth256BytesC[],dml_uint_t BlockHeight256BytesC[],dml_float_t DisplayPipeLineDeliveryTimeLuma[],dml_float_t DisplayPipeLineDeliveryTimeChroma[],dml_float_t DisplayPipeLineDeliveryTimeLumaPrefetch[],dml_float_t DisplayPipeLineDeliveryTimeChromaPrefetch[],dml_float_t DisplayPipeRequestDeliveryTimeLuma[],dml_float_t DisplayPipeRequestDeliveryTimeChroma[],dml_float_t DisplayPipeRequestDeliveryTimeLumaPrefetch[],dml_float_t DisplayPipeRequestDeliveryTimeChromaPrefetch[],dml_float_t CursorRequestDeliveryTime[],dml_float_t CursorRequestDeliveryTimePrefetch[])3266 static void CalculatePixelDeliveryTimes(
3267 		dml_uint_t NumberOfActiveSurfaces,
3268 		dml_float_t VRatio[],
3269 		dml_float_t VRatioChroma[],
3270 		dml_float_t VRatioPrefetchY[],
3271 		dml_float_t VRatioPrefetchC[],
3272 		dml_uint_t swath_width_luma_ub[],
3273 		dml_uint_t swath_width_chroma_ub[],
3274 		dml_uint_t DPPPerSurface[],
3275 		dml_float_t HRatio[],
3276 		dml_float_t HRatioChroma[],
3277 		dml_float_t PixelClock[],
3278 		dml_float_t PSCL_THROUGHPUT[],
3279 		dml_float_t PSCL_THROUGHPUT_CHROMA[],
3280 		dml_float_t Dppclk[],
3281 		dml_uint_t BytePerPixelC[],
3282 		enum dml_rotation_angle SourceScan[],
3283 		dml_uint_t NumberOfCursors[],
3284 		dml_uint_t CursorWidth[],
3285 		dml_uint_t CursorBPP[],
3286 		dml_uint_t BlockWidth256BytesY[],
3287 		dml_uint_t BlockHeight256BytesY[],
3288 		dml_uint_t BlockWidth256BytesC[],
3289 		dml_uint_t BlockHeight256BytesC[],
3290 
3291 		// Output
3292 		dml_float_t DisplayPipeLineDeliveryTimeLuma[],
3293 		dml_float_t DisplayPipeLineDeliveryTimeChroma[],
3294 		dml_float_t DisplayPipeLineDeliveryTimeLumaPrefetch[],
3295 		dml_float_t DisplayPipeLineDeliveryTimeChromaPrefetch[],
3296 		dml_float_t DisplayPipeRequestDeliveryTimeLuma[],
3297 		dml_float_t DisplayPipeRequestDeliveryTimeChroma[],
3298 		dml_float_t DisplayPipeRequestDeliveryTimeLumaPrefetch[],
3299 		dml_float_t DisplayPipeRequestDeliveryTimeChromaPrefetch[],
3300 		dml_float_t CursorRequestDeliveryTime[],
3301 		dml_float_t CursorRequestDeliveryTimePrefetch[])
3302 {
3303 		dml_float_t req_per_swath_ub;
3304 
3305 		for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3306 
3307 #ifdef __DML_VBA_DEBUG__
3308 		dml_print("DML::%s: k=%u : HRatio = %f\n", __func__, k, HRatio[k]);
3309 		dml_print("DML::%s: k=%u : VRatio = %f\n", __func__, k, VRatio[k]);
3310 		dml_print("DML::%s: k=%u : HRatioChroma = %f\n", __func__, k, HRatioChroma[k]);
3311 		dml_print("DML::%s: k=%u : VRatioChroma = %f\n", __func__, k, VRatioChroma[k]);
3312 		dml_print("DML::%s: k=%u : swath_width_luma_ub = %u\n", __func__, k, swath_width_luma_ub[k]);
3313 		dml_print("DML::%s: k=%u : swath_width_chroma_ub = %u\n", __func__, k, swath_width_chroma_ub[k]);
3314 		dml_print("DML::%s: k=%u : PSCL_THROUGHPUT = %f\n", __func__, k, PSCL_THROUGHPUT[k]);
3315 		dml_print("DML::%s: k=%u : PSCL_THROUGHPUT_CHROMA = %f\n", __func__, k, PSCL_THROUGHPUT_CHROMA[k]);
3316 		dml_print("DML::%s: k=%u : DPPPerSurface = %u\n", __func__, k, DPPPerSurface[k]);
3317 		dml_print("DML::%s: k=%u : PixelClock = %f\n", __func__, k, PixelClock[k]);
3318 		dml_print("DML::%s: k=%u : Dppclk = %f\n", __func__, k, Dppclk[k]);
3319 #endif
3320 
3321 		if (VRatio[k] <= 1) {
3322 			DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] * DPPPerSurface[k] / HRatio[k] / PixelClock[k];
3323 		} else {
3324 			DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / Dppclk[k];
3325 		}
3326 
3327 		if (BytePerPixelC[k] == 0) {
3328 			DisplayPipeLineDeliveryTimeChroma[k] = 0;
3329 		} else {
3330 			if (VRatioChroma[k] <= 1) {
3331 				DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] * DPPPerSurface[k] / HRatioChroma[k] / PixelClock[k];
3332 			} else {
3333 				DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / Dppclk[k];
3334 			}
3335 		}
3336 
3337 		if (VRatioPrefetchY[k] <= 1) {
3338 			DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] * DPPPerSurface[k] / HRatio[k] / PixelClock[k];
3339 		} else {
3340 			DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / Dppclk[k];
3341 		}
3342 
3343 		if (BytePerPixelC[k] == 0) {
3344 			DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
3345 		} else {
3346 			if (VRatioPrefetchC[k] <= 1) {
3347 				DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] * DPPPerSurface[k] / HRatioChroma[k] / PixelClock[k];
3348 			} else {
3349 				DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / Dppclk[k];
3350 			}
3351 		}
3352 #ifdef __DML_VBA_DEBUG__
3353 		dml_print("DML::%s: k=%u : DisplayPipeLineDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLuma[k]);
3354 		dml_print("DML::%s: k=%u : DisplayPipeLineDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLumaPrefetch[k]);
3355 		dml_print("DML::%s: k=%u : DisplayPipeLineDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChroma[k]);
3356 		dml_print("DML::%s: k=%u : DisplayPipeLineDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChromaPrefetch[k]);
3357 #endif
3358 	}
3359 
3360 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3361 		if (!dml_is_vertical_rotation(SourceScan[k])) {
3362 			req_per_swath_ub = swath_width_luma_ub[k] / BlockWidth256BytesY[k];
3363 		} else {
3364 			req_per_swath_ub = swath_width_luma_ub[k] / BlockHeight256BytesY[k];
3365 		}
3366 #ifdef __DML_VBA_DEBUG__
3367 		dml_print("DML::%s: k=%u : req_per_swath_ub = %f (Luma)\n", __func__, k, req_per_swath_ub);
3368 #endif
3369 
3370 		DisplayPipeRequestDeliveryTimeLuma[k] = DisplayPipeLineDeliveryTimeLuma[k] / req_per_swath_ub;
3371 		DisplayPipeRequestDeliveryTimeLumaPrefetch[k] = DisplayPipeLineDeliveryTimeLumaPrefetch[k] / req_per_swath_ub;
3372 		if (BytePerPixelC[k] == 0) {
3373 			DisplayPipeRequestDeliveryTimeChroma[k] = 0;
3374 			DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = 0;
3375 		} else {
3376 			if (!dml_is_vertical_rotation(SourceScan[k])) {
3377 				req_per_swath_ub = swath_width_chroma_ub[k] / BlockWidth256BytesC[k];
3378 			} else {
3379 				req_per_swath_ub = swath_width_chroma_ub[k] / BlockHeight256BytesC[k];
3380 			}
3381 #ifdef __DML_VBA_DEBUG__
3382 			dml_print("DML::%s: k=%u : req_per_swath_ub = %f (Chroma)\n", __func__, k, req_per_swath_ub);
3383 #endif
3384 			DisplayPipeRequestDeliveryTimeChroma[k] = DisplayPipeLineDeliveryTimeChroma[k] / req_per_swath_ub;
3385 			DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = DisplayPipeLineDeliveryTimeChromaPrefetch[k] / req_per_swath_ub;
3386 		}
3387 #ifdef __DML_VBA_DEBUG__
3388 		dml_print("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLuma[k]);
3389 		dml_print("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLumaPrefetch[k]);
3390 		dml_print("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChroma[k]);
3391 		dml_print("DML::%s: k=%u : DisplayPipeRequestDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChromaPrefetch[k]);
3392 #endif
3393 	}
3394 
3395 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3396 		dml_uint_t cursor_req_per_width;
3397 		cursor_req_per_width = (dml_uint_t)(dml_ceil((dml_float_t) CursorWidth[k] * (dml_float_t) CursorBPP[k] / 256.0 / 8.0, 1.0));
3398 		if (NumberOfCursors[k] > 0) {
3399 			if (VRatio[k] <= 1) {
3400 				CursorRequestDeliveryTime[k] = (dml_float_t) CursorWidth[k] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
3401 			} else {
3402 				CursorRequestDeliveryTime[k] = (dml_float_t) CursorWidth[k] / PSCL_THROUGHPUT[k] / Dppclk[k] / cursor_req_per_width;
3403 			}
3404 			if (VRatioPrefetchY[k] <= 1) {
3405 				CursorRequestDeliveryTimePrefetch[k] = (dml_float_t) CursorWidth[k] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
3406 		} else {
3407 			CursorRequestDeliveryTimePrefetch[k] = (dml_float_t) CursorWidth[k] / PSCL_THROUGHPUT[k] / Dppclk[k] / cursor_req_per_width;
3408 			}
3409 		} else {
3410 			CursorRequestDeliveryTime[k] = 0;
3411 			CursorRequestDeliveryTimePrefetch[k] = 0;
3412 		}
3413 #ifdef __DML_VBA_DEBUG__
3414 		dml_print("DML::%s: k=%u : NumberOfCursors = %u\n", __func__, k, NumberOfCursors[k]);
3415 		dml_print("DML::%s: k=%u : CursorRequestDeliveryTime = %f\n", __func__, k, CursorRequestDeliveryTime[k]);
3416 		dml_print("DML::%s: k=%u : CursorRequestDeliveryTimePrefetch = %f\n", __func__, k, CursorRequestDeliveryTimePrefetch[k]);
3417 #endif
3418 	}
3419 } // CalculatePixelDeliveryTimes
3420 
CalculateMetaAndPTETimes(dml_bool_t use_one_row_for_frame[],dml_uint_t NumberOfActiveSurfaces,dml_bool_t GPUVMEnable,dml_uint_t MetaChunkSize,dml_uint_t MinMetaChunkSizeBytes,dml_uint_t HTotal[],dml_float_t VRatio[],dml_float_t VRatioChroma[],dml_float_t DestinationLinesToRequestRowInVBlank[],dml_float_t DestinationLinesToRequestRowInImmediateFlip[],dml_bool_t DCCEnable[],dml_float_t PixelClock[],dml_uint_t BytePerPixelY[],dml_uint_t BytePerPixelC[],enum dml_rotation_angle SourceScan[],dml_uint_t dpte_row_height[],dml_uint_t dpte_row_height_chroma[],dml_uint_t meta_row_width[],dml_uint_t meta_row_width_chroma[],dml_uint_t meta_row_height[],dml_uint_t meta_row_height_chroma[],dml_uint_t meta_req_width[],dml_uint_t meta_req_width_chroma[],dml_uint_t meta_req_height[],dml_uint_t meta_req_height_chroma[],dml_uint_t dpte_group_bytes[],dml_uint_t PTERequestSizeY[],dml_uint_t PTERequestSizeC[],dml_uint_t PixelPTEReqWidthY[],dml_uint_t PixelPTEReqHeightY[],dml_uint_t PixelPTEReqWidthC[],dml_uint_t PixelPTEReqHeightC[],dml_uint_t dpte_row_width_luma_ub[],dml_uint_t dpte_row_width_chroma_ub[],dml_float_t DST_Y_PER_PTE_ROW_NOM_L[],dml_float_t DST_Y_PER_PTE_ROW_NOM_C[],dml_float_t DST_Y_PER_META_ROW_NOM_L[],dml_float_t DST_Y_PER_META_ROW_NOM_C[],dml_float_t TimePerMetaChunkNominal[],dml_float_t TimePerChromaMetaChunkNominal[],dml_float_t TimePerMetaChunkVBlank[],dml_float_t TimePerChromaMetaChunkVBlank[],dml_float_t TimePerMetaChunkFlip[],dml_float_t TimePerChromaMetaChunkFlip[],dml_float_t time_per_pte_group_nom_luma[],dml_float_t time_per_pte_group_vblank_luma[],dml_float_t time_per_pte_group_flip_luma[],dml_float_t time_per_pte_group_nom_chroma[],dml_float_t time_per_pte_group_vblank_chroma[],dml_float_t time_per_pte_group_flip_chroma[])3421 static void CalculateMetaAndPTETimes(
3422 		dml_bool_t use_one_row_for_frame[],
3423 		dml_uint_t NumberOfActiveSurfaces,
3424 		dml_bool_t GPUVMEnable,
3425 		dml_uint_t MetaChunkSize,
3426 		dml_uint_t MinMetaChunkSizeBytes,
3427 		dml_uint_t HTotal[],
3428 		dml_float_t VRatio[],
3429 		dml_float_t VRatioChroma[],
3430 		dml_float_t DestinationLinesToRequestRowInVBlank[],
3431 		dml_float_t DestinationLinesToRequestRowInImmediateFlip[],
3432 		dml_bool_t DCCEnable[],
3433 		dml_float_t PixelClock[],
3434 		dml_uint_t BytePerPixelY[],
3435 		dml_uint_t BytePerPixelC[],
3436 		enum dml_rotation_angle SourceScan[],
3437 		dml_uint_t dpte_row_height[],
3438 		dml_uint_t dpte_row_height_chroma[],
3439 		dml_uint_t meta_row_width[],
3440 		dml_uint_t meta_row_width_chroma[],
3441 		dml_uint_t meta_row_height[],
3442 		dml_uint_t meta_row_height_chroma[],
3443 		dml_uint_t meta_req_width[],
3444 		dml_uint_t meta_req_width_chroma[],
3445 		dml_uint_t meta_req_height[],
3446 		dml_uint_t meta_req_height_chroma[],
3447 		dml_uint_t dpte_group_bytes[],
3448 		dml_uint_t PTERequestSizeY[],
3449 		dml_uint_t PTERequestSizeC[],
3450 		dml_uint_t PixelPTEReqWidthY[],
3451 		dml_uint_t PixelPTEReqHeightY[],
3452 		dml_uint_t PixelPTEReqWidthC[],
3453 		dml_uint_t PixelPTEReqHeightC[],
3454 		dml_uint_t dpte_row_width_luma_ub[],
3455 		dml_uint_t dpte_row_width_chroma_ub[],
3456 
3457 		// Output
3458 		dml_float_t DST_Y_PER_PTE_ROW_NOM_L[],
3459 		dml_float_t DST_Y_PER_PTE_ROW_NOM_C[],
3460 		dml_float_t DST_Y_PER_META_ROW_NOM_L[],
3461 		dml_float_t DST_Y_PER_META_ROW_NOM_C[],
3462 		dml_float_t TimePerMetaChunkNominal[],
3463 		dml_float_t TimePerChromaMetaChunkNominal[],
3464 		dml_float_t TimePerMetaChunkVBlank[],
3465 		dml_float_t TimePerChromaMetaChunkVBlank[],
3466 		dml_float_t TimePerMetaChunkFlip[],
3467 		dml_float_t TimePerChromaMetaChunkFlip[],
3468 		dml_float_t time_per_pte_group_nom_luma[],
3469 		dml_float_t time_per_pte_group_vblank_luma[],
3470 		dml_float_t time_per_pte_group_flip_luma[],
3471 		dml_float_t time_per_pte_group_nom_chroma[],
3472 		dml_float_t time_per_pte_group_vblank_chroma[],
3473 		dml_float_t time_per_pte_group_flip_chroma[])
3474 {
3475 	dml_uint_t meta_chunk_width;
3476 	dml_uint_t min_meta_chunk_width;
3477 	dml_uint_t meta_chunk_per_row_int;
3478 	dml_uint_t meta_row_remainder;
3479 	dml_uint_t meta_chunk_threshold;
3480 	dml_uint_t meta_chunks_per_row_ub;
3481 	dml_uint_t meta_chunk_width_chroma;
3482 	dml_uint_t min_meta_chunk_width_chroma;
3483 	dml_uint_t meta_chunk_per_row_int_chroma;
3484 	dml_uint_t meta_row_remainder_chroma;
3485 	dml_uint_t meta_chunk_threshold_chroma;
3486 	dml_uint_t meta_chunks_per_row_ub_chroma;
3487 	dml_uint_t dpte_group_width_luma;
3488 	dml_uint_t dpte_groups_per_row_luma_ub;
3489 	dml_uint_t dpte_group_width_chroma;
3490 	dml_uint_t dpte_groups_per_row_chroma_ub;
3491 
3492 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3493 		DST_Y_PER_PTE_ROW_NOM_L[k] = dpte_row_height[k] / VRatio[k];
3494 		if (BytePerPixelC[k] == 0) {
3495 			DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
3496 		} else {
3497 			DST_Y_PER_PTE_ROW_NOM_C[k] = dpte_row_height_chroma[k] / VRatioChroma[k];
3498 		}
3499 		DST_Y_PER_META_ROW_NOM_L[k] = meta_row_height[k] / VRatio[k];
3500 		if (BytePerPixelC[k] == 0) {
3501 			DST_Y_PER_META_ROW_NOM_C[k] = 0;
3502 		} else {
3503 			DST_Y_PER_META_ROW_NOM_C[k] = meta_row_height_chroma[k] / VRatioChroma[k];
3504 		}
3505 	}
3506 
3507 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3508 		if (DCCEnable[k] == true) {
3509 			meta_chunk_width = MetaChunkSize * 1024 * 256 / BytePerPixelY[k] / meta_row_height[k];
3510 			min_meta_chunk_width = MinMetaChunkSizeBytes * 256 / BytePerPixelY[k] / meta_row_height[k];
3511 			meta_chunk_per_row_int = meta_row_width[k] / meta_chunk_width;
3512 			meta_row_remainder = meta_row_width[k] % meta_chunk_width;
3513 			if (!dml_is_vertical_rotation(SourceScan[k])) {
3514 				meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width[k];
3515 			} else {
3516 				meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height[k];
3517 			}
3518 			if (meta_row_remainder <= meta_chunk_threshold) {
3519 				meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
3520 			} else {
3521 				meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
3522 			}
3523 			TimePerMetaChunkNominal[k] = meta_row_height[k] / VRatio[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
3524 			TimePerMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
3525 			TimePerMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
3526 			if (BytePerPixelC[k] == 0) {
3527 				TimePerChromaMetaChunkNominal[k] = 0;
3528 				TimePerChromaMetaChunkVBlank[k] = 0;
3529 				TimePerChromaMetaChunkFlip[k] = 0;
3530 			} else {
3531 				meta_chunk_width_chroma = MetaChunkSize * 1024 * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
3532 				min_meta_chunk_width_chroma = MinMetaChunkSizeBytes * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
3533 				meta_chunk_per_row_int_chroma = (dml_uint_t)((dml_float_t) meta_row_width_chroma[k] / meta_chunk_width_chroma);
3534 				meta_row_remainder_chroma = meta_row_width_chroma[k] % meta_chunk_width_chroma;
3535 				if (!dml_is_vertical_rotation(SourceScan[k])) {
3536 					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_width_chroma[k];
3537 				} else {
3538 					meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_height_chroma[k];
3539 				}
3540 				if (meta_row_remainder_chroma <= meta_chunk_threshold_chroma) {
3541 					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 1;
3542 				} else {
3543 					meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 2;
3544 				}
3545 				TimePerChromaMetaChunkNominal[k] = meta_row_height_chroma[k] / VRatioChroma[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
3546 				TimePerChromaMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
3547 				TimePerChromaMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
3548 			}
3549 		} else {
3550 			TimePerMetaChunkNominal[k] = 0;
3551 			TimePerMetaChunkVBlank[k] = 0;
3552 			TimePerMetaChunkFlip[k] = 0;
3553 			TimePerChromaMetaChunkNominal[k] = 0;
3554 			TimePerChromaMetaChunkVBlank[k] = 0;
3555 			TimePerChromaMetaChunkFlip[k] = 0;
3556 		}
3557 	}
3558 
3559 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3560 		if (GPUVMEnable == true) {
3561 			if (!dml_is_vertical_rotation(SourceScan[k])) {
3562 				dpte_group_width_luma = (dml_uint_t)((dml_float_t) dpte_group_bytes[k] / (dml_float_t) PTERequestSizeY[k] * PixelPTEReqWidthY[k]);
3563 			} else {
3564 				dpte_group_width_luma = (dml_uint_t)((dml_float_t) dpte_group_bytes[k] / (dml_float_t) PTERequestSizeY[k] * PixelPTEReqHeightY[k]);
3565 			}
3566 
3567 			if (use_one_row_for_frame[k]) {
3568 				dpte_groups_per_row_luma_ub = (dml_uint_t)(dml_ceil((dml_float_t) dpte_row_width_luma_ub[k] / (dml_float_t) dpte_group_width_luma / 2.0, 1.0));
3569 			} else {
3570 				dpte_groups_per_row_luma_ub = (dml_uint_t)(dml_ceil((dml_float_t) dpte_row_width_luma_ub[k] / (dml_float_t) dpte_group_width_luma, 1.0));
3571 			}
3572 
3573 			dml_print("DML::%s: k=%u, use_one_row_for_frame = %u\n", __func__, k, use_one_row_for_frame[k]);
3574 			dml_print("DML::%s: k=%u, dpte_group_bytes = %u\n", __func__, k, dpte_group_bytes[k]);
3575 			dml_print("DML::%s: k=%u, PTERequestSizeY = %u\n", __func__, k, PTERequestSizeY[k]);
3576 			dml_print("DML::%s: k=%u, PixelPTEReqWidthY = %u\n", __func__, k, PixelPTEReqWidthY[k]);
3577 			dml_print("DML::%s: k=%u, PixelPTEReqHeightY = %u\n", __func__, k, PixelPTEReqHeightY[k]);
3578 			dml_print("DML::%s: k=%u, dpte_row_width_luma_ub = %u\n", __func__, k, dpte_row_width_luma_ub[k]);
3579 			dml_print("DML::%s: k=%u, dpte_group_width_luma = %u\n", __func__, k, dpte_group_width_luma);
3580 			dml_print("DML::%s: k=%u, dpte_groups_per_row_luma_ub = %u\n", __func__, k, dpte_groups_per_row_luma_ub);
3581 
3582 			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;
3583 			time_per_pte_group_vblank_luma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
3584 			time_per_pte_group_flip_luma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
3585 			if (BytePerPixelC[k] == 0) {
3586 				time_per_pte_group_nom_chroma[k] = 0;
3587 				time_per_pte_group_vblank_chroma[k] = 0;
3588 				time_per_pte_group_flip_chroma[k] = 0;
3589 			} else {
3590 				if (!dml_is_vertical_rotation(SourceScan[k])) {
3591 					dpte_group_width_chroma = (dml_uint_t)((dml_float_t) dpte_group_bytes[k] / (dml_float_t) PTERequestSizeC[k] * PixelPTEReqWidthC[k]);
3592 				} else {
3593 					dpte_group_width_chroma = (dml_uint_t)((dml_float_t) dpte_group_bytes[k] / (dml_float_t) PTERequestSizeC[k] * PixelPTEReqHeightC[k]);
3594 				}
3595 
3596 				if (use_one_row_for_frame[k]) {
3597 					dpte_groups_per_row_chroma_ub = (dml_uint_t)(dml_ceil((dml_float_t) dpte_row_width_chroma_ub[k] / (dml_float_t) dpte_group_width_chroma / 2.0, 1.0));
3598 				} else {
3599 					dpte_groups_per_row_chroma_ub = (dml_uint_t)(dml_ceil((dml_float_t) dpte_row_width_chroma_ub[k] / (dml_float_t) dpte_group_width_chroma, 1.0));
3600 				}
3601 				dml_print("DML::%s: k=%u, dpte_row_width_chroma_ub = %u\n", __func__, k, dpte_row_width_chroma_ub[k]);
3602 				dml_print("DML::%s: k=%u, dpte_group_width_chroma = %u\n", __func__, k, dpte_group_width_chroma);
3603 				dml_print("DML::%s: k=%u, dpte_groups_per_row_chroma_ub = %u\n", __func__, k, dpte_groups_per_row_chroma_ub);
3604 
3605 				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;
3606 				time_per_pte_group_vblank_chroma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
3607 				time_per_pte_group_flip_chroma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
3608 			}
3609 		} else {
3610 			time_per_pte_group_nom_luma[k] = 0;
3611 			time_per_pte_group_vblank_luma[k] = 0;
3612 			time_per_pte_group_flip_luma[k] = 0;
3613 			time_per_pte_group_nom_chroma[k] = 0;
3614 			time_per_pte_group_vblank_chroma[k] = 0;
3615 			time_per_pte_group_flip_chroma[k] = 0;
3616 		}
3617 #ifdef __DML_VBA_DEBUG__
3618 		dml_print("DML::%s: k=%u, DestinationLinesToRequestRowInVBlank = %f\n", __func__, k, DestinationLinesToRequestRowInVBlank[k]);
3619 		dml_print("DML::%s: k=%u, DestinationLinesToRequestRowInImmediateFlip = %f\n", __func__, k, DestinationLinesToRequestRowInImmediateFlip[k]);
3620 
3621 		dml_print("DML::%s: k=%u, DST_Y_PER_PTE_ROW_NOM_L = %f\n", __func__, k, DST_Y_PER_PTE_ROW_NOM_L[k]);
3622 		dml_print("DML::%s: k=%u, DST_Y_PER_PTE_ROW_NOM_C = %f\n", __func__, k, DST_Y_PER_PTE_ROW_NOM_C[k]);
3623 		dml_print("DML::%s: k=%u, DST_Y_PER_META_ROW_NOM_L = %f\n", __func__, k, DST_Y_PER_META_ROW_NOM_L[k]);
3624 		dml_print("DML::%s: k=%u, DST_Y_PER_META_ROW_NOM_C = %f\n", __func__, k, DST_Y_PER_META_ROW_NOM_C[k]);
3625 		dml_print("DML::%s: k=%u, TimePerMetaChunkNominal = %f\n", __func__, k, TimePerMetaChunkNominal[k]);
3626 		dml_print("DML::%s: k=%u, TimePerMetaChunkVBlank = %f\n", __func__, k, TimePerMetaChunkVBlank[k]);
3627 		dml_print("DML::%s: k=%u, TimePerMetaChunkFlip = %f\n", __func__, k, TimePerMetaChunkFlip[k]);
3628 		dml_print("DML::%s: k=%u, TimePerChromaMetaChunkNominal = %f\n", __func__, k, TimePerChromaMetaChunkNominal[k]);
3629 		dml_print("DML::%s: k=%u, TimePerChromaMetaChunkVBlank = %f\n", __func__, k, TimePerChromaMetaChunkVBlank[k]);
3630 		dml_print("DML::%s: k=%u, TimePerChromaMetaChunkFlip = %f\n", __func__, k, TimePerChromaMetaChunkFlip[k]);
3631 		dml_print("DML::%s: k=%u, time_per_pte_group_nom_luma = %f\n", __func__, k, time_per_pte_group_nom_luma[k]);
3632 		dml_print("DML::%s: k=%u, time_per_pte_group_vblank_luma = %f\n", __func__, k, time_per_pte_group_vblank_luma[k]);
3633 		dml_print("DML::%s: k=%u, time_per_pte_group_flip_luma = %f\n", __func__, k, time_per_pte_group_flip_luma[k]);
3634 		dml_print("DML::%s: k=%u, time_per_pte_group_nom_chroma = %f\n", __func__, k, time_per_pte_group_nom_chroma[k]);
3635 		dml_print("DML::%s: k=%u, time_per_pte_group_vblank_chroma = %f\n", __func__, k, time_per_pte_group_vblank_chroma[k]);
3636 		dml_print("DML::%s: k=%u, time_per_pte_group_flip_chroma   = %f\n", __func__, k, time_per_pte_group_flip_chroma[k]);
3637 #endif
3638 	}
3639 } // CalculateMetaAndPTETimes
3640 
CalculateVMGroupAndRequestTimes(dml_uint_t NumberOfActiveSurfaces,dml_bool_t GPUVMEnable,dml_uint_t GPUVMMaxPageTableLevels,dml_uint_t HTotal[],dml_uint_t BytePerPixelC[],dml_float_t DestinationLinesToRequestVMInVBlank[],dml_float_t DestinationLinesToRequestVMInImmediateFlip[],dml_bool_t DCCEnable[],dml_float_t PixelClock[],dml_uint_t dpte_row_width_luma_ub[],dml_uint_t dpte_row_width_chroma_ub[],dml_uint_t vm_group_bytes[],dml_uint_t dpde0_bytes_per_frame_ub_l[],dml_uint_t dpde0_bytes_per_frame_ub_c[],dml_uint_t meta_pte_bytes_per_frame_ub_l[],dml_uint_t meta_pte_bytes_per_frame_ub_c[],dml_float_t TimePerVMGroupVBlank[],dml_float_t TimePerVMGroupFlip[],dml_float_t TimePerVMRequestVBlank[],dml_float_t TimePerVMRequestFlip[])3641 static void CalculateVMGroupAndRequestTimes(
3642 		dml_uint_t NumberOfActiveSurfaces,
3643 		dml_bool_t GPUVMEnable,
3644 		dml_uint_t GPUVMMaxPageTableLevels,
3645 		dml_uint_t HTotal[],
3646 		dml_uint_t BytePerPixelC[],
3647 		dml_float_t DestinationLinesToRequestVMInVBlank[],
3648 		dml_float_t DestinationLinesToRequestVMInImmediateFlip[],
3649 		dml_bool_t DCCEnable[],
3650 		dml_float_t PixelClock[],
3651 		dml_uint_t dpte_row_width_luma_ub[],
3652 		dml_uint_t dpte_row_width_chroma_ub[],
3653 		dml_uint_t vm_group_bytes[],
3654 		dml_uint_t dpde0_bytes_per_frame_ub_l[],
3655 		dml_uint_t dpde0_bytes_per_frame_ub_c[],
3656 		dml_uint_t meta_pte_bytes_per_frame_ub_l[],
3657 		dml_uint_t meta_pte_bytes_per_frame_ub_c[],
3658 
3659 		// Output
3660 		dml_float_t TimePerVMGroupVBlank[],
3661 		dml_float_t TimePerVMGroupFlip[],
3662 		dml_float_t TimePerVMRequestVBlank[],
3663 		dml_float_t TimePerVMRequestFlip[])
3664 {
3665 	dml_uint_t num_group_per_lower_vm_stage;
3666 	dml_uint_t num_req_per_lower_vm_stage;
3667 
3668 #ifdef __DML_VBA_DEBUG__
3669 	dml_print("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces);
3670 	dml_print("DML::%s: GPUVMEnable = %u\n", __func__, GPUVMEnable);
3671 #endif
3672 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
3673 
3674 #ifdef __DML_VBA_DEBUG__
3675 		dml_print("DML::%s: k=%u, DCCEnable = %u\n", __func__, k, DCCEnable[k]);
3676 		dml_print("DML::%s: k=%u, vm_group_bytes = %u\n", __func__, k, vm_group_bytes[k]);
3677 		dml_print("DML::%s: k=%u, dpde0_bytes_per_frame_ub_l = %u\n", __func__, k, dpde0_bytes_per_frame_ub_l[k]);
3678 		dml_print("DML::%s: k=%u, dpde0_bytes_per_frame_ub_c = %u\n", __func__, k, dpde0_bytes_per_frame_ub_c[k]);
3679 		dml_print("DML::%s: k=%u, meta_pte_bytes_per_frame_ub_l = %u\n", __func__, k, meta_pte_bytes_per_frame_ub_l[k]);
3680 		dml_print("DML::%s: k=%u, meta_pte_bytes_per_frame_ub_c = %u\n", __func__, k, meta_pte_bytes_per_frame_ub_c[k]);
3681 #endif
3682 
3683 		if (GPUVMEnable == true && (DCCEnable[k] == true || GPUVMMaxPageTableLevels > 1)) {
3684 			if (DCCEnable[k] == false) {
3685 				if (BytePerPixelC[k] > 0) {
3686 					num_group_per_lower_vm_stage = (dml_uint_t) (dml_ceil((dml_float_t) dpde0_bytes_per_frame_ub_l[k] / (dml_float_t) vm_group_bytes[k], 1.0) +
3687 													dml_ceil((dml_float_t) dpde0_bytes_per_frame_ub_c[k] / (dml_float_t) vm_group_bytes[k], 1.0));
3688 				} else {
3689 					num_group_per_lower_vm_stage = (dml_uint_t) (dml_ceil((dml_float_t) dpde0_bytes_per_frame_ub_l[k] / (dml_float_t) vm_group_bytes[k], 1.0));
3690 				}
3691 			} else {
3692 				if (GPUVMMaxPageTableLevels == 1) {
3693 					if (BytePerPixelC[k] > 0) {
3694 						num_group_per_lower_vm_stage = (dml_uint_t)(dml_ceil((dml_float_t) (meta_pte_bytes_per_frame_ub_l[k]) / (dml_float_t) (vm_group_bytes[k]), 1.0) +
3695 																	dml_ceil((dml_float_t) (meta_pte_bytes_per_frame_ub_c[k]) / (dml_float_t) (vm_group_bytes[k]), 1.0));
3696 					} else {
3697 						num_group_per_lower_vm_stage = (dml_uint_t)(dml_ceil((dml_float_t) (meta_pte_bytes_per_frame_ub_l[k]) / (dml_float_t) (vm_group_bytes[k]), 1.0));
3698 					}
3699 				} else {
3700 					if (BytePerPixelC[k] > 0) {
3701 						num_group_per_lower_vm_stage = (dml_uint_t)(2.0 + dml_ceil((dml_float_t) (dpde0_bytes_per_frame_ub_l[k]) / (dml_float_t) (vm_group_bytes[k]), 1) +
3702 														dml_ceil((dml_float_t) (dpde0_bytes_per_frame_ub_c[k]) / (dml_float_t) (vm_group_bytes[k]), 1) +
3703 														dml_ceil((dml_float_t) (meta_pte_bytes_per_frame_ub_l[k]) / (dml_float_t) (vm_group_bytes[k]), 1) +
3704 														dml_ceil((dml_float_t) (meta_pte_bytes_per_frame_ub_c[k]) / (dml_float_t) (vm_group_bytes[k]), 1));
3705 					} else {
3706 						num_group_per_lower_vm_stage = (dml_uint_t)(1.0 + dml_ceil((dml_float_t) (dpde0_bytes_per_frame_ub_l[k]) / (dml_float_t) (vm_group_bytes[k]), 1) +
3707 																	dml_ceil((dml_float_t) (meta_pte_bytes_per_frame_ub_l[k]) / (dml_float_t) (vm_group_bytes[k]), 1));
3708 					}
3709 				}
3710 			}
3711 
3712 			if (DCCEnable[k] == false) {
3713 				if (BytePerPixelC[k] > 0) {
3714 					num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + dpde0_bytes_per_frame_ub_c[k] / 64;
3715 				} else {
3716 					num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64;
3717 				}
3718 			} else {
3719 				if (GPUVMMaxPageTableLevels == 1) {
3720 					if (BytePerPixelC[k] > 0) {
3721 						num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_c[k] / 64;
3722 					} else {
3723 						num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64;
3724 					}
3725 				} else {
3726 					if (BytePerPixelC[k] > 0) {
3727 						num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + dpde0_bytes_per_frame_ub_c[k] / 64 + meta_pte_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_c[k] / 64;
3728 					} else {
3729 						num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_l[k] / 64;
3730 					}
3731 				}
3732 			}
3733 
3734 			TimePerVMGroupVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k] / num_group_per_lower_vm_stage;
3735 			TimePerVMGroupFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k] / num_group_per_lower_vm_stage;
3736 			TimePerVMRequestVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
3737 			TimePerVMRequestFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
3738 
3739 			if (GPUVMMaxPageTableLevels > 2) {
3740 				TimePerVMGroupVBlank[k] = TimePerVMGroupVBlank[k] / 2;
3741 				TimePerVMGroupFlip[k] = TimePerVMGroupFlip[k] / 2;
3742 				TimePerVMRequestVBlank[k] = TimePerVMRequestVBlank[k] / 2;
3743 				TimePerVMRequestFlip[k]    = TimePerVMRequestFlip[k] / 2;
3744 			}
3745 
3746 		} else {
3747 			TimePerVMGroupVBlank[k] = 0;
3748 			TimePerVMGroupFlip[k] = 0;
3749 			TimePerVMRequestVBlank[k] = 0;
3750 			TimePerVMRequestFlip[k] = 0;
3751 		}
3752 
3753 #ifdef __DML_VBA_DEBUG__
3754 			dml_print("DML::%s: k=%u, TimePerVMGroupVBlank = %f\n", __func__, k, TimePerVMGroupVBlank[k]);
3755 			dml_print("DML::%s: k=%u, TimePerVMGroupFlip = %f\n", __func__, k, TimePerVMGroupFlip[k]);
3756 			dml_print("DML::%s: k=%u, TimePerVMRequestVBlank = %f\n", __func__, k, TimePerVMRequestVBlank[k]);
3757 			dml_print("DML::%s: k=%u, TimePerVMRequestFlip = %f\n", __func__, k, TimePerVMRequestFlip[k]);
3758 #endif
3759 	}
3760 } // CalculateVMGroupAndRequestTimes
3761 
CalculateStutterEfficiency(struct display_mode_lib_scratch_st * scratch,struct CalculateStutterEfficiency_params_st * p)3762 static void CalculateStutterEfficiency(struct display_mode_lib_scratch_st *scratch,
3763 		struct CalculateStutterEfficiency_params_st *p)
3764 {
3765 	dml_float_t DETBufferingTimeY = 0;
3766 	dml_float_t SwathWidthYCriticalSurface = 0;
3767 	dml_float_t SwathHeightYCriticalSurface = 0;
3768 	dml_float_t VActiveTimeCriticalSurface = 0;
3769 	dml_float_t FrameTimeCriticalSurface = 0;
3770 	dml_uint_t BytePerPixelYCriticalSurface = 0;
3771 	dml_float_t LinesToFinishSwathTransferStutterCriticalSurface = 0;
3772 	dml_uint_t DETBufferSizeYCriticalSurface = 0;
3773 	dml_float_t MinTTUVBlankCriticalSurface = 0;
3774 	dml_uint_t BlockWidth256BytesYCriticalSurface = 0;
3775 	dml_bool_t SinglePlaneCriticalSurface = 0;
3776 	dml_bool_t SinglePipeCriticalSurface = 0;
3777 	dml_float_t TotalCompressedReadBandwidth = 0;
3778 	dml_float_t TotalRowReadBandwidth = 0;
3779 	dml_float_t AverageDCCCompressionRate = 0;
3780 	dml_float_t EffectiveCompressedBufferSize = 0;
3781 	dml_float_t PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = 0;
3782 	dml_float_t StutterBurstTime = 0;
3783 	dml_uint_t TotalActiveWriteback = 0;
3784 	dml_float_t LinesInDETY = 0;
3785 	dml_float_t LinesInDETYRoundedDownToSwath = 0;
3786 	dml_float_t MaximumEffectiveCompressionLuma = 0;
3787 	dml_float_t MaximumEffectiveCompressionChroma = 0;
3788 	dml_float_t TotalZeroSizeRequestReadBandwidth = 0;
3789 	dml_float_t TotalZeroSizeCompressedReadBandwidth = 0;
3790 	dml_float_t AverageDCCZeroSizeFraction = 0;
3791 	dml_float_t AverageZeroSizeCompressionRate = 0;
3792 
3793 	dml_bool_t FoundCriticalSurface = false;
3794 
3795 	dml_uint_t TotalNumberOfActiveOTG = 0;
3796 	dml_float_t SinglePixelClock = 0;
3797 	dml_uint_t SingleHTotal = 0;
3798 	dml_uint_t SingleVTotal = 0;
3799 	dml_bool_t SameTiming = true;
3800 
3801 	dml_float_t LastStutterPeriod = 0.0;
3802 	dml_float_t LastZ8StutterPeriod = 0.0;
3803 
3804 	dml_uint_t SwathSizeCriticalSurface;
3805 	dml_uint_t LastChunkOfSwathSize;
3806 	dml_uint_t MissingPartOfLastSwathOfDETSize;
3807 
3808 	TotalZeroSizeRequestReadBandwidth = 0;
3809 	TotalZeroSizeCompressedReadBandwidth = 0;
3810 	TotalRowReadBandwidth = 0;
3811 	TotalCompressedReadBandwidth = 0;
3812 
3813 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
3814 	if (p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) {
3815 		if (p->DCCEnable[k] == true) {
3816 			if ((dml_is_vertical_rotation(p->SourceScan[k]) && p->BlockWidth256BytesY[k] > p->SwathHeightY[k]) || (!dml_is_vertical_rotation(p->SourceScan[k]) && p->BlockHeight256BytesY[k] > p->SwathHeightY[k]) || p->DCCYMaxUncompressedBlock[k] < 256) {
3817 				MaximumEffectiveCompressionLuma = 2;
3818 			} else {
3819 				MaximumEffectiveCompressionLuma = 4;
3820 			}
3821 			TotalCompressedReadBandwidth = TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] / dml_min(p->NetDCCRateLuma[k], MaximumEffectiveCompressionLuma);
3822 #ifdef __DML_VBA_DEBUG__
3823 			dml_print("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, p->ReadBandwidthSurfaceLuma[k]);
3824 			dml_print("DML::%s: k=%u, NetDCCRateLuma = %f\n", __func__, k, p->NetDCCRateLuma[k]);
3825 			dml_print("DML::%s: k=%u, MaximumEffectiveCompressionLuma = %f\n", __func__, k, MaximumEffectiveCompressionLuma);
3826 #endif
3827 			TotalZeroSizeRequestReadBandwidth = TotalZeroSizeRequestReadBandwidth + p->ReadBandwidthSurfaceLuma[k] * p->DCCFractionOfZeroSizeRequestsLuma[k];
3828 			TotalZeroSizeCompressedReadBandwidth = TotalZeroSizeCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] * p->DCCFractionOfZeroSizeRequestsLuma[k] / MaximumEffectiveCompressionLuma;
3829 
3830 			if (p->ReadBandwidthSurfaceChroma[k] > 0) {
3831 				if ((dml_is_vertical_rotation(p->SourceScan[k]) && p->BlockWidth256BytesC[k] > p->SwathHeightC[k]) || (!dml_is_vertical_rotation(p->SourceScan[k]) && p->BlockHeight256BytesC[k] > p->SwathHeightC[k]) || p->DCCCMaxUncompressedBlock[k] < 256) {
3832 					MaximumEffectiveCompressionChroma = 2;
3833 				} else {
3834 					MaximumEffectiveCompressionChroma = 4;
3835 				}
3836 				TotalCompressedReadBandwidth = TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceChroma[k] / dml_min(p->NetDCCRateChroma[k], MaximumEffectiveCompressionChroma);
3837 #ifdef __DML_VBA_DEBUG__
3838 				dml_print("DML::%s: k=%u, ReadBandwidthSurfaceChroma = %f\n", __func__, k, p->ReadBandwidthSurfaceChroma[k]);
3839 				dml_print("DML::%s: k=%u, NetDCCRateChroma = %f\n", __func__, k, p->NetDCCRateChroma[k]);
3840 				dml_print("DML::%s: k=%u, MaximumEffectiveCompressionChroma = %f\n", __func__, k, MaximumEffectiveCompressionChroma);
3841 #endif
3842 				TotalZeroSizeRequestReadBandwidth = TotalZeroSizeRequestReadBandwidth + p->ReadBandwidthSurfaceChroma[k] * p->DCCFractionOfZeroSizeRequestsChroma[k];
3843 				TotalZeroSizeCompressedReadBandwidth = TotalZeroSizeCompressedReadBandwidth + p->ReadBandwidthSurfaceChroma[k] * p->DCCFractionOfZeroSizeRequestsChroma[k] / MaximumEffectiveCompressionChroma;
3844 			}
3845 		} else {
3846 			TotalCompressedReadBandwidth = TotalCompressedReadBandwidth + p->ReadBandwidthSurfaceLuma[k] + p->ReadBandwidthSurfaceChroma[k];
3847 		}
3848 		TotalRowReadBandwidth = TotalRowReadBandwidth + p->DPPPerSurface[k] * (p->meta_row_bw[k] + p->dpte_row_bw[k]);
3849 	}
3850 	}
3851 
3852 	AverageDCCCompressionRate = p->TotalDataReadBandwidth / TotalCompressedReadBandwidth;
3853 	AverageDCCZeroSizeFraction = TotalZeroSizeRequestReadBandwidth / p->TotalDataReadBandwidth;
3854 
3855 #ifdef __DML_VBA_DEBUG__
3856 	dml_print("DML::%s: UnboundedRequestEnabled = %u\n", __func__, p->UnboundedRequestEnabled);
3857 	dml_print("DML::%s: TotalCompressedReadBandwidth = %f\n", __func__, TotalCompressedReadBandwidth);
3858 	dml_print("DML::%s: TotalZeroSizeRequestReadBandwidth = %f\n", __func__, TotalZeroSizeRequestReadBandwidth);
3859 	dml_print("DML::%s: TotalZeroSizeCompressedReadBandwidth = %f\n", __func__, TotalZeroSizeCompressedReadBandwidth);
3860 	dml_print("DML::%s: MaximumEffectiveCompressionLuma = %f\n", __func__, MaximumEffectiveCompressionLuma);
3861 	dml_print("DML::%s: MaximumEffectiveCompressionChroma = %f\n", __func__, MaximumEffectiveCompressionChroma);
3862 	dml_print("DML::%s: AverageDCCCompressionRate = %f\n", __func__, AverageDCCCompressionRate);
3863 	dml_print("DML::%s: AverageDCCZeroSizeFraction = %f\n", __func__, AverageDCCZeroSizeFraction);
3864 	dml_print("DML::%s: CompbufReservedSpace64B = %u\n", __func__, p->CompbufReservedSpace64B);
3865 	dml_print("DML::%s: CompbufReservedSpaceZs = %u\n", __func__, p->CompbufReservedSpaceZs);
3866 	dml_print("DML::%s: CompressedBufferSizeInkByte = %u\n", __func__, p->CompressedBufferSizeInkByte);
3867 #endif
3868 	if (AverageDCCZeroSizeFraction == 1) {
3869 		AverageZeroSizeCompressionRate = TotalZeroSizeRequestReadBandwidth / TotalZeroSizeCompressedReadBandwidth;
3870 		EffectiveCompressedBufferSize = (dml_float_t)p->MetaFIFOSizeInKEntries * 1024 * 64 * AverageZeroSizeCompressionRate + ((dml_float_t)p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 * AverageZeroSizeCompressionRate;
3871 	} 	else if (AverageDCCZeroSizeFraction > 0) {
3872 		AverageZeroSizeCompressionRate = TotalZeroSizeRequestReadBandwidth / TotalZeroSizeCompressedReadBandwidth;
3873 		EffectiveCompressedBufferSize = dml_min((dml_float_t)p->CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate,
3874 											(dml_float_t)p->MetaFIFOSizeInKEntries * 1024 * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate + 1 / AverageDCCCompressionRate)) +
3875 										dml_min(((dml_float_t)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64) * AverageDCCCompressionRate,
3876 											((dml_float_t)p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate));
3877 
3878 #ifdef __DML_VBA_DEBUG__
3879 		dml_print("DML::%s: min 1 = %f\n", __func__, p->CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate);
3880 		dml_print("DML::%s: min 2 = %f\n", __func__, p->MetaFIFOSizeInKEntries * 1024 * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate + 1 / AverageDCCCompressionRate));
3881 		dml_print("DML::%s: min 3 = %f\n", __func__, (p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64) * AverageDCCCompressionRate);
3882 		dml_print("DML::%s: min 4 = %f\n", __func__, (p->ZeroSizeBufferEntries - p->CompbufReservedSpaceZs) * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate));
3883 #endif
3884 	} else {
3885 		EffectiveCompressedBufferSize = dml_min((dml_float_t)p->CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate,
3886 												(dml_float_t)p->MetaFIFOSizeInKEntries * 1024 * 64 * AverageDCCCompressionRate) +
3887 												((dml_float_t)p->ROBBufferSizeInKByte * 1024 - p->CompbufReservedSpace64B * 64) * AverageDCCCompressionRate;
3888 
3889 #ifdef __DML_VBA_DEBUG__
3890 		dml_print("DML::%s: min 1 = %f\n", __func__, p->CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate);
3891 		dml_print("DML::%s: min 2 = %f\n", __func__, p->MetaFIFOSizeInKEntries * 1024 * 64 * AverageDCCCompressionRate);
3892 #endif
3893 	}
3894 
3895 #ifdef __DML_VBA_DEBUG__
3896 	dml_print("DML::%s: MetaFIFOSizeInKEntries = %u\n", __func__, p->MetaFIFOSizeInKEntries);
3897 	dml_print("DML::%s: AverageZeroSizeCompressionRate = %f\n", __func__, AverageZeroSizeCompressionRate);
3898 	dml_print("DML::%s: EffectiveCompressedBufferSize = %f\n", __func__, EffectiveCompressedBufferSize);
3899 #endif
3900 
3901 	*p->StutterPeriod = 0;
3902 
3903 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
3904 	if (p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) {
3905 		LinesInDETY = ((dml_float_t)p->DETBufferSizeY[k] + (p->UnboundedRequestEnabled == true ? EffectiveCompressedBufferSize : 0) * p->ReadBandwidthSurfaceLuma[k] / p->TotalDataReadBandwidth) / p->BytePerPixelDETY[k] / p->SwathWidthY[k];
3906 		LinesInDETYRoundedDownToSwath = dml_floor(LinesInDETY, p->SwathHeightY[k]);
3907 		DETBufferingTimeY = LinesInDETYRoundedDownToSwath * ((dml_float_t)p->HTotal[k] / p->PixelClock[k]) / p->VRatio[k];
3908 #ifdef __DML_VBA_DEBUG__
3909 		dml_print("DML::%s: k=%u, DETBufferSizeY = %u\n", __func__, k, p->DETBufferSizeY[k]);
3910 		dml_print("DML::%s: k=%u, BytePerPixelDETY = %f\n", __func__, k, p->BytePerPixelDETY[k]);
3911 		dml_print("DML::%s: k=%u, SwathWidthY = %u\n", __func__, k, p->SwathWidthY[k]);
3912 		dml_print("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, p->ReadBandwidthSurfaceLuma[k]);
3913 		dml_print("DML::%s: k=%u, TotalDataReadBandwidth = %f\n", __func__, k, p->TotalDataReadBandwidth);
3914 		dml_print("DML::%s: k=%u, LinesInDETY = %f\n", __func__, k, LinesInDETY);
3915 		dml_print("DML::%s: k=%u, LinesInDETYRoundedDownToSwath = %f\n", __func__, k, LinesInDETYRoundedDownToSwath);
3916 		dml_print("DML::%s: k=%u, HTotal = %u\n", __func__, k, p->HTotal[k]);
3917 		dml_print("DML::%s: k=%u, PixelClock = %f\n", __func__, k, p->PixelClock[k]);
3918 		dml_print("DML::%s: k=%u, VRatio = %f\n", __func__, k, p->VRatio[k]);
3919 		dml_print("DML::%s: k=%u, DETBufferingTimeY = %f\n", __func__, k, DETBufferingTimeY);
3920 		dml_print("DML::%s: k=%u,PixelClock = %f\n", __func__, k, p->PixelClock[k]);
3921 #endif
3922 
3923 		if (!FoundCriticalSurface || DETBufferingTimeY < *p->StutterPeriod) {
3924 			dml_bool_t isInterlaceTiming = p->Interlace[k] && !p->ProgressiveToInterlaceUnitInOPP;
3925 
3926 			FoundCriticalSurface = true;
3927 			*p->StutterPeriod = DETBufferingTimeY;
3928 			FrameTimeCriticalSurface = (isInterlaceTiming ? dml_floor((dml_float_t)p->VTotal[k]/2.0, 1.0) : p->VTotal[k]) * (dml_float_t)p->HTotal[k] / p->PixelClock[k];
3929 			VActiveTimeCriticalSurface = (isInterlaceTiming ? dml_floor((dml_float_t)p->VActive[k]/2.0, 1.0) : p->VActive[k]) * (dml_float_t)p->HTotal[k] / p->PixelClock[k];
3930 			BytePerPixelYCriticalSurface = p->BytePerPixelY[k];
3931 			SwathWidthYCriticalSurface = p->SwathWidthY[k];
3932 			SwathHeightYCriticalSurface = p->SwathHeightY[k];
3933 			BlockWidth256BytesYCriticalSurface = p->BlockWidth256BytesY[k];
3934 			LinesToFinishSwathTransferStutterCriticalSurface = p->SwathHeightY[k] - (LinesInDETY - LinesInDETYRoundedDownToSwath);
3935 			DETBufferSizeYCriticalSurface = p->DETBufferSizeY[k];
3936 			MinTTUVBlankCriticalSurface = p->MinTTUVBlank[k];
3937 			SinglePlaneCriticalSurface = (p->ReadBandwidthSurfaceChroma[k] == 0);
3938 			SinglePipeCriticalSurface = (p->DPPPerSurface[k] == 1);
3939 
3940 #ifdef __DML_VBA_DEBUG__
3941 			dml_print("DML::%s: k=%u, FoundCriticalSurface = %u\n", __func__, k, FoundCriticalSurface);
3942 			dml_print("DML::%s: k=%u, StutterPeriod = %f\n", __func__, k, *p->StutterPeriod);
3943 			dml_print("DML::%s: k=%u, MinTTUVBlankCriticalSurface = %f\n", __func__, k, MinTTUVBlankCriticalSurface);
3944 			dml_print("DML::%s: k=%u, FrameTimeCriticalSurface = %f\n", __func__, k, FrameTimeCriticalSurface);
3945 			dml_print("DML::%s: k=%u, VActiveTimeCriticalSurface = %f\n", __func__, k, VActiveTimeCriticalSurface);
3946 			dml_print("DML::%s: k=%u, BytePerPixelYCriticalSurface = %u\n", __func__, k, BytePerPixelYCriticalSurface);
3947 			dml_print("DML::%s: k=%u, SwathWidthYCriticalSurface = %f\n", __func__, k, SwathWidthYCriticalSurface);
3948 			dml_print("DML::%s: k=%u, SwathHeightYCriticalSurface = %f\n", __func__, k, SwathHeightYCriticalSurface);
3949 			dml_print("DML::%s: k=%u, BlockWidth256BytesYCriticalSurface = %u\n", __func__, k, BlockWidth256BytesYCriticalSurface);
3950 			dml_print("DML::%s: k=%u, SinglePlaneCriticalSurface = %u\n", __func__, k, SinglePlaneCriticalSurface);
3951 			dml_print("DML::%s: k=%u, SinglePipeCriticalSurface = %u\n", __func__, k, SinglePipeCriticalSurface);
3952 			dml_print("DML::%s: k=%u, LinesToFinishSwathTransferStutterCriticalSurface = %f\n", __func__, k, LinesToFinishSwathTransferStutterCriticalSurface);
3953 #endif
3954 		}
3955 	}
3956 	}
3957 
3958 	PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = dml_min(*p->StutterPeriod * p->TotalDataReadBandwidth, EffectiveCompressedBufferSize);
3959 #ifdef __DML_VBA_DEBUG__
3960 	dml_print("DML::%s: ROBBufferSizeInKByte = %u\n", __func__, p->ROBBufferSizeInKByte);
3961 	dml_print("DML::%s: AverageDCCCompressionRate = %f\n", __func__, AverageDCCCompressionRate);
3962 	dml_print("DML::%s: StutterPeriod * TotalDataReadBandwidth = %f\n", __func__, *p->StutterPeriod * p->TotalDataReadBandwidth);
3963 	dml_print("DML::%s: ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate + EffectiveCompressedBufferSize = %f\n", __func__, p->ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate + EffectiveCompressedBufferSize);
3964 	dml_print("DML::%s: EffectiveCompressedBufferSize = %f\n", __func__, EffectiveCompressedBufferSize);
3965 	dml_print("DML::%s: PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = %f\n", __func__, PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer);
3966 	dml_print("DML::%s: ReturnBW = %f\n", __func__, p->ReturnBW);
3967 	dml_print("DML::%s: TotalDataReadBandwidth = %f\n", __func__, p->TotalDataReadBandwidth);
3968 	dml_print("DML::%s: TotalRowReadBandwidth = %f\n", __func__, TotalRowReadBandwidth);
3969 	dml_print("DML::%s: DCFCLK = %f\n", __func__, p->DCFCLK);
3970 #endif
3971 
3972 	StutterBurstTime = PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / AverageDCCCompressionRate / p->ReturnBW + (*p->StutterPeriod * p->TotalDataReadBandwidth - PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (p->DCFCLK * 64) + *p->StutterPeriod * TotalRowReadBandwidth / p->ReturnBW;
3973 #ifdef __DML_VBA_DEBUG__
3974 	dml_print("DML::%s: Part 1 = %f\n", __func__, PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / AverageDCCCompressionRate / p->ReturnBW);
3975 	dml_print("DML::%s: StutterPeriod * TotalDataReadBandwidth = %f\n", __func__, (*p->StutterPeriod * p->TotalDataReadBandwidth));
3976 	dml_print("DML::%s: Part 2 = %f\n", __func__, (*p->StutterPeriod * p->TotalDataReadBandwidth - PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (p->DCFCLK * 64));
3977 	dml_print("DML::%s: Part 3 = %f\n", __func__, *p->StutterPeriod * TotalRowReadBandwidth / p->ReturnBW);
3978 	dml_print("DML::%s: StutterBurstTime = %f\n", __func__, StutterBurstTime);
3979 #endif
3980 	StutterBurstTime = dml_max(StutterBurstTime, LinesToFinishSwathTransferStutterCriticalSurface * BytePerPixelYCriticalSurface * SwathWidthYCriticalSurface / p->ReturnBW);
3981 
3982 	dml_print("DML::%s: Time to finish residue swath=%f\n", __func__, LinesToFinishSwathTransferStutterCriticalSurface * BytePerPixelYCriticalSurface * SwathWidthYCriticalSurface / p->ReturnBW);
3983 
3984 	TotalActiveWriteback = 0;
3985 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
3986 		if (p->WritebackEnable[k]) {
3987 			TotalActiveWriteback = TotalActiveWriteback + 1;
3988 		}
3989 	}
3990 
3991 	if (TotalActiveWriteback == 0) {
3992 #ifdef __DML_VBA_DEBUG__
3993 		dml_print("DML::%s: SRExitTime = %f\n", __func__, p->SRExitTime);
3994 		dml_print("DML::%s: SRExitZ8Time = %f\n", __func__, p->SRExitZ8Time);
3995 		dml_print("DML::%s: StutterBurstTime = %f (final)\n", __func__, StutterBurstTime);
3996 		dml_print("DML::%s: StutterPeriod = %f\n", __func__, *p->StutterPeriod);
3997 #endif
3998 		*p->StutterEfficiencyNotIncludingVBlank = dml_max(0., 1 - (p->SRExitTime + StutterBurstTime) / *p->StutterPeriod) * 100;
3999 		*p->Z8StutterEfficiencyNotIncludingVBlank = dml_max(0., 1 - (p->SRExitZ8Time + StutterBurstTime) / *p->StutterPeriod) * 100;
4000 		*p->NumberOfStutterBurstsPerFrame = (*p->StutterEfficiencyNotIncludingVBlank > 0 ? (dml_uint_t)(dml_ceil(VActiveTimeCriticalSurface / *p->StutterPeriod, 1)) : 0);
4001 		*p->Z8NumberOfStutterBurstsPerFrame = (*p->Z8StutterEfficiencyNotIncludingVBlank > 0 ? (dml_uint_t)(dml_ceil(VActiveTimeCriticalSurface / *p->StutterPeriod, 1)) : 0);
4002 	} else {
4003 		*p->StutterEfficiencyNotIncludingVBlank = 0.;
4004 		*p->Z8StutterEfficiencyNotIncludingVBlank = 0.;
4005 		*p->NumberOfStutterBurstsPerFrame = 0;
4006 		*p->Z8NumberOfStutterBurstsPerFrame = 0;
4007 	}
4008 #ifdef __DML_VBA_DEBUG__
4009 	dml_print("DML::%s: VActiveTimeCriticalSurface = %f\n", __func__, VActiveTimeCriticalSurface);
4010 	dml_print("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->StutterEfficiencyNotIncludingVBlank);
4011 	dml_print("DML::%s: Z8StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->Z8StutterEfficiencyNotIncludingVBlank);
4012 	dml_print("DML::%s: NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->NumberOfStutterBurstsPerFrame);
4013 	dml_print("DML::%s: Z8NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->Z8NumberOfStutterBurstsPerFrame);
4014 #endif
4015 
4016 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4017 		if (p->UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) {
4018 			if (p->BlendingAndTiming[k] == k) {
4019 				if (TotalNumberOfActiveOTG == 0) {
4020 					SinglePixelClock = p->PixelClock[k];
4021 					SingleHTotal = p->HTotal[k];
4022 					SingleVTotal = p->VTotal[k];
4023 				} else if (SinglePixelClock != p->PixelClock[k] || SingleHTotal != p->HTotal[k] || SingleVTotal != p->VTotal[k]) {
4024 					SameTiming = false;
4025 				}
4026 				TotalNumberOfActiveOTG = TotalNumberOfActiveOTG + 1;
4027 			}
4028 		}
4029 	}
4030 
4031 	if (*p->StutterEfficiencyNotIncludingVBlank > 0) {
4032 		LastStutterPeriod = VActiveTimeCriticalSurface - (*p->NumberOfStutterBurstsPerFrame - 1) * *p->StutterPeriod;
4033 
4034 		if ((p->SynchronizeTimingsFinal || TotalNumberOfActiveOTG == 1) && SameTiming &&
4035 			LastStutterPeriod + MinTTUVBlankCriticalSurface > p->StutterEnterPlusExitWatermark) {
4036 			*p->StutterEfficiency = (1 - (*p->NumberOfStutterBurstsPerFrame * p->SRExitTime + StutterBurstTime * VActiveTimeCriticalSurface / *p->StutterPeriod) / FrameTimeCriticalSurface) * 100;
4037 		} else {
4038 			*p->StutterEfficiency = *p->StutterEfficiencyNotIncludingVBlank;
4039 		}
4040 	} else {
4041 		*p->StutterEfficiency = 0;
4042 	}
4043 
4044 	if (*p->Z8StutterEfficiencyNotIncludingVBlank > 0) {
4045 		LastZ8StutterPeriod = VActiveTimeCriticalSurface - (*p->NumberOfStutterBurstsPerFrame - 1) * *p->StutterPeriod;
4046 		if ((p->SynchronizeTimingsFinal || TotalNumberOfActiveOTG == 1) && SameTiming && LastZ8StutterPeriod + MinTTUVBlankCriticalSurface > p->Z8StutterEnterPlusExitWatermark) {
4047 			*p->Z8StutterEfficiency = (1 - (*p->NumberOfStutterBurstsPerFrame * p->SRExitZ8Time + StutterBurstTime * VActiveTimeCriticalSurface / *p->StutterPeriod) / FrameTimeCriticalSurface) * 100;
4048 		} else {
4049 			*p->Z8StutterEfficiency = *p->Z8StutterEfficiencyNotIncludingVBlank;
4050 		}
4051 	} else {
4052 		*p->Z8StutterEfficiency = 0.;
4053 	}
4054 
4055 #ifdef __DML_VBA_DEBUG__
4056 		dml_print("DML::%s: LastZ8StutterPeriod = %f\n", __func__, LastZ8StutterPeriod);
4057 		dml_print("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, p->Z8StutterEnterPlusExitWatermark);
4058 		dml_print("DML::%s: StutterBurstTime = %f\n", __func__, StutterBurstTime);
4059 		dml_print("DML::%s: StutterPeriod = %f\n", __func__, *p->StutterPeriod);
4060 		dml_print("DML::%s: StutterEfficiency = %f\n", __func__, *p->StutterEfficiency);
4061 		dml_print("DML::%s: Z8StutterEfficiency = %f\n", __func__, *p->Z8StutterEfficiency);
4062 		dml_print("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *p->StutterEfficiencyNotIncludingVBlank);
4063 		dml_print("DML::%s: Z8NumberOfStutterBurstsPerFrame = %u\n", __func__, *p->Z8NumberOfStutterBurstsPerFrame);
4064 #endif
4065 
4066 		SwathSizeCriticalSurface = (dml_uint_t)(BytePerPixelYCriticalSurface * SwathHeightYCriticalSurface * dml_ceil(SwathWidthYCriticalSurface, BlockWidth256BytesYCriticalSurface));
4067 		LastChunkOfSwathSize = SwathSizeCriticalSurface % (p->PixelChunkSizeInKByte * 1024);
4068 		MissingPartOfLastSwathOfDETSize = (dml_uint_t)(dml_ceil(DETBufferSizeYCriticalSurface, SwathSizeCriticalSurface) - DETBufferSizeYCriticalSurface);
4069 
4070 		*p->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = !(!p->UnboundedRequestEnabled && (p->NumberOfActiveSurfaces == 1) && SinglePlaneCriticalSurface && SinglePipeCriticalSurface && (LastChunkOfSwathSize > 0) &&
4071 			(LastChunkOfSwathSize <= 4096) && (MissingPartOfLastSwathOfDETSize > 0) && (MissingPartOfLastSwathOfDETSize <= LastChunkOfSwathSize));
4072 
4073 #ifdef __DML_VBA_DEBUG__
4074 	dml_print("DML::%s: SwathSizeCriticalSurface = %u\n", __func__, SwathSizeCriticalSurface);
4075 	dml_print("DML::%s: DETBufferSizeYCriticalSurface = %u\n", __func__, DETBufferSizeYCriticalSurface);
4076 	dml_print("DML::%s: PixelChunkSizeInKByte = %u\n", __func__, p->PixelChunkSizeInKByte);
4077 	dml_print("DML::%s: LastChunkOfSwathSize = %u\n", __func__, LastChunkOfSwathSize);
4078 	dml_print("DML::%s: MissingPartOfLastSwathOfDETSize = %u\n", __func__, MissingPartOfLastSwathOfDETSize);
4079 	dml_print("DML::%s: DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = %u\n", __func__, *p->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE);
4080 #endif
4081 } // CalculateStutterEfficiency
4082 
4083 /// \CalculateSwathAndDETConfiguration
4084 /// @brief Calculates swath width and different return buffers sizing (DET, CDB, etc.)
CalculateSwathAndDETConfiguration(struct display_mode_lib_scratch_st * scratch,struct CalculateSwathAndDETConfiguration_params_st * p)4085 static void CalculateSwathAndDETConfiguration(struct display_mode_lib_scratch_st *scratch,
4086 	struct CalculateSwathAndDETConfiguration_params_st *p)
4087 {
4088 	dml_uint_t MaximumSwathHeightY[__DML_NUM_PLANES__];
4089 	dml_uint_t MaximumSwathHeightC[__DML_NUM_PLANES__];
4090 	dml_uint_t RoundedUpMaxSwathSizeBytesY[__DML_NUM_PLANES__];
4091 	dml_uint_t RoundedUpMaxSwathSizeBytesC[__DML_NUM_PLANES__];
4092 	dml_uint_t RoundedUpSwathSizeBytesY[__DML_NUM_PLANES__];
4093 	dml_uint_t RoundedUpSwathSizeBytesC[__DML_NUM_PLANES__];
4094 	dml_uint_t SwathWidthSingleDPP[__DML_NUM_PLANES__];
4095 	dml_uint_t SwathWidthSingleDPPChroma[__DML_NUM_PLANES__];
4096 
4097 	dml_uint_t TotalActiveDPP = 0;
4098 	dml_bool_t NoChromaOrLinearSurfaces = true;
4099 	dml_uint_t SurfaceDoingUnboundedRequest = 0;
4100 
4101 	dml_uint_t DETBufferSizeInKByteForSwathCalculation;
4102 
4103 	const long TTUFIFODEPTH = 8;
4104 	const long MAXIMUMCOMPRESSION = 4;
4105 
4106 #ifdef __DML_VBA_DEBUG__
4107 	dml_print("DML::%s: ForceSingleDPP = %u\n", __func__, p->ForceSingleDPP);
4108 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4109 		dml_print("DML::%s: DPPPerSurface[%u] = %u\n", __func__, k, p->DPPPerSurface[k]);
4110 	}
4111 #endif
4112 	CalculateSwathWidth(p->ForceSingleDPP,
4113 		p->NumberOfActiveSurfaces,
4114 		p->SourcePixelFormat,
4115 		p->SourceScan,
4116 		p->ViewportStationary,
4117 		p->ViewportWidth,
4118 		p->ViewportHeight,
4119 		p->ViewportXStart,
4120 		p->ViewportYStart,
4121 		p->ViewportXStartC,
4122 		p->ViewportYStartC,
4123 		p->SurfaceWidthY,
4124 		p->SurfaceWidthC,
4125 		p->SurfaceHeightY,
4126 		p->SurfaceHeightC,
4127 		p->ODMMode,
4128 		p->BytePerPixY,
4129 		p->BytePerPixC,
4130 		p->Read256BytesBlockHeightY,
4131 		p->Read256BytesBlockHeightC,
4132 		p->Read256BytesBlockWidthY,
4133 		p->Read256BytesBlockWidthC,
4134 		p->BlendingAndTiming,
4135 		p->HActive,
4136 		p->HRatio,
4137 		p->DPPPerSurface,
4138 
4139 		// Output
4140 		SwathWidthSingleDPP,
4141 		SwathWidthSingleDPPChroma,
4142 		p->SwathWidth,
4143 		p->SwathWidthChroma,
4144 		MaximumSwathHeightY,
4145 		MaximumSwathHeightC,
4146 		p->swath_width_luma_ub,
4147 		p->swath_width_chroma_ub);
4148 
4149 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4150 		RoundedUpMaxSwathSizeBytesY[k] = (dml_uint_t)(p->swath_width_luma_ub[k] * p->BytePerPixDETY[k] * MaximumSwathHeightY[k]);
4151 		RoundedUpMaxSwathSizeBytesC[k] = (dml_uint_t)(p->swath_width_chroma_ub[k] * p->BytePerPixDETC[k] * MaximumSwathHeightC[k]);
4152 #ifdef __DML_VBA_DEBUG__
4153 		dml_print("DML::%s: k=%u DPPPerSurface = %u\n", __func__, k, p->DPPPerSurface[k]);
4154 		dml_print("DML::%s: k=%u swath_width_luma_ub = %u\n", __func__, k, p->swath_width_luma_ub[k]);
4155 		dml_print("DML::%s: k=%u BytePerPixDETY = %f\n", __func__, k, p->BytePerPixDETY[k]);
4156 		dml_print("DML::%s: k=%u MaximumSwathHeightY = %u\n", __func__, k, MaximumSwathHeightY[k]);
4157 		dml_print("DML::%s: k=%u RoundedUpMaxSwathSizeBytesY = %u\n", __func__, k, RoundedUpMaxSwathSizeBytesY[k]);
4158 		dml_print("DML::%s: k=%u swath_width_chroma_ub = %u\n", __func__, k, p->swath_width_chroma_ub[k]);
4159 		dml_print("DML::%s: k=%u BytePerPixDETC = %f\n", __func__, k, p->BytePerPixDETC[k]);
4160 		dml_print("DML::%s: k=%u MaximumSwathHeightC = %u\n", __func__, k, MaximumSwathHeightC[k]);
4161 		dml_print("DML::%s: k=%u RoundedUpMaxSwathSizeBytesC = %u\n", __func__, k, RoundedUpMaxSwathSizeBytesC[k]);
4162 #endif
4163 		if (p->SourcePixelFormat[k] == dml_420_10) {
4164 			RoundedUpMaxSwathSizeBytesY[k] = (dml_uint_t)(dml_ceil((dml_float_t) RoundedUpMaxSwathSizeBytesY[k], 256));
4165 			RoundedUpMaxSwathSizeBytesC[k] = (dml_uint_t)(dml_ceil((dml_float_t) RoundedUpMaxSwathSizeBytesC[k], 256));
4166 		}
4167 	}
4168 
4169 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4170 		TotalActiveDPP = TotalActiveDPP + (p->ForceSingleDPP ? 1 : p->DPPPerSurface[k]);
4171 		if (p->DPPPerSurface[k] > 0)
4172 			SurfaceDoingUnboundedRequest = k;
4173 		if (p->SourcePixelFormat[k] == dml_420_8 || p->SourcePixelFormat[k] == dml_420_10 ||
4174 				p->SourcePixelFormat[k] == dml_420_12 || p->SourcePixelFormat[k] == dml_rgbe_alpha
4175 				|| p->SurfaceTiling[k] == dml_sw_linear) {
4176 			NoChromaOrLinearSurfaces = false;
4177 		}
4178 	}
4179 
4180 	*p->UnboundedRequestEnabled = UnboundedRequest(p->UseUnboundedRequestingFinal, TotalActiveDPP,
4181 			NoChromaOrLinearSurfaces, p->Output[0]);
4182 
4183 	CalculateDETBufferSize(p->DETSizeOverride,
4184 		p->UseMALLForPStateChange,
4185 		p->ForceSingleDPP,
4186 		p->NumberOfActiveSurfaces,
4187 		*p->UnboundedRequestEnabled,
4188 		p->nomDETInKByte,
4189 		p->MaxTotalDETInKByte,
4190 		p->ConfigReturnBufferSizeInKByte,
4191 		p->MinCompressedBufferSizeInKByte,
4192 		p->ConfigReturnBufferSegmentSizeInkByte,
4193 		p->CompressedBufferSegmentSizeInkByteFinal,
4194 		p->SourcePixelFormat,
4195 		p->ReadBandwidthLuma,
4196 		p->ReadBandwidthChroma,
4197 		RoundedUpMaxSwathSizeBytesY,
4198 		RoundedUpMaxSwathSizeBytesC,
4199 		p->DPPPerSurface,
4200 
4201 		// Output
4202 		p->DETBufferSizeInKByte, // per hubp pipe
4203 		p->CompressedBufferSizeInkByte);
4204 
4205 #ifdef __DML_VBA_DEBUG__
4206 		dml_print("DML::%s: TotalActiveDPP = %u\n", __func__, TotalActiveDPP);
4207 		dml_print("DML::%s: nomDETInKByte = %u\n", __func__, p->nomDETInKByte);
4208 		dml_print("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, p->ConfigReturnBufferSizeInKByte);
4209 		dml_print("DML::%s: UseUnboundedRequestingFinal = %u\n", __func__, p->UseUnboundedRequestingFinal);
4210 		dml_print("DML::%s: UnboundedRequestEnabled = %u\n", __func__, *p->UnboundedRequestEnabled);
4211 		dml_print("DML::%s: CompressedBufferSizeInkByte = %u\n", __func__, *p->CompressedBufferSizeInkByte);
4212 #endif
4213 
4214 	*p->ViewportSizeSupport = true;
4215 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4216 
4217 		DETBufferSizeInKByteForSwathCalculation =  (p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe ? 1024 : p->DETBufferSizeInKByte[k]);
4218 #ifdef __DML_VBA_DEBUG__
4219 	dml_print("DML::%s: k=%u DETBufferSizeInKByteForSwathCalculation = %u\n", __func__, k, DETBufferSizeInKByteForSwathCalculation);
4220 #endif
4221 
4222 		if (RoundedUpMaxSwathSizeBytesY[k] + RoundedUpMaxSwathSizeBytesC[k] <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
4223 			p->SwathHeightY[k] = MaximumSwathHeightY[k];
4224 			p->SwathHeightC[k] = MaximumSwathHeightC[k];
4225 			RoundedUpSwathSizeBytesY[k] = RoundedUpMaxSwathSizeBytesY[k];
4226 			RoundedUpSwathSizeBytesC[k] = RoundedUpMaxSwathSizeBytesC[k];
4227 		} else if (RoundedUpMaxSwathSizeBytesY[k] >= 1.5 * RoundedUpMaxSwathSizeBytesC[k] && RoundedUpMaxSwathSizeBytesY[k] / 2 + RoundedUpMaxSwathSizeBytesC[k] <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
4228 			p->SwathHeightY[k] = MaximumSwathHeightY[k] / 2;
4229 			p->SwathHeightC[k] = MaximumSwathHeightC[k];
4230 			RoundedUpSwathSizeBytesY[k] = RoundedUpMaxSwathSizeBytesY[k] / 2;
4231 			RoundedUpSwathSizeBytesC[k] = RoundedUpMaxSwathSizeBytesC[k];
4232 		} else if (RoundedUpMaxSwathSizeBytesY[k] < 1.5 * RoundedUpMaxSwathSizeBytesC[k] && RoundedUpMaxSwathSizeBytesY[k] + RoundedUpMaxSwathSizeBytesC[k] / 2 <= DETBufferSizeInKByteForSwathCalculation * 1024 / 2) {
4233 			p->SwathHeightY[k] = MaximumSwathHeightY[k];
4234 			p->SwathHeightC[k] = MaximumSwathHeightC[k] / 2;
4235 			RoundedUpSwathSizeBytesY[k] = RoundedUpMaxSwathSizeBytesY[k];
4236 			RoundedUpSwathSizeBytesC[k] = RoundedUpMaxSwathSizeBytesC[k] / 2;
4237 		} else {
4238 			p->SwathHeightY[k] = MaximumSwathHeightY[k] / 2;
4239 			p->SwathHeightC[k] = MaximumSwathHeightC[k] / 2;
4240 			RoundedUpSwathSizeBytesY[k] = RoundedUpMaxSwathSizeBytesY[k] / 2;
4241 			RoundedUpSwathSizeBytesC[k] = RoundedUpMaxSwathSizeBytesC[k] / 2;
4242 		}
4243 
4244 		if ((RoundedUpMaxSwathSizeBytesY[k] / 2 + RoundedUpMaxSwathSizeBytesC[k] / 2 > DETBufferSizeInKByteForSwathCalculation * 1024 / 2) ||
4245 			p->SwathWidth[k] > p->MaximumSwathWidthLuma[k] || (p->SwathHeightC[k] > 0 && p->SwathWidthChroma[k] > p->MaximumSwathWidthChroma[k])) {
4246 			*p->ViewportSizeSupport = false;
4247 			p->ViewportSizeSupportPerSurface[k] = false;
4248 		} else {
4249 			p->ViewportSizeSupportPerSurface[k] = true;
4250 		}
4251 
4252 	if (p->SwathHeightC[k] == 0) {
4253 #ifdef __DML_VBA_DEBUG__
4254 			dml_print("DML::%s: k=%u All DET for plane0\n", __func__, k);
4255 #endif
4256 			p->DETBufferSizeY[k] = p->DETBufferSizeInKByte[k] * 1024;
4257 			p->DETBufferSizeC[k] = 0;
4258 		} else if (RoundedUpSwathSizeBytesY[k] <= 1.5 * RoundedUpSwathSizeBytesC[k]) {
4259 #ifdef __DML_VBA_DEBUG__
4260 			dml_print("DML::%s: k=%u Half DET for plane0, half for plane1\n", __func__, k);
4261 #endif
4262 			p->DETBufferSizeY[k] = p->DETBufferSizeInKByte[k] * 1024 / 2;
4263 			p->DETBufferSizeC[k] = p->DETBufferSizeInKByte[k] * 1024 / 2;
4264 		} else {
4265 #ifdef __DML_VBA_DEBUG__
4266 			dml_print("DML::%s: k=%u 2/3 DET for plane0, 1/3 for plane1\n", __func__, k);
4267 #endif
4268 			p->DETBufferSizeY[k] = (dml_uint_t)(dml_floor(p->DETBufferSizeInKByte[k] * 1024 * 2 / 3, 1024));
4269 			p->DETBufferSizeC[k] = p->DETBufferSizeInKByte[k] * 1024 - p->DETBufferSizeY[k];
4270 		}
4271 
4272 #ifdef __DML_VBA_DEBUG__
4273 		dml_print("DML::%s: k=%u SwathHeightY = %u\n", __func__, k, p->SwathHeightY[k]);
4274 		dml_print("DML::%s: k=%u SwathHeightC = %u\n", __func__, k, p->SwathHeightC[k]);
4275 		dml_print("DML::%s: k=%u RoundedUpMaxSwathSizeBytesY = %u\n", __func__, k, RoundedUpMaxSwathSizeBytesY[k]);
4276 		dml_print("DML::%s: k=%u RoundedUpMaxSwathSizeBytesC = %u\n", __func__, k, RoundedUpMaxSwathSizeBytesC[k]);
4277 		dml_print("DML::%s: k=%u RoundedUpSwathSizeBytesY = %u\n", __func__, k, RoundedUpSwathSizeBytesY[k]);
4278 		dml_print("DML::%s: k=%u RoundedUpSwathSizeBytesC = %u\n", __func__, k, RoundedUpSwathSizeBytesC[k]);
4279 		dml_print("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, p->DETBufferSizeInKByte[k]);
4280 		dml_print("DML::%s: k=%u DETBufferSizeY = %u\n", __func__, k, p->DETBufferSizeY[k]);
4281 		dml_print("DML::%s: k=%u DETBufferSizeC = %u\n", __func__, k, p->DETBufferSizeC[k]);
4282 		dml_print("DML::%s: k=%u ViewportSizeSupportPerSurface = %u\n", __func__, k, p->ViewportSizeSupportPerSurface[k]);
4283 #endif
4284 
4285 	}
4286 
4287 	*p->compbuf_reserved_space_64b = 2 * p->PixelChunkSizeInKByte * 1024 / 64;
4288 	if (*p->UnboundedRequestEnabled) {
4289 		*p->compbuf_reserved_space_64b = dml_max(*p->compbuf_reserved_space_64b,
4290 				(dml_float_t)(p->ROBBufferSizeInKByte * 1024/64)
4291 				- (dml_float_t)(RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest] * TTUFIFODEPTH / MAXIMUMCOMPRESSION/64));
4292 	}
4293 	*p->compbuf_reserved_space_zs = 2 * p->PixelChunkSizeInKByte * 1024 / 256;
4294 } // CalculateSwathAndDETConfiguration
4295 
CalculateSwathWidth(dml_bool_t ForceSingleDPP,dml_uint_t NumberOfActiveSurfaces,enum dml_source_format_class SourcePixelFormat[],enum dml_rotation_angle SourceScan[],dml_bool_t ViewportStationary[],dml_uint_t ViewportWidth[],dml_uint_t ViewportHeight[],dml_uint_t ViewportXStart[],dml_uint_t ViewportYStart[],dml_uint_t ViewportXStartC[],dml_uint_t ViewportYStartC[],dml_uint_t SurfaceWidthY[],dml_uint_t SurfaceWidthC[],dml_uint_t SurfaceHeightY[],dml_uint_t SurfaceHeightC[],enum dml_odm_mode ODMMode[],dml_uint_t BytePerPixY[],dml_uint_t BytePerPixC[],dml_uint_t Read256BytesBlockHeightY[],dml_uint_t Read256BytesBlockHeightC[],dml_uint_t Read256BytesBlockWidthY[],dml_uint_t Read256BytesBlockWidthC[],dml_uint_t BlendingAndTiming[],dml_uint_t HActive[],dml_float_t HRatio[],dml_uint_t DPPPerSurface[],dml_uint_t SwathWidthSingleDPPY[],dml_uint_t SwathWidthSingleDPPC[],dml_uint_t SwathWidthY[],dml_uint_t SwathWidthC[],dml_uint_t MaximumSwathHeightY[],dml_uint_t MaximumSwathHeightC[],dml_uint_t swath_width_luma_ub[],dml_uint_t swath_width_chroma_ub[])4296 static void CalculateSwathWidth(
4297 		dml_bool_t ForceSingleDPP,
4298 		dml_uint_t NumberOfActiveSurfaces,
4299 		enum dml_source_format_class SourcePixelFormat[],
4300 		enum dml_rotation_angle SourceScan[],
4301 		dml_bool_t ViewportStationary[],
4302 		dml_uint_t ViewportWidth[],
4303 		dml_uint_t ViewportHeight[],
4304 		dml_uint_t ViewportXStart[],
4305 		dml_uint_t ViewportYStart[],
4306 		dml_uint_t ViewportXStartC[],
4307 		dml_uint_t ViewportYStartC[],
4308 		dml_uint_t SurfaceWidthY[],
4309 		dml_uint_t SurfaceWidthC[],
4310 		dml_uint_t SurfaceHeightY[],
4311 		dml_uint_t SurfaceHeightC[],
4312 		enum dml_odm_mode ODMMode[],
4313 		dml_uint_t BytePerPixY[],
4314 		dml_uint_t BytePerPixC[],
4315 		dml_uint_t Read256BytesBlockHeightY[],
4316 		dml_uint_t Read256BytesBlockHeightC[],
4317 		dml_uint_t Read256BytesBlockWidthY[],
4318 		dml_uint_t Read256BytesBlockWidthC[],
4319 		dml_uint_t BlendingAndTiming[],
4320 		dml_uint_t HActive[],
4321 		dml_float_t HRatio[],
4322 		dml_uint_t DPPPerSurface[],
4323 
4324 		// Output
4325 		dml_uint_t SwathWidthSingleDPPY[],
4326 		dml_uint_t SwathWidthSingleDPPC[],
4327 		dml_uint_t SwathWidthY[], // per-pipe
4328 		dml_uint_t SwathWidthC[], // per-pipe
4329 		dml_uint_t MaximumSwathHeightY[],
4330 		dml_uint_t MaximumSwathHeightC[],
4331 		dml_uint_t swath_width_luma_ub[], // per-pipe
4332 		dml_uint_t swath_width_chroma_ub[]) // per-pipe
4333 {
4334 	enum dml_odm_mode   MainSurfaceODMMode;
4335 	dml_uint_t surface_width_ub_l;
4336 	dml_uint_t surface_height_ub_l;
4337 	dml_uint_t surface_width_ub_c = 0;
4338 	dml_uint_t surface_height_ub_c = 0;
4339 
4340 #ifdef __DML_VBA_DEBUG__
4341 	dml_print("DML::%s: ForceSingleDPP = %u\n", __func__, ForceSingleDPP);
4342 	dml_print("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces);
4343 #endif
4344 
4345 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4346 		if (!dml_is_vertical_rotation(SourceScan[k])) {
4347 			SwathWidthSingleDPPY[k] = ViewportWidth[k];
4348 		} else {
4349 			SwathWidthSingleDPPY[k] = ViewportHeight[k];
4350 		}
4351 
4352 #ifdef __DML_VBA_DEBUG__
4353 		dml_print("DML::%s: k=%u ViewportWidth=%u\n", __func__, k, ViewportWidth[k]);
4354 		dml_print("DML::%s: k=%u ViewportHeight=%u\n", __func__, k, ViewportHeight[k]);
4355 		dml_print("DML::%s: k=%u DPPPerSurface=%u\n", __func__, k, DPPPerSurface[k]);
4356 #endif
4357 
4358 		MainSurfaceODMMode = ODMMode[k];
4359 		for (dml_uint_t j = 0; j < NumberOfActiveSurfaces; ++j) {
4360 			if (BlendingAndTiming[k] == j) {
4361 				MainSurfaceODMMode = ODMMode[j];
4362 			}
4363 		}
4364 
4365 		if (ForceSingleDPP) {
4366 			SwathWidthY[k] = SwathWidthSingleDPPY[k];
4367 		} else {
4368 			if (MainSurfaceODMMode == dml_odm_mode_combine_4to1) {
4369 				SwathWidthY[k] = (dml_uint_t)(dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 4.0 * HRatio[k], true)));
4370 			} else if (MainSurfaceODMMode == dml_odm_mode_combine_2to1) {
4371 				SwathWidthY[k] = (dml_uint_t)(dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 2.0 * HRatio[k], true)));
4372 			} else if (DPPPerSurface[k] == 2) {
4373 				SwathWidthY[k] = SwathWidthSingleDPPY[k] / 2;
4374 			} else {
4375 				SwathWidthY[k] = SwathWidthSingleDPPY[k];
4376 			}
4377 		}
4378 
4379 #ifdef __DML_VBA_DEBUG__
4380 		dml_print("DML::%s: k=%u HActive=%u\n", __func__, k, HActive[k]);
4381 		dml_print("DML::%s: k=%u HRatio=%f\n", __func__, k, HRatio[k]);
4382 		dml_print("DML::%s: k=%u MainSurfaceODMMode=%u\n", __func__, k, MainSurfaceODMMode);
4383 		dml_print("DML::%s: k=%u SwathWidthSingleDPPY=%u\n", __func__, k, SwathWidthSingleDPPY[k]);
4384 		dml_print("DML::%s: k=%u SwathWidthY=%u\n", __func__, k, SwathWidthY[k]);
4385 #endif
4386 
4387 		if (SourcePixelFormat[k] == dml_420_8 || SourcePixelFormat[k] == dml_420_10 || SourcePixelFormat[k] == dml_420_12) {
4388 			SwathWidthC[k] = SwathWidthY[k] / 2;
4389 			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k] / 2;
4390 		} else {
4391 			SwathWidthC[k] = SwathWidthY[k];
4392 			SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k];
4393 		}
4394 
4395 		if (ForceSingleDPP == true) {
4396 			SwathWidthY[k] = SwathWidthSingleDPPY[k];
4397 			SwathWidthC[k] = SwathWidthSingleDPPC[k];
4398 		}
4399 
4400 		surface_width_ub_l = (dml_uint_t)dml_ceil(SurfaceWidthY[k], Read256BytesBlockWidthY[k]);
4401 		surface_height_ub_l = (dml_uint_t)dml_ceil(SurfaceHeightY[k], Read256BytesBlockHeightY[k]);
4402 
4403 		if (!dml_is_vertical_rotation(SourceScan[k])) {
4404 			MaximumSwathHeightY[k] = Read256BytesBlockHeightY[k];
4405 			MaximumSwathHeightC[k] = Read256BytesBlockHeightC[k];
4406 			if (ViewportStationary[k] && DPPPerSurface[k] == 1) {
4407 				swath_width_luma_ub[k] = (dml_uint_t)(dml_min(surface_width_ub_l, dml_floor(ViewportXStart[k] + SwathWidthY[k] + Read256BytesBlockWidthY[k] - 1, Read256BytesBlockWidthY[k]) - dml_floor(ViewportXStart[k], Read256BytesBlockWidthY[k])));
4408 			} else {
4409 				swath_width_luma_ub[k] = (dml_uint_t)(dml_min(surface_width_ub_l, dml_ceil(SwathWidthY[k] - 1, Read256BytesBlockWidthY[k]) + Read256BytesBlockWidthY[k]));
4410 			}
4411 			if (BytePerPixC[k] > 0) {
4412 				surface_width_ub_c = (dml_uint_t)dml_ceil(SurfaceWidthC[k], Read256BytesBlockWidthC[k]);
4413 				if (ViewportStationary[k] && DPPPerSurface[k] == 1) {
4414 					swath_width_chroma_ub[k] = (dml_uint_t)(dml_min(surface_width_ub_c, dml_floor(ViewportXStartC[k] + SwathWidthC[k] + Read256BytesBlockWidthC[k] - 1, Read256BytesBlockWidthC[k]) - dml_floor(ViewportXStartC[k], Read256BytesBlockWidthC[k])));
4415 				} else {
4416 					swath_width_chroma_ub[k] = (dml_uint_t)(dml_min(surface_width_ub_c, dml_ceil(SwathWidthC[k] - 1, Read256BytesBlockWidthC[k]) + Read256BytesBlockWidthC[k]));
4417 				}
4418 			} else {
4419 				swath_width_chroma_ub[k] = 0;
4420 			}
4421 		} else {
4422 			MaximumSwathHeightY[k] = Read256BytesBlockWidthY[k];
4423 			MaximumSwathHeightC[k] = Read256BytesBlockWidthC[k];
4424 
4425 			if (ViewportStationary[k] && DPPPerSurface[k] == 1) {
4426 				swath_width_luma_ub[k] = (dml_uint_t)(dml_min(surface_height_ub_l, dml_floor(ViewportYStart[k] + SwathWidthY[k] + Read256BytesBlockHeightY[k] - 1, Read256BytesBlockHeightY[k]) - dml_floor(ViewportYStart[k], Read256BytesBlockHeightY[k])));
4427 			} else {
4428 				swath_width_luma_ub[k] = (dml_uint_t)(dml_min(surface_height_ub_l, dml_ceil(SwathWidthY[k] - 1, Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k]));
4429 			}
4430 			if (BytePerPixC[k] > 0) {
4431 				surface_height_ub_c = (dml_uint_t)dml_ceil(SurfaceHeightC[k], Read256BytesBlockHeightC[k]);
4432 				if (ViewportStationary[k] && DPPPerSurface[k] == 1) {
4433 					swath_width_chroma_ub[k] = (dml_uint_t)(dml_min(surface_height_ub_c, dml_floor(ViewportYStartC[k] + SwathWidthC[k] + Read256BytesBlockHeightC[k] - 1, Read256BytesBlockHeightC[k]) - dml_floor(ViewportYStartC[k], Read256BytesBlockHeightC[k])));
4434 				} else {
4435 					swath_width_chroma_ub[k] = (dml_uint_t)(dml_min(surface_height_ub_c, dml_ceil(SwathWidthC[k] - 1, Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k]));
4436 				}
4437 			} else {
4438 				swath_width_chroma_ub[k] = 0;
4439 			}
4440 		}
4441 
4442 #ifdef __DML_VBA_DEBUG__
4443 		dml_print("DML::%s: k=%u surface_width_ub_l=%u\n", __func__, k, surface_width_ub_l);
4444 		dml_print("DML::%s: k=%u surface_height_ub_l=%u\n", __func__, k, surface_height_ub_l);
4445 		dml_print("DML::%s: k=%u surface_width_ub_c=%u\n", __func__, k, surface_width_ub_c);
4446 		dml_print("DML::%s: k=%u surface_height_ub_c=%u\n", __func__, k, surface_height_ub_c);
4447 		dml_print("DML::%s: k=%u Read256BytesBlockWidthY=%u\n", __func__, k, Read256BytesBlockWidthY[k]);
4448 		dml_print("DML::%s: k=%u Read256BytesBlockHeightY=%u\n", __func__, k, Read256BytesBlockHeightY[k]);
4449 		dml_print("DML::%s: k=%u Read256BytesBlockWidthC=%u\n", __func__, k, Read256BytesBlockWidthC[k]);
4450 		dml_print("DML::%s: k=%u Read256BytesBlockHeightC=%u\n", __func__, k, Read256BytesBlockHeightC[k]);
4451 		dml_print("DML::%s: k=%u ViewportStationary=%u\n", __func__, k, ViewportStationary[k]);
4452 		dml_print("DML::%s: k=%u DPPPerSurface=%u\n", __func__, k, DPPPerSurface[k]);
4453 		dml_print("DML::%s: k=%u swath_width_luma_ub=%u\n", __func__, k, swath_width_luma_ub[k]);
4454 		dml_print("DML::%s: k=%u swath_width_chroma_ub=%u\n", __func__, k, swath_width_chroma_ub[k]);
4455 		dml_print("DML::%s: k=%u MaximumSwathHeightY=%u\n", __func__, k, MaximumSwathHeightY[k]);
4456 		dml_print("DML::%s: k=%u MaximumSwathHeightC=%u\n", __func__, k, MaximumSwathHeightC[k]);
4457 #endif
4458 
4459 	}
4460 } // CalculateSwathWidth
4461 
CalculateExtraLatency(dml_uint_t RoundTripPingLatencyCycles,dml_uint_t ReorderingBytes,dml_float_t DCFCLK,dml_uint_t TotalNumberOfActiveDPP,dml_uint_t PixelChunkSizeInKByte,dml_uint_t TotalNumberOfDCCActiveDPP,dml_uint_t MetaChunkSize,dml_float_t ReturnBW,dml_bool_t GPUVMEnable,dml_bool_t HostVMEnable,dml_uint_t NumberOfActiveSurfaces,dml_uint_t NumberOfDPP[],dml_uint_t dpte_group_bytes[],dml_float_t HostVMInefficiencyFactor,dml_uint_t HostVMMinPageSize,dml_uint_t HostVMMaxNonCachedPageTableLevels)4462 static noinline_for_stack dml_float_t CalculateExtraLatency(
4463 		dml_uint_t RoundTripPingLatencyCycles,
4464 		dml_uint_t ReorderingBytes,
4465 		dml_float_t DCFCLK,
4466 		dml_uint_t TotalNumberOfActiveDPP,
4467 		dml_uint_t PixelChunkSizeInKByte,
4468 		dml_uint_t TotalNumberOfDCCActiveDPP,
4469 		dml_uint_t MetaChunkSize,
4470 		dml_float_t ReturnBW,
4471 		dml_bool_t GPUVMEnable,
4472 		dml_bool_t HostVMEnable,
4473 		dml_uint_t NumberOfActiveSurfaces,
4474 		dml_uint_t NumberOfDPP[],
4475 		dml_uint_t dpte_group_bytes[],
4476 		dml_float_t HostVMInefficiencyFactor,
4477 		dml_uint_t HostVMMinPageSize,
4478 		dml_uint_t HostVMMaxNonCachedPageTableLevels)
4479 {
4480 	dml_float_t ExtraLatencyBytes;
4481 	dml_float_t ExtraLatency;
4482 
4483 	ExtraLatencyBytes = CalculateExtraLatencyBytes(
4484 			ReorderingBytes,
4485 			TotalNumberOfActiveDPP,
4486 			PixelChunkSizeInKByte,
4487 			TotalNumberOfDCCActiveDPP,
4488 			MetaChunkSize,
4489 			GPUVMEnable,
4490 			HostVMEnable,
4491 			NumberOfActiveSurfaces,
4492 			NumberOfDPP,
4493 			dpte_group_bytes,
4494 			HostVMInefficiencyFactor,
4495 			HostVMMinPageSize,
4496 			HostVMMaxNonCachedPageTableLevels);
4497 
4498 	ExtraLatency = (RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__) / DCFCLK + ExtraLatencyBytes / ReturnBW;
4499 
4500 #ifdef __DML_VBA_DEBUG__
4501 	dml_print("DML::%s: RoundTripPingLatencyCycles=%u\n", __func__, RoundTripPingLatencyCycles);
4502 	dml_print("DML::%s: DCFCLK=%f\n", __func__, DCFCLK);
4503 	dml_print("DML::%s: ExtraLatencyBytes=%f\n", __func__, ExtraLatencyBytes);
4504 	dml_print("DML::%s: ReturnBW=%f\n", __func__, ReturnBW);
4505 	dml_print("DML::%s: ExtraLatency=%f\n", __func__, ExtraLatency);
4506 #endif
4507 
4508 	return ExtraLatency;
4509 } // CalculateExtraLatency
4510 
CalculateHostVMDynamicLevels(dml_bool_t GPUVMEnable,dml_bool_t HostVMEnable,dml_uint_t HostVMMinPageSize,dml_uint_t HostVMMaxNonCachedPageTableLevels)4511 static dml_uint_t CalculateHostVMDynamicLevels(
4512 									dml_bool_t GPUVMEnable,
4513 									dml_bool_t HostVMEnable,
4514 									dml_uint_t HostVMMinPageSize,
4515 									dml_uint_t HostVMMaxNonCachedPageTableLevels)
4516 {
4517 	dml_uint_t HostVMDynamicLevels = 0;
4518 
4519 	if (GPUVMEnable && HostVMEnable) {
4520 		if (HostVMMinPageSize < 2048)
4521 			HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
4522 		else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576)
4523 			HostVMDynamicLevels = (dml_uint_t) dml_max(0, (dml_float_t) HostVMMaxNonCachedPageTableLevels - 1);
4524 		else
4525 			HostVMDynamicLevels = (dml_uint_t) dml_max(0, (dml_float_t) HostVMMaxNonCachedPageTableLevels - 2);
4526 	} else {
4527 		HostVMDynamicLevels = 0;
4528 	}
4529 	return HostVMDynamicLevels;
4530 }
4531 
CalculateExtraLatencyBytes(dml_uint_t ReorderingBytes,dml_uint_t TotalNumberOfActiveDPP,dml_uint_t PixelChunkSizeInKByte,dml_uint_t TotalNumberOfDCCActiveDPP,dml_uint_t MetaChunkSize,dml_bool_t GPUVMEnable,dml_bool_t HostVMEnable,dml_uint_t NumberOfActiveSurfaces,dml_uint_t NumberOfDPP[],dml_uint_t dpte_group_bytes[],dml_float_t HostVMInefficiencyFactor,dml_uint_t HostVMMinPageSize,dml_uint_t HostVMMaxNonCachedPageTableLevels)4532 static dml_uint_t CalculateExtraLatencyBytes(dml_uint_t ReorderingBytes,
4533 										dml_uint_t TotalNumberOfActiveDPP,
4534 										dml_uint_t PixelChunkSizeInKByte,
4535 										dml_uint_t TotalNumberOfDCCActiveDPP,
4536 										dml_uint_t MetaChunkSize,
4537 										dml_bool_t GPUVMEnable,
4538 										dml_bool_t HostVMEnable,
4539 										dml_uint_t NumberOfActiveSurfaces,
4540 										dml_uint_t NumberOfDPP[],
4541 										dml_uint_t dpte_group_bytes[],
4542 										dml_float_t HostVMInefficiencyFactor,
4543 										dml_uint_t HostVMMinPageSize,
4544 										dml_uint_t HostVMMaxNonCachedPageTableLevels)
4545 {
4546 	dml_uint_t  HostVMDynamicLevels = CalculateHostVMDynamicLevels(GPUVMEnable, HostVMEnable, HostVMMinPageSize, HostVMMaxNonCachedPageTableLevels);
4547 	dml_float_t ret                 = ReorderingBytes + (TotalNumberOfActiveDPP * PixelChunkSizeInKByte + TotalNumberOfDCCActiveDPP * MetaChunkSize) * 1024.0;
4548 
4549 	if (GPUVMEnable == true) {
4550 		for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4551 			ret = ret + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactor;
4552 		}
4553 	}
4554 	return (dml_uint_t)(ret);
4555 }
4556 
CalculateUrgentLatency(dml_float_t UrgentLatencyPixelDataOnly,dml_float_t UrgentLatencyPixelMixedWithVMData,dml_float_t UrgentLatencyVMDataOnly,dml_bool_t DoUrgentLatencyAdjustment,dml_float_t UrgentLatencyAdjustmentFabricClockComponent,dml_float_t UrgentLatencyAdjustmentFabricClockReference,dml_float_t FabricClock)4557 static dml_float_t CalculateUrgentLatency(
4558 		dml_float_t UrgentLatencyPixelDataOnly,
4559 		dml_float_t UrgentLatencyPixelMixedWithVMData,
4560 		dml_float_t UrgentLatencyVMDataOnly,
4561 		dml_bool_t DoUrgentLatencyAdjustment,
4562 		dml_float_t UrgentLatencyAdjustmentFabricClockComponent,
4563 		dml_float_t UrgentLatencyAdjustmentFabricClockReference,
4564 		dml_float_t FabricClock)
4565 {
4566 	dml_float_t   ret;
4567 
4568 	ret = dml_max3(UrgentLatencyPixelDataOnly, UrgentLatencyPixelMixedWithVMData, UrgentLatencyVMDataOnly);
4569 	if (DoUrgentLatencyAdjustment == true) {
4570 		ret = ret + UrgentLatencyAdjustmentFabricClockComponent * (UrgentLatencyAdjustmentFabricClockReference / FabricClock - 1);
4571 	}
4572 	return ret;
4573 }
4574 
RequiredDTBCLK(dml_bool_t DSCEnable,dml_float_t PixelClock,enum dml_output_format_class OutputFormat,dml_float_t OutputBpp,dml_uint_t DSCSlices,dml_uint_t HTotal,dml_uint_t HActive,dml_uint_t AudioRate,dml_uint_t AudioLayout)4575 static dml_float_t RequiredDTBCLK(
4576 		dml_bool_t DSCEnable,
4577 		dml_float_t PixelClock,
4578 		enum dml_output_format_class OutputFormat,
4579 		dml_float_t OutputBpp,
4580 		dml_uint_t DSCSlices,
4581 		dml_uint_t HTotal,
4582 		dml_uint_t HActive,
4583 		dml_uint_t AudioRate,
4584 		dml_uint_t AudioLayout)
4585 {
4586 	if (DSCEnable != true) {
4587 		return dml_max(PixelClock / 4.0 * OutputBpp / 24.0, 25.0);
4588 	} else {
4589 		dml_float_t PixelWordRate = PixelClock / (OutputFormat == dml_444 ? 1 : 2);
4590 		dml_float_t HCActive = dml_ceil(DSCSlices * dml_ceil(OutputBpp * dml_ceil(HActive / DSCSlices, 1) / 8.0, 1) / 3.0, 1);
4591 		dml_float_t HCBlank = 64 + 32 * dml_ceil(AudioRate * (AudioLayout == 1 ? 1 : 0.25) * HTotal / (PixelClock * 1000), 1);
4592 		dml_float_t AverageTribyteRate = PixelWordRate * (HCActive + HCBlank) / HTotal;
4593 		dml_float_t HActiveTribyteRate = PixelWordRate * HCActive / HActive;
4594 		return dml_max4(PixelWordRate / 4.0, AverageTribyteRate / 4.0, HActiveTribyteRate / 4.0, 25.0) * 1.002;
4595 	}
4596 }
4597 
UseMinimumDCFCLK(struct display_mode_lib_scratch_st * scratch,struct UseMinimumDCFCLK_params_st * p)4598 static void UseMinimumDCFCLK(struct display_mode_lib_scratch_st *scratch, struct UseMinimumDCFCLK_params_st *p)
4599 {
4600 	struct UseMinimumDCFCLK_locals_st *s = &scratch->UseMinimumDCFCLK_locals;
4601 
4602 	s->NormalEfficiency = p->PercentOfIdealSDPPortBWReceivedAfterUrgLatency / 100.0;
4603 	for (dml_uint_t j = 0; j < 2; ++j) {
4604 
4605 
4606 		s->TotalMaxPrefetchFlipDPTERowBandwidth[j] = 0;
4607 		for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4608 			s->TotalMaxPrefetchFlipDPTERowBandwidth[j] = s->TotalMaxPrefetchFlipDPTERowBandwidth[j] + p->NoOfDPP[j][k] * p->DPTEBytesPerRow[j][k] / (15.75 * p->HTotal[k] / p->PixelClock[k]);
4609 		}
4610 
4611 		for (dml_uint_t k = 0; k <= p->NumberOfActiveSurfaces - 1; ++k) {
4612 			s->NoOfDPPState[k] = p->NoOfDPP[j][k];
4613 		}
4614 
4615 		s->DPTEBandwidth = s->TotalMaxPrefetchFlipDPTERowBandwidth[j];
4616 
4617 		s->DCFCLKRequiredForAverageBandwidth = dml_max(p->ProjectedDCFCLKDeepSleep[j], s->DPTEBandwidth / s->NormalEfficiency / p->ReturnBusWidth);
4618 
4619 		s->ExtraLatencyBytes = CalculateExtraLatencyBytes(p->ReorderingBytes, p->TotalNumberOfActiveDPP[j], p->PixelChunkSizeInKByte, p->TotalNumberOfDCCActiveDPP[j],
4620 			p->MetaChunkSize, p->GPUVMEnable, p->HostVMEnable, p->NumberOfActiveSurfaces, s->NoOfDPPState, p->dpte_group_bytes,
4621 												1, p->HostVMMinPageSize, p->HostVMMaxNonCachedPageTableLevels);
4622 		s->ExtraLatencyCycles = p->RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__ + s->ExtraLatencyBytes / s->NormalEfficiency / p->ReturnBusWidth;
4623 		for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4624 			dml_float_t DCFCLKCyclesRequiredInPrefetch;
4625 			dml_float_t PrefetchTime;
4626 
4627 			s->PixelDCFCLKCyclesRequiredInPrefetch[k] = (p->PrefetchLinesY[j][k] * p->swath_width_luma_ub_all_states[j][k] * p->BytePerPixelY[k] + p->PrefetchLinesC[j][k] * p->swath_width_chroma_ub_all_states[j][k] * p->BytePerPixelC[k]) / s->NormalEfficiency / p->ReturnBusWidth;
4628 			DCFCLKCyclesRequiredInPrefetch = 2 * s->ExtraLatencyCycles / s->NoOfDPPState[k] + p->PDEAndMetaPTEBytesPerFrame[j][k] / s->NormalEfficiency / s->NormalEfficiency / p->ReturnBusWidth * (p->GPUVMMaxPageTableLevels > 2 ? 1 : 0) + 2 * p->DPTEBytesPerRow[j][k] / s->NormalEfficiency / s->NormalEfficiency / p->ReturnBusWidth + 2 * p->MetaRowBytes[j][k] / s->NormalEfficiency / p->ReturnBusWidth + s->PixelDCFCLKCyclesRequiredInPrefetch[k];
4629 			s->PrefetchPixelLinesTime[k] = dml_max(p->PrefetchLinesY[j][k], p->PrefetchLinesC[j][k]) * p->HTotal[k] / p->PixelClock[k];
4630 			s->DynamicMetadataVMExtraLatency[k] = (p->GPUVMEnable == true && p->DynamicMetadataEnable[k] == true && p->DynamicMetadataVMEnabled == true) ? p->UrgLatency * p->GPUVMMaxPageTableLevels * (p->HostVMEnable == true ? p->HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0;
4631 
4632 			s->MinimumTWait = CalculateTWait(p->MaxPrefetchMode,
4633 				p->UseMALLForPStateChange[k],
4634 				p->SynchronizeDRRDisplaysForUCLKPStateChangeFinal,
4635 				p->DRRDisplay[k],
4636 				p->DRAMClockChangeLatencyFinal,
4637 				p->FCLKChangeLatency,
4638 				p->UrgLatency,
4639 				p->SREnterPlusExitTime);
4640 
4641 			PrefetchTime = (p->MaximumVStartup[j][k] - 1) * p->HTotal[k] / p->PixelClock[k] - s->MinimumTWait - p->UrgLatency * ((p->GPUVMMaxPageTableLevels <= 2 ? p->GPUVMMaxPageTableLevels : p->GPUVMMaxPageTableLevels - 2) *  (p->HostVMEnable == true ? p->HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1) - s->DynamicMetadataVMExtraLatency[k];
4642 
4643 			if (PrefetchTime > 0) {
4644 				dml_float_t ExpectedVRatioPrefetch;
4645 				ExpectedVRatioPrefetch = s->PrefetchPixelLinesTime[k] / (PrefetchTime * s->PixelDCFCLKCyclesRequiredInPrefetch[k] / DCFCLKCyclesRequiredInPrefetch);
4646 				s->DCFCLKRequiredForPeakBandwidthPerSurface[k] = s->NoOfDPPState[k] * s->PixelDCFCLKCyclesRequiredInPrefetch[k] / s->PrefetchPixelLinesTime[k] * dml_max(1.0, ExpectedVRatioPrefetch) * dml_max(1.0, ExpectedVRatioPrefetch / 4);
4647 				if (p->HostVMEnable == true || p->ImmediateFlipRequirement == true) {
4648 					s->DCFCLKRequiredForPeakBandwidthPerSurface[k] = s->DCFCLKRequiredForPeakBandwidthPerSurface[k] + s->NoOfDPPState[k] * s->DPTEBandwidth / s->NormalEfficiency / s->NormalEfficiency / p->ReturnBusWidth;
4649 				}
4650 			} else {
4651 				s->DCFCLKRequiredForPeakBandwidthPerSurface[k] = p->DCFCLKPerState;
4652 			}
4653 			if (p->DynamicMetadataEnable[k] == true) {
4654 				dml_float_t TSetupPipe;
4655 				dml_float_t TdmbfPipe;
4656 				dml_float_t TdmsksPipe;
4657 				dml_float_t TdmecPipe;
4658 				dml_float_t AllowedTimeForUrgentExtraLatency;
4659 
4660 				CalculateVUpdateAndDynamicMetadataParameters(
4661 					p->MaxInterDCNTileRepeaters,
4662 					p->RequiredDPPCLKPerSurface[j][k],
4663 					p->RequiredDISPCLK[j],
4664 					p->ProjectedDCFCLKDeepSleep[j],
4665 					p->PixelClock[k],
4666 					p->HTotal[k],
4667 					p->VTotal[k] - p->VActive[k],
4668 					p->DynamicMetadataTransmittedBytes[k],
4669 					p->DynamicMetadataLinesBeforeActiveRequired[k],
4670 					p->Interlace[k],
4671 					p->ProgressiveToInterlaceUnitInOPP,
4672 
4673 					// Output
4674 					&TSetupPipe,
4675 					&TdmbfPipe,
4676 					&TdmecPipe,
4677 					&TdmsksPipe,
4678 					&s->dummy1,
4679 					&s->dummy2,
4680 					&s->dummy3);
4681 
4682 				AllowedTimeForUrgentExtraLatency = p->MaximumVStartup[j][k] * p->HTotal[k] / p->PixelClock[k] - s->MinimumTWait - TSetupPipe - TdmbfPipe - TdmecPipe - TdmsksPipe - s->DynamicMetadataVMExtraLatency[k];
4683 				if (AllowedTimeForUrgentExtraLatency > 0) {
4684 					s->DCFCLKRequiredForPeakBandwidthPerSurface[k] = dml_max(s->DCFCLKRequiredForPeakBandwidthPerSurface[k], s->ExtraLatencyCycles / AllowedTimeForUrgentExtraLatency);
4685 				} else {
4686 					s->DCFCLKRequiredForPeakBandwidthPerSurface[k] = p->DCFCLKPerState;
4687 				}
4688 			}
4689 		}
4690 		s->DCFCLKRequiredForPeakBandwidth = 0;
4691 		for (dml_uint_t k = 0; k <= p->NumberOfActiveSurfaces - 1; ++k) {
4692 			s->DCFCLKRequiredForPeakBandwidth = s->DCFCLKRequiredForPeakBandwidth + s->DCFCLKRequiredForPeakBandwidthPerSurface[k];
4693 		}
4694 		s->MinimumTvmPlus2Tr0 = p->UrgLatency * (p->GPUVMEnable == true ? (p->HostVMEnable == true ? (p->GPUVMMaxPageTableLevels + 2) * (p->HostVMMaxNonCachedPageTableLevels + 1) - 1 : p->GPUVMMaxPageTableLevels + 1) : 0);
4695 		for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
4696 			dml_float_t MaximumTvmPlus2Tr0PlusTsw;
4697 			MaximumTvmPlus2Tr0PlusTsw = (p->MaximumVStartup[j][k] - 2) * p->HTotal[k] / p->PixelClock[k] - s->MinimumTWait - s->DynamicMetadataVMExtraLatency[k];
4698 			if (MaximumTvmPlus2Tr0PlusTsw <= s->MinimumTvmPlus2Tr0 + s->PrefetchPixelLinesTime[k] / 4) {
4699 				s->DCFCLKRequiredForPeakBandwidth = p->DCFCLKPerState;
4700 			} else {
4701 				s->DCFCLKRequiredForPeakBandwidth = dml_max3(s->DCFCLKRequiredForPeakBandwidth,
4702 														2 * s->ExtraLatencyCycles / (MaximumTvmPlus2Tr0PlusTsw - s->MinimumTvmPlus2Tr0 - s->PrefetchPixelLinesTime[k] / 4),
4703 														(2 * s->ExtraLatencyCycles + s->PixelDCFCLKCyclesRequiredInPrefetch[k]) / (MaximumTvmPlus2Tr0PlusTsw - s->MinimumTvmPlus2Tr0));
4704 			}
4705 		}
4706 		p->DCFCLKState[j] = dml_min(p->DCFCLKPerState, 1.05 * dml_max(s->DCFCLKRequiredForAverageBandwidth, s->DCFCLKRequiredForPeakBandwidth));
4707 	}
4708 }
4709 
4710 
UnboundedRequest(enum dml_unbounded_requesting_policy UseUnboundedRequestingFinal,dml_uint_t TotalNumberOfActiveDPP,dml_bool_t NoChromaOrLinear,enum dml_output_encoder_class Output)4711 static dml_bool_t UnboundedRequest(enum dml_unbounded_requesting_policy UseUnboundedRequestingFinal,
4712 						dml_uint_t TotalNumberOfActiveDPP,
4713 						dml_bool_t NoChromaOrLinear,
4714 						enum dml_output_encoder_class Output)
4715 {
4716 	dml_bool_t ret_val = false;
4717 
4718 	ret_val = (UseUnboundedRequestingFinal != dml_unbounded_requesting_disable
4719 			&& TotalNumberOfActiveDPP == 1 && NoChromaOrLinear);
4720 	if (UseUnboundedRequestingFinal == dml_unbounded_requesting_edp_only && Output != dml_edp) {
4721 		ret_val = false;
4722 	}
4723 	return (ret_val);
4724 }
4725 
CalculateSurfaceSizeInMall(dml_uint_t NumberOfActiveSurfaces,dml_uint_t MALLAllocatedForDCN,enum dml_use_mall_for_static_screen_mode UseMALLForStaticScreen[],dml_bool_t DCCEnable[],dml_bool_t ViewportStationary[],dml_uint_t ViewportXStartY[],dml_uint_t ViewportYStartY[],dml_uint_t ViewportXStartC[],dml_uint_t ViewportYStartC[],dml_uint_t ViewportWidthY[],dml_uint_t ViewportHeightY[],dml_uint_t BytesPerPixelY[],dml_uint_t ViewportWidthC[],dml_uint_t ViewportHeightC[],dml_uint_t BytesPerPixelC[],dml_uint_t SurfaceWidthY[],dml_uint_t SurfaceWidthC[],dml_uint_t SurfaceHeightY[],dml_uint_t SurfaceHeightC[],dml_uint_t Read256BytesBlockWidthY[],dml_uint_t Read256BytesBlockWidthC[],dml_uint_t Read256BytesBlockHeightY[],dml_uint_t Read256BytesBlockHeightC[],dml_uint_t ReadBlockWidthY[],dml_uint_t ReadBlockWidthC[],dml_uint_t ReadBlockHeightY[],dml_uint_t ReadBlockHeightC[],dml_uint_t SurfaceSizeInMALL[],dml_bool_t * ExceededMALLSize)4726 static void CalculateSurfaceSizeInMall(
4727 		dml_uint_t NumberOfActiveSurfaces,
4728 		dml_uint_t MALLAllocatedForDCN,
4729 		enum dml_use_mall_for_static_screen_mode UseMALLForStaticScreen[],
4730 		dml_bool_t DCCEnable[],
4731 		dml_bool_t ViewportStationary[],
4732 		dml_uint_t ViewportXStartY[],
4733 		dml_uint_t ViewportYStartY[],
4734 		dml_uint_t ViewportXStartC[],
4735 		dml_uint_t ViewportYStartC[],
4736 		dml_uint_t ViewportWidthY[],
4737 		dml_uint_t ViewportHeightY[],
4738 		dml_uint_t BytesPerPixelY[],
4739 		dml_uint_t ViewportWidthC[],
4740 		dml_uint_t ViewportHeightC[],
4741 		dml_uint_t BytesPerPixelC[],
4742 		dml_uint_t SurfaceWidthY[],
4743 		dml_uint_t SurfaceWidthC[],
4744 		dml_uint_t SurfaceHeightY[],
4745 		dml_uint_t SurfaceHeightC[],
4746 		dml_uint_t Read256BytesBlockWidthY[],
4747 		dml_uint_t Read256BytesBlockWidthC[],
4748 		dml_uint_t Read256BytesBlockHeightY[],
4749 		dml_uint_t Read256BytesBlockHeightC[],
4750 		dml_uint_t ReadBlockWidthY[],
4751 		dml_uint_t ReadBlockWidthC[],
4752 		dml_uint_t ReadBlockHeightY[],
4753 		dml_uint_t ReadBlockHeightC[],
4754 
4755 		// Output
4756 		dml_uint_t SurfaceSizeInMALL[],
4757 		dml_bool_t *ExceededMALLSize)
4758 {
4759 	dml_uint_t TotalSurfaceSizeInMALL  = 0;
4760 
4761 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4762 		if (ViewportStationary[k]) {
4763 			SurfaceSizeInMALL[k] = (dml_uint_t)(dml_min(dml_ceil(SurfaceWidthY[k], ReadBlockWidthY[k]), dml_floor(ViewportXStartY[k] + ViewportWidthY[k] + ReadBlockWidthY[k] - 1, ReadBlockWidthY[k]) - dml_floor(ViewportXStartY[k], ReadBlockWidthY[k])) *
4764 									dml_min(dml_ceil(SurfaceHeightY[k], ReadBlockHeightY[k]), dml_floor(ViewportYStartY[k] + ViewportHeightY[k] + ReadBlockHeightY[k] - 1, ReadBlockHeightY[k]) - dml_floor(ViewportYStartY[k], ReadBlockHeightY[k])) *
4765 									BytesPerPixelY[k]);
4766 
4767 			if (ReadBlockWidthC[k] > 0) {
4768 				SurfaceSizeInMALL[k] = (dml_uint_t)(SurfaceSizeInMALL[k] +
4769 										dml_min(dml_ceil(SurfaceWidthC[k], ReadBlockWidthC[k]), dml_floor(ViewportXStartC[k] + ViewportWidthC[k] + ReadBlockWidthC[k] - 1, ReadBlockWidthC[k]) - dml_floor(ViewportXStartC[k], ReadBlockWidthC[k])) *
4770 										dml_min(dml_ceil(SurfaceHeightC[k], ReadBlockHeightC[k]), dml_floor(ViewportYStartC[k] + ViewportHeightC[k] + ReadBlockHeightC[k] - 1, ReadBlockHeightC[k]) - dml_floor(ViewportYStartC[k], ReadBlockHeightC[k])) * BytesPerPixelC[k]);
4771 			}
4772 			if (DCCEnable[k] == true) {
4773 				SurfaceSizeInMALL[k] = (dml_uint_t)(SurfaceSizeInMALL[k] +
4774 					dml_min(dml_ceil(SurfaceWidthY[k], 8 * Read256BytesBlockWidthY[k]), dml_floor(ViewportXStartY[k] + ViewportWidthY[k] + 8 * Read256BytesBlockWidthY[k] - 1, 8 * Read256BytesBlockWidthY[k]) - dml_floor(ViewportXStartY[k], 8 * Read256BytesBlockWidthY[k])) *
4775 					dml_min(dml_ceil(SurfaceHeightY[k], 8 * Read256BytesBlockHeightY[k]), dml_floor(ViewportYStartY[k] + ViewportHeightY[k] + 8 * Read256BytesBlockHeightY[k] - 1, 8 * Read256BytesBlockHeightY[k]) - dml_floor(ViewportYStartY[k], 8 * Read256BytesBlockHeightY[k])) * BytesPerPixelY[k] / 256);
4776 				if (Read256BytesBlockWidthC[k] > 0) {
4777 					SurfaceSizeInMALL[k] = (dml_uint_t)(SurfaceSizeInMALL[k] +
4778 						dml_min(dml_ceil(SurfaceWidthC[k], 8 * Read256BytesBlockWidthC[k]), dml_floor(ViewportXStartC[k] + ViewportWidthC[k] + 8 * Read256BytesBlockWidthC[k] - 1, 8 * Read256BytesBlockWidthC[k]) - dml_floor(ViewportXStartC[k], 8 * Read256BytesBlockWidthC[k])) *
4779 						dml_min(dml_ceil(SurfaceHeightC[k], 8 * Read256BytesBlockHeightC[k]), dml_floor(ViewportYStartC[k] + ViewportHeightC[k] + 8 * Read256BytesBlockHeightC[k] - 1, 8 * Read256BytesBlockHeightC[k]) - dml_floor(ViewportYStartC[k], 8 * Read256BytesBlockHeightC[k])) * BytesPerPixelC[k] / 256);
4780 				}
4781 			}
4782 		} else {
4783 			SurfaceSizeInMALL[k] = (dml_uint_t)(dml_ceil(dml_min(SurfaceWidthY[k], ViewportWidthY[k] + ReadBlockWidthY[k] - 1), ReadBlockWidthY[k]) * dml_ceil(dml_min(SurfaceHeightY[k], ViewportHeightY[k] + ReadBlockHeightY[k] - 1), ReadBlockHeightY[k]) * BytesPerPixelY[k]);
4784 			if (ReadBlockWidthC[k] > 0) {
4785 				SurfaceSizeInMALL[k] = (dml_uint_t)(SurfaceSizeInMALL[k] +
4786 										dml_ceil(dml_min(SurfaceWidthC[k], ViewportWidthC[k] + ReadBlockWidthC[k] - 1), ReadBlockWidthC[k]) *
4787 										dml_ceil(dml_min(SurfaceHeightC[k], ViewportHeightC[k] + ReadBlockHeightC[k] - 1), ReadBlockHeightC[k]) * BytesPerPixelC[k]);
4788 		}
4789 		if (DCCEnable[k] == true) {
4790 			SurfaceSizeInMALL[k] = (dml_uint_t)(SurfaceSizeInMALL[k] +
4791 					dml_ceil(dml_min(SurfaceWidthY[k], ViewportWidthY[k] + 8 * Read256BytesBlockWidthY[k] - 1), 8 * Read256BytesBlockWidthY[k]) *
4792 					dml_ceil(dml_min(SurfaceHeightY[k], ViewportHeightY[k] + 8 * Read256BytesBlockHeightY[k] - 1), 8 * Read256BytesBlockHeightY[k]) * BytesPerPixelY[k] / 256);
4793 
4794 				if (Read256BytesBlockWidthC[k] > 0) {
4795 					SurfaceSizeInMALL[k] = (dml_uint_t)(SurfaceSizeInMALL[k] +
4796 						dml_ceil(dml_min(SurfaceWidthC[k], ViewportWidthC[k] + 8 * Read256BytesBlockWidthC[k] - 1), 8 * Read256BytesBlockWidthC[k]) *
4797 						dml_ceil(dml_min(SurfaceHeightC[k], ViewportHeightC[k] + 8 * Read256BytesBlockHeightC[k] - 1), 8 * Read256BytesBlockHeightC[k]) * BytesPerPixelC[k] / 256);
4798 				}
4799 			}
4800 		}
4801 	}
4802 
4803 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4804 		if (UseMALLForStaticScreen[k] == dml_use_mall_static_screen_enable)
4805 			TotalSurfaceSizeInMALL = TotalSurfaceSizeInMALL + SurfaceSizeInMALL[k];
4806 	}
4807 	*ExceededMALLSize = (TotalSurfaceSizeInMALL > MALLAllocatedForDCN * 1024 * 1024);
4808 } // CalculateSurfaceSizeInMall
4809 
CalculateDETBufferSize(dml_uint_t DETSizeOverride[],enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],dml_bool_t ForceSingleDPP,dml_uint_t NumberOfActiveSurfaces,dml_bool_t UnboundedRequestEnabled,dml_uint_t nomDETInKByte,dml_uint_t MaxTotalDETInKByte,dml_uint_t ConfigReturnBufferSizeInKByte,dml_uint_t MinCompressedBufferSizeInKByte,dml_uint_t ConfigReturnBufferSegmentSizeInkByte,dml_uint_t CompressedBufferSegmentSizeInkByteFinal,enum dml_source_format_class SourcePixelFormat[],dml_float_t ReadBandwidthLuma[],dml_float_t ReadBandwidthChroma[],dml_uint_t RoundedUpMaxSwathSizeBytesY[],dml_uint_t RoundedUpMaxSwathSizeBytesC[],dml_uint_t DPPPerSurface[],dml_uint_t DETBufferSizeInKByte[],dml_uint_t * CompressedBufferSizeInkByte)4810 static void CalculateDETBufferSize(
4811 						dml_uint_t DETSizeOverride[],
4812 						enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
4813 						dml_bool_t ForceSingleDPP,
4814 						dml_uint_t NumberOfActiveSurfaces,
4815 						dml_bool_t UnboundedRequestEnabled,
4816 						dml_uint_t nomDETInKByte,
4817 						dml_uint_t MaxTotalDETInKByte,
4818 						dml_uint_t ConfigReturnBufferSizeInKByte,
4819 						dml_uint_t MinCompressedBufferSizeInKByte,
4820 						dml_uint_t ConfigReturnBufferSegmentSizeInkByte,
4821 						dml_uint_t CompressedBufferSegmentSizeInkByteFinal,
4822 						enum dml_source_format_class SourcePixelFormat[],
4823 						dml_float_t ReadBandwidthLuma[],
4824 						dml_float_t ReadBandwidthChroma[],
4825 						dml_uint_t RoundedUpMaxSwathSizeBytesY[],
4826 						dml_uint_t RoundedUpMaxSwathSizeBytesC[],
4827 						dml_uint_t DPPPerSurface[],
4828 						// Output
4829 						dml_uint_t DETBufferSizeInKByte[],
4830 						dml_uint_t *CompressedBufferSizeInkByte)
4831 {
4832 	dml_uint_t DETBufferSizePoolInKByte;
4833 	dml_uint_t NextDETBufferPieceInKByte;
4834 	dml_bool_t DETPieceAssignedToThisSurfaceAlready[__DML_NUM_PLANES__];
4835 	dml_bool_t NextPotentialSurfaceToAssignDETPieceFound;
4836 	dml_uint_t NextSurfaceToAssignDETPiece;
4837 	dml_float_t TotalBandwidth;
4838 	dml_float_t BandwidthOfSurfacesNotAssignedDETPiece;
4839 	dml_uint_t max_minDET;
4840 	dml_uint_t minDET;
4841 	dml_uint_t minDET_pipe;
4842 
4843 #ifdef __DML_VBA_DEBUG__
4844 	dml_print("DML::%s: ForceSingleDPP = %u\n", __func__, ForceSingleDPP);
4845 	dml_print("DML::%s: nomDETInKByte = %u\n", __func__, nomDETInKByte);
4846 	dml_print("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, NumberOfActiveSurfaces);
4847 	dml_print("DML::%s: UnboundedRequestEnabled = %u\n", __func__, UnboundedRequestEnabled);
4848 	dml_print("DML::%s: MaxTotalDETInKByte = %u\n", __func__, MaxTotalDETInKByte);
4849 	dml_print("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, ConfigReturnBufferSizeInKByte);
4850 	dml_print("DML::%s: MinCompressedBufferSizeInKByte = %u\n", __func__, MinCompressedBufferSizeInKByte);
4851 	dml_print("DML::%s: CompressedBufferSegmentSizeInkByteFinal = %u\n", __func__, CompressedBufferSegmentSizeInkByteFinal);
4852 #endif
4853 
4854 	// Note: Will use default det size if that fits 2 swaths
4855 	if (UnboundedRequestEnabled) {
4856 		if (DETSizeOverride[0] > 0) {
4857 			DETBufferSizeInKByte[0] = DETSizeOverride[0];
4858 		} else {
4859 			DETBufferSizeInKByte[0] = (dml_uint_t) dml_max(128.0, dml_ceil(2.0 * ((dml_float_t) RoundedUpMaxSwathSizeBytesY[0] + (dml_float_t) RoundedUpMaxSwathSizeBytesC[0]) / 1024.0, ConfigReturnBufferSegmentSizeInkByte));
4860 		}
4861 		*CompressedBufferSizeInkByte = ConfigReturnBufferSizeInKByte - DETBufferSizeInKByte[0];
4862 	} else {
4863 		DETBufferSizePoolInKByte = MaxTotalDETInKByte;
4864 		for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4865 			DETBufferSizeInKByte[k] = 0;
4866 			if (SourcePixelFormat[k] == dml_420_8 || SourcePixelFormat[k] == dml_420_10 || SourcePixelFormat[k] == dml_420_12) {
4867 				max_minDET = nomDETInKByte - ConfigReturnBufferSegmentSizeInkByte;
4868 			} else {
4869 				max_minDET = nomDETInKByte;
4870 			}
4871 			minDET = 128;
4872 			minDET_pipe = 0;
4873 
4874 			// add DET resource until can hold 2 full swaths
4875 			while (minDET <= max_minDET && minDET_pipe == 0) {
4876 				if (2.0 * ((dml_float_t) RoundedUpMaxSwathSizeBytesY[k] + (dml_float_t) RoundedUpMaxSwathSizeBytesC[k]) / 1024.0 <= minDET)
4877 					minDET_pipe = minDET;
4878 				minDET = minDET + ConfigReturnBufferSegmentSizeInkByte;
4879 			}
4880 
4881 #ifdef __DML_VBA_DEBUG__
4882 			dml_print("DML::%s: k=%u minDET = %u\n", __func__, k, minDET);
4883 			dml_print("DML::%s: k=%u max_minDET = %u\n", __func__, k, max_minDET);
4884 			dml_print("DML::%s: k=%u minDET_pipe = %u\n", __func__, k, minDET_pipe);
4885 			dml_print("DML::%s: k=%u RoundedUpMaxSwathSizeBytesY = %u\n", __func__, k, RoundedUpMaxSwathSizeBytesY[k]);
4886 			dml_print("DML::%s: k=%u RoundedUpMaxSwathSizeBytesC = %u\n", __func__, k, RoundedUpMaxSwathSizeBytesC[k]);
4887 #endif
4888 
4889 			if (minDET_pipe == 0) {
4890 				minDET_pipe = (dml_uint_t)(dml_max(128, dml_ceil(((dml_float_t)RoundedUpMaxSwathSizeBytesY[k] + (dml_float_t)RoundedUpMaxSwathSizeBytesC[k]) / 1024.0, ConfigReturnBufferSegmentSizeInkByte)));
4891 #ifdef __DML_VBA_DEBUG__
4892 				dml_print("DML::%s: k=%u minDET_pipe = %u (assume each plane take half DET)\n", __func__, k, minDET_pipe);
4893 #endif
4894 			}
4895 
4896 			if (UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe) {
4897 				DETBufferSizeInKByte[k] = 0;
4898 			} else if (DETSizeOverride[k] > 0) {
4899 				DETBufferSizeInKByte[k] = DETSizeOverride[k];
4900 				DETBufferSizePoolInKByte = DETBufferSizePoolInKByte - (ForceSingleDPP ? 1 : DPPPerSurface[k]) * DETSizeOverride[k];
4901 			} else if ((ForceSingleDPP ? 1 : DPPPerSurface[k]) * minDET_pipe <= DETBufferSizePoolInKByte) {
4902 				DETBufferSizeInKByte[k] = minDET_pipe;
4903 				DETBufferSizePoolInKByte = DETBufferSizePoolInKByte - (ForceSingleDPP ? 1 : DPPPerSurface[k]) * minDET_pipe;
4904 			}
4905 
4906 #ifdef __DML_VBA_DEBUG__
4907 			dml_print("DML::%s: k=%u DPPPerSurface = %u\n", __func__, k, DPPPerSurface[k]);
4908 			dml_print("DML::%s: k=%u DETSizeOverride = %u\n", __func__, k, DETSizeOverride[k]);
4909 			dml_print("DML::%s: k=%u DETBufferSizeInKByte = %u\n", __func__, k, DETBufferSizeInKByte[k]);
4910 			dml_print("DML::%s: DETBufferSizePoolInKByte = %u\n", __func__, DETBufferSizePoolInKByte);
4911 #endif
4912 		}
4913 
4914 		TotalBandwidth = 0;
4915 		for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4916 			if (UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe)
4917 				TotalBandwidth = TotalBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
4918 		}
4919 #ifdef __DML_VBA_DEBUG__
4920 		dml_print("DML::%s: --- Before bandwidth adjustment ---\n", __func__);
4921 		for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4922 			dml_print("DML::%s: k=%u DETBufferSizeInKByte   = %u\n", __func__, k, DETBufferSizeInKByte[k]);
4923 		}
4924 		dml_print("DML::%s: --- DET allocation with bandwidth ---\n", __func__);
4925 #endif
4926 		dml_print("DML::%s: TotalBandwidth = %f\n", __func__, TotalBandwidth);
4927 		BandwidthOfSurfacesNotAssignedDETPiece = TotalBandwidth;
4928 		for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4929 
4930 			if (UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe) {
4931 				DETPieceAssignedToThisSurfaceAlready[k] = true;
4932 			} else if (DETSizeOverride[k] > 0 || (((dml_float_t) (ForceSingleDPP ? 1 : DPPPerSurface[k]) * (dml_float_t) DETBufferSizeInKByte[k] / (dml_float_t) MaxTotalDETInKByte) >= ((ReadBandwidthLuma[k] + ReadBandwidthChroma[k]) / TotalBandwidth))) {
4933 				DETPieceAssignedToThisSurfaceAlready[k] = true;
4934 				BandwidthOfSurfacesNotAssignedDETPiece = BandwidthOfSurfacesNotAssignedDETPiece - ReadBandwidthLuma[k] - ReadBandwidthChroma[k];
4935 			} else {
4936 				DETPieceAssignedToThisSurfaceAlready[k] = false;
4937 			}
4938 #ifdef __DML_VBA_DEBUG__
4939 			dml_print("DML::%s: k=%u DETPieceAssignedToThisSurfaceAlready = %u\n", __func__, k, DETPieceAssignedToThisSurfaceAlready[k]);
4940 			dml_print("DML::%s: k=%u BandwidthOfSurfacesNotAssignedDETPiece = %f\n", __func__, k, BandwidthOfSurfacesNotAssignedDETPiece);
4941 #endif
4942 		}
4943 
4944 		for (dml_uint_t j = 0; j < NumberOfActiveSurfaces; ++j) {
4945 			NextPotentialSurfaceToAssignDETPieceFound = false;
4946 			NextSurfaceToAssignDETPiece = 0;
4947 
4948 			for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
4949 #ifdef __DML_VBA_DEBUG__
4950 				dml_print("DML::%s: j=%u k=%u, ReadBandwidthLuma[k] = %f\n", __func__, j, k, ReadBandwidthLuma[k]);
4951 				dml_print("DML::%s: j=%u k=%u, ReadBandwidthChroma[k] = %f\n", __func__, j, k, ReadBandwidthChroma[k]);
4952 				dml_print("DML::%s: j=%u k=%u, ReadBandwidthLuma[Next] = %f\n", __func__, j, k, ReadBandwidthLuma[NextSurfaceToAssignDETPiece]);
4953 				dml_print("DML::%s: j=%u k=%u, ReadBandwidthChroma[Next] = %f\n", __func__, j, k, ReadBandwidthChroma[NextSurfaceToAssignDETPiece]);
4954 				dml_print("DML::%s: j=%u k=%u, NextSurfaceToAssignDETPiece = %u\n", __func__, j, k, NextSurfaceToAssignDETPiece);
4955 #endif
4956 				if (!DETPieceAssignedToThisSurfaceAlready[k] && (!NextPotentialSurfaceToAssignDETPieceFound ||
4957 					ReadBandwidthLuma[k] + ReadBandwidthChroma[k] < ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[NextSurfaceToAssignDETPiece])) {
4958 					NextSurfaceToAssignDETPiece = k;
4959 					NextPotentialSurfaceToAssignDETPieceFound = true;
4960 				}
4961 #ifdef __DML_VBA_DEBUG__
4962 				dml_print("DML::%s: j=%u k=%u, DETPieceAssignedToThisSurfaceAlready = %u\n", __func__, j, k, DETPieceAssignedToThisSurfaceAlready[k]);
4963 				dml_print("DML::%s: j=%u k=%u, NextPotentialSurfaceToAssignDETPieceFound = %u\n", __func__, j, k, NextPotentialSurfaceToAssignDETPieceFound);
4964 #endif
4965 			}
4966 
4967 			if (NextPotentialSurfaceToAssignDETPieceFound) {
4968 				// Note: To show the banker's rounding behavior in VBA and also the fact that the DET buffer size varies due to precision issue
4969 				//
4970 				//dml_float_t tmp1 =  ((dml_float_t) DETBufferSizePoolInKByte * (ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[NextSurfaceToAssignDETPiece]) / BandwidthOfSurfacesNotAssignedDETPiece /
4971 				//                         ((ForceSingleDPP ? 1 : DPPPerSurface[NextSurfaceToAssignDETPiece]) * 64.0));
4972 				//dml_float_t tmp2 =  dml_round((dml_float_t) DETBufferSizePoolInKByte * (ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[NextSurfaceToAssignDETPiece]) / BandwidthOfSurfacesNotAssignedDETPiece /
4973 				//                         ((ForceSingleDPP ? 1 : DPPPerSurface[NextSurfaceToAssignDETPiece]) * 64.0));
4974 				//
4975 				//dml_print("DML::%s: j=%u, tmp1 = %f\n", __func__, j, tmp1);
4976 				//dml_print("DML::%s: j=%u, tmp2 = %f\n", __func__, j, tmp2);
4977 
4978 				NextDETBufferPieceInKByte = (dml_uint_t)(dml_min(
4979 											dml_round((dml_float_t) DETBufferSizePoolInKByte * (ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[NextSurfaceToAssignDETPiece]) / BandwidthOfSurfacesNotAssignedDETPiece /
4980 												((ForceSingleDPP ? 1 : DPPPerSurface[NextSurfaceToAssignDETPiece]) * ConfigReturnBufferSegmentSizeInkByte), true)
4981 												* (ForceSingleDPP ? 1 : DPPPerSurface[NextSurfaceToAssignDETPiece]) * ConfigReturnBufferSegmentSizeInkByte,
4982 											dml_floor((dml_float_t) DETBufferSizePoolInKByte, (ForceSingleDPP ? 1 : DPPPerSurface[NextSurfaceToAssignDETPiece]) * ConfigReturnBufferSegmentSizeInkByte)));
4983 
4984 #ifdef __DML_VBA_DEBUG__
4985 				dml_print("DML::%s: j=%u, DETBufferSizePoolInKByte = %u\n", __func__, j, DETBufferSizePoolInKByte);
4986 				dml_print("DML::%s: j=%u, NextSurfaceToAssignDETPiece = %u\n", __func__, j, NextSurfaceToAssignDETPiece);
4987 				dml_print("DML::%s: j=%u, ReadBandwidthLuma[%u] = %f\n", __func__, j, NextSurfaceToAssignDETPiece, ReadBandwidthLuma[NextSurfaceToAssignDETPiece]);
4988 				dml_print("DML::%s: j=%u, ReadBandwidthChroma[%u] = %f\n", __func__, j, NextSurfaceToAssignDETPiece, ReadBandwidthChroma[NextSurfaceToAssignDETPiece]);
4989 				dml_print("DML::%s: j=%u, BandwidthOfSurfacesNotAssignedDETPiece = %f\n", __func__, j, BandwidthOfSurfacesNotAssignedDETPiece);
4990 				dml_print("DML::%s: j=%u, NextDETBufferPieceInKByte = %u\n", __func__, j, NextDETBufferPieceInKByte);
4991 				dml_print("DML::%s: j=%u, DETBufferSizeInKByte[%u] increases from %u ", __func__, j, NextSurfaceToAssignDETPiece, DETBufferSizeInKByte[NextSurfaceToAssignDETPiece]);
4992 #endif
4993 
4994 				DETBufferSizeInKByte[NextSurfaceToAssignDETPiece] = DETBufferSizeInKByte[NextSurfaceToAssignDETPiece] + NextDETBufferPieceInKByte / (ForceSingleDPP ? 1 : DPPPerSurface[NextSurfaceToAssignDETPiece]);
4995 #ifdef __DML_VBA_DEBUG__
4996 				dml_print("to %u\n", DETBufferSizeInKByte[NextSurfaceToAssignDETPiece]);
4997 #endif
4998 
4999 				DETBufferSizePoolInKByte = DETBufferSizePoolInKByte - NextDETBufferPieceInKByte;
5000 				DETPieceAssignedToThisSurfaceAlready[NextSurfaceToAssignDETPiece] = true;
5001 				BandwidthOfSurfacesNotAssignedDETPiece = BandwidthOfSurfacesNotAssignedDETPiece - (ReadBandwidthLuma[NextSurfaceToAssignDETPiece] + ReadBandwidthChroma[NextSurfaceToAssignDETPiece]);
5002 			}
5003 		}
5004 		*CompressedBufferSizeInkByte = MinCompressedBufferSizeInKByte;
5005 	}
5006 	*CompressedBufferSizeInkByte = *CompressedBufferSizeInkByte * CompressedBufferSegmentSizeInkByteFinal / ConfigReturnBufferSegmentSizeInkByte;
5007 
5008 #ifdef __DML_VBA_DEBUG__
5009 	dml_print("DML::%s: --- After bandwidth adjustment ---\n", __func__);
5010 	dml_print("DML::%s: CompressedBufferSizeInkByte = %u\n", __func__, *CompressedBufferSizeInkByte);
5011 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5012 		dml_print("DML::%s: k=%u DETBufferSizeInKByte = %u (TotalReadBandWidth=%f)\n", __func__, k, DETBufferSizeInKByte[k], ReadBandwidthLuma[k] + ReadBandwidthChroma[k]);
5013 	}
5014 #endif
5015 } // CalculateDETBufferSize
5016 
5017 
5018 /// @brief Calculate the bound for return buffer sizing
CalculateMaxDETAndMinCompressedBufferSize(dml_uint_t ConfigReturnBufferSizeInKByte,dml_uint_t ConfigReturnBufferSegmentSizeInKByte,dml_uint_t ROBBufferSizeInKByte,dml_uint_t MaxNumDPP,dml_bool_t nomDETInKByteOverrideEnable,dml_uint_t nomDETInKByteOverrideValue,dml_uint_t * MaxTotalDETInKByte,dml_uint_t * nomDETInKByte,dml_uint_t * MinCompressedBufferSizeInKByte)5019 static void CalculateMaxDETAndMinCompressedBufferSize(
5020 		dml_uint_t  ConfigReturnBufferSizeInKByte,
5021 		dml_uint_t  ConfigReturnBufferSegmentSizeInKByte,
5022 		dml_uint_t  ROBBufferSizeInKByte,
5023 		dml_uint_t MaxNumDPP,
5024 		dml_bool_t nomDETInKByteOverrideEnable, // VBA_DELTA, allow DV to override default DET size
5025 		dml_uint_t nomDETInKByteOverrideValue,  // VBA_DELTA
5026 
5027 		// Output
5028 		dml_uint_t *MaxTotalDETInKByte,
5029 		dml_uint_t *nomDETInKByte,
5030 		dml_uint_t *MinCompressedBufferSizeInKByte)
5031 {
5032 	*MaxTotalDETInKByte = ConfigReturnBufferSizeInKByte - ConfigReturnBufferSegmentSizeInKByte;
5033 	*nomDETInKByte = (dml_uint_t)(dml_floor((dml_float_t) *MaxTotalDETInKByte / (dml_float_t) MaxNumDPP, ConfigReturnBufferSegmentSizeInKByte));
5034 	*MinCompressedBufferSizeInKByte = ConfigReturnBufferSizeInKByte - *MaxTotalDETInKByte;
5035 
5036 #ifdef __DML_VBA_DEBUG__
5037 	dml_print("DML::%s: ConfigReturnBufferSizeInKByte = %u\n", __func__, ConfigReturnBufferSizeInKByte);
5038 	dml_print("DML::%s: ROBBufferSizeInKByte = %u\n", __func__, ROBBufferSizeInKByte);
5039 	dml_print("DML::%s: MaxNumDPP = %u\n", __func__, MaxNumDPP);
5040 	dml_print("DML::%s: MaxTotalDETInKByte = %u\n", __func__, *MaxTotalDETInKByte);
5041 	dml_print("DML::%s: nomDETInKByte = %u\n", __func__, *nomDETInKByte);
5042 	dml_print("DML::%s: MinCompressedBufferSizeInKByte = %u\n", __func__, *MinCompressedBufferSizeInKByte);
5043 #endif
5044 
5045 	if (nomDETInKByteOverrideEnable) {
5046 		*nomDETInKByte = nomDETInKByteOverrideValue;
5047 		dml_print("DML::%s: nomDETInKByte = %u (overrided)\n", __func__, *nomDETInKByte);
5048 	}
5049 } // CalculateMaxDETAndMinCompressedBufferSize
5050 
5051 /// @brief Calculate all the RQ request attributes, like row height and # swath
CalculateVMRowAndSwath(struct display_mode_lib_scratch_st * scratch,struct CalculateVMRowAndSwath_params_st * p)5052 static void CalculateVMRowAndSwath(struct display_mode_lib_scratch_st *scratch,
5053 		struct CalculateVMRowAndSwath_params_st *p)
5054 {
5055 	struct CalculateVMRowAndSwath_locals_st *s = &scratch->CalculateVMRowAndSwath_locals;
5056 
5057 	s->HostVMDynamicLevels = CalculateHostVMDynamicLevels(p->GPUVMEnable, p->HostVMEnable, p->HostVMMinPageSize, p->HostVMMaxNonCachedPageTableLevels);
5058 
5059 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
5060 		if (p->HostVMEnable == true) {
5061 			p->vm_group_bytes[k] = 512;
5062 			p->dpte_group_bytes[k] = 512;
5063 		} else if (p->GPUVMEnable == true) {
5064 			p->vm_group_bytes[k] = 2048;
5065 			if (p->GPUVMMinPageSizeKBytes[k] >= 64 && dml_is_vertical_rotation(p->myPipe[k].SourceScan)) {
5066 				p->dpte_group_bytes[k] = 512;
5067 			} else {
5068 				p->dpte_group_bytes[k] = 2048;
5069 			}
5070 		} else {
5071 			p->vm_group_bytes[k] = 0;
5072 			p->dpte_group_bytes[k] = 0;
5073 		}
5074 
5075 		if (p->myPipe[k].SourcePixelFormat == dml_420_8 || p->myPipe[k].SourcePixelFormat == dml_420_10 ||
5076 			p->myPipe[k].SourcePixelFormat == dml_420_12 || p->myPipe[k].SourcePixelFormat == dml_rgbe_alpha) {
5077 			if ((p->myPipe[k].SourcePixelFormat == dml_420_10 || p->myPipe[k].SourcePixelFormat == dml_420_12) && !dml_is_vertical_rotation(p->myPipe[k].SourceScan)) {
5078 				s->PTEBufferSizeInRequestsForLuma[k] = (p->PTEBufferSizeInRequestsLuma + p->PTEBufferSizeInRequestsChroma) / 2;
5079 				s->PTEBufferSizeInRequestsForChroma[k] = s->PTEBufferSizeInRequestsForLuma[k];
5080 			} else {
5081 				s->PTEBufferSizeInRequestsForLuma[k] = p->PTEBufferSizeInRequestsLuma;
5082 				s->PTEBufferSizeInRequestsForChroma[k] = p->PTEBufferSizeInRequestsChroma;
5083 			}
5084 
5085 			s->PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(
5086 				p->myPipe[k].ViewportStationary,
5087 				p->myPipe[k].DCCEnable,
5088 				p->myPipe[k].DPPPerSurface,
5089 				p->myPipe[k].BlockHeight256BytesC,
5090 				p->myPipe[k].BlockWidth256BytesC,
5091 				p->myPipe[k].SourcePixelFormat,
5092 				p->myPipe[k].SurfaceTiling,
5093 				p->myPipe[k].BytePerPixelC,
5094 				p->myPipe[k].SourceScan,
5095 				p->SwathWidthC[k],
5096 				p->myPipe[k].ViewportHeightChroma,
5097 				p->myPipe[k].ViewportXStartC,
5098 				p->myPipe[k].ViewportYStartC,
5099 				p->GPUVMEnable,
5100 				p->GPUVMMaxPageTableLevels,
5101 				p->GPUVMMinPageSizeKBytes[k],
5102 				s->PTEBufferSizeInRequestsForChroma[k],
5103 				p->myPipe[k].PitchC,
5104 				p->myPipe[k].DCCMetaPitchC,
5105 				p->myPipe[k].BlockWidthC,
5106 				p->myPipe[k].BlockHeightC,
5107 
5108 				// Output
5109 				&s->MetaRowByteC[k],
5110 				&s->PixelPTEBytesPerRowC[k],
5111 				&s->PixelPTEBytesPerRowStorageC[k],
5112 				&p->dpte_row_width_chroma_ub[k],
5113 				&p->dpte_row_height_chroma[k],
5114 				&p->dpte_row_height_linear_chroma[k],
5115 				&s->PixelPTEBytesPerRowC_one_row_per_frame[k],
5116 				&s->dpte_row_width_chroma_ub_one_row_per_frame[k],
5117 				&s->dpte_row_height_chroma_one_row_per_frame[k],
5118 				&p->meta_req_width_chroma[k],
5119 				&p->meta_req_height_chroma[k],
5120 				&p->meta_row_width_chroma[k],
5121 				&p->meta_row_height_chroma[k],
5122 				&p->PixelPTEReqWidthC[k],
5123 				&p->PixelPTEReqHeightC[k],
5124 				&p->PTERequestSizeC[k],
5125 				&p->dpde0_bytes_per_frame_ub_c[k],
5126 				&p->meta_pte_bytes_per_frame_ub_c[k]);
5127 
5128 			p->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines (
5129 				p->myPipe[k].VRatioChroma,
5130 				p->myPipe[k].VTapsChroma,
5131 				p->myPipe[k].InterlaceEnable,
5132 				p->myPipe[k].ProgressiveToInterlaceUnitInOPP,
5133 				p->myPipe[k].SwathHeightC,
5134 				p->myPipe[k].SourceScan,
5135 				p->myPipe[k].ViewportStationary,
5136 				p->SwathWidthC[k],
5137 				p->myPipe[k].ViewportHeightChroma,
5138 				p->myPipe[k].ViewportXStartC,
5139 				p->myPipe[k].ViewportYStartC,
5140 
5141 				// Output
5142 				&p->VInitPreFillC[k],
5143 				&p->MaxNumSwathC[k]);
5144 		} else {
5145 			s->PTEBufferSizeInRequestsForLuma[k] = p->PTEBufferSizeInRequestsLuma + p->PTEBufferSizeInRequestsChroma;
5146 			s->PTEBufferSizeInRequestsForChroma[k] = 0;
5147 			s->PixelPTEBytesPerRowC[k] = 0;
5148 			s->PixelPTEBytesPerRowStorageC[k] = 0;
5149 			s->PDEAndMetaPTEBytesFrameC = 0;
5150 			s->MetaRowByteC[k] = 0;
5151 			p->MaxNumSwathC[k] = 0;
5152 			p->PrefetchSourceLinesC[k] = 0;
5153 			s->dpte_row_height_chroma_one_row_per_frame[k] = 0;
5154 			s->dpte_row_width_chroma_ub_one_row_per_frame[k] = 0;
5155 			s->PixelPTEBytesPerRowC_one_row_per_frame[k] = 0;
5156 		}
5157 
5158 		s->PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
5159 			p->myPipe[k].ViewportStationary,
5160 			p->myPipe[k].DCCEnable,
5161 			p->myPipe[k].DPPPerSurface,
5162 			p->myPipe[k].BlockHeight256BytesY,
5163 			p->myPipe[k].BlockWidth256BytesY,
5164 			p->myPipe[k].SourcePixelFormat,
5165 			p->myPipe[k].SurfaceTiling,
5166 			p->myPipe[k].BytePerPixelY,
5167 			p->myPipe[k].SourceScan,
5168 			p->SwathWidthY[k],
5169 			p->myPipe[k].ViewportHeight,
5170 			p->myPipe[k].ViewportXStart,
5171 			p->myPipe[k].ViewportYStart,
5172 			p->GPUVMEnable,
5173 			p->GPUVMMaxPageTableLevels,
5174 			p->GPUVMMinPageSizeKBytes[k],
5175 			s->PTEBufferSizeInRequestsForLuma[k],
5176 			p->myPipe[k].PitchY,
5177 			p->myPipe[k].DCCMetaPitchY,
5178 			p->myPipe[k].BlockWidthY,
5179 			p->myPipe[k].BlockHeightY,
5180 
5181 			// Output
5182 			&s->MetaRowByteY[k],
5183 			&s->PixelPTEBytesPerRowY[k],
5184 			&s->PixelPTEBytesPerRowStorageY[k],
5185 			&p->dpte_row_width_luma_ub[k],
5186 			&p->dpte_row_height_luma[k],
5187 			&p->dpte_row_height_linear_luma[k],
5188 			&s->PixelPTEBytesPerRowY_one_row_per_frame[k],
5189 			&s->dpte_row_width_luma_ub_one_row_per_frame[k],
5190 			&s->dpte_row_height_luma_one_row_per_frame[k],
5191 			&p->meta_req_width[k],
5192 			&p->meta_req_height[k],
5193 			&p->meta_row_width[k],
5194 			&p->meta_row_height[k],
5195 			&p->PixelPTEReqWidthY[k],
5196 			&p->PixelPTEReqHeightY[k],
5197 			&p->PTERequestSizeY[k],
5198 			&p->dpde0_bytes_per_frame_ub_l[k],
5199 			&p->meta_pte_bytes_per_frame_ub_l[k]);
5200 
5201 			p->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
5202 			p->myPipe[k].VRatio,
5203 			p->myPipe[k].VTaps,
5204 			p->myPipe[k].InterlaceEnable,
5205 			p->myPipe[k].ProgressiveToInterlaceUnitInOPP,
5206 			p->myPipe[k].SwathHeightY,
5207 			p->myPipe[k].SourceScan,
5208 			p->myPipe[k].ViewportStationary,
5209 			p->SwathWidthY[k],
5210 			p->myPipe[k].ViewportHeight,
5211 			p->myPipe[k].ViewportXStart,
5212 			p->myPipe[k].ViewportYStart,
5213 
5214 			// Output
5215 			&p->VInitPreFillY[k],
5216 			&p->MaxNumSwathY[k]);
5217 
5218 		p->PDEAndMetaPTEBytesFrame[k] = (s->PDEAndMetaPTEBytesFrameY + s->PDEAndMetaPTEBytesFrameC) * (1 + 8 * s->HostVMDynamicLevels);
5219 		p->MetaRowByte[k] = s->MetaRowByteY[k] + s->MetaRowByteC[k];
5220 
5221 		if (s->PixelPTEBytesPerRowStorageY[k] <= 64 * s->PTEBufferSizeInRequestsForLuma[k] && s->PixelPTEBytesPerRowStorageC[k] <= 64 * s->PTEBufferSizeInRequestsForChroma[k]) {
5222 			p->PTEBufferSizeNotExceeded[k] = true;
5223 		} else {
5224 			p->PTEBufferSizeNotExceeded[k] = false;
5225 #ifdef __DML_VBA_DEBUG__
5226 			dml_print("DML::%s: k=%u, PixelPTEBytesPerRowY = %u\n", __func__, k, s->PixelPTEBytesPerRowY[k]);
5227 			dml_print("DML::%s: k=%u, PixelPTEBytesPerRowC = %u\n", __func__, k, s->PixelPTEBytesPerRowC[k]);
5228 			dml_print("DML::%s: k=%u, PixelPTEBytesPerRowStorageY = %u\n", __func__, k, s->PixelPTEBytesPerRowStorageY[k]);
5229 			dml_print("DML::%s: k=%u, PixelPTEBytesPerRowStorageC = %u\n", __func__, k, s->PixelPTEBytesPerRowStorageC[k]);
5230 			dml_print("DML::%s: k=%u, PTEBufferSizeInRequestsForLuma = %u\n", __func__, k, s->PTEBufferSizeInRequestsForLuma[k]);
5231 			dml_print("DML::%s: k=%u, PTEBufferSizeInRequestsForChroma = %u\n", __func__, k, s->PTEBufferSizeInRequestsForChroma[k]);
5232 			dml_print("DML::%s: k=%u, PTEBufferSizeNotExceeded          = %u\n",  __func__, k, p->PTEBufferSizeNotExceeded[k]);
5233 #endif
5234 		}
5235 		s->one_row_per_frame_fits_in_buffer[k] = (s->PixelPTEBytesPerRowY_one_row_per_frame[k] <= 64 * 2 * s->PTEBufferSizeInRequestsForLuma[k] &&
5236 			s->PixelPTEBytesPerRowC_one_row_per_frame[k] <= 64 * 2 * s->PTEBufferSizeInRequestsForChroma[k]);
5237 
5238 #ifdef __DML_VBA_DEBUG__
5239 		dml_print("DML::%s: k=%u, PDEAndMetaPTEBytesFrame = %u\n", __func__, k, p->PDEAndMetaPTEBytesFrame[k]);
5240 		dml_print("DML::%s: k=%u, PDEAndMetaPTEBytesFrameY = %u\n", __func__, k, s->PDEAndMetaPTEBytesFrameY);
5241 		dml_print("DML::%s: k=%u, PDEAndMetaPTEBytesFrameC = %u\n", __func__, k, s->PDEAndMetaPTEBytesFrameC);
5242 		dml_print("DML::%s: k=%u, HostVMDynamicLevels = %u\n", __func__, k, s->HostVMDynamicLevels);
5243 		dml_print("DML::%s: k=%u, one_row_per_frame_fits_in_buffer = %u\n", __func__, k, s->one_row_per_frame_fits_in_buffer[k]);
5244 		dml_print("DML::%s: k=%u, PixelPTEBytesPerRowY_one_row_per_frame = %u\n", __func__, k, s->PixelPTEBytesPerRowY_one_row_per_frame[k]);
5245 		dml_print("DML::%s: k=%u, PixelPTEBytesPerRowC_one_row_per_frame    = %u\n",  __func__, k, s->PixelPTEBytesPerRowC_one_row_per_frame[k]);
5246 #endif
5247 	}
5248 
5249 	CalculateMALLUseForStaticScreen(
5250 		p->NumberOfActiveSurfaces,
5251 		p->MALLAllocatedForDCN,
5252 		p->UseMALLForStaticScreen,   // mode
5253 		p->SurfaceSizeInMALL,
5254 		s->one_row_per_frame_fits_in_buffer,
5255 		// Output
5256 		p->UsesMALLForStaticScreen); // boolen
5257 
5258 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
5259 		if (p->PTEBufferModeOverrideEn[k] == 1) {
5260 			p->PTE_BUFFER_MODE[k] = p->PTEBufferModeOverrideVal[k];
5261 		}
5262 		p->PTE_BUFFER_MODE[k] = p->myPipe[k].FORCE_ONE_ROW_FOR_FRAME || p->UsesMALLForStaticScreen[k] || (p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_sub_viewport) ||
5263 			(p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe) || (p->GPUVMMinPageSizeKBytes[k] > 64);
5264 		p->BIGK_FRAGMENT_SIZE[k] = (dml_uint_t)(dml_log2(p->GPUVMMinPageSizeKBytes[k] * 1024) - 12);
5265 	}
5266 
5267 	for (dml_uint_t k = 0; k < p->NumberOfActiveSurfaces; ++k) {
5268 #ifdef __DML_VBA_DEBUG__
5269 		dml_print("DML::%s: k=%u, SurfaceSizeInMALL         = %u\n",  __func__, k, p->SurfaceSizeInMALL[k]);
5270 		dml_print("DML::%s: k=%u, UsesMALLForStaticScreen   = %u\n",  __func__, k, p->UsesMALLForStaticScreen[k]);
5271 #endif
5272 		p->use_one_row_for_frame[k] = p->myPipe[k].FORCE_ONE_ROW_FOR_FRAME || p->UsesMALLForStaticScreen[k] || (p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_sub_viewport) ||
5273 									(p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe) || (p->GPUVMMinPageSizeKBytes[k] > 64 && dml_is_vertical_rotation(p->myPipe[k].SourceScan));
5274 
5275 		p->use_one_row_for_frame_flip[k] = p->use_one_row_for_frame[k] && !(p->UseMALLForPStateChange[k] == dml_use_mall_pstate_change_full_frame);
5276 
5277 		if (p->use_one_row_for_frame[k]) {
5278 			p->dpte_row_height_luma[k] = s->dpte_row_height_luma_one_row_per_frame[k];
5279 			p->dpte_row_width_luma_ub[k] = s->dpte_row_width_luma_ub_one_row_per_frame[k];
5280 			s->PixelPTEBytesPerRowY[k] = s->PixelPTEBytesPerRowY_one_row_per_frame[k];
5281 			p->dpte_row_height_chroma[k] = s->dpte_row_height_chroma_one_row_per_frame[k];
5282 			p->dpte_row_width_chroma_ub[k] = s->dpte_row_width_chroma_ub_one_row_per_frame[k];
5283 			s->PixelPTEBytesPerRowC[k] = s->PixelPTEBytesPerRowC_one_row_per_frame[k];
5284 			p->PTEBufferSizeNotExceeded[k] = s->one_row_per_frame_fits_in_buffer[k];
5285 		}
5286 
5287 		if (p->MetaRowByte[k] <= p->DCCMetaBufferSizeBytes) {
5288 			p->DCCMetaBufferSizeNotExceeded[k] = true;
5289 		} else {
5290 			p->DCCMetaBufferSizeNotExceeded[k] = false;
5291 
5292 #ifdef __DML_VBA_DEBUG__
5293 			dml_print("DML::%s: k=%u, MetaRowByte                   = %u\n",  __func__, k, p->MetaRowByte[k]);
5294 			dml_print("DML::%s: k=%u, DCCMetaBufferSizeBytes        = %u\n",  __func__, k, p->DCCMetaBufferSizeBytes);
5295 			dml_print("DML::%s: k=%u, DCCMetaBufferSizeNotExceeded  = %u\n",  __func__, k, p->DCCMetaBufferSizeNotExceeded[k]);
5296 #endif
5297 		}
5298 		s->PixelPTEBytesPerRowY[k] = s->PixelPTEBytesPerRowY[k] * (1 + 8 * s->HostVMDynamicLevels);
5299 		s->PixelPTEBytesPerRowC[k] = s->PixelPTEBytesPerRowC[k] * (1 + 8 * s->HostVMDynamicLevels);
5300 		p->PixelPTEBytesPerRow[k] = s->PixelPTEBytesPerRowY[k] + s->PixelPTEBytesPerRowC[k];
5301 		if (p->use_one_row_for_frame[k])
5302 			p->PixelPTEBytesPerRow[k] = p->PixelPTEBytesPerRow[k] / 2;
5303 
5304 		CalculateRowBandwidth(
5305 			p->GPUVMEnable,
5306 			p->myPipe[k].SourcePixelFormat,
5307 			p->myPipe[k].VRatio,
5308 			p->myPipe[k].VRatioChroma,
5309 			p->myPipe[k].DCCEnable,
5310 			p->myPipe[k].HTotal / p->myPipe[k].PixelClock,
5311 			s->MetaRowByteY[k],
5312 			s->MetaRowByteC[k],
5313 			p->meta_row_height[k],
5314 			p->meta_row_height_chroma[k],
5315 			s->PixelPTEBytesPerRowY[k],
5316 			s->PixelPTEBytesPerRowC[k],
5317 			p->dpte_row_height_luma[k],
5318 			p->dpte_row_height_chroma[k],
5319 
5320 			// Output
5321 			&p->meta_row_bw[k],
5322 			&p->dpte_row_bw[k]);
5323 #ifdef __DML_VBA_DEBUG__
5324 		dml_print("DML::%s: k=%u, use_one_row_for_frame = %u\n", __func__, k, p->use_one_row_for_frame[k]);
5325 		dml_print("DML::%s: k=%u, use_one_row_for_frame_flip = %u\n", __func__, k, p->use_one_row_for_frame_flip[k]);
5326 		dml_print("DML::%s: k=%u, UseMALLForPStateChange = %u\n", __func__, k, p->UseMALLForPStateChange[k]);
5327 		dml_print("DML::%s: k=%u, dpte_row_height_luma = %u\n", __func__, k, p->dpte_row_height_luma[k]);
5328 		dml_print("DML::%s: k=%u, dpte_row_width_luma_ub = %u\n", __func__, k, p->dpte_row_width_luma_ub[k]);
5329 		dml_print("DML::%s: k=%u, PixelPTEBytesPerRowY = %u\n", __func__, k, s->PixelPTEBytesPerRowY[k]);
5330 		dml_print("DML::%s: k=%u, dpte_row_height_chroma = %u\n", __func__, k, p->dpte_row_height_chroma[k]);
5331 		dml_print("DML::%s: k=%u, dpte_row_width_chroma_ub = %u\n", __func__, k, p->dpte_row_width_chroma_ub[k]);
5332 		dml_print("DML::%s: k=%u, PixelPTEBytesPerRowC = %u\n", __func__, k, s->PixelPTEBytesPerRowC[k]);
5333 		dml_print("DML::%s: k=%u, PixelPTEBytesPerRow = %u\n", __func__, k, p->PixelPTEBytesPerRow[k]);
5334 		dml_print("DML::%s: k=%u, PTEBufferSizeNotExceeded = %u\n", __func__, k, p->PTEBufferSizeNotExceeded[k]);
5335 		dml_print("DML::%s: k=%u, PTE_BUFFER_MODE = %u\n", __func__, k, p->PTE_BUFFER_MODE[k]);
5336 		dml_print("DML::%s: k=%u, BIGK_FRAGMENT_SIZE     = %u\n", __func__, k, p->BIGK_FRAGMENT_SIZE[k]);
5337 #endif
5338 	}
5339 }
5340 
CalculateOutputLink(dml_float_t PHYCLKPerState,dml_float_t PHYCLKD18PerState,dml_float_t PHYCLKD32PerState,dml_float_t Downspreading,dml_bool_t IsMainSurfaceUsingTheIndicatedTiming,enum dml_output_encoder_class Output,enum dml_output_format_class OutputFormat,dml_uint_t HTotal,dml_uint_t HActive,dml_float_t PixelClockBackEnd,dml_float_t ForcedOutputLinkBPP,dml_uint_t DSCInputBitPerComponent,dml_uint_t NumberOfDSCSlices,dml_float_t AudioSampleRate,dml_uint_t AudioSampleLayout,enum dml_odm_mode ODMModeNoDSC,enum dml_odm_mode ODMModeDSC,enum dml_dsc_enable DSCEnable,dml_uint_t OutputLinkDPLanes,enum dml_output_link_dp_rate OutputLinkDPRate,dml_bool_t * RequiresDSC,dml_bool_t * RequiresFEC,dml_float_t * OutBpp,enum dml_output_type_and_rate__type * OutputType,enum dml_output_type_and_rate__rate * OutputRate,dml_uint_t * RequiredSlots)5341 static void CalculateOutputLink(
5342 		dml_float_t PHYCLKPerState,
5343 		dml_float_t PHYCLKD18PerState,
5344 		dml_float_t PHYCLKD32PerState,
5345 		dml_float_t Downspreading,
5346 		dml_bool_t IsMainSurfaceUsingTheIndicatedTiming,
5347 		enum dml_output_encoder_class Output,
5348 		enum dml_output_format_class OutputFormat,
5349 		dml_uint_t HTotal,
5350 		dml_uint_t HActive,
5351 		dml_float_t PixelClockBackEnd,
5352 		dml_float_t ForcedOutputLinkBPP,
5353 		dml_uint_t DSCInputBitPerComponent,
5354 		dml_uint_t NumberOfDSCSlices,
5355 		dml_float_t AudioSampleRate,
5356 		dml_uint_t AudioSampleLayout,
5357 		enum dml_odm_mode ODMModeNoDSC,
5358 		enum dml_odm_mode ODMModeDSC,
5359 		enum dml_dsc_enable DSCEnable,
5360 		dml_uint_t OutputLinkDPLanes,
5361 		enum dml_output_link_dp_rate OutputLinkDPRate,
5362 
5363 		// Output
5364 		dml_bool_t *RequiresDSC,
5365 		dml_bool_t *RequiresFEC,
5366 		dml_float_t *OutBpp,
5367 		enum dml_output_type_and_rate__type *OutputType,
5368 		enum dml_output_type_and_rate__rate *OutputRate,
5369 		dml_uint_t *RequiredSlots)
5370 {
5371 	dml_bool_t LinkDSCEnable;
5372 	dml_uint_t dummy;
5373 	*RequiresDSC = false;
5374 	*RequiresFEC = false;
5375 	*OutBpp = 0;
5376 
5377 	*OutputType = dml_output_type_unknown;
5378 	*OutputRate = dml_output_rate_unknown;
5379 
5380 	if (IsMainSurfaceUsingTheIndicatedTiming) {
5381 		if (Output == dml_hdmi) {
5382 			*RequiresDSC = false;
5383 			*RequiresFEC = false;
5384 			*OutBpp = TruncToValidBPP(dml_min(600, PHYCLKPerState) * 10, 3, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, false, Output,
5385 									OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, &dummy);
5386 			//OutputTypeAndRate = "HDMI";
5387 			*OutputType = dml_output_type_hdmi;
5388 
5389 		} else if (Output == dml_dp || Output == dml_dp2p0 || Output == dml_edp) {
5390 			if (DSCEnable == dml_dsc_enable) {
5391 				*RequiresDSC = true;
5392 				LinkDSCEnable = true;
5393 				if (Output == dml_dp || Output == dml_dp2p0) {
5394 					*RequiresFEC = true;
5395 				} else {
5396 					*RequiresFEC = false;
5397 				}
5398 			} else {
5399 				*RequiresDSC = false;
5400 				LinkDSCEnable = false;
5401 				if (Output == dml_dp2p0) {
5402 					*RequiresFEC = true;
5403 				} else {
5404 					*RequiresFEC = false;
5405 				}
5406 			}
5407 			if (Output == dml_dp2p0) {
5408 				*OutBpp = 0;
5409 				if ((OutputLinkDPRate == dml_dp_rate_na || OutputLinkDPRate == dml_dp_rate_uhbr10) && PHYCLKD32PerState >= 10000 / 32.0) {
5410 					*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 10000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5411 												OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5412 					if (*OutBpp == 0 && PHYCLKD32PerState < 13500 / 32.0 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) {
5413 						*RequiresDSC = true;
5414 						LinkDSCEnable = true;
5415 						*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 10000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5416 													OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5417 					}
5418 					//OutputTypeAndRate = Output & " UHBR10";
5419 					*OutputType = dml_output_type_dp2p0;
5420 					*OutputRate = dml_output_rate_dp_rate_uhbr10;
5421 				}
5422 				if ((OutputLinkDPRate == dml_dp_rate_na || OutputLinkDPRate == dml_dp_rate_uhbr13p5) && *OutBpp == 0 && PHYCLKD32PerState >= 13500 / 32.0) {
5423 					*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 13500, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5424 												OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5425 
5426 					if (*OutBpp == 0 && PHYCLKD32PerState < 20000 / 32 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) {
5427 						*RequiresDSC = true;
5428 						LinkDSCEnable = true;
5429 						*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 13500, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5430 												OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5431 					}
5432 					//OutputTypeAndRate = Output & " UHBR13p5";
5433 					*OutputType = dml_output_type_dp2p0;
5434 					*OutputRate = dml_output_rate_dp_rate_uhbr13p5;
5435 				}
5436 				if ((OutputLinkDPRate == dml_dp_rate_na || OutputLinkDPRate == dml_dp_rate_uhbr20) && *OutBpp == 0 && PHYCLKD32PerState >= 20000 / 32) {
5437 					*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 20000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5438 											OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5439 					if (*OutBpp == 0 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) {
5440 						*RequiresDSC = true;
5441 						LinkDSCEnable = true;
5442 						*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 20000, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5443 												OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5444 					}
5445 					//OutputTypeAndRate = Output & " UHBR20";
5446 					*OutputType = dml_output_type_dp2p0;
5447 					*OutputRate = dml_output_rate_dp_rate_uhbr20;
5448 				}
5449 			} else { // output is dp or edp
5450 				*OutBpp = 0;
5451 				if ((OutputLinkDPRate == dml_dp_rate_na || OutputLinkDPRate == dml_dp_rate_hbr) && PHYCLKPerState >= 270) {
5452 					*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 2700, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5453 											OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5454 					if (*OutBpp == 0 && PHYCLKPerState < 540 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) {
5455 						*RequiresDSC = true;
5456 						LinkDSCEnable = true;
5457 						if (Output == dml_dp) {
5458 							*RequiresFEC = true;
5459 						}
5460 						*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 2700, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5461 												OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5462 					}
5463 					//OutputTypeAndRate = Output & " HBR";
5464 					*OutputType = (Output == dml_dp) ? dml_output_type_dp : dml_output_type_edp;
5465 					*OutputRate = dml_output_rate_dp_rate_hbr;
5466 				}
5467 				if ((OutputLinkDPRate == dml_dp_rate_na || OutputLinkDPRate == dml_dp_rate_hbr2) && *OutBpp == 0 && PHYCLKPerState >= 540) {
5468 					*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 5400, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5469 											OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5470 
5471 					if (*OutBpp == 0 && PHYCLKPerState < 810 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) {
5472 						*RequiresDSC = true;
5473 						LinkDSCEnable = true;
5474 						if (Output == dml_dp) {
5475 							*RequiresFEC = true;
5476 						}
5477 						*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 5400, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5478 												OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5479 					}
5480 					//OutputTypeAndRate = Output & " HBR2";
5481 					*OutputType = (Output == dml_dp) ? dml_output_type_dp : dml_output_type_edp;
5482 					*OutputRate = dml_output_rate_dp_rate_hbr2;
5483 				}
5484 				if ((OutputLinkDPRate == dml_dp_rate_na || OutputLinkDPRate == dml_dp_rate_hbr3) && *OutBpp == 0 && PHYCLKPerState >= 810) { // VBA_ERROR, vba code doesn't have hbr3 check
5485 					*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 8100, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5486 											OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5487 
5488 					if (*OutBpp == 0 && DSCEnable == dml_dsc_enable_if_necessary && ForcedOutputLinkBPP == 0) {
5489 						*RequiresDSC = true;
5490 						LinkDSCEnable = true;
5491 						if (Output == dml_dp) {
5492 							*RequiresFEC = true;
5493 						}
5494 						*OutBpp = TruncToValidBPP((1 - Downspreading / 100) * 8100, OutputLinkDPLanes, HTotal, HActive, PixelClockBackEnd, ForcedOutputLinkBPP, LinkDSCEnable, Output,
5495 												OutputFormat, DSCInputBitPerComponent, NumberOfDSCSlices, (dml_uint_t)AudioSampleRate, AudioSampleLayout, ODMModeNoDSC, ODMModeDSC, RequiredSlots);
5496 					}
5497 					//OutputTypeAndRate = Output & " HBR3";
5498 					*OutputType = (Output == dml_dp) ? dml_output_type_dp : dml_output_type_edp;
5499 					*OutputRate = dml_output_rate_dp_rate_hbr3;
5500 				}
5501 			}
5502 		}
5503 	}
5504 }
5505 
5506 /// @brief Determine the ODM mode and number of DPP used per plane based on dispclk, dsc usage, odm usage policy
CalculateODMMode(dml_uint_t MaximumPixelsPerLinePerDSCUnit,dml_uint_t HActive,enum dml_output_encoder_class Output,enum dml_output_format_class OutputFormat,enum dml_odm_use_policy ODMUse,dml_float_t StateDispclk,dml_float_t MaxDispclk,dml_bool_t DSCEnable,dml_uint_t TotalNumberOfActiveDPP,dml_uint_t MaxNumDPP,dml_float_t PixelClock,dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,dml_float_t DISPCLKRampingMargin,dml_float_t DISPCLKDPPCLKVCOSpeed,dml_uint_t NumberOfDSCSlices,dml_bool_t * TotalAvailablePipesSupport,dml_uint_t * NumberOfDPP,enum dml_odm_mode * ODMMode,dml_float_t * RequiredDISPCLKPerSurface)5507 static void CalculateODMMode(
5508 		dml_uint_t MaximumPixelsPerLinePerDSCUnit,
5509 		dml_uint_t HActive,
5510 		enum dml_output_encoder_class Output,
5511 		enum dml_output_format_class OutputFormat,
5512 		enum dml_odm_use_policy ODMUse,
5513 		dml_float_t StateDispclk,
5514 		dml_float_t MaxDispclk,
5515 		dml_bool_t DSCEnable,
5516 		dml_uint_t TotalNumberOfActiveDPP,
5517 		dml_uint_t MaxNumDPP,
5518 		dml_float_t PixelClock,
5519 		dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,
5520 		dml_float_t DISPCLKRampingMargin,
5521 		dml_float_t DISPCLKDPPCLKVCOSpeed,
5522 		dml_uint_t NumberOfDSCSlices,
5523 
5524 		// Output
5525 		dml_bool_t *TotalAvailablePipesSupport,
5526 		dml_uint_t *NumberOfDPP,
5527 		enum dml_odm_mode *ODMMode,
5528 		dml_float_t *RequiredDISPCLKPerSurface)
5529 {
5530 
5531 	dml_float_t SurfaceRequiredDISPCLKWithoutODMCombine;
5532 	dml_float_t SurfaceRequiredDISPCLKWithODMCombineTwoToOne;
5533 	dml_float_t SurfaceRequiredDISPCLKWithODMCombineFourToOne;
5534 
5535 	SurfaceRequiredDISPCLKWithoutODMCombine = CalculateRequiredDispclk(dml_odm_mode_bypass, PixelClock, DISPCLKDPPCLKDSCCLKDownSpreading, DISPCLKRampingMargin, DISPCLKDPPCLKVCOSpeed, MaxDispclk);
5536 	SurfaceRequiredDISPCLKWithODMCombineTwoToOne = CalculateRequiredDispclk(dml_odm_mode_combine_2to1, PixelClock, DISPCLKDPPCLKDSCCLKDownSpreading, DISPCLKRampingMargin, DISPCLKDPPCLKVCOSpeed, MaxDispclk);
5537 	SurfaceRequiredDISPCLKWithODMCombineFourToOne = CalculateRequiredDispclk(dml_odm_mode_combine_4to1, PixelClock, DISPCLKDPPCLKDSCCLKDownSpreading, DISPCLKRampingMargin, DISPCLKDPPCLKVCOSpeed, MaxDispclk);
5538 	*TotalAvailablePipesSupport = true;
5539 
5540 	if (OutputFormat == dml_420) {
5541 		if (HActive > 4 * DML2_MAX_FMT_420_BUFFER_WIDTH)
5542 			*TotalAvailablePipesSupport = false;
5543 		else if (HActive > 2 * DML2_MAX_FMT_420_BUFFER_WIDTH)
5544 			ODMUse = dml_odm_use_policy_combine_4to1;
5545 		else if (HActive > DML2_MAX_FMT_420_BUFFER_WIDTH && ODMUse != dml_odm_use_policy_combine_4to1)
5546 			ODMUse = dml_odm_use_policy_combine_2to1;
5547 		if (Output == dml_hdmi && ODMUse == dml_odm_use_policy_combine_2to1)
5548 			*TotalAvailablePipesSupport = false;
5549 		if ((Output == dml_hdmi || Output == dml_dp || Output == dml_edp) && ODMUse == dml_odm_use_policy_combine_4to1)
5550 			*TotalAvailablePipesSupport = false;
5551 	}
5552 
5553 	if (ODMUse == dml_odm_use_policy_bypass || ODMUse == dml_odm_use_policy_combine_as_needed)
5554 		*ODMMode = dml_odm_mode_bypass;
5555 	else if (ODMUse == dml_odm_use_policy_combine_2to1)
5556 		*ODMMode = dml_odm_mode_combine_2to1;
5557 	else if (ODMUse == dml_odm_use_policy_combine_4to1)
5558 		*ODMMode = dml_odm_mode_combine_4to1;
5559 	else if (ODMUse == dml_odm_use_policy_split_1to2)
5560 		*ODMMode = dml_odm_mode_split_1to2;
5561 	else if (ODMUse == dml_odm_use_policy_mso_1to2)
5562 		*ODMMode = dml_odm_mode_mso_1to2;
5563 	else if (ODMUse == dml_odm_use_policy_mso_1to4)
5564 		*ODMMode = dml_odm_mode_mso_1to4;
5565 
5566 	*RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithoutODMCombine;
5567 	*NumberOfDPP = 0;
5568 
5569 	if (!(Output == dml_hdmi || Output == dml_dp || Output == dml_edp) && (ODMUse == dml_odm_use_policy_combine_4to1 || (ODMUse == dml_odm_use_policy_combine_as_needed &&
5570 		(SurfaceRequiredDISPCLKWithODMCombineTwoToOne > StateDispclk || (DSCEnable && (HActive > 2 * MaximumPixelsPerLinePerDSCUnit)) || NumberOfDSCSlices > 8)))) {
5571 		if (TotalNumberOfActiveDPP + 4 <= MaxNumDPP) {
5572 			*ODMMode = dml_odm_mode_combine_4to1;
5573 			*RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithODMCombineFourToOne;
5574 			*NumberOfDPP = 4;
5575 		} else {
5576 			*TotalAvailablePipesSupport = false;
5577 		}
5578 	} else if (Output != dml_hdmi && (ODMUse == dml_odm_use_policy_combine_2to1 || (ODMUse == dml_odm_use_policy_combine_as_needed &&
5579 				((SurfaceRequiredDISPCLKWithoutODMCombine > StateDispclk && SurfaceRequiredDISPCLKWithODMCombineTwoToOne <= StateDispclk) ||
5580 				(DSCEnable && (HActive > MaximumPixelsPerLinePerDSCUnit)) || (NumberOfDSCSlices <= 8 && NumberOfDSCSlices > 4))))) {
5581 		if (TotalNumberOfActiveDPP + 2 <= MaxNumDPP) {
5582 			*ODMMode = dml_odm_mode_combine_2to1;
5583 			*RequiredDISPCLKPerSurface = SurfaceRequiredDISPCLKWithODMCombineTwoToOne;
5584 			*NumberOfDPP = 2;
5585 		} else {
5586 			*TotalAvailablePipesSupport = false;
5587 		}
5588 	} else {
5589 		if (TotalNumberOfActiveDPP + 1 <= MaxNumDPP) {
5590 			*NumberOfDPP = 1;
5591 		} else {
5592 			*TotalAvailablePipesSupport = false;
5593 		}
5594 	}
5595 }
5596 
5597 /// @brief Calculate the required DISPCLK given the odm mode and pixclk
CalculateRequiredDispclk(enum dml_odm_mode ODMMode,dml_float_t PixelClock,dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,dml_float_t DISPCLKRampingMargin,dml_float_t DISPCLKDPPCLKVCOSpeed,dml_float_t MaxDispclk)5598 static dml_float_t CalculateRequiredDispclk(
5599 		enum dml_odm_mode ODMMode,
5600 		dml_float_t PixelClock,
5601 		dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,
5602 		dml_float_t DISPCLKRampingMargin,
5603 		dml_float_t DISPCLKDPPCLKVCOSpeed,
5604 		dml_float_t MaxDispclk)
5605 {
5606 	dml_float_t RequiredDispclk = 0.;
5607 	dml_float_t PixelClockAfterODM;
5608 
5609 	dml_float_t DISPCLKWithRampingRoundedToDFSGranularity;
5610 	dml_float_t DISPCLKWithoutRampingRoundedToDFSGranularity;
5611 	dml_float_t MaxDispclkRoundedDownToDFSGranularity;
5612 
5613 	if (ODMMode == dml_odm_mode_combine_4to1) {
5614 		PixelClockAfterODM = PixelClock / 4;
5615 	} else if (ODMMode == dml_odm_mode_combine_2to1) {
5616 		PixelClockAfterODM = PixelClock / 2;
5617 	} else {
5618 		PixelClockAfterODM = PixelClock;
5619 	}
5620 
5621 	DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularity(PixelClockAfterODM * (1.0 + DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + DISPCLKRampingMargin / 100.0), 1, DISPCLKDPPCLKVCOSpeed);
5622 	DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularity(PixelClockAfterODM * (1.0 + DISPCLKDPPCLKDSCCLKDownSpreading / 100.0), 1, DISPCLKDPPCLKVCOSpeed);
5623 	MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularity(MaxDispclk, 0, DISPCLKDPPCLKVCOSpeed);
5624 
5625 	if (DISPCLKWithoutRampingRoundedToDFSGranularity > MaxDispclkRoundedDownToDFSGranularity) {
5626 		RequiredDispclk = DISPCLKWithoutRampingRoundedToDFSGranularity;
5627 	} else if (DISPCLKWithRampingRoundedToDFSGranularity > MaxDispclkRoundedDownToDFSGranularity) {
5628 		RequiredDispclk = MaxDispclkRoundedDownToDFSGranularity;
5629 	} else {
5630 		RequiredDispclk = DISPCLKWithRampingRoundedToDFSGranularity;
5631 	}
5632 
5633 	return RequiredDispclk;
5634 }
5635 
5636 /// @brief Determine DPPCLK if there only one DPP per plane, main factor is the pixel rate and DPP scaling parameter
CalculateSinglePipeDPPCLKAndSCLThroughput(dml_float_t HRatio,dml_float_t HRatioChroma,dml_float_t VRatio,dml_float_t VRatioChroma,dml_float_t MaxDCHUBToPSCLThroughput,dml_float_t MaxPSCLToLBThroughput,dml_float_t PixelClock,enum dml_source_format_class SourcePixelFormat,dml_uint_t HTaps,dml_uint_t HTapsChroma,dml_uint_t VTaps,dml_uint_t VTapsChroma,dml_float_t * PSCL_THROUGHPUT,dml_float_t * PSCL_THROUGHPUT_CHROMA,dml_float_t * DPPCLKUsingSingleDPP)5637 static void CalculateSinglePipeDPPCLKAndSCLThroughput(
5638 		dml_float_t HRatio,
5639 		dml_float_t HRatioChroma,
5640 		dml_float_t VRatio,
5641 		dml_float_t VRatioChroma,
5642 		dml_float_t MaxDCHUBToPSCLThroughput,
5643 		dml_float_t MaxPSCLToLBThroughput,
5644 		dml_float_t PixelClock,
5645 		enum dml_source_format_class SourcePixelFormat,
5646 		dml_uint_t HTaps,
5647 		dml_uint_t HTapsChroma,
5648 		dml_uint_t VTaps,
5649 		dml_uint_t VTapsChroma,
5650 
5651 		// Output
5652 		dml_float_t *PSCL_THROUGHPUT,
5653 		dml_float_t *PSCL_THROUGHPUT_CHROMA,
5654 		dml_float_t *DPPCLKUsingSingleDPP)
5655 {
5656 	dml_float_t DPPCLKUsingSingleDPPLuma;
5657 	dml_float_t DPPCLKUsingSingleDPPChroma;
5658 
5659 	if (HRatio > 1) {
5660 		*PSCL_THROUGHPUT = dml_min(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput * HRatio / dml_ceil((dml_float_t) HTaps / 6.0, 1.0));
5661 	} else {
5662 		*PSCL_THROUGHPUT = dml_min(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput);
5663 	}
5664 
5665 	DPPCLKUsingSingleDPPLuma = PixelClock * dml_max3(VTaps / 6 * dml_min(1, HRatio), HRatio * VRatio / *PSCL_THROUGHPUT, 1);
5666 
5667 	if ((HTaps > 6 || VTaps > 6) && DPPCLKUsingSingleDPPLuma < 2 * PixelClock)
5668 		DPPCLKUsingSingleDPPLuma = 2 * PixelClock;
5669 
5670 	if ((SourcePixelFormat != dml_420_8 && SourcePixelFormat != dml_420_10 && SourcePixelFormat != dml_420_12 && SourcePixelFormat != dml_rgbe_alpha)) {
5671 		*PSCL_THROUGHPUT_CHROMA = 0;
5672 		*DPPCLKUsingSingleDPP = DPPCLKUsingSingleDPPLuma;
5673 	} else {
5674 		if (HRatioChroma > 1) {
5675 			*PSCL_THROUGHPUT_CHROMA = dml_min(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput * HRatioChroma / dml_ceil((dml_float_t) HTapsChroma / 6.0, 1.0));
5676 		} else {
5677 			*PSCL_THROUGHPUT_CHROMA = dml_min(MaxDCHUBToPSCLThroughput, MaxPSCLToLBThroughput);
5678 		}
5679 		DPPCLKUsingSingleDPPChroma = PixelClock * dml_max3(VTapsChroma / 6 * dml_min(1, HRatioChroma),
5680 															HRatioChroma * VRatioChroma / *PSCL_THROUGHPUT_CHROMA, 1);
5681 		if ((HTapsChroma > 6 || VTapsChroma > 6) && DPPCLKUsingSingleDPPChroma < 2 * PixelClock)
5682 			DPPCLKUsingSingleDPPChroma = 2 * PixelClock;
5683 		*DPPCLKUsingSingleDPP = dml_max(DPPCLKUsingSingleDPPLuma, DPPCLKUsingSingleDPPChroma);
5684 	}
5685 }
5686 
5687 /// @brief Calculate the actual dppclk freq
5688 /// @param DPPCLKUsingSingleDPP DppClk freq required if there is only 1 DPP per plane
5689 /// @param DPPPerSurface Number of DPP for each plane
CalculateDPPCLK(dml_uint_t NumberOfActiveSurfaces,dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,dml_float_t DISPCLKDPPCLKVCOSpeed,dml_float_t DPPCLKUsingSingleDPP[],dml_uint_t DPPPerSurface[],dml_float_t * GlobalDPPCLK,dml_float_t Dppclk[])5690 static void CalculateDPPCLK(
5691 		dml_uint_t NumberOfActiveSurfaces,
5692 		dml_float_t DISPCLKDPPCLKDSCCLKDownSpreading,
5693 		dml_float_t DISPCLKDPPCLKVCOSpeed,
5694 		dml_float_t DPPCLKUsingSingleDPP[],
5695 		dml_uint_t DPPPerSurface[],
5696 
5697 		// Output
5698 		dml_float_t *GlobalDPPCLK,
5699 		dml_float_t Dppclk[])
5700 {
5701 	*GlobalDPPCLK = 0;
5702 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5703 		Dppclk[k] = DPPCLKUsingSingleDPP[k] / DPPPerSurface[k] * (1 + DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
5704 		*GlobalDPPCLK = dml_max(*GlobalDPPCLK, Dppclk[k]);
5705 	}
5706 	*GlobalDPPCLK = RoundToDFSGranularity(*GlobalDPPCLK, 1, DISPCLKDPPCLKVCOSpeed);
5707 
5708 	dml_print("DML::%s: GlobalDPPCLK = %f\n", __func__, *GlobalDPPCLK);
5709 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5710 		Dppclk[k] = *GlobalDPPCLK / 255.0 * dml_ceil(Dppclk[k] * 255.0 / *GlobalDPPCLK, 1.0);
5711 		dml_print("DML::%s: Dppclk[%0d] = %f\n", __func__, k, Dppclk[k]);
5712 	}
5713 }
5714 
CalculateMALLUseForStaticScreen(dml_uint_t NumberOfActiveSurfaces,dml_uint_t MALLAllocatedForDCNFinal,enum dml_use_mall_for_static_screen_mode * UseMALLForStaticScreen,dml_uint_t SurfaceSizeInMALL[],dml_bool_t one_row_per_frame_fits_in_buffer[],dml_bool_t UsesMALLForStaticScreen[])5715 static void CalculateMALLUseForStaticScreen(
5716 		dml_uint_t NumberOfActiveSurfaces,
5717 		dml_uint_t MALLAllocatedForDCNFinal,
5718 		enum dml_use_mall_for_static_screen_mode *UseMALLForStaticScreen,
5719 		dml_uint_t SurfaceSizeInMALL[],
5720 		dml_bool_t one_row_per_frame_fits_in_buffer[],
5721 
5722 		// Output
5723 		dml_bool_t UsesMALLForStaticScreen[])
5724 {
5725 
5726 	dml_uint_t SurfaceToAddToMALL;
5727 	dml_bool_t CanAddAnotherSurfaceToMALL;
5728 	dml_uint_t TotalSurfaceSizeInMALL;
5729 
5730 	TotalSurfaceSizeInMALL = 0;
5731 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5732 		UsesMALLForStaticScreen[k] = (UseMALLForStaticScreen[k] == dml_use_mall_static_screen_enable);
5733 		if (UsesMALLForStaticScreen[k])
5734 			TotalSurfaceSizeInMALL = TotalSurfaceSizeInMALL + SurfaceSizeInMALL[k];
5735 #ifdef __DML_VBA_DEBUG__
5736 		dml_print("DML::%s: k=%u, UsesMALLForStaticScreen = %u\n",  __func__, k, UsesMALLForStaticScreen[k]);
5737 		dml_print("DML::%s: k=%u, TotalSurfaceSizeInMALL = %u\n",  __func__, k, TotalSurfaceSizeInMALL);
5738 #endif
5739 	}
5740 
5741 	SurfaceToAddToMALL = 0;
5742 	CanAddAnotherSurfaceToMALL = true;
5743 	while (CanAddAnotherSurfaceToMALL) {
5744 		CanAddAnotherSurfaceToMALL = false;
5745 		for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5746 			if (TotalSurfaceSizeInMALL + SurfaceSizeInMALL[k] <= MALLAllocatedForDCNFinal * 1024 * 1024 &&
5747 				!UsesMALLForStaticScreen[k] && UseMALLForStaticScreen[k] != dml_use_mall_static_screen_disable && one_row_per_frame_fits_in_buffer[k] &&
5748 				(!CanAddAnotherSurfaceToMALL || SurfaceSizeInMALL[k] < SurfaceSizeInMALL[SurfaceToAddToMALL])) {
5749 				CanAddAnotherSurfaceToMALL = true;
5750 				SurfaceToAddToMALL = k;
5751 				dml_print("DML::%s: k=%u, UseMALLForStaticScreen = %u (dis, en, optimize)\n",  __func__, k, UseMALLForStaticScreen[k]);
5752 			}
5753 		}
5754 		if (CanAddAnotherSurfaceToMALL) {
5755 			UsesMALLForStaticScreen[SurfaceToAddToMALL] = true;
5756 			TotalSurfaceSizeInMALL = TotalSurfaceSizeInMALL + SurfaceSizeInMALL[SurfaceToAddToMALL];
5757 
5758 #ifdef __DML_VBA_DEBUG__
5759 			dml_print("DML::%s: SurfaceToAddToMALL       = %u\n",  __func__, SurfaceToAddToMALL);
5760 			dml_print("DML::%s: TotalSurfaceSizeInMALL   = %u\n",  __func__, TotalSurfaceSizeInMALL);
5761 #endif
5762 		}
5763 	}
5764 }
5765 
5766 // @brief Calculate return bw for VM only traffic
dml_get_return_bw_mbps_vm_only(const struct soc_bounding_box_st * soc,dml_bool_t use_ideal_dram_bw_strobe,dml_bool_t HostVMEnable,dml_float_t DCFCLK,dml_float_t FabricClock,dml_float_t DRAMSpeed)5767 dml_float_t dml_get_return_bw_mbps_vm_only(
5768 								const struct soc_bounding_box_st *soc,
5769 								dml_bool_t use_ideal_dram_bw_strobe,
5770 								dml_bool_t HostVMEnable,
5771 								dml_float_t DCFCLK,
5772 								dml_float_t FabricClock,
5773 								dml_float_t DRAMSpeed)
5774 {
5775 	dml_float_t VMDataOnlyReturnBW =
5776 		dml_min3(soc->return_bus_width_bytes * DCFCLK * soc->pct_ideal_sdp_bw_after_urgent / 100.0,
5777 				FabricClock * soc->fabric_datapath_to_dcn_data_return_bytes * soc->pct_ideal_sdp_bw_after_urgent / 100.0,
5778 				DRAMSpeed * soc->num_chans *  soc->dram_channel_width_bytes *
5779 				((use_ideal_dram_bw_strobe && !HostVMEnable) ? soc->pct_ideal_dram_bw_after_urgent_strobe :  soc->pct_ideal_dram_bw_after_urgent_vm_only) / 100.0);
5780 #ifdef __DML_VBA_DEBUG__
5781 	dml_print("DML::%s: use_ideal_dram_bw_strobe = %u\n", __func__, use_ideal_dram_bw_strobe);
5782 	dml_print("DML::%s: HostVMEnable = %u\n", __func__, HostVMEnable);
5783 	dml_print("DML::%s: DCFCLK = %f\n", __func__, DCFCLK);
5784 	dml_print("DML::%s: FabricClock = %f\n", __func__, FabricClock);
5785 	dml_print("DML::%s: DRAMSpeed = %f\n", __func__, DRAMSpeed);
5786 	dml_print("DML::%s: VMDataOnlyReturnBW = %f\n", __func__, VMDataOnlyReturnBW);
5787 #endif
5788 	return VMDataOnlyReturnBW;
5789 }
5790 
5791 // Function: dml_get_return_bw_mbps
5792 // Megabyte per second
dml_get_return_bw_mbps(const struct soc_bounding_box_st * soc,dml_bool_t use_ideal_dram_bw_strobe,dml_bool_t HostVMEnable,dml_float_t DCFCLK,dml_float_t FabricClock,dml_float_t DRAMSpeed)5793 dml_float_t dml_get_return_bw_mbps(
5794 						const struct soc_bounding_box_st *soc,
5795 						dml_bool_t use_ideal_dram_bw_strobe,
5796 						dml_bool_t HostVMEnable,
5797 						dml_float_t DCFCLK,
5798 						dml_float_t FabricClock,
5799 						dml_float_t DRAMSpeed)
5800 {
5801 	dml_float_t ReturnBW = 0.;
5802 	dml_float_t IdealSDPPortBandwidth    = soc->return_bus_width_bytes * DCFCLK;
5803 	dml_float_t IdealFabricBandwidth     = FabricClock * soc->fabric_datapath_to_dcn_data_return_bytes;
5804 	dml_float_t IdealDRAMBandwidth       = DRAMSpeed * soc->num_chans * soc->dram_channel_width_bytes;
5805 	dml_float_t PixelDataOnlyReturnBW    = dml_min3(IdealSDPPortBandwidth * soc->pct_ideal_sdp_bw_after_urgent / 100,
5806 												IdealFabricBandwidth * soc->pct_ideal_fabric_bw_after_urgent / 100,
5807 												IdealDRAMBandwidth * ((use_ideal_dram_bw_strobe && !HostVMEnable) ? soc->pct_ideal_dram_bw_after_urgent_strobe :
5808 																						soc->pct_ideal_dram_bw_after_urgent_pixel_only) / 100);
5809 	dml_float_t PixelMixedWithVMDataReturnBW = dml_min3(IdealSDPPortBandwidth * soc->pct_ideal_sdp_bw_after_urgent / 100,
5810 													IdealFabricBandwidth * soc->pct_ideal_fabric_bw_after_urgent / 100,
5811 													IdealDRAMBandwidth * ((use_ideal_dram_bw_strobe && !HostVMEnable) ? soc->pct_ideal_dram_bw_after_urgent_strobe :
5812 																							soc->pct_ideal_dram_bw_after_urgent_pixel_and_vm) / 100);
5813 
5814 	if (HostVMEnable != true) {
5815 		ReturnBW = PixelDataOnlyReturnBW;
5816 	} else {
5817 		ReturnBW = PixelMixedWithVMDataReturnBW;
5818 	}
5819 
5820 #ifdef __DML_VBA_DEBUG__
5821 	dml_print("DML::%s: use_ideal_dram_bw_strobe = %u\n", __func__, use_ideal_dram_bw_strobe);
5822 	dml_print("DML::%s: HostVMEnable = %u\n", __func__, HostVMEnable);
5823 	dml_print("DML::%s: DCFCLK = %f\n", __func__, DCFCLK);
5824 	dml_print("DML::%s: FabricClock = %f\n", __func__, FabricClock);
5825 	dml_print("DML::%s: DRAMSpeed = %f\n", __func__, DRAMSpeed);
5826 	dml_print("DML::%s: IdealSDPPortBandwidth = %f\n", __func__, IdealSDPPortBandwidth);
5827 	dml_print("DML::%s: IdealFabricBandwidth = %f\n", __func__, IdealFabricBandwidth);
5828 	dml_print("DML::%s: IdealDRAMBandwidth = %f\n", __func__, IdealDRAMBandwidth);
5829 	dml_print("DML::%s: PixelDataOnlyReturnBW = %f\n", __func__, PixelDataOnlyReturnBW);
5830 	dml_print("DML::%s: PixelMixedWithVMDataReturnBW = %f\n", __func__, PixelMixedWithVMDataReturnBW);
5831 	dml_print("DML::%s: ReturnBW                  = %f MBps\n", __func__, ReturnBW);
5832 #endif
5833 	return ReturnBW;
5834 }
5835 
5836 // Function: dml_get_return_dram_bw_mbps
5837 // Megabyte per second
dml_get_return_dram_bw_mbps(const struct soc_bounding_box_st * soc,dml_bool_t use_ideal_dram_bw_strobe,dml_bool_t HostVMEnable,dml_float_t DRAMSpeed)5838 static dml_float_t dml_get_return_dram_bw_mbps(
5839 						const struct soc_bounding_box_st *soc,
5840 						dml_bool_t use_ideal_dram_bw_strobe,
5841 						dml_bool_t HostVMEnable,
5842 						dml_float_t DRAMSpeed)
5843 {
5844 	dml_float_t ReturnDRAMBW = 0.;
5845 	dml_float_t IdealDRAMBandwidth       = DRAMSpeed * soc->num_chans * soc->dram_channel_width_bytes;
5846 	dml_float_t PixelDataOnlyReturnBW    = IdealDRAMBandwidth * ((use_ideal_dram_bw_strobe && !HostVMEnable) ? soc->pct_ideal_dram_bw_after_urgent_strobe :
5847 																						soc->pct_ideal_dram_bw_after_urgent_pixel_only) / 100;
5848 	dml_float_t PixelMixedWithVMDataReturnBW =  IdealDRAMBandwidth * ((use_ideal_dram_bw_strobe && !HostVMEnable) ? soc->pct_ideal_dram_bw_after_urgent_strobe :
5849 																							soc->pct_ideal_dram_bw_after_urgent_pixel_and_vm) / 100;
5850 
5851 	if (HostVMEnable != true) {
5852 		ReturnDRAMBW = PixelDataOnlyReturnBW;
5853 	} else {
5854 		ReturnDRAMBW = PixelMixedWithVMDataReturnBW;
5855 	}
5856 
5857 #ifdef __DML_VBA_DEBUG__
5858 	dml_print("DML::%s: use_ideal_dram_bw_strobe = %u\n", __func__, use_ideal_dram_bw_strobe);
5859 	dml_print("DML::%s: HostVMEnable = %u\n", __func__, HostVMEnable);
5860 	dml_print("DML::%s: DRAMSpeed = %f\n", __func__, DRAMSpeed);
5861 	dml_print("DML::%s: IdealDRAMBandwidth = %f\n", __func__, IdealDRAMBandwidth);
5862 	dml_print("DML::%s: PixelDataOnlyReturnBW = %f\n", __func__, PixelDataOnlyReturnBW);
5863 	dml_print("DML::%s: PixelMixedWithVMDataReturnBW = %f\n", __func__, PixelMixedWithVMDataReturnBW);
5864 	dml_print("DML::%s: ReturnDRAMBW                     = %f MBps\n", __func__, ReturnDRAMBW);
5865 #endif
5866 	return ReturnDRAMBW;
5867 }
5868 
5869 /// @brief BACKEND
DSCDelayRequirement(dml_bool_t DSCEnabled,enum dml_odm_mode ODMMode,dml_uint_t DSCInputBitPerComponent,dml_float_t OutputBpp,dml_uint_t HActive,dml_uint_t HTotal,dml_uint_t NumberOfDSCSlices,enum dml_output_format_class OutputFormat,enum dml_output_encoder_class Output,dml_float_t PixelClock,dml_float_t PixelClockBackEnd)5870 static dml_uint_t DSCDelayRequirement(
5871 						dml_bool_t DSCEnabled,
5872 						enum dml_odm_mode ODMMode,
5873 						dml_uint_t DSCInputBitPerComponent,
5874 						dml_float_t OutputBpp,
5875 						dml_uint_t HActive,
5876 						dml_uint_t HTotal,
5877 						dml_uint_t NumberOfDSCSlices,
5878 						enum dml_output_format_class OutputFormat,
5879 						enum dml_output_encoder_class Output,
5880 						dml_float_t PixelClock,
5881 						dml_float_t PixelClockBackEnd)
5882 {
5883 	dml_uint_t DSCDelayRequirement_val = 0;
5884 
5885 	if (DSCEnabled == true && OutputBpp != 0) {
5886 		if (ODMMode == dml_odm_mode_combine_4to1) {
5887 			DSCDelayRequirement_val = dscceComputeDelay(DSCInputBitPerComponent, OutputBpp, (dml_uint_t)(dml_ceil((dml_float_t) HActive / (dml_float_t) NumberOfDSCSlices, 1.0)),
5888 												(dml_uint_t) (NumberOfDSCSlices / 4.0), OutputFormat, Output) + dscComputeDelay(OutputFormat, Output);
5889 		} else if (ODMMode == dml_odm_mode_combine_2to1) {
5890 			DSCDelayRequirement_val = dscceComputeDelay(DSCInputBitPerComponent, OutputBpp, (dml_uint_t)(dml_ceil((dml_float_t) HActive / (dml_float_t) NumberOfDSCSlices, 1.0)),
5891 												(dml_uint_t) (NumberOfDSCSlices / 2.0), OutputFormat, Output) + dscComputeDelay(OutputFormat, Output);
5892 		} else {
5893 			DSCDelayRequirement_val = dscceComputeDelay(DSCInputBitPerComponent, OutputBpp, (dml_uint_t)((dml_float_t) dml_ceil(HActive / (dml_float_t) NumberOfDSCSlices, 1.0)),
5894 										NumberOfDSCSlices, OutputFormat, Output) + dscComputeDelay(OutputFormat, Output);
5895 		}
5896 		DSCDelayRequirement_val = (dml_uint_t)(DSCDelayRequirement_val + (HTotal - HActive) * dml_ceil((dml_float_t) DSCDelayRequirement_val / (dml_float_t) HActive, 1.0));
5897 		DSCDelayRequirement_val = (dml_uint_t)(DSCDelayRequirement_val * PixelClock / PixelClockBackEnd);
5898 
5899 	} else {
5900 		DSCDelayRequirement_val = 0;
5901 	}
5902 #ifdef __DML_VBA_DEBUG__
5903 	dml_print("DML::%s: DSCEnabled = %u\n", __func__, DSCEnabled);
5904 	dml_print("DML::%s: ODMMode = %u\n", __func__, ODMMode);
5905 	dml_print("DML::%s: OutputBpp = %f\n", __func__, OutputBpp);
5906 	dml_print("DML::%s: HActive = %u\n", __func__, HActive);
5907 	dml_print("DML::%s: HTotal = %u\n", __func__, HTotal);
5908 	dml_print("DML::%s: PixelClock = %f\n", __func__, PixelClock);
5909 	dml_print("DML::%s: PixelClockBackEnd = %f\n", __func__, PixelClockBackEnd);
5910 	dml_print("DML::%s: OutputFormat = %u\n", __func__, OutputFormat);
5911 	dml_print("DML::%s: DSCInputBitPerComponent = %u\n", __func__, DSCInputBitPerComponent);
5912 	dml_print("DML::%s: NumberOfDSCSlices = %u\n", __func__, NumberOfDSCSlices);
5913 	dml_print("DML::%s: DSCDelayRequirement_val = %u\n", __func__, DSCDelayRequirement_val);
5914 #endif
5915 
5916 	return DSCDelayRequirement_val;
5917 }
5918 
CalculateVActiveBandwithSupport(dml_uint_t NumberOfActiveSurfaces,dml_float_t ReturnBW,dml_bool_t NotUrgentLatencyHiding[],dml_float_t ReadBandwidthLuma[],dml_float_t ReadBandwidthChroma[],dml_float_t cursor_bw[],dml_float_t meta_row_bandwidth[],dml_float_t dpte_row_bandwidth[],dml_uint_t NumberOfDPP[],dml_float_t UrgentBurstFactorLuma[],dml_float_t UrgentBurstFactorChroma[],dml_float_t UrgentBurstFactorCursor[])5919 static noinline_for_stack dml_bool_t CalculateVActiveBandwithSupport(dml_uint_t NumberOfActiveSurfaces,
5920 										dml_float_t ReturnBW,
5921 										dml_bool_t NotUrgentLatencyHiding[],
5922 										dml_float_t ReadBandwidthLuma[],
5923 										dml_float_t ReadBandwidthChroma[],
5924 										dml_float_t cursor_bw[],
5925 										dml_float_t meta_row_bandwidth[],
5926 										dml_float_t dpte_row_bandwidth[],
5927 										dml_uint_t NumberOfDPP[],
5928 										dml_float_t UrgentBurstFactorLuma[],
5929 										dml_float_t UrgentBurstFactorChroma[],
5930 										dml_float_t UrgentBurstFactorCursor[])
5931 {
5932 	dml_bool_t NotEnoughUrgentLatencyHiding = false;
5933 	dml_bool_t CalculateVActiveBandwithSupport_val = false;
5934 	dml_float_t VActiveBandwith = 0;
5935 
5936 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5937 		if (NotUrgentLatencyHiding[k]) {
5938 			NotEnoughUrgentLatencyHiding = true;
5939 		}
5940 	}
5941 
5942 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5943 		VActiveBandwith = VActiveBandwith + ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k] + NumberOfDPP[k] * meta_row_bandwidth[k] + NumberOfDPP[k] * dpte_row_bandwidth[k];
5944 	}
5945 
5946 	CalculateVActiveBandwithSupport_val = (VActiveBandwith <= ReturnBW) && !NotEnoughUrgentLatencyHiding;
5947 
5948 #ifdef __DML_VBA_DEBUG__
5949 	dml_print("DML::%s: NotEnoughUrgentLatencyHiding        = %u\n", __func__, NotEnoughUrgentLatencyHiding);
5950 	dml_print("DML::%s: VActiveBandwith                     = %f\n", __func__, VActiveBandwith);
5951 	dml_print("DML::%s: ReturnBW                            = %f\n", __func__, ReturnBW);
5952 	dml_print("DML::%s: CalculateVActiveBandwithSupport_val = %u\n", __func__, CalculateVActiveBandwithSupport_val);
5953 #endif
5954 	return CalculateVActiveBandwithSupport_val;
5955 }
5956 
CalculatePrefetchBandwithSupport(dml_uint_t NumberOfActiveSurfaces,dml_float_t ReturnBW,enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],dml_bool_t NotUrgentLatencyHiding[],dml_float_t ReadBandwidthLuma[],dml_float_t ReadBandwidthChroma[],dml_float_t PrefetchBandwidthLuma[],dml_float_t PrefetchBandwidthChroma[],dml_float_t cursor_bw[],dml_float_t meta_row_bandwidth[],dml_float_t dpte_row_bandwidth[],dml_float_t cursor_bw_pre[],dml_float_t prefetch_vmrow_bw[],dml_uint_t NumberOfDPP[],dml_float_t UrgentBurstFactorLuma[],dml_float_t UrgentBurstFactorChroma[],dml_float_t UrgentBurstFactorCursor[],dml_float_t UrgentBurstFactorLumaPre[],dml_float_t UrgentBurstFactorChromaPre[],dml_float_t UrgentBurstFactorCursorPre[],dml_float_t * PrefetchBandwidth,dml_float_t * PrefetchBandwidthNotIncludingMALLPrefetch,dml_float_t * FractionOfUrgentBandwidth,dml_bool_t * PrefetchBandwidthSupport)5957 static void CalculatePrefetchBandwithSupport(
5958 										dml_uint_t NumberOfActiveSurfaces,
5959 										dml_float_t ReturnBW,
5960 										enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
5961 										dml_bool_t NotUrgentLatencyHiding[],
5962 										dml_float_t ReadBandwidthLuma[],
5963 										dml_float_t ReadBandwidthChroma[],
5964 										dml_float_t PrefetchBandwidthLuma[],
5965 										dml_float_t PrefetchBandwidthChroma[],
5966 										dml_float_t cursor_bw[],
5967 										dml_float_t meta_row_bandwidth[],
5968 										dml_float_t dpte_row_bandwidth[],
5969 										dml_float_t cursor_bw_pre[],
5970 										dml_float_t prefetch_vmrow_bw[],
5971 										dml_uint_t NumberOfDPP[],
5972 										dml_float_t UrgentBurstFactorLuma[],
5973 										dml_float_t UrgentBurstFactorChroma[],
5974 										dml_float_t UrgentBurstFactorCursor[],
5975 										dml_float_t UrgentBurstFactorLumaPre[],
5976 										dml_float_t UrgentBurstFactorChromaPre[],
5977 										dml_float_t UrgentBurstFactorCursorPre[],
5978 
5979 										// Output
5980 										dml_float_t *PrefetchBandwidth,
5981 										dml_float_t *PrefetchBandwidthNotIncludingMALLPrefetch,
5982 										dml_float_t *FractionOfUrgentBandwidth,
5983 										dml_bool_t *PrefetchBandwidthSupport)
5984 {
5985 	dml_bool_t NotEnoughUrgentLatencyHiding = false;
5986 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5987 		if (NotUrgentLatencyHiding[k]) {
5988 			NotEnoughUrgentLatencyHiding = true;
5989 		}
5990 	}
5991 
5992 	*PrefetchBandwidth = 0;
5993 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
5994 		*PrefetchBandwidth = *PrefetchBandwidth + dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
5995 														ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k] + NumberOfDPP[k] * (meta_row_bandwidth[k] + dpte_row_bandwidth[k]),
5996 														NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k] + PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k]) + cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
5997 	}
5998 
5999 	*PrefetchBandwidthNotIncludingMALLPrefetch = 0;
6000 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
6001 		if (UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe)
6002 			*PrefetchBandwidthNotIncludingMALLPrefetch = *PrefetchBandwidthNotIncludingMALLPrefetch
6003 				+ dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
6004 				ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k]
6005 				+ cursor_bw[k] * UrgentBurstFactorCursor[k]
6006 				+ NumberOfDPP[k] * (meta_row_bandwidth[k] + dpte_row_bandwidth[k]),
6007 				NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k]
6008 				+ PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k])
6009 				+ cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
6010 	}
6011 
6012 	*PrefetchBandwidthSupport = (*PrefetchBandwidth <= ReturnBW) && !NotEnoughUrgentLatencyHiding;
6013 	*FractionOfUrgentBandwidth = *PrefetchBandwidth / ReturnBW;
6014 
6015 #ifdef __DML_VBA_DEBUG__
6016 	dml_print("DML::%s: ReturnBW = %f\n", __func__, ReturnBW);
6017 	dml_print("DML::%s: PrefetchBandwidth = %f\n", __func__, *PrefetchBandwidth);
6018 	dml_print("DML::%s: FractionOfUrgentBandwidth = %f\n", __func__, *FractionOfUrgentBandwidth);
6019    dml_print("DML::%s: PrefetchBandwidthSupport = %u\n", __func__, *PrefetchBandwidthSupport);
6020 #endif
6021 }
6022 
CalculateBandwidthAvailableForImmediateFlip(dml_uint_t NumberOfActiveSurfaces,dml_float_t ReturnBW,dml_float_t ReadBandwidthLuma[],dml_float_t ReadBandwidthChroma[],dml_float_t PrefetchBandwidthLuma[],dml_float_t PrefetchBandwidthChroma[],dml_float_t cursor_bw[],dml_float_t cursor_bw_pre[],dml_uint_t NumberOfDPP[],dml_float_t UrgentBurstFactorLuma[],dml_float_t UrgentBurstFactorChroma[],dml_float_t UrgentBurstFactorCursor[],dml_float_t UrgentBurstFactorLumaPre[],dml_float_t UrgentBurstFactorChromaPre[],dml_float_t UrgentBurstFactorCursorPre[])6023 static noinline_for_stack dml_float_t CalculateBandwidthAvailableForImmediateFlip(
6024 													dml_uint_t NumberOfActiveSurfaces,
6025 													dml_float_t ReturnBW,
6026 													dml_float_t ReadBandwidthLuma[],
6027 													dml_float_t ReadBandwidthChroma[],
6028 													dml_float_t PrefetchBandwidthLuma[],
6029 													dml_float_t PrefetchBandwidthChroma[],
6030 													dml_float_t cursor_bw[],
6031 													dml_float_t cursor_bw_pre[],
6032 													dml_uint_t NumberOfDPP[],
6033 													dml_float_t UrgentBurstFactorLuma[],
6034 													dml_float_t UrgentBurstFactorChroma[],
6035 													dml_float_t UrgentBurstFactorCursor[],
6036 													dml_float_t UrgentBurstFactorLumaPre[],
6037 													dml_float_t UrgentBurstFactorChromaPre[],
6038 													dml_float_t UrgentBurstFactorCursorPre[])
6039 {
6040 	dml_float_t ret_val = ReturnBW;
6041 
6042 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
6043 		ret_val = ret_val - dml_max(ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k],
6044 									NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k] + PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k]) +
6045 									cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
6046 #ifdef __DML_VBA_DEBUG__
6047 		dml_print("DML::%s: k=%u\n", __func__, k);
6048 		dml_print("DML::%s: NumberOfDPP = %u\n", __func__, NumberOfDPP[k]);
6049 		dml_print("DML::%s: ReadBandwidthLuma = %f\n", __func__, ReadBandwidthLuma[k]);
6050 		dml_print("DML::%s: UrgentBurstFactorLuma = %f\n", __func__, UrgentBurstFactorLuma[k]);
6051 		dml_print("DML::%s: ReadBandwidthChroma = %f\n", __func__, ReadBandwidthChroma[k]);
6052 		dml_print("DML::%s: UrgentBurstFactorChroma = %f\n", __func__, UrgentBurstFactorChroma[k]);
6053 		dml_print("DML::%s: cursor_bw = %f\n", __func__, cursor_bw[k]);
6054 		dml_print("DML::%s: UrgentBurstFactorCursor = %f\n", __func__, UrgentBurstFactorCursor[k]);
6055 
6056 		dml_print("DML::%s: PrefetchBandwidthLuma = %f\n", __func__, PrefetchBandwidthLuma[k]);
6057 		dml_print("DML::%s: UrgentBurstFactorLumaPre = %f\n", __func__, UrgentBurstFactorLumaPre[k]);
6058 		dml_print("DML::%s: PrefetchBandwidthChroma = %f\n", __func__, PrefetchBandwidthChroma[k]);
6059 		dml_print("DML::%s: UrgentBurstFactorChromaPre = %f\n", __func__, UrgentBurstFactorChromaPre[k]);
6060 		dml_print("DML::%s: cursor_bw_pre = %f\n", __func__, cursor_bw_pre[k]);
6061 		dml_print("DML::%s: UrgentBurstFactorCursorPre = %f\n", __func__, UrgentBurstFactorCursorPre[k]);
6062 		dml_print("DML::%s: ret_val              = %f\n", __func__, ret_val);
6063 #endif
6064 	}
6065 
6066 	return ret_val;
6067 }
6068 
CalculateImmediateFlipBandwithSupport(dml_uint_t NumberOfActiveSurfaces,dml_float_t ReturnBW,enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],enum dml_immediate_flip_requirement ImmediateFlipRequirement[],dml_float_t final_flip_bw[],dml_float_t ReadBandwidthLuma[],dml_float_t ReadBandwidthChroma[],dml_float_t PrefetchBandwidthLuma[],dml_float_t PrefetchBandwidthChroma[],dml_float_t cursor_bw[],dml_float_t meta_row_bandwidth[],dml_float_t dpte_row_bandwidth[],dml_float_t cursor_bw_pre[],dml_float_t prefetch_vmrow_bw[],dml_uint_t NumberOfDPP[],dml_float_t UrgentBurstFactorLuma[],dml_float_t UrgentBurstFactorChroma[],dml_float_t UrgentBurstFactorCursor[],dml_float_t UrgentBurstFactorLumaPre[],dml_float_t UrgentBurstFactorChromaPre[],dml_float_t UrgentBurstFactorCursorPre[],dml_float_t * TotalBandwidth,dml_float_t * TotalBandwidthNotIncludingMALLPrefetch,dml_float_t * FractionOfUrgentBandwidth,dml_bool_t * ImmediateFlipBandwidthSupport)6069 static void CalculateImmediateFlipBandwithSupport(
6070 											dml_uint_t NumberOfActiveSurfaces,
6071 											dml_float_t ReturnBW,
6072 											enum dml_use_mall_for_pstate_change_mode UseMALLForPStateChange[],
6073 											enum dml_immediate_flip_requirement ImmediateFlipRequirement[],
6074 											dml_float_t final_flip_bw[],
6075 											dml_float_t ReadBandwidthLuma[],
6076 											dml_float_t ReadBandwidthChroma[],
6077 											dml_float_t PrefetchBandwidthLuma[],
6078 											dml_float_t PrefetchBandwidthChroma[],
6079 											dml_float_t cursor_bw[],
6080 											dml_float_t meta_row_bandwidth[],
6081 											dml_float_t dpte_row_bandwidth[],
6082 											dml_float_t cursor_bw_pre[],
6083 											dml_float_t prefetch_vmrow_bw[],
6084 											dml_uint_t NumberOfDPP[],
6085 											dml_float_t UrgentBurstFactorLuma[],
6086 											dml_float_t UrgentBurstFactorChroma[],
6087 											dml_float_t UrgentBurstFactorCursor[],
6088 											dml_float_t UrgentBurstFactorLumaPre[],
6089 											dml_float_t UrgentBurstFactorChromaPre[],
6090 											dml_float_t UrgentBurstFactorCursorPre[],
6091 
6092 											// Output
6093 											dml_float_t *TotalBandwidth,
6094 											dml_float_t *TotalBandwidthNotIncludingMALLPrefetch,
6095 											dml_float_t *FractionOfUrgentBandwidth,
6096 											dml_bool_t *ImmediateFlipBandwidthSupport)
6097 {
6098 	*TotalBandwidth = 0;
6099 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
6100 		if (ImmediateFlipRequirement[k] != dml_immediate_flip_not_required) {
6101 
6102 
6103 
6104 			*TotalBandwidth = *TotalBandwidth + dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
6105 														NumberOfDPP[k] * final_flip_bw[k] + ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k],
6106 														NumberOfDPP[k] * (final_flip_bw[k] + PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k] + PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k]) + cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
6107 		} else {
6108 			*TotalBandwidth = *TotalBandwidth + dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
6109 														NumberOfDPP[k] * (meta_row_bandwidth[k] + dpte_row_bandwidth[k]) + ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k],
6110 														NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k] + PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k]) + cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
6111 		}
6112 #ifdef __DML_VBA_DEBUG__
6113 		dml_print("DML::%s: k = %u\n", __func__, k);
6114 		dml_print("DML::%s: ImmediateFlipRequirement = %u\n", __func__, ImmediateFlipRequirement[k]);
6115 		dml_print("DML::%s: TotalBandwidth = %f\n", __func__, *TotalBandwidth);
6116 		dml_print("DML::%s: NumberOfDPP = %u\n", __func__, NumberOfDPP[k]);
6117 		dml_print("DML::%s: prefetch_vmrow_bw = %f\n", __func__, prefetch_vmrow_bw[k]);
6118 		dml_print("DML::%s: final_flip_bw = %f\n", __func__, final_flip_bw[k]);
6119 		dml_print("DML::%s: ReadBandwidthLuma = %f\n", __func__, ReadBandwidthLuma[k]);
6120 		dml_print("DML::%s: UrgentBurstFactorLuma = %f\n", __func__, UrgentBurstFactorLuma[k]);
6121 		dml_print("DML::%s: ReadBandwidthChroma = %f\n", __func__, ReadBandwidthChroma[k]);
6122 		dml_print("DML::%s: UrgentBurstFactorChroma = %f\n", __func__, UrgentBurstFactorChroma[k]);
6123 		dml_print("DML::%s: cursor_bw = %f\n", __func__, cursor_bw[k]);
6124 		dml_print("DML::%s: UrgentBurstFactorCursor = %f\n", __func__, UrgentBurstFactorCursor[k]);
6125 		dml_print("DML::%s: PrefetchBandwidthLuma = %f\n", __func__, PrefetchBandwidthLuma[k]);
6126 		dml_print("DML::%s: UrgentBurstFactorLumaPre = %f\n", __func__, UrgentBurstFactorLumaPre[k]);
6127 		dml_print("DML::%s: PrefetchBandwidthChroma = %f\n", __func__, PrefetchBandwidthChroma[k]);
6128 		dml_print("DML::%s: UrgentBurstFactorChromaPre = %f\n", __func__, UrgentBurstFactorChromaPre[k]);
6129 		dml_print("DML::%s: cursor_bw_pre = %f\n", __func__, cursor_bw_pre[k]);
6130 		dml_print("DML::%s: UrgentBurstFactorCursorPre = %f\n", __func__, UrgentBurstFactorCursorPre[k]);
6131 		dml_print("DML::%s: meta_row_bandwidth = %f\n", __func__, meta_row_bandwidth[k]);
6132 		dml_print("DML::%s: dpte_row_bandwidth          = %f\n", __func__, dpte_row_bandwidth[k]);
6133 #endif
6134 	}
6135 
6136 	*TotalBandwidthNotIncludingMALLPrefetch = 0;
6137 	for (dml_uint_t k = 0; k < NumberOfActiveSurfaces; ++k) {
6138 		if (UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) {
6139 			if (ImmediateFlipRequirement[k] != dml_immediate_flip_not_required)
6140 				*TotalBandwidthNotIncludingMALLPrefetch = *TotalBandwidthNotIncludingMALLPrefetch + dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
6141 					NumberOfDPP[k] * final_flip_bw[k] + ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k],
6142 					NumberOfDPP[k] * (final_flip_bw[k] + PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k] + PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k])
6143 					+ cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
6144 			else
6145 				*TotalBandwidthNotIncludingMALLPrefetch = *TotalBandwidthNotIncludingMALLPrefetch + dml_max3(NumberOfDPP[k] * prefetch_vmrow_bw[k],
6146 					NumberOfDPP[k] * (meta_row_bandwidth[k] + dpte_row_bandwidth[k])
6147 					+ ReadBandwidthLuma[k] * UrgentBurstFactorLuma[k] + ReadBandwidthChroma[k] * UrgentBurstFactorChroma[k] + cursor_bw[k] * UrgentBurstFactorCursor[k],
6148 					NumberOfDPP[k] * (PrefetchBandwidthLuma[k] * UrgentBurstFactorLumaPre[k] + PrefetchBandwidthChroma[k] * UrgentBurstFactorChromaPre[k])
6149 					+ cursor_bw_pre[k] * UrgentBurstFactorCursorPre[k]);
6150 		}
6151 	}
6152 
6153 	*ImmediateFlipBandwidthSupport = (*TotalBandwidth <= ReturnBW);
6154 	*FractionOfUrgentBandwidth = *TotalBandwidth / ReturnBW;
6155 #ifdef __DML_VBA_DEBUG__
6156 	dml_print("DML::%s: ReturnBW = %f\n", __func__, ReturnBW);
6157 	dml_print("DML::%s: TotalBandwidth = %f\n", __func__, *TotalBandwidth);
6158 	dml_print("DML::%s: ImmediateFlipBandwidthSupport = %u\n", __func__, *ImmediateFlipBandwidthSupport);
6159 #endif
6160 }
6161 
MicroSecToVertLines(dml_uint_t num_us,dml_uint_t h_total,dml_float_t pixel_clock)6162 static dml_uint_t MicroSecToVertLines(dml_uint_t num_us, dml_uint_t h_total, dml_float_t pixel_clock)
6163 {
6164 	dml_uint_t lines_time_in_ns = 1000.0 * (h_total * 1000.0) / (pixel_clock * 1000.0);
6165 
6166 	return dml_ceil(1000.0 * num_us / lines_time_in_ns, 1.0);
6167 }
6168 
6169 /// @brief Calculate the maximum vstartup for mode support and mode programming consideration
6170 ///         Bounded by min of actual vblank and input vblank_nom, dont want vstartup/ready to start too early if actual vbllank is huge
CalculateMaxVStartup(dml_uint_t plane_idx,dml_bool_t ptoi_supported,dml_uint_t vblank_nom_default_us,struct dml_timing_cfg_st * timing,dml_float_t write_back_delay_us)6171 static dml_uint_t CalculateMaxVStartup(
6172 			dml_uint_t          plane_idx,
6173 			dml_bool_t          ptoi_supported,
6174 			dml_uint_t          vblank_nom_default_us,
6175 			struct dml_timing_cfg_st  *timing,
6176 			dml_float_t         write_back_delay_us)
6177 {
6178 	dml_uint_t vblank_size = 0;
6179 	dml_uint_t max_vstartup_lines = 0;
6180 	const dml_uint_t max_allowed_vblank_nom = 1023;
6181 
6182 	dml_float_t line_time_us = (dml_float_t) timing->HTotal[plane_idx] / timing->PixelClock[plane_idx];
6183 	dml_uint_t vblank_actual = timing->VTotal[plane_idx] - timing->VActive[plane_idx];
6184 
6185 	dml_uint_t vblank_nom_default_in_line = MicroSecToVertLines(vblank_nom_default_us, timing->HTotal[plane_idx],
6186 			timing->PixelClock[plane_idx]);
6187 	dml_uint_t vblank_nom_input = (dml_uint_t)dml_min(vblank_actual, vblank_nom_default_in_line);
6188 
6189 	// vblank_nom should not be smaller than (VSync (VTotal - VActive - VFrontPorch) + 2)
6190 	// + 2 is because
6191 	// 1 -> VStartup_start should be 1 line before VSync
6192 	// 1 -> always reserve 1 line between start of VBlank to VStartup signal
6193 	dml_uint_t vblank_nom_vsync_capped = dml_max(vblank_nom_input,
6194 			timing->VTotal[plane_idx] - timing->VActive[plane_idx] - timing->VFrontPorch[plane_idx] + 2);
6195 	dml_uint_t vblank_nom_max_allowed_capped = dml_min(vblank_nom_vsync_capped, max_allowed_vblank_nom);
6196 	dml_uint_t vblank_avail = (vblank_nom_max_allowed_capped == 0) ?
6197 			vblank_nom_default_in_line : vblank_nom_max_allowed_capped;
6198 
6199 	vblank_size = (dml_uint_t) dml_min(vblank_actual, vblank_avail);
6200 
6201    if (timing->Interlace[plane_idx] && !ptoi_supported)
6202 		max_vstartup_lines = (dml_uint_t) (dml_floor(vblank_size/2.0, 1.0));
6203 	else
6204 		max_vstartup_lines = vblank_size - (dml_uint_t) dml_max(1.0, dml_ceil(write_back_delay_us/line_time_us, 1.0));
6205 #ifdef __DML_VBA_DEBUG__
6206 	dml_print("DML::%s: plane_idx = %u\n", __func__, plane_idx);
6207 	dml_print("DML::%s: VBlankNom = %u\n", __func__, timing->VBlankNom[plane_idx]);
6208 	dml_print("DML::%s: vblank_nom_default_us = %u\n", __func__, vblank_nom_default_us);
6209 	dml_print("DML::%s: line_time_us = %f\n", __func__, line_time_us);
6210 	dml_print("DML::%s: vblank_actual = %u\n", __func__, vblank_actual);
6211 	dml_print("DML::%s: vblank_avail = %u\n", __func__, vblank_avail);
6212 	dml_print("DML::%s: max_vstartup_lines = %u\n", __func__, max_vstartup_lines);
6213 #endif
6214 	max_vstartup_lines = (dml_uint_t) dml_min(max_vstartup_lines, DML_MAX_VSTARTUP_START);
6215 	return max_vstartup_lines;
6216 }
6217 
set_calculate_prefetch_schedule_params(struct display_mode_lib_st * mode_lib,struct CalculatePrefetchSchedule_params_st * CalculatePrefetchSchedule_params,dml_uint_t j,dml_uint_t k)6218 static noinline_for_stack void set_calculate_prefetch_schedule_params(struct display_mode_lib_st *mode_lib,
6219 						   struct CalculatePrefetchSchedule_params_st *CalculatePrefetchSchedule_params,
6220 						   dml_uint_t j,
6221 						   dml_uint_t k)
6222 {
6223 				CalculatePrefetchSchedule_params->DSCDelay = mode_lib->ms.DSCDelayPerState[k];
6224 				CalculatePrefetchSchedule_params->EnhancedPrefetchScheduleAccelerationFinal = mode_lib->ms.policy.EnhancedPrefetchScheduleAccelerationFinal;
6225 				CalculatePrefetchSchedule_params->DPPCLKDelaySubtotalPlusCNVCFormater = mode_lib->ms.ip.dppclk_delay_subtotal + mode_lib->ms.ip.dppclk_delay_cnvc_formatter;
6226 				CalculatePrefetchSchedule_params->DPPCLKDelaySCL = mode_lib->ms.ip.dppclk_delay_scl;
6227 				CalculatePrefetchSchedule_params->DPPCLKDelaySCLLBOnly = mode_lib->ms.ip.dppclk_delay_scl_lb_only;
6228 				CalculatePrefetchSchedule_params->DPPCLKDelayCNVCCursor = mode_lib->ms.ip.dppclk_delay_cnvc_cursor;
6229 				CalculatePrefetchSchedule_params->DISPCLKDelaySubtotal = mode_lib->ms.ip.dispclk_delay_subtotal;
6230 				CalculatePrefetchSchedule_params->DPP_RECOUT_WIDTH = (dml_uint_t)(mode_lib->ms.SwathWidthYThisState[k] / mode_lib->ms.cache_display_cfg.plane.HRatio[k]);
6231 				CalculatePrefetchSchedule_params->OutputFormat = mode_lib->ms.cache_display_cfg.output.OutputFormat[k];
6232 				CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ms.ip.max_inter_dcn_tile_repeaters;
6233 				CalculatePrefetchSchedule_params->GPUVMPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
6234 				CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
6235 				CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
6236 				CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
6237 				CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
6238 				CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k];
6239 				CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
6240 				CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k];
6241 				CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataTransmittedBytes[k];
6242 				CalculatePrefetchSchedule_params->UrgentLatency = mode_lib->ms.UrgLatency;
6243 				CalculatePrefetchSchedule_params->UrgentExtraLatency = mode_lib->ms.ExtraLatency;
6244 				CalculatePrefetchSchedule_params->TCalc = mode_lib->ms.TimeCalc;
6245 				CalculatePrefetchSchedule_params->PDEAndMetaPTEBytesFrame = mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k];
6246 				CalculatePrefetchSchedule_params->MetaRowByte = mode_lib->ms.MetaRowBytes[j][k];
6247 				CalculatePrefetchSchedule_params->PixelPTEBytesPerRow = mode_lib->ms.DPTEBytesPerRow[j][k];
6248 				CalculatePrefetchSchedule_params->PrefetchSourceLinesY = mode_lib->ms.PrefetchLinesY[j][k];
6249 				CalculatePrefetchSchedule_params->VInitPreFillY = mode_lib->ms.PrefillY[k];
6250 				CalculatePrefetchSchedule_params->MaxNumSwathY = mode_lib->ms.MaxNumSwY[k];
6251 				CalculatePrefetchSchedule_params->PrefetchSourceLinesC = mode_lib->ms.PrefetchLinesC[j][k];
6252 				CalculatePrefetchSchedule_params->VInitPreFillC = mode_lib->ms.PrefillC[k];
6253 				CalculatePrefetchSchedule_params->MaxNumSwathC = mode_lib->ms.MaxNumSwC[k];
6254 				CalculatePrefetchSchedule_params->swath_width_luma_ub = mode_lib->ms.swath_width_luma_ub_this_state[k];
6255 				CalculatePrefetchSchedule_params->swath_width_chroma_ub = mode_lib->ms.swath_width_chroma_ub_this_state[k];
6256 				CalculatePrefetchSchedule_params->SwathHeightY = mode_lib->ms.SwathHeightYThisState[k];
6257 				CalculatePrefetchSchedule_params->SwathHeightC = mode_lib->ms.SwathHeightCThisState[k];
6258 				CalculatePrefetchSchedule_params->TWait = mode_lib->ms.TWait;
6259 				CalculatePrefetchSchedule_params->DestinationLinesForPrefetch = &mode_lib->ms.LineTimesForPrefetch[k];
6260 				CalculatePrefetchSchedule_params->DestinationLinesToRequestVMInVBlank = &mode_lib->ms.LinesForMetaPTE[k];
6261 				CalculatePrefetchSchedule_params->DestinationLinesToRequestRowInVBlank = &mode_lib->ms.LinesForMetaAndDPTERow[k];
6262 				CalculatePrefetchSchedule_params->VRatioPrefetchY = &mode_lib->ms.VRatioPreY[j][k];
6263 				CalculatePrefetchSchedule_params->VRatioPrefetchC = &mode_lib->ms.VRatioPreC[j][k];
6264 				CalculatePrefetchSchedule_params->RequiredPrefetchPixDataBWLuma = &mode_lib->ms.RequiredPrefetchPixelDataBWLuma[k];
6265 				CalculatePrefetchSchedule_params->RequiredPrefetchPixDataBWChroma = &mode_lib->ms.RequiredPrefetchPixelDataBWChroma[k];
6266 				CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &mode_lib->ms.support.NoTimeForDynamicMetadata[j][k];
6267 				CalculatePrefetchSchedule_params->Tno_bw = &mode_lib->ms.Tno_bw[k];
6268 }
6269 
dml_prefetch_check(struct display_mode_lib_st * mode_lib)6270 static noinline_for_stack void dml_prefetch_check(struct display_mode_lib_st *mode_lib)
6271 {
6272 	struct dml_core_mode_support_locals_st *s = &mode_lib->scratch.dml_core_mode_support_locals;
6273 	struct CalculatePrefetchSchedule_params_st *CalculatePrefetchSchedule_params = &mode_lib->scratch.CalculatePrefetchSchedule_params;
6274 	struct CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params_st *CalculateWatermarks_params = &mode_lib->scratch.CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params;
6275 	struct DmlPipe *myPipe;
6276 	dml_uint_t j, k;
6277 
6278 	for (j = 0; j < 2; ++j) {
6279 		mode_lib->ms.TimeCalc = 24 / mode_lib->ms.ProjectedDCFCLKDeepSleep[j];
6280 
6281 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
6282 			mode_lib->ms.NoOfDPPThisState[k] = mode_lib->ms.NoOfDPP[j][k];
6283 			mode_lib->ms.swath_width_luma_ub_this_state[k] = mode_lib->ms.swath_width_luma_ub_all_states[j][k];
6284 			mode_lib->ms.swath_width_chroma_ub_this_state[k] = mode_lib->ms.swath_width_chroma_ub_all_states[j][k];
6285 			mode_lib->ms.SwathWidthYThisState[k] = mode_lib->ms.SwathWidthYAllStates[j][k];
6286 			mode_lib->ms.SwathWidthCThisState[k] = mode_lib->ms.SwathWidthCAllStates[j][k];
6287 			mode_lib->ms.SwathHeightYThisState[k] = mode_lib->ms.SwathHeightYAllStates[j][k];
6288 			mode_lib->ms.SwathHeightCThisState[k] = mode_lib->ms.SwathHeightCAllStates[j][k];
6289 			mode_lib->ms.UnboundedRequestEnabledThisState = mode_lib->ms.UnboundedRequestEnabledAllStates[j];
6290 			mode_lib->ms.CompressedBufferSizeInkByteThisState = mode_lib->ms.CompressedBufferSizeInkByteAllStates[j];
6291 			mode_lib->ms.DETBufferSizeInKByteThisState[k] = mode_lib->ms.DETBufferSizeInKByteAllStates[j][k];
6292 			mode_lib->ms.DETBufferSizeYThisState[k] = mode_lib->ms.DETBufferSizeYAllStates[j][k];
6293 			mode_lib->ms.DETBufferSizeCThisState[k] = mode_lib->ms.DETBufferSizeCAllStates[j][k];
6294 		}
6295 
6296 		mode_lib->ms.support.VActiveBandwithSupport[j] = CalculateVActiveBandwithSupport(
6297 			mode_lib->ms.num_active_planes,
6298 			mode_lib->ms.ReturnBWPerState[j],
6299 			mode_lib->ms.NotUrgentLatencyHiding,
6300 			mode_lib->ms.ReadBandwidthLuma,
6301 			mode_lib->ms.ReadBandwidthChroma,
6302 			mode_lib->ms.cursor_bw,
6303 			mode_lib->ms.meta_row_bandwidth_this_state,
6304 			mode_lib->ms.dpte_row_bandwidth_this_state,
6305 			mode_lib->ms.NoOfDPPThisState,
6306 			mode_lib->ms.UrgentBurstFactorLuma[j],
6307 			mode_lib->ms.UrgentBurstFactorChroma[j],
6308 			mode_lib->ms.UrgentBurstFactorCursor[j]);
6309 
6310 		s->VMDataOnlyReturnBWPerState = dml_get_return_bw_mbps_vm_only(
6311 																	&mode_lib->ms.soc,
6312 																	mode_lib->ms.state.use_ideal_dram_bw_strobe,
6313 																	mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
6314 																	mode_lib->ms.DCFCLKState[j],
6315 																	mode_lib->ms.state.fabricclk_mhz,
6316 																	mode_lib->ms.state.dram_speed_mts);
6317 
6318 		s->HostVMInefficiencyFactor = 1;
6319 		if (mode_lib->ms.cache_display_cfg.plane.GPUVMEnable && mode_lib->ms.cache_display_cfg.plane.HostVMEnable)
6320 			s->HostVMInefficiencyFactor = mode_lib->ms.ReturnBWPerState[j] / s->VMDataOnlyReturnBWPerState;
6321 
6322 		mode_lib->ms.ExtraLatency = CalculateExtraLatency(
6323 				mode_lib->ms.soc.round_trip_ping_latency_dcfclk_cycles,
6324 				s->ReorderingBytes,
6325 				mode_lib->ms.DCFCLKState[j],
6326 				mode_lib->ms.TotalNumberOfActiveDPP[j],
6327 				mode_lib->ms.ip.pixel_chunk_size_kbytes,
6328 				mode_lib->ms.TotalNumberOfDCCActiveDPP[j],
6329 				mode_lib->ms.ip.meta_chunk_size_kbytes,
6330 				mode_lib->ms.ReturnBWPerState[j],
6331 				mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
6332 				mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
6333 				mode_lib->ms.num_active_planes,
6334 				mode_lib->ms.NoOfDPPThisState,
6335 				mode_lib->ms.dpte_group_bytes,
6336 				s->HostVMInefficiencyFactor,
6337 				mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
6338 				mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
6339 
6340 		s->NextMaxVStartup = s->MaxVStartupAllPlanes[j];
6341 		s->MaxVStartup = 0;
6342 		s->AllPrefetchModeTested = true;
6343 		for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6344 			CalculatePrefetchMode(mode_lib->ms.policy.AllowForPStateChangeOrStutterInVBlank[k], &s->MinPrefetchMode[k], &s->MaxPrefetchMode[k]);
6345 			s->NextPrefetchMode[k] = s->MinPrefetchMode[k];
6346 		}
6347 
6348 		do {
6349 			s->MaxVStartup = s->NextMaxVStartup;
6350 			s->AllPrefetchModeTested = true;
6351 
6352 			for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6353 				mode_lib->ms.PrefetchMode[k] = s->NextPrefetchMode[k];
6354 				mode_lib->ms.TWait = CalculateTWait(
6355 								mode_lib->ms.PrefetchMode[k],
6356 								mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k],
6357 								mode_lib->ms.policy.SynchronizeDRRDisplaysForUCLKPStateChangeFinal,
6358 								mode_lib->ms.cache_display_cfg.timing.DRRDisplay[k],
6359 								mode_lib->ms.state.dram_clock_change_latency_us,
6360 								mode_lib->ms.state.fclk_change_latency_us,
6361 								mode_lib->ms.UrgLatency,
6362 								mode_lib->ms.state.sr_enter_plus_exit_time_us);
6363 
6364 				myPipe = &s->myPipe;
6365 				myPipe->Dppclk = mode_lib->ms.RequiredDPPCLKPerSurface[j][k];
6366 				myPipe->Dispclk = mode_lib->ms.RequiredDISPCLK[j];
6367 				myPipe->PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock[k];
6368 				myPipe->DCFClkDeepSleep = mode_lib->ms.ProjectedDCFCLKDeepSleep[j];
6369 				myPipe->DPPPerSurface = mode_lib->ms.NoOfDPP[j][k];
6370 				myPipe->ScalerEnabled = mode_lib->ms.cache_display_cfg.plane.ScalerEnabled[k];
6371 				myPipe->SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan[k];
6372 				myPipe->BlockWidth256BytesY = mode_lib->ms.Read256BlockWidthY[k];
6373 				myPipe->BlockHeight256BytesY = mode_lib->ms.Read256BlockHeightY[k];
6374 				myPipe->BlockWidth256BytesC = mode_lib->ms.Read256BlockWidthC[k];
6375 				myPipe->BlockHeight256BytesC = mode_lib->ms.Read256BlockHeightC[k];
6376 				myPipe->InterlaceEnable = mode_lib->ms.cache_display_cfg.timing.Interlace[k];
6377 				myPipe->NumberOfCursors = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k];
6378 				myPipe->VBlank = mode_lib->ms.cache_display_cfg.timing.VTotal[k] - mode_lib->ms.cache_display_cfg.timing.VActive[k];
6379 				myPipe->HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal[k];
6380 				myPipe->HActive = mode_lib->ms.cache_display_cfg.timing.HActive[k];
6381 				myPipe->DCCEnable = mode_lib->ms.cache_display_cfg.surface.DCCEnable[k];
6382 				myPipe->ODMMode = mode_lib->ms.ODMModePerState[k];
6383 				myPipe->SourcePixelFormat = mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k];
6384 				myPipe->BytePerPixelY = mode_lib->ms.BytePerPixelY[k];
6385 				myPipe->BytePerPixelC = mode_lib->ms.BytePerPixelC[k];
6386 				myPipe->ProgressiveToInterlaceUnitInOPP = mode_lib->ms.ip.ptoi_supported;
6387 
6388 #ifdef __DML_VBA_DEBUG__
6389 				dml_print("DML::%s: Calling CalculatePrefetchSchedule for j=%u, k=%u\n", __func__, j, k);
6390 				dml_print("DML::%s: MaximumVStartup = %u\n", __func__, s->MaximumVStartup[j][k]);
6391 				dml_print("DML::%s: MaxVStartup = %u\n", __func__, s->MaxVStartup);
6392 				dml_print("DML::%s: NextPrefetchMode = %u\n", __func__, s->NextPrefetchMode[k]);
6393 				dml_print("DML::%s: AllowForPStateChangeOrStutterInVBlank = %u\n", __func__, mode_lib->ms.policy.AllowForPStateChangeOrStutterInVBlank[k]);
6394 				dml_print("DML::%s: PrefetchMode = %u\n", __func__, mode_lib->ms.PrefetchMode[k]);
6395 #endif
6396 
6397 				CalculatePrefetchSchedule_params->HostVMInefficiencyFactor = s->HostVMInefficiencyFactor;
6398 				CalculatePrefetchSchedule_params->myPipe = myPipe;
6399 				CalculatePrefetchSchedule_params->VStartup = (dml_uint_t)(dml_min(s->MaxVStartup, s->MaximumVStartup[j][k]));
6400 				CalculatePrefetchSchedule_params->MaxVStartup = s->MaximumVStartup[j][k];
6401 				CalculatePrefetchSchedule_params->DSTXAfterScaler = &s->DSTXAfterScaler[k];
6402 				CalculatePrefetchSchedule_params->DSTYAfterScaler = &s->DSTYAfterScaler[k];
6403 				CalculatePrefetchSchedule_params->prefetch_vmrow_bw = &mode_lib->ms.prefetch_vmrow_bw[k];
6404 				CalculatePrefetchSchedule_params->Tdmdl_vm = &s->dummy_single[0];
6405 				CalculatePrefetchSchedule_params->Tdmdl = &s->dummy_single[1];
6406 				CalculatePrefetchSchedule_params->TSetup = &s->dummy_single[2];
6407 				CalculatePrefetchSchedule_params->VUpdateOffsetPix = &s->dummy_integer[0];
6408 				CalculatePrefetchSchedule_params->VUpdateWidthPix = &s->dummy_integer[1];
6409 				CalculatePrefetchSchedule_params->VReadyOffsetPix = &s->dummy_integer[2];
6410 
6411 				set_calculate_prefetch_schedule_params(mode_lib, CalculatePrefetchSchedule_params, j, k);
6412 
6413 				mode_lib->ms.support.NoTimeForPrefetch[j][k] =
6414 								CalculatePrefetchSchedule(&mode_lib->scratch,
6415 								CalculatePrefetchSchedule_params);
6416 			}
6417 
6418 			for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6419 					CalculateUrgentBurstFactor(
6420 							mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k],
6421 							mode_lib->ms.swath_width_luma_ub_this_state[k],
6422 							mode_lib->ms.swath_width_chroma_ub_this_state[k],
6423 							mode_lib->ms.SwathHeightYThisState[k],
6424 							mode_lib->ms.SwathHeightCThisState[k],
6425 							mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
6426 							mode_lib->ms.UrgLatency,
6427 							mode_lib->ms.ip.cursor_buffer_size,
6428 							mode_lib->ms.cache_display_cfg.plane.CursorWidth[k],
6429 							mode_lib->ms.cache_display_cfg.plane.CursorBPP[k],
6430 							mode_lib->ms.VRatioPreY[j][k],
6431 							mode_lib->ms.VRatioPreC[j][k],
6432 							mode_lib->ms.BytePerPixelInDETY[k],
6433 							mode_lib->ms.BytePerPixelInDETC[k],
6434 							mode_lib->ms.DETBufferSizeYThisState[k],
6435 							mode_lib->ms.DETBufferSizeCThisState[k],
6436 							/* Output */
6437 							&mode_lib->ms.UrgentBurstFactorCursorPre[k],
6438 							&mode_lib->ms.UrgentBurstFactorLumaPre[k],
6439 							&mode_lib->ms.UrgentBurstFactorChromaPre[k],
6440 							&mode_lib->ms.NotUrgentLatencyHidingPre[k]);
6441 
6442 					mode_lib->ms.cursor_bw_pre[k] = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k] * mode_lib->ms.cache_display_cfg.plane.CursorWidth[k] *
6443 													mode_lib->ms.cache_display_cfg.plane.CursorBPP[k] / 8.0 / (mode_lib->ms.cache_display_cfg.timing.HTotal[k] /
6444 													mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * mode_lib->ms.VRatioPreY[j][k];
6445 			}
6446 
6447 			{
6448 			CalculatePrefetchBandwithSupport(
6449 				mode_lib->ms.num_active_planes,
6450 				mode_lib->ms.ReturnBWPerState[j],
6451 				mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange,
6452 				mode_lib->ms.NotUrgentLatencyHidingPre,
6453 				mode_lib->ms.ReadBandwidthLuma,
6454 				mode_lib->ms.ReadBandwidthChroma,
6455 				mode_lib->ms.RequiredPrefetchPixelDataBWLuma,
6456 				mode_lib->ms.RequiredPrefetchPixelDataBWChroma,
6457 				mode_lib->ms.cursor_bw,
6458 				mode_lib->ms.meta_row_bandwidth_this_state,
6459 				mode_lib->ms.dpte_row_bandwidth_this_state,
6460 				mode_lib->ms.cursor_bw_pre,
6461 				mode_lib->ms.prefetch_vmrow_bw,
6462 				mode_lib->ms.NoOfDPPThisState,
6463 				mode_lib->ms.UrgentBurstFactorLuma[j],
6464 				mode_lib->ms.UrgentBurstFactorChroma[j],
6465 				mode_lib->ms.UrgentBurstFactorCursor[j],
6466 				mode_lib->ms.UrgentBurstFactorLumaPre,
6467 				mode_lib->ms.UrgentBurstFactorChromaPre,
6468 				mode_lib->ms.UrgentBurstFactorCursorPre,
6469 
6470 				/* output */
6471 				&s->dummy_single[0], // dml_float_t *PrefetchBandwidth
6472 				&s->dummy_single[1], // dml_float_t *PrefetchBandwidthNotIncludingMALLPrefetch
6473 				&mode_lib->mp.FractionOfUrgentBandwidth, // dml_float_t *FractionOfUrgentBandwidth
6474 				&mode_lib->ms.support.PrefetchSupported[j]);
6475 			}
6476 
6477 			for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6478 				if (mode_lib->ms.LineTimesForPrefetch[k] < 2.0
6479 					|| mode_lib->ms.LinesForMetaPTE[k] >= 32.0
6480 					|| mode_lib->ms.LinesForMetaAndDPTERow[k] >= 16.0
6481 					|| mode_lib->ms.support.NoTimeForPrefetch[j][k] == true) {
6482 						mode_lib->ms.support.PrefetchSupported[j] = false;
6483 				}
6484 			}
6485 
6486 			mode_lib->ms.support.DynamicMetadataSupported[j] = true;
6487 			for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
6488 				if (mode_lib->ms.support.NoTimeForDynamicMetadata[j][k] == true) {
6489 					mode_lib->ms.support.DynamicMetadataSupported[j] = false;
6490 				}
6491 			}
6492 
6493 			mode_lib->ms.support.VRatioInPrefetchSupported[j] = true;
6494 			for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6495 				if (mode_lib->ms.support.NoTimeForPrefetch[j][k] == true ||
6496 					mode_lib->ms.VRatioPreY[j][k] > __DML_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__ ||
6497 					mode_lib->ms.VRatioPreC[j][k] > __DML_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__ ||
6498 					((s->MaxVStartup < s->MaximumVStartup[j][k] || mode_lib->ms.policy.EnhancedPrefetchScheduleAccelerationFinal == 0) &&
6499 						(mode_lib->ms.VRatioPreY[j][k] > __DML_MAX_VRATIO_PRE__ || mode_lib->ms.VRatioPreC[j][k] > __DML_MAX_VRATIO_PRE__))) {
6500 							mode_lib->ms.support.VRatioInPrefetchSupported[j] = false;
6501 				}
6502 			}
6503 
6504 			s->AnyLinesForVMOrRowTooLarge = false;
6505 			for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
6506 				if (mode_lib->ms.LinesForMetaAndDPTERow[k] >= 16 || mode_lib->ms.LinesForMetaPTE[k] >= 32) {
6507 					s->AnyLinesForVMOrRowTooLarge = true;
6508 				}
6509 			}
6510 
6511 			if (mode_lib->ms.support.PrefetchSupported[j] == true && mode_lib->ms.support.VRatioInPrefetchSupported[j] == true) {
6512 				mode_lib->ms.BandwidthAvailableForImmediateFlip = CalculateBandwidthAvailableForImmediateFlip(
6513 						mode_lib->ms.num_active_planes,
6514 						mode_lib->ms.ReturnBWPerState[j],
6515 						mode_lib->ms.ReadBandwidthLuma,
6516 						mode_lib->ms.ReadBandwidthChroma,
6517 						mode_lib->ms.RequiredPrefetchPixelDataBWLuma,
6518 						mode_lib->ms.RequiredPrefetchPixelDataBWChroma,
6519 						mode_lib->ms.cursor_bw,
6520 						mode_lib->ms.cursor_bw_pre,
6521 						mode_lib->ms.NoOfDPPThisState,
6522 						mode_lib->ms.UrgentBurstFactorLuma[j],
6523 						mode_lib->ms.UrgentBurstFactorChroma[j],
6524 						mode_lib->ms.UrgentBurstFactorCursor[j],
6525 						mode_lib->ms.UrgentBurstFactorLumaPre,
6526 						mode_lib->ms.UrgentBurstFactorChromaPre,
6527 						mode_lib->ms.UrgentBurstFactorCursorPre);
6528 
6529 				mode_lib->ms.TotImmediateFlipBytes = 0;
6530 				for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6531 					if (!(mode_lib->ms.policy.ImmediateFlipRequirement[k] == dml_immediate_flip_not_required)) {
6532 						mode_lib->ms.TotImmediateFlipBytes = mode_lib->ms.TotImmediateFlipBytes + mode_lib->ms.NoOfDPP[j][k] * (mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k] + mode_lib->ms.MetaRowBytes[j][k]);
6533 						if (mode_lib->ms.use_one_row_for_frame_flip[j][k]) {
6534 							mode_lib->ms.TotImmediateFlipBytes = mode_lib->ms.TotImmediateFlipBytes + mode_lib->ms.NoOfDPP[j][k] * (2 * mode_lib->ms.DPTEBytesPerRow[j][k]);
6535 						} else {
6536 							mode_lib->ms.TotImmediateFlipBytes = mode_lib->ms.TotImmediateFlipBytes + mode_lib->ms.NoOfDPP[j][k] * mode_lib->ms.DPTEBytesPerRow[j][k];
6537 						}
6538 					}
6539 				}
6540 
6541 				for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6542 					CalculateFlipSchedule(
6543 						s->HostVMInefficiencyFactor,
6544 						mode_lib->ms.ExtraLatency,
6545 						mode_lib->ms.UrgLatency,
6546 						mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels,
6547 						mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
6548 						mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
6549 						mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
6550 						mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
6551 						mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k],
6552 						mode_lib->ms.MetaRowBytes[j][k],
6553 						mode_lib->ms.DPTEBytesPerRow[j][k],
6554 						mode_lib->ms.BandwidthAvailableForImmediateFlip,
6555 						mode_lib->ms.TotImmediateFlipBytes,
6556 						mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k],
6557 						(mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]),
6558 						mode_lib->ms.cache_display_cfg.plane.VRatio[k],
6559 						mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k],
6560 						mode_lib->ms.Tno_bw[k],
6561 						mode_lib->ms.cache_display_cfg.surface.DCCEnable[k],
6562 						mode_lib->ms.dpte_row_height[k],
6563 						mode_lib->ms.meta_row_height[k],
6564 						mode_lib->ms.dpte_row_height_chroma[k],
6565 						mode_lib->ms.meta_row_height_chroma[k],
6566 						mode_lib->ms.use_one_row_for_frame_flip[j][k], // 24
6567 
6568 						/* Output */
6569 						&mode_lib->ms.DestinationLinesToRequestVMInImmediateFlip[k],
6570 						&mode_lib->ms.DestinationLinesToRequestRowInImmediateFlip[k],
6571 						&mode_lib->ms.final_flip_bw[k],
6572 						&mode_lib->ms.ImmediateFlipSupportedForPipe[k]);
6573 				}
6574 
6575 				{
6576 				CalculateImmediateFlipBandwithSupport(mode_lib->ms.num_active_planes,
6577 													mode_lib->ms.ReturnBWPerState[j],
6578 													mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange,
6579 													mode_lib->ms.policy.ImmediateFlipRequirement,
6580 													mode_lib->ms.final_flip_bw,
6581 													mode_lib->ms.ReadBandwidthLuma,
6582 													mode_lib->ms.ReadBandwidthChroma,
6583 													mode_lib->ms.RequiredPrefetchPixelDataBWLuma,
6584 													mode_lib->ms.RequiredPrefetchPixelDataBWChroma,
6585 													mode_lib->ms.cursor_bw,
6586 													mode_lib->ms.meta_row_bandwidth_this_state,
6587 													mode_lib->ms.dpte_row_bandwidth_this_state,
6588 													mode_lib->ms.cursor_bw_pre,
6589 													mode_lib->ms.prefetch_vmrow_bw,
6590 													mode_lib->ms.NoOfDPP[j], // VBA_ERROR DPPPerSurface is not assigned at this point, should use NoOfDpp here
6591 													mode_lib->ms.UrgentBurstFactorLuma[j],
6592 													mode_lib->ms.UrgentBurstFactorChroma[j],
6593 													mode_lib->ms.UrgentBurstFactorCursor[j],
6594 													mode_lib->ms.UrgentBurstFactorLumaPre,
6595 													mode_lib->ms.UrgentBurstFactorChromaPre,
6596 													mode_lib->ms.UrgentBurstFactorCursorPre,
6597 
6598 													/* output */
6599 													&s->dummy_single[0], // dml_float_t *TotalBandwidth
6600 													&s->dummy_single[1], // dml_float_t *TotalBandwidthNotIncludingMALLPrefetch
6601 													&s->dummy_single[2], // dml_float_t *FractionOfUrgentBandwidth
6602 													&mode_lib->ms.support.ImmediateFlipSupportedForState[j]); // dml_bool_t *ImmediateFlipBandwidthSupport
6603 				}
6604 
6605 				for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6606 					if (!(mode_lib->ms.policy.ImmediateFlipRequirement[k] == dml_immediate_flip_not_required) && (mode_lib->ms.ImmediateFlipSupportedForPipe[k] == false))
6607 						mode_lib->ms.support.ImmediateFlipSupportedForState[j] = false;
6608 				}
6609 
6610 			} else { // if prefetch not support, assume iflip not supported
6611 				mode_lib->ms.support.ImmediateFlipSupportedForState[j] = false;
6612 			}
6613 
6614 			if (s->MaxVStartup <= __DML_VBA_MIN_VSTARTUP__ || s->AnyLinesForVMOrRowTooLarge == false) {
6615 				s->NextMaxVStartup = s->MaxVStartupAllPlanes[j];
6616 				for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6617 					s->NextPrefetchMode[k] = s->NextPrefetchMode[k] + 1;
6618 
6619 					if (s->NextPrefetchMode[k] <= s->MaxPrefetchMode[k])
6620 						s->AllPrefetchModeTested = false;
6621 				}
6622 			} else {
6623 				s->NextMaxVStartup = s->NextMaxVStartup - 1;
6624 			}
6625 		} while (!((mode_lib->ms.support.PrefetchSupported[j] == true && mode_lib->ms.support.DynamicMetadataSupported[j] == true &&
6626 					mode_lib->ms.support.VRatioInPrefetchSupported[j] == true &&
6627 					// consider flip support is okay if when there is no hostvm and the user does't require a iflip OR the flip bw is ok
6628 					// If there is hostvm, DCN needs to support iflip for invalidation
6629 					((s->ImmediateFlipRequiredFinal) || mode_lib->ms.support.ImmediateFlipSupportedForState[j] == true)) ||
6630 					(s->NextMaxVStartup == s->MaxVStartupAllPlanes[j] && s->AllPrefetchModeTested)));
6631 
6632 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
6633 			mode_lib->ms.use_one_row_for_frame_this_state[k] = mode_lib->ms.use_one_row_for_frame[j][k];
6634 		}
6635 
6636 		s->mSOCParameters.UrgentLatency = mode_lib->ms.UrgLatency;
6637 		s->mSOCParameters.ExtraLatency = mode_lib->ms.ExtraLatency;
6638 		s->mSOCParameters.WritebackLatency = mode_lib->ms.state.writeback_latency_us;
6639 		s->mSOCParameters.DRAMClockChangeLatency = mode_lib->ms.state.dram_clock_change_latency_us;
6640 		s->mSOCParameters.FCLKChangeLatency = mode_lib->ms.state.fclk_change_latency_us;
6641 		s->mSOCParameters.SRExitTime = mode_lib->ms.state.sr_exit_time_us;
6642 		s->mSOCParameters.SREnterPlusExitTime = mode_lib->ms.state.sr_enter_plus_exit_time_us;
6643 		s->mSOCParameters.SRExitZ8Time = mode_lib->ms.state.sr_exit_z8_time_us;
6644 		s->mSOCParameters.SREnterPlusExitZ8Time = mode_lib->ms.state.sr_enter_plus_exit_z8_time_us;
6645 		s->mSOCParameters.USRRetrainingLatency = mode_lib->ms.state.usr_retraining_latency_us;
6646 		s->mSOCParameters.SMNLatency = mode_lib->ms.soc.smn_latency_us;
6647 
6648 		CalculateWatermarks_params->USRRetrainingRequiredFinal = mode_lib->ms.policy.USRRetrainingRequiredFinal;
6649 		CalculateWatermarks_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
6650 		CalculateWatermarks_params->PrefetchMode = mode_lib->ms.PrefetchMode;
6651 		CalculateWatermarks_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
6652 		CalculateWatermarks_params->MaxLineBufferLines = mode_lib->ms.ip.max_line_buffer_lines;
6653 		CalculateWatermarks_params->LineBufferSize = mode_lib->ms.ip.line_buffer_size_bits;
6654 		CalculateWatermarks_params->WritebackInterfaceBufferSize = mode_lib->ms.ip.writeback_interface_buffer_size_kbytes;
6655 		CalculateWatermarks_params->DCFCLK = mode_lib->ms.DCFCLKState[j];
6656 		CalculateWatermarks_params->ReturnBW = mode_lib->ms.ReturnBWPerState[j];
6657 		CalculateWatermarks_params->SynchronizeTimingsFinal = mode_lib->ms.policy.SynchronizeTimingsFinal;
6658 		CalculateWatermarks_params->SynchronizeDRRDisplaysForUCLKPStateChangeFinal = mode_lib->ms.policy.SynchronizeDRRDisplaysForUCLKPStateChangeFinal;
6659 		CalculateWatermarks_params->DRRDisplay = mode_lib->ms.cache_display_cfg.timing.DRRDisplay;
6660 		CalculateWatermarks_params->dpte_group_bytes = mode_lib->ms.dpte_group_bytes;
6661 		CalculateWatermarks_params->meta_row_height = mode_lib->ms.meta_row_height;
6662 		CalculateWatermarks_params->meta_row_height_chroma = mode_lib->ms.meta_row_height_chroma;
6663 		CalculateWatermarks_params->mmSOCParameters = s->mSOCParameters;
6664 		CalculateWatermarks_params->WritebackChunkSize = mode_lib->ms.ip.writeback_chunk_size_kbytes;
6665 		CalculateWatermarks_params->SOCCLK = mode_lib->ms.state.socclk_mhz;
6666 		CalculateWatermarks_params->DCFClkDeepSleep = mode_lib->ms.ProjectedDCFCLKDeepSleep[j];
6667 		CalculateWatermarks_params->DETBufferSizeY = mode_lib->ms.DETBufferSizeYThisState;
6668 		CalculateWatermarks_params->DETBufferSizeC = mode_lib->ms.DETBufferSizeCThisState;
6669 		CalculateWatermarks_params->SwathHeightY = mode_lib->ms.SwathHeightYThisState;
6670 		CalculateWatermarks_params->SwathHeightC = mode_lib->ms.SwathHeightCThisState;
6671 		CalculateWatermarks_params->LBBitPerPixel = mode_lib->ms.cache_display_cfg.plane.LBBitPerPixel;
6672 		CalculateWatermarks_params->SwathWidthY = mode_lib->ms.SwathWidthYThisState;
6673 		CalculateWatermarks_params->SwathWidthC = mode_lib->ms.SwathWidthCThisState;
6674 		CalculateWatermarks_params->HRatio = mode_lib->ms.cache_display_cfg.plane.HRatio;
6675 		CalculateWatermarks_params->HRatioChroma = mode_lib->ms.cache_display_cfg.plane.HRatioChroma;
6676 		CalculateWatermarks_params->VTaps = mode_lib->ms.cache_display_cfg.plane.VTaps;
6677 		CalculateWatermarks_params->VTapsChroma = mode_lib->ms.cache_display_cfg.plane.VTapsChroma;
6678 		CalculateWatermarks_params->VRatio = mode_lib->ms.cache_display_cfg.plane.VRatio;
6679 		CalculateWatermarks_params->VRatioChroma = mode_lib->ms.cache_display_cfg.plane.VRatioChroma;
6680 		CalculateWatermarks_params->HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal;
6681 		CalculateWatermarks_params->VTotal = mode_lib->ms.cache_display_cfg.timing.VTotal;
6682 		CalculateWatermarks_params->VActive = mode_lib->ms.cache_display_cfg.timing.VActive;
6683 		CalculateWatermarks_params->PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock;
6684 		CalculateWatermarks_params->BlendingAndTiming = mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming;
6685 		CalculateWatermarks_params->DPPPerSurface = mode_lib->ms.NoOfDPPThisState;
6686 		CalculateWatermarks_params->BytePerPixelDETY = mode_lib->ms.BytePerPixelInDETY;
6687 		CalculateWatermarks_params->BytePerPixelDETC = mode_lib->ms.BytePerPixelInDETC;
6688 		CalculateWatermarks_params->DSTXAfterScaler = s->DSTXAfterScaler;
6689 		CalculateWatermarks_params->DSTYAfterScaler = s->DSTYAfterScaler;
6690 		CalculateWatermarks_params->WritebackEnable = mode_lib->ms.cache_display_cfg.writeback.WritebackEnable;
6691 		CalculateWatermarks_params->WritebackPixelFormat = mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat;
6692 		CalculateWatermarks_params->WritebackDestinationWidth = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth;
6693 		CalculateWatermarks_params->WritebackDestinationHeight = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight;
6694 		CalculateWatermarks_params->WritebackSourceHeight = mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight;
6695 		CalculateWatermarks_params->UnboundedRequestEnabled = mode_lib->ms.UnboundedRequestEnabledThisState;
6696 		CalculateWatermarks_params->CompressedBufferSizeInkByte = mode_lib->ms.CompressedBufferSizeInkByteThisState;
6697 
6698 		// Output
6699 		CalculateWatermarks_params->Watermark = &s->dummy_watermark; // Watermarks *Watermark
6700 		CalculateWatermarks_params->DRAMClockChangeSupport = &mode_lib->ms.support.DRAMClockChangeSupport[j];
6701 		CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = &s->dummy_single_array[0]; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[]
6702 		CalculateWatermarks_params->SubViewportLinesNeededInMALL = &mode_lib->ms.SubViewportLinesNeededInMALL[j]; // dml_uint_t SubViewportLinesNeededInMALL[]
6703 		CalculateWatermarks_params->FCLKChangeSupport = &mode_lib->ms.support.FCLKChangeSupport[j];
6704 		CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &s->dummy_single[0]; // dml_float_t *MaxActiveFCLKChangeLatencySupported
6705 		CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport[j];
6706 		CalculateWatermarks_params->ActiveDRAMClockChangeLatencyMargin = mode_lib->ms.support.ActiveDRAMClockChangeLatencyMargin;
6707 
6708 		CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(&mode_lib->scratch,
6709 			CalculateWatermarks_params);
6710 
6711 	} // for j
6712 }
6713 
set_vm_row_and_swath_parameters(struct display_mode_lib_st * mode_lib)6714 static noinline_for_stack void set_vm_row_and_swath_parameters(struct display_mode_lib_st *mode_lib)
6715 {
6716 	struct CalculateVMRowAndSwath_params_st *CalculateVMRowAndSwath_params = &mode_lib->scratch.CalculateVMRowAndSwath_params;
6717 	struct dml_core_mode_support_locals_st *s = &mode_lib->scratch.dml_core_mode_support_locals;
6718 
6719 	CalculateVMRowAndSwath_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
6720 	CalculateVMRowAndSwath_params->myPipe = s->SurfParameters;
6721 	CalculateVMRowAndSwath_params->SurfaceSizeInMALL = mode_lib->ms.SurfaceSizeInMALL;
6722 	CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsLuma = mode_lib->ms.ip.dpte_buffer_size_in_pte_reqs_luma;
6723 	CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsChroma = mode_lib->ms.ip.dpte_buffer_size_in_pte_reqs_chroma;
6724 	CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ms.ip.dcc_meta_buffer_size_bytes;
6725 	CalculateVMRowAndSwath_params->UseMALLForStaticScreen = mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen;
6726 	CalculateVMRowAndSwath_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
6727 	CalculateVMRowAndSwath_params->MALLAllocatedForDCN = mode_lib->ms.soc.mall_allocated_for_dcn_mbytes;
6728 	CalculateVMRowAndSwath_params->SwathWidthY = mode_lib->ms.SwathWidthYThisState;
6729 	CalculateVMRowAndSwath_params->SwathWidthC = mode_lib->ms.SwathWidthCThisState;
6730 	CalculateVMRowAndSwath_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
6731 	CalculateVMRowAndSwath_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
6732 	CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
6733 	CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
6734 	CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
6735 	CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
6736 	CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
6737 	CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
6738 	CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = mode_lib->ms.PTEBufferSizeNotExceededPerState;
6739 	CalculateVMRowAndSwath_params->DCCMetaBufferSizeNotExceeded = mode_lib->ms.DCCMetaBufferSizeNotExceededPerState;
6740 	CalculateVMRowAndSwath_params->dpte_row_width_luma_ub = s->dummy_integer_array[0];
6741 	CalculateVMRowAndSwath_params->dpte_row_width_chroma_ub = s->dummy_integer_array[1];
6742 	CalculateVMRowAndSwath_params->dpte_row_height_luma = mode_lib->ms.dpte_row_height;
6743 	CalculateVMRowAndSwath_params->dpte_row_height_chroma = mode_lib->ms.dpte_row_height_chroma;
6744 	CalculateVMRowAndSwath_params->dpte_row_height_linear_luma = s->dummy_integer_array[2]; // VBA_DELTA
6745 	CalculateVMRowAndSwath_params->dpte_row_height_linear_chroma = s->dummy_integer_array[3]; // VBA_DELTA
6746 	CalculateVMRowAndSwath_params->meta_req_width = s->dummy_integer_array[4];
6747 	CalculateVMRowAndSwath_params->meta_req_width_chroma = s->dummy_integer_array[5];
6748 	CalculateVMRowAndSwath_params->meta_req_height = s->dummy_integer_array[6];
6749 	CalculateVMRowAndSwath_params->meta_req_height_chroma = s->dummy_integer_array[7];
6750 	CalculateVMRowAndSwath_params->meta_row_width = s->dummy_integer_array[8];
6751 	CalculateVMRowAndSwath_params->meta_row_width_chroma = s->dummy_integer_array[9];
6752 	CalculateVMRowAndSwath_params->meta_row_height = mode_lib->ms.meta_row_height;
6753 	CalculateVMRowAndSwath_params->meta_row_height_chroma = mode_lib->ms.meta_row_height_chroma;
6754 	CalculateVMRowAndSwath_params->vm_group_bytes = s->dummy_integer_array[10];
6755 	CalculateVMRowAndSwath_params->dpte_group_bytes = mode_lib->ms.dpte_group_bytes;
6756 	CalculateVMRowAndSwath_params->PixelPTEReqWidthY = s->dummy_integer_array[11];
6757 	CalculateVMRowAndSwath_params->PixelPTEReqHeightY = s->dummy_integer_array[12];
6758 	CalculateVMRowAndSwath_params->PTERequestSizeY = s->dummy_integer_array[13];
6759 	CalculateVMRowAndSwath_params->PixelPTEReqWidthC = s->dummy_integer_array[14];
6760 	CalculateVMRowAndSwath_params->PixelPTEReqHeightC = s->dummy_integer_array[15];
6761 	CalculateVMRowAndSwath_params->PTERequestSizeC = s->dummy_integer_array[16];
6762 	CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_l = s->dummy_integer_array[17];
6763 	CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_l = s->dummy_integer_array[18];
6764 	CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_c = s->dummy_integer_array[19];
6765 	CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_c = s->dummy_integer_array[20];
6766 	CalculateVMRowAndSwath_params->PrefetchSourceLinesY = mode_lib->ms.PrefetchLinesYThisState;
6767 	CalculateVMRowAndSwath_params->PrefetchSourceLinesC = mode_lib->ms.PrefetchLinesCThisState;
6768 	CalculateVMRowAndSwath_params->VInitPreFillY = mode_lib->ms.PrefillY;
6769 	CalculateVMRowAndSwath_params->VInitPreFillC = mode_lib->ms.PrefillC;
6770 	CalculateVMRowAndSwath_params->MaxNumSwathY = mode_lib->ms.MaxNumSwY;
6771 	CalculateVMRowAndSwath_params->MaxNumSwathC = mode_lib->ms.MaxNumSwC;
6772 	CalculateVMRowAndSwath_params->meta_row_bw = mode_lib->ms.meta_row_bandwidth_this_state;
6773 	CalculateVMRowAndSwath_params->dpte_row_bw = mode_lib->ms.dpte_row_bandwidth_this_state;
6774 	CalculateVMRowAndSwath_params->PixelPTEBytesPerRow = mode_lib->ms.DPTEBytesPerRowThisState;
6775 	CalculateVMRowAndSwath_params->PDEAndMetaPTEBytesFrame = mode_lib->ms.PDEAndMetaPTEBytesPerFrameThisState;
6776 	CalculateVMRowAndSwath_params->MetaRowByte = mode_lib->ms.MetaRowBytesThisState;
6777 	CalculateVMRowAndSwath_params->use_one_row_for_frame = mode_lib->ms.use_one_row_for_frame_this_state;
6778 	CalculateVMRowAndSwath_params->use_one_row_for_frame_flip = mode_lib->ms.use_one_row_for_frame_flip_this_state;
6779 	CalculateVMRowAndSwath_params->UsesMALLForStaticScreen = s->dummy_boolean_array[0];
6780 	CalculateVMRowAndSwath_params->PTE_BUFFER_MODE = s->dummy_boolean_array[1];
6781 	CalculateVMRowAndSwath_params->BIGK_FRAGMENT_SIZE = s->dummy_integer_array[21];
6782 }
6783 
6784 /// @brief The Mode Support function.
dml_core_mode_support(struct display_mode_lib_st * mode_lib)6785 dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib)
6786 {
6787 	struct dml_core_mode_support_locals_st *s = &mode_lib->scratch.dml_core_mode_support_locals;
6788 	struct UseMinimumDCFCLK_params_st *UseMinimumDCFCLK_params = &mode_lib->scratch.UseMinimumDCFCLK_params;
6789 	struct CalculateSwathAndDETConfiguration_params_st *CalculateSwathAndDETConfiguration_params = &mode_lib->scratch.CalculateSwathAndDETConfiguration_params;
6790 	struct CalculateVMRowAndSwath_params_st *CalculateVMRowAndSwath_params = &mode_lib->scratch.CalculateVMRowAndSwath_params;
6791 
6792 	dml_uint_t j, k, m;
6793 
6794 	mode_lib->ms.num_active_planes = dml_get_num_active_planes(&mode_lib->ms.cache_display_cfg);
6795 	dml_print("DML::%s: num_active_planes = %u\n", __func__, mode_lib->ms.num_active_planes);
6796 
6797 	CalculateMaxDETAndMinCompressedBufferSize(
6798 								mode_lib->ms.ip.config_return_buffer_size_in_kbytes,
6799 								mode_lib->ms.ip.config_return_buffer_segment_size_in_kbytes,
6800 								mode_lib->ms.ip.rob_buffer_size_kbytes,
6801 								mode_lib->ms.ip.max_num_dpp,
6802 								mode_lib->ms.policy.NomDETInKByteOverrideEnable,   // VBA_DELTA
6803 								mode_lib->ms.policy.NomDETInKByteOverrideValue,    // VBA_DELTA
6804 
6805 								/* Output */
6806 								&mode_lib->ms.MaxTotalDETInKByte,
6807 								&mode_lib->ms.NomDETInKByte,
6808 								&mode_lib->ms.MinCompressedBufferSizeInKByte);
6809 
6810 	PixelClockAdjustmentForProgressiveToInterlaceUnit(&mode_lib->ms.cache_display_cfg, mode_lib->ms.ip.ptoi_supported);
6811 
6812 
6813 	/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
6814 
6815 	/*Scale Ratio, taps Support Check*/
6816 	mode_lib->ms.support.ScaleRatioAndTapsSupport = true;
6817 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6818 		if (mode_lib->ms.cache_display_cfg.plane.ScalerEnabled[k] == false
6819 				&& ((mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_64
6820 						&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_32
6821 						&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_16
6822 						&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_mono_16
6823 						&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_mono_8
6824 						&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_rgbe
6825 						&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_rgbe_alpha)
6826 						|| mode_lib->ms.cache_display_cfg.plane.HRatio[k] != 1.0
6827 						|| mode_lib->ms.cache_display_cfg.plane.HTaps[k] != 1.0
6828 						|| mode_lib->ms.cache_display_cfg.plane.VRatio[k] != 1.0
6829 						|| mode_lib->ms.cache_display_cfg.plane.VTaps[k] != 1.0)) {
6830 			mode_lib->ms.support.ScaleRatioAndTapsSupport = false;
6831 		} else if (mode_lib->ms.cache_display_cfg.plane.VTaps[k] < 1.0 || mode_lib->ms.cache_display_cfg.plane.VTaps[k] > 8.0
6832 				|| mode_lib->ms.cache_display_cfg.plane.HTaps[k] < 1.0 || mode_lib->ms.cache_display_cfg.plane.HTaps[k] > 8.0
6833 				|| (mode_lib->ms.cache_display_cfg.plane.HTaps[k] > 1.0 && (mode_lib->ms.cache_display_cfg.plane.HTaps[k] % 2) == 1)
6834 				|| mode_lib->ms.cache_display_cfg.plane.HRatio[k] > mode_lib->ms.ip.max_hscl_ratio
6835 				|| mode_lib->ms.cache_display_cfg.plane.VRatio[k] > mode_lib->ms.ip.max_vscl_ratio
6836 				|| mode_lib->ms.cache_display_cfg.plane.HRatio[k] > mode_lib->ms.cache_display_cfg.plane.HTaps[k]
6837 				|| mode_lib->ms.cache_display_cfg.plane.VRatio[k] > mode_lib->ms.cache_display_cfg.plane.VTaps[k]
6838 				|| (mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_64
6839 					&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_32
6840 					&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_16
6841 					&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_mono_16
6842 					&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_mono_8
6843 					&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_rgbe
6844 					&& (mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k] < 1 || mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k] > 8 || mode_lib->ms.cache_display_cfg.plane.HTapsChroma[k] < 1 || mode_lib->ms.cache_display_cfg.plane.HTapsChroma[k] > 8 ||
6845 						(mode_lib->ms.cache_display_cfg.plane.HTapsChroma[k] > 1 && mode_lib->ms.cache_display_cfg.plane.HTapsChroma[k] % 2 == 1) ||
6846 					mode_lib->ms.cache_display_cfg.plane.HRatioChroma[k] > mode_lib->ms.ip.max_hscl_ratio ||
6847 					mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k] > mode_lib->ms.ip.max_vscl_ratio ||
6848 					mode_lib->ms.cache_display_cfg.plane.HRatioChroma[k] > mode_lib->ms.cache_display_cfg.plane.HTapsChroma[k] ||
6849 					mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k] > mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k]))) {
6850 			mode_lib->ms.support.ScaleRatioAndTapsSupport = false;
6851 		}
6852 	}
6853 
6854 	/*Source Format, Pixel Format and Scan Support Check*/
6855 	mode_lib->ms.support.SourceFormatPixelAndScanSupport = true;
6856 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6857 			if (mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k] == dml_sw_linear && (!(!dml_is_vertical_rotation(mode_lib->ms.cache_display_cfg.plane.SourceScan[k])) || mode_lib->ms.cache_display_cfg.surface.DCCEnable[k] == true)) {
6858 			mode_lib->ms.support.SourceFormatPixelAndScanSupport = false;
6859 		}
6860 	}
6861 
6862 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6863 		CalculateBytePerPixelAndBlockSizes(
6864 								mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k],
6865 								mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k],
6866 
6867 								/* Output */
6868 								&mode_lib->ms.BytePerPixelY[k],
6869 								&mode_lib->ms.BytePerPixelC[k],
6870 								&mode_lib->ms.BytePerPixelInDETY[k],
6871 								&mode_lib->ms.BytePerPixelInDETC[k],
6872 								&mode_lib->ms.Read256BlockHeightY[k],
6873 								&mode_lib->ms.Read256BlockHeightC[k],
6874 								&mode_lib->ms.Read256BlockWidthY[k],
6875 								&mode_lib->ms.Read256BlockWidthC[k],
6876 								&mode_lib->ms.MacroTileHeightY[k],
6877 								&mode_lib->ms.MacroTileHeightC[k],
6878 								&mode_lib->ms.MacroTileWidthY[k],
6879 								&mode_lib->ms.MacroTileWidthC[k]);
6880 	}
6881 
6882 	/*Bandwidth Support Check*/
6883 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6884 		if (!dml_is_vertical_rotation(mode_lib->ms.cache_display_cfg.plane.SourceScan[k])) {
6885 			mode_lib->ms.SwathWidthYSingleDPP[k] = mode_lib->ms.cache_display_cfg.plane.ViewportWidth[k];
6886 			mode_lib->ms.SwathWidthCSingleDPP[k] = mode_lib->ms.cache_display_cfg.plane.ViewportWidthChroma[k];
6887 		} else {
6888 			mode_lib->ms.SwathWidthYSingleDPP[k] = mode_lib->ms.cache_display_cfg.plane.ViewportHeight[k];
6889 			mode_lib->ms.SwathWidthCSingleDPP[k] = mode_lib->ms.cache_display_cfg.plane.ViewportHeightChroma[k];
6890 		}
6891 	}
6892 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6893 		mode_lib->ms.ReadBandwidthLuma[k] = mode_lib->ms.SwathWidthYSingleDPP[k] * dml_ceil(mode_lib->ms.BytePerPixelInDETY[k], 1.0) / (mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * mode_lib->ms.cache_display_cfg.plane.VRatio[k];
6894 		mode_lib->ms.ReadBandwidthChroma[k] = mode_lib->ms.SwathWidthYSingleDPP[k] / 2 * dml_ceil(mode_lib->ms.BytePerPixelInDETC[k], 2.0) / (mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * mode_lib->ms.cache_display_cfg.plane.VRatio[k] / 2.0;
6895 	}
6896 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6897 		if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true
6898 				&& mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[k] == dml_444_64) {
6899 			mode_lib->ms.WriteBandwidth[k] = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k]
6900 					* mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[k]
6901 					/ (mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[k]
6902 							* mode_lib->ms.cache_display_cfg.timing.HTotal[k]
6903 							/ mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * 8.0;
6904 		} else if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
6905 			mode_lib->ms.WriteBandwidth[k] = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k]
6906 					* mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[k]
6907 					/ (mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[k]
6908 							* mode_lib->ms.cache_display_cfg.timing.HTotal[k]
6909 							/ mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * 4.0;
6910 		} else {
6911 			mode_lib->ms.WriteBandwidth[k] = 0.0;
6912 		}
6913 	}
6914 
6915 	/*Writeback Latency support check*/
6916 	mode_lib->ms.support.WritebackLatencySupport = true;
6917 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6918 		if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true &&
6919 			(mode_lib->ms.WriteBandwidth[k] > mode_lib->ms.ip.writeback_interface_buffer_size_kbytes * 1024 / mode_lib->ms.state.writeback_latency_us)) {
6920 			mode_lib->ms.support.WritebackLatencySupport = false;
6921 		}
6922 	}
6923 
6924 	/*Writeback Mode Support Check*/
6925 	s->TotalNumberOfActiveWriteback = 0;
6926 	for (k = 0; k <= (dml_uint_t) mode_lib->ms.num_active_planes - 1; k++) {
6927 		if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
6928 			s->TotalNumberOfActiveWriteback = s->TotalNumberOfActiveWriteback + 1;
6929 		}
6930    }
6931 
6932 	mode_lib->ms.support.EnoughWritebackUnits = 1;
6933 	if (s->TotalNumberOfActiveWriteback > (dml_uint_t) mode_lib->ms.ip.max_num_wb) {
6934 		mode_lib->ms.support.EnoughWritebackUnits = false;
6935 	}
6936 
6937 	/*Writeback Scale Ratio and Taps Support Check*/
6938 	mode_lib->ms.support.WritebackScaleRatioAndTapsSupport = true;
6939 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6940 		if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
6941 			if (mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[k] > mode_lib->ms.ip.writeback_max_hscl_ratio
6942 				|| mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[k] > mode_lib->ms.ip.writeback_max_vscl_ratio
6943 				|| mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[k] < mode_lib->ms.ip.writeback_min_hscl_ratio
6944 				|| mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[k] < mode_lib->ms.ip.writeback_min_vscl_ratio
6945 				|| mode_lib->ms.cache_display_cfg.writeback.WritebackHTaps[k] > (dml_uint_t) mode_lib->ms.ip.writeback_max_hscl_taps
6946 				|| mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[k] > (dml_uint_t) mode_lib->ms.ip.writeback_max_vscl_taps
6947 				|| mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[k] > (dml_uint_t) mode_lib->ms.cache_display_cfg.writeback.WritebackHTaps[k]
6948 				|| mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[k] > (dml_uint_t) mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[k]
6949 				|| (mode_lib->ms.cache_display_cfg.writeback.WritebackHTaps[k] > 2.0 && ((mode_lib->ms.cache_display_cfg.writeback.WritebackHTaps[k] % 2) == 1))) {
6950 				mode_lib->ms.support.WritebackScaleRatioAndTapsSupport = false;
6951 			}
6952 			if (2.0 * mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k] * (mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[k] - 1) * 57 > mode_lib->ms.ip.writeback_line_buffer_buffer_size) {
6953 				mode_lib->ms.support.WritebackScaleRatioAndTapsSupport = false;
6954 			}
6955 		}
6956 	}
6957 
6958 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6959 		CalculateSinglePipeDPPCLKAndSCLThroughput(
6960 				mode_lib->ms.cache_display_cfg.plane.HRatio[k],
6961 				mode_lib->ms.cache_display_cfg.plane.HRatioChroma[k],
6962 				mode_lib->ms.cache_display_cfg.plane.VRatio[k],
6963 				mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k],
6964 				mode_lib->ms.ip.max_dchub_pscl_bw_pix_per_clk,
6965 				mode_lib->ms.ip.max_pscl_lb_bw_pix_per_clk,
6966 				mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
6967 				mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k],
6968 				mode_lib->ms.cache_display_cfg.plane.HTaps[k],
6969 				mode_lib->ms.cache_display_cfg.plane.HTapsChroma[k],
6970 				mode_lib->ms.cache_display_cfg.plane.VTaps[k],
6971 				mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k],
6972 				/* Output */
6973 				&mode_lib->ms.PSCL_FACTOR[k],
6974 				&mode_lib->ms.PSCL_FACTOR_CHROMA[k],
6975 				&mode_lib->ms.MinDPPCLKUsingSingleDPP[k]);
6976 	}
6977 
6978 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
6979 		if (mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k] == dml_sw_linear) {
6980 			s->MaximumSwathWidthSupportLuma = 8192;
6981 		} else if (!dml_is_vertical_rotation(mode_lib->ms.cache_display_cfg.plane.SourceScan[k]) && mode_lib->ms.BytePerPixelC[k] > 0 && mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_rgbe_alpha) {
6982 			s->MaximumSwathWidthSupportLuma = 7680;
6983 		} else if (dml_is_vertical_rotation(mode_lib->ms.cache_display_cfg.plane.SourceScan[k]) && mode_lib->ms.BytePerPixelC[k] > 0 && mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_rgbe_alpha) {
6984 			s->MaximumSwathWidthSupportLuma = 4320;
6985 		} else if (mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_rgbe_alpha) {
6986 			s->MaximumSwathWidthSupportLuma = 3840;
6987 		} else if (dml_is_vertical_rotation(mode_lib->ms.cache_display_cfg.plane.SourceScan[k]) && mode_lib->ms.BytePerPixelY[k] == 8 && mode_lib->ms.cache_display_cfg.surface.DCCEnable[k] == true) {
6988 			s->MaximumSwathWidthSupportLuma = 3072;
6989 		} else {
6990 			s->MaximumSwathWidthSupportLuma = 6144;
6991 		}
6992 
6993        if (mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_420_8 || mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_420_10 || mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_420_12) {
6994 			s->MaximumSwathWidthSupportChroma = (dml_uint_t)(s->MaximumSwathWidthSupportLuma / 2.0);
6995 		} else {
6996 			s->MaximumSwathWidthSupportChroma = s->MaximumSwathWidthSupportLuma;
6997        }
6998 		mode_lib->ms.MaximumSwathWidthInLineBufferLuma = mode_lib->ms.ip.line_buffer_size_bits * dml_max(mode_lib->ms.cache_display_cfg.plane.HRatio[k], 1.0) / mode_lib->ms.cache_display_cfg.plane.LBBitPerPixel[k] /
6999 															(mode_lib->ms.cache_display_cfg.plane.VTaps[k] + dml_max(dml_ceil(mode_lib->ms.cache_display_cfg.plane.VRatio[k], 1.0) - 2, 0.0));
7000 		if (mode_lib->ms.BytePerPixelC[k] == 0.0) {
7001 			mode_lib->ms.MaximumSwathWidthInLineBufferChroma = 0;
7002 		} else {
7003 			mode_lib->ms.MaximumSwathWidthInLineBufferChroma =
7004 							mode_lib->ms.ip.line_buffer_size_bits
7005 									* dml_max(mode_lib->ms.cache_display_cfg.plane.HRatioChroma[k], 1.0)
7006 									/ mode_lib->ms.cache_display_cfg.plane.LBBitPerPixel[k]
7007 									/ (mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k]
7008 									+ dml_max(dml_ceil(mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k], 1.0) - 2, 0.0));
7009 		}
7010 		mode_lib->ms.MaximumSwathWidthLuma[k] = dml_min(s->MaximumSwathWidthSupportLuma, mode_lib->ms.MaximumSwathWidthInLineBufferLuma);
7011 		mode_lib->ms.MaximumSwathWidthChroma[k] = dml_min(s->MaximumSwathWidthSupportChroma, mode_lib->ms.MaximumSwathWidthInLineBufferChroma);
7012 	}
7013 
7014 	/*Number Of DSC Slices*/
7015 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7016 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k &&
7017 			mode_lib->ms.cache_display_cfg.output.DSCEnable[k] != dml_dsc_disable) {
7018 			mode_lib->ms.support.NumberOfDSCSlices[k] = mode_lib->ms.cache_display_cfg.output.DSCSlices[k];
7019 
7020 			if (mode_lib->ms.support.NumberOfDSCSlices[k] == 0) {
7021 				if (mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] > 4800) {
7022 					mode_lib->ms.support.NumberOfDSCSlices[k] = (dml_uint_t)(dml_ceil(mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] / 600, 4));
7023 				} else if (mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] > 2400) {
7024 					mode_lib->ms.support.NumberOfDSCSlices[k] = 8;
7025 				} else if (mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] > 1200) {
7026 					mode_lib->ms.support.NumberOfDSCSlices[k] = 4;
7027 				} else if (mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] > 340) {
7028 					mode_lib->ms.support.NumberOfDSCSlices[k] = 2;
7029 				} else {
7030 					mode_lib->ms.support.NumberOfDSCSlices[k] = 1;
7031 				}
7032 			}
7033 		} else {
7034 			mode_lib->ms.support.NumberOfDSCSlices[k] = 1;
7035 		}
7036 	}
7037 
7038 	CalculateSwathAndDETConfiguration_params->DETSizeOverride = mode_lib->ms.cache_display_cfg.plane.DETSizeOverride;
7039 	CalculateSwathAndDETConfiguration_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
7040 	CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSizeInKByte = mode_lib->ms.ip.config_return_buffer_size_in_kbytes;
7041 	CalculateSwathAndDETConfiguration_params->ROBBufferSizeInKByte = mode_lib->ms.ip.rob_buffer_size_kbytes;
7042 	CalculateSwathAndDETConfiguration_params->MaxTotalDETInKByte = mode_lib->ms.MaxTotalDETInKByte;
7043 	CalculateSwathAndDETConfiguration_params->MinCompressedBufferSizeInKByte = mode_lib->ms.MinCompressedBufferSizeInKByte;
7044 	CalculateSwathAndDETConfiguration_params->PixelChunkSizeInKByte = mode_lib->ms.ip.pixel_chunk_size_kbytes;
7045 	CalculateSwathAndDETConfiguration_params->ForceSingleDPP = 1;
7046 	CalculateSwathAndDETConfiguration_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
7047 	CalculateSwathAndDETConfiguration_params->nomDETInKByte = mode_lib->ms.NomDETInKByte;
7048 	CalculateSwathAndDETConfiguration_params->UseUnboundedRequestingFinal = mode_lib->ms.policy.UseUnboundedRequesting;
7049 	CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSegmentSizeInkByte = mode_lib->ms.ip.config_return_buffer_segment_size_in_kbytes;
7050 	CalculateSwathAndDETConfiguration_params->CompressedBufferSegmentSizeInkByteFinal = mode_lib->ms.ip.compressed_buffer_segment_size_in_kbytes;
7051 	CalculateSwathAndDETConfiguration_params->Output = mode_lib->ms.cache_display_cfg.output.OutputEncoder;
7052 	CalculateSwathAndDETConfiguration_params->ReadBandwidthLuma = mode_lib->ms.ReadBandwidthLuma;
7053 	CalculateSwathAndDETConfiguration_params->ReadBandwidthChroma = mode_lib->ms.ReadBandwidthChroma;
7054 	CalculateSwathAndDETConfiguration_params->MaximumSwathWidthLuma = mode_lib->ms.MaximumSwathWidthLuma;
7055 	CalculateSwathAndDETConfiguration_params->MaximumSwathWidthChroma = mode_lib->ms.MaximumSwathWidthChroma;
7056 	CalculateSwathAndDETConfiguration_params->SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan;
7057 	CalculateSwathAndDETConfiguration_params->ViewportStationary = mode_lib->ms.cache_display_cfg.plane.ViewportStationary;
7058 	CalculateSwathAndDETConfiguration_params->SourcePixelFormat = mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat;
7059 	CalculateSwathAndDETConfiguration_params->SurfaceTiling = mode_lib->ms.cache_display_cfg.surface.SurfaceTiling;
7060 	CalculateSwathAndDETConfiguration_params->ViewportWidth = mode_lib->ms.cache_display_cfg.plane.ViewportWidth;
7061 	CalculateSwathAndDETConfiguration_params->ViewportHeight = mode_lib->ms.cache_display_cfg.plane.ViewportHeight;
7062 	CalculateSwathAndDETConfiguration_params->ViewportXStart = mode_lib->ms.cache_display_cfg.plane.ViewportXStart;
7063 	CalculateSwathAndDETConfiguration_params->ViewportYStart = mode_lib->ms.cache_display_cfg.plane.ViewportYStart;
7064 	CalculateSwathAndDETConfiguration_params->ViewportXStartC = mode_lib->ms.cache_display_cfg.plane.ViewportXStartC;
7065 	CalculateSwathAndDETConfiguration_params->ViewportYStartC = mode_lib->ms.cache_display_cfg.plane.ViewportYStartC;
7066 	CalculateSwathAndDETConfiguration_params->SurfaceWidthY = mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY;
7067 	CalculateSwathAndDETConfiguration_params->SurfaceWidthC = mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC;
7068 	CalculateSwathAndDETConfiguration_params->SurfaceHeightY = mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY;
7069 	CalculateSwathAndDETConfiguration_params->SurfaceHeightC = mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC;
7070 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightY = mode_lib->ms.Read256BlockHeightY;
7071 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightC = mode_lib->ms.Read256BlockHeightC;
7072 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthY = mode_lib->ms.Read256BlockWidthY;
7073 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthC = mode_lib->ms.Read256BlockWidthC;
7074 	CalculateSwathAndDETConfiguration_params->ODMMode = s->dummy_odm_mode;
7075 	CalculateSwathAndDETConfiguration_params->BlendingAndTiming = mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming;
7076 	CalculateSwathAndDETConfiguration_params->BytePerPixY = mode_lib->ms.BytePerPixelY;
7077 	CalculateSwathAndDETConfiguration_params->BytePerPixC = mode_lib->ms.BytePerPixelC;
7078 	CalculateSwathAndDETConfiguration_params->BytePerPixDETY = mode_lib->ms.BytePerPixelInDETY;
7079 	CalculateSwathAndDETConfiguration_params->BytePerPixDETC = mode_lib->ms.BytePerPixelInDETC;
7080 	CalculateSwathAndDETConfiguration_params->HActive = mode_lib->ms.cache_display_cfg.timing.HActive;
7081 	CalculateSwathAndDETConfiguration_params->HRatio = mode_lib->ms.cache_display_cfg.plane.HRatio;
7082 	CalculateSwathAndDETConfiguration_params->HRatioChroma = mode_lib->ms.cache_display_cfg.plane.HRatioChroma;
7083 	CalculateSwathAndDETConfiguration_params->DPPPerSurface = s->dummy_integer_array[0];
7084 	CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = s->dummy_integer_array[1];
7085 	CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = s->dummy_integer_array[2];
7086 	CalculateSwathAndDETConfiguration_params->SwathWidth = s->dummy_integer_array[3];
7087 	CalculateSwathAndDETConfiguration_params->SwathWidthChroma = s->dummy_integer_array[4];
7088 	CalculateSwathAndDETConfiguration_params->SwathHeightY = s->dummy_integer_array[5];
7089 	CalculateSwathAndDETConfiguration_params->SwathHeightC = s->dummy_integer_array[6];
7090 	CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = s->dummy_integer_array[7];
7091 	CalculateSwathAndDETConfiguration_params->DETBufferSizeY = mode_lib->ms.DETBufferSizeY;
7092 	CalculateSwathAndDETConfiguration_params->DETBufferSizeC = mode_lib->ms.DETBufferSizeC;
7093 	CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &s->dummy_boolean[0];
7094 	CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = &s->dummy_integer[2];
7095 	CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_zs = &s->dummy_integer[1];
7096 	CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &s->dummy_integer[0];
7097 	CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = mode_lib->ms.SingleDPPViewportSizeSupportPerSurface;
7098 	CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &s->dummy_boolean[1];
7099 
7100 	CalculateSwathAndDETConfiguration(&mode_lib->scratch,
7101 	CalculateSwathAndDETConfiguration_params); /* dml_bool_t *ViewportSizeSupport */
7102 
7103 	s->MPCCombineMethodAsNeededForPStateChangeAndVoltage = false;
7104 	s->MPCCombineMethodAsPossible = false;
7105 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7106 		if (mode_lib->ms.policy.MPCCombineUse[k] == dml_mpc_as_needed_for_pstate_and_voltage)
7107 			s->MPCCombineMethodAsNeededForPStateChangeAndVoltage = true;
7108 		if (mode_lib->ms.policy.MPCCombineUse[k] == dml_mpc_as_possible)
7109 			s->MPCCombineMethodAsPossible = true;
7110 	}
7111 	mode_lib->ms.support.MPCCombineMethodIncompatible = s->MPCCombineMethodAsNeededForPStateChangeAndVoltage && s->MPCCombineMethodAsPossible;
7112 
7113 	for (j = 0; j < 2; j++) {
7114 		mode_lib->ms.TotalNumberOfActiveDPP[j] = 0;
7115 		mode_lib->ms.support.TotalAvailablePipesSupport[j] = true;
7116 
7117 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7118 			CalculateODMMode(
7119 					mode_lib->ms.ip.maximum_pixels_per_line_per_dsc_unit,
7120 					mode_lib->ms.cache_display_cfg.timing.HActive[k],
7121 					mode_lib->ms.cache_display_cfg.output.OutputEncoder[k],
7122 					mode_lib->ms.cache_display_cfg.output.OutputFormat[k],
7123 					mode_lib->ms.policy.ODMUse[k],
7124 					mode_lib->ms.state.dispclk_mhz,
7125 					mode_lib->ms.max_state.dispclk_mhz,
7126 					false, // DSCEnable
7127 					mode_lib->ms.TotalNumberOfActiveDPP[j],
7128 					mode_lib->ms.ip.max_num_dpp,
7129 					mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
7130 					mode_lib->ms.soc.dcn_downspread_percent,
7131 					mode_lib->ms.ip.dispclk_ramp_margin_percent,
7132 					mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz,
7133 					mode_lib->ms.support.NumberOfDSCSlices[k],
7134 
7135 					/* Output */
7136 					&s->TotalAvailablePipesSupportNoDSC,
7137 					&s->NumberOfDPPNoDSC,
7138 					&s->ODMModeNoDSC,
7139 					&s->RequiredDISPCLKPerSurfaceNoDSC);
7140 
7141 			CalculateODMMode(
7142 					mode_lib->ms.ip.maximum_pixels_per_line_per_dsc_unit,
7143 					mode_lib->ms.cache_display_cfg.timing.HActive[k],
7144 					mode_lib->ms.cache_display_cfg.output.OutputEncoder[k],
7145 					mode_lib->ms.cache_display_cfg.output.OutputFormat[k],
7146 					mode_lib->ms.policy.ODMUse[k],
7147 					mode_lib->ms.state.dispclk_mhz,
7148 					mode_lib->ms.max_state.dispclk_mhz,
7149 					true, // DSCEnable
7150 					mode_lib->ms.TotalNumberOfActiveDPP[j],
7151 					mode_lib->ms.ip.max_num_dpp,
7152 					mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
7153 					mode_lib->ms.soc.dcn_downspread_percent,
7154 					mode_lib->ms.ip.dispclk_ramp_margin_percent,
7155 					mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz,
7156 					mode_lib->ms.support.NumberOfDSCSlices[k],
7157 
7158 					/* Output */
7159 					&s->TotalAvailablePipesSupportDSC,
7160 					&s->NumberOfDPPDSC,
7161 					&s->ODMModeDSC,
7162 					&s->RequiredDISPCLKPerSurfaceDSC);
7163 
7164 			CalculateOutputLink(
7165 					mode_lib->ms.state.phyclk_mhz,
7166 					mode_lib->ms.state.phyclk_d18_mhz,
7167 					mode_lib->ms.state.phyclk_d32_mhz,
7168 					mode_lib->ms.soc.phy_downspread_percent,
7169 					(mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k),
7170 					mode_lib->ms.cache_display_cfg.output.OutputEncoder[k],
7171 					mode_lib->ms.cache_display_cfg.output.OutputFormat[k],
7172 					mode_lib->ms.cache_display_cfg.timing.HTotal[k],
7173 					mode_lib->ms.cache_display_cfg.timing.HActive[k],
7174 					mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k],
7175 					mode_lib->ms.cache_display_cfg.output.ForcedOutputLinkBPP[k],
7176 					mode_lib->ms.cache_display_cfg.output.DSCInputBitPerComponent[k],
7177 					mode_lib->ms.support.NumberOfDSCSlices[k],
7178 					mode_lib->ms.cache_display_cfg.output.AudioSampleRate[k],
7179 					mode_lib->ms.cache_display_cfg.output.AudioSampleLayout[k],
7180 					s->ODMModeNoDSC,
7181 					s->ODMModeDSC,
7182 					mode_lib->ms.cache_display_cfg.output.DSCEnable[k],
7183 					mode_lib->ms.cache_display_cfg.output.OutputLinkDPLanes[k],
7184 					mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k],
7185 
7186 					/* Output */
7187 					&mode_lib->ms.RequiresDSC[k],
7188 					&mode_lib->ms.RequiresFEC[k],
7189 					&mode_lib->ms.OutputBppPerState[k],
7190 					&mode_lib->ms.OutputTypePerState[k], // VBA_DELTA, VBA uses a string to represent type and rate, but DML uses enum, don't want to rely on strng
7191 					&mode_lib->ms.OutputRatePerState[k],
7192 					&mode_lib->ms.RequiredSlots[k]);
7193 
7194 			if (mode_lib->ms.RequiresDSC[k] == false) {
7195 				mode_lib->ms.ODMModePerState[k] = s->ODMModeNoDSC;
7196 				mode_lib->ms.RequiredDISPCLKPerSurface[j][k] = s->RequiredDISPCLKPerSurfaceNoDSC;
7197 				if (!s->TotalAvailablePipesSupportNoDSC)
7198 					mode_lib->ms.support.TotalAvailablePipesSupport[j] = false;
7199 				mode_lib->ms.TotalNumberOfActiveDPP[j] = mode_lib->ms.TotalNumberOfActiveDPP[j] + s->NumberOfDPPNoDSC;
7200 			} else {
7201 				mode_lib->ms.ODMModePerState[k] = s->ODMModeDSC;
7202 				mode_lib->ms.RequiredDISPCLKPerSurface[j][k] = s->RequiredDISPCLKPerSurfaceDSC;
7203 				if (!s->TotalAvailablePipesSupportDSC)
7204 					mode_lib->ms.support.TotalAvailablePipesSupport[j] = false;
7205 				mode_lib->ms.TotalNumberOfActiveDPP[j] = mode_lib->ms.TotalNumberOfActiveDPP[j] + s->NumberOfDPPDSC;
7206 			}
7207 		}
7208 
7209 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7210 			if (mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_4to1) {
7211 				mode_lib->ms.MPCCombine[j][k] = false;
7212 				mode_lib->ms.NoOfDPP[j][k] = 4;
7213 			} else if (mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_2to1) {
7214 				mode_lib->ms.MPCCombine[j][k] = false;
7215 				mode_lib->ms.NoOfDPP[j][k] = 2;
7216 			} else if (mode_lib->ms.policy.MPCCombineUse[k] == dml_mpc_disabled) {
7217 				mode_lib->ms.MPCCombine[j][k] = false;
7218 				mode_lib->ms.NoOfDPP[j][k] = 1;
7219 			} else if (RoundToDFSGranularity(mode_lib->ms.MinDPPCLKUsingSingleDPP[k] * (1 + mode_lib->ms.soc.dcn_downspread_percent / 100),
7220 											1, mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz) <= mode_lib->ms.state.dppclk_mhz &&
7221 											mode_lib->ms.SingleDPPViewportSizeSupportPerSurface[k] == true) {
7222 				mode_lib->ms.MPCCombine[j][k] = false;
7223 				mode_lib->ms.NoOfDPP[j][k] = 1;
7224 			} else if (mode_lib->ms.TotalNumberOfActiveDPP[j] < (dml_uint_t) mode_lib->ms.ip.max_num_dpp) {
7225 				mode_lib->ms.MPCCombine[j][k] = true;
7226 				mode_lib->ms.NoOfDPP[j][k] = 2;
7227 				mode_lib->ms.TotalNumberOfActiveDPP[j] = (dml_uint_t) mode_lib->ms.TotalNumberOfActiveDPP[j] + 1;
7228 			} else {
7229 				mode_lib->ms.MPCCombine[j][k] = false;
7230 				mode_lib->ms.NoOfDPP[j][k] = 1;
7231 				mode_lib->ms.support.TotalAvailablePipesSupport[j] = false;
7232 			}
7233 		}
7234 
7235 		mode_lib->ms.TotalNumberOfSingleDPPSurfaces[j] = 0;
7236 		s->NoChromaOrLinear = true;
7237 		for (k = 0; k < (dml_uint_t) mode_lib->ms.num_active_planes; ++k) {
7238 			if (mode_lib->ms.NoOfDPP[j][k] == 1)
7239 				mode_lib->ms.TotalNumberOfSingleDPPSurfaces[j] = mode_lib->ms.TotalNumberOfSingleDPPSurfaces[j] + 1;
7240 			if (mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_420_8
7241 					|| mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_420_10
7242 					|| mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_420_12
7243 					|| mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] == dml_rgbe_alpha
7244 					|| mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k] == dml_sw_linear) {
7245 				s->NoChromaOrLinear = false;
7246 			}
7247 		}
7248 
7249 		if (j == 1 && !UnboundedRequest(mode_lib->ms.policy.UseUnboundedRequesting,
7250 				mode_lib->ms.TotalNumberOfActiveDPP[j], s->NoChromaOrLinear,
7251 				mode_lib->ms.cache_display_cfg.output.OutputEncoder[0])) {
7252 			while (!(mode_lib->ms.TotalNumberOfActiveDPP[j] >= (dml_uint_t) mode_lib->ms.ip.max_num_dpp || mode_lib->ms.TotalNumberOfSingleDPPSurfaces[j] == 0)) {
7253 				s->BWOfNonCombinedSurfaceOfMaximumBandwidth = 0;
7254 				s->NumberOfNonCombinedSurfaceOfMaximumBandwidth = 0;
7255 				for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7256 					if (mode_lib->ms.policy.MPCCombineUse[k] != dml_mpc_disabled && mode_lib->ms.policy.MPCCombineUse[k] != dml_mpc_as_needed_for_voltage &&
7257 						mode_lib->ms.ReadBandwidthLuma[k] + mode_lib->ms.ReadBandwidthChroma[k] > s->BWOfNonCombinedSurfaceOfMaximumBandwidth &&
7258 						(mode_lib->ms.ODMModePerState[k] != dml_odm_mode_combine_2to1 && mode_lib->ms.ODMModePerState[k] != dml_odm_mode_combine_4to1) &&
7259 						mode_lib->ms.MPCCombine[j][k] == false) {
7260 						s->BWOfNonCombinedSurfaceOfMaximumBandwidth = mode_lib->ms.ReadBandwidthLuma[k] + mode_lib->ms.ReadBandwidthChroma[k];
7261 						s->NumberOfNonCombinedSurfaceOfMaximumBandwidth = k;
7262 					}
7263 				}
7264 				mode_lib->ms.MPCCombine[j][s->NumberOfNonCombinedSurfaceOfMaximumBandwidth] = true;
7265 				mode_lib->ms.NoOfDPP[j][s->NumberOfNonCombinedSurfaceOfMaximumBandwidth] = 2;
7266 				mode_lib->ms.TotalNumberOfActiveDPP[j] = mode_lib->ms.TotalNumberOfActiveDPP[j] + 1;
7267 				mode_lib->ms.TotalNumberOfSingleDPPSurfaces[j] = mode_lib->ms.TotalNumberOfSingleDPPSurfaces[j] - 1;
7268 			}
7269 		}
7270 
7271 		//DISPCLK/DPPCLK
7272 		mode_lib->ms.WritebackRequiredDISPCLK = 0;
7273 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7274 			if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k]) {
7275 				mode_lib->ms.WritebackRequiredDISPCLK = dml_max(mode_lib->ms.WritebackRequiredDISPCLK,
7276 																	CalculateWriteBackDISPCLK(mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[k],
7277 																							mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
7278 																							mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[k],
7279 																							mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[k],
7280 																							mode_lib->ms.cache_display_cfg.writeback.WritebackHTaps[k],
7281 																							mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[k],
7282 																							mode_lib->ms.cache_display_cfg.writeback.WritebackSourceWidth[k],
7283 																							mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k],
7284 																							mode_lib->ms.cache_display_cfg.timing.HTotal[k],
7285 																							mode_lib->ms.ip.writeback_line_buffer_buffer_size,
7286 																							mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz));
7287 			}
7288 		}
7289 
7290 		 mode_lib->ms.RequiredDISPCLK[j] = mode_lib->ms.WritebackRequiredDISPCLK;
7291 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7292 			mode_lib->ms.RequiredDISPCLK[j] = dml_max(mode_lib->ms.RequiredDISPCLK[j], mode_lib->ms.RequiredDISPCLKPerSurface[j][k]);
7293 		}
7294 
7295 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7296 			mode_lib->ms.NoOfDPPThisState[k] = mode_lib->ms.NoOfDPP[j][k];
7297 		}
7298 
7299 		CalculateDPPCLK(mode_lib->ms.num_active_planes,
7300 					mode_lib->ms.soc.dcn_downspread_percent,
7301 					mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz,
7302 					mode_lib->ms.MinDPPCLKUsingSingleDPP,
7303 					mode_lib->ms.NoOfDPPThisState,
7304 					/* Output */
7305 					&mode_lib->ms.GlobalDPPCLK,
7306 					mode_lib->ms.RequiredDPPCLKThisState);
7307 
7308 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7309 			mode_lib->ms.RequiredDPPCLKPerSurface[j][k] = mode_lib->ms.RequiredDPPCLKThisState[k];
7310 		}
7311 
7312 		mode_lib->ms.support.DISPCLK_DPPCLK_Support[j] = !((mode_lib->ms.RequiredDISPCLK[j] > mode_lib->ms.state.dispclk_mhz) || (mode_lib->ms.GlobalDPPCLK > mode_lib->ms.state.dppclk_mhz));
7313 
7314 		if (mode_lib->ms.TotalNumberOfActiveDPP[j] > (dml_uint_t) mode_lib->ms.ip.max_num_dpp) {
7315 			mode_lib->ms.support.TotalAvailablePipesSupport[j] = false;
7316 		}
7317 	} // j
7318 
7319 	/* Total Available OTG, HDMIFRL, DP Support Check */
7320 	s->TotalNumberOfActiveOTG = 0;
7321 	s->TotalNumberOfActiveHDMIFRL = 0;
7322 	s->TotalNumberOfActiveDP2p0 = 0;
7323 	s->TotalNumberOfActiveDP2p0Outputs = 0;
7324 
7325 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7326 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k) {
7327 			s->TotalNumberOfActiveOTG = s->TotalNumberOfActiveOTG + 1;
7328 			if (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl)
7329 				s->TotalNumberOfActiveHDMIFRL = s->TotalNumberOfActiveHDMIFRL + 1;
7330 			if (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp2p0) {
7331 				s->TotalNumberOfActiveDP2p0 = s->TotalNumberOfActiveDP2p0 + 1;
7332 				if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[k] == k || mode_lib->ms.cache_display_cfg.output.OutputMultistreamEn[k] == false) {
7333 					s->TotalNumberOfActiveDP2p0Outputs = s->TotalNumberOfActiveDP2p0Outputs + 1;
7334 				}
7335 			}
7336 		}
7337 	}
7338 
7339 	mode_lib->ms.support.NumberOfOTGSupport      = (s->TotalNumberOfActiveOTG <= (dml_uint_t) mode_lib->ms.ip.max_num_otg);
7340 	mode_lib->ms.support.NumberOfHDMIFRLSupport  = (s->TotalNumberOfActiveHDMIFRL <= (dml_uint_t) mode_lib->ms.ip.max_num_hdmi_frl_outputs);
7341 	mode_lib->ms.support.NumberOfDP2p0Support    = (s->TotalNumberOfActiveDP2p0 <= (dml_uint_t) mode_lib->ms.ip.max_num_dp2p0_streams && s->TotalNumberOfActiveDP2p0Outputs <= (dml_uint_t) mode_lib->ms.ip.max_num_dp2p0_outputs);
7342 
7343 	/* Display IO and DSC Support Check */
7344 	mode_lib->ms.support.NonsupportedDSCInputBPC = false;
7345 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
7346 		if (mode_lib->ms.cache_display_cfg.output.OutputDisabled[k] == false &&
7347 			!(mode_lib->ms.cache_display_cfg.output.DSCInputBitPerComponent[k] == 12.0
7348 				|| mode_lib->ms.cache_display_cfg.output.DSCInputBitPerComponent[k] == 10.0
7349 				|| mode_lib->ms.cache_display_cfg.output.DSCInputBitPerComponent[k] == 8.0
7350 				|| mode_lib->ms.cache_display_cfg.output.DSCInputBitPerComponent[k] > (dml_uint_t) mode_lib->ms.ip.maximum_dsc_bits_per_component
7351 				)) {
7352 			mode_lib->ms.support.NonsupportedDSCInputBPC = true;
7353 		}
7354 	}
7355 
7356 	mode_lib->ms.support.ExceededMultistreamSlots = false;
7357 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7358 		if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[k] == k) {
7359 			s->TotalSlots = mode_lib->ms.RequiredSlots[k];
7360 			for (j = 0; j < mode_lib->ms.num_active_planes; ++j) {
7361 				if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[j] == k)
7362 					s->TotalSlots = s->TotalSlots + mode_lib->ms.RequiredSlots[j];
7363 			}
7364 			if (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp && s->TotalSlots > 63)
7365 				mode_lib->ms.support.ExceededMultistreamSlots = true;
7366 			if (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp2p0 && s->TotalSlots > 64)
7367 				mode_lib->ms.support.ExceededMultistreamSlots = true;
7368 		}
7369 	}
7370 	mode_lib->ms.support.LinkCapacitySupport = true;
7371 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7372 		if (mode_lib->ms.cache_display_cfg.output.OutputDisabled[k] == false &&
7373 			mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k && (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp2p0 || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_edp ||
7374 			mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmi || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl) && mode_lib->ms.OutputBppPerState[k] == 0) {
7375 			mode_lib->ms.support.LinkCapacitySupport = false;
7376 		}
7377 	}
7378 
7379 	mode_lib->ms.support.P2IWith420 = false;
7380 	mode_lib->ms.support.DSCOnlyIfNecessaryWithBPP = false;
7381 	mode_lib->ms.support.DSC422NativeNotSupported = false;
7382 	mode_lib->ms.support.LinkRateDoesNotMatchDPVersion = false;
7383 	mode_lib->ms.support.LinkRateForMultistreamNotIndicated = false;
7384 	mode_lib->ms.support.BPPForMultistreamNotIndicated = false;
7385 	mode_lib->ms.support.MultistreamWithHDMIOreDP = false;
7386 	mode_lib->ms.support.MSOOrODMSplitWithNonDPLink = false;
7387 	mode_lib->ms.support.NotEnoughLanesForMSO = false;
7388 
7389 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7390 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k && (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp2p0 || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_edp ||
7391 														mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmi || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl)) {
7392 			if (mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_420 && mode_lib->ms.cache_display_cfg.timing.Interlace[k] == 1 && mode_lib->ms.ip.ptoi_supported == true)
7393 				mode_lib->ms.support.P2IWith420 = true;
7394 
7395 			if (mode_lib->ms.cache_display_cfg.output.DSCEnable[k] == dml_dsc_enable_if_necessary && mode_lib->ms.cache_display_cfg.output.ForcedOutputLinkBPP[k] != 0)
7396 				mode_lib->ms.support.DSCOnlyIfNecessaryWithBPP = true;
7397 			if ((mode_lib->ms.cache_display_cfg.output.DSCEnable[k] == dml_dsc_enable || mode_lib->ms.cache_display_cfg.output.DSCEnable[k] == dml_dsc_enable_if_necessary) && mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_n422 && !mode_lib->ms.ip.dsc422_native_support)
7398 				mode_lib->ms.support.DSC422NativeNotSupported = true;
7399 
7400 			if (((mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k] == dml_dp_rate_hbr || mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k] == dml_dp_rate_hbr2 || mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k] == dml_dp_rate_hbr3) &&
7401 					mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] != dml_dp && mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] != dml_edp) ||
7402 					((mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k] == dml_dp_rate_uhbr10 || mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k] == dml_dp_rate_uhbr13p5 || mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k] == dml_dp_rate_uhbr20) &&
7403 					mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] != dml_dp2p0))
7404 				mode_lib->ms.support.LinkRateDoesNotMatchDPVersion = true;
7405 
7406 			if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamEn[k] == 1) {
7407 				if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[k] == k && mode_lib->ms.cache_display_cfg.output.OutputLinkDPRate[k] == dml_dp_rate_na)
7408 					mode_lib->ms.support.LinkRateForMultistreamNotIndicated = true;
7409 				if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[k] == k && mode_lib->ms.cache_display_cfg.output.ForcedOutputLinkBPP[k] == 0)
7410 					mode_lib->ms.support.BPPForMultistreamNotIndicated = true;
7411 				for (j = 0; j < mode_lib->ms.num_active_planes; ++j) {
7412 					if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[k] == j && mode_lib->ms.cache_display_cfg.output.ForcedOutputLinkBPP[k] == 0)
7413 						mode_lib->ms.support.BPPForMultistreamNotIndicated = true;
7414 				}
7415 			}
7416 
7417 			if ((mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_edp || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmi || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl)) {
7418 				if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamEn[k] == 1 && mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[k] == k)
7419 					mode_lib->ms.support.MultistreamWithHDMIOreDP = true;
7420 				for (j = 0; j < mode_lib->ms.num_active_planes; ++j) {
7421 					if (mode_lib->ms.cache_display_cfg.output.OutputMultistreamEn[k] == 1 && mode_lib->ms.cache_display_cfg.output.OutputMultistreamId[k] == j)
7422 						mode_lib->ms.support.MultistreamWithHDMIOreDP = true;
7423 				}
7424 			}
7425 			if (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] != dml_dp && (mode_lib->ms.policy.ODMUse[k] == dml_odm_use_policy_split_1to2 ||
7426 				mode_lib->ms.policy.ODMUse[k] == dml_odm_use_policy_mso_1to2 || mode_lib->ms.policy.ODMUse[k] == dml_odm_use_policy_mso_1to4))
7427 				mode_lib->ms.support.MSOOrODMSplitWithNonDPLink = true;
7428 
7429 			if ((mode_lib->ms.policy.ODMUse[k] == dml_odm_use_policy_mso_1to2 && mode_lib->ms.cache_display_cfg.output.OutputLinkDPLanes[k] < 2) ||
7430 				(mode_lib->ms.policy.ODMUse[k] == dml_odm_use_policy_mso_1to4 && mode_lib->ms.cache_display_cfg.output.OutputLinkDPLanes[k] < 4))
7431 				mode_lib->ms.support.NotEnoughLanesForMSO = true;
7432 		}
7433 	}
7434 
7435 	mode_lib->ms.support.DTBCLKRequiredMoreThanSupported = false;
7436 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7437 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k &&
7438 				mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl &&
7439 				RequiredDTBCLK(
7440 							mode_lib->ms.RequiresDSC[k],
7441 							mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k],
7442 							mode_lib->ms.cache_display_cfg.output.OutputFormat[k],
7443 							mode_lib->ms.OutputBppPerState[k],
7444 							mode_lib->ms.support.NumberOfDSCSlices[k],
7445 							mode_lib->ms.cache_display_cfg.timing.HTotal[k],
7446 							mode_lib->ms.cache_display_cfg.timing.HActive[k],
7447 							mode_lib->ms.cache_display_cfg.output.AudioSampleRate[k],
7448 							mode_lib->ms.cache_display_cfg.output.AudioSampleLayout[k]) > mode_lib->ms.state.dtbclk_mhz) {
7449 								mode_lib->ms.support.DTBCLKRequiredMoreThanSupported = true;
7450 							}
7451 	}
7452 
7453 	mode_lib->ms.support.ODMCombineTwoToOneSupportCheckOK = true;
7454 	mode_lib->ms.support.ODMCombineFourToOneSupportCheckOK = true;
7455 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7456 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k && mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_2to1 && mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmi) {
7457 			mode_lib->ms.support.ODMCombineTwoToOneSupportCheckOK = false;
7458 		}
7459 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k && mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_4to1 && (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp ||
7460 			mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_edp || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmi)) {
7461 			mode_lib->ms.support.ODMCombineFourToOneSupportCheckOK = false;
7462 		}
7463 	}
7464 
7465 	mode_lib->ms.support.DSCCLKRequiredMoreThanSupported = false;
7466 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
7467 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k) {
7468 			if (mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp ||
7469 				mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_dp2p0 ||
7470 				mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_edp ||
7471 				mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl) {
7472 				if (mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_420) {
7473 					s->DSCFormatFactor = 2;
7474 				} else if (mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_444) {
7475 					s->DSCFormatFactor = 1;
7476 				} else if (mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_n422 || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl) {
7477 					s->DSCFormatFactor = 2;
7478 				} else {
7479 					s->DSCFormatFactor = 1;
7480 				}
7481 #ifdef __DML_VBA_DEBUG__
7482 				dml_print("DML::%s: k=%u, RequiresDSC = %u\n",  __func__, k, mode_lib->ms.RequiresDSC[k]);
7483 #endif
7484 				if (mode_lib->ms.RequiresDSC[k] == true) {
7485 					if (mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_4to1) {
7486 						if (mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] / 12.0 / (dml_float_t)s->DSCFormatFactor > (1.0 - mode_lib->ms.soc.dcn_downspread_percent / 100.0) * mode_lib->ms.state.dscclk_mhz) {
7487 #ifdef __DML_VBA_DEBUG__
7488 							dml_print("DML::%s: k=%u, PixelClockBackEnd     = %f\n",  __func__, k, mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k]);
7489 							dml_print("DML::%s: k=%u, DSCCLKPerState        = %f\n",  __func__, k, mode_lib->ms.state.dscclk_mhz);
7490 							dml_print("DML::%s: k=%u, DSCFormatFactor       = %u\n",  __func__, k, s->DSCFormatFactor);
7491 #endif
7492 							mode_lib->ms.support.DSCCLKRequiredMoreThanSupported = true;
7493 						}
7494 					} else if (mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_2to1) {
7495 						if (mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] / 6.0 / (dml_float_t)s->DSCFormatFactor > (1.0 - mode_lib->ms.soc.dcn_downspread_percent / 100.0) * mode_lib->ms.state.dscclk_mhz) {
7496 							mode_lib->ms.support.DSCCLKRequiredMoreThanSupported = true;
7497 						}
7498 					} else {
7499 						if (mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] / 3.0 / (dml_float_t)s->DSCFormatFactor > (1.0 - mode_lib->ms.soc.dcn_downspread_percent / 100.0) * mode_lib->ms.state.dscclk_mhz) {
7500 							mode_lib->ms.support.DSCCLKRequiredMoreThanSupported = true;
7501 						}
7502 					}
7503 				}
7504 			}
7505 		}
7506 	}
7507 #ifdef __DML_VBA_DEBUG__
7508 	dml_print("DML::%s: DSCCLKRequiredMoreThanSupported = %u\n",  __func__, mode_lib->ms.support.DSCCLKRequiredMoreThanSupported);
7509 #endif
7510 
7511 	/* Check DSC Unit and Slices Support */
7512 	mode_lib->ms.support.NotEnoughDSCUnits = false;
7513 	mode_lib->ms.support.NotEnoughDSCSlices = false;
7514 	s->TotalDSCUnitsRequired = 0;
7515 	mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport = true;
7516 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7517 		if (mode_lib->ms.RequiresDSC[k] == true) {
7518 			if (mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_4to1) {
7519 				if (mode_lib->ms.cache_display_cfg.timing.HActive[k] > 4 * (dml_uint_t) mode_lib->ms.ip.maximum_pixels_per_line_per_dsc_unit)
7520 					mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport = false;
7521 				s->TotalDSCUnitsRequired = s->TotalDSCUnitsRequired + 4;
7522 				if (mode_lib->ms.support.NumberOfDSCSlices[k] > 16)
7523 					mode_lib->ms.support.NotEnoughDSCSlices = true;
7524 			} else if (mode_lib->ms.ODMModePerState[k] == dml_odm_mode_combine_2to1) {
7525 				if (mode_lib->ms.cache_display_cfg.timing.HActive[k] > 2 * (dml_uint_t) mode_lib->ms.ip.maximum_pixels_per_line_per_dsc_unit)
7526 					mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport = false;
7527 				s->TotalDSCUnitsRequired = s->TotalDSCUnitsRequired + 2;
7528 				if (mode_lib->ms.support.NumberOfDSCSlices[k] > 8)
7529 					mode_lib->ms.support.NotEnoughDSCSlices = true;
7530 			} else {
7531 				if (mode_lib->ms.cache_display_cfg.timing.HActive[k] > (dml_uint_t) mode_lib->ms.ip.maximum_pixels_per_line_per_dsc_unit)
7532 					mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport = false;
7533 				s->TotalDSCUnitsRequired = s->TotalDSCUnitsRequired + 1;
7534 				if (mode_lib->ms.support.NumberOfDSCSlices[k] > 4)
7535 					mode_lib->ms.support.NotEnoughDSCSlices = true;
7536 			}
7537 		}
7538 	}
7539    if (s->TotalDSCUnitsRequired > (dml_uint_t) mode_lib->ms.ip.num_dsc) {
7540 		mode_lib->ms.support.NotEnoughDSCUnits = true;
7541 	}
7542 
7543 	/*DSC Delay per state*/
7544 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7545 		mode_lib->ms.DSCDelayPerState[k] = DSCDelayRequirement(mode_lib->ms.RequiresDSC[k],
7546 													mode_lib->ms.ODMModePerState[k],
7547 													mode_lib->ms.cache_display_cfg.output.DSCInputBitPerComponent[k],
7548 													mode_lib->ms.OutputBppPerState[k],
7549 													mode_lib->ms.cache_display_cfg.timing.HActive[k],
7550 													mode_lib->ms.cache_display_cfg.timing.HTotal[k],
7551 													mode_lib->ms.support.NumberOfDSCSlices[k],
7552 													mode_lib->ms.cache_display_cfg.output.OutputFormat[k],
7553 													mode_lib->ms.cache_display_cfg.output.OutputEncoder[k],
7554 													mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
7555 													mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k]);
7556 	}
7557 
7558 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
7559 		for (m = 0; m <= mode_lib->ms.num_active_planes - 1; m++) {
7560 			for (j = 0; j <= mode_lib->ms.num_active_planes - 1; j++) {
7561 				if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == m && mode_lib->ms.RequiresDSC[m] == true) {
7562 					mode_lib->ms.DSCDelayPerState[k] = mode_lib->ms.DSCDelayPerState[m];
7563 				}
7564 			}
7565 		}
7566 	}
7567 
7568 	//Calculate Swath, DET Configuration, DCFCLKDeepSleep
7569 	//
7570 	for (j = 0; j < 2; ++j) {
7571 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7572 			mode_lib->ms.RequiredDPPCLKThisState[k] = mode_lib->ms.RequiredDPPCLKPerSurface[j][k];
7573 			mode_lib->ms.NoOfDPPThisState[k] = mode_lib->ms.NoOfDPP[j][k];
7574 			mode_lib->ms.ODMModeThisState[k] = mode_lib->ms.ODMModePerState[k];
7575 		}
7576 
7577 		CalculateSwathAndDETConfiguration_params->DETSizeOverride = mode_lib->ms.cache_display_cfg.plane.DETSizeOverride;
7578 		CalculateSwathAndDETConfiguration_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
7579 		CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSizeInKByte = mode_lib->ms.ip.config_return_buffer_size_in_kbytes;
7580 		CalculateSwathAndDETConfiguration_params->ROBBufferSizeInKByte = mode_lib->ms.ip.rob_buffer_size_kbytes;
7581 		CalculateSwathAndDETConfiguration_params->MaxTotalDETInKByte = mode_lib->ms.MaxTotalDETInKByte;
7582 		CalculateSwathAndDETConfiguration_params->MinCompressedBufferSizeInKByte = mode_lib->ms.MinCompressedBufferSizeInKByte;
7583 		CalculateSwathAndDETConfiguration_params->PixelChunkSizeInKByte = mode_lib->ms.ip.pixel_chunk_size_kbytes;
7584 		CalculateSwathAndDETConfiguration_params->ForceSingleDPP = false;
7585 		CalculateSwathAndDETConfiguration_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
7586 		CalculateSwathAndDETConfiguration_params->nomDETInKByte = mode_lib->ms.NomDETInKByte;
7587 		CalculateSwathAndDETConfiguration_params->UseUnboundedRequestingFinal = mode_lib->ms.policy.UseUnboundedRequesting;
7588 		CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSegmentSizeInkByte = mode_lib->ms.ip.config_return_buffer_segment_size_in_kbytes;
7589 		CalculateSwathAndDETConfiguration_params->CompressedBufferSegmentSizeInkByteFinal = mode_lib->ms.ip.compressed_buffer_segment_size_in_kbytes;
7590 		CalculateSwathAndDETConfiguration_params->Output = mode_lib->ms.cache_display_cfg.output.OutputEncoder;
7591 		CalculateSwathAndDETConfiguration_params->ReadBandwidthLuma = mode_lib->ms.ReadBandwidthLuma;
7592 		CalculateSwathAndDETConfiguration_params->ReadBandwidthChroma = mode_lib->ms.ReadBandwidthChroma;
7593 		CalculateSwathAndDETConfiguration_params->MaximumSwathWidthLuma = mode_lib->ms.MaximumSwathWidthLuma;
7594 		CalculateSwathAndDETConfiguration_params->MaximumSwathWidthChroma = mode_lib->ms.MaximumSwathWidthChroma;
7595 		CalculateSwathAndDETConfiguration_params->SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan;
7596 		CalculateSwathAndDETConfiguration_params->ViewportStationary = mode_lib->ms.cache_display_cfg.plane.ViewportStationary;
7597 		CalculateSwathAndDETConfiguration_params->SourcePixelFormat = mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat;
7598 		CalculateSwathAndDETConfiguration_params->SurfaceTiling = mode_lib->ms.cache_display_cfg.surface.SurfaceTiling;
7599 		CalculateSwathAndDETConfiguration_params->ViewportWidth = mode_lib->ms.cache_display_cfg.plane.ViewportWidth;
7600 		CalculateSwathAndDETConfiguration_params->ViewportHeight = mode_lib->ms.cache_display_cfg.plane.ViewportHeight;
7601 		CalculateSwathAndDETConfiguration_params->ViewportXStart = mode_lib->ms.cache_display_cfg.plane.ViewportXStart;
7602 		CalculateSwathAndDETConfiguration_params->ViewportYStart = mode_lib->ms.cache_display_cfg.plane.ViewportYStart;
7603 		CalculateSwathAndDETConfiguration_params->ViewportXStartC = mode_lib->ms.cache_display_cfg.plane.ViewportXStartC;
7604 		CalculateSwathAndDETConfiguration_params->ViewportYStartC = mode_lib->ms.cache_display_cfg.plane.ViewportYStartC;
7605 		CalculateSwathAndDETConfiguration_params->SurfaceWidthY = mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY;
7606 		CalculateSwathAndDETConfiguration_params->SurfaceWidthC = mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC;
7607 		CalculateSwathAndDETConfiguration_params->SurfaceHeightY = mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY;
7608 		CalculateSwathAndDETConfiguration_params->SurfaceHeightC = mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC;
7609 		CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightY = mode_lib->ms.Read256BlockHeightY;
7610 		CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightC = mode_lib->ms.Read256BlockHeightC;
7611 		CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthY = mode_lib->ms.Read256BlockWidthY;
7612 		CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthC = mode_lib->ms.Read256BlockWidthC;
7613 		CalculateSwathAndDETConfiguration_params->ODMMode = mode_lib->ms.ODMModeThisState;
7614 		CalculateSwathAndDETConfiguration_params->BlendingAndTiming = mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming;
7615 		CalculateSwathAndDETConfiguration_params->BytePerPixY = mode_lib->ms.BytePerPixelY;
7616 		CalculateSwathAndDETConfiguration_params->BytePerPixC = mode_lib->ms.BytePerPixelC;
7617 		CalculateSwathAndDETConfiguration_params->BytePerPixDETY = mode_lib->ms.BytePerPixelInDETY;
7618 		CalculateSwathAndDETConfiguration_params->BytePerPixDETC = mode_lib->ms.BytePerPixelInDETC;
7619 		CalculateSwathAndDETConfiguration_params->HActive = mode_lib->ms.cache_display_cfg.timing.HActive;
7620 		CalculateSwathAndDETConfiguration_params->HRatio = mode_lib->ms.cache_display_cfg.plane.HRatio;
7621 		CalculateSwathAndDETConfiguration_params->HRatioChroma = mode_lib->ms.cache_display_cfg.plane.HRatioChroma;
7622 		CalculateSwathAndDETConfiguration_params->DPPPerSurface = mode_lib->ms.NoOfDPPThisState;
7623 		CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = mode_lib->ms.swath_width_luma_ub_this_state;
7624 		CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = mode_lib->ms.swath_width_chroma_ub_this_state;
7625 		CalculateSwathAndDETConfiguration_params->SwathWidth = mode_lib->ms.SwathWidthYThisState;
7626 		CalculateSwathAndDETConfiguration_params->SwathWidthChroma = mode_lib->ms.SwathWidthCThisState;
7627 		CalculateSwathAndDETConfiguration_params->SwathHeightY = mode_lib->ms.SwathHeightYThisState;
7628 		CalculateSwathAndDETConfiguration_params->SwathHeightC = mode_lib->ms.SwathHeightCThisState;
7629 		CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = mode_lib->ms.DETBufferSizeInKByteThisState;
7630 		CalculateSwathAndDETConfiguration_params->DETBufferSizeY = mode_lib->ms.DETBufferSizeYThisState;
7631 		CalculateSwathAndDETConfiguration_params->DETBufferSizeC = mode_lib->ms.DETBufferSizeCThisState;
7632 		CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &mode_lib->ms.UnboundedRequestEnabledThisState;
7633 		CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = &s->dummy_integer[2];
7634 		CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_zs = &s->dummy_integer[1];
7635 		CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &mode_lib->ms.CompressedBufferSizeInkByteThisState;
7636 		CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = s->dummy_boolean_array[0];
7637 		CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &mode_lib->ms.support.ViewportSizeSupport[j];
7638 
7639 		CalculateSwathAndDETConfiguration(&mode_lib->scratch,
7640 		CalculateSwathAndDETConfiguration_params);
7641 
7642 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7643 			mode_lib->ms.swath_width_luma_ub_all_states[j][k] = mode_lib->ms.swath_width_luma_ub_this_state[k];
7644 			mode_lib->ms.swath_width_chroma_ub_all_states[j][k] = mode_lib->ms.swath_width_chroma_ub_this_state[k];
7645 			mode_lib->ms.SwathWidthYAllStates[j][k] = mode_lib->ms.SwathWidthYThisState[k];
7646 			mode_lib->ms.SwathWidthCAllStates[j][k] = mode_lib->ms.SwathWidthCThisState[k];
7647 			mode_lib->ms.SwathHeightYAllStates[j][k] = mode_lib->ms.SwathHeightYThisState[k];
7648 			mode_lib->ms.SwathHeightCAllStates[j][k] = mode_lib->ms.SwathHeightCThisState[k];
7649 			mode_lib->ms.UnboundedRequestEnabledAllStates[j] = mode_lib->ms.UnboundedRequestEnabledThisState;
7650 			mode_lib->ms.CompressedBufferSizeInkByteAllStates[j] = mode_lib->ms.CompressedBufferSizeInkByteThisState;
7651 			mode_lib->ms.DETBufferSizeInKByteAllStates[j][k] = mode_lib->ms.DETBufferSizeInKByteThisState[k];
7652 			mode_lib->ms.DETBufferSizeYAllStates[j][k] = mode_lib->ms.DETBufferSizeYThisState[k];
7653 			mode_lib->ms.DETBufferSizeCAllStates[j][k] = mode_lib->ms.DETBufferSizeCThisState[k];
7654 		}
7655 	}
7656 
7657 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7658 		mode_lib->ms.cursor_bw[k] = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k] * mode_lib->ms.cache_display_cfg.plane.CursorWidth[k] * mode_lib->ms.cache_display_cfg.plane.CursorBPP[k] / 8.0 / (mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * mode_lib->ms.cache_display_cfg.plane.VRatio[k];
7659 	}
7660 
7661 	CalculateSurfaceSizeInMall(
7662 			mode_lib->ms.num_active_planes,
7663 			mode_lib->ms.soc.mall_allocated_for_dcn_mbytes,
7664 			mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen,
7665 			mode_lib->ms.cache_display_cfg.surface.DCCEnable,
7666 			mode_lib->ms.cache_display_cfg.plane.ViewportStationary,
7667 			mode_lib->ms.cache_display_cfg.plane.ViewportXStart,
7668 			mode_lib->ms.cache_display_cfg.plane.ViewportYStart,
7669 			mode_lib->ms.cache_display_cfg.plane.ViewportXStartC,
7670 			mode_lib->ms.cache_display_cfg.plane.ViewportYStartC,
7671 			mode_lib->ms.cache_display_cfg.plane.ViewportWidth,
7672 			mode_lib->ms.cache_display_cfg.plane.ViewportHeight,
7673 			mode_lib->ms.BytePerPixelY,
7674 			mode_lib->ms.cache_display_cfg.plane.ViewportWidthChroma,
7675 			mode_lib->ms.cache_display_cfg.plane.ViewportHeightChroma,
7676 			mode_lib->ms.BytePerPixelC,
7677 			mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY,
7678 			mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC,
7679 			mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY,
7680 			mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC,
7681 			mode_lib->ms.Read256BlockWidthY,
7682 			mode_lib->ms.Read256BlockWidthC,
7683 			mode_lib->ms.Read256BlockHeightY,
7684 			mode_lib->ms.Read256BlockHeightC,
7685 			mode_lib->ms.MacroTileWidthY,
7686 			mode_lib->ms.MacroTileWidthC,
7687 			mode_lib->ms.MacroTileHeightY,
7688 			mode_lib->ms.MacroTileHeightC,
7689 
7690 			/* Output */
7691 			mode_lib->ms.SurfaceSizeInMALL,
7692 			&mode_lib->ms.support.ExceededMALLSize);
7693 
7694 	for (j = 0; j < 2; j++) {
7695 		for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
7696 			mode_lib->ms.swath_width_luma_ub_this_state[k] = mode_lib->ms.swath_width_luma_ub_all_states[j][k];
7697 			mode_lib->ms.swath_width_chroma_ub_this_state[k] = mode_lib->ms.swath_width_chroma_ub_all_states[j][k];
7698 			mode_lib->ms.SwathWidthYThisState[k] = mode_lib->ms.SwathWidthYAllStates[j][k];
7699 			mode_lib->ms.SwathWidthCThisState[k] = mode_lib->ms.SwathWidthCAllStates[j][k];
7700 			mode_lib->ms.SwathHeightYThisState[k] = mode_lib->ms.SwathHeightYAllStates[j][k];
7701 			mode_lib->ms.SwathHeightCThisState[k] = mode_lib->ms.SwathHeightCAllStates[j][k];
7702 			mode_lib->ms.DETBufferSizeInKByteThisState[k] = mode_lib->ms.DETBufferSizeInKByteAllStates[j][k];
7703 			mode_lib->ms.DETBufferSizeYThisState[k] = mode_lib->ms.DETBufferSizeYAllStates[j][k];
7704 			mode_lib->ms.DETBufferSizeCThisState[k] = mode_lib->ms.DETBufferSizeCAllStates[j][k];
7705 			mode_lib->ms.RequiredDPPCLKThisState[k] = mode_lib->ms.RequiredDPPCLKPerSurface[j][k];
7706 			mode_lib->ms.NoOfDPPThisState[k] = mode_lib->ms.NoOfDPP[j][k];
7707 		}
7708 
7709 		mode_lib->ms.TotalNumberOfDCCActiveDPP[j] = 0;
7710 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7711 			if (mode_lib->ms.cache_display_cfg.surface.DCCEnable[k] == true) {
7712 				mode_lib->ms.TotalNumberOfDCCActiveDPP[j] = mode_lib->ms.TotalNumberOfDCCActiveDPP[j] + mode_lib->ms.NoOfDPP[j][k];
7713 			}
7714 		}
7715 
7716 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7717 			s->SurfParameters[k].PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock[k];
7718 			s->SurfParameters[k].DPPPerSurface = mode_lib->ms.NoOfDPP[j][k];
7719 			s->SurfParameters[k].SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan[k];
7720 			s->SurfParameters[k].ViewportHeight = mode_lib->ms.cache_display_cfg.plane.ViewportHeight[k];
7721 			s->SurfParameters[k].ViewportHeightChroma = mode_lib->ms.cache_display_cfg.plane.ViewportHeightChroma[k];
7722 			s->SurfParameters[k].BlockWidth256BytesY = mode_lib->ms.Read256BlockWidthY[k];
7723 			s->SurfParameters[k].BlockHeight256BytesY = mode_lib->ms.Read256BlockHeightY[k];
7724 			s->SurfParameters[k].BlockWidth256BytesC = mode_lib->ms.Read256BlockWidthC[k];
7725 			s->SurfParameters[k].BlockHeight256BytesC = mode_lib->ms.Read256BlockHeightC[k];
7726 			s->SurfParameters[k].BlockWidthY = mode_lib->ms.MacroTileWidthY[k];
7727 			s->SurfParameters[k].BlockHeightY = mode_lib->ms.MacroTileHeightY[k];
7728 			s->SurfParameters[k].BlockWidthC = mode_lib->ms.MacroTileWidthC[k];
7729 			s->SurfParameters[k].BlockHeightC = mode_lib->ms.MacroTileHeightC[k];
7730 			s->SurfParameters[k].InterlaceEnable = mode_lib->ms.cache_display_cfg.timing.Interlace[k];
7731 			s->SurfParameters[k].HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal[k];
7732 			s->SurfParameters[k].DCCEnable = mode_lib->ms.cache_display_cfg.surface.DCCEnable[k];
7733 			s->SurfParameters[k].SourcePixelFormat = mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k];
7734 			s->SurfParameters[k].SurfaceTiling = mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k];
7735 			s->SurfParameters[k].BytePerPixelY = mode_lib->ms.BytePerPixelY[k];
7736 			s->SurfParameters[k].BytePerPixelC = mode_lib->ms.BytePerPixelC[k];
7737 			s->SurfParameters[k].ProgressiveToInterlaceUnitInOPP = mode_lib->ms.ip.ptoi_supported;
7738 			s->SurfParameters[k].VRatio = mode_lib->ms.cache_display_cfg.plane.VRatio[k];
7739 			s->SurfParameters[k].VRatioChroma = mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k];
7740 			s->SurfParameters[k].VTaps = mode_lib->ms.cache_display_cfg.plane.VTaps[k];
7741 			s->SurfParameters[k].VTapsChroma = mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k];
7742 			s->SurfParameters[k].PitchY = mode_lib->ms.cache_display_cfg.surface.PitchY[k];
7743 			s->SurfParameters[k].DCCMetaPitchY = mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchY[k];
7744 			s->SurfParameters[k].PitchC = mode_lib->ms.cache_display_cfg.surface.PitchC[k];
7745 			s->SurfParameters[k].DCCMetaPitchC = mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchC[k];
7746 			s->SurfParameters[k].ViewportStationary = mode_lib->ms.cache_display_cfg.plane.ViewportStationary[k];
7747 			s->SurfParameters[k].ViewportXStart = mode_lib->ms.cache_display_cfg.plane.ViewportXStart[k];
7748 			s->SurfParameters[k].ViewportYStart = mode_lib->ms.cache_display_cfg.plane.ViewportYStart[k];
7749 			s->SurfParameters[k].ViewportXStartC = mode_lib->ms.cache_display_cfg.plane.ViewportXStartC[k];
7750 			s->SurfParameters[k].ViewportYStartC = mode_lib->ms.cache_display_cfg.plane.ViewportYStartC[k];
7751 			s->SurfParameters[k].FORCE_ONE_ROW_FOR_FRAME = mode_lib->ms.cache_display_cfg.plane.ForceOneRowForFrame[k];
7752 			s->SurfParameters[k].SwathHeightY = mode_lib->ms.SwathHeightYThisState[k];
7753 			s->SurfParameters[k].SwathHeightC = mode_lib->ms.SwathHeightCThisState[k];
7754 		}
7755 
7756 		set_vm_row_and_swath_parameters(mode_lib);
7757 
7758 		CalculateVMRowAndSwath(&mode_lib->scratch,
7759 			CalculateVMRowAndSwath_params);
7760 
7761 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7762 			mode_lib->ms.PrefetchLinesY[j][k] = mode_lib->ms.PrefetchLinesYThisState[k];
7763 			mode_lib->ms.PrefetchLinesC[j][k] = mode_lib->ms.PrefetchLinesCThisState[k];
7764 			mode_lib->ms.meta_row_bandwidth[j][k] = mode_lib->ms.meta_row_bandwidth_this_state[k];
7765 			mode_lib->ms.dpte_row_bandwidth[j][k] = mode_lib->ms.dpte_row_bandwidth_this_state[k];
7766 			mode_lib->ms.DPTEBytesPerRow[j][k] = mode_lib->ms.DPTEBytesPerRowThisState[k];
7767 			mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k] = mode_lib->ms.PDEAndMetaPTEBytesPerFrameThisState[k];
7768 			mode_lib->ms.MetaRowBytes[j][k] = mode_lib->ms.MetaRowBytesThisState[k];
7769 			mode_lib->ms.use_one_row_for_frame[j][k] = mode_lib->ms.use_one_row_for_frame_this_state[k];
7770 			mode_lib->ms.use_one_row_for_frame_flip[j][k] = mode_lib->ms.use_one_row_for_frame_flip_this_state[k];
7771 		}
7772 
7773 		mode_lib->ms.support.PTEBufferSizeNotExceeded[j] = true;
7774 
7775 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7776 			if (mode_lib->ms.PTEBufferSizeNotExceededPerState[k] == false)
7777 				mode_lib->ms.support.PTEBufferSizeNotExceeded[j] = false;
7778 #ifdef __DML_VBA_DEBUG__
7779 			dml_print("DML::%s: j=%u k=%u, PTEBufferSizeNotExceededPerState[%u] = %u\n",  __func__, j, k, k, mode_lib->ms.PTEBufferSizeNotExceededPerState[k]);
7780 #endif
7781 		}
7782 #ifdef __DML_VBA_DEBUG__
7783 		dml_print("DML::%s: PTEBufferSizeNotExceeded[%u] = %u\n",  __func__, j, mode_lib->ms.support.PTEBufferSizeNotExceeded[j]);
7784 #endif
7785 
7786 		mode_lib->ms.support.DCCMetaBufferSizeNotExceeded[j] = true;
7787 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7788 			if (mode_lib->ms.DCCMetaBufferSizeNotExceededPerState[k] == false)
7789 				mode_lib->ms.support.DCCMetaBufferSizeNotExceeded[j] = false;
7790 		}
7791 
7792 		mode_lib->ms.UrgLatency = CalculateUrgentLatency(mode_lib->ms.state.urgent_latency_pixel_data_only_us,
7793 													mode_lib->ms.state.urgent_latency_pixel_mixed_with_vm_data_us,
7794 													mode_lib->ms.state.urgent_latency_vm_data_only_us,
7795 													mode_lib->ms.soc.do_urgent_latency_adjustment,
7796 													mode_lib->ms.state.urgent_latency_adjustment_fabric_clock_component_us,
7797 													mode_lib->ms.state.urgent_latency_adjustment_fabric_clock_reference_mhz,
7798 													mode_lib->ms.state.fabricclk_mhz);
7799 
7800 		/* Getter functions work at mp interface so copy the urgent latency to mp*/
7801 		mode_lib->mp.UrgentLatency = mode_lib->ms.UrgLatency;
7802 
7803 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7804 			CalculateUrgentBurstFactor(
7805 				mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k],
7806 				mode_lib->ms.swath_width_luma_ub_this_state[k],
7807 				mode_lib->ms.swath_width_chroma_ub_this_state[k],
7808 				mode_lib->ms.SwathHeightYThisState[k],
7809 				mode_lib->ms.SwathHeightCThisState[k],
7810 				(dml_float_t) mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
7811 				mode_lib->ms.UrgLatency,
7812 				mode_lib->ms.ip.cursor_buffer_size,
7813 				mode_lib->ms.cache_display_cfg.plane.CursorWidth[k],
7814 				mode_lib->ms.cache_display_cfg.plane.CursorBPP[k],
7815 				mode_lib->ms.cache_display_cfg.plane.VRatio[k],
7816 				mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k],
7817 				mode_lib->ms.BytePerPixelInDETY[k],
7818 				mode_lib->ms.BytePerPixelInDETC[k],
7819 				mode_lib->ms.DETBufferSizeYThisState[k],
7820 				mode_lib->ms.DETBufferSizeCThisState[k],
7821 				/* Output */
7822 				&mode_lib->ms.UrgentBurstFactorCursor[j][k],
7823 				&mode_lib->ms.UrgentBurstFactorLuma[j][k],
7824 				&mode_lib->ms.UrgentBurstFactorChroma[j][k],
7825 				&mode_lib->ms.NotUrgentLatencyHiding[k]);
7826 		}
7827 
7828 		CalculateDCFCLKDeepSleep(
7829 				mode_lib->ms.num_active_planes,
7830 				mode_lib->ms.BytePerPixelY,
7831 				mode_lib->ms.BytePerPixelC,
7832 				mode_lib->ms.cache_display_cfg.plane.VRatio,
7833 				mode_lib->ms.cache_display_cfg.plane.VRatioChroma,
7834 				mode_lib->ms.SwathWidthYThisState,
7835 				mode_lib->ms.SwathWidthCThisState,
7836 				mode_lib->ms.NoOfDPPThisState,
7837 				mode_lib->ms.cache_display_cfg.plane.HRatio,
7838 				mode_lib->ms.cache_display_cfg.plane.HRatioChroma,
7839 				mode_lib->ms.cache_display_cfg.timing.PixelClock,
7840 				mode_lib->ms.PSCL_FACTOR,
7841 				mode_lib->ms.PSCL_FACTOR_CHROMA,
7842 				mode_lib->ms.RequiredDPPCLKThisState,
7843 				mode_lib->ms.ReadBandwidthLuma,
7844 				mode_lib->ms.ReadBandwidthChroma,
7845 				mode_lib->ms.soc.return_bus_width_bytes,
7846 
7847 				/* Output */
7848 				&mode_lib->ms.ProjectedDCFCLKDeepSleep[j]);
7849 	}
7850 
7851 	//Calculate Return BW
7852 	for (j = 0; j < 2; ++j) {
7853 		for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
7854 			if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k) {
7855 				if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
7856 					mode_lib->ms.WritebackDelayTime[k] = mode_lib->ms.state.writeback_latency_us + CalculateWriteBackDelay(
7857 									mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[k],
7858 									mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[k],
7859 									mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[k],
7860 									mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[k],
7861 									mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k],
7862 									mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[k],
7863 									mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[k],
7864 									mode_lib->ms.cache_display_cfg.timing.HTotal[k]) / mode_lib->ms.RequiredDISPCLK[j];
7865 				} else {
7866 					mode_lib->ms.WritebackDelayTime[k] = 0.0;
7867 				}
7868 				for (m = 0; m <= mode_lib->ms.num_active_planes - 1; m++) {
7869 					if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[m] == k && mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[m] == true) {
7870 						mode_lib->ms.WritebackDelayTime[k] = dml_max(mode_lib->ms.WritebackDelayTime[k],
7871 											mode_lib->ms.state.writeback_latency_us + CalculateWriteBackDelay(
7872 											mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[m],
7873 											mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[m],
7874 											mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[m],
7875 											mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[m],
7876 											mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[m],
7877 											mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[m],
7878 											mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[m],
7879 											mode_lib->ms.cache_display_cfg.timing.HTotal[m]) / mode_lib->ms.RequiredDISPCLK[j]);
7880 					}
7881 				}
7882 			}
7883 		}
7884 		for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
7885 			for (m = 0; m <= mode_lib->ms.num_active_planes - 1; m++) {
7886 				if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == m) {
7887 					mode_lib->ms.WritebackDelayTime[k] = mode_lib->ms.WritebackDelayTime[m];
7888 				}
7889 			}
7890 		}
7891        s->MaxVStartupAllPlanes[j] = 0;  // max vstartup among all planes
7892 
7893 		for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
7894 			s->MaximumVStartup[j][k] = CalculateMaxVStartup(k,
7895 														mode_lib->ms.ip.ptoi_supported,
7896 														mode_lib->ms.ip.vblank_nom_default_us,
7897 														&mode_lib->ms.cache_display_cfg.timing,
7898 														mode_lib->ms.WritebackDelayTime[k]);
7899 
7900 			s->MaxVStartupAllPlanes[j] = (dml_uint_t)(dml_max(s->MaxVStartupAllPlanes[j], s->MaximumVStartup[j][k]));
7901 #ifdef __DML_VBA_DEBUG__
7902 			dml_print("DML::%s: k=%u, MaxVStartupAllPlanes[%u] = %u\n", __func__, k, j, s->MaxVStartupAllPlanes[j]);
7903 			dml_print("DML::%s: k=%u, MaximumVStartup[%u][%u] = %u\n", __func__, k, j, k, s->MaximumVStartup[j][k]);
7904 #endif
7905 		}
7906 	}
7907 
7908 	s->ReorderingBytes = (dml_uint_t)(mode_lib->ms.soc.num_chans * dml_max3(mode_lib->ms.soc.urgent_out_of_order_return_per_channel_pixel_only_bytes,
7909 																mode_lib->ms.soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes,
7910 																mode_lib->ms.soc.urgent_out_of_order_return_per_channel_vm_only_bytes));
7911 
7912 	for (j = 0; j < 2; ++j) {
7913 		mode_lib->ms.DCFCLKState[j] = mode_lib->ms.state.dcfclk_mhz;
7914 	}
7915 
7916 	/* Immediate Flip and MALL parameters */
7917 	s->ImmediateFlipRequiredFinal = false;
7918 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7919 		s->ImmediateFlipRequiredFinal = s->ImmediateFlipRequiredFinal || (mode_lib->ms.policy.ImmediateFlipRequirement[k] == dml_immediate_flip_required);
7920 	}
7921 
7922 	mode_lib->ms.support.ImmediateFlipRequiredButTheRequirementForEachSurfaceIsNotSpecified = false;
7923 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7924 		mode_lib->ms.support.ImmediateFlipRequiredButTheRequirementForEachSurfaceIsNotSpecified = mode_lib->ms.support.ImmediateFlipRequiredButTheRequirementForEachSurfaceIsNotSpecified ||
7925 																							((mode_lib->ms.policy.ImmediateFlipRequirement[k] != dml_immediate_flip_required) &&
7926 																							(mode_lib->ms.policy.ImmediateFlipRequirement[k] != dml_immediate_flip_not_required));
7927 	}
7928 	mode_lib->ms.support.ImmediateFlipRequiredButTheRequirementForEachSurfaceIsNotSpecified = mode_lib->ms.support.ImmediateFlipRequiredButTheRequirementForEachSurfaceIsNotSpecified && s->ImmediateFlipRequiredFinal;
7929 
7930 	mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe = false;
7931 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7932 		mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe =
7933 										mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe || ((mode_lib->ms.cache_display_cfg.plane.HostVMEnable == true || mode_lib->ms.policy.ImmediateFlipRequirement[k] != dml_immediate_flip_not_required) &&
7934 										(mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] == dml_use_mall_pstate_change_full_frame || mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe));
7935 	}
7936 
7937 	mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen = false;
7938 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7939 		mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen = mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen ||
7940 																((mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen[k] == dml_use_mall_static_screen_enable || mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen[k] == dml_use_mall_static_screen_optimize) && (mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe)) ||
7941 																((mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen[k] == dml_use_mall_static_screen_disable || mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen[k] == dml_use_mall_static_screen_optimize) && (mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] == dml_use_mall_pstate_change_full_frame));
7942 	}
7943 
7944 	s->FullFrameMALLPStateMethod = false;
7945 	s->SubViewportMALLPStateMethod = false;
7946 	s->PhantomPipeMALLPStateMethod = false;
7947 	s->SubViewportMALLRefreshGreaterThan120Hz = false;
7948 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
7949 		if (mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] == dml_use_mall_pstate_change_full_frame)
7950 			s->FullFrameMALLPStateMethod = true;
7951 		if (mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] == dml_use_mall_pstate_change_sub_viewport) {
7952 			s->SubViewportMALLPStateMethod = true;
7953 			if (mode_lib->ms.cache_display_cfg.timing.RefreshRate[k] > 120)
7954 				s->SubViewportMALLRefreshGreaterThan120Hz = true;
7955 		}
7956 		if (mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] == dml_use_mall_pstate_change_phantom_pipe)
7957 			s->PhantomPipeMALLPStateMethod = true;
7958 	}
7959 	mode_lib->ms.support.InvalidCombinationOfMALLUseForPState = (s->SubViewportMALLPStateMethod != s->PhantomPipeMALLPStateMethod)
7960 	|| (s->SubViewportMALLPStateMethod && s->FullFrameMALLPStateMethod) || s->SubViewportMALLRefreshGreaterThan120Hz;
7961 
7962     if (mode_lib->ms.policy.UseMinimumRequiredDCFCLK == true) {
7963 		UseMinimumDCFCLK_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
7964 		UseMinimumDCFCLK_params->DRRDisplay = mode_lib->ms.cache_display_cfg.timing.DRRDisplay;
7965 		UseMinimumDCFCLK_params->SynchronizeDRRDisplaysForUCLKPStateChangeFinal = mode_lib->ms.policy.SynchronizeDRRDisplaysForUCLKPStateChangeFinal;
7966 		UseMinimumDCFCLK_params->MaxInterDCNTileRepeaters = mode_lib->ms.ip.max_inter_dcn_tile_repeaters;
7967 		UseMinimumDCFCLK_params->MaxPrefetchMode = dml_prefetch_support_stutter;
7968 		UseMinimumDCFCLK_params->DRAMClockChangeLatencyFinal = mode_lib->ms.state.dram_clock_change_latency_us;
7969 		UseMinimumDCFCLK_params->FCLKChangeLatency = mode_lib->ms.state.fclk_change_latency_us;
7970 		UseMinimumDCFCLK_params->SREnterPlusExitTime = mode_lib->ms.state.sr_enter_plus_exit_time_us;
7971 		UseMinimumDCFCLK_params->ReturnBusWidth = mode_lib->ms.soc.return_bus_width_bytes;
7972 		UseMinimumDCFCLK_params->RoundTripPingLatencyCycles = mode_lib->ms.soc.round_trip_ping_latency_dcfclk_cycles;
7973 		UseMinimumDCFCLK_params->ReorderingBytes = s->ReorderingBytes;
7974 		UseMinimumDCFCLK_params->PixelChunkSizeInKByte = mode_lib->ms.ip.pixel_chunk_size_kbytes;
7975 		UseMinimumDCFCLK_params->MetaChunkSize = mode_lib->ms.ip.meta_chunk_size_kbytes;
7976 		UseMinimumDCFCLK_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
7977 		UseMinimumDCFCLK_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
7978 		UseMinimumDCFCLK_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
7979 		UseMinimumDCFCLK_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
7980 		UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
7981 		UseMinimumDCFCLK_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
7982 		UseMinimumDCFCLK_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
7983 		UseMinimumDCFCLK_params->ImmediateFlipRequirement = s->ImmediateFlipRequiredFinal;
7984 		UseMinimumDCFCLK_params->ProgressiveToInterlaceUnitInOPP = mode_lib->ms.ip.ptoi_supported;
7985 		UseMinimumDCFCLK_params->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation = mode_lib->ms.soc.max_avg_sdp_bw_use_normal_percent;
7986 		UseMinimumDCFCLK_params->PercentOfIdealSDPPortBWReceivedAfterUrgLatency = mode_lib->ms.soc.pct_ideal_sdp_bw_after_urgent;
7987 		UseMinimumDCFCLK_params->VTotal = mode_lib->ms.cache_display_cfg.timing.VTotal;
7988 		UseMinimumDCFCLK_params->VActive = mode_lib->ms.cache_display_cfg.timing.VActive;
7989 		UseMinimumDCFCLK_params->DynamicMetadataTransmittedBytes = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataTransmittedBytes;
7990 		UseMinimumDCFCLK_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired;
7991 		UseMinimumDCFCLK_params->Interlace = mode_lib->ms.cache_display_cfg.timing.Interlace;
7992 		UseMinimumDCFCLK_params->RequiredDPPCLKPerSurface = mode_lib->ms.RequiredDPPCLKPerSurface;
7993 		UseMinimumDCFCLK_params->RequiredDISPCLK = mode_lib->ms.RequiredDISPCLK;
7994 		UseMinimumDCFCLK_params->UrgLatency = mode_lib->ms.UrgLatency;
7995 		UseMinimumDCFCLK_params->NoOfDPP = mode_lib->ms.NoOfDPP;
7996 		UseMinimumDCFCLK_params->ProjectedDCFCLKDeepSleep = mode_lib->ms.ProjectedDCFCLKDeepSleep;
7997 		UseMinimumDCFCLK_params->MaximumVStartup = s->MaximumVStartup;
7998 		UseMinimumDCFCLK_params->TotalNumberOfActiveDPP = mode_lib->ms.TotalNumberOfActiveDPP;
7999 		UseMinimumDCFCLK_params->TotalNumberOfDCCActiveDPP = mode_lib->ms.TotalNumberOfDCCActiveDPP;
8000 		UseMinimumDCFCLK_params->dpte_group_bytes = mode_lib->ms.dpte_group_bytes;
8001 		UseMinimumDCFCLK_params->PrefetchLinesY = mode_lib->ms.PrefetchLinesY;
8002 		UseMinimumDCFCLK_params->PrefetchLinesC = mode_lib->ms.PrefetchLinesC;
8003 		UseMinimumDCFCLK_params->swath_width_luma_ub_all_states = mode_lib->ms.swath_width_luma_ub_all_states;
8004 		UseMinimumDCFCLK_params->swath_width_chroma_ub_all_states = mode_lib->ms.swath_width_chroma_ub_all_states;
8005 		UseMinimumDCFCLK_params->BytePerPixelY = mode_lib->ms.BytePerPixelY;
8006 		UseMinimumDCFCLK_params->BytePerPixelC = mode_lib->ms.BytePerPixelC;
8007 		UseMinimumDCFCLK_params->HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal;
8008 		UseMinimumDCFCLK_params->PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock;
8009 		UseMinimumDCFCLK_params->PDEAndMetaPTEBytesPerFrame = mode_lib->ms.PDEAndMetaPTEBytesPerFrame;
8010 		UseMinimumDCFCLK_params->DPTEBytesPerRow = mode_lib->ms.DPTEBytesPerRow;
8011 		UseMinimumDCFCLK_params->MetaRowBytes = mode_lib->ms.MetaRowBytes;
8012 		UseMinimumDCFCLK_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable;
8013 		UseMinimumDCFCLK_params->ReadBandwidthLuma = mode_lib->ms.ReadBandwidthLuma;
8014 		UseMinimumDCFCLK_params->ReadBandwidthChroma = mode_lib->ms.ReadBandwidthChroma;
8015 		UseMinimumDCFCLK_params->DCFCLKPerState = mode_lib->ms.state.dcfclk_mhz;
8016 		UseMinimumDCFCLK_params->DCFCLKState = mode_lib->ms.DCFCLKState;
8017 
8018 		UseMinimumDCFCLK(&mode_lib->scratch,
8019 		UseMinimumDCFCLK_params);
8020 
8021 	 } // UseMinimumRequiredDCFCLK == true
8022 
8023 	for (j = 0; j < 2; ++j) {
8024 		mode_lib->ms.ReturnBWPerState[j] = dml_get_return_bw_mbps(&mode_lib->ms.soc, mode_lib->ms.state.use_ideal_dram_bw_strobe,
8025 																mode_lib->ms.cache_display_cfg.plane.HostVMEnable, mode_lib->ms.DCFCLKState[j], mode_lib->ms.state.fabricclk_mhz,
8026 																mode_lib->ms.state.dram_speed_mts);
8027 		mode_lib->ms.ReturnDRAMBWPerState[j] = dml_get_return_dram_bw_mbps(&mode_lib->ms.soc, mode_lib->ms.state.use_ideal_dram_bw_strobe,
8028 																mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
8029 																mode_lib->ms.state.dram_speed_mts);
8030 	}
8031 
8032 	//Re-ordering Buffer Support Check
8033 	for (j = 0; j < 2; ++j) {
8034 		if ((mode_lib->ms.ip.rob_buffer_size_kbytes - mode_lib->ms.ip.pixel_chunk_size_kbytes) * 1024 / mode_lib->ms.ReturnBWPerState[j] >
8035 			(mode_lib->ms.soc.round_trip_ping_latency_dcfclk_cycles + 32) / mode_lib->ms.DCFCLKState[j] + s->ReorderingBytes / mode_lib->ms.ReturnBWPerState[j]) {
8036 			mode_lib->ms.support.ROBSupport[j] = true;
8037 		} else {
8038 			mode_lib->ms.support.ROBSupport[j] = false;
8039 		}
8040 		dml_print("DML::%s: DEBUG ROBSupport[%u] = %u (%u)\n",  __func__, j, mode_lib->ms.support.ROBSupport[j], __LINE__);
8041 	}
8042 
8043 	//Vertical Active BW support check
8044 	s->MaxTotalVActiveRDBandwidth = 0;
8045 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8046 		s->MaxTotalVActiveRDBandwidth = s->MaxTotalVActiveRDBandwidth + mode_lib->ms.ReadBandwidthLuma[k] + mode_lib->ms.ReadBandwidthChroma[k];
8047 	}
8048 
8049 	for (j = 0; j < 2; ++j) {
8050 		mode_lib->ms.support.MaxTotalVerticalActiveAvailableBandwidth[j] = dml_min3(mode_lib->ms.soc.return_bus_width_bytes * mode_lib->ms.DCFCLKState[j] * mode_lib->ms.soc.max_avg_sdp_bw_use_normal_percent / 100.0,
8051 																	mode_lib->ms.state.fabricclk_mhz * mode_lib->ms.soc.fabric_datapath_to_dcn_data_return_bytes * mode_lib->ms.soc.max_avg_fabric_bw_use_normal_percent / 100.0,
8052 																	mode_lib->ms.state.dram_speed_mts * mode_lib->ms.soc.num_chans * mode_lib->ms.soc.dram_channel_width_bytes *
8053 																	((mode_lib->ms.state.use_ideal_dram_bw_strobe && !mode_lib->ms.cache_display_cfg.plane.HostVMEnable) ?
8054 																	mode_lib->ms.soc.max_avg_dram_bw_use_normal_strobe_percent : mode_lib->ms.soc.max_avg_dram_bw_use_normal_percent) / 100.0);
8055 
8056 		if (s->MaxTotalVActiveRDBandwidth <= mode_lib->ms.support.MaxTotalVerticalActiveAvailableBandwidth[j]) {
8057 			mode_lib->ms.support.TotalVerticalActiveBandwidthSupport[j] = true;
8058 		} else {
8059 			mode_lib->ms.support.TotalVerticalActiveBandwidthSupport[j] = false;
8060 		}
8061 	}
8062 
8063 	/* Prefetch Check */
8064 	dml_prefetch_check(mode_lib);
8065 
8066 	// End of Prefetch Check
8067 	dml_print("DML::%s: Done prefetch calculation\n", __func__);
8068 
8069 	/*Cursor Support Check*/
8070 	mode_lib->ms.support.CursorSupport = true;
8071 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
8072 		if (mode_lib->ms.cache_display_cfg.plane.CursorWidth[k] > 0.0) {
8073 			if (mode_lib->ms.cache_display_cfg.plane.CursorBPP[k] == 64 && mode_lib->ms.ip.cursor_64bpp_support == false) {
8074 				mode_lib->ms.support.CursorSupport = false;
8075 			}
8076 		}
8077 	}
8078 
8079 	/*Valid Pitch Check*/
8080 	mode_lib->ms.support.PitchSupport = true;
8081 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
8082 		mode_lib->ms.support.AlignedYPitch[k] = dml_ceil(
8083 				dml_max(mode_lib->ms.cache_display_cfg.surface.PitchY[k], mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY[k]),
8084 				mode_lib->ms.MacroTileWidthY[k]);
8085 		if (mode_lib->ms.cache_display_cfg.surface.DCCEnable[k] == true) {
8086 			mode_lib->ms.support.AlignedDCCMetaPitchY[k] = dml_ceil(dml_max(mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchY[k], mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY[k]), 64.0 * mode_lib->ms.Read256BlockWidthY[k]);
8087 		} else {
8088 			mode_lib->ms.support.AlignedDCCMetaPitchY[k] = mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchY[k];
8089 		}
8090 		if (mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_64
8091 			&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_32
8092 			&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_16
8093 			&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_mono_16
8094 			&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_rgbe
8095 			&& mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_mono_8) {
8096 			mode_lib->ms.support.AlignedCPitch[k] = dml_ceil(dml_max(mode_lib->ms.cache_display_cfg.surface.PitchC[k], mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC[k]), mode_lib->ms.MacroTileWidthC[k]);
8097 			if (mode_lib->ms.cache_display_cfg.surface.DCCEnable[k] == true) {
8098 				mode_lib->ms.support.AlignedDCCMetaPitchC[k] = dml_ceil(dml_max(mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchC[k], mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC[k]), 64.0 * mode_lib->ms.Read256BlockWidthC[k]);
8099 			} else {
8100 				mode_lib->ms.support.AlignedDCCMetaPitchC[k] = mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchC[k];
8101 			}
8102 		} else {
8103 			mode_lib->ms.support.AlignedCPitch[k] = mode_lib->ms.cache_display_cfg.surface.PitchC[k];
8104 			mode_lib->ms.support.AlignedDCCMetaPitchC[k] = mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchC[k];
8105 		}
8106 		if (mode_lib->ms.support.AlignedYPitch[k] > mode_lib->ms.cache_display_cfg.surface.PitchY[k] || mode_lib->ms.support.AlignedCPitch[k] > mode_lib->ms.cache_display_cfg.surface.PitchC[k] ||
8107 			mode_lib->ms.support.AlignedDCCMetaPitchY[k] > mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchY[k] || mode_lib->ms.support.AlignedDCCMetaPitchC[k] > mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchC[k]) {
8108 			mode_lib->ms.support.PitchSupport = false;
8109 		}
8110 	}
8111 
8112 	mode_lib->ms.support.ViewportExceedsSurface = false;
8113 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
8114 		if (mode_lib->ms.cache_display_cfg.plane.ViewportWidth[k] > mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY[k] || mode_lib->ms.cache_display_cfg.plane.ViewportHeight[k] > mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY[k]) {
8115 			mode_lib->ms.support.ViewportExceedsSurface = true;
8116 			if (mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_64 && mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_32 &&
8117 				mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_16 && mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_444_8 && mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k] != dml_rgbe) {
8118 				if (mode_lib->ms.cache_display_cfg.plane.ViewportWidthChroma[k] > mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC[k] || mode_lib->ms.cache_display_cfg.plane.ViewportHeightChroma[k] > mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC[k]) {
8119 					mode_lib->ms.support.ViewportExceedsSurface = true;
8120 				}
8121 			}
8122 		}
8123 	}
8124 
8125 	/*Mode Support, Voltage State and SOC Configuration*/
8126 	for (j = 0; j < 2; j++) { // j iterator is for the combine mode off or on
8127 		dml_print("DML::%s: checking support for j=%u\n", __func__, j);
8128 		dml_print("DML::%s: state_idx=%0d max_state_idx=%0d\n", __func__, mode_lib->ms.state_idx, mode_lib->ms.max_state_idx);
8129 
8130 		s->is_max_pwr_state = (mode_lib->ms.max_state_idx == mode_lib->ms.state_idx);
8131 		s->is_max_dram_pwr_state = (mode_lib->ms.max_state.dram_speed_mts == mode_lib->ms.state.dram_speed_mts);
8132 
8133 		s->dram_clock_change_support = (!mode_lib->ms.policy.DRAMClockChangeRequirementFinal ||
8134 											(s->is_max_dram_pwr_state && mode_lib->policy.AssumeModeSupportAtMaxPwrStateEvenDRAMClockChangeNotSupported) ||
8135 											mode_lib->ms.support.DRAMClockChangeSupport[j] != dml_dram_clock_change_unsupported);
8136 		s->f_clock_change_support = (!mode_lib->ms.policy.FCLKChangeRequirementFinal ||
8137 											(s->is_max_pwr_state && mode_lib->policy.AssumeModeSupportAtMaxPwrStateEvenFClockChangeNotSupported) ||
8138 											mode_lib->ms.support.FCLKChangeSupport[j] != dml_fclock_change_unsupported);
8139 
8140 		if (mode_lib->ms.support.ScaleRatioAndTapsSupport == true
8141 			&& mode_lib->ms.support.SourceFormatPixelAndScanSupport == true
8142 			&& mode_lib->ms.support.ViewportSizeSupport[j] == true
8143 			&& !mode_lib->ms.support.LinkRateDoesNotMatchDPVersion
8144 			&& !mode_lib->ms.support.LinkRateForMultistreamNotIndicated
8145 			&& !mode_lib->ms.support.BPPForMultistreamNotIndicated
8146 			&& !mode_lib->ms.support.MultistreamWithHDMIOreDP
8147 			&& !mode_lib->ms.support.ExceededMultistreamSlots
8148 			&& !mode_lib->ms.support.MSOOrODMSplitWithNonDPLink
8149 			&& !mode_lib->ms.support.NotEnoughLanesForMSO
8150 			&& mode_lib->ms.support.LinkCapacitySupport == true
8151 			&& !mode_lib->ms.support.P2IWith420
8152 			&& !mode_lib->ms.support.DSCOnlyIfNecessaryWithBPP
8153 			&& !mode_lib->ms.support.DSC422NativeNotSupported
8154 			&& !mode_lib->ms.support.MPCCombineMethodIncompatible
8155 			&& mode_lib->ms.support.ODMCombineTwoToOneSupportCheckOK == true
8156 			&& mode_lib->ms.support.ODMCombineFourToOneSupportCheckOK == true
8157 			&& mode_lib->ms.support.NotEnoughDSCUnits == false
8158 			&& !mode_lib->ms.support.NotEnoughDSCSlices
8159 			&& !mode_lib->ms.support.ImmediateFlipOrHostVMAndPStateWithMALLFullFrameOrPhantomPipe
8160 			&& !mode_lib->ms.support.InvalidCombinationOfMALLUseForPStateAndStaticScreen
8161 			&& mode_lib->ms.support.DSCCLKRequiredMoreThanSupported == false
8162 			&& mode_lib->ms.support.PixelsPerLinePerDSCUnitSupport
8163 			&& mode_lib->ms.support.DTBCLKRequiredMoreThanSupported == false
8164 			&& !mode_lib->ms.support.InvalidCombinationOfMALLUseForPState
8165 			&& !mode_lib->ms.support.ImmediateFlipRequiredButTheRequirementForEachSurfaceIsNotSpecified
8166 			&& mode_lib->ms.support.ROBSupport[j] == true
8167 			&& mode_lib->ms.support.DISPCLK_DPPCLK_Support[j] == true
8168 			&& mode_lib->ms.support.TotalAvailablePipesSupport[j] == true
8169 			&& mode_lib->ms.support.NumberOfOTGSupport == true
8170 			&& mode_lib->ms.support.NumberOfHDMIFRLSupport == true
8171 			&& mode_lib->ms.support.NumberOfDP2p0Support == true
8172 			&& mode_lib->ms.support.EnoughWritebackUnits == true
8173 			&& mode_lib->ms.support.WritebackLatencySupport == true
8174 			&& mode_lib->ms.support.WritebackScaleRatioAndTapsSupport == true
8175 			&& mode_lib->ms.support.CursorSupport == true
8176 			&& mode_lib->ms.support.PitchSupport == true
8177 			&& mode_lib->ms.support.ViewportExceedsSurface == false
8178 			&& mode_lib->ms.support.PrefetchSupported[j] == true
8179 			&& mode_lib->ms.support.VActiveBandwithSupport[j] == true
8180 			&& mode_lib->ms.support.DynamicMetadataSupported[j] == true
8181 			&& mode_lib->ms.support.TotalVerticalActiveBandwidthSupport[j] == true
8182 			&& mode_lib->ms.support.VRatioInPrefetchSupported[j] == true
8183 			&& mode_lib->ms.support.PTEBufferSizeNotExceeded[j] == true
8184 			&& mode_lib->ms.support.DCCMetaBufferSizeNotExceeded[j] == true
8185 			&& mode_lib->ms.support.NonsupportedDSCInputBPC == false
8186 			&& !mode_lib->ms.support.ExceededMALLSize
8187 			&& ((mode_lib->ms.cache_display_cfg.plane.HostVMEnable == false && !s->ImmediateFlipRequiredFinal) || mode_lib->ms.support.ImmediateFlipSupportedForState[j])
8188 			&& s->dram_clock_change_support == true
8189 			&& s->f_clock_change_support == true
8190 			&& (!mode_lib->ms.policy.USRRetrainingRequiredFinal || mode_lib->ms.support.USRRetrainingSupport[j])) {
8191 			dml_print("DML::%s: mode is supported\n", __func__);
8192 			mode_lib->ms.support.ModeSupport[j] = true;
8193 		} else {
8194 			dml_print("DML::%s: mode is NOT supported\n", __func__);
8195 			mode_lib->ms.support.ModeSupport[j] = false;
8196 			dml_print_mode_support(mode_lib, j);
8197 		}
8198 	}
8199 
8200 	mode_lib->ms.support.MaximumMPCCombine = 0;
8201 	mode_lib->ms.support.ModeIsSupported = 0;
8202 	if (mode_lib->ms.support.ModeSupport[0] == true || mode_lib->ms.support.ModeSupport[1] == true) {  // if the mode is supported by either no combine or mpccombine
8203 		mode_lib->ms.support.ModeIsSupported = mode_lib->ms.support.ModeSupport[0] == true || mode_lib->ms.support.ModeSupport[1] == true;
8204 
8205 		// Determine if MPC combine is necessary, depends on if using MPC combine will help dram clock change or fclk change, etc.
8206 		if ((mode_lib->ms.support.ModeSupport[0] == false && mode_lib->ms.support.ModeSupport[1] == true) || s->MPCCombineMethodAsPossible ||
8207 			(s->MPCCombineMethodAsNeededForPStateChangeAndVoltage && mode_lib->ms.policy.DRAMClockChangeRequirementFinal &&
8208 			(((mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vactive || mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vactive_w_mall_full_frame || mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vactive_w_mall_sub_vp) &&
8209 			!(mode_lib->ms.support.DRAMClockChangeSupport[0] == dml_dram_clock_change_vactive || mode_lib->ms.support.DRAMClockChangeSupport[0] == dml_dram_clock_change_vactive_w_mall_full_frame || mode_lib->ms.support.DRAMClockChangeSupport[0] == dml_dram_clock_change_vactive_w_mall_sub_vp)) ||
8210 			((mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vblank || mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vblank_drr
8211 		|| mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vblank_w_mall_full_frame || mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vblank_drr_w_mall_full_frame
8212 		|| mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vblank_w_mall_sub_vp || mode_lib->ms.support.DRAMClockChangeSupport[1] == dml_dram_clock_change_vblank_drr_w_mall_sub_vp
8213 		) &&
8214 				mode_lib->ms.support.DRAMClockChangeSupport[0] == dml_dram_clock_change_unsupported)))
8215 			|| (s->MPCCombineMethodAsNeededForPStateChangeAndVoltage && mode_lib->ms.policy.FCLKChangeRequirementFinal &&
8216 				((mode_lib->ms.support.FCLKChangeSupport[1] == dml_fclock_change_vactive && mode_lib->ms.support.FCLKChangeSupport[0] != dml_fclock_change_vactive) ||
8217 				(mode_lib->ms.support.FCLKChangeSupport[1] == dml_fclock_change_vblank && mode_lib->ms.support.FCLKChangeSupport[0] == dml_fclock_change_unsupported)))) {
8218 			mode_lib->ms.support.MaximumMPCCombine = 1;
8219 		} else {
8220 			mode_lib->ms.support.MaximumMPCCombine = 0;
8221 		}
8222 	}
8223 
8224 	// Since now the mode_support work on 1 particular power state, so there is only 1 state idx (index 0).
8225 	mode_lib->ms.support.ImmediateFlipSupport          = mode_lib->ms.support.ImmediateFlipSupportedForState[mode_lib->ms.support.MaximumMPCCombine];   // Consider flip support if max combine support imm flip
8226 	mode_lib->ms.support.UnboundedRequestEnabled       = mode_lib->ms.UnboundedRequestEnabledAllStates[mode_lib->ms.support.MaximumMPCCombine];         // Not used, informational
8227 	mode_lib->ms.support.CompressedBufferSizeInkByte   = mode_lib->ms.CompressedBufferSizeInkByteAllStates[mode_lib->ms.support.MaximumMPCCombine];     // Not used, informational
8228 
8229 	dml_print("DML::%s: ModeIsSupported                = %u\n", __func__, mode_lib->ms.support.ModeIsSupported);
8230 	dml_print("DML::%s: MaximumMPCCombine              = %u\n", __func__, mode_lib->ms.support.MaximumMPCCombine);
8231 	dml_print("DML::%s: ImmediateFlipSupport           = %u\n", __func__, mode_lib->ms.support.ImmediateFlipSupport);
8232 	dml_print("DML::%s: UnboundedRequestEnabled        = %u\n", __func__, mode_lib->ms.support.UnboundedRequestEnabled);
8233 	dml_print("DML::%s: CompressedBufferSizeInkByte    = %u\n", __func__, mode_lib->ms.support.CompressedBufferSizeInkByte);
8234 
8235 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
8236 		mode_lib->ms.support.MPCCombineEnable[k]   = mode_lib->ms.MPCCombine[mode_lib->ms.support.MaximumMPCCombine][k];
8237 		mode_lib->ms.support.DPPPerSurface[k]      = mode_lib->ms.NoOfDPP[mode_lib->ms.support.MaximumMPCCombine][k];
8238 		mode_lib->ms.SwathHeightY[k]               = mode_lib->ms.SwathHeightYAllStates[mode_lib->ms.support.MaximumMPCCombine][k];
8239 		mode_lib->ms.SwathHeightC[k]               = mode_lib->ms.SwathHeightCAllStates[mode_lib->ms.support.MaximumMPCCombine][k];
8240 		mode_lib->ms.DETBufferSizeInKByte[k]       = mode_lib->ms.DETBufferSizeInKByteAllStates[mode_lib->ms.support.MaximumMPCCombine][k];
8241 		mode_lib->ms.DETBufferSizeY[k]             = mode_lib->ms.DETBufferSizeYAllStates[mode_lib->ms.support.MaximumMPCCombine][k];
8242 		mode_lib->ms.DETBufferSizeC[k]             = mode_lib->ms.DETBufferSizeCAllStates[mode_lib->ms.support.MaximumMPCCombine][k];
8243 	}
8244 
8245 	mode_lib->ms.DRAMSpeed     = mode_lib->ms.state.dram_speed_mts;
8246 	mode_lib->ms.FabricClock   = mode_lib->ms.state.fabricclk_mhz;
8247 	mode_lib->ms.SOCCLK        = mode_lib->ms.state.socclk_mhz;
8248 	mode_lib->ms.DCFCLK        = mode_lib->ms.DCFCLKState[mode_lib->ms.support.MaximumMPCCombine];
8249 	mode_lib->ms.ReturnBW      = mode_lib->ms.ReturnBWPerState[mode_lib->ms.support.MaximumMPCCombine];
8250 	mode_lib->ms.ReturnDRAMBW  = mode_lib->ms.ReturnDRAMBWPerState[mode_lib->ms.support.MaximumMPCCombine];
8251 
8252 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
8253 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k) {
8254 			mode_lib->ms.support.ODMMode[k] = mode_lib->ms.ODMModePerState[k];
8255 		} else {
8256 			mode_lib->ms.support.ODMMode[k] = dml_odm_mode_bypass;
8257 		}
8258 
8259 		mode_lib->ms.support.DSCEnabled[k] = mode_lib->ms.RequiresDSC[k];
8260 		mode_lib->ms.support.FECEnabled[k] = mode_lib->ms.RequiresFEC[k];
8261 		mode_lib->ms.support.OutputBpp[k] = mode_lib->ms.OutputBppPerState[k];
8262 		mode_lib->ms.support.OutputType[k] = mode_lib->ms.OutputTypePerState[k];
8263 		mode_lib->ms.support.OutputRate[k] = mode_lib->ms.OutputRatePerState[k];
8264 		mode_lib->ms.support.SubViewportLinesNeededInMALL[k] = mode_lib->ms.SubViewportLinesNeededInMALL[k];
8265 	}
8266 
8267 	return mode_lib->ms.support.ModeIsSupported;
8268 } // dml_core_mode_support
8269 
8270 /// @brief This function calculates some parameters thats are needed ahead of the mode programming function all
dml_core_mode_support_partial(struct display_mode_lib_st * mode_lib)8271 void dml_core_mode_support_partial(struct display_mode_lib_st *mode_lib)
8272 {
8273 	CalculateMaxDETAndMinCompressedBufferSize(
8274 								mode_lib->ms.ip.config_return_buffer_size_in_kbytes,
8275 								mode_lib->ms.ip.config_return_buffer_segment_size_in_kbytes,
8276 								mode_lib->ms.ip.rob_buffer_size_kbytes,
8277 								mode_lib->ms.ip.max_num_dpp,
8278 								mode_lib->ms.policy.NomDETInKByteOverrideEnable,
8279 								mode_lib->ms.policy.NomDETInKByteOverrideValue,
8280 
8281 								/* Output */
8282 								&mode_lib->ms.MaxTotalDETInKByte,
8283 								&mode_lib->ms.NomDETInKByte,
8284 								&mode_lib->ms.MinCompressedBufferSizeInKByte);
8285 
8286 	PixelClockAdjustmentForProgressiveToInterlaceUnit(&mode_lib->ms.cache_display_cfg, mode_lib->ms.ip.ptoi_supported);
8287 
8288 	mode_lib->ms.ReturnBW = dml_get_return_bw_mbps(&mode_lib->ms.soc,
8289 													mode_lib->ms.state.use_ideal_dram_bw_strobe,
8290 													mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
8291 													mode_lib->ms.DCFCLK,
8292 													mode_lib->ms.FabricClock,
8293 													mode_lib->ms.DRAMSpeed);
8294 	dml_print("DML::%s: ReturnBW = %f\n", __func__, mode_lib->ms.ReturnBW);
8295 
8296 } // dml_core_mode_support_partial
8297 
8298 /// @brief This is the mode programming function. It is assumed the display cfg is support at the given power state
dml_core_mode_programming(struct display_mode_lib_st * mode_lib,const struct dml_clk_cfg_st * clk_cfg)8299 void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struct dml_clk_cfg_st *clk_cfg)
8300 {
8301 	struct dml_core_mode_programming_locals_st *s = &mode_lib->scratch.dml_core_mode_programming_locals;
8302 	struct CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params_st *CalculateWatermarks_params = &mode_lib->scratch.CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params;
8303 	struct CalculateVMRowAndSwath_params_st *CalculateVMRowAndSwath_params = &mode_lib->scratch.CalculateVMRowAndSwath_params;
8304 	struct CalculateSwathAndDETConfiguration_params_st *CalculateSwathAndDETConfiguration_params = &mode_lib->scratch.CalculateSwathAndDETConfiguration_params;
8305 	struct CalculateStutterEfficiency_params_st *CalculateStutterEfficiency_params = &mode_lib->scratch.CalculateStutterEfficiency_params;
8306 	struct CalculatePrefetchSchedule_params_st *CalculatePrefetchSchedule_params = &mode_lib->scratch.CalculatePrefetchSchedule_params;
8307 
8308 	struct mode_program_st   *locals    = &mode_lib->mp;
8309 	struct DmlPipe *myPipe;
8310 	dml_uint_t j = 0, k = 0;
8311 	dml_float_t TWait;
8312 	dml_bool_t isInterlaceTiming;
8313 
8314 	mode_lib->ms.num_active_planes = dml_get_num_active_planes(&mode_lib->ms.cache_display_cfg);
8315 	mode_lib->mp.num_active_pipes = dml_get_num_active_pipes(&mode_lib->ms.cache_display_cfg);
8316 	dml_calc_pipe_plane_mapping(&mode_lib->ms.cache_display_cfg.hw, mode_lib->mp.pipe_plane);
8317 
8318 #ifdef __DML_VBA_DEBUG__
8319 	dml_print("DML::%s: --- START --- \n",  __func__);
8320 	dml_print("DML::%s: num_active_planes = %u\n", __func__, mode_lib->ms.num_active_planes);
8321 	dml_print("DML::%s: num_active_pipes = %u\n", __func__, mode_lib->mp.num_active_pipes);
8322 #endif
8323 
8324 	s->DSCFormatFactor          = 0;
8325 
8326 	// Unlike dppclk and dispclk which can be calculated in mode_programming
8327 	// DCFCLK is calculated in mode_support (which is the state bbox dcfclk or min dcfclk if min dcfclk option is used in mode support calculation)
8328 	if (clk_cfg->dcfclk_option != dml_use_override_freq)
8329 		locals->Dcfclk = mode_lib->ms.DCFCLK;
8330 	else
8331 		locals->Dcfclk = clk_cfg->dcfclk_mhz;
8332 
8333 #ifdef __DML_VBA_DEBUG__
8334 	dml_print_dml_policy(&mode_lib->ms.policy);
8335 	dml_print_soc_state_bounding_box(&mode_lib->ms.state);
8336 	dml_print_soc_bounding_box(&mode_lib->ms.soc);
8337 	dml_print_clk_cfg(clk_cfg);
8338 
8339 	dml_print("DML::%s: ImmediateFlipSupport = %u\n", __func__, mode_lib->ms.support.ImmediateFlipSupport);
8340 	dml_print("DML::%s: Using DCFCLK = %f\n", __func__, locals->Dcfclk);
8341 	dml_print("DML::%s: Using SOCCLK = %f\n", __func__, mode_lib->ms.SOCCLK);
8342 #endif
8343 
8344 	locals->WritebackDISPCLK = 0.0;
8345 	locals->GlobalDPPCLK = 0.0;
8346 
8347 	// DISPCLK and DPPCLK Calculation
8348 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8349 		if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k]) {
8350 			locals->WritebackDISPCLK =
8351 					dml_max(
8352 							locals->WritebackDISPCLK,
8353 							CalculateWriteBackDISPCLK(
8354 									mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[k],
8355 									mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
8356 									mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[k],
8357 									mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[k],
8358 									mode_lib->ms.cache_display_cfg.writeback.WritebackHTaps[k],
8359 									mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[k],
8360 									mode_lib->ms.cache_display_cfg.writeback.WritebackSourceWidth[k],
8361 									mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k],
8362 									mode_lib->ms.cache_display_cfg.timing.HTotal[k],
8363 									mode_lib->ms.ip.writeback_line_buffer_buffer_size,
8364 									mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz));
8365 		}
8366 	}
8367 
8368 	locals->Dispclk_calculated = locals->WritebackDISPCLK;
8369 
8370 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8371 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k) {
8372 				locals->Dispclk_calculated = dml_max(locals->Dispclk_calculated, CalculateRequiredDispclk(
8373 																					mode_lib->ms.cache_display_cfg.hw.ODMMode[k],
8374 																					mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
8375 																					mode_lib->ms.soc.dcn_downspread_percent,
8376 																					mode_lib->ms.ip.dispclk_ramp_margin_percent,
8377 																					mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz,
8378 																					mode_lib->ms.max_state.dispclk_mhz));
8379 		}
8380 	}
8381 	if (clk_cfg->dispclk_option == dml_use_required_freq)
8382 		locals->Dispclk = locals->Dispclk_calculated;
8383 	else if (clk_cfg->dispclk_option == dml_use_override_freq)
8384 		locals->Dispclk = clk_cfg->dispclk_mhz;
8385 	else
8386 		locals->Dispclk = mode_lib->ms.state.dispclk_mhz;
8387 #ifdef __DML_VBA_DEBUG__
8388 	 dml_print("DML::%s: Using Dispclk = %f\n", __func__, locals->Dispclk);
8389 #endif
8390 
8391 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8392 		CalculateSinglePipeDPPCLKAndSCLThroughput(
8393 				mode_lib->ms.cache_display_cfg.plane.HRatio[k],
8394 				mode_lib->ms.cache_display_cfg.plane.HRatioChroma[k],
8395 				mode_lib->ms.cache_display_cfg.plane.VRatio[k],
8396 				mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k],
8397 				mode_lib->ms.ip.max_dchub_pscl_bw_pix_per_clk,
8398 				mode_lib->ms.ip.max_pscl_lb_bw_pix_per_clk,
8399 				mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
8400 				mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k],
8401 				mode_lib->ms.cache_display_cfg.plane.HTaps[k],
8402 				mode_lib->ms.cache_display_cfg.plane.HTapsChroma[k],
8403 				mode_lib->ms.cache_display_cfg.plane.VTaps[k],
8404 				mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k],
8405 
8406 				/* Output */
8407 				&locals->PSCL_THROUGHPUT[k],
8408 				&locals->PSCL_THROUGHPUT_CHROMA[k],
8409 				&locals->DPPCLKUsingSingleDPP[k]);
8410 	}
8411 
8412 	CalculateDPPCLK(mode_lib->ms.num_active_planes,
8413 					mode_lib->ms.soc.dcn_downspread_percent,
8414 					mode_lib->ms.soc.dispclk_dppclk_vco_speed_mhz,
8415 					locals->DPPCLKUsingSingleDPP,
8416 					mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
8417 					/* Output */
8418 					&locals->GlobalDPPCLK,
8419 					locals->Dppclk_calculated);
8420 
8421 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8422 		if (clk_cfg->dppclk_option[k] == dml_use_required_freq)
8423 			locals->Dppclk[k] = locals->Dppclk_calculated[k];
8424 		else if (clk_cfg->dppclk_option[k] == dml_use_override_freq)
8425 			locals->Dppclk[k] = clk_cfg->dppclk_mhz[k];
8426 		else
8427 			locals->Dppclk[k] = mode_lib->ms.state.dppclk_mhz;
8428 #ifdef __DML_VBA_DEBUG__
8429 		dml_print("DML::%s: Using Dppclk[%0d] = %f\n", __func__, k, locals->Dppclk[k]);
8430 #endif
8431 	}
8432 
8433 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8434 		CalculateBytePerPixelAndBlockSizes(
8435 				mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k],
8436 				mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k],
8437 
8438 				/* Output */
8439 				&locals->BytePerPixelY[k],
8440 				&locals->BytePerPixelC[k],
8441 				&locals->BytePerPixelDETY[k],
8442 				&locals->BytePerPixelDETC[k],
8443 				&locals->BlockHeight256BytesY[k],
8444 				&locals->BlockHeight256BytesC[k],
8445 				&locals->BlockWidth256BytesY[k],
8446 				&locals->BlockWidth256BytesC[k],
8447 				&locals->BlockHeightY[k],
8448 				&locals->BlockHeightC[k],
8449 				&locals->BlockWidthY[k],
8450 				&locals->BlockWidthC[k]);
8451 	}
8452 
8453 
8454 	dml_print("DML::%s: %u\n", __func__, __LINE__);
8455 	CalculateSwathWidth(
8456 		false,  // ForceSingleDPP
8457 		mode_lib->ms.num_active_planes,
8458 		mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat,
8459 		mode_lib->ms.cache_display_cfg.plane.SourceScan,
8460 		mode_lib->ms.cache_display_cfg.plane.ViewportStationary,
8461 		mode_lib->ms.cache_display_cfg.plane.ViewportWidth,
8462 		mode_lib->ms.cache_display_cfg.plane.ViewportHeight,
8463 		mode_lib->ms.cache_display_cfg.plane.ViewportXStart,
8464 		mode_lib->ms.cache_display_cfg.plane.ViewportYStart,
8465 		mode_lib->ms.cache_display_cfg.plane.ViewportXStartC,
8466 		mode_lib->ms.cache_display_cfg.plane.ViewportYStartC,
8467 		mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY,
8468 		mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC,
8469 		mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY,
8470 		mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC,
8471 		mode_lib->ms.cache_display_cfg.hw.ODMMode,
8472 		locals->BytePerPixelY,
8473 		locals->BytePerPixelC,
8474 		locals->BlockHeight256BytesY,
8475 		locals->BlockHeight256BytesC,
8476 		locals->BlockWidth256BytesY,
8477 		locals->BlockWidth256BytesC,
8478 		mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming,
8479 		mode_lib->ms.cache_display_cfg.timing.HActive,
8480 		mode_lib->ms.cache_display_cfg.plane.HRatio,
8481 		mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
8482 
8483 		/* Output */
8484 		locals->SwathWidthSingleDPPY,
8485 		locals->SwathWidthSingleDPPC,
8486 		locals->SwathWidthY,
8487 		locals->SwathWidthC,
8488 		s->dummy_integer_array[0], // dml_uint_t MaximumSwathHeightY[]
8489 		s->dummy_integer_array[1], // dml_uint_t MaximumSwathHeightC[]
8490 		locals->swath_width_luma_ub,
8491 		locals->swath_width_chroma_ub);
8492 
8493 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8494 		locals->ReadBandwidthSurfaceLuma[k] = locals->SwathWidthSingleDPPY[k] * locals->BytePerPixelY[k] / (mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * mode_lib->ms.cache_display_cfg.plane.VRatio[k];
8495 		locals->ReadBandwidthSurfaceChroma[k] = locals->SwathWidthSingleDPPC[k] * locals->BytePerPixelC[k] / (mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k];
8496 		dml_print("DML::%s: ReadBandwidthSurfaceLuma[%i] = %fBps\n", __func__, k, locals->ReadBandwidthSurfaceLuma[k]);
8497 		dml_print("DML::%s: ReadBandwidthSurfaceChroma[%i] = %fBps\n", __func__, k, locals->ReadBandwidthSurfaceChroma[k]);
8498 	}
8499 
8500 	CalculateSwathAndDETConfiguration_params->DETSizeOverride = mode_lib->ms.cache_display_cfg.plane.DETSizeOverride;
8501 	CalculateSwathAndDETConfiguration_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
8502 	CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSizeInKByte = mode_lib->ms.ip.config_return_buffer_size_in_kbytes;
8503 	CalculateSwathAndDETConfiguration_params->ROBBufferSizeInKByte = mode_lib->ms.ip.rob_buffer_size_kbytes;
8504 	CalculateSwathAndDETConfiguration_params->MaxTotalDETInKByte = mode_lib->ms.MaxTotalDETInKByte;
8505 	CalculateSwathAndDETConfiguration_params->MinCompressedBufferSizeInKByte = mode_lib->ms.MinCompressedBufferSizeInKByte;
8506 	CalculateSwathAndDETConfiguration_params->PixelChunkSizeInKByte = mode_lib->ms.ip.pixel_chunk_size_kbytes;
8507 	CalculateSwathAndDETConfiguration_params->ForceSingleDPP = false;
8508 	CalculateSwathAndDETConfiguration_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
8509 	CalculateSwathAndDETConfiguration_params->nomDETInKByte = mode_lib->ms.NomDETInKByte;
8510 	CalculateSwathAndDETConfiguration_params->UseUnboundedRequestingFinal = mode_lib->ms.policy.UseUnboundedRequesting;
8511 	CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSegmentSizeInkByte = mode_lib->ms.ip.config_return_buffer_segment_size_in_kbytes;
8512 	CalculateSwathAndDETConfiguration_params->CompressedBufferSegmentSizeInkByteFinal = mode_lib->ms.ip.compressed_buffer_segment_size_in_kbytes;
8513 	CalculateSwathAndDETConfiguration_params->Output = s->dummy_output_encoder_array;
8514 	CalculateSwathAndDETConfiguration_params->ReadBandwidthLuma = locals->ReadBandwidthSurfaceLuma;
8515 	CalculateSwathAndDETConfiguration_params->ReadBandwidthChroma = locals->ReadBandwidthSurfaceChroma;
8516 	CalculateSwathAndDETConfiguration_params->MaximumSwathWidthLuma = s->dummy_single_array[0];
8517 	CalculateSwathAndDETConfiguration_params->MaximumSwathWidthChroma = s->dummy_single_array[1];
8518 	CalculateSwathAndDETConfiguration_params->SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan;
8519 	CalculateSwathAndDETConfiguration_params->ViewportStationary = mode_lib->ms.cache_display_cfg.plane.ViewportStationary;
8520 	CalculateSwathAndDETConfiguration_params->SourcePixelFormat = mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat;
8521 	CalculateSwathAndDETConfiguration_params->SurfaceTiling = mode_lib->ms.cache_display_cfg.surface.SurfaceTiling;
8522 	CalculateSwathAndDETConfiguration_params->ViewportWidth = mode_lib->ms.cache_display_cfg.plane.ViewportWidth;
8523 	CalculateSwathAndDETConfiguration_params->ViewportHeight = mode_lib->ms.cache_display_cfg.plane.ViewportHeight;
8524 	CalculateSwathAndDETConfiguration_params->ViewportXStart = mode_lib->ms.cache_display_cfg.plane.ViewportXStart;
8525 	CalculateSwathAndDETConfiguration_params->ViewportYStart = mode_lib->ms.cache_display_cfg.plane.ViewportYStart;
8526 	CalculateSwathAndDETConfiguration_params->ViewportXStartC = mode_lib->ms.cache_display_cfg.plane.ViewportXStartC;
8527 	CalculateSwathAndDETConfiguration_params->ViewportYStartC = mode_lib->ms.cache_display_cfg.plane.ViewportYStartC;
8528 	CalculateSwathAndDETConfiguration_params->SurfaceWidthY = mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY;
8529 	CalculateSwathAndDETConfiguration_params->SurfaceWidthC = mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC;
8530 	CalculateSwathAndDETConfiguration_params->SurfaceHeightY = mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY;
8531 	CalculateSwathAndDETConfiguration_params->SurfaceHeightC = mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC;
8532 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightY = locals->BlockHeight256BytesY;
8533 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightC = locals->BlockHeight256BytesC;
8534 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthY = locals->BlockWidth256BytesY;
8535 	CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthC = locals->BlockWidth256BytesC;
8536 	CalculateSwathAndDETConfiguration_params->ODMMode = mode_lib->ms.cache_display_cfg.hw.ODMMode;
8537 	CalculateSwathAndDETConfiguration_params->BlendingAndTiming = mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming;
8538 	CalculateSwathAndDETConfiguration_params->BytePerPixY = locals->BytePerPixelY;
8539 	CalculateSwathAndDETConfiguration_params->BytePerPixC = locals->BytePerPixelC;
8540 	CalculateSwathAndDETConfiguration_params->BytePerPixDETY = locals->BytePerPixelDETY;
8541 	CalculateSwathAndDETConfiguration_params->BytePerPixDETC = locals->BytePerPixelDETC;
8542 	CalculateSwathAndDETConfiguration_params->HActive = mode_lib->ms.cache_display_cfg.timing.HActive;
8543 	CalculateSwathAndDETConfiguration_params->HRatio = mode_lib->ms.cache_display_cfg.plane.HRatio;
8544 	CalculateSwathAndDETConfiguration_params->HRatioChroma = mode_lib->ms.cache_display_cfg.plane.HRatioChroma;
8545 	CalculateSwathAndDETConfiguration_params->DPPPerSurface = mode_lib->ms.cache_display_cfg.hw.DPPPerSurface;
8546 	CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = s->dummy_long_array[0];
8547 	CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = s->dummy_long_array[1];
8548 	CalculateSwathAndDETConfiguration_params->SwathWidth = s->dummy_long_array[2];
8549 	CalculateSwathAndDETConfiguration_params->SwathWidthChroma = s->dummy_long_array[3];
8550 	CalculateSwathAndDETConfiguration_params->SwathHeightY = locals->SwathHeightY;
8551 	CalculateSwathAndDETConfiguration_params->SwathHeightC = locals->SwathHeightC;
8552 	CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = locals->DETBufferSizeInKByte;
8553 	CalculateSwathAndDETConfiguration_params->DETBufferSizeY = locals->DETBufferSizeY;
8554 	CalculateSwathAndDETConfiguration_params->DETBufferSizeC = locals->DETBufferSizeC;
8555 	CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &locals->UnboundedRequestEnabled;
8556 	CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = &locals->compbuf_reserved_space_64b;
8557 	CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_zs = &locals->compbuf_reserved_space_zs;
8558 	CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &locals->CompressedBufferSizeInkByte;
8559 	CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = &s->dummy_boolean_array[0][0];
8560 	CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &s->dummy_boolean[0];
8561 
8562 	// VBA_DELTA
8563 	// Calculate DET size, swath height here. In VBA, they are calculated in mode check stage
8564 	CalculateSwathAndDETConfiguration(&mode_lib->scratch,
8565 		CalculateSwathAndDETConfiguration_params);
8566 
8567 	// DCFCLK Deep Sleep
8568 	CalculateDCFCLKDeepSleep(
8569 			mode_lib->ms.num_active_planes,
8570 			locals->BytePerPixelY,
8571 			locals->BytePerPixelC,
8572 			mode_lib->ms.cache_display_cfg.plane.VRatio,
8573 			mode_lib->ms.cache_display_cfg.plane.VRatioChroma,
8574 			locals->SwathWidthY,
8575 			locals->SwathWidthC,
8576 			mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
8577 			mode_lib->ms.cache_display_cfg.plane.HRatio,
8578 			mode_lib->ms.cache_display_cfg.plane.HRatioChroma,
8579 			mode_lib->ms.cache_display_cfg.timing.PixelClock,
8580 			locals->PSCL_THROUGHPUT,
8581 			locals->PSCL_THROUGHPUT_CHROMA,
8582 			locals->Dppclk,
8583 			locals->ReadBandwidthSurfaceLuma,
8584 			locals->ReadBandwidthSurfaceChroma,
8585 			mode_lib->ms.soc.return_bus_width_bytes,
8586 
8587 			/* Output */
8588 			&locals->DCFCLKDeepSleep);
8589 
8590 	// DSCCLK
8591 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8592 		if ((mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] != k) || !mode_lib->ms.cache_display_cfg.hw.DSCEnabled[k]) {
8593 			locals->DSCCLK_calculated[k] = 0.0;
8594 		} else {
8595 			if (mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_420)
8596 				s->DSCFormatFactor = 2;
8597 			else if (mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_444)
8598 				s->DSCFormatFactor = 1;
8599 			else if (mode_lib->ms.cache_display_cfg.output.OutputFormat[k] == dml_n422 || mode_lib->ms.cache_display_cfg.output.OutputEncoder[k] == dml_hdmifrl)
8600 				s->DSCFormatFactor = 2;
8601 			else
8602 				s->DSCFormatFactor = 1;
8603 			if (mode_lib->ms.cache_display_cfg.hw.ODMMode[k] == dml_odm_mode_combine_4to1)
8604 				locals->DSCCLK_calculated[k] = mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] / 12 / s->DSCFormatFactor / (1 - mode_lib->ms.soc.dcn_downspread_percent / 100);
8605 			else if (mode_lib->ms.cache_display_cfg.hw.ODMMode[k] == dml_odm_mode_combine_2to1)
8606 				locals->DSCCLK_calculated[k] = mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] / 6 / s->DSCFormatFactor / (1 - mode_lib->ms.soc.dcn_downspread_percent / 100);
8607 			else
8608 				locals->DSCCLK_calculated[k] = mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k] / 3 / s->DSCFormatFactor / (1 - mode_lib->ms.soc.dcn_downspread_percent / 100);
8609 		}
8610 	}
8611 
8612 	// DSC Delay
8613 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8614 		locals->DSCDelay[k] = DSCDelayRequirement(mode_lib->ms.cache_display_cfg.hw.DSCEnabled[k],
8615 												mode_lib->ms.cache_display_cfg.hw.ODMMode[k],
8616 												mode_lib->ms.cache_display_cfg.output.DSCInputBitPerComponent[k],
8617 												mode_lib->ms.cache_display_cfg.output.OutputBpp[k],
8618 												mode_lib->ms.cache_display_cfg.timing.HActive[k],
8619 												mode_lib->ms.cache_display_cfg.timing.HTotal[k],
8620 												mode_lib->ms.cache_display_cfg.hw.NumberOfDSCSlices[k],
8621 												mode_lib->ms.cache_display_cfg.output.OutputFormat[k],
8622 												mode_lib->ms.cache_display_cfg.output.OutputEncoder[k],
8623 												mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
8624 												mode_lib->ms.cache_display_cfg.output.PixelClockBackEnd[k]);
8625 	}
8626 
8627 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k)
8628 		for (j = 0; j < mode_lib->ms.num_active_planes; ++j) // NumberOfSurfaces
8629 			if (j != k && mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == j && mode_lib->ms.cache_display_cfg.hw.DSCEnabled[j])
8630 				locals->DSCDelay[k] = locals->DSCDelay[j];
8631 
8632 	// Prefetch
8633 	CalculateSurfaceSizeInMall(
8634 		mode_lib->ms.num_active_planes,
8635 		mode_lib->ms.soc.mall_allocated_for_dcn_mbytes,
8636 		mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen,
8637 		mode_lib->ms.cache_display_cfg.surface.DCCEnable,
8638 		mode_lib->ms.cache_display_cfg.plane.ViewportStationary,
8639 		mode_lib->ms.cache_display_cfg.plane.ViewportXStart,
8640 		mode_lib->ms.cache_display_cfg.plane.ViewportYStart,
8641 		mode_lib->ms.cache_display_cfg.plane.ViewportXStartC,
8642 		mode_lib->ms.cache_display_cfg.plane.ViewportYStartC,
8643 		mode_lib->ms.cache_display_cfg.plane.ViewportWidth,
8644 		mode_lib->ms.cache_display_cfg.plane.ViewportHeight,
8645 		locals->BytePerPixelY,
8646 		mode_lib->ms.cache_display_cfg.plane.ViewportWidthChroma,
8647 		mode_lib->ms.cache_display_cfg.plane.ViewportHeightChroma,
8648 		locals->BytePerPixelC,
8649 		mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY,
8650 		mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC,
8651 		mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY,
8652 		mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC,
8653 		locals->BlockWidth256BytesY,
8654 		locals->BlockWidth256BytesC,
8655 		locals->BlockHeight256BytesY,
8656 		locals->BlockHeight256BytesC,
8657 		locals->BlockWidthY,
8658 		locals->BlockWidthC,
8659 		locals->BlockHeightY,
8660 		locals->BlockHeightC,
8661 
8662 		/* Output */
8663 		locals->SurfaceSizeInTheMALL,
8664 		&s->dummy_boolean[0]); /* dml_bool_t *ExceededMALLSize */
8665 
8666 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8667 		s->SurfaceParameters[k].PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock[k];
8668 		s->SurfaceParameters[k].DPPPerSurface = mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k];
8669 		s->SurfaceParameters[k].SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan[k];
8670 		s->SurfaceParameters[k].ViewportHeight = mode_lib->ms.cache_display_cfg.plane.ViewportHeight[k];
8671 		s->SurfaceParameters[k].ViewportHeightChroma = mode_lib->ms.cache_display_cfg.plane.ViewportHeightChroma[k];
8672 		s->SurfaceParameters[k].BlockWidth256BytesY = locals->BlockWidth256BytesY[k];
8673 		s->SurfaceParameters[k].BlockHeight256BytesY = locals->BlockHeight256BytesY[k];
8674 		s->SurfaceParameters[k].BlockWidth256BytesC = locals->BlockWidth256BytesC[k];
8675 		s->SurfaceParameters[k].BlockHeight256BytesC = locals->BlockHeight256BytesC[k];
8676 		s->SurfaceParameters[k].BlockWidthY = locals->BlockWidthY[k];
8677 		s->SurfaceParameters[k].BlockHeightY = locals->BlockHeightY[k];
8678 		s->SurfaceParameters[k].BlockWidthC = locals->BlockWidthC[k];
8679 		s->SurfaceParameters[k].BlockHeightC = locals->BlockHeightC[k];
8680 		s->SurfaceParameters[k].InterlaceEnable = mode_lib->ms.cache_display_cfg.timing.Interlace[k];
8681 		s->SurfaceParameters[k].HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal[k];
8682 		s->SurfaceParameters[k].DCCEnable = mode_lib->ms.cache_display_cfg.surface.DCCEnable[k];
8683 		s->SurfaceParameters[k].SourcePixelFormat = mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k];
8684 		s->SurfaceParameters[k].SurfaceTiling = mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k];
8685 		s->SurfaceParameters[k].BytePerPixelY = locals->BytePerPixelY[k];
8686 		s->SurfaceParameters[k].BytePerPixelC = locals->BytePerPixelC[k];
8687 		s->SurfaceParameters[k].ProgressiveToInterlaceUnitInOPP = mode_lib->ms.ip.ptoi_supported;
8688 		s->SurfaceParameters[k].VRatio = mode_lib->ms.cache_display_cfg.plane.VRatio[k];
8689 		s->SurfaceParameters[k].VRatioChroma = mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k];
8690 		s->SurfaceParameters[k].VTaps = mode_lib->ms.cache_display_cfg.plane.VTaps[k];
8691 		s->SurfaceParameters[k].VTapsChroma = mode_lib->ms.cache_display_cfg.plane.VTapsChroma[k];
8692 		s->SurfaceParameters[k].PitchY = mode_lib->ms.cache_display_cfg.surface.PitchY[k];
8693 		s->SurfaceParameters[k].DCCMetaPitchY = mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchY[k];
8694 		s->SurfaceParameters[k].PitchC = mode_lib->ms.cache_display_cfg.surface.PitchC[k];
8695 		s->SurfaceParameters[k].DCCMetaPitchC = mode_lib->ms.cache_display_cfg.surface.DCCMetaPitchC[k];
8696 		s->SurfaceParameters[k].ViewportStationary = mode_lib->ms.cache_display_cfg.plane.ViewportStationary[k];
8697 		s->SurfaceParameters[k].ViewportXStart = mode_lib->ms.cache_display_cfg.plane.ViewportXStart[k];
8698 		s->SurfaceParameters[k].ViewportYStart = mode_lib->ms.cache_display_cfg.plane.ViewportYStart[k];
8699 		s->SurfaceParameters[k].ViewportXStartC = mode_lib->ms.cache_display_cfg.plane.ViewportXStartC[k];
8700 		s->SurfaceParameters[k].ViewportYStartC = mode_lib->ms.cache_display_cfg.plane.ViewportYStartC[k];
8701 		s->SurfaceParameters[k].FORCE_ONE_ROW_FOR_FRAME = mode_lib->ms.cache_display_cfg.plane.ForceOneRowForFrame[k];
8702 		s->SurfaceParameters[k].SwathHeightY = locals->SwathHeightY[k];
8703 		s->SurfaceParameters[k].SwathHeightC = locals->SwathHeightC[k];
8704 	}
8705 
8706 	CalculateVMRowAndSwath_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
8707 	CalculateVMRowAndSwath_params->myPipe = s->SurfaceParameters;
8708 	CalculateVMRowAndSwath_params->SurfaceSizeInMALL = locals->SurfaceSizeInTheMALL;
8709 	CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsLuma = mode_lib->ms.ip.dpte_buffer_size_in_pte_reqs_luma;
8710 	CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsChroma = mode_lib->ms.ip.dpte_buffer_size_in_pte_reqs_chroma;
8711 	CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ms.ip.dcc_meta_buffer_size_bytes;
8712 	CalculateVMRowAndSwath_params->UseMALLForStaticScreen = mode_lib->ms.cache_display_cfg.plane.UseMALLForStaticScreen;
8713 	CalculateVMRowAndSwath_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
8714 	CalculateVMRowAndSwath_params->MALLAllocatedForDCN = mode_lib->ms.soc.mall_allocated_for_dcn_mbytes;
8715 	CalculateVMRowAndSwath_params->SwathWidthY = locals->SwathWidthY;
8716 	CalculateVMRowAndSwath_params->SwathWidthC = locals->SwathWidthC;
8717 	CalculateVMRowAndSwath_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
8718 	CalculateVMRowAndSwath_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
8719 	CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
8720 	CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
8721 	CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
8722 	CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
8723 	CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
8724 	CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
8725 	CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0];
8726 	CalculateVMRowAndSwath_params->DCCMetaBufferSizeNotExceeded = s->dummy_boolean_array[1];
8727 	CalculateVMRowAndSwath_params->dpte_row_width_luma_ub = locals->dpte_row_width_luma_ub;
8728 	CalculateVMRowAndSwath_params->dpte_row_width_chroma_ub = locals->dpte_row_width_chroma_ub;
8729 	CalculateVMRowAndSwath_params->dpte_row_height_luma = locals->dpte_row_height;
8730 	CalculateVMRowAndSwath_params->dpte_row_height_chroma = locals->dpte_row_height_chroma;
8731 	CalculateVMRowAndSwath_params->dpte_row_height_linear_luma = locals->dpte_row_height_linear;
8732 	CalculateVMRowAndSwath_params->dpte_row_height_linear_chroma = locals->dpte_row_height_linear_chroma;
8733 	CalculateVMRowAndSwath_params->meta_req_width = locals->meta_req_width;
8734 	CalculateVMRowAndSwath_params->meta_req_width_chroma = locals->meta_req_width_chroma;
8735 	CalculateVMRowAndSwath_params->meta_req_height = locals->meta_req_height;
8736 	CalculateVMRowAndSwath_params->meta_req_height_chroma = locals->meta_req_height_chroma;
8737 	CalculateVMRowAndSwath_params->meta_row_width = locals->meta_row_width;
8738 	CalculateVMRowAndSwath_params->meta_row_width_chroma = locals->meta_row_width_chroma;
8739 	CalculateVMRowAndSwath_params->meta_row_height = locals->meta_row_height;
8740 	CalculateVMRowAndSwath_params->meta_row_height_chroma = locals->meta_row_height_chroma;
8741 	CalculateVMRowAndSwath_params->vm_group_bytes = locals->vm_group_bytes;
8742 	CalculateVMRowAndSwath_params->dpte_group_bytes = locals->dpte_group_bytes;
8743 	CalculateVMRowAndSwath_params->PixelPTEReqWidthY = locals->PixelPTEReqWidthY;
8744 	CalculateVMRowAndSwath_params->PixelPTEReqHeightY = locals->PixelPTEReqHeightY;
8745 	CalculateVMRowAndSwath_params->PTERequestSizeY = locals->PTERequestSizeY;
8746 	CalculateVMRowAndSwath_params->PixelPTEReqWidthC = locals->PixelPTEReqWidthC;
8747 	CalculateVMRowAndSwath_params->PixelPTEReqHeightC = locals->PixelPTEReqHeightC;
8748 	CalculateVMRowAndSwath_params->PTERequestSizeC = locals->PTERequestSizeC;
8749 	CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_l = locals->dpde0_bytes_per_frame_ub_l;
8750 	CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_l = locals->meta_pte_bytes_per_frame_ub_l;
8751 	CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_c = locals->dpde0_bytes_per_frame_ub_c;
8752 	CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_c = locals->meta_pte_bytes_per_frame_ub_c;
8753 	CalculateVMRowAndSwath_params->PrefetchSourceLinesY = locals->PrefetchSourceLinesY;
8754 	CalculateVMRowAndSwath_params->PrefetchSourceLinesC = locals->PrefetchSourceLinesC;
8755 	CalculateVMRowAndSwath_params->VInitPreFillY = locals->VInitPreFillY;
8756 	CalculateVMRowAndSwath_params->VInitPreFillC = locals->VInitPreFillC;
8757 	CalculateVMRowAndSwath_params->MaxNumSwathY = locals->MaxNumSwathY;
8758 	CalculateVMRowAndSwath_params->MaxNumSwathC = locals->MaxNumSwathC;
8759 	CalculateVMRowAndSwath_params->meta_row_bw = locals->meta_row_bw;
8760 	CalculateVMRowAndSwath_params->dpte_row_bw = locals->dpte_row_bw;
8761 	CalculateVMRowAndSwath_params->PixelPTEBytesPerRow = locals->PixelPTEBytesPerRow;
8762 	CalculateVMRowAndSwath_params->PDEAndMetaPTEBytesFrame = locals->PDEAndMetaPTEBytesFrame;
8763 	CalculateVMRowAndSwath_params->MetaRowByte = locals->MetaRowByte;
8764 	CalculateVMRowAndSwath_params->use_one_row_for_frame = locals->use_one_row_for_frame;
8765 	CalculateVMRowAndSwath_params->use_one_row_for_frame_flip = locals->use_one_row_for_frame_flip;
8766 	CalculateVMRowAndSwath_params->UsesMALLForStaticScreen = locals->UsesMALLForStaticScreen;
8767 	CalculateVMRowAndSwath_params->PTE_BUFFER_MODE = locals->PTE_BUFFER_MODE;
8768 	CalculateVMRowAndSwath_params->BIGK_FRAGMENT_SIZE = locals->BIGK_FRAGMENT_SIZE;
8769 
8770 	CalculateVMRowAndSwath(&mode_lib->scratch,
8771 	CalculateVMRowAndSwath_params);
8772 
8773 	s->ReorderBytes = (dml_uint_t)(mode_lib->ms.soc.num_chans * dml_max3(
8774 			mode_lib->ms.soc.urgent_out_of_order_return_per_channel_pixel_only_bytes,
8775 			mode_lib->ms.soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes,
8776 			mode_lib->ms.soc.urgent_out_of_order_return_per_channel_vm_only_bytes));
8777 
8778 	s->VMDataOnlyReturnBW = dml_get_return_bw_mbps_vm_only(&mode_lib->ms.soc,
8779 																	mode_lib->ms.state.use_ideal_dram_bw_strobe,
8780 																	mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
8781 																	locals->Dcfclk,
8782 																	mode_lib->ms.FabricClock,
8783 																	mode_lib->ms.DRAMSpeed);
8784 
8785 #ifdef __DML_VBA_DEBUG__
8786 	dml_print("DML::%s: locals->Dcfclk = %f\n", __func__, locals->Dcfclk);
8787 	dml_print("DML::%s: mode_lib->ms.soc.return_bus_width_bytes = %u\n", __func__, mode_lib->ms.soc.return_bus_width_bytes);
8788 	dml_print("DML::%s: mode_lib->ms.FabricClock = %f\n", __func__, mode_lib->ms.FabricClock);
8789 	dml_print("DML::%s: mode_lib->ms.soc.fabric_datapath_to_dcn_data_return_bytes = %u\n", __func__, mode_lib->ms.soc.fabric_datapath_to_dcn_data_return_bytes);
8790 	dml_print("DML::%s: mode_lib->ms.soc.pct_ideal_sdp_bw_after_urgent = %f\n", __func__, mode_lib->ms.soc.pct_ideal_sdp_bw_after_urgent);
8791 	dml_print("DML::%s: mode_lib->ms.DRAMSpeed = %f\n", __func__, mode_lib->ms.DRAMSpeed);
8792 	dml_print("DML::%s: mode_lib->ms.soc.num_chans = %u\n", __func__, mode_lib->ms.soc.num_chans);
8793 	dml_print("DML::%s: mode_lib->ms.soc.dram_channel_width_bytes = %u\n", __func__, mode_lib->ms.soc.dram_channel_width_bytes);
8794 	dml_print("DML::%s: mode_lib->ms.state_idx = %u\n", __func__, mode_lib->ms.state_idx);
8795 	dml_print("DML::%s: mode_lib->ms.max_state_idx = %u\n", __func__, mode_lib->ms.max_state_idx);
8796 	dml_print("DML::%s: mode_lib->ms.state.use_ideal_dram_bw_strobe = %u\n", __func__, mode_lib->ms.state.use_ideal_dram_bw_strobe);
8797 	dml_print("DML::%s: VMDataOnlyReturnBW = %f\n", __func__, s->VMDataOnlyReturnBW);
8798 	dml_print("DML::%s: ReturnBW = %f\n",  __func__, mode_lib->ms.ReturnBW);
8799 #endif
8800 
8801 	s->HostVMInefficiencyFactor = 1.0;
8802 	if (mode_lib->ms.cache_display_cfg.plane.GPUVMEnable && mode_lib->ms.cache_display_cfg.plane.HostVMEnable)
8803 		s->HostVMInefficiencyFactor = mode_lib->ms.ReturnBW / s->VMDataOnlyReturnBW;
8804 
8805 	s->TotalDCCActiveDPP = 0;
8806 	s->TotalActiveDPP = 0;
8807 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8808 		s->TotalActiveDPP = s->TotalActiveDPP + mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k];
8809 		if (mode_lib->ms.cache_display_cfg.surface.DCCEnable[k])
8810 			s->TotalDCCActiveDPP = s->TotalDCCActiveDPP + mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k];
8811 	}
8812 
8813 	locals->UrgentExtraLatency = CalculateExtraLatency(
8814 			mode_lib->ms.soc.round_trip_ping_latency_dcfclk_cycles,
8815 			s->ReorderBytes,
8816 			locals->Dcfclk,
8817 			s->TotalActiveDPP,
8818 			mode_lib->ms.ip.pixel_chunk_size_kbytes,
8819 			s->TotalDCCActiveDPP,
8820 			mode_lib->ms.ip.meta_chunk_size_kbytes,
8821 			mode_lib->ms.ReturnBW,
8822 			mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
8823 			mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
8824 			mode_lib->ms.num_active_planes,
8825 			mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
8826 			locals->dpte_group_bytes,
8827 			s->HostVMInefficiencyFactor,
8828 			mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
8829 			mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
8830 
8831 	locals->TCalc = 24.0 / locals->DCFCLKDeepSleep;
8832 
8833 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8834 		if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == k) {
8835 			if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
8836 				locals->WritebackDelay[k] =
8837 						mode_lib->ms.state.writeback_latency_us
8838 								+ CalculateWriteBackDelay(
8839 										mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[k],
8840 										mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[k],
8841 										mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[k],
8842 										mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[k],
8843 										mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k],
8844 										mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[k],
8845 										mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[k],
8846 										mode_lib->ms.cache_display_cfg.timing.HTotal[k]) / locals->Dispclk;
8847 			} else
8848 				locals->WritebackDelay[k] = 0;
8849 			for (j = 0; j < mode_lib->ms.num_active_planes; ++j) {
8850 				if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[j] == k
8851 						&& mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[j] == true) {
8852 					locals->WritebackDelay[k] =
8853 							dml_max(
8854 									locals->WritebackDelay[k],
8855 									mode_lib->ms.state.writeback_latency_us
8856 											+ CalculateWriteBackDelay(
8857 													mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[j],
8858 													mode_lib->ms.cache_display_cfg.writeback.WritebackHRatio[j],
8859 													mode_lib->ms.cache_display_cfg.writeback.WritebackVRatio[j],
8860 													mode_lib->ms.cache_display_cfg.writeback.WritebackVTaps[j],
8861 													mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[j],
8862 													mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[j],
8863 													mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[j],
8864 													mode_lib->ms.cache_display_cfg.timing.HTotal[k]) / locals->Dispclk);
8865 				}
8866 			}
8867 		}
8868 	}
8869 
8870 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k)
8871 		for (j = 0; j < mode_lib->ms.num_active_planes; ++j)
8872 			if (mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming[k] == j)
8873 				locals->WritebackDelay[k] = locals->WritebackDelay[j];
8874 
8875 	locals->UrgentLatency = CalculateUrgentLatency(mode_lib->ms.state.urgent_latency_pixel_data_only_us,
8876 												mode_lib->ms.state.urgent_latency_pixel_mixed_with_vm_data_us,
8877 												mode_lib->ms.state.urgent_latency_vm_data_only_us,
8878 												mode_lib->ms.soc.do_urgent_latency_adjustment,
8879 												mode_lib->ms.state.urgent_latency_adjustment_fabric_clock_component_us,
8880 												mode_lib->ms.state.urgent_latency_adjustment_fabric_clock_reference_mhz,
8881 												mode_lib->ms.FabricClock);
8882 
8883 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8884 		CalculateUrgentBurstFactor(mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k],
8885 									locals->swath_width_luma_ub[k],
8886 									locals->swath_width_chroma_ub[k],
8887 									locals->SwathHeightY[k],
8888 									locals->SwathHeightC[k],
8889 									mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
8890 									locals->UrgentLatency,
8891 									mode_lib->ms.ip.cursor_buffer_size,
8892 									mode_lib->ms.cache_display_cfg.plane.CursorWidth[k],
8893 									mode_lib->ms.cache_display_cfg.plane.CursorBPP[k],
8894 									mode_lib->ms.cache_display_cfg.plane.VRatio[k],
8895 									mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k],
8896 									locals->BytePerPixelDETY[k],
8897 									locals->BytePerPixelDETC[k],
8898 									locals->DETBufferSizeY[k],
8899 									locals->DETBufferSizeC[k],
8900 
8901 									/* output */
8902 									&locals->UrgBurstFactorCursor[k],
8903 									&locals->UrgBurstFactorLuma[k],
8904 									&locals->UrgBurstFactorChroma[k],
8905 									&locals->NoUrgentLatencyHiding[k]);
8906 
8907 		locals->cursor_bw[k] = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k] * mode_lib->ms.cache_display_cfg.plane.CursorWidth[k] * mode_lib->ms.cache_display_cfg.plane.CursorBPP[k] / 8.0 /
8908 								((dml_float_t) mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * mode_lib->ms.cache_display_cfg.plane.VRatio[k];
8909 	}
8910 
8911 	s->VStartupLines = __DML_VBA_MIN_VSTARTUP__;
8912 	s->MaxVStartupAllPlanes = 0;
8913 
8914 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8915 		s->MaxVStartupLines[k] = CalculateMaxVStartup(k,
8916 													mode_lib->ms.ip.ptoi_supported,
8917 													mode_lib->ms.ip.vblank_nom_default_us,
8918 													&mode_lib->ms.cache_display_cfg.timing,
8919 													locals->WritebackDelay[k]);
8920 
8921 #ifdef __DML_VBA_DEBUG__
8922 		dml_print("DML::%s: k=%u MaxVStartupLines   = %u\n", __func__, k, s->MaxVStartupLines[k]);
8923 		dml_print("DML::%s: k=%u WritebackDelay     = %f\n", __func__, k, locals->WritebackDelay[k]);
8924 #endif
8925 	}
8926 
8927 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k)
8928 		s->MaxVStartupAllPlanes = (dml_uint_t)(dml_max(s->MaxVStartupAllPlanes, s->MaxVStartupLines[k]));
8929 
8930 	s->ImmediateFlipRequirementFinal = false;
8931 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8932 		s->ImmediateFlipRequirementFinal = s->ImmediateFlipRequirementFinal || (mode_lib->ms.policy.ImmediateFlipRequirement[k] == dml_immediate_flip_required);
8933 	}
8934 #ifdef __DML_VBA_DEBUG__
8935 	dml_print("DML::%s: ImmediateFlipRequirementFinal = %u\n", __func__, s->ImmediateFlipRequirementFinal);
8936 #endif
8937 
8938 	// The prefetch scheduling should only be calculated once as per AllowForPStateChangeOrStutterInVBlank requirement
8939 	// If the AllowForPStateChangeOrStutterInVBlank requirement is not strict (i.e. only try those power saving feature
8940 	// if possible, then will try to program for the best power saving features in order of difficulty (dram, fclk, stutter)
8941 	s->iteration = 0;
8942 	s->MaxTotalRDBandwidth = 0;
8943 	s->AllPrefetchModeTested = false;
8944 	for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
8945 		CalculatePrefetchMode(mode_lib->ms.policy.AllowForPStateChangeOrStutterInVBlank[k], &s->MinPrefetchMode[k], &s->MaxPrefetchMode[k]);
8946 		s->NextPrefetchMode[k] = s->MinPrefetchMode[k];
8947 	}
8948 
8949 	do {
8950 		s->MaxTotalRDBandwidthNoUrgentBurst = 0.0;
8951 		s->DestinationLineTimesForPrefetchLessThan2 = false;
8952 		s->VRatioPrefetchMoreThanMax = false;
8953 
8954 		dml_print("DML::%s: Start one iteration: VStartupLines = %u\n", __func__, s->VStartupLines);
8955 
8956 		s->AllPrefetchModeTested = true;
8957 		s->MaxTotalRDBandwidth = 0;
8958 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
8959 			locals->PrefetchMode[k] = s->NextPrefetchMode[k];
8960 			TWait = CalculateTWait(
8961 					locals->PrefetchMode[k],
8962 					mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k],
8963 					mode_lib->ms.policy.SynchronizeDRRDisplaysForUCLKPStateChangeFinal,
8964 					mode_lib->ms.cache_display_cfg.timing.DRRDisplay[k],
8965 					mode_lib->ms.state.dram_clock_change_latency_us,
8966 					mode_lib->ms.state.fclk_change_latency_us,
8967 					locals->UrgentLatency,
8968 					mode_lib->ms.state.sr_enter_plus_exit_time_us);
8969 
8970 			myPipe = &s->myPipe;
8971 			myPipe->Dppclk = locals->Dppclk[k];
8972 			myPipe->Dispclk = locals->Dispclk;
8973 			myPipe->PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock[k];
8974 			myPipe->DCFClkDeepSleep = locals->DCFCLKDeepSleep;
8975 			myPipe->DPPPerSurface = mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k];
8976 			myPipe->ScalerEnabled = mode_lib->ms.cache_display_cfg.plane.ScalerEnabled[k];
8977 			myPipe->SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan[k];
8978 			myPipe->BlockWidth256BytesY = locals->BlockWidth256BytesY[k];
8979 			myPipe->BlockHeight256BytesY = locals->BlockHeight256BytesY[k];
8980 			myPipe->BlockWidth256BytesC = locals->BlockWidth256BytesC[k];
8981 			myPipe->BlockHeight256BytesC = locals->BlockHeight256BytesC[k];
8982 			myPipe->InterlaceEnable = mode_lib->ms.cache_display_cfg.timing.Interlace[k];
8983 			myPipe->NumberOfCursors = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k];
8984 			myPipe->VBlank = mode_lib->ms.cache_display_cfg.timing.VTotal[k] - mode_lib->ms.cache_display_cfg.timing.VActive[k];
8985 			myPipe->HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal[k];
8986 			myPipe->HActive = mode_lib->ms.cache_display_cfg.timing.HActive[k];
8987 			myPipe->DCCEnable = mode_lib->ms.cache_display_cfg.surface.DCCEnable[k];
8988 			myPipe->ODMMode = mode_lib->ms.cache_display_cfg.hw.ODMMode[k];
8989 			myPipe->SourcePixelFormat = mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k];
8990 			myPipe->BytePerPixelY = locals->BytePerPixelY[k];
8991 			myPipe->BytePerPixelC = locals->BytePerPixelC[k];
8992 			myPipe->ProgressiveToInterlaceUnitInOPP = mode_lib->ms.ip.ptoi_supported;
8993 
8994 #ifdef __DML_VBA_DEBUG__
8995 			dml_print("DML::%s: Calling CalculatePrefetchSchedule for k=%u\n", __func__, k);
8996 			dml_print("DML::%s: AllowForPStateChangeOrStutterInVBlank = %u\n", __func__, mode_lib->ms.policy.AllowForPStateChangeOrStutterInVBlank[k]);
8997 			dml_print("DML::%s: PrefetchMode[k] = %u (Min=%u Max=%u)\n", __func__, locals->PrefetchMode[k], s->MinPrefetchMode[k], s->MaxPrefetchMode[k]);
8998 #endif
8999 
9000 			CalculatePrefetchSchedule_params->EnhancedPrefetchScheduleAccelerationFinal = mode_lib->ms.policy.EnhancedPrefetchScheduleAccelerationFinal;
9001 			CalculatePrefetchSchedule_params->HostVMInefficiencyFactor = s->HostVMInefficiencyFactor;
9002 			CalculatePrefetchSchedule_params->myPipe = myPipe;
9003 			CalculatePrefetchSchedule_params->DSCDelay = locals->DSCDelay[k];
9004 			CalculatePrefetchSchedule_params->DPPCLKDelaySubtotalPlusCNVCFormater = mode_lib->ms.ip.dppclk_delay_subtotal + mode_lib->ms.ip.dppclk_delay_cnvc_formatter;
9005 			CalculatePrefetchSchedule_params->DPPCLKDelaySCL = mode_lib->ms.ip.dppclk_delay_scl;
9006 			CalculatePrefetchSchedule_params->DPPCLKDelaySCLLBOnly = mode_lib->ms.ip.dppclk_delay_scl_lb_only;
9007 			CalculatePrefetchSchedule_params->DPPCLKDelayCNVCCursor = mode_lib->ms.ip.dppclk_delay_cnvc_cursor;
9008 			CalculatePrefetchSchedule_params->DISPCLKDelaySubtotal = mode_lib->ms.ip.dispclk_delay_subtotal;
9009 			CalculatePrefetchSchedule_params->DPP_RECOUT_WIDTH = (dml_uint_t)(locals->SwathWidthY[k] / mode_lib->ms.cache_display_cfg.plane.HRatio[k]);
9010 			CalculatePrefetchSchedule_params->OutputFormat = mode_lib->ms.cache_display_cfg.output.OutputFormat[k];
9011 			CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ms.ip.max_inter_dcn_tile_repeaters;
9012 			CalculatePrefetchSchedule_params->VStartup = (dml_uint_t)(dml_min(s->VStartupLines, s->MaxVStartupLines[k]));
9013 			CalculatePrefetchSchedule_params->MaxVStartup = s->MaxVStartupLines[k];
9014 			CalculatePrefetchSchedule_params->GPUVMPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
9015 			CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
9016 			CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
9017 			CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
9018 			CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
9019 			CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k];
9020 			CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
9021 			CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k];
9022 			CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataTransmittedBytes[k];
9023 			CalculatePrefetchSchedule_params->UrgentLatency = locals->UrgentLatency;
9024 			CalculatePrefetchSchedule_params->UrgentExtraLatency = locals->UrgentExtraLatency;
9025 			CalculatePrefetchSchedule_params->TCalc = locals->TCalc;
9026 			CalculatePrefetchSchedule_params->PDEAndMetaPTEBytesFrame = locals->PDEAndMetaPTEBytesFrame[k];
9027 			CalculatePrefetchSchedule_params->MetaRowByte = locals->MetaRowByte[k];
9028 			CalculatePrefetchSchedule_params->PixelPTEBytesPerRow = locals->PixelPTEBytesPerRow[k];
9029 			CalculatePrefetchSchedule_params->PrefetchSourceLinesY = locals->PrefetchSourceLinesY[k];
9030 			CalculatePrefetchSchedule_params->VInitPreFillY = locals->VInitPreFillY[k];
9031 			CalculatePrefetchSchedule_params->MaxNumSwathY = locals->MaxNumSwathY[k];
9032 			CalculatePrefetchSchedule_params->PrefetchSourceLinesC = locals->PrefetchSourceLinesC[k];
9033 			CalculatePrefetchSchedule_params->VInitPreFillC = locals->VInitPreFillC[k];
9034 			CalculatePrefetchSchedule_params->MaxNumSwathC = locals->MaxNumSwathC[k];
9035 			CalculatePrefetchSchedule_params->swath_width_luma_ub = locals->swath_width_luma_ub[k];
9036 			CalculatePrefetchSchedule_params->swath_width_chroma_ub = locals->swath_width_chroma_ub[k];
9037 			CalculatePrefetchSchedule_params->SwathHeightY = locals->SwathHeightY[k];
9038 			CalculatePrefetchSchedule_params->SwathHeightC = locals->SwathHeightC[k];
9039 			CalculatePrefetchSchedule_params->TWait = TWait;
9040 			CalculatePrefetchSchedule_params->DSTXAfterScaler = &locals->DSTXAfterScaler[k];
9041 			CalculatePrefetchSchedule_params->DSTYAfterScaler = &locals->DSTYAfterScaler[k];
9042 			CalculatePrefetchSchedule_params->DestinationLinesForPrefetch = &locals->DestinationLinesForPrefetch[k];
9043 			CalculatePrefetchSchedule_params->DestinationLinesToRequestVMInVBlank = &locals->DestinationLinesToRequestVMInVBlank[k];
9044 			CalculatePrefetchSchedule_params->DestinationLinesToRequestRowInVBlank = &locals->DestinationLinesToRequestRowInVBlank[k];
9045 			CalculatePrefetchSchedule_params->VRatioPrefetchY = &locals->VRatioPrefetchY[k];
9046 			CalculatePrefetchSchedule_params->VRatioPrefetchC = &locals->VRatioPrefetchC[k];
9047 			CalculatePrefetchSchedule_params->RequiredPrefetchPixDataBWLuma = &locals->RequiredPrefetchPixDataBWLuma[k];
9048 			CalculatePrefetchSchedule_params->RequiredPrefetchPixDataBWChroma = &locals->RequiredPrefetchPixDataBWChroma[k];
9049 			CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &locals->NotEnoughTimeForDynamicMetadata[k];
9050 			CalculatePrefetchSchedule_params->Tno_bw = &locals->Tno_bw[k];
9051 			CalculatePrefetchSchedule_params->prefetch_vmrow_bw = &locals->prefetch_vmrow_bw[k];
9052 			CalculatePrefetchSchedule_params->Tdmdl_vm = &locals->Tdmdl_vm[k];
9053 			CalculatePrefetchSchedule_params->Tdmdl = &locals->Tdmdl[k];
9054 			CalculatePrefetchSchedule_params->TSetup = &locals->TSetup[k];
9055 			CalculatePrefetchSchedule_params->VUpdateOffsetPix = &locals->VUpdateOffsetPix[k];
9056 			CalculatePrefetchSchedule_params->VUpdateWidthPix = &locals->VUpdateWidthPix[k];
9057 			CalculatePrefetchSchedule_params->VReadyOffsetPix = &locals->VReadyOffsetPix[k];
9058 
9059 			locals->NoTimeToPrefetch[k] =
9060 				CalculatePrefetchSchedule(&mode_lib->scratch,
9061 					CalculatePrefetchSchedule_params);
9062 
9063 #ifdef __DML_VBA_DEBUG__
9064 			dml_print("DML::%s: k=%0u NoTimeToPrefetch=%0d\n", __func__, k, locals->NoTimeToPrefetch[k]);
9065 #endif
9066 			locals->VStartup[k] = (dml_uint_t)(dml_min(s->VStartupLines, s->MaxVStartupLines[k]));
9067 			locals->VStartupMin[k] = locals->VStartup[k];
9068 		}
9069 
9070 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9071 			CalculateUrgentBurstFactor(
9072 				mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k],
9073 				locals->swath_width_luma_ub[k],
9074 				locals->swath_width_chroma_ub[k],
9075 				locals->SwathHeightY[k],
9076 				locals->SwathHeightC[k],
9077 				mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
9078 				locals->UrgentLatency,
9079 				mode_lib->ms.ip.cursor_buffer_size,
9080 				mode_lib->ms.cache_display_cfg.plane.CursorWidth[k],
9081 				mode_lib->ms.cache_display_cfg.plane.CursorBPP[k],
9082 				locals->VRatioPrefetchY[k],
9083 				locals->VRatioPrefetchC[k],
9084 				locals->BytePerPixelDETY[k],
9085 				locals->BytePerPixelDETC[k],
9086 				locals->DETBufferSizeY[k],
9087 				locals->DETBufferSizeC[k],
9088 				/* Output */
9089 				&locals->UrgBurstFactorCursorPre[k],
9090 				&locals->UrgBurstFactorLumaPre[k],
9091 				&locals->UrgBurstFactorChromaPre[k],
9092 				&locals->NoUrgentLatencyHidingPre[k]);
9093 
9094 			locals->cursor_bw_pre[k] = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k] * mode_lib->ms.cache_display_cfg.plane.CursorWidth[k] * mode_lib->ms.cache_display_cfg.plane.CursorBPP[k] / 8.0 / (mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * locals->VRatioPrefetchY[k];
9095 
9096 #ifdef __DML_VBA_DEBUG__
9097 			dml_print("DML::%s: k=%0u DPPPerSurface=%u\n", __func__, k, mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k]);
9098 			dml_print("DML::%s: k=%0u UrgBurstFactorLuma=%f\n", __func__, k, locals->UrgBurstFactorLuma[k]);
9099 			dml_print("DML::%s: k=%0u UrgBurstFactorChroma=%f\n", __func__, k, locals->UrgBurstFactorChroma[k]);
9100 			dml_print("DML::%s: k=%0u UrgBurstFactorLumaPre=%f\n", __func__, k, locals->UrgBurstFactorLumaPre[k]);
9101 			dml_print("DML::%s: k=%0u UrgBurstFactorChromaPre=%f\n", __func__, k, locals->UrgBurstFactorChromaPre[k]);
9102 
9103 			dml_print("DML::%s: k=%0u VRatioPrefetchY=%f\n", __func__, k, locals->VRatioPrefetchY[k]);
9104 			dml_print("DML::%s: k=%0u VRatioY=%f\n", __func__, k, mode_lib->ms.cache_display_cfg.plane.VRatio[k]);
9105 
9106 			dml_print("DML::%s: k=%0u prefetch_vmrow_bw=%f\n", __func__, k, locals->prefetch_vmrow_bw[k]);
9107 			dml_print("DML::%s: k=%0u ReadBandwidthSurfaceLuma=%f\n", __func__, k, locals->ReadBandwidthSurfaceLuma[k]);
9108 			dml_print("DML::%s: k=%0u ReadBandwidthSurfaceChroma=%f\n", __func__, k, locals->ReadBandwidthSurfaceChroma[k]);
9109 			dml_print("DML::%s: k=%0u cursor_bw=%f\n", __func__, k, locals->cursor_bw[k]);
9110 			dml_print("DML::%s: k=%0u meta_row_bw=%f\n", __func__, k, locals->meta_row_bw[k]);
9111 			dml_print("DML::%s: k=%0u dpte_row_bw=%f\n", __func__, k, locals->dpte_row_bw[k]);
9112 			dml_print("DML::%s: k=%0u RequiredPrefetchPixDataBWLuma=%f\n", __func__, k, locals->RequiredPrefetchPixDataBWLuma[k]);
9113 			dml_print("DML::%s: k=%0u RequiredPrefetchPixDataBWChroma=%f\n", __func__, k, locals->RequiredPrefetchPixDataBWChroma[k]);
9114 			dml_print("DML::%s: k=%0u cursor_bw_pre=%f\n", __func__, k, locals->cursor_bw_pre[k]);
9115 			dml_print("DML::%s: k=%0u MaxTotalRDBandwidthNoUrgentBurst=%f\n", __func__, k, s->MaxTotalRDBandwidthNoUrgentBurst);
9116 #endif
9117 			if (locals->DestinationLinesForPrefetch[k] < 2)
9118 				s->DestinationLineTimesForPrefetchLessThan2 = true;
9119 
9120 			if (locals->VRatioPrefetchY[k] > __DML_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__ ||
9121 				locals->VRatioPrefetchC[k] > __DML_MAX_VRATIO_PRE_ENHANCE_PREFETCH_ACC__ ||
9122 				((s->VStartupLines < s->MaxVStartupLines[k] || mode_lib->ms.policy.EnhancedPrefetchScheduleAccelerationFinal == 0) &&
9123 					(locals->VRatioPrefetchY[k] > __DML_MAX_VRATIO_PRE__ || locals->VRatioPrefetchC[k] > __DML_MAX_VRATIO_PRE__)))
9124 				s->VRatioPrefetchMoreThanMax = true;
9125 
9126 			//dml_bool_t DestinationLinesToRequestVMInVBlankEqualOrMoreThan32 = false;
9127 			//dml_bool_t DestinationLinesToRequestRowInVBlankEqualOrMoreThan16 = false;
9128 			//if (locals->DestinationLinesToRequestVMInVBlank[k] >= 32) {
9129 			//    DestinationLinesToRequestVMInVBlankEqualOrMoreThan32 = true;
9130 			//}
9131 
9132 			//if (locals->DestinationLinesToRequestRowInVBlank[k] >= 16) {
9133 			//    DestinationLinesToRequestRowInVBlankEqualOrMoreThan16 = true;
9134 			//}
9135 		}
9136 
9137 		locals->FractionOfUrgentBandwidth = s->MaxTotalRDBandwidthNoUrgentBurst / mode_lib->ms.ReturnBW;
9138 
9139 #ifdef __DML_VBA_DEBUG__
9140 		dml_print("DML::%s: MaxTotalRDBandwidthNoUrgentBurst=%f \n", __func__, s->MaxTotalRDBandwidthNoUrgentBurst);
9141 		dml_print("DML::%s: ReturnBW=%f \n", __func__, mode_lib->ms.ReturnBW);
9142 		dml_print("DML::%s: FractionOfUrgentBandwidth=%f \n", __func__, locals->FractionOfUrgentBandwidth);
9143 #endif
9144 
9145 		CalculatePrefetchBandwithSupport(
9146 			mode_lib->ms.num_active_planes,
9147 			mode_lib->ms.ReturnBW,
9148 			mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange,
9149 			locals->NoUrgentLatencyHidingPre,
9150 			locals->ReadBandwidthSurfaceLuma,
9151 			locals->ReadBandwidthSurfaceChroma,
9152 			locals->RequiredPrefetchPixDataBWLuma,
9153 			locals->RequiredPrefetchPixDataBWChroma,
9154 			locals->cursor_bw,
9155 			locals->meta_row_bw,
9156 			locals->dpte_row_bw,
9157 			locals->cursor_bw_pre,
9158 			locals->prefetch_vmrow_bw,
9159 			mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
9160 			locals->UrgBurstFactorLuma,
9161 			locals->UrgBurstFactorChroma,
9162 			locals->UrgBurstFactorCursor,
9163 			locals->UrgBurstFactorLumaPre,
9164 			locals->UrgBurstFactorChromaPre,
9165 			locals->UrgBurstFactorCursorPre,
9166 
9167 			/* output */
9168 			&s->MaxTotalRDBandwidth, // dml_float_t *PrefetchBandwidth
9169 			&s->MaxTotalRDBandwidthNotIncludingMALLPrefetch, // dml_float_t *PrefetchBandwidthNotIncludingMALLPrefetch
9170 			&s->dummy_single[0], // dml_float_t *FractionOfUrgentBandwidth
9171 			&locals->PrefetchModeSupported);
9172 
9173 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k)
9174 			s->dummy_unit_vector[k] = 1.0;
9175 
9176 		CalculatePrefetchBandwithSupport(mode_lib->ms.num_active_planes,
9177 			mode_lib->ms.ReturnBW,
9178 			mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange,
9179 			locals->NoUrgentLatencyHidingPre,
9180 			locals->ReadBandwidthSurfaceLuma,
9181 			locals->ReadBandwidthSurfaceChroma,
9182 			locals->RequiredPrefetchPixDataBWLuma,
9183 			locals->RequiredPrefetchPixDataBWChroma,
9184 			locals->cursor_bw,
9185 			locals->meta_row_bw,
9186 			locals->dpte_row_bw,
9187 			locals->cursor_bw_pre,
9188 			locals->prefetch_vmrow_bw,
9189 			mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
9190 			s->dummy_unit_vector,
9191 			s->dummy_unit_vector,
9192 			s->dummy_unit_vector,
9193 			s->dummy_unit_vector,
9194 			s->dummy_unit_vector,
9195 			s->dummy_unit_vector,
9196 
9197 			/* output */
9198 			&s->NonUrgentMaxTotalRDBandwidth, // dml_float_t *PrefetchBandwidth
9199 			&s->NonUrgentMaxTotalRDBandwidthNotIncludingMALLPrefetch, // dml_float_t *PrefetchBandwidthNotIncludingMALLPrefetch
9200 			&locals->FractionOfUrgentBandwidth,
9201 			&s->dummy_boolean[0]); // dml_bool_t *PrefetchBandwidthSupport
9202 
9203 
9204 
9205 		if (s->VRatioPrefetchMoreThanMax != false || s->DestinationLineTimesForPrefetchLessThan2 != false) {
9206 			dml_print("DML::%s: VRatioPrefetchMoreThanMax                   = %u\n", __func__, s->VRatioPrefetchMoreThanMax);
9207 			dml_print("DML::%s: DestinationLineTimesForPrefetchLessThan2    = %u\n", __func__, s->DestinationLineTimesForPrefetchLessThan2);
9208 			locals->PrefetchModeSupported = false;
9209 		}
9210 
9211 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9212 			if (locals->NoTimeToPrefetch[k] == true || locals->NotEnoughTimeForDynamicMetadata[k]) {
9213 				dml_print("DML::%s: k=%u, NoTimeToPrefetch = %0d\n", __func__, k, locals->NoTimeToPrefetch[k]);
9214 				dml_print("DML::%s: k=%u, NotEnoughTimeForDynamicMetadata=%u\n", __func__, k, locals->NotEnoughTimeForDynamicMetadata[k]);
9215 				locals->PrefetchModeSupported = false;
9216 			}
9217 		}
9218 
9219 
9220 		if (locals->PrefetchModeSupported == true && mode_lib->ms.support.ImmediateFlipSupport == true) {
9221 			locals->BandwidthAvailableForImmediateFlip = CalculateBandwidthAvailableForImmediateFlip(
9222 																	mode_lib->ms.num_active_planes,
9223 																	mode_lib->ms.ReturnBW,
9224 																	locals->ReadBandwidthSurfaceLuma,
9225 																	locals->ReadBandwidthSurfaceChroma,
9226 																	locals->RequiredPrefetchPixDataBWLuma,
9227 																	locals->RequiredPrefetchPixDataBWChroma,
9228 																	locals->cursor_bw,
9229 																	locals->cursor_bw_pre,
9230 																	mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
9231 																	locals->UrgBurstFactorLuma,
9232 																	locals->UrgBurstFactorChroma,
9233 																	locals->UrgBurstFactorCursor,
9234 																	locals->UrgBurstFactorLumaPre,
9235 																	locals->UrgBurstFactorChromaPre,
9236 																	locals->UrgBurstFactorCursorPre);
9237 
9238 			locals->TotImmediateFlipBytes = 0;
9239 			for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9240 				if (mode_lib->ms.policy.ImmediateFlipRequirement[k] != dml_immediate_flip_not_required) {
9241 					locals->TotImmediateFlipBytes = locals->TotImmediateFlipBytes + mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k] * (locals->PDEAndMetaPTEBytesFrame[k] + locals->MetaRowByte[k]);
9242 					if (locals->use_one_row_for_frame_flip[k]) {
9243 						locals->TotImmediateFlipBytes = locals->TotImmediateFlipBytes + mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k] * (2 * locals->PixelPTEBytesPerRow[k]);
9244 					} else {
9245 						locals->TotImmediateFlipBytes = locals->TotImmediateFlipBytes + mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k] * locals->PixelPTEBytesPerRow[k];
9246 					}
9247 #ifdef __DML_VBA_DEBUG__
9248 					dml_print("DML::%s: k = %u\n", __func__, k);
9249 					dml_print("DML::%s: DPPPerSurface = %u\n", __func__, mode_lib->ms.cache_display_cfg.hw.DPPPerSurface[k]);
9250 					dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %u\n", __func__, locals->PDEAndMetaPTEBytesFrame[k]);
9251 					dml_print("DML::%s: MetaRowByte = %u\n", __func__, locals->MetaRowByte[k]);
9252 					dml_print("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, locals->PixelPTEBytesPerRow[k]);
9253 					dml_print("DML::%s: TotImmediateFlipBytes = %u\n", __func__, locals->TotImmediateFlipBytes);
9254 #endif
9255 				}
9256 			}
9257 			for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9258 				CalculateFlipSchedule(
9259 						s->HostVMInefficiencyFactor,
9260 						locals->UrgentExtraLatency,
9261 						locals->UrgentLatency,
9262 						mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels,
9263 						mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
9264 						mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
9265 						mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
9266 						mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
9267 						locals->PDEAndMetaPTEBytesFrame[k],
9268 						locals->MetaRowByte[k],
9269 						locals->PixelPTEBytesPerRow[k],
9270 						locals->BandwidthAvailableForImmediateFlip,
9271 						locals->TotImmediateFlipBytes,
9272 						mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k],
9273 						mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k],
9274 						mode_lib->ms.cache_display_cfg.plane.VRatio[k],
9275 						mode_lib->ms.cache_display_cfg.plane.VRatioChroma[k],
9276 						locals->Tno_bw[k],
9277 						mode_lib->ms.cache_display_cfg.surface.DCCEnable[k],
9278 						locals->dpte_row_height[k],
9279 						locals->meta_row_height[k],
9280 						locals->dpte_row_height_chroma[k],
9281 						locals->meta_row_height_chroma[k],
9282 						locals->use_one_row_for_frame_flip[k],
9283 
9284 						/* Output */
9285 						&locals->DestinationLinesToRequestVMInImmediateFlip[k],
9286 						&locals->DestinationLinesToRequestRowInImmediateFlip[k],
9287 						&locals->final_flip_bw[k],
9288 						&locals->ImmediateFlipSupportedForPipe[k]);
9289 			}
9290 
9291 			CalculateImmediateFlipBandwithSupport(mode_lib->ms.num_active_planes,
9292 												mode_lib->ms.ReturnBW,
9293 												mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange,
9294 												mode_lib->ms.policy.ImmediateFlipRequirement,
9295 												locals->final_flip_bw,
9296 												locals->ReadBandwidthSurfaceLuma,
9297 												locals->ReadBandwidthSurfaceChroma,
9298 												locals->RequiredPrefetchPixDataBWLuma,
9299 												locals->RequiredPrefetchPixDataBWChroma,
9300 												locals->cursor_bw,
9301 												locals->meta_row_bw,
9302 												locals->dpte_row_bw,
9303 												locals->cursor_bw_pre,
9304 												locals->prefetch_vmrow_bw,
9305 												mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
9306 												locals->UrgBurstFactorLuma,
9307 												locals->UrgBurstFactorChroma,
9308 												locals->UrgBurstFactorCursor,
9309 												locals->UrgBurstFactorLumaPre,
9310 												locals->UrgBurstFactorChromaPre,
9311 												locals->UrgBurstFactorCursorPre,
9312 
9313 												/* output */
9314 												&locals->total_dcn_read_bw_with_flip, // dml_float_t *TotalBandwidth
9315 												&locals->total_dcn_read_bw_with_flip_not_including_MALL_prefetch, // dml_float_t TotalBandwidthNotIncludingMALLPrefetch
9316 												&s->dummy_single[0], // dml_float_t *FractionOfUrgentBandwidth
9317 												&locals->ImmediateFlipSupported); // dml_bool_t *ImmediateFlipBandwidthSupport
9318 
9319 			CalculateImmediateFlipBandwithSupport(mode_lib->ms.num_active_planes,
9320 				mode_lib->ms.ReturnBW,
9321 				mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange,
9322 				mode_lib->ms.policy.ImmediateFlipRequirement,
9323 				locals->final_flip_bw,
9324 				locals->ReadBandwidthSurfaceLuma,
9325 				locals->ReadBandwidthSurfaceChroma,
9326 				locals->RequiredPrefetchPixDataBWLuma,
9327 				locals->RequiredPrefetchPixDataBWChroma,
9328 				locals->cursor_bw,
9329 				locals->meta_row_bw,
9330 				locals->dpte_row_bw,
9331 				locals->cursor_bw_pre,
9332 				locals->prefetch_vmrow_bw,
9333 				mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
9334 				s->dummy_unit_vector,
9335 				s->dummy_unit_vector,
9336 				s->dummy_unit_vector,
9337 				s->dummy_unit_vector,
9338 				s->dummy_unit_vector,
9339 				s->dummy_unit_vector,
9340 
9341 				/* output */
9342 				&locals->non_urgent_total_dcn_read_bw_with_flip, // dml_float_t *TotalBandwidth
9343 				&locals->non_urgent_total_dcn_read_bw_with_flip_not_including_MALL_prefetch, // dml_float_t TotalBandwidthNotIncludingMALLPrefetch
9344 				&locals->FractionOfUrgentBandwidthImmediateFlip, // dml_float_t *FractionOfUrgentBandwidth
9345 				&s->dummy_boolean[0]); // dml_bool_t *ImmediateFlipBandwidthSupport
9346 
9347 			for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9348 				if (mode_lib->ms.policy.ImmediateFlipRequirement[k] != dml_immediate_flip_not_required && locals->ImmediateFlipSupportedForPipe[k] == false) {
9349 					locals->ImmediateFlipSupported = false;
9350 #ifdef __DML_VBA_DEBUG__
9351 					dml_print("DML::%s: Pipe %0d not supporting iflip\n", __func__, k);
9352 #endif
9353 				}
9354 			}
9355 		} else {
9356 			locals->ImmediateFlipSupported = false;
9357 			locals->total_dcn_read_bw_with_flip = s->MaxTotalRDBandwidth;
9358 			locals->total_dcn_read_bw_with_flip_not_including_MALL_prefetch = s->MaxTotalRDBandwidthNotIncludingMALLPrefetch;
9359 			locals->non_urgent_total_dcn_read_bw_with_flip = s->NonUrgentMaxTotalRDBandwidth;
9360 			locals->non_urgent_total_dcn_read_bw_with_flip_not_including_MALL_prefetch = s->NonUrgentMaxTotalRDBandwidthNotIncludingMALLPrefetch;
9361 		}
9362 
9363 		/* consider flip support is okay if the flip bw is ok or (when user does't require a iflip and there is no host vm) */
9364 		locals->PrefetchAndImmediateFlipSupported = (locals->PrefetchModeSupported == true &&
9365 													((!mode_lib->ms.support.ImmediateFlipSupport && !mode_lib->ms.cache_display_cfg.plane.HostVMEnable && !s->ImmediateFlipRequirementFinal) ||
9366 													locals->ImmediateFlipSupported)) ? true : false;
9367 
9368 #ifdef __DML_VBA_DEBUG__
9369 		dml_print("DML::%s: PrefetchModeSupported = %u\n", __func__, locals->PrefetchModeSupported);
9370 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k)
9371 		dml_print("DML::%s: ImmediateFlipRequirement[%u] = %u\n", __func__, k, mode_lib->ms.policy.ImmediateFlipRequirement[k] == dml_immediate_flip_required);
9372 		dml_print("DML::%s: HostVMEnable = %u\n", __func__, mode_lib->ms.cache_display_cfg.plane.HostVMEnable);
9373 		dml_print("DML::%s: ImmediateFlipSupport = %u (from mode_support)\n", __func__, mode_lib->ms.support.ImmediateFlipSupport);
9374 		dml_print("DML::%s: ImmediateFlipSupported = %u\n", __func__, locals->ImmediateFlipSupported);
9375 		dml_print("DML::%s: PrefetchAndImmediateFlipSupported = %u\n", __func__, locals->PrefetchAndImmediateFlipSupported);
9376 #endif
9377 		dml_print("DML::%s: Done one iteration: VStartupLines=%u, MaxVStartupAllPlanes=%u\n", __func__, s->VStartupLines, s->MaxVStartupAllPlanes);
9378 
9379 		s->VStartupLines = s->VStartupLines + 1;
9380 
9381 		if (s->VStartupLines > s->MaxVStartupAllPlanes) {
9382 			s->VStartupLines = __DML_VBA_MIN_VSTARTUP__;
9383 
9384 			for (k = 0; k <= mode_lib->ms.num_active_planes - 1; k++) {
9385 				s->NextPrefetchMode[k] = s->NextPrefetchMode[k] + 1;
9386 
9387 				if (s->NextPrefetchMode[k] <= s->MaxPrefetchMode[k])
9388 					s->AllPrefetchModeTested = false;
9389 				dml_print("DML::%s: VStartupLines=%u, reaches max vstartup, try next prefetch mode=%u\n", __func__, s->VStartupLines-1, s->AllPrefetchModeTested);
9390 			}
9391 		} else {
9392 			s->AllPrefetchModeTested = false;
9393 		}
9394 		s->iteration++;
9395 		if (s->iteration > 2500) {
9396 			dml_print("ERROR: DML::%s: Too many errors, exit now\n", __func__);
9397 			ASSERT(0);
9398 		}
9399 	} while (!(locals->PrefetchAndImmediateFlipSupported || s->AllPrefetchModeTested));
9400 
9401 	if (locals->PrefetchAndImmediateFlipSupported) {
9402 		dml_print("DML::%s: Good, Prefetch and flip scheduling solution found at VStartupLines=%u (MaxVStartupAllPlanes=%u)\n", __func__, s->VStartupLines-1, s->MaxVStartupAllPlanes);
9403 	} else {
9404 		dml_print("DML::%s: Bad, Prefetch and flip scheduling solution did NOT find solution! (MaxVStartupAllPlanes=%u)\n", __func__, s->MaxVStartupAllPlanes);
9405 	}
9406 
9407 	//Watermarks and NB P-State/DRAM Clock Change Support
9408 	{
9409 		s->mmSOCParameters.UrgentLatency = locals->UrgentLatency;
9410 		s->mmSOCParameters.ExtraLatency = locals->UrgentExtraLatency;
9411 		s->mmSOCParameters.WritebackLatency = mode_lib->ms.state.writeback_latency_us;
9412 		s->mmSOCParameters.DRAMClockChangeLatency = mode_lib->ms.state.dram_clock_change_latency_us;
9413 		s->mmSOCParameters.FCLKChangeLatency = mode_lib->ms.state.fclk_change_latency_us;
9414 		s->mmSOCParameters.SRExitTime = mode_lib->ms.state.sr_exit_time_us;
9415 		s->mmSOCParameters.SREnterPlusExitTime = mode_lib->ms.state.sr_enter_plus_exit_time_us;
9416 		s->mmSOCParameters.SRExitZ8Time = mode_lib->ms.state.sr_exit_z8_time_us;
9417 		s->mmSOCParameters.SREnterPlusExitZ8Time = mode_lib->ms.state.sr_enter_plus_exit_z8_time_us;
9418 		s->mmSOCParameters.USRRetrainingLatency = mode_lib->ms.state.usr_retraining_latency_us;
9419 		s->mmSOCParameters.SMNLatency = mode_lib->ms.soc.smn_latency_us;
9420 
9421 		CalculateWatermarks_params->USRRetrainingRequiredFinal = mode_lib->ms.policy.USRRetrainingRequiredFinal;
9422 		CalculateWatermarks_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
9423 		CalculateWatermarks_params->PrefetchMode = locals->PrefetchMode;
9424 		CalculateWatermarks_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
9425 		CalculateWatermarks_params->MaxLineBufferLines = mode_lib->ms.ip.max_line_buffer_lines;
9426 		CalculateWatermarks_params->LineBufferSize = mode_lib->ms.ip.line_buffer_size_bits;
9427 		CalculateWatermarks_params->WritebackInterfaceBufferSize = mode_lib->ms.ip.writeback_interface_buffer_size_kbytes;
9428 		CalculateWatermarks_params->DCFCLK = locals->Dcfclk;
9429 		CalculateWatermarks_params->ReturnBW = mode_lib->ms.ReturnBW;
9430 		CalculateWatermarks_params->SynchronizeTimingsFinal = mode_lib->ms.policy.SynchronizeTimingsFinal;
9431 		CalculateWatermarks_params->SynchronizeDRRDisplaysForUCLKPStateChangeFinal = mode_lib->ms.policy.SynchronizeDRRDisplaysForUCLKPStateChangeFinal;
9432 		CalculateWatermarks_params->DRRDisplay = mode_lib->ms.cache_display_cfg.timing.DRRDisplay;
9433 		CalculateWatermarks_params->dpte_group_bytes = locals->dpte_group_bytes;
9434 		CalculateWatermarks_params->meta_row_height = locals->meta_row_height;
9435 		CalculateWatermarks_params->meta_row_height_chroma = locals->meta_row_height_chroma;
9436 		CalculateWatermarks_params->mmSOCParameters = s->mmSOCParameters;
9437 		CalculateWatermarks_params->WritebackChunkSize = mode_lib->ms.ip.writeback_chunk_size_kbytes;
9438 		CalculateWatermarks_params->SOCCLK = mode_lib->ms.SOCCLK;
9439 		CalculateWatermarks_params->DCFClkDeepSleep = locals->DCFCLKDeepSleep;
9440 		CalculateWatermarks_params->DETBufferSizeY = locals->DETBufferSizeY;
9441 		CalculateWatermarks_params->DETBufferSizeC = locals->DETBufferSizeC;
9442 		CalculateWatermarks_params->SwathHeightY = locals->SwathHeightY;
9443 		CalculateWatermarks_params->SwathHeightC = locals->SwathHeightC;
9444 		CalculateWatermarks_params->LBBitPerPixel = mode_lib->ms.cache_display_cfg.plane.LBBitPerPixel;
9445 		CalculateWatermarks_params->SwathWidthY = locals->SwathWidthY;
9446 		CalculateWatermarks_params->SwathWidthC = locals->SwathWidthC;
9447 		CalculateWatermarks_params->HRatio = mode_lib->ms.cache_display_cfg.plane.HRatio;
9448 		CalculateWatermarks_params->HRatioChroma = mode_lib->ms.cache_display_cfg.plane.HRatioChroma;
9449 		CalculateWatermarks_params->VTaps = mode_lib->ms.cache_display_cfg.plane.VTaps;
9450 		CalculateWatermarks_params->VTapsChroma = mode_lib->ms.cache_display_cfg.plane.VTapsChroma;
9451 		CalculateWatermarks_params->VRatio = mode_lib->ms.cache_display_cfg.plane.VRatio;
9452 		CalculateWatermarks_params->VRatioChroma = mode_lib->ms.cache_display_cfg.plane.VRatioChroma;
9453 		CalculateWatermarks_params->HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal;
9454 		CalculateWatermarks_params->VTotal = mode_lib->ms.cache_display_cfg.timing.VTotal;
9455 		CalculateWatermarks_params->VActive = mode_lib->ms.cache_display_cfg.timing.VActive;
9456 		CalculateWatermarks_params->PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock;
9457 		CalculateWatermarks_params->BlendingAndTiming = mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming;
9458 		CalculateWatermarks_params->DPPPerSurface = mode_lib->ms.cache_display_cfg.hw.DPPPerSurface;
9459 		CalculateWatermarks_params->BytePerPixelDETY = locals->BytePerPixelDETY;
9460 		CalculateWatermarks_params->BytePerPixelDETC = locals->BytePerPixelDETC;
9461 		CalculateWatermarks_params->DSTXAfterScaler = locals->DSTXAfterScaler;
9462 		CalculateWatermarks_params->DSTYAfterScaler = locals->DSTYAfterScaler;
9463 		CalculateWatermarks_params->WritebackEnable = mode_lib->ms.cache_display_cfg.writeback.WritebackEnable;
9464 		CalculateWatermarks_params->WritebackPixelFormat = mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat;
9465 		CalculateWatermarks_params->WritebackDestinationWidth = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth;
9466 		CalculateWatermarks_params->WritebackDestinationHeight = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight;
9467 		CalculateWatermarks_params->WritebackSourceHeight = mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight;
9468 		CalculateWatermarks_params->UnboundedRequestEnabled = locals->UnboundedRequestEnabled;
9469 		CalculateWatermarks_params->CompressedBufferSizeInkByte = locals->CompressedBufferSizeInkByte;
9470 
9471 		// Output
9472 		CalculateWatermarks_params->Watermark = &locals->Watermark; // Watermarks *Watermark
9473 		CalculateWatermarks_params->DRAMClockChangeSupport = &locals->DRAMClockChangeSupport;
9474 		CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = locals->MaxActiveDRAMClockChangeLatencySupported; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[]
9475 		CalculateWatermarks_params->SubViewportLinesNeededInMALL = locals->SubViewportLinesNeededInMALL; // dml_uint_t SubViewportLinesNeededInMALL[]
9476 		CalculateWatermarks_params->FCLKChangeSupport = &locals->FCLKChangeSupport;
9477 		CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &locals->MaxActiveFCLKChangeLatencySupported; // dml_float_t *MaxActiveFCLKChangeLatencySupported
9478 		CalculateWatermarks_params->USRRetrainingSupport = &locals->USRRetrainingSupport;
9479 
9480 		CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
9481 			&mode_lib->scratch,
9482 			CalculateWatermarks_params);
9483 
9484 		/* Copy the calculated watermarks to mp.Watermark as the getter functions are
9485 		 * implemented by the DML team to copy the calculated values from the mp.Watermark interface.
9486 		 * &mode_lib->mp.Watermark and &locals->Watermark are the same address, memcpy may lead to
9487 		 * unexpected behavior. memmove should be used.
9488 		 */
9489 		memmove(&mode_lib->mp.Watermark, CalculateWatermarks_params->Watermark, sizeof(struct Watermarks));
9490 
9491 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9492 			if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
9493 				locals->WritebackAllowDRAMClockChangeEndPosition[k] = dml_max(0, locals->VStartupMin[k] * mode_lib->ms.cache_display_cfg.timing.HTotal[k] /
9494 																			mode_lib->ms.cache_display_cfg.timing.PixelClock[k] - locals->Watermark.WritebackDRAMClockChangeWatermark);
9495 				locals->WritebackAllowFCLKChangeEndPosition[k] = dml_max(0, locals->VStartupMin[k] * mode_lib->ms.cache_display_cfg.timing.HTotal[k] /
9496 																			mode_lib->ms.cache_display_cfg.timing.PixelClock[k] - locals->Watermark.WritebackFCLKChangeWatermark);
9497 			} else {
9498 				locals->WritebackAllowDRAMClockChangeEndPosition[k] = 0;
9499 				locals->WritebackAllowFCLKChangeEndPosition[k] = 0;
9500 			}
9501 		}
9502 	}
9503 
9504 	//Display Pipeline Delivery Time in Prefetch, Groups
9505 	CalculatePixelDeliveryTimes(
9506 			mode_lib->ms.num_active_planes,
9507 			mode_lib->ms.cache_display_cfg.plane.VRatio,
9508 			mode_lib->ms.cache_display_cfg.plane.VRatioChroma,
9509 			locals->VRatioPrefetchY,
9510 			locals->VRatioPrefetchC,
9511 			locals->swath_width_luma_ub,
9512 			locals->swath_width_chroma_ub,
9513 			mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
9514 			mode_lib->ms.cache_display_cfg.plane.HRatio,
9515 			mode_lib->ms.cache_display_cfg.plane.HRatioChroma,
9516 			mode_lib->ms.cache_display_cfg.timing.PixelClock,
9517 			locals->PSCL_THROUGHPUT,
9518 			locals->PSCL_THROUGHPUT_CHROMA,
9519 			locals->Dppclk,
9520 			locals->BytePerPixelC,
9521 			mode_lib->ms.cache_display_cfg.plane.SourceScan,
9522 			mode_lib->ms.cache_display_cfg.plane.NumberOfCursors,
9523 			mode_lib->ms.cache_display_cfg.plane.CursorWidth,
9524 			mode_lib->ms.cache_display_cfg.plane.CursorBPP,
9525 			locals->BlockWidth256BytesY,
9526 			locals->BlockHeight256BytesY,
9527 			locals->BlockWidth256BytesC,
9528 			locals->BlockHeight256BytesC,
9529 
9530 			/* Output */
9531 			locals->DisplayPipeLineDeliveryTimeLuma,
9532 			locals->DisplayPipeLineDeliveryTimeChroma,
9533 			locals->DisplayPipeLineDeliveryTimeLumaPrefetch,
9534 			locals->DisplayPipeLineDeliveryTimeChromaPrefetch,
9535 			locals->DisplayPipeRequestDeliveryTimeLuma,
9536 			locals->DisplayPipeRequestDeliveryTimeChroma,
9537 			locals->DisplayPipeRequestDeliveryTimeLumaPrefetch,
9538 			locals->DisplayPipeRequestDeliveryTimeChromaPrefetch,
9539 			locals->CursorRequestDeliveryTime,
9540 			locals->CursorRequestDeliveryTimePrefetch);
9541 
9542 	CalculateMetaAndPTETimes(
9543 			locals->use_one_row_for_frame,
9544 			mode_lib->ms.num_active_planes,
9545 			mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
9546 			mode_lib->ms.ip.meta_chunk_size_kbytes,
9547 			mode_lib->ms.ip.min_meta_chunk_size_bytes,
9548 			mode_lib->ms.cache_display_cfg.timing.HTotal,
9549 			mode_lib->ms.cache_display_cfg.plane.VRatio,
9550 			mode_lib->ms.cache_display_cfg.plane.VRatioChroma,
9551 			locals->DestinationLinesToRequestRowInVBlank,
9552 			locals->DestinationLinesToRequestRowInImmediateFlip,
9553 			mode_lib->ms.cache_display_cfg.surface.DCCEnable,
9554 			mode_lib->ms.cache_display_cfg.timing.PixelClock,
9555 			locals->BytePerPixelY,
9556 			locals->BytePerPixelC,
9557 			mode_lib->ms.cache_display_cfg.plane.SourceScan,
9558 			locals->dpte_row_height,
9559 			locals->dpte_row_height_chroma,
9560 			locals->meta_row_width,
9561 			locals->meta_row_width_chroma,
9562 			locals->meta_row_height,
9563 			locals->meta_row_height_chroma,
9564 			locals->meta_req_width,
9565 			locals->meta_req_width_chroma,
9566 			locals->meta_req_height,
9567 			locals->meta_req_height_chroma,
9568 			locals->dpte_group_bytes,
9569 			locals->PTERequestSizeY,
9570 			locals->PTERequestSizeC,
9571 			locals->PixelPTEReqWidthY,
9572 			locals->PixelPTEReqHeightY,
9573 			locals->PixelPTEReqWidthC,
9574 			locals->PixelPTEReqHeightC,
9575 			locals->dpte_row_width_luma_ub,
9576 			locals->dpte_row_width_chroma_ub,
9577 
9578 			/* Output */
9579 			locals->DST_Y_PER_PTE_ROW_NOM_L,
9580 			locals->DST_Y_PER_PTE_ROW_NOM_C,
9581 			locals->DST_Y_PER_META_ROW_NOM_L,
9582 			locals->DST_Y_PER_META_ROW_NOM_C,
9583 			locals->TimePerMetaChunkNominal,
9584 			locals->TimePerChromaMetaChunkNominal,
9585 			locals->TimePerMetaChunkVBlank,
9586 			locals->TimePerChromaMetaChunkVBlank,
9587 			locals->TimePerMetaChunkFlip,
9588 			locals->TimePerChromaMetaChunkFlip,
9589 			locals->time_per_pte_group_nom_luma,
9590 			locals->time_per_pte_group_vblank_luma,
9591 			locals->time_per_pte_group_flip_luma,
9592 			locals->time_per_pte_group_nom_chroma,
9593 			locals->time_per_pte_group_vblank_chroma,
9594 			locals->time_per_pte_group_flip_chroma);
9595 
9596 	CalculateVMGroupAndRequestTimes(
9597 			mode_lib->ms.num_active_planes,
9598 			mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
9599 			mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels,
9600 			mode_lib->ms.cache_display_cfg.timing.HTotal,
9601 			locals->BytePerPixelC,
9602 			locals->DestinationLinesToRequestVMInVBlank,
9603 			locals->DestinationLinesToRequestVMInImmediateFlip,
9604 			mode_lib->ms.cache_display_cfg.surface.DCCEnable,
9605 			mode_lib->ms.cache_display_cfg.timing.PixelClock,
9606 			locals->dpte_row_width_luma_ub,
9607 			locals->dpte_row_width_chroma_ub,
9608 			locals->vm_group_bytes,
9609 			locals->dpde0_bytes_per_frame_ub_l,
9610 			locals->dpde0_bytes_per_frame_ub_c,
9611 			locals->meta_pte_bytes_per_frame_ub_l,
9612 			locals->meta_pte_bytes_per_frame_ub_c,
9613 
9614 			/* Output */
9615 			locals->TimePerVMGroupVBlank,
9616 			locals->TimePerVMGroupFlip,
9617 			locals->TimePerVMRequestVBlank,
9618 			locals->TimePerVMRequestFlip);
9619 
9620 	// Min TTUVBlank
9621 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9622 		if (locals->PrefetchMode[k] == 0) {
9623 			locals->MinTTUVBlank[k] = dml_max4(
9624 					locals->Watermark.DRAMClockChangeWatermark,
9625 					locals->Watermark.FCLKChangeWatermark,
9626 					locals->Watermark.StutterEnterPlusExitWatermark,
9627 					locals->Watermark.UrgentWatermark);
9628 		} else if (locals->PrefetchMode[k] == 1) {
9629 			locals->MinTTUVBlank[k] = dml_max3(
9630 					locals->Watermark.FCLKChangeWatermark,
9631 					locals->Watermark.StutterEnterPlusExitWatermark,
9632 					locals->Watermark.UrgentWatermark);
9633 		} else if (locals->PrefetchMode[k] == 2) {
9634 			locals->MinTTUVBlank[k] = dml_max(
9635 					locals->Watermark.StutterEnterPlusExitWatermark,
9636 					locals->Watermark.UrgentWatermark);
9637 		} else {
9638 			locals->MinTTUVBlank[k] = locals->Watermark.UrgentWatermark;
9639 		}
9640 		if (!mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k])
9641 			locals->MinTTUVBlank[k] = locals->TCalc + locals->MinTTUVBlank[k];
9642 	}
9643 
9644 	// DCC Configuration
9645 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9646 #ifdef __DML_VBA_DEBUG__
9647 		dml_print("DML::%s: Calculate DCC configuration for surface k=%u\n", __func__, k);
9648 #endif
9649 		CalculateDCCConfiguration(
9650 			mode_lib->ms.cache_display_cfg.surface.DCCEnable[k],
9651 			mode_lib->ms.policy.DCCProgrammingAssumesScanDirectionUnknownFinal,
9652 			mode_lib->ms.cache_display_cfg.surface.SourcePixelFormat[k],
9653 			mode_lib->ms.cache_display_cfg.surface.SurfaceWidthY[k],
9654 			mode_lib->ms.cache_display_cfg.surface.SurfaceWidthC[k],
9655 			mode_lib->ms.cache_display_cfg.surface.SurfaceHeightY[k],
9656 			mode_lib->ms.cache_display_cfg.surface.SurfaceHeightC[k],
9657 			mode_lib->ms.NomDETInKByte,
9658 			locals->BlockHeight256BytesY[k],
9659 			locals->BlockHeight256BytesC[k],
9660 			mode_lib->ms.cache_display_cfg.surface.SurfaceTiling[k],
9661 			locals->BytePerPixelY[k],
9662 			locals->BytePerPixelC[k],
9663 			locals->BytePerPixelDETY[k],
9664 			locals->BytePerPixelDETC[k],
9665 			mode_lib->ms.cache_display_cfg.plane.SourceScan[k],
9666 			/* Output */
9667 			&locals->DCCYMaxUncompressedBlock[k],
9668 			&locals->DCCCMaxUncompressedBlock[k],
9669 			&locals->DCCYMaxCompressedBlock[k],
9670 			&locals->DCCCMaxCompressedBlock[k],
9671 			&locals->DCCYIndependentBlock[k],
9672 			&locals->DCCCIndependentBlock[k]);
9673 	}
9674 
9675 	// VStartup Adjustment
9676 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9677 		s->Tvstartup_margin = (s->MaxVStartupLines[k] - locals->VStartupMin[k]) * mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k];
9678 #ifdef __DML_VBA_DEBUG__
9679 		dml_print("DML::%s: k=%u, MinTTUVBlank = %f (before vstartup margin)\n", __func__, k, locals->MinTTUVBlank[k]);
9680 #endif
9681 
9682 		locals->MinTTUVBlank[k] = locals->MinTTUVBlank[k] + s->Tvstartup_margin;
9683 
9684 #ifdef __DML_VBA_DEBUG__
9685 		dml_print("DML::%s: k=%u, Tvstartup_margin = %f\n", __func__, k, s->Tvstartup_margin);
9686 		dml_print("DML::%s: k=%u, MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
9687 		dml_print("DML::%s: k=%u, MinTTUVBlank = %f\n", __func__, k, locals->MinTTUVBlank[k]);
9688 #endif
9689 
9690 		locals->Tdmdl[k] = locals->Tdmdl[k] + s->Tvstartup_margin;
9691 		if (mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k] && mode_lib->ms.ip.dynamic_metadata_vm_enabled) {
9692 			locals->Tdmdl_vm[k] = locals->Tdmdl_vm[k] + s->Tvstartup_margin;
9693 		}
9694 
9695 		isInterlaceTiming        = (mode_lib->ms.cache_display_cfg.timing.Interlace[k] && !mode_lib->ms.ip.ptoi_supported);
9696 
9697 		// The actual positioning of the vstartup
9698 		locals->VStartup[k] = (isInterlaceTiming ? (2 * s->MaxVStartupLines[k]) : s->MaxVStartupLines[k]);
9699 
9700 		s->dlg_vblank_start        =  ((isInterlaceTiming ? dml_floor((mode_lib->ms.cache_display_cfg.timing.VTotal[k] - mode_lib->ms.cache_display_cfg.timing.VFrontPorch[k]) / 2.0, 1.0) :
9701 																	mode_lib->ms.cache_display_cfg.timing.VTotal[k]) - mode_lib->ms.cache_display_cfg.timing.VFrontPorch[k]);
9702 		s->LSetup                  = dml_floor(4.0 * locals->TSetup[k] / ((dml_float_t) mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]), 1.0) / 4.0;
9703 		s->blank_lines_remaining   = (mode_lib->ms.cache_display_cfg.timing.VTotal[k] - mode_lib->ms.cache_display_cfg.timing.VActive[k]) - locals->VStartup[k];
9704 
9705 		if (s->blank_lines_remaining < 0) {
9706 			dml_print("ERROR: Vstartup is larger than vblank!?\n");
9707 			s->blank_lines_remaining = 0;
9708 			ASSERT(0);
9709 		}
9710 		locals->MIN_DST_Y_NEXT_START[k] = s->dlg_vblank_start + s->blank_lines_remaining + s->LSetup;
9711 
9712 		// debug only
9713 		s->old_MIN_DST_Y_NEXT_START = ((isInterlaceTiming ? dml_floor((mode_lib->ms.cache_display_cfg.timing.VTotal[k] - mode_lib->ms.cache_display_cfg.timing.VFrontPorch[k]) / 2.0, 1.0) :
9714 																	mode_lib->ms.cache_display_cfg.timing.VTotal[k]) - mode_lib->ms.cache_display_cfg.timing.VFrontPorch[k])
9715 											+ dml_max(1.0, dml_ceil((dml_float_t) locals->WritebackDelay[k] / ((dml_float_t) mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]), 1.0))
9716 											+ dml_floor(4.0 * locals->TSetup[k] / ((dml_float_t) mode_lib->ms.cache_display_cfg.timing.HTotal[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]), 1.0) / 4.0;
9717 
9718 		if (((locals->VUpdateOffsetPix[k] + locals->VUpdateWidthPix[k] + locals->VReadyOffsetPix[k]) / (double) mode_lib->ms.cache_display_cfg.timing.HTotal[k]) <=
9719 			(isInterlaceTiming ?
9720 				dml_floor((mode_lib->ms.cache_display_cfg.timing.VTotal[k] - mode_lib->ms.cache_display_cfg.timing.VActive[k] - mode_lib->ms.cache_display_cfg.timing.VFrontPorch[k] - locals->VStartup[k]) / 2.0, 1.0) :
9721 				(int) (mode_lib->ms.cache_display_cfg.timing.VTotal[k] - mode_lib->ms.cache_display_cfg.timing.VActive[k] - mode_lib->ms.cache_display_cfg.timing.VFrontPorch[k] - locals->VStartup[k]))) {
9722 			locals->VREADY_AT_OR_AFTER_VSYNC[k] = true;
9723 		} else {
9724 			locals->VREADY_AT_OR_AFTER_VSYNC[k] = false;
9725 		}
9726 #ifdef __DML_VBA_DEBUG__
9727 		dml_print("DML::%s: k=%u, VStartup = %u (max)\n", __func__, k, locals->VStartup[k]);
9728 		dml_print("DML::%s: k=%u, VStartupMin = %u (max)\n", __func__, k, locals->VStartupMin[k]);
9729 		dml_print("DML::%s: k=%u, VUpdateOffsetPix = %u\n", __func__, k, locals->VUpdateOffsetPix[k]);
9730 		dml_print("DML::%s: k=%u, VUpdateWidthPix = %u\n", __func__, k, locals->VUpdateWidthPix[k]);
9731 		dml_print("DML::%s: k=%u, VReadyOffsetPix = %u\n", __func__, k, locals->VReadyOffsetPix[k]);
9732 		dml_print("DML::%s: k=%u, HTotal = %u\n", __func__, k, mode_lib->ms.cache_display_cfg.timing.HTotal[k]);
9733 		dml_print("DML::%s: k=%u, VTotal = %u\n", __func__, k, mode_lib->ms.cache_display_cfg.timing.VTotal[k]);
9734 		dml_print("DML::%s: k=%u, VActive = %u\n", __func__, k, mode_lib->ms.cache_display_cfg.timing.VActive[k]);
9735 		dml_print("DML::%s: k=%u, VFrontPorch = %u\n", __func__, k, mode_lib->ms.cache_display_cfg.timing.VFrontPorch[k]);
9736 		dml_print("DML::%s: k=%u, TSetup = %f\n", __func__, k, locals->TSetup[k]);
9737 		dml_print("DML::%s: k=%u, MIN_DST_Y_NEXT_START = %f\n", __func__, k, locals->MIN_DST_Y_NEXT_START[k]);
9738 		dml_print("DML::%s: k=%u, MIN_DST_Y_NEXT_START = %f (old)\n", __func__, k, s->old_MIN_DST_Y_NEXT_START);
9739 		dml_print("DML::%s: k=%u, VREADY_AT_OR_AFTER_VSYNC = %u\n", __func__, k, locals->VREADY_AT_OR_AFTER_VSYNC[k]);
9740 #endif
9741 	}
9742 
9743 	//Maximum Bandwidth Used
9744 	s->TotalWRBandwidth = 0;
9745 	s->WRBandwidth = 0;
9746 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9747 		if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true && mode_lib->ms.cache_display_cfg.writeback.WritebackPixelFormat[k] == dml_444_32) {
9748 			s->WRBandwidth = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k] * mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[k] /
9749 							(mode_lib->ms.cache_display_cfg.timing.HTotal[k] * mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * 4;
9750 		} else if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
9751 			s->WRBandwidth = mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationWidth[k] * mode_lib->ms.cache_display_cfg.writeback.WritebackDestinationHeight[k] /
9752 							(mode_lib->ms.cache_display_cfg.timing.HTotal[k] * mode_lib->ms.cache_display_cfg.writeback.WritebackSourceHeight[k] / mode_lib->ms.cache_display_cfg.timing.PixelClock[k]) * 8;
9753 		}
9754 		s->TotalWRBandwidth = s->TotalWRBandwidth + s->WRBandwidth;
9755 	}
9756 
9757 	locals->TotalDataReadBandwidth = 0;
9758 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9759 		locals->TotalDataReadBandwidth = locals->TotalDataReadBandwidth + locals->ReadBandwidthSurfaceLuma[k] + locals->ReadBandwidthSurfaceChroma[k];
9760 
9761 #ifdef __DML_VBA_DEBUG__
9762 		dml_print("DML::%s: k=%u, TotalDataReadBandwidth = %f\n", __func__, k, locals->TotalDataReadBandwidth);
9763 		dml_print("DML::%s: k=%u, ReadBandwidthSurfaceLuma = %f\n", __func__, k, locals->ReadBandwidthSurfaceLuma[k]);
9764 		dml_print("DML::%s: k=%u, ReadBandwidthSurfaceChroma = %f\n", __func__, k, locals->ReadBandwidthSurfaceChroma[k]);
9765 #endif
9766 	}
9767 
9768 	locals->TotalDataReadBandwidthNotIncludingMALLPrefetch = 0;
9769 	for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
9770 		if (mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[k] != dml_use_mall_pstate_change_phantom_pipe) {
9771 			locals->TotalDataReadBandwidthNotIncludingMALLPrefetch = locals->TotalDataReadBandwidthNotIncludingMALLPrefetch
9772 		+ locals->ReadBandwidthSurfaceLuma[k] + locals->ReadBandwidthSurfaceChroma[k];
9773 		}
9774 	}
9775 
9776 	CalculateStutterEfficiency_params->CompressedBufferSizeInkByte = locals->CompressedBufferSizeInkByte;
9777 	CalculateStutterEfficiency_params->UseMALLForPStateChange = mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange;
9778 	CalculateStutterEfficiency_params->UnboundedRequestEnabled = locals->UnboundedRequestEnabled;
9779 	CalculateStutterEfficiency_params->MetaFIFOSizeInKEntries = mode_lib->ms.ip.meta_fifo_size_in_kentries;
9780 	CalculateStutterEfficiency_params->ZeroSizeBufferEntries = mode_lib->ms.ip.zero_size_buffer_entries;
9781 	CalculateStutterEfficiency_params->PixelChunkSizeInKByte = mode_lib->ms.ip.pixel_chunk_size_kbytes;
9782 	CalculateStutterEfficiency_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
9783 	CalculateStutterEfficiency_params->ROBBufferSizeInKByte = mode_lib->ms.ip.rob_buffer_size_kbytes;
9784 	CalculateStutterEfficiency_params->TotalDataReadBandwidth = locals->TotalDataReadBandwidth;
9785 	CalculateStutterEfficiency_params->DCFCLK = locals->Dcfclk;
9786 	CalculateStutterEfficiency_params->ReturnBW = mode_lib->ms.ReturnBW;
9787 	CalculateStutterEfficiency_params->CompbufReservedSpace64B = locals->compbuf_reserved_space_64b;
9788 	CalculateStutterEfficiency_params->CompbufReservedSpaceZs = locals->compbuf_reserved_space_zs;
9789 	CalculateStutterEfficiency_params->SRExitTime = mode_lib->ms.state.sr_exit_time_us;
9790 	CalculateStutterEfficiency_params->SRExitZ8Time = mode_lib->ms.state.sr_exit_z8_time_us;
9791 	CalculateStutterEfficiency_params->SynchronizeTimingsFinal = mode_lib->ms.policy.SynchronizeTimingsFinal;
9792 	CalculateStutterEfficiency_params->BlendingAndTiming = mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming;
9793 	CalculateStutterEfficiency_params->StutterEnterPlusExitWatermark = locals->Watermark.StutterEnterPlusExitWatermark;
9794 	CalculateStutterEfficiency_params->Z8StutterEnterPlusExitWatermark = locals->Watermark.Z8StutterEnterPlusExitWatermark;
9795 	CalculateStutterEfficiency_params->ProgressiveToInterlaceUnitInOPP = mode_lib->ms.ip.ptoi_supported;
9796 	CalculateStutterEfficiency_params->Interlace = mode_lib->ms.cache_display_cfg.timing.Interlace;
9797 	CalculateStutterEfficiency_params->MinTTUVBlank = locals->MinTTUVBlank;
9798 	CalculateStutterEfficiency_params->DPPPerSurface = mode_lib->ms.cache_display_cfg.hw.DPPPerSurface;
9799 	CalculateStutterEfficiency_params->DETBufferSizeY = locals->DETBufferSizeY;
9800 	CalculateStutterEfficiency_params->BytePerPixelY = locals->BytePerPixelY;
9801 	CalculateStutterEfficiency_params->BytePerPixelDETY = locals->BytePerPixelDETY;
9802 	CalculateStutterEfficiency_params->SwathWidthY = locals->SwathWidthY;
9803 	CalculateStutterEfficiency_params->SwathHeightY = locals->SwathHeightY;
9804 	CalculateStutterEfficiency_params->SwathHeightC = locals->SwathHeightC;
9805 	CalculateStutterEfficiency_params->NetDCCRateLuma = mode_lib->ms.cache_display_cfg.surface.DCCRateLuma;
9806 	CalculateStutterEfficiency_params->NetDCCRateChroma = mode_lib->ms.cache_display_cfg.surface.DCCRateChroma;
9807 	CalculateStutterEfficiency_params->DCCFractionOfZeroSizeRequestsLuma = mode_lib->ms.cache_display_cfg.surface.DCCFractionOfZeroSizeRequestsLuma;
9808 	CalculateStutterEfficiency_params->DCCFractionOfZeroSizeRequestsChroma = mode_lib->ms.cache_display_cfg.surface.DCCFractionOfZeroSizeRequestsChroma;
9809 	CalculateStutterEfficiency_params->HTotal = mode_lib->ms.cache_display_cfg.timing.HTotal;
9810 	CalculateStutterEfficiency_params->VTotal = mode_lib->ms.cache_display_cfg.timing.VTotal;
9811 	CalculateStutterEfficiency_params->PixelClock = mode_lib->ms.cache_display_cfg.timing.PixelClock;
9812 	CalculateStutterEfficiency_params->VRatio = mode_lib->ms.cache_display_cfg.plane.VRatio;
9813 	CalculateStutterEfficiency_params->SourceScan = mode_lib->ms.cache_display_cfg.plane.SourceScan;
9814 	CalculateStutterEfficiency_params->BlockHeight256BytesY = locals->BlockHeight256BytesY;
9815 	CalculateStutterEfficiency_params->BlockWidth256BytesY = locals->BlockWidth256BytesY;
9816 	CalculateStutterEfficiency_params->BlockHeight256BytesC = locals->BlockHeight256BytesC;
9817 	CalculateStutterEfficiency_params->BlockWidth256BytesC = locals->BlockWidth256BytesC;
9818 	CalculateStutterEfficiency_params->DCCYMaxUncompressedBlock = locals->DCCYMaxUncompressedBlock;
9819 	CalculateStutterEfficiency_params->DCCCMaxUncompressedBlock = locals->DCCCMaxUncompressedBlock;
9820 	CalculateStutterEfficiency_params->VActive = mode_lib->ms.cache_display_cfg.timing.VActive;
9821 	CalculateStutterEfficiency_params->DCCEnable = mode_lib->ms.cache_display_cfg.surface.DCCEnable;
9822 	CalculateStutterEfficiency_params->WritebackEnable = mode_lib->ms.cache_display_cfg.writeback.WritebackEnable;
9823 	CalculateStutterEfficiency_params->ReadBandwidthSurfaceLuma = locals->ReadBandwidthSurfaceLuma;
9824 	CalculateStutterEfficiency_params->ReadBandwidthSurfaceChroma = locals->ReadBandwidthSurfaceChroma;
9825 	CalculateStutterEfficiency_params->meta_row_bw = locals->meta_row_bw;
9826 	CalculateStutterEfficiency_params->dpte_row_bw = locals->dpte_row_bw;
9827 	CalculateStutterEfficiency_params->StutterEfficiencyNotIncludingVBlank = &locals->StutterEfficiencyNotIncludingVBlank;
9828 	CalculateStutterEfficiency_params->StutterEfficiency = &locals->StutterEfficiency;
9829 	CalculateStutterEfficiency_params->NumberOfStutterBurstsPerFrame = &locals->NumberOfStutterBurstsPerFrame;
9830 	CalculateStutterEfficiency_params->Z8StutterEfficiencyNotIncludingVBlank = &locals->Z8StutterEfficiencyNotIncludingVBlank;
9831 	CalculateStutterEfficiency_params->Z8StutterEfficiency = &locals->Z8StutterEfficiency;
9832 	CalculateStutterEfficiency_params->Z8NumberOfStutterBurstsPerFrame = &locals->Z8NumberOfStutterBurstsPerFrame;
9833 	CalculateStutterEfficiency_params->StutterPeriod = &locals->StutterPeriod;
9834 	CalculateStutterEfficiency_params->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = &locals->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE;
9835 
9836 	// Stutter Efficiency
9837 	CalculateStutterEfficiency(&mode_lib->scratch,
9838 		CalculateStutterEfficiency_params);
9839 
9840 #ifdef __DML_VBA_ALLOW_DELTA__
9841 	{
9842 	dml_float_t dummy_single[2];
9843 	dml_uint_t dummy_integer[1];
9844 	dml_bool_t dummy_boolean[1];
9845 
9846 	// Calculate z8 stutter eff assuming 0 reserved space
9847 	CalculateStutterEfficiency(
9848 			locals->CompressedBufferSizeInkByte,
9849 			mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange,
9850 			locals->UnboundedRequestEnabled,
9851 			mode_lib->ms.ip.meta_fifo_size_in_kentries,
9852 			mode_lib->ms.ip.zero_size_buffer_entries,
9853 			mode_lib->ms.ip.pixel_chunk_size_kbytes,
9854 			mode_lib->ms.num_active_planes,
9855 			mode_lib->ms.ip.rob_buffer_size_kbytes,
9856 			locals->TotalDataReadBandwidth,
9857 			locals->Dcfclk,
9858 			mode_lib->ms.ReturnBW,
9859 			0, //mode_lib->ms.ip.compbuf_reserved_space_64b,
9860 			0, //mode_lib->ms.ip.compbuf_reserved_space_zs,
9861 			mode_lib->ms.state.sr_exit_time_us,
9862 			mode_lib->ms.state.sr_exit_z8_time_us,
9863 			mode_lib->ms.policy.SynchronizeTimingsFinal,
9864 			mode_lib->ms.cache_display_cfg.plane.BlendingAndTiming,
9865 			locals->Watermark.StutterEnterPlusExitWatermark,
9866 			locals->Watermark.Z8StutterEnterPlusExitWatermark,
9867 			mode_lib->ms.ip.ptoi_supported,
9868 			mode_lib->ms.cache_display_cfg.timing.Interlace,
9869 			locals->MinTTUVBlank,
9870 			mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
9871 			mode_lib->ms.DETBufferSizeY,
9872 			locals->BytePerPixelY,
9873 			locals->BytePerPixelDETY,
9874 			locals->SwathWidthY,
9875 			mode_lib->ms.SwathHeightY,
9876 			mode_lib->ms.SwathHeightC,
9877 			mode_lib->ms.cache_display_cfg.surface.DCCRateLuma,
9878 			mode_lib->ms.cache_display_cfg.surface.DCCRateChroma,
9879 			mode_lib->ms.cache_display_cfg.surface.DCCFractionOfZeroSizeRequestsLuma,
9880 			mode_lib->ms.cache_display_cfg.surface.DCCFractionOfZeroSizeRequestsChroma,
9881 			mode_lib->ms.cache_display_cfg.timing.HTotal,
9882 			mode_lib->ms.cache_display_cfg.timing.VTotal,
9883 			mode_lib->ms.cache_display_cfg.timing.PixelClock,
9884 			mode_lib->ms.cache_display_cfg.plane.VRatio,
9885 			mode_lib->ms.cache_display_cfg.plane.SourceScan,
9886 			locals->BlockHeight256BytesY,
9887 			locals->BlockWidth256BytesY,
9888 			locals->BlockHeight256BytesC,
9889 			locals->BlockWidth256BytesC,
9890 			locals->DCCYMaxUncompressedBlock,
9891 			locals->DCCCMaxUncompressedBlock,
9892 			mode_lib->ms.cache_display_cfg.timing.VActive,
9893 			mode_lib->ms.cache_display_cfg.surface.DCCEnable,
9894 			mode_lib->ms.cache_display_cfg.writeback.WritebackEnable,
9895 			locals->ReadBandwidthSurfaceLuma,
9896 			locals->ReadBandwidthSurfaceChroma,
9897 			locals->meta_row_bw,
9898 			locals->dpte_row_bw,
9899 
9900 			/* Output */
9901 			&dummy_single[0],
9902 			&dummy_single[1],
9903 			&dummy_integer[0],
9904 			&locals->Z8StutterEfficiencyNotIncludingVBlankBestCase,
9905 			&locals->Z8StutterEfficiencyBestCase,
9906 			&locals->Z8NumberOfStutterBurstsPerFrameBestCase,
9907 			&locals->StutterPeriodBestCase,
9908 			&dummy_boolean[0]);
9909 	}
9910 #else
9911 	locals->Z8StutterEfficiencyNotIncludingVBlankBestCase = locals->Z8StutterEfficiencyNotIncludingVBlank;
9912 	locals->Z8StutterEfficiencyBestCase                   = locals->Z8StutterEfficiency;
9913 	locals->Z8NumberOfStutterBurstsPerFrameBestCase       = locals->Z8NumberOfStutterBurstsPerFrame;
9914 	locals->StutterPeriodBestCase                         = locals->StutterPeriod;
9915 #endif
9916 
9917 #ifdef __DML_VBA_DEBUG__
9918 	dml_print("DML::%s: --- END --- \n",  __func__);
9919 #endif
9920 } // dml_core_mode_programming
9921 
9922 /// Function: dml_core_get_row_heights
9923 /// @brief Get row height for DPTE and META with minimal input.
dml_core_get_row_heights(dml_uint_t * dpte_row_height,dml_uint_t * meta_row_height,const struct display_mode_lib_st * mode_lib,dml_bool_t is_plane1,enum dml_source_format_class SourcePixelFormat,enum dml_swizzle_mode SurfaceTiling,enum dml_rotation_angle ScanDirection,dml_uint_t pitch,dml_uint_t GPUVMMinPageSizeKBytes)9924 void dml_core_get_row_heights(
9925 						dml_uint_t                         *dpte_row_height,
9926 						dml_uint_t                         *meta_row_height,
9927 						const struct display_mode_lib_st   *mode_lib,
9928 						dml_bool_t                         is_plane1,
9929 						enum dml_source_format_class        SourcePixelFormat,
9930 						enum dml_swizzle_mode            SurfaceTiling,
9931 						enum dml_rotation_angle          ScanDirection,
9932 						dml_uint_t                         pitch,
9933 						dml_uint_t                         GPUVMMinPageSizeKBytes)
9934 {
9935 	dml_uint_t BytePerPixelY;
9936 	dml_uint_t BytePerPixelC;
9937 	dml_float_t BytePerPixelInDETY;
9938 	dml_float_t BytePerPixelInDETC;
9939 	dml_uint_t BlockHeight256BytesY;
9940 	dml_uint_t BlockHeight256BytesC;
9941 	dml_uint_t BlockWidth256BytesY;
9942 	dml_uint_t BlockWidth256BytesC;
9943 	dml_uint_t MacroTileWidthY;
9944 	dml_uint_t MacroTileWidthC;
9945 	dml_uint_t MacroTileHeightY;
9946 	dml_uint_t MacroTileHeightC;
9947 
9948 	dml_uint_t BytePerPixel;
9949 	dml_uint_t BlockHeight256Bytes;
9950 	dml_uint_t BlockWidth256Bytes;
9951 	dml_uint_t MacroTileWidth;
9952 	dml_uint_t MacroTileHeight;
9953 	dml_uint_t PTEBufferSizeInRequests;
9954 
9955 	dml_uint_t dummy_integer[16];
9956 
9957 	CalculateBytePerPixelAndBlockSizes(
9958 		SourcePixelFormat,
9959 		SurfaceTiling,
9960 
9961 		/* Output */
9962 		&BytePerPixelY,
9963 		&BytePerPixelC,
9964 		&BytePerPixelInDETY,
9965 		&BytePerPixelInDETC,
9966 		&BlockHeight256BytesY,
9967 		&BlockHeight256BytesC,
9968 		&BlockWidth256BytesY,
9969 		&BlockWidth256BytesC,
9970 		&MacroTileHeightY,
9971 		&MacroTileHeightC,
9972 		&MacroTileWidthY,
9973 		&MacroTileWidthC);
9974 
9975 	BytePerPixel = is_plane1 ? BytePerPixelC : BytePerPixelY;
9976 	BlockHeight256Bytes = is_plane1 ? BlockHeight256BytesC : BlockHeight256BytesY;
9977 	BlockWidth256Bytes = is_plane1 ? BlockWidth256BytesC : BlockWidth256BytesY;
9978 	MacroTileWidth = is_plane1 ? MacroTileWidthC : MacroTileWidthY;
9979 	MacroTileHeight = is_plane1 ? MacroTileHeightC : MacroTileHeightY;
9980 	PTEBufferSizeInRequests = is_plane1 ? mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma : mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma;
9981 #ifdef __DML_RQ_DLG_CALC_DEBUG__
9982 	dml_print("DML_DLG: %s: is_plane1 = %u\n", __func__, is_plane1);
9983 	dml_print("DML_DLG: %s: BytePerPixel = %u\n", __func__, BytePerPixel);
9984 	dml_print("DML_DLG: %s: BlockHeight256Bytes = %u\n", __func__, BlockHeight256Bytes);
9985 	dml_print("DML_DLG: %s: BlockWidth256Bytes = %u\n", __func__, BlockWidth256Bytes);
9986 	dml_print("DML_DLG: %s: MacroTileWidth = %u\n", __func__, MacroTileWidth);
9987 	dml_print("DML_DLG: %s: MacroTileHeight = %u\n", __func__, MacroTileHeight);
9988 	dml_print("DML_DLG: %s: PTEBufferSizeInRequests = %u\n", __func__, PTEBufferSizeInRequests);
9989 	dml_print("DML_DLG: %s: dpte_buffer_size_in_pte_reqs_luma = %u\n", __func__, mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma);
9990 	dml_print("DML_DLG: %s: dpte_buffer_size_in_pte_reqs_chroma = %u\n", __func__, mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma);
9991 	dml_print("DML_DLG: %s: GPUVMMinPageSizeKBytes = %u\n", __func__, GPUVMMinPageSizeKBytes);
9992 #endif
9993 
9994 	// just supply with enough parameters to calculate meta and dte
9995 	CalculateVMAndRowBytes(
9996 			0, // dml_bool_t ViewportStationary,
9997 			1, // dml_bool_t DCCEnable,
9998 			1, // dml_uint_t NumberOfDPPs,
9999 			BlockHeight256Bytes,
10000 			BlockWidth256Bytes,
10001 			SourcePixelFormat,
10002 			SurfaceTiling,
10003 			BytePerPixel,
10004 			ScanDirection,
10005 			0, // dml_uint_t SwathWidth,
10006 			0, // dml_uint_t ViewportHeight, (Note: DML calculates one_row_for_frame height regardless, would need test input if that height is useful)
10007 			0, // dml_uint_t ViewportXStart,
10008 			0, // dml_uint_t ViewportYStart,
10009 			1, // dml_bool_t GPUVMEnable,
10010 			4, // dml_uint_t GPUVMMaxPageTableLevels,
10011 			GPUVMMinPageSizeKBytes,
10012 			PTEBufferSizeInRequests,
10013 			pitch,
10014 			0, // dml_uint_t DCCMetaPitch,
10015 			MacroTileWidth,
10016 			MacroTileHeight,
10017 
10018 			// /* Output */
10019 			&dummy_integer[0], // dml_uint_t *MetaRowByte,
10020 			&dummy_integer[1], // dml_uint_t *PixelPTEBytesPerRow,
10021 			&dummy_integer[2], // dml_uint_t *PixelPTEBytesPerRowStorage,
10022 			&dummy_integer[3], // dml_uint_t *dpte_row_width_ub,
10023 			dpte_row_height,
10024 			&dummy_integer[4], // dml_uint_t *dpte_row_height_linear
10025 			&dummy_integer[5], // dml_uint_t *PixelPTEBytesPerRow_one_row_per_frame,
10026 			&dummy_integer[6], // dml_uint_t *dpte_row_width_ub_one_row_per_frame,
10027 			&dummy_integer[7], // dml_uint_t *dpte_row_height_one_row_per_frame,
10028 			&dummy_integer[8], // dml_uint_t *MetaRequestWidth,
10029 			&dummy_integer[9], // dml_uint_t *MetaRequestHeight,
10030 			&dummy_integer[10], // dml_uint_t *meta_row_width,
10031 			meta_row_height,
10032 			&dummy_integer[11], // dml_uint_t *PixelPTEReqWidth,
10033 			&dummy_integer[12], // dml_uint_t *PixelPTEReqHeight,
10034 			&dummy_integer[13], // dml_uint_t *PTERequestSize,
10035 			&dummy_integer[14], // dml_uint_t *DPDE0BytesFrame,
10036 			&dummy_integer[15]); // dml_uint_t *MetaPTEBytesFrame)
10037 
10038 #ifdef __DML_RQ_DLG_CALC_DEBUG__
10039 	dml_print("DML_DLG: %s: dpte_row_height = %u\n", __func__, *dpte_row_height);
10040 	dml_print("DML_DLG: %s: meta_row_height = %u\n", __func__, *meta_row_height);
10041 #endif
10042 }
10043 
dml_get_soc_state_bounding_box(const struct soc_states_st * states,dml_uint_t state_idx)10044 static struct soc_state_bounding_box_st dml_get_soc_state_bounding_box(
10045 	const struct soc_states_st *states,
10046 	dml_uint_t state_idx)
10047 {
10048 	dml_print("DML::%s: state_idx=%u (num_states=%u)\n", __func__, state_idx, states->num_states);
10049 
10050 	if (state_idx >= (dml_uint_t)states->num_states) {
10051 		dml_print("DML::%s: ERROR: Invalid state_idx=%u! num_states=%u\n", __func__, state_idx, states->num_states);
10052 		ASSERT(0);
10053 	}
10054 	return (states->state_array[state_idx]);
10055 }
10056 
10057 /// @brief Copy the parameters to a calculation struct, it actually only need when the DML needs to have
10058 ///        the intelligence to re-calculate when any of display cfg, bbox, or policy changes since last calculated.
10059 ///
cache_ip_soc_cfg(struct display_mode_lib_st * mode_lib,dml_uint_t state_idx)10060 static void cache_ip_soc_cfg(struct display_mode_lib_st *mode_lib,
10061 						dml_uint_t state_idx)
10062 {
10063 	mode_lib->ms.state_idx = state_idx;
10064 	mode_lib->ms.max_state_idx = mode_lib->states.num_states - 1;
10065 	mode_lib->ms.soc = mode_lib->soc;
10066 	mode_lib->ms.ip = mode_lib->ip;
10067 	mode_lib->ms.policy = mode_lib->policy;
10068 	mode_lib->ms.state = dml_get_soc_state_bounding_box(&mode_lib->states, state_idx);
10069 	mode_lib->ms.max_state = dml_get_soc_state_bounding_box(&mode_lib->states, mode_lib->states.num_states - 1);
10070 }
10071 
cache_display_cfg(struct display_mode_lib_st * mode_lib,const struct dml_display_cfg_st * display_cfg)10072 static void cache_display_cfg(struct display_mode_lib_st *mode_lib,
10073 	const struct dml_display_cfg_st *display_cfg)
10074 {
10075 	mode_lib->ms.cache_display_cfg = *display_cfg;
10076 }
10077 
fetch_socbb_params(struct display_mode_lib_st * mode_lib)10078 static void fetch_socbb_params(struct display_mode_lib_st *mode_lib)
10079 {
10080 	struct soc_state_bounding_box_st *state = &mode_lib->ms.state;
10081 
10082 	// Default values, SOCCLK, DRAMSpeed, and FabricClock will be reassigned to the same state value in mode_check step
10083 	// If UseMinimumRequiredDCFCLK is used, the DCFCLK will be the min dcflk for the mode support
10084 	mode_lib->ms.SOCCLK = (dml_float_t)state->socclk_mhz;
10085 	mode_lib->ms.DRAMSpeed = (dml_float_t)state->dram_speed_mts;
10086 	mode_lib->ms.FabricClock = (dml_float_t)state->fabricclk_mhz;
10087 	mode_lib->ms.DCFCLK = (dml_float_t)state->dcfclk_mhz;
10088 }
10089 
10090 /// @brief Use display_cfg directly for mode_support calculation
10091 ///        Calculated values and informational output are stored in mode_lib.vba data struct
10092 ///        The display configuration is described with pipes struct and num_pipes
10093 ///        This function is used when physical resource mapping is not finalized (for example,
10094 ///        don't know how many pipes to represent a surface)
10095 /// @param mode_lib Contains the bounding box and policy setting.
10096 /// @param state_idx Power state index
10097 /// @param display_cfg Display configurations. A display
dml_mode_support(struct display_mode_lib_st * mode_lib,dml_uint_t state_idx,const struct dml_display_cfg_st * display_cfg)10098 dml_bool_t dml_mode_support(
10099 	struct display_mode_lib_st *mode_lib,
10100 	dml_uint_t                        state_idx,
10101 	const struct dml_display_cfg_st *display_cfg)
10102 {
10103 	dml_bool_t is_mode_support;
10104 
10105 	dml_print("DML::%s: ------------- START ----------\n", __func__);
10106 	cache_ip_soc_cfg(mode_lib, state_idx);
10107 	cache_display_cfg(mode_lib, display_cfg);
10108 
10109 	fetch_socbb_params(mode_lib);
10110 
10111 	dml_print("DML::%s: state_idx          = %u\n", __func__, state_idx);
10112 
10113 	is_mode_support = dml_core_mode_support(mode_lib);
10114 
10115 	dml_print("DML::%s: is_mode_support = %u\n", __func__, is_mode_support);
10116 	dml_print("DML::%s: ------------- DONE ----------\n", __func__);
10117 	return is_mode_support;
10118 }
10119 
10120 /// @Brief A function to calculate the programming values for DCN DCHUB (Assume mode is supported)
10121 /// The output will be stored in the mode_lib.mp (mode_program_st) data struct and those can be accessed via the getter functions
10122 /// Calculated values include: watermarks, dlg, rq reg, different clock frequency
10123 /// This function returns 1 when there is no error.
10124 /// Note: In this function, it is assumed that DCFCLK, SOCCLK freq are the state values, and mode_program will just use the DML calculated DPPCLK and DISPCLK
10125 /// @param mode_lib mode_lib data struct that house all the input/output/bbox and calculation values.
10126 /// @param state_idx Power state idx chosen
10127 /// @param display_cfg Display Configuration
10128 /// @param call_standalone Calling mode_programming without calling mode support.  Some of the "support" struct member will be pre-calculated before doing mode programming
10129 /// TODO: Add clk_cfg input, could be useful for standalone mode
dml_mode_programming(struct display_mode_lib_st * mode_lib,dml_uint_t state_idx,const struct dml_display_cfg_st * display_cfg,bool call_standalone)10130 dml_bool_t dml_mode_programming(
10131 	struct display_mode_lib_st *mode_lib,
10132 	dml_uint_t                         state_idx,
10133 	const struct dml_display_cfg_st *display_cfg,
10134 	bool                               call_standalone)
10135 {
10136 	struct dml_clk_cfg_st clk_cfg;
10137 	memset(&clk_cfg, 0, sizeof(clk_cfg));
10138 
10139 	clk_cfg.dcfclk_option = dml_use_required_freq;
10140 	clk_cfg.dispclk_option = dml_use_required_freq;
10141 	for (dml_uint_t k = 0; k < __DML_NUM_PLANES__; ++k)
10142 		clk_cfg.dppclk_option[k] = dml_use_required_freq;
10143 
10144 	dml_print("DML::%s: ------------- START ----------\n", __func__);
10145 	dml_print("DML::%s: state_idx       = %u\n", __func__, state_idx);
10146 	dml_print("DML::%s: call_standalone = %u\n", __func__, call_standalone);
10147 
10148 	cache_ip_soc_cfg(mode_lib, state_idx);
10149 	cache_display_cfg(mode_lib, display_cfg);
10150 
10151 	fetch_socbb_params(mode_lib);
10152 	if (call_standalone) {
10153 		mode_lib->ms.support.ImmediateFlipSupport = 1; // assume mode support say immediate flip ok at max state/combine
10154 		dml_core_mode_support_partial(mode_lib);
10155 	}
10156 
10157 	dml_core_mode_programming(mode_lib, &clk_cfg);
10158 
10159 	dml_print("DML::%s: ------------- DONE ----------\n", __func__);
10160 	dml_print("DML::%s: PrefetchAndImmediateFlipSupported = %0d\n", __func__, mode_lib->mp.PrefetchAndImmediateFlipSupported);
10161 	return mode_lib->mp.PrefetchAndImmediateFlipSupported;
10162 }
10163 
mode_support_pwr_states(dml_uint_t * lowest_state_idx,struct display_mode_lib_st * mode_lib,const struct dml_display_cfg_st * display_cfg,dml_uint_t start_state_idx,dml_uint_t end_state_idx)10164 static dml_uint_t mode_support_pwr_states(
10165 	dml_uint_t *lowest_state_idx,
10166 	struct display_mode_lib_st *mode_lib,
10167 	const struct dml_display_cfg_st *display_cfg,
10168 	dml_uint_t start_state_idx,
10169 	dml_uint_t end_state_idx)
10170 {
10171 	dml_uint_t state_idx = 0;
10172 	dml_bool_t mode_is_supported = 0;
10173 	*lowest_state_idx = end_state_idx;
10174 
10175 	if (end_state_idx < start_state_idx)
10176 		ASSERT(0);
10177 
10178 	if (end_state_idx >= mode_lib->states.num_states) // idx is 0-based
10179 		ASSERT(0);
10180 
10181 	for (state_idx = start_state_idx; state_idx <= end_state_idx; state_idx++) {
10182 		if (dml_mode_support(mode_lib, state_idx, display_cfg)) {
10183 			dml_print("DML::%s: Mode is supported at power state_idx = %u\n", __func__, state_idx);
10184 			mode_is_supported = 1;
10185 			*lowest_state_idx = state_idx;
10186 			break;
10187 		}
10188 	}
10189 
10190 	return mode_is_supported;
10191 }
10192 
dml_mode_support_ex(struct dml_mode_support_ex_params_st * in_out_params)10193 dml_uint_t dml_mode_support_ex(struct dml_mode_support_ex_params_st *in_out_params)
10194 {
10195 	dml_uint_t result;
10196 
10197 	result = mode_support_pwr_states(&in_out_params->out_lowest_state_idx,
10198 		in_out_params->mode_lib,
10199 		in_out_params->in_display_cfg,
10200 		in_out_params->in_start_state_idx,
10201 		in_out_params->mode_lib->states.num_states - 1);
10202 
10203 	if (result)
10204 		*in_out_params->out_evaluation_info = in_out_params->mode_lib->ms.support;
10205 
10206 	return result;
10207 }
10208 
dml_get_is_phantom_pipe(struct display_mode_lib_st * mode_lib,dml_uint_t pipe_idx)10209 dml_bool_t dml_get_is_phantom_pipe(struct display_mode_lib_st *mode_lib, dml_uint_t pipe_idx)
10210 {
10211 	dml_uint_t plane_idx = mode_lib->mp.pipe_plane[pipe_idx];
10212 	dml_print("DML::%s: pipe_idx=%d UseMALLForPStateChange=%0d\n", __func__, pipe_idx, mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[plane_idx]);
10213 	return (mode_lib->ms.cache_display_cfg.plane.UseMALLForPStateChange[plane_idx] == dml_use_mall_pstate_change_phantom_pipe);
10214 }
10215 
10216 
10217 #define dml_get_per_surface_var_func(variable, type, interval_var) type dml_get_##variable(struct display_mode_lib_st *mode_lib, dml_uint_t surface_idx) \
10218 { \
10219 	dml_uint_t plane_idx; \
10220 	plane_idx = mode_lib->mp.pipe_plane[surface_idx]; \
10221 	return (type) interval_var[plane_idx]; \
10222 }
10223 
10224 #define dml_get_var_func(var, type, internal_var)  type dml_get_##var(struct display_mode_lib_st *mode_lib) \
10225 { \
10226 	return (type) internal_var; \
10227 }
10228 
10229 dml_get_var_func(wm_urgent, dml_float_t, mode_lib->mp.Watermark.UrgentWatermark);
10230 dml_get_var_func(wm_stutter_exit, dml_float_t, mode_lib->mp.Watermark.StutterExitWatermark);
10231 dml_get_var_func(wm_stutter_enter_exit, dml_float_t, mode_lib->mp.Watermark.StutterEnterPlusExitWatermark);
10232 dml_get_var_func(wm_memory_trip, dml_float_t, mode_lib->mp.UrgentLatency);
10233 dml_get_var_func(wm_fclk_change, dml_float_t, mode_lib->mp.Watermark.FCLKChangeWatermark);
10234 dml_get_var_func(wm_usr_retraining, dml_float_t, mode_lib->mp.Watermark.USRRetrainingWatermark);
10235 dml_get_var_func(wm_dram_clock_change, dml_float_t, mode_lib->mp.Watermark.DRAMClockChangeWatermark);
10236 dml_get_var_func(wm_z8_stutter_enter_exit, dml_float_t, mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark);
10237 dml_get_var_func(wm_z8_stutter, dml_float_t, mode_lib->mp.Watermark.Z8StutterExitWatermark);
10238 dml_get_var_func(fraction_of_urgent_bandwidth, dml_float_t, mode_lib->mp.FractionOfUrgentBandwidth);
10239 dml_get_var_func(fraction_of_urgent_bandwidth_imm_flip, dml_float_t, mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip);
10240 dml_get_var_func(urgent_latency, dml_float_t, mode_lib->mp.UrgentLatency);
10241 dml_get_var_func(clk_dcf_deepsleep, dml_float_t, mode_lib->mp.DCFCLKDeepSleep);
10242 dml_get_var_func(wm_writeback_dram_clock_change, dml_float_t, mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark);
10243 dml_get_var_func(wm_writeback_urgent, dml_float_t, mode_lib->mp.Watermark.WritebackUrgentWatermark);
10244 dml_get_var_func(stutter_efficiency, dml_float_t, mode_lib->mp.StutterEfficiency);
10245 dml_get_var_func(stutter_efficiency_no_vblank, dml_float_t, mode_lib->mp.StutterEfficiencyNotIncludingVBlank);
10246 dml_get_var_func(stutter_efficiency_z8, dml_float_t, mode_lib->mp.Z8StutterEfficiency);
10247 dml_get_var_func(stutter_num_bursts_z8, dml_float_t, mode_lib->mp.Z8NumberOfStutterBurstsPerFrame);
10248 dml_get_var_func(stutter_period, dml_float_t, mode_lib->mp.StutterPeriod);
10249 dml_get_var_func(stutter_efficiency_z8_bestcase, dml_float_t, mode_lib->mp.Z8StutterEfficiencyBestCase);
10250 dml_get_var_func(stutter_num_bursts_z8_bestcase, dml_float_t, mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase);
10251 dml_get_var_func(stutter_period_bestcase, dml_float_t, mode_lib->mp.StutterPeriodBestCase);
10252 dml_get_var_func(urgent_extra_latency, dml_float_t, mode_lib->mp.UrgentExtraLatency);
10253 dml_get_var_func(fclk_change_latency, dml_float_t, mode_lib->mp.MaxActiveFCLKChangeLatencySupported);
10254 dml_get_var_func(dispclk_calculated, dml_float_t, mode_lib->mp.Dispclk_calculated);
10255 dml_get_var_func(total_data_read_bw, dml_float_t, mode_lib->mp.TotalDataReadBandwidth);
10256 dml_get_var_func(return_bw, dml_float_t, mode_lib->ms.ReturnBW);
10257 dml_get_var_func(return_dram_bw, dml_float_t, mode_lib->ms.ReturnDRAMBW);
10258 dml_get_var_func(tcalc, dml_float_t, mode_lib->mp.TCalc);
10259 dml_get_var_func(comp_buffer_size_kbytes, dml_uint_t, mode_lib->mp.CompressedBufferSizeInkByte);
10260 dml_get_var_func(pixel_chunk_size_in_kbyte, dml_uint_t, mode_lib->ms.ip.pixel_chunk_size_kbytes);
10261 dml_get_var_func(alpha_pixel_chunk_size_in_kbyte, dml_uint_t, mode_lib->ms.ip.alpha_pixel_chunk_size_kbytes);
10262 dml_get_var_func(meta_chunk_size_in_kbyte, dml_uint_t, mode_lib->ms.ip.meta_chunk_size_kbytes);
10263 dml_get_var_func(min_pixel_chunk_size_in_byte, dml_uint_t, mode_lib->ms.ip.min_pixel_chunk_size_bytes);
10264 dml_get_var_func(min_meta_chunk_size_in_byte, dml_uint_t, mode_lib->ms.ip.min_meta_chunk_size_bytes);
10265 dml_get_var_func(total_immediate_flip_bytes, dml_uint_t, mode_lib->mp.TotImmediateFlipBytes);
10266 
10267 dml_get_per_surface_var_func(dsc_delay, dml_uint_t, mode_lib->mp.DSCDelay); // this is the dsc latency
10268 dml_get_per_surface_var_func(dppclk_calculated, dml_float_t, mode_lib->mp.Dppclk_calculated);
10269 dml_get_per_surface_var_func(dscclk_calculated, dml_float_t, mode_lib->mp.DSCCLK_calculated);
10270 dml_get_per_surface_var_func(min_ttu_vblank_in_us, dml_float_t, mode_lib->mp.MinTTUVBlank);
10271 dml_get_per_surface_var_func(vratio_prefetch_l, dml_float_t, mode_lib->mp.VRatioPrefetchY);
10272 dml_get_per_surface_var_func(vratio_prefetch_c, dml_float_t, mode_lib->mp.VRatioPrefetchC);
10273 dml_get_per_surface_var_func(dst_x_after_scaler, dml_uint_t, mode_lib->mp.DSTXAfterScaler);
10274 dml_get_per_surface_var_func(dst_y_after_scaler, dml_uint_t, mode_lib->mp.DSTYAfterScaler);
10275 dml_get_per_surface_var_func(dst_y_per_vm_vblank, dml_float_t, mode_lib->mp.DestinationLinesToRequestVMInVBlank);
10276 dml_get_per_surface_var_func(dst_y_per_row_vblank, dml_float_t, mode_lib->mp.DestinationLinesToRequestRowInVBlank);
10277 dml_get_per_surface_var_func(dst_y_prefetch, dml_float_t, mode_lib->mp.DestinationLinesForPrefetch);
10278 dml_get_per_surface_var_func(dst_y_per_vm_flip, dml_float_t, mode_lib->mp.DestinationLinesToRequestVMInImmediateFlip);
10279 dml_get_per_surface_var_func(dst_y_per_row_flip, dml_float_t, mode_lib->mp.DestinationLinesToRequestRowInImmediateFlip);
10280 dml_get_per_surface_var_func(dst_y_per_pte_row_nom_l, dml_float_t, mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_L);
10281 dml_get_per_surface_var_func(dst_y_per_pte_row_nom_c, dml_float_t, mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_C);
10282 dml_get_per_surface_var_func(dst_y_per_meta_row_nom_l, dml_float_t, mode_lib->mp.DST_Y_PER_META_ROW_NOM_L);
10283 dml_get_per_surface_var_func(dst_y_per_meta_row_nom_c, dml_float_t, mode_lib->mp.DST_Y_PER_META_ROW_NOM_C);
10284 dml_get_per_surface_var_func(refcyc_per_vm_group_vblank_in_us, dml_float_t, mode_lib->mp.TimePerVMGroupVBlank);
10285 dml_get_per_surface_var_func(refcyc_per_vm_group_flip_in_us, dml_float_t, mode_lib->mp.TimePerVMGroupFlip);
10286 dml_get_per_surface_var_func(refcyc_per_vm_req_vblank_in_us, dml_float_t, mode_lib->mp.TimePerVMRequestVBlank);
10287 dml_get_per_surface_var_func(refcyc_per_vm_req_flip_in_us, dml_float_t, mode_lib->mp.TimePerVMRequestFlip);
10288 dml_get_per_surface_var_func(refcyc_per_vm_dmdata_in_us, dml_float_t, mode_lib->mp.Tdmdl_vm);
10289 dml_get_per_surface_var_func(dmdata_dl_delta_in_us, dml_float_t, mode_lib->mp.Tdmdl);
10290 dml_get_per_surface_var_func(refcyc_per_line_delivery_l_in_us, dml_float_t, mode_lib->mp.DisplayPipeLineDeliveryTimeLuma);
10291 dml_get_per_surface_var_func(refcyc_per_line_delivery_c_in_us, dml_float_t, mode_lib->mp.DisplayPipeLineDeliveryTimeChroma);
10292 dml_get_per_surface_var_func(refcyc_per_line_delivery_pre_l_in_us, dml_float_t, mode_lib->mp.DisplayPipeLineDeliveryTimeLumaPrefetch);
10293 dml_get_per_surface_var_func(refcyc_per_line_delivery_pre_c_in_us, dml_float_t, mode_lib->mp.DisplayPipeLineDeliveryTimeChromaPrefetch);
10294 dml_get_per_surface_var_func(refcyc_per_req_delivery_l_in_us, dml_float_t, mode_lib->mp.DisplayPipeRequestDeliveryTimeLuma);
10295 dml_get_per_surface_var_func(refcyc_per_req_delivery_c_in_us, dml_float_t, mode_lib->mp.DisplayPipeRequestDeliveryTimeChroma);
10296 dml_get_per_surface_var_func(refcyc_per_req_delivery_pre_l_in_us, dml_float_t, mode_lib->mp.DisplayPipeRequestDeliveryTimeLumaPrefetch);
10297 dml_get_per_surface_var_func(refcyc_per_req_delivery_pre_c_in_us, dml_float_t, mode_lib->mp.DisplayPipeRequestDeliveryTimeChromaPrefetch);
10298 dml_get_per_surface_var_func(refcyc_per_cursor_req_delivery_in_us, dml_float_t, mode_lib->mp.CursorRequestDeliveryTime);
10299 dml_get_per_surface_var_func(refcyc_per_cursor_req_delivery_pre_in_us, dml_float_t, mode_lib->mp.CursorRequestDeliveryTimePrefetch);
10300 dml_get_per_surface_var_func(refcyc_per_meta_chunk_nom_l_in_us, dml_float_t, mode_lib->mp.TimePerMetaChunkNominal);
10301 dml_get_per_surface_var_func(refcyc_per_meta_chunk_nom_c_in_us, dml_float_t, mode_lib->mp.TimePerChromaMetaChunkNominal);
10302 dml_get_per_surface_var_func(refcyc_per_meta_chunk_vblank_l_in_us, dml_float_t, mode_lib->mp.TimePerMetaChunkVBlank);
10303 dml_get_per_surface_var_func(refcyc_per_meta_chunk_vblank_c_in_us, dml_float_t, mode_lib->mp.TimePerChromaMetaChunkVBlank);
10304 dml_get_per_surface_var_func(refcyc_per_meta_chunk_flip_l_in_us, dml_float_t, mode_lib->mp.TimePerMetaChunkFlip);
10305 dml_get_per_surface_var_func(refcyc_per_meta_chunk_flip_c_in_us, dml_float_t, mode_lib->mp.TimePerChromaMetaChunkFlip);
10306 dml_get_per_surface_var_func(refcyc_per_pte_group_nom_l_in_us, dml_float_t, mode_lib->mp.time_per_pte_group_nom_luma);
10307 dml_get_per_surface_var_func(refcyc_per_pte_group_nom_c_in_us, dml_float_t, mode_lib->mp.time_per_pte_group_nom_chroma);
10308 dml_get_per_surface_var_func(refcyc_per_pte_group_vblank_l_in_us, dml_float_t, mode_lib->mp.time_per_pte_group_vblank_luma);
10309 dml_get_per_surface_var_func(refcyc_per_pte_group_vblank_c_in_us, dml_float_t, mode_lib->mp.time_per_pte_group_vblank_chroma);
10310 dml_get_per_surface_var_func(refcyc_per_pte_group_flip_l_in_us, dml_float_t, mode_lib->mp.time_per_pte_group_flip_luma);
10311 dml_get_per_surface_var_func(refcyc_per_pte_group_flip_c_in_us, dml_float_t, mode_lib->mp.time_per_pte_group_flip_chroma);
10312 dml_get_per_surface_var_func(dpte_group_size_in_bytes, dml_uint_t, mode_lib->mp.dpte_group_bytes);
10313 dml_get_per_surface_var_func(vm_group_size_in_bytes, dml_uint_t, mode_lib->mp.vm_group_bytes);
10314 dml_get_per_surface_var_func(swath_height_l, dml_uint_t, mode_lib->ms.SwathHeightY);
10315 dml_get_per_surface_var_func(swath_height_c, dml_uint_t, mode_lib->ms.SwathHeightC);
10316 dml_get_per_surface_var_func(dpte_row_height_l, dml_uint_t, mode_lib->mp.dpte_row_height);
10317 dml_get_per_surface_var_func(dpte_row_height_c, dml_uint_t, mode_lib->mp.dpte_row_height_chroma);
10318 dml_get_per_surface_var_func(dpte_row_height_linear_l, dml_uint_t, mode_lib->mp.dpte_row_height_linear);
10319 dml_get_per_surface_var_func(dpte_row_height_linear_c, dml_uint_t, mode_lib->mp.dpte_row_height_linear_chroma);
10320 dml_get_per_surface_var_func(meta_row_height_l, dml_uint_t, mode_lib->mp.meta_row_height);
10321 dml_get_per_surface_var_func(meta_row_height_c, dml_uint_t, mode_lib->mp.meta_row_height_chroma);
10322 
10323 dml_get_per_surface_var_func(vstartup_calculated, dml_uint_t, mode_lib->mp.VStartup);
10324 dml_get_per_surface_var_func(vupdate_offset, dml_uint_t, mode_lib->mp.VUpdateOffsetPix);
10325 dml_get_per_surface_var_func(vupdate_width, dml_uint_t, mode_lib->mp.VUpdateWidthPix);
10326 dml_get_per_surface_var_func(vready_offset, dml_uint_t, mode_lib->mp.VReadyOffsetPix);
10327 dml_get_per_surface_var_func(vready_at_or_after_vsync, dml_uint_t, mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC);
10328 dml_get_per_surface_var_func(min_dst_y_next_start, dml_uint_t, mode_lib->mp.MIN_DST_Y_NEXT_START);
10329 dml_get_per_surface_var_func(det_stored_buffer_size_l_bytes, dml_uint_t, mode_lib->ms.DETBufferSizeY);
10330 dml_get_per_surface_var_func(det_stored_buffer_size_c_bytes, dml_uint_t, mode_lib->ms.DETBufferSizeC);
10331 dml_get_per_surface_var_func(use_mall_for_static_screen, dml_uint_t, mode_lib->mp.UsesMALLForStaticScreen);
10332 dml_get_per_surface_var_func(surface_size_for_mall, dml_uint_t, mode_lib->mp.SurfaceSizeInTheMALL);
10333 dml_get_per_surface_var_func(dcc_max_uncompressed_block_l, dml_uint_t, mode_lib->mp.DCCYMaxUncompressedBlock);
10334 dml_get_per_surface_var_func(dcc_max_compressed_block_l, dml_uint_t, mode_lib->mp.DCCYMaxCompressedBlock);
10335 dml_get_per_surface_var_func(dcc_independent_block_l, dml_uint_t, mode_lib->mp.DCCYIndependentBlock);
10336 dml_get_per_surface_var_func(dcc_max_uncompressed_block_c, dml_uint_t, mode_lib->mp.DCCCMaxUncompressedBlock);
10337 dml_get_per_surface_var_func(dcc_max_compressed_block_c, dml_uint_t, mode_lib->mp.DCCCMaxCompressedBlock);
10338 dml_get_per_surface_var_func(dcc_independent_block_c, dml_uint_t, mode_lib->mp.DCCCIndependentBlock);
10339 dml_get_per_surface_var_func(max_active_dram_clock_change_latency_supported, dml_uint_t, mode_lib->mp.MaxActiveDRAMClockChangeLatencySupported);
10340 dml_get_per_surface_var_func(pte_buffer_mode, dml_uint_t, mode_lib->mp.PTE_BUFFER_MODE);
10341 dml_get_per_surface_var_func(bigk_fragment_size, dml_uint_t, mode_lib->mp.BIGK_FRAGMENT_SIZE);
10342 dml_get_per_surface_var_func(dpte_bytes_per_row, dml_uint_t, mode_lib->mp.PixelPTEBytesPerRow);
10343 dml_get_per_surface_var_func(meta_bytes_per_row, dml_uint_t, mode_lib->mp.MetaRowByte);
10344 dml_get_per_surface_var_func(det_buffer_size_kbytes, dml_uint_t, mode_lib->ms.DETBufferSizeInKByte);
10345 
10346