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