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