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

source code of linux/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c