drm/amd/display: Create debug option to disable v.active clock change policy.
[linux-2.6-microblaze.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.DRAMClockChangeSupportsVActive &&
2615                 mode_lib->vba.MinActiveDRAMClockChangeMargin > 50) {
2616                 mode_lib->vba.DRAMClockChangeWatermark += 25;
2617                 mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
2618         } else if (mode_lib->vba.DummyPStateCheck &&
2619                         mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
2620                 mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
2621         } else {
2622                 if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
2623                         mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vblank;
2624                         for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2625                                 if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
2626                                         mode_lib->vba.DRAMClockChangeSupport[0][0] =
2627                                                         dm_dram_clock_change_unsupported;
2628                                 }
2629                         }
2630                 } else {
2631                         mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_unsupported;
2632                 }
2633         }
2634         for (k = 0; k <= mode_lib->vba.soc.num_states; k++)
2635                 for (j = 0; j < 2; j++)
2636                         mode_lib->vba.DRAMClockChangeSupport[k][j] = mode_lib->vba.DRAMClockChangeSupport[0][0];
2637
2638         //XFC Parameters:
2639         for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2640                 if (mode_lib->vba.XFCEnabled[k] == true) {
2641                         double TWait;
2642
2643                         mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
2644                         mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
2645                         mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
2646                         TWait = CalculateTWait(
2647                                         mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
2648                                         mode_lib->vba.DRAMClockChangeLatency,
2649                                         mode_lib->vba.UrgentLatencyPixelDataOnly,
2650                                         mode_lib->vba.SREnterPlusExitTime);
2651                         mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
2652                                         mode_lib,
2653                                         mode_lib->vba.VRatio[k],
2654                                         mode_lib->vba.SwathWidthY[k],
2655                                         dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
2656                                         mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
2657                                         mode_lib->vba.XFCTSlvVupdateOffset,
2658                                         mode_lib->vba.XFCTSlvVupdateWidth,
2659                                         mode_lib->vba.XFCTSlvVreadyOffset,
2660                                         mode_lib->vba.XFCXBUFLatencyTolerance,
2661                                         mode_lib->vba.XFCFillBWOverhead,
2662                                         mode_lib->vba.XFCSlvChunkSize,
2663                                         mode_lib->vba.XFCBusTransportTime,
2664                                         mode_lib->vba.TCalc,
2665                                         TWait,
2666                                         &mode_lib->vba.SrcActiveDrainRate,
2667                                         &mode_lib->vba.TInitXFill,
2668                                         &mode_lib->vba.TslvChk);
2669                         mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
2670                                         dml_floor(
2671                                                         mode_lib->vba.XFCRemoteSurfaceFlipDelay
2672                                                                         / (mode_lib->vba.HTotal[k]
2673                                                                                         / mode_lib->vba.PixelClock[k]),
2674                                                         1);
2675                         mode_lib->vba.XFCTransferDelay[k] =
2676                                         dml_ceil(
2677                                                         mode_lib->vba.XFCBusTransportTime
2678                                                                         / (mode_lib->vba.HTotal[k]
2679                                                                                         / mode_lib->vba.PixelClock[k]),
2680                                                         1);
2681                         mode_lib->vba.XFCPrechargeDelay[k] =
2682                                         dml_ceil(
2683                                                         (mode_lib->vba.XFCBusTransportTime
2684                                                                         + mode_lib->vba.TInitXFill
2685                                                                         + mode_lib->vba.TslvChk)
2686                                                                         / (mode_lib->vba.HTotal[k]
2687                                                                                         / mode_lib->vba.PixelClock[k]),
2688                                                         1);
2689                         mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
2690                                         * mode_lib->vba.SrcActiveDrainRate;
2691                         mode_lib->vba.FinalFillMargin =
2692                                         (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
2693                                                         + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
2694                                                         * mode_lib->vba.HTotal[k]
2695                                                         / mode_lib->vba.PixelClock[k]
2696                                                         * mode_lib->vba.SrcActiveDrainRate
2697                                                         + mode_lib->vba.XFCFillConstant;
2698                         mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
2699                                         * mode_lib->vba.SrcActiveDrainRate
2700                                         + mode_lib->vba.FinalFillMargin;
2701                         mode_lib->vba.RemainingFillLevel = dml_max(
2702                                         0.0,
2703                                         mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
2704                         mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
2705                                         / (mode_lib->vba.SrcActiveDrainRate
2706                                                         * mode_lib->vba.XFCFillBWOverhead / 100);
2707                         mode_lib->vba.XFCPrefetchMargin[k] =
2708                                         mode_lib->vba.XFCRemoteSurfaceFlipDelay
2709                                                         + mode_lib->vba.TFinalxFill
2710                                                         + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
2711                                                                         + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
2712                                                                         * mode_lib->vba.HTotal[k]
2713                                                                         / mode_lib->vba.PixelClock[k];
2714                 } else {
2715                         mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
2716                         mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
2717                         mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
2718                         mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
2719                         mode_lib->vba.XFCPrechargeDelay[k] = 0;
2720                         mode_lib->vba.XFCTransferDelay[k] = 0;
2721                         mode_lib->vba.XFCPrefetchMargin[k] = 0;
2722                 }
2723         }
2724         {
2725                 unsigned int VStartupMargin = 0;
2726                 bool FirstMainPlane = true;
2727
2728                 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2729                         if (mode_lib->vba.BlendingAndTiming[k] == k) {
2730                                 unsigned int Margin = (mode_lib->vba.MaxVStartupLines[k] - mode_lib->vba.VStartup[k])
2731                                                 * mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k];
2732
2733                                 if (FirstMainPlane) {
2734                                         VStartupMargin = Margin;
2735                                         FirstMainPlane = false;
2736                                 } else
2737                                         VStartupMargin = dml_min(VStartupMargin, Margin);
2738                 }
2739
2740                 if (mode_lib->vba.UseMaximumVStartup) {
2741                         if (mode_lib->vba.VTotal_Max[k] == mode_lib->vba.VTotal[k]) {
2742                                 //only use max vstart if it is not drr or lateflip.
2743                                 mode_lib->vba.VStartup[k] = mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]];
2744                         }
2745                 }
2746         }
2747 }
2748 }
2749
2750 static void dml20v2_DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
2751 {
2752         double BytePerPixDETY;
2753         double BytePerPixDETC;
2754         double Read256BytesBlockHeightY;
2755         double Read256BytesBlockHeightC;
2756         double Read256BytesBlockWidthY;
2757         double Read256BytesBlockWidthC;
2758         double MaximumSwathHeightY;
2759         double MaximumSwathHeightC;
2760         double MinimumSwathHeightY;
2761         double MinimumSwathHeightC;
2762         double SwathWidth;
2763         double SwathWidthGranularityY;
2764         double SwathWidthGranularityC;
2765         double RoundedUpMaxSwathSizeBytesY;
2766         double RoundedUpMaxSwathSizeBytesC;
2767         unsigned int j, k;
2768
2769         for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2770                 bool MainPlaneDoesODMCombine = false;
2771
2772                 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
2773                         BytePerPixDETY = 8;
2774                         BytePerPixDETC = 0;
2775                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
2776                         BytePerPixDETY = 4;
2777                         BytePerPixDETC = 0;
2778                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
2779                         BytePerPixDETY = 2;
2780                         BytePerPixDETC = 0;
2781                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
2782                         BytePerPixDETY = 1;
2783                         BytePerPixDETC = 0;
2784                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
2785                         BytePerPixDETY = 1;
2786                         BytePerPixDETC = 2;
2787                 } else {
2788                         BytePerPixDETY = 4.0 / 3.0;
2789                         BytePerPixDETC = 8.0 / 3.0;
2790                 }
2791
2792                 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
2793                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
2794                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
2795                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
2796                         if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
2797                                 Read256BytesBlockHeightY = 1;
2798                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
2799                                 Read256BytesBlockHeightY = 4;
2800                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
2801                                         || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
2802                                 Read256BytesBlockHeightY = 8;
2803                         } else {
2804                                 Read256BytesBlockHeightY = 16;
2805                         }
2806                         Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
2807                                         / Read256BytesBlockHeightY;
2808                         Read256BytesBlockHeightC = 0;
2809                         Read256BytesBlockWidthC = 0;
2810                 } else {
2811                         if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
2812                                 Read256BytesBlockHeightY = 1;
2813                                 Read256BytesBlockHeightC = 1;
2814                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
2815                                 Read256BytesBlockHeightY = 16;
2816                                 Read256BytesBlockHeightC = 8;
2817                         } else {
2818                                 Read256BytesBlockHeightY = 8;
2819                                 Read256BytesBlockHeightC = 8;
2820                         }
2821                         Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
2822                                         / Read256BytesBlockHeightY;
2823                         Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
2824                                         / Read256BytesBlockHeightC;
2825                 }
2826
2827                 if (mode_lib->vba.SourceScan[k] == dm_horz) {
2828                         MaximumSwathHeightY = Read256BytesBlockHeightY;
2829                         MaximumSwathHeightC = Read256BytesBlockHeightC;
2830                 } else {
2831                         MaximumSwathHeightY = Read256BytesBlockWidthY;
2832                         MaximumSwathHeightC = Read256BytesBlockWidthC;
2833                 }
2834
2835                 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
2836                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
2837                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
2838                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
2839                         if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
2840                                         || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
2841                                                         && (mode_lib->vba.SurfaceTiling[k]
2842                                                                         == dm_sw_4kb_s
2843                                                                         || mode_lib->vba.SurfaceTiling[k]
2844                                                                                         == dm_sw_4kb_s_x
2845                                                                         || mode_lib->vba.SurfaceTiling[k]
2846                                                                                         == dm_sw_64kb_s
2847                                                                         || mode_lib->vba.SurfaceTiling[k]
2848                                                                                         == dm_sw_64kb_s_t
2849                                                                         || mode_lib->vba.SurfaceTiling[k]
2850                                                                                         == dm_sw_64kb_s_x
2851                                                                         || mode_lib->vba.SurfaceTiling[k]
2852                                                                                         == dm_sw_var_s
2853                                                                         || mode_lib->vba.SurfaceTiling[k]
2854                                                                                         == dm_sw_var_s_x)
2855                                                         && mode_lib->vba.SourceScan[k] == dm_horz)) {
2856                                 MinimumSwathHeightY = MaximumSwathHeightY;
2857                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
2858                                         && mode_lib->vba.SourceScan[k] != dm_horz) {
2859                                 MinimumSwathHeightY = MaximumSwathHeightY;
2860                         } else {
2861                                 MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
2862                         }
2863                         MinimumSwathHeightC = MaximumSwathHeightC;
2864                 } else {
2865                         if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
2866                                 MinimumSwathHeightY = MaximumSwathHeightY;
2867                                 MinimumSwathHeightC = MaximumSwathHeightC;
2868                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
2869                                         && mode_lib->vba.SourceScan[k] == dm_horz) {
2870                                 MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
2871                                 MinimumSwathHeightC = MaximumSwathHeightC;
2872                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
2873                                         && mode_lib->vba.SourceScan[k] == dm_horz) {
2874                                 MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
2875                                 MinimumSwathHeightY = MaximumSwathHeightY;
2876                         } else {
2877                                 MinimumSwathHeightY = MaximumSwathHeightY;
2878                                 MinimumSwathHeightC = MaximumSwathHeightC;
2879                         }
2880                 }
2881
2882                 if (mode_lib->vba.SourceScan[k] == dm_horz) {
2883                         SwathWidth = mode_lib->vba.ViewportWidth[k];
2884                 } else {
2885                         SwathWidth = mode_lib->vba.ViewportHeight[k];
2886                 }
2887
2888                 if (mode_lib->vba.ODMCombineEnabled[k] == true) {
2889                         MainPlaneDoesODMCombine = true;
2890                 }
2891                 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
2892                         if (mode_lib->vba.BlendingAndTiming[k] == j
2893                                         && mode_lib->vba.ODMCombineEnabled[j] == true) {
2894                                 MainPlaneDoesODMCombine = true;
2895                         }
2896                 }
2897
2898                 if (MainPlaneDoesODMCombine == true) {
2899                         SwathWidth = dml_min(
2900                                         SwathWidth,
2901                                         mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
2902                 } else {
2903                         if (mode_lib->vba.DPPPerPlane[k] == 0)
2904                                 SwathWidth = 0;
2905                         else
2906                                 SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
2907                 }
2908
2909                 SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
2910                 RoundedUpMaxSwathSizeBytesY = (dml_ceil(
2911                                 (double) (SwathWidth - 1),
2912                                 SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
2913                                 * MaximumSwathHeightY;
2914                 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
2915                         RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
2916                                         + 256;
2917                 }
2918                 if (MaximumSwathHeightC > 0) {
2919                         SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
2920                                         / MaximumSwathHeightC;
2921                         RoundedUpMaxSwathSizeBytesC = (dml_ceil(
2922                                         (double) (SwathWidth / 2.0 - 1),
2923                                         SwathWidthGranularityC) + SwathWidthGranularityC)
2924                                         * BytePerPixDETC * MaximumSwathHeightC;
2925                         if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
2926                                 RoundedUpMaxSwathSizeBytesC = dml_ceil(
2927                                                 RoundedUpMaxSwathSizeBytesC,
2928                                                 256) + 256;
2929                         }
2930                 } else
2931                         RoundedUpMaxSwathSizeBytesC = 0.0;
2932
2933                 if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
2934                                 <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
2935                         mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
2936                         mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
2937                 } else {
2938                         mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
2939                         mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
2940                 }
2941
2942                 if (mode_lib->vba.SwathHeightC[k] == 0) {
2943                         mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024;
2944                         mode_lib->vba.DETBufferSizeC[k] = 0;
2945                 } else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
2946                         mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
2947                                         * 1024.0 / 2;
2948                         mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
2949                                         * 1024.0 / 2;
2950                 } else {
2951                         mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
2952                                         * 1024.0 * 2 / 3;
2953                         mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
2954                                         * 1024.0 / 3;
2955                 }
2956         }
2957 }
2958
2959 static double CalculateTWait(
2960                 unsigned int PrefetchMode,
2961                 double DRAMClockChangeLatency,
2962                 double UrgentLatencyPixelDataOnly,
2963                 double SREnterPlusExitTime)
2964 {
2965         if (PrefetchMode == 0) {
2966                 return dml_max(
2967                                 DRAMClockChangeLatency + UrgentLatencyPixelDataOnly,
2968                                 dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly));
2969         } else if (PrefetchMode == 1) {
2970                 return dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly);
2971         } else {
2972                 return UrgentLatencyPixelDataOnly;
2973         }
2974 }
2975
2976 static double CalculateRemoteSurfaceFlipDelay(
2977                 struct display_mode_lib *mode_lib,
2978                 double VRatio,
2979                 double SwathWidth,
2980                 double Bpp,
2981                 double LineTime,
2982                 double XFCTSlvVupdateOffset,
2983                 double XFCTSlvVupdateWidth,
2984                 double XFCTSlvVreadyOffset,
2985                 double XFCXBUFLatencyTolerance,
2986                 double XFCFillBWOverhead,
2987                 double XFCSlvChunkSize,
2988                 double XFCBusTransportTime,
2989                 double TCalc,
2990                 double TWait,
2991                 double *SrcActiveDrainRate,
2992                 double *TInitXFill,
2993                 double *TslvChk)
2994 {
2995         double TSlvSetup, AvgfillRate, result;
2996
2997         *SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
2998         TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
2999         *TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
3000         AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
3001         *TslvChk = XFCSlvChunkSize / AvgfillRate;
3002         dml_print(
3003                         "DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
3004                         *SrcActiveDrainRate);
3005         dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
3006         dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
3007         dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
3008         dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
3009         result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
3010         dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
3011         return result;
3012 }
3013
3014 static double CalculateWriteBackDelay(
3015                 enum source_format_class WritebackPixelFormat,
3016                 double WritebackHRatio,
3017                 double WritebackVRatio,
3018                 unsigned int WritebackLumaHTaps,
3019                 unsigned int WritebackLumaVTaps,
3020                 unsigned int WritebackChromaHTaps,
3021                 unsigned int WritebackChromaVTaps,
3022                 unsigned int WritebackDestinationWidth)
3023 {
3024         double CalculateWriteBackDelay =
3025                         dml_max(
3026                                         dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
3027                                         WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
3028                                                         * dml_ceil(
3029                                                                         WritebackDestinationWidth
3030                                                                                         / 4.0,
3031                                                                         1)
3032                                                         + dml_ceil(1.0 / WritebackVRatio, 1)
3033                                                                         * (dml_ceil(
3034                                                                                         WritebackLumaVTaps
3035                                                                                                         / 4.0,
3036                                                                                         1) + 4));
3037
3038         if (WritebackPixelFormat != dm_444_32) {
3039                 CalculateWriteBackDelay =
3040                                 dml_max(
3041                                                 CalculateWriteBackDelay,
3042                                                 dml_max(
3043                                                                 dml_ceil(
3044                                                                                 WritebackChromaHTaps
3045                                                                                                 / 2.0,
3046                                                                                 1)
3047                                                                                 / (2
3048                                                                                                 * WritebackHRatio),
3049                                                                 WritebackChromaVTaps
3050                                                                                 * dml_ceil(
3051                                                                                                 1
3052                                                                                                                 / (2
3053                                                                                                                                 * WritebackVRatio),
3054                                                                                                 1)
3055                                                                                 * dml_ceil(
3056                                                                                                 WritebackDestinationWidth
3057                                                                                                                 / 2.0
3058                                                                                                                 / 2.0,
3059                                                                                                 1)
3060                                                                                 + dml_ceil(
3061                                                                                                 1
3062                                                                                                                 / (2
3063                                                                                                                                 * WritebackVRatio),
3064                                                                                                 1)
3065                                                                                                 * (dml_ceil(
3066                                                                                                                 WritebackChromaVTaps
3067                                                                                                                                 / 4.0,
3068                                                                                                                 1)
3069                                                                                                                 + 4)));
3070         }
3071         return CalculateWriteBackDelay;
3072 }
3073
3074 static void CalculateActiveRowBandwidth(
3075                 bool GPUVMEnable,
3076                 enum source_format_class SourcePixelFormat,
3077                 double VRatio,
3078                 bool DCCEnable,
3079                 double LineTime,
3080                 unsigned int MetaRowByteLuma,
3081                 unsigned int MetaRowByteChroma,
3082                 unsigned int meta_row_height_luma,
3083                 unsigned int meta_row_height_chroma,
3084                 unsigned int PixelPTEBytesPerRowLuma,
3085                 unsigned int PixelPTEBytesPerRowChroma,
3086                 unsigned int dpte_row_height_luma,
3087                 unsigned int dpte_row_height_chroma,
3088                 double *meta_row_bw,
3089                 double *dpte_row_bw,
3090                 double *qual_row_bw)
3091 {
3092         if (DCCEnable != true) {
3093                 *meta_row_bw = 0;
3094         } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3095                 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
3096                                 + VRatio / 2 * MetaRowByteChroma
3097                                                 / (meta_row_height_chroma * LineTime);
3098         } else {
3099                 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
3100         }
3101
3102         if (GPUVMEnable != true) {
3103                 *dpte_row_bw = 0;
3104         } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3105                 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
3106                                 + VRatio / 2 * PixelPTEBytesPerRowChroma
3107                                                 / (dpte_row_height_chroma * LineTime);
3108         } else {
3109                 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
3110         }
3111
3112         if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
3113                 *qual_row_bw = *meta_row_bw + *dpte_row_bw;
3114         } else {
3115                 *qual_row_bw = 0;
3116         }
3117 }
3118
3119 static void CalculateFlipSchedule(
3120                 struct display_mode_lib *mode_lib,
3121                 double UrgentExtraLatency,
3122                 double UrgentLatencyPixelDataOnly,
3123                 unsigned int GPUVMMaxPageTableLevels,
3124                 bool GPUVMEnable,
3125                 double BandwidthAvailableForImmediateFlip,
3126                 unsigned int TotImmediateFlipBytes,
3127                 enum source_format_class SourcePixelFormat,
3128                 unsigned int ImmediateFlipBytes,
3129                 double LineTime,
3130                 double VRatio,
3131                 double Tno_bw,
3132                 double PDEAndMetaPTEBytesFrame,
3133                 unsigned int MetaRowByte,
3134                 unsigned int PixelPTEBytesPerRow,
3135                 bool DCCEnable,
3136                 unsigned int dpte_row_height,
3137                 unsigned int meta_row_height,
3138                 double qual_row_bw,
3139                 double *DestinationLinesToRequestVMInImmediateFlip,
3140                 double *DestinationLinesToRequestRowInImmediateFlip,
3141                 double *final_flip_bw,
3142                 bool *ImmediateFlipSupportedForPipe)
3143 {
3144         double min_row_time = 0.0;
3145
3146         if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3147                 *DestinationLinesToRequestVMInImmediateFlip = 0.0;
3148                 *DestinationLinesToRequestRowInImmediateFlip = 0.0;
3149                 *final_flip_bw = qual_row_bw;
3150                 *ImmediateFlipSupportedForPipe = true;
3151         } else {
3152                 double TimeForFetchingMetaPTEImmediateFlip;
3153                 double TimeForFetchingRowInVBlankImmediateFlip;
3154
3155                 if (GPUVMEnable == true) {
3156                         mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
3157                                         * ImmediateFlipBytes / TotImmediateFlipBytes;
3158                         TimeForFetchingMetaPTEImmediateFlip =
3159                                         dml_max(
3160                                                         Tno_bw
3161                                                                         + PDEAndMetaPTEBytesFrame
3162                                                                                         / mode_lib->vba.ImmediateFlipBW[0],
3163                                                         dml_max(
3164                                                                         UrgentExtraLatency
3165                                                                                         + UrgentLatencyPixelDataOnly
3166                                                                                                         * (GPUVMMaxPageTableLevels
3167                                                                                                                         - 1),
3168                                                                         LineTime / 4.0));
3169                 } else {
3170                         TimeForFetchingMetaPTEImmediateFlip = 0;
3171                 }
3172
3173                 *DestinationLinesToRequestVMInImmediateFlip = dml_floor(
3174                                 4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
3175                                 1) / 4.0;
3176
3177                 if ((GPUVMEnable == true || DCCEnable == true)) {
3178                         mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
3179                                         * ImmediateFlipBytes / TotImmediateFlipBytes;
3180                         TimeForFetchingRowInVBlankImmediateFlip = dml_max(
3181                                         (MetaRowByte + PixelPTEBytesPerRow)
3182                                                         / mode_lib->vba.ImmediateFlipBW[0],
3183                                         dml_max(UrgentLatencyPixelDataOnly, LineTime / 4.0));
3184                 } else {
3185                         TimeForFetchingRowInVBlankImmediateFlip = 0;
3186                 }
3187
3188                 *DestinationLinesToRequestRowInImmediateFlip = dml_floor(
3189                                 4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
3190                                 1) / 4.0;
3191
3192                 if (GPUVMEnable == true) {
3193                         *final_flip_bw =
3194                                         dml_max(
3195                                                         PDEAndMetaPTEBytesFrame
3196                                                                         / (*DestinationLinesToRequestVMInImmediateFlip
3197                                                                                         * LineTime),
3198                                                         (MetaRowByte + PixelPTEBytesPerRow)
3199                                                                         / (TimeForFetchingRowInVBlankImmediateFlip
3200                                                                                         * LineTime));
3201                 } else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
3202                         *final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
3203                                         / (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
3204                 } else {
3205                         *final_flip_bw = 0;
3206                 }
3207
3208                 if (GPUVMEnable && !DCCEnable)
3209                         min_row_time = dpte_row_height * LineTime / VRatio;
3210                 else if (!GPUVMEnable && DCCEnable)
3211                         min_row_time = meta_row_height * LineTime / VRatio;
3212                 else
3213                         min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
3214                                         / VRatio;
3215
3216                 if (*DestinationLinesToRequestVMInImmediateFlip >= 8
3217                                 || *DestinationLinesToRequestRowInImmediateFlip >= 16
3218                                 || TimeForFetchingMetaPTEImmediateFlip
3219                                                 + 2 * TimeForFetchingRowInVBlankImmediateFlip
3220                                                 > min_row_time)
3221                         *ImmediateFlipSupportedForPipe = false;
3222                 else
3223                         *ImmediateFlipSupportedForPipe = true;
3224         }
3225 }
3226
3227 static unsigned int TruncToValidBPP(
3228                 double DecimalBPP,
3229                 bool DSCEnabled,
3230                 enum output_encoder_class Output,
3231                 enum output_format_class Format,
3232                 unsigned int DSCInputBitPerComponent)
3233 {
3234         if (Output == dm_hdmi) {
3235                 if (Format == dm_420) {
3236                         if (DecimalBPP >= 18)
3237                                 return 18;
3238                         else if (DecimalBPP >= 15)
3239                                 return 15;
3240                         else if (DecimalBPP >= 12)
3241                                 return 12;
3242                         else
3243                                 return BPP_INVALID;
3244                 } else if (Format == dm_444) {
3245                         if (DecimalBPP >= 36)
3246                                 return 36;
3247                         else if (DecimalBPP >= 30)
3248                                 return 30;
3249                         else if (DecimalBPP >= 24)
3250                                 return 24;
3251                         else if (DecimalBPP >= 18)
3252                                 return 18;
3253                         else
3254                                 return BPP_INVALID;
3255                 } else {
3256                         if (DecimalBPP / 1.5 >= 24)
3257                                 return 24;
3258                         else if (DecimalBPP / 1.5 >= 20)
3259                                 return 20;
3260                         else if (DecimalBPP / 1.5 >= 16)
3261                                 return 16;
3262                         else
3263                                 return BPP_INVALID;
3264                 }
3265         } else {
3266                 if (DSCEnabled) {
3267                         if (Format == dm_420) {
3268                                 if (DecimalBPP < 6)
3269                                         return BPP_INVALID;
3270                                 else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
3271                                         return 1.5 * DSCInputBitPerComponent - 1 / 16;
3272                                 else
3273                                         return dml_floor(16 * DecimalBPP, 1) / 16;
3274                         } else if (Format == dm_n422) {
3275                                 if (DecimalBPP < 7)
3276                                         return BPP_INVALID;
3277                                 else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
3278                                         return 2 * DSCInputBitPerComponent - 1 / 16;
3279                                 else
3280                                         return dml_floor(16 * DecimalBPP, 1) / 16;
3281                         } else {
3282                                 if (DecimalBPP < 8)
3283                                         return BPP_INVALID;
3284                                 else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
3285                                         return 3 * DSCInputBitPerComponent - 1 / 16;
3286                                 else
3287                                         return dml_floor(16 * DecimalBPP, 1) / 16;
3288                         }
3289                 } else if (Format == dm_420) {
3290                         if (DecimalBPP >= 18)
3291                                 return 18;
3292                         else if (DecimalBPP >= 15)
3293                                 return 15;
3294                         else if (DecimalBPP >= 12)
3295                                 return 12;
3296                         else
3297                                 return BPP_INVALID;
3298                 } else if (Format == dm_s422 || Format == dm_n422) {
3299                         if (DecimalBPP >= 24)
3300                                 return 24;
3301                         else if (DecimalBPP >= 20)
3302                                 return 20;
3303                         else if (DecimalBPP >= 16)
3304                                 return 16;
3305                         else
3306                                 return BPP_INVALID;
3307                 } else {
3308                         if (DecimalBPP >= 36)
3309                                 return 36;
3310                         else if (DecimalBPP >= 30)
3311                                 return 30;
3312                         else if (DecimalBPP >= 24)
3313                                 return 24;
3314                         else if (DecimalBPP >= 18)
3315                                 return 18;
3316                         else
3317                                 return BPP_INVALID;
3318                 }
3319         }
3320 }
3321
3322 void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
3323 {
3324         struct vba_vars_st *locals = &mode_lib->vba;
3325
3326         int i;
3327         unsigned int j, k, m;
3328
3329         /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
3330
3331         /*Scale Ratio, taps Support Check*/
3332
3333         mode_lib->vba.ScaleRatioAndTapsSupport = true;
3334         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3335                 if (mode_lib->vba.ScalerEnabled[k] == false
3336                                 && ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
3337                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
3338                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
3339                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
3340                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
3341                                                 || mode_lib->vba.HRatio[k] != 1.0
3342                                                 || mode_lib->vba.htaps[k] != 1.0
3343                                                 || mode_lib->vba.VRatio[k] != 1.0
3344                                                 || mode_lib->vba.vtaps[k] != 1.0)) {
3345                         mode_lib->vba.ScaleRatioAndTapsSupport = false;
3346                 } else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
3347                                 || mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
3348                                 || (mode_lib->vba.htaps[k] > 1.0
3349                                                 && (mode_lib->vba.htaps[k] % 2) == 1)
3350                                 || mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
3351                                 || mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
3352                                 || mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
3353                                 || mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
3354                                 || (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
3355                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
3356                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
3357                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
3358                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
3359                                                 && (mode_lib->vba.HRatio[k] / 2.0
3360                                                                 > mode_lib->vba.HTAPsChroma[k]
3361                                                                 || mode_lib->vba.VRatio[k] / 2.0
3362                                                                                 > mode_lib->vba.VTAPsChroma[k]))) {
3363                         mode_lib->vba.ScaleRatioAndTapsSupport = false;
3364                 }
3365         }
3366         /*Source Format, Pixel Format and Scan Support Check*/
3367
3368         mode_lib->vba.SourceFormatPixelAndScanSupport = true;
3369         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3370                 if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
3371                                 && mode_lib->vba.SourceScan[k] != dm_horz)
3372                                 || ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
3373                                                 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
3374                                                 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
3375                                                 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
3376                                                 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
3377                                                 || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
3378                                                 || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
3379                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
3380                                 || (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
3381                                                 && (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
3382                                                                 || mode_lib->vba.SourcePixelFormat[k]
3383                                                                                 == dm_420_8
3384                                                                 || mode_lib->vba.SourcePixelFormat[k]
3385                                                                                 == dm_420_10))
3386                                 || (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
3387                                                 || mode_lib->vba.SurfaceTiling[k]
3388                                                                 == dm_sw_gfx7_2d_thin_lvp)
3389                                                 && !((mode_lib->vba.SourcePixelFormat[k]
3390                                                                 == dm_444_64
3391                                                                 || mode_lib->vba.SourcePixelFormat[k]
3392                                                                                 == dm_444_32)
3393                                                                 && mode_lib->vba.SourceScan[k]
3394                                                                                 == dm_horz
3395                                                                 && mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
3396                                                                                 == true
3397                                                                 && mode_lib->vba.DCCEnable[k]
3398                                                                                 == false))
3399                                                 || (mode_lib->vba.DCCEnable[k] == true
3400                                                                 && (mode_lib->vba.SurfaceTiling[k]
3401                                                                                 == dm_sw_linear
3402                                                                                 || mode_lib->vba.SourcePixelFormat[k]
3403                                                                                                 == dm_420_8
3404                                                                                 || mode_lib->vba.SourcePixelFormat[k]
3405                                                                                                 == dm_420_10)))) {
3406                         mode_lib->vba.SourceFormatPixelAndScanSupport = false;
3407                 }
3408         }
3409         /*Bandwidth Support Check*/
3410
3411         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3412                 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
3413                         locals->BytePerPixelInDETY[k] = 8.0;
3414                         locals->BytePerPixelInDETC[k] = 0.0;
3415                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
3416                         locals->BytePerPixelInDETY[k] = 4.0;
3417                         locals->BytePerPixelInDETC[k] = 0.0;
3418                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
3419                                 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
3420                         locals->BytePerPixelInDETY[k] = 2.0;
3421                         locals->BytePerPixelInDETC[k] = 0.0;
3422                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
3423                         locals->BytePerPixelInDETY[k] = 1.0;
3424                         locals->BytePerPixelInDETC[k] = 0.0;
3425                 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
3426                         locals->BytePerPixelInDETY[k] = 1.0;
3427                         locals->BytePerPixelInDETC[k] = 2.0;
3428                 } else {
3429                         locals->BytePerPixelInDETY[k] = 4.0 / 3;
3430                         locals->BytePerPixelInDETC[k] = 8.0 / 3;
3431                 }
3432                 if (mode_lib->vba.SourceScan[k] == dm_horz) {
3433                         locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
3434                 } else {
3435                         locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
3436                 }
3437         }
3438         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3439                 locals->ReadBandwidthLuma[k] = locals->SwathWidthYSingleDPP[k] * dml_ceil(locals->BytePerPixelInDETY[k], 1.0)
3440                                 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
3441                 locals->ReadBandwidthChroma[k] = locals->SwathWidthYSingleDPP[k] / 2 * dml_ceil(locals->BytePerPixelInDETC[k], 2.0)
3442                                 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k] / 2.0;
3443                 locals->ReadBandwidth[k] = locals->ReadBandwidthLuma[k] + locals->ReadBandwidthChroma[k];
3444         }
3445         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3446                 if (mode_lib->vba.WritebackEnable[k] == true
3447                                 && mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
3448                         locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
3449                                         * mode_lib->vba.WritebackDestinationHeight[k]
3450                                         / (mode_lib->vba.WritebackSourceHeight[k]
3451                                                         * mode_lib->vba.HTotal[k]
3452                                                         / mode_lib->vba.PixelClock[k]) * 4.0;
3453                 } else if (mode_lib->vba.WritebackEnable[k] == true
3454                                 && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
3455                         locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
3456                                         * mode_lib->vba.WritebackDestinationHeight[k]
3457                                         / (mode_lib->vba.WritebackSourceHeight[k]
3458                                                         * mode_lib->vba.HTotal[k]
3459                                                         / mode_lib->vba.PixelClock[k]) * 3.0;
3460                 } else if (mode_lib->vba.WritebackEnable[k] == true) {
3461                         locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
3462                                         * mode_lib->vba.WritebackDestinationHeight[k]
3463                                         / (mode_lib->vba.WritebackSourceHeight[k]
3464                                                         * mode_lib->vba.HTotal[k]
3465                                                         / mode_lib->vba.PixelClock[k]) * 1.5;
3466                 } else {
3467                         locals->WriteBandwidth[k] = 0.0;
3468                 }
3469         }
3470         mode_lib->vba.DCCEnabledInAnyPlane = false;
3471         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3472                 if (mode_lib->vba.DCCEnable[k] == true) {
3473                         mode_lib->vba.DCCEnabledInAnyPlane = true;
3474                 }
3475         }
3476         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
3477                 locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
3478                                 mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
3479                                                 * mode_lib->vba.DRAMChannelWidth,
3480                                 mode_lib->vba.FabricClockPerState[i]
3481                                                 * mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000;
3482                 locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth * locals->DCFCLKPerState[i],
3483                                 locals->FabricAndDRAMBandwidthPerState[i] * 1000)
3484                                 * locals->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
3485
3486                 locals->ReturnBWPerState[i] = locals->ReturnBWToDCNPerState;
3487
3488                 if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
3489                         locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
3490                                         locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
3491                                         ((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
3492                                         / (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
3493                                         * locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
3494                 }
3495                 locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
3496                                 locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
3497                                 + (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
3498
3499                 if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
3500                         locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
3501                                 4 * locals->ReturnBWToDCNPerState *
3502                                 (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
3503                                 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
3504                                 dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
3505                                 + (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
3506                 }
3507
3508                 locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth *
3509                                 locals->DCFCLKPerState[i], locals->FabricAndDRAMBandwidthPerState[i] * 1000);
3510
3511                 if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
3512                         locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
3513                                         locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
3514                                         ((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
3515                                         / (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
3516                                         * locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
3517                 }
3518                 locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
3519                                 locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
3520                                 + (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
3521
3522                 if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
3523                         locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
3524                                 4 * locals->ReturnBWToDCNPerState *
3525                                 (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
3526                                 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
3527                                 dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
3528                                 + (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
3529                 }
3530         }
3531         /*Writeback Latency support check*/
3532
3533         mode_lib->vba.WritebackLatencySupport = true;
3534         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3535                 if (mode_lib->vba.WritebackEnable[k] == true) {
3536                         if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
3537                                 if (locals->WriteBandwidth[k]
3538                                                 > (mode_lib->vba.WritebackInterfaceLumaBufferSize
3539                                                                 + mode_lib->vba.WritebackInterfaceChromaBufferSize)
3540                                                                 / mode_lib->vba.WritebackLatency) {
3541                                         mode_lib->vba.WritebackLatencySupport = false;
3542                                 }
3543                         } else {
3544                                 if (locals->WriteBandwidth[k]
3545                                                 > 1.5
3546                                                                 * dml_min(
3547                                                                                 mode_lib->vba.WritebackInterfaceLumaBufferSize,
3548                                                                                 2.0
3549                                                                                                 * mode_lib->vba.WritebackInterfaceChromaBufferSize)
3550                                                                 / mode_lib->vba.WritebackLatency) {
3551                                         mode_lib->vba.WritebackLatencySupport = false;
3552                                 }
3553                         }
3554                 }
3555         }
3556         /*Re-ordering Buffer Support Check*/
3557
3558         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
3559                 locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
3560                                 (mode_lib->vba.RoundTripPingLatencyCycles + 32.0) / mode_lib->vba.DCFCLKPerState[i]
3561                                 + locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i];
3562                 if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i]
3563                                 > locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
3564                         locals->ROBSupport[i] = true;
3565                 } else {
3566                         locals->ROBSupport[i] = false;
3567                 }
3568         }
3569         /*Writeback Mode Support Check*/
3570
3571         mode_lib->vba.TotalNumberOfActiveWriteback = 0;
3572         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3573                 if (mode_lib->vba.WritebackEnable[k] == true) {
3574                         if (mode_lib->vba.ActiveWritebacksPerPlane[k] == 0)
3575                                 mode_lib->vba.ActiveWritebacksPerPlane[k] = 1;
3576                         mode_lib->vba.TotalNumberOfActiveWriteback =
3577                                         mode_lib->vba.TotalNumberOfActiveWriteback
3578                                                         + mode_lib->vba.ActiveWritebacksPerPlane[k];
3579                 }
3580         }
3581         mode_lib->vba.WritebackModeSupport = true;
3582         if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
3583                 mode_lib->vba.WritebackModeSupport = false;
3584         }
3585         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3586                 if (mode_lib->vba.WritebackEnable[k] == true
3587                                 && mode_lib->vba.Writeback10bpc420Supported != true
3588                                 && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
3589                         mode_lib->vba.WritebackModeSupport = false;
3590                 }
3591         }
3592         /*Writeback Scale Ratio and Taps Support Check*/
3593
3594         mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
3595         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3596                 if (mode_lib->vba.WritebackEnable[k] == true) {
3597                         if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
3598                                         && (mode_lib->vba.WritebackHRatio[k] != 1.0
3599                                                         || mode_lib->vba.WritebackVRatio[k] != 1.0)) {
3600                                 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
3601                         }
3602                         if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
3603                                         || mode_lib->vba.WritebackVRatio[k]
3604                                                         > mode_lib->vba.WritebackMaxVSCLRatio
3605                                         || mode_lib->vba.WritebackHRatio[k]
3606                                                         < mode_lib->vba.WritebackMinHSCLRatio
3607                                         || mode_lib->vba.WritebackVRatio[k]
3608                                                         < mode_lib->vba.WritebackMinVSCLRatio
3609                                         || mode_lib->vba.WritebackLumaHTaps[k]
3610                                                         > mode_lib->vba.WritebackMaxHSCLTaps
3611                                         || mode_lib->vba.WritebackLumaVTaps[k]
3612                                                         > mode_lib->vba.WritebackMaxVSCLTaps
3613                                         || mode_lib->vba.WritebackHRatio[k]
3614                                                         > mode_lib->vba.WritebackLumaHTaps[k]
3615                                         || mode_lib->vba.WritebackVRatio[k]
3616                                                         > mode_lib->vba.WritebackLumaVTaps[k]
3617                                         || (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
3618                                                         && ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
3619                                                                         == 1))
3620                                         || (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
3621                                                         && (mode_lib->vba.WritebackChromaHTaps[k]
3622                                                                         > mode_lib->vba.WritebackMaxHSCLTaps
3623                                                                         || mode_lib->vba.WritebackChromaVTaps[k]
3624                                                                                         > mode_lib->vba.WritebackMaxVSCLTaps
3625                                                                         || 2.0
3626                                                                                         * mode_lib->vba.WritebackHRatio[k]
3627                                                                                         > mode_lib->vba.WritebackChromaHTaps[k]
3628                                                                         || 2.0
3629                                                                                         * mode_lib->vba.WritebackVRatio[k]
3630                                                                                         > mode_lib->vba.WritebackChromaVTaps[k]
3631                                                                         || (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
3632                                                                                 && ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
3633                                 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
3634                         }
3635                         if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
3636                                 mode_lib->vba.WritebackLumaVExtra =
3637                                                 dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
3638                         } else {
3639                                 mode_lib->vba.WritebackLumaVExtra = -1;
3640                         }
3641                         if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
3642                                         && mode_lib->vba.WritebackLumaVTaps[k]
3643                                                         > (mode_lib->vba.WritebackLineBufferLumaBufferSize
3644                                                                         + mode_lib->vba.WritebackLineBufferChromaBufferSize)
3645                                                                         / 3.0
3646                                                                         / mode_lib->vba.WritebackDestinationWidth[k]
3647                                                                         - mode_lib->vba.WritebackLumaVExtra)
3648                                         || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
3649                                                         && mode_lib->vba.WritebackLumaVTaps[k]
3650                                                                         > mode_lib->vba.WritebackLineBufferLumaBufferSize
3651                                                                                         * 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
3652                                                                                         - mode_lib->vba.WritebackLumaVExtra)
3653                                         || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
3654                                                         && mode_lib->vba.WritebackLumaVTaps[k]
3655                                                                         > mode_lib->vba.WritebackLineBufferLumaBufferSize
3656                                                                                         * 8.0 / 10.0
3657                                                                                         / mode_lib->vba.WritebackDestinationWidth[k]
3658                                                                                         - mode_lib->vba.WritebackLumaVExtra)) {
3659                                 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
3660                         }
3661                         if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
3662                                 mode_lib->vba.WritebackChromaVExtra = 0.0;
3663                         } else {
3664                                 mode_lib->vba.WritebackChromaVExtra = -1;
3665                         }
3666                         if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
3667                                         && mode_lib->vba.WritebackChromaVTaps[k]
3668                                                         > mode_lib->vba.WritebackLineBufferChromaBufferSize
3669                                                                         * 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
3670                                                                         - mode_lib->vba.WritebackChromaVExtra)
3671                                         || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
3672                                                         && mode_lib->vba.WritebackChromaVTaps[k]
3673                                                                         > mode_lib->vba.WritebackLineBufferChromaBufferSize
3674                                                                                         * 8.0 / 10.0
3675                                                                                         / mode_lib->vba.WritebackDestinationWidth[k]
3676                                                                                         - mode_lib->vba.WritebackChromaVExtra)) {
3677                                 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
3678                         }
3679                 }
3680         }
3681         /*Maximum DISPCLK/DPPCLK Support check*/
3682
3683         mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
3684         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3685                 if (mode_lib->vba.WritebackEnable[k] == true) {
3686                         mode_lib->vba.WritebackRequiredDISPCLK =
3687                                         dml_max(
3688                                                         mode_lib->vba.WritebackRequiredDISPCLK,
3689                                                         CalculateWriteBackDISPCLK(
3690                                                                         mode_lib->vba.WritebackPixelFormat[k],
3691                                                                         mode_lib->vba.PixelClock[k],
3692                                                                         mode_lib->vba.WritebackHRatio[k],
3693                                                                         mode_lib->vba.WritebackVRatio[k],
3694                                                                         mode_lib->vba.WritebackLumaHTaps[k],
3695                                                                         mode_lib->vba.WritebackLumaVTaps[k],
3696                                                                         mode_lib->vba.WritebackChromaHTaps[k],
3697                                                                         mode_lib->vba.WritebackChromaVTaps[k],
3698                                                                         mode_lib->vba.WritebackDestinationWidth[k],
3699                                                                         mode_lib->vba.HTotal[k],
3700                                                                         mode_lib->vba.WritebackChromaLineBufferWidth));
3701                 }
3702         }
3703         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3704                 if (mode_lib->vba.HRatio[k] > 1.0) {
3705                         locals->PSCL_FACTOR[k] = dml_min(
3706                                         mode_lib->vba.MaxDCHUBToPSCLThroughput,
3707                                         mode_lib->vba.MaxPSCLToLBThroughput
3708                                                         * mode_lib->vba.HRatio[k]
3709                                                         / dml_ceil(
3710                                                                         mode_lib->vba.htaps[k]
3711                                                                                         / 6.0,
3712                                                                         1.0));
3713                 } else {
3714                         locals->PSCL_FACTOR[k] = dml_min(
3715                                         mode_lib->vba.MaxDCHUBToPSCLThroughput,
3716                                         mode_lib->vba.MaxPSCLToLBThroughput);
3717                 }
3718                 if (locals->BytePerPixelInDETC[k] == 0.0) {
3719                         locals->PSCL_FACTOR_CHROMA[k] = 0.0;
3720                         locals->MinDPPCLKUsingSingleDPP[k] =
3721                                         mode_lib->vba.PixelClock[k]
3722                                                         * dml_max3(
3723                                                                         mode_lib->vba.vtaps[k] / 6.0
3724                                                                                         * dml_min(
3725                                                                                                         1.0,
3726                                                                                                         mode_lib->vba.HRatio[k]),
3727                                                                         mode_lib->vba.HRatio[k]
3728                                                                                         * mode_lib->vba.VRatio[k]
3729                                                                                         / locals->PSCL_FACTOR[k],
3730                                                                         1.0);
3731                         if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
3732                                         && locals->MinDPPCLKUsingSingleDPP[k]
3733                                                         < 2.0 * mode_lib->vba.PixelClock[k]) {
3734                                 locals->MinDPPCLKUsingSingleDPP[k] = 2.0
3735                                                 * mode_lib->vba.PixelClock[k];
3736                         }
3737                 } else {
3738                         if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
3739                                 locals->PSCL_FACTOR_CHROMA[k] =
3740                                                 dml_min(
3741                                                                 mode_lib->vba.MaxDCHUBToPSCLThroughput,
3742                                                                 mode_lib->vba.MaxPSCLToLBThroughput
3743                                                                                 * mode_lib->vba.HRatio[k]
3744                                                                                 / 2.0
3745                                                                                 / dml_ceil(
3746                                                                                                 mode_lib->vba.HTAPsChroma[k]
3747                                                                                                                 / 6.0,
3748                                                                                                 1.0));
3749                         } else {
3750                                 locals->PSCL_FACTOR_CHROMA[k] = dml_min(
3751                                                 mode_lib->vba.MaxDCHUBToPSCLThroughput,
3752                                                 mode_lib->vba.MaxPSCLToLBThroughput);
3753                         }
3754                         locals->MinDPPCLKUsingSingleDPP[k] =
3755                                         mode_lib->vba.PixelClock[k]
3756                                                         * dml_max5(
3757                                                                         mode_lib->vba.vtaps[k] / 6.0
3758                                                                                         * dml_min(
3759                                                                                                         1.0,
3760                                                                                                         mode_lib->vba.HRatio[k]),
3761                                                                         mode_lib->vba.HRatio[k]
3762                                                                                         * mode_lib->vba.VRatio[k]
3763                                                                                         / locals->PSCL_FACTOR[k],
3764                                                                         mode_lib->vba.VTAPsChroma[k]
3765                                                                                         / 6.0
3766                                                                                         * dml_min(
3767                                                                                                         1.0,
3768                                                                                                         mode_lib->vba.HRatio[k]
3769                                                                                                                         / 2.0),
3770                                                                         mode_lib->vba.HRatio[k]
3771                                                                                         * mode_lib->vba.VRatio[k]
3772                                                                                         / 4.0
3773                                                                                         / locals->PSCL_FACTOR_CHROMA[k],
3774                                                                         1.0);
3775                         if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
3776                                         || mode_lib->vba.HTAPsChroma[k] > 6.0
3777                                         || mode_lib->vba.VTAPsChroma[k] > 6.0)
3778                                         && locals->MinDPPCLKUsingSingleDPP[k]
3779                                                         < 2.0 * mode_lib->vba.PixelClock[k]) {
3780                                 locals->MinDPPCLKUsingSingleDPP[k] = 2.0
3781                                                 * mode_lib->vba.PixelClock[k];
3782                         }
3783                 }
3784         }
3785         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3786                 Calculate256BBlockSizes(
3787                                 mode_lib->vba.SourcePixelFormat[k],
3788                                 mode_lib->vba.SurfaceTiling[k],
3789                                 dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
3790                                 dml_ceil(locals->BytePerPixelInDETC[k], 2.0),
3791                                 &locals->Read256BlockHeightY[k],
3792                                 &locals->Read256BlockHeightC[k],
3793                                 &locals->Read256BlockWidthY[k],
3794                                 &locals->Read256BlockWidthC[k]);
3795                 if (mode_lib->vba.SourceScan[k] == dm_horz) {
3796                         locals->MaxSwathHeightY[k] = locals->Read256BlockHeightY[k];
3797                         locals->MaxSwathHeightC[k] = locals->Read256BlockHeightC[k];
3798                 } else {
3799                         locals->MaxSwathHeightY[k] = locals->Read256BlockWidthY[k];
3800                         locals->MaxSwathHeightC[k] = locals->Read256BlockWidthC[k];
3801                 }
3802                 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3803                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
3804                                 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
3805                                 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
3806                                 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
3807                         if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
3808                                         || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3809                                                         && (mode_lib->vba.SurfaceTiling[k]
3810                                                                         == dm_sw_4kb_s
3811                                                                         || mode_lib->vba.SurfaceTiling[k]
3812                                                                                         == dm_sw_4kb_s_x
3813                                                                         || mode_lib->vba.SurfaceTiling[k]
3814                                                                                         == dm_sw_64kb_s
3815                                                                         || mode_lib->vba.SurfaceTiling[k]
3816                                                                                         == dm_sw_64kb_s_t
3817                                                                         || mode_lib->vba.SurfaceTiling[k]
3818                                                                                         == dm_sw_64kb_s_x
3819                                                                         || mode_lib->vba.SurfaceTiling[k]
3820                                                                                         == dm_sw_var_s
3821                                                                         || mode_lib->vba.SurfaceTiling[k]
3822                                                                                         == dm_sw_var_s_x)
3823                                                         && mode_lib->vba.SourceScan[k] == dm_horz)) {
3824                                 locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
3825                         } else {
3826                                 locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
3827                                                 / 2.0;
3828                         }
3829                         locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
3830                 } else {
3831                         if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3832                                 locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
3833                                 locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
3834                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
3835                                         && mode_lib->vba.SourceScan[k] == dm_horz) {
3836                                 locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
3837                                                 / 2.0;
3838                                 locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
3839                         } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
3840                                         && mode_lib->vba.SourceScan[k] == dm_horz) {
3841                                 locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k]
3842                                                 / 2.0;
3843                                 locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
3844                         } else {
3845                                 locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
3846                                 locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
3847                         }
3848                 }
3849                 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3850                         mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
3851                 } else {
3852                         mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
3853                 }
3854                 mode_lib->vba.MaximumSwathWidthInDETBuffer =
3855                                 dml_min(
3856                                                 mode_lib->vba.MaximumSwathWidthSupport,
3857                                                 mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
3858                                                                 / (locals->BytePerPixelInDETY[k]
3859                                                                                 * locals->MinSwathHeightY[k]
3860                                                                                 + locals->BytePerPixelInDETC[k]
3861                                                                                                 / 2.0
3862                                                                                                 * locals->MinSwathHeightC[k]));
3863                 if (locals->BytePerPixelInDETC[k] == 0.0) {
3864                         mode_lib->vba.MaximumSwathWidthInLineBuffer =
3865                                         mode_lib->vba.LineBufferSize
3866                                                         * dml_max(mode_lib->vba.HRatio[k], 1.0)
3867                                                         / mode_lib->vba.LBBitPerPixel[k]
3868                                                         / (mode_lib->vba.vtaps[k]
3869                                                                         + dml_max(
3870                                                                                         dml_ceil(
3871                                                                                                         mode_lib->vba.VRatio[k],
3872                                                                                                         1.0)
3873                                                                                                         - 2,
3874                                                                                         0.0));
3875                 } else {
3876                         mode_lib->vba.MaximumSwathWidthInLineBuffer =
3877                                         dml_min(
3878                                                         mode_lib->vba.LineBufferSize
3879                                                                         * dml_max(
3880                                                                                         mode_lib->vba.HRatio[k],
3881                                                                                         1.0)
3882                                                                         / mode_lib->vba.LBBitPerPixel[k]
3883                                                                         / (mode_lib->vba.vtaps[k]
3884                                                                                         + dml_max(
3885                                                                                                         dml_ceil(
3886                                                                                                                         mode_lib->vba.VRatio[k],
3887                                                                                                                         1.0)
3888                                                                                                                         - 2,
3889                                                                                                         0.0)),
3890                                                         2.0 * mode_lib->vba.LineBufferSize
3891                                                                         * dml_max(
3892                                                                                         mode_lib->vba.HRatio[k]
3893                                                                                                         / 2.0,
3894                                                                                         1.0)
3895                                                                         / mode_lib->vba.LBBitPerPixel[k]
3896                                                                         / (mode_lib->vba.VTAPsChroma[k]
3897                                                                                         + dml_max(
3898                                                                                                         dml_ceil(
3899                                                                                                                         mode_lib->vba.VRatio[k]
3900                                                                                                                                         / 2.0,
3901                                                                                                                         1.0)
3902                                                                                                                         - 2,
3903                                                                                                         0.0)));
3904                 }
3905                 locals->MaximumSwathWidth[k] = dml_min(
3906                                 mode_lib->vba.MaximumSwathWidthInDETBuffer,
3907                                 mode_lib->vba.MaximumSwathWidthInLineBuffer);
3908         }
3909         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
3910                 double MaxMaxDispclkRoundedDown = RoundToDFSGranularityDown(
3911                         mode_lib->vba.MaxDispclk[mode_lib->vba.soc.num_states],
3912                         mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
3913
3914                 for (j = 0; j < 2; j++) {
3915                         mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
3916                                 mode_lib->vba.MaxDispclk[i],
3917                                 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
3918                         mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
3919                                 mode_lib->vba.MaxDppclk[i],
3920                                 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
3921                         locals->RequiredDISPCLK[i][j] = 0.0;
3922                         locals->DISPCLK_DPPCLK_Support[i][j] = true;
3923                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3924                                 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
3925                                                 mode_lib->vba.PixelClock[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
3926                                                                 * (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
3927                                 if (mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine >= mode_lib->vba.MaxDispclk[i]
3928                                                 && i == mode_lib->vba.soc.num_states)
3929                                         mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine = mode_lib->vba.PixelClock[k]
3930                                                         * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
3931
3932                                 mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
3933                                         * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
3934                                 if (mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine >= mode_lib->vba.MaxDispclk[i]
3935                                                 && i == mode_lib->vba.soc.num_states)
3936                                         mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
3937                                                         * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
3938                                 if (mode_lib->vba.ODMCapability == false ||
3939                                                 (locals->PlaneRequiredDISPCLKWithoutODMCombine <= MaxMaxDispclkRoundedDown
3940                                                         && (!locals->DSCEnabled[k] || locals->HActive[k] <= DCN20_MAX_DSC_IMAGE_WIDTH))) {
3941                                         locals->ODMCombineEnablePerState[i][k] = false;
3942                                         mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
3943                                 } else {
3944                                         locals->ODMCombineEnablePerState[i][k] = true;
3945                                         mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
3946                                 }
3947                                 if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
3948                                                 && locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
3949                                                 && locals->ODMCombineEnablePerState[i][k] == false) {
3950                                         locals->NoOfDPP[i][j][k] = 1;
3951                                         locals->RequiredDPPCLK[i][j][k] =
3952                                                 locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
3953                                 } else {
3954                                         locals->NoOfDPP[i][j][k] = 2;
3955                                         locals->RequiredDPPCLK[i][j][k] =
3956                                                 locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
3957                                 }
3958                                 locals->RequiredDISPCLK[i][j] = dml_max(
3959                                                 locals->RequiredDISPCLK[i][j],
3960                                                 mode_lib->vba.PlaneRequiredDISPCLK);
3961                                 if ((locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
3962                                                 > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
3963                                                 || (mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
3964                                         locals->DISPCLK_DPPCLK_Support[i][j] = false;
3965                                 }
3966                         }
3967                         locals->TotalNumberOfActiveDPP[i][j] = 0.0;
3968                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
3969                                 locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
3970                         if (j == 1) {
3971                                 while (locals->TotalNumberOfActiveDPP[i][j] < mode_lib->vba.MaxNumDPP
3972                                                 && locals->TotalNumberOfActiveDPP[i][j] < 2 * mode_lib->vba.NumberOfActivePlanes) {
3973                                         double BWOfNonSplitPlaneOfMaximumBandwidth;
3974                                         unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
3975
3976                                         BWOfNonSplitPlaneOfMaximumBandwidth = 0;
3977                                         NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
3978                                         for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3979                                                 if (locals->ReadBandwidth[k] > BWOfNonSplitPlaneOfMaximumBandwidth && locals->NoOfDPP[i][j][k] == 1) {
3980                                                         BWOfNonSplitPlaneOfMaximumBandwidth = locals->ReadBandwidth[k];
3981                                                         NumberOfNonSplitPlaneOfMaximumBandwidth = k;
3982                                                 }
3983                                         }
3984                                         locals->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
3985                                         locals->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
3986                                                 locals->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
3987                                                         * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
3988                                         locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + 1;
3989                                 }
3990                         }
3991                         if (locals->TotalNumberOfActiveDPP[i][j] > mode_lib->vba.MaxNumDPP) {
3992                                 locals->RequiredDISPCLK[i][j] = 0.0;
3993                                 locals->DISPCLK_DPPCLK_Support[i][j] = true;
3994                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
3995                                         locals->ODMCombineEnablePerState[i][k] = false;
3996                                         if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
3997                                                 locals->NoOfDPP[i][j][k] = 1;
3998                                                 locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
3999                                                         * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4000                                         } else {
4001                                                 locals->NoOfDPP[i][j][k] = 2;
4002                                                 locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
4003                                                                                 * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
4004                                         }
4005                                         if (i != mode_lib->vba.soc.num_states) {
4006                                                 mode_lib->vba.PlaneRequiredDISPCLK =
4007                                                                 mode_lib->vba.PixelClock[k]
4008                                                                                 * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4009                                                                                 * (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
4010                                         } else {
4011                                                 mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PixelClock[k]
4012                                                         * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4013                                         }
4014                                         locals->RequiredDISPCLK[i][j] = dml_max(
4015                                                         locals->RequiredDISPCLK[i][j],
4016                                                         mode_lib->vba.PlaneRequiredDISPCLK);
4017                                         if (locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4018                                                         > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
4019                                                         || mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)
4020                                                 locals->DISPCLK_DPPCLK_Support[i][j] = false;
4021                                 }
4022                                 locals->TotalNumberOfActiveDPP[i][j] = 0.0;
4023                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
4024                                         locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
4025                         }
4026                         locals->RequiredDISPCLK[i][j] = dml_max(
4027                                         locals->RequiredDISPCLK[i][j],
4028                                         mode_lib->vba.WritebackRequiredDISPCLK);
4029                         if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
4030                                         < mode_lib->vba.WritebackRequiredDISPCLK) {
4031                                 locals->DISPCLK_DPPCLK_Support[i][j] = false;
4032                         }
4033                 }
4034         }
4035         /*Viewport Size Check*/
4036
4037         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4038                 locals->ViewportSizeSupport[i] = true;
4039                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4040                         if (locals->ODMCombineEnablePerState[i][k] == true) {
4041                                 if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
4042                                                 > locals->MaximumSwathWidth[k]) {
4043                                         locals->ViewportSizeSupport[i] = false;
4044                                 }
4045                         } else {
4046                                 if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
4047                                         locals->ViewportSizeSupport[i] = false;
4048                                 }
4049                         }
4050                 }
4051         }
4052         /*Total Available Pipes Support Check*/
4053
4054         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4055                 for (j = 0; j < 2; j++) {
4056                         if (locals->TotalNumberOfActiveDPP[i][j] <= mode_lib->vba.MaxNumDPP)
4057                                 locals->TotalAvailablePipesSupport[i][j] = true;
4058                         else
4059                                 locals->TotalAvailablePipesSupport[i][j] = false;
4060                 }
4061         }
4062         /*Total Available OTG Support Check*/
4063
4064         mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
4065         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4066                 if (mode_lib->vba.BlendingAndTiming[k] == k) {
4067                         mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
4068                                         + 1.0;
4069                 }
4070         }
4071         if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
4072                 mode_lib->vba.NumberOfOTGSupport = true;
4073         } else {
4074                 mode_lib->vba.NumberOfOTGSupport = false;
4075         }
4076         /*Display IO and DSC Support Check*/
4077
4078         mode_lib->vba.NonsupportedDSCInputBPC = false;
4079         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4080                 if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
4081                                 || mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
4082                                 || mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
4083                         mode_lib->vba.NonsupportedDSCInputBPC = true;
4084                 }
4085         }
4086         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4087                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4088                         locals->RequiresDSC[i][k] = 0;
4089                         locals->RequiresFEC[i][k] = 0;
4090                         if (mode_lib->vba.BlendingAndTiming[k] == k) {
4091                                 if (mode_lib->vba.Output[k] == dm_hdmi) {
4092                                         locals->RequiresDSC[i][k] = 0;
4093                                         locals->RequiresFEC[i][k] = 0;
4094                                         locals->OutputBppPerState[i][k] = TruncToValidBPP(
4095                                                         dml_min(600.0, mode_lib->vba.PHYCLKPerState[i]) / mode_lib->vba.PixelClockBackEnd[k] * 24,
4096                                                         false,
4097                                                         mode_lib->vba.Output[k],
4098                                                         mode_lib->vba.OutputFormat[k],
4099                                                         mode_lib->vba.DSCInputBitPerComponent[k]);
4100                                 } else if (mode_lib->vba.Output[k] == dm_dp
4101                                                 || mode_lib->vba.Output[k] == dm_edp) {
4102                                         if (mode_lib->vba.Output[k] == dm_edp) {
4103                                                 mode_lib->vba.EffectiveFECOverhead = 0.0;
4104                                         } else {
4105                                                 mode_lib->vba.EffectiveFECOverhead =
4106                                                                 mode_lib->vba.FECOverhead;
4107                                         }
4108                                         if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
4109                                                 mode_lib->vba.Outbpp = TruncToValidBPP(
4110                                                                 (1.0 - mode_lib->vba.Downspreading / 100.0) * 270.0
4111                                                                 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
4112                                                                 false,
4113                                                                 mode_lib->vba.Output[k],
4114                                                                 mode_lib->vba.OutputFormat[k],
4115                                                                 mode_lib->vba.DSCInputBitPerComponent[k]);
4116                                                 mode_lib->vba.OutbppDSC = TruncToValidBPP(
4117                                                                 (1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 270.0
4118                                                                 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
4119                                                                 true,
4120                                                                 mode_lib->vba.Output[k],
4121                                                                 mode_lib->vba.OutputFormat[k],
4122                                                                 mode_lib->vba.DSCInputBitPerComponent[k]);
4123                                                 if (mode_lib->vba.DSCEnabled[k] == true) {
4124                                                         locals->RequiresDSC[i][k] = true;
4125                                                         if (mode_lib->vba.Output[k] == dm_dp) {
4126                                                                 locals->RequiresFEC[i][k] = true;
4127                                                         } else {
4128                                                                 locals->RequiresFEC[i][k] = false;
4129                                                         }
4130                                                         mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
4131                                                 } else {
4132                                                         locals->RequiresDSC[i][k] = false;
4133                                                         locals->RequiresFEC[i][k] = false;
4134                                                 }
4135                                                 locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
4136                                         }
4137                                         if (mode_lib->vba.Outbpp == BPP_INVALID && mode_lib->vba.PHYCLKPerState[i] >= 540.0) {
4138                                                 mode_lib->vba.Outbpp = TruncToValidBPP(
4139                                                                 (1.0 - mode_lib->vba.Downspreading / 100.0) * 540.0
4140                                                                 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
4141                                                                         false,
4142                                                                         mode_lib->vba.Output[k],
4143                                                                         mode_lib->vba.OutputFormat[k],
4144                                                                         mode_lib->vba.DSCInputBitPerComponent[k]);
4145                                                 mode_lib->vba.OutbppDSC = TruncToValidBPP(
4146                                                                 (1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 540.0
4147                                                                 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
4148                                                                 true,
4149                                                                 mode_lib->vba.Output[k],
4150                                                                 mode_lib->vba.OutputFormat[k],
4151                                                                 mode_lib->vba.DSCInputBitPerComponent[k]);
4152                                                 if (mode_lib->vba.DSCEnabled[k] == true) {
4153                                                         locals->RequiresDSC[i][k] = true;
4154                                                         if (mode_lib->vba.Output[k] == dm_dp) {
4155                                                                 locals->RequiresFEC[i][k] = true;
4156                                                         } else {
4157                                                                 locals->RequiresFEC[i][k] = false;
4158                                                         }
4159                                                         mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
4160                                                 } else {
4161                                                         locals->RequiresDSC[i][k] = false;
4162                                                         locals->RequiresFEC[i][k] = false;
4163                                                 }
4164                                                 locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
4165                                         }
4166                                         if (mode_lib->vba.Outbpp == BPP_INVALID
4167                                                         && mode_lib->vba.PHYCLKPerState[i]
4168                                                                         >= 810.0) {
4169                                                 mode_lib->vba.Outbpp = TruncToValidBPP(
4170                                                                 (1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0
4171                                                                 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
4172                                                                 false,
4173                                                                 mode_lib->vba.Output[k],
4174                                                                 mode_lib->vba.OutputFormat[k],
4175                                                                 mode_lib->vba.DSCInputBitPerComponent[k]);
4176                                                 mode_lib->vba.OutbppDSC = TruncToValidBPP(
4177                                                                 (1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0
4178                                                                 * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
4179                                                                 true,
4180                                                                 mode_lib->vba.Output[k],
4181                                                                 mode_lib->vba.OutputFormat[k],
4182                                                                 mode_lib->vba.DSCInputBitPerComponent[k]);
4183                                                 if (mode_lib->vba.DSCEnabled[k] == true || mode_lib->vba.Outbpp == BPP_INVALID) {
4184                                                         locals->RequiresDSC[i][k] = true;
4185                                                         if (mode_lib->vba.Output[k] == dm_dp) {
4186                                                                 locals->RequiresFEC[i][k] = true;
4187                                                         } else {
4188                                                                 locals->RequiresFEC[i][k] = false;
4189                                                         }
4190                                                         mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
4191                                                 } else {
4192                                                         locals->RequiresDSC[i][k] = false;
4193                                                         locals->RequiresFEC[i][k] = false;
4194                                                 }
4195                                                 locals->OutputBppPerState[i][k] =
4196                                                                 mode_lib->vba.Outbpp;
4197                                         }
4198                                 }
4199                         } else {
4200                                 locals->OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
4201                         }
4202                 }
4203         }
4204         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4205                 locals->DIOSupport[i] = true;
4206                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4207                         if (locals->OutputBppPerState[i][k] == BPP_INVALID
4208                                         || (mode_lib->vba.OutputFormat[k] == dm_420
4209                                                         && mode_lib->vba.Interlace[k] == true
4210                                                         && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) {
4211                                 locals->DIOSupport[i] = false;
4212                         }
4213                 }
4214         }
4215         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4216                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4217                         locals->DSCCLKRequiredMoreThanSupported[i] = false;
4218                         if (mode_lib->vba.BlendingAndTiming[k] == k) {
4219                                 if ((mode_lib->vba.Output[k] == dm_dp
4220                                                 || mode_lib->vba.Output[k] == dm_edp)) {
4221                                         if (mode_lib->vba.OutputFormat[k] == dm_420
4222                                                         || mode_lib->vba.OutputFormat[k]
4223                                                                         == dm_n422) {
4224                                                 mode_lib->vba.DSCFormatFactor = 2;
4225                                         } else {
4226                                                 mode_lib->vba.DSCFormatFactor = 1;
4227                                         }
4228                                         if (locals->RequiresDSC[i][k] == true) {
4229                                                 if (locals->ODMCombineEnablePerState[i][k]
4230                                                                 == true) {
4231                                                         if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
4232                                                                         > (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
4233                                                                 locals->DSCCLKRequiredMoreThanSupported[i] =
4234                                                                                 true;
4235                                                         }
4236                                                 } else {
4237                                                         if (mode_lib->vba.PixelClockBackEnd[k] / 3.0 / mode_lib->vba.DSCFormatFactor
4238                                                                         > (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
4239                                                                 locals->DSCCLKRequiredMoreThanSupported[i] =
4240                                                                                 true;
4241                                                         }
4242                                                 }
4243                                         }
4244                                 }
4245                         }
4246                 }
4247         }
4248         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4249                 locals->NotEnoughDSCUnits[i] = false;
4250                 mode_lib->vba.TotalDSCUnitsRequired = 0.0;
4251                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4252                         if (locals->RequiresDSC[i][k] == true) {
4253                                 if (locals->ODMCombineEnablePerState[i][k] == true) {
4254                                         mode_lib->vba.TotalDSCUnitsRequired =
4255                                                         mode_lib->vba.TotalDSCUnitsRequired + 2.0;
4256                                 } else {
4257                                         mode_lib->vba.TotalDSCUnitsRequired =
4258                                                         mode_lib->vba.TotalDSCUnitsRequired + 1.0;
4259                                 }
4260                         }
4261                 }
4262                 if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
4263                         locals->NotEnoughDSCUnits[i] = true;
4264                 }
4265         }
4266         /*DSC Delay per state*/
4267
4268         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4269                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4270                         if (mode_lib->vba.BlendingAndTiming[k] != k) {
4271                                 mode_lib->vba.slices = 0;
4272                         } else if (locals->RequiresDSC[i][k] == 0
4273                                         || locals->RequiresDSC[i][k] == false) {
4274                                 mode_lib->vba.slices = 0;
4275                         } else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
4276                                 mode_lib->vba.slices = dml_ceil(
4277                                                 mode_lib->vba.PixelClockBackEnd[k] / 400.0,
4278                                                 4.0);
4279                         } else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
4280                                 mode_lib->vba.slices = 8.0;
4281                         } else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
4282                                 mode_lib->vba.slices = 4.0;
4283                         } else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
4284                                 mode_lib->vba.slices = 2.0;
4285                         } else {
4286                                 mode_lib->vba.slices = 1.0;
4287                         }
4288                         if (locals->OutputBppPerState[i][k] == BPP_BLENDED_PIPE
4289                                         || locals->OutputBppPerState[i][k] == BPP_INVALID) {
4290                                 mode_lib->vba.bpp = 0.0;
4291                         } else {
4292                                 mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
4293                         }
4294                         if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
4295                                 if (locals->ODMCombineEnablePerState[i][k] == false) {
4296                                         locals->DSCDelayPerState[i][k] =
4297                                                         dscceComputeDelay(
4298                                                                         mode_lib->vba.DSCInputBitPerComponent[k],
4299                                                                         mode_lib->vba.bpp,
4300                                                                         dml_ceil(
4301                                                                                         mode_lib->vba.HActive[k]
4302                                                                                                         / mode_lib->vba.slices,
4303                                                                                         1.0),
4304                                                                         mode_lib->vba.slices,
4305                                                                         mode_lib->vba.OutputFormat[k])
4306                                                                         + dscComputeDelay(
4307                                                                                         mode_lib->vba.OutputFormat[k]);
4308                                 } else {
4309                                         locals->DSCDelayPerState[i][k] =
4310                                                         2.0 * (dscceComputeDelay(
4311                                                                                         mode_lib->vba.DSCInputBitPerComponent[k],
4312                                                                                         mode_lib->vba.bpp,
4313                                                                                         dml_ceil(mode_lib->vba.HActive[k] / mode_lib->vba.slices, 1.0),
4314                                                                                         mode_lib->vba.slices / 2,
4315                                                                                         mode_lib->vba.OutputFormat[k])
4316                                                                         + dscComputeDelay(mode_lib->vba.OutputFormat[k]));
4317                                 }
4318                                 locals->DSCDelayPerState[i][k] =
4319                                                 locals->DSCDelayPerState[i][k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k];
4320                         } else {
4321                                 locals->DSCDelayPerState[i][k] = 0.0;
4322                         }
4323                 }
4324                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4325                         for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
4326                                 for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
4327                                         if (mode_lib->vba.BlendingAndTiming[k] == m && locals->RequiresDSC[i][m] == true)
4328                                                 locals->DSCDelayPerState[i][k] = locals->DSCDelayPerState[i][m];
4329                                 }
4330                         }
4331                 }
4332         }
4333
4334         //Prefetch Check
4335         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4336                 for (j = 0; j < 2; j++) {
4337                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4338                                 if (locals->ODMCombineEnablePerState[i][k] == true)
4339                                         locals->SwathWidthYPerState[i][j][k] = dml_min(locals->SwathWidthYSingleDPP[k], dml_round(locals->HActive[k] / 2 * locals->HRatio[k]));
4340                                 else
4341                                         locals->SwathWidthYPerState[i][j][k] = locals->SwathWidthYSingleDPP[k] / locals->NoOfDPP[i][j][k];
4342                                 locals->SwathWidthGranularityY = 256  / dml_ceil(locals->BytePerPixelInDETY[k], 1) / locals->MaxSwathHeightY[k];
4343                                 locals->RoundedUpMaxSwathSizeBytesY = (dml_ceil(locals->SwathWidthYPerState[i][j][k] - 1, locals->SwathWidthGranularityY)
4344                                                 + locals->SwathWidthGranularityY) * locals->BytePerPixelInDETY[k] * locals->MaxSwathHeightY[k];
4345                                 if (locals->SourcePixelFormat[k] == dm_420_10) {
4346                                         locals->RoundedUpMaxSwathSizeBytesY = dml_ceil(locals->RoundedUpMaxSwathSizeBytesY, 256) + 256;
4347                                 }
4348                                 if (locals->MaxSwathHeightC[k] > 0) {
4349                                         locals->SwathWidthGranularityC = 256 / dml_ceil(locals->BytePerPixelInDETC[k], 2) / locals->MaxSwathHeightC[k];
4350
4351                                         locals->RoundedUpMaxSwathSizeBytesC = (dml_ceil(locals->SwathWidthYPerState[i][j][k] / 2 - 1, locals->SwathWidthGranularityC)
4352                                         + locals->SwathWidthGranularityC) * locals->BytePerPixelInDETC[k] * locals->MaxSwathHeightC[k];
4353                                 }
4354                                 if (locals->SourcePixelFormat[k] == dm_420_10) {
4355                                         locals->RoundedUpMaxSwathSizeBytesC = dml_ceil(locals->RoundedUpMaxSwathSizeBytesC, 256)  + 256;
4356                                 } else {
4357                                         locals->RoundedUpMaxSwathSizeBytesC = 0;
4358                                 }
4359
4360                                 if (locals->RoundedUpMaxSwathSizeBytesY + locals->RoundedUpMaxSwathSizeBytesC <= locals->DETBufferSizeInKByte * 1024 / 2) {
4361                                         locals->SwathHeightYPerState[i][j][k] = locals->MaxSwathHeightY[k];
4362                                         locals->SwathHeightCPerState[i][j][k] = locals->MaxSwathHeightC[k];
4363                                 } else {
4364                                         locals->SwathHeightYPerState[i][j][k] = locals->MinSwathHeightY[k];
4365                                         locals->SwathHeightCPerState[i][j][k] = locals->MinSwathHeightC[k];
4366                                 }
4367
4368                                 if (locals->BytePerPixelInDETC[k] == 0) {
4369                                         locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
4370                                         locals->LinesInDETChroma = 0;
4371                                 } else if (locals->SwathHeightYPerState[i][j][k] <= locals->SwathHeightCPerState[i][j][k]) {
4372                                         locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 / 2 / locals->BytePerPixelInDETY[k] /
4373                                                         locals->SwathWidthYPerState[i][j][k];
4374                                         locals->LinesInDETChroma = locals->DETBufferSizeInKByte * 1024 / 2 / locals->BytePerPixelInDETC[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
4375                                 } else {
4376                                         locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 * 2 / 3 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
4377                                         locals->LinesInDETChroma = locals->DETBufferSizeInKByte * 1024 / 3 / locals->BytePerPixelInDETY[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
4378                                 }
4379
4380                                 locals->EffectiveLBLatencyHidingSourceLinesLuma = dml_min(locals->MaxLineBufferLines,
4381                                         dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k] / (locals->SwathWidthYPerState[i][j][k]
4382                                         / dml_max(locals->HRatio[k], 1)), 1)) - (locals->vtaps[k] - 1);
4383
4384                                 locals->EffectiveLBLatencyHidingSourceLinesChroma =  dml_min(locals->MaxLineBufferLines,
4385                                                 dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k]
4386                                                 / (locals->SwathWidthYPerState[i][j][k] / 2
4387                                                 / dml_max(locals->HRatio[k] / 2, 1)), 1)) - (locals->VTAPsChroma[k] - 1);
4388
4389                                 locals->EffectiveDETLBLinesLuma = dml_floor(locals->LinesInDETLuma +  dml_min(
4390                                                 locals->LinesInDETLuma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETY[k] *
4391                                                 locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i],
4392                                                 locals->EffectiveLBLatencyHidingSourceLinesLuma),
4393                                                 locals->SwathHeightYPerState[i][j][k]);
4394
4395                                 locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + dml_min(
4396                                                 locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETC[k] *
4397                                                 locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i],
4398                                                 locals->EffectiveLBLatencyHidingSourceLinesChroma),
4399                                                 locals->SwathHeightCPerState[i][j][k]);
4400
4401                                 if (locals->BytePerPixelInDETC[k] == 0) {
4402                                         locals->UrgentLatencySupportUsPerState[i][j][k] = 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                                 } else {
4406                                         locals->UrgentLatencySupportUsPerState[i][j][k] = dml_min(
4407                                                 locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
4408                                                 / locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
4409                                                 dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]),
4410                                                         locals->EffectiveDETLBLinesChroma * (locals->HTotal[k] / locals->PixelClock[k]) / (locals->VRatio[k] / 2) -
4411                                                         locals->EffectiveDETLBLinesChroma * locals->SwathWidthYPerState[i][j][k] / 2 *
4412                                                         dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]));
4413                                 }
4414                         }
4415                 }
4416         }
4417
4418         for (i = 0; i <= locals->soc.num_states; i++) {
4419                 for (j = 0; j < 2; j++) {
4420                         locals->UrgentLatencySupport[i][j] = true;
4421                         for (k = 0; k < locals->NumberOfActivePlanes; k++) {
4422                                 if (locals->UrgentLatencySupportUsPerState[i][j][k] < locals->UrgentLatency)
4423                                         locals->UrgentLatencySupport[i][j] = false;
4424                         }
4425                 }
4426         }
4427
4428
4429         /*Prefetch Check*/
4430         for (i = 0; i <= locals->soc.num_states; i++) {
4431                 for (j = 0; j < 2; j++) {
4432                         locals->TotalNumberOfDCCActiveDPP[i][j] = 0;
4433                         for (k = 0; k < locals->NumberOfActivePlanes; k++) {
4434                                 if (locals->DCCEnable[k] == true) {
4435                                         locals->TotalNumberOfDCCActiveDPP[i][j] =
4436                                                 locals->TotalNumberOfDCCActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
4437                                 }
4438                         }
4439                 }
4440         }
4441
4442         CalculateMinAndMaxPrefetchMode(locals->AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &locals->MinPrefetchMode, &locals->MaxPrefetchMode);
4443
4444         locals->MaxTotalVActiveRDBandwidth = 0;
4445         for (k = 0; k < locals->NumberOfActivePlanes; k++) {
4446                 locals->MaxTotalVActiveRDBandwidth = locals->MaxTotalVActiveRDBandwidth + locals->ReadBandwidth[k];
4447         }
4448
4449         for (i = 0; i <= locals->soc.num_states; i++) {
4450                 for (j = 0; j < 2; j++) {
4451                         for (k = 0; k < locals->NumberOfActivePlanes; k++) {
4452                                 locals->NoOfDPPThisState[k] = locals->NoOfDPP[i][j][k];
4453                                 locals->RequiredDPPCLKThisState[k] = locals->RequiredDPPCLK[i][j][k];
4454                                 locals->SwathHeightYThisState[k] = locals->SwathHeightYPerState[i][j][k];
4455                                 locals->SwathHeightCThisState[k] = locals->SwathHeightCPerState[i][j][k];
4456                                 locals->SwathWidthYThisState[k] = locals->SwathWidthYPerState[i][j][k];
4457                                 mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
4458                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep,
4459                                                 mode_lib->vba.PixelClock[k] / 16.0);
4460                                 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
4461                                         if (mode_lib->vba.VRatio[k] <= 1.0) {
4462                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep =
4463                                                                 dml_max(
4464                                                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep,
4465                                                                                 1.1
4466                                                                                                 * dml_ceil(
4467                                                                                                                 mode_lib->vba.BytePerPixelInDETY[k],
4468                                                                                                                 1.0)
4469                                                                                                 / 64.0
4470                                                                                                 * mode_lib->vba.HRatio[k]
4471                                                                                                 * mode_lib->vba.PixelClock[k]
4472                                                                                                 / mode_lib->vba.NoOfDPP[i][j][k]);
4473                                         } else {
4474                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep =
4475                                                                 dml_max(
4476                                                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep,
4477                                                                                 1.1
4478                                                                                                 * dml_ceil(
4479                                                                                                                 mode_lib->vba.BytePerPixelInDETY[k],
4480                                                                                                                 1.0)
4481                                                                                                 / 64.0
4482                                                                                                 * mode_lib->vba.PSCL_FACTOR[k]
4483                                                                                                 * mode_lib->vba.RequiredDPPCLK[i][j][k]);
4484                                         }
4485                                 } else {
4486                                         if (mode_lib->vba.VRatio[k] <= 1.0) {
4487                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep =
4488                                                                 dml_max(
4489                                                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep,
4490                                                                                 1.1
4491                                                                                                 * dml_ceil(
4492                                                                                                                 mode_lib->vba.BytePerPixelInDETY[k],
4493                                                                                                                 1.0)
4494                                                                                                 / 32.0
4495                                                                                                 * mode_lib->vba.HRatio[k]
4496                                                                                                 * mode_lib->vba.PixelClock[k]
4497                                                                                                 / mode_lib->vba.NoOfDPP[i][j][k]);
4498                                         } else {
4499                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep =
4500                                                                 dml_max(
4501                                                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep,
4502                                                                                 1.1
4503                                                                                                 * dml_ceil(
4504                                                                                                                 mode_lib->vba.BytePerPixelInDETY[k],
4505                                                                                                                 1.0)
4506                                                                                                 / 32.0
4507                                                                                                 * mode_lib->vba.PSCL_FACTOR[k]
4508                                                                                                 * mode_lib->vba.RequiredDPPCLK[i][j][k]);
4509                                         }
4510                                         if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
4511                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep =
4512                                                                 dml_max(
4513                                                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep,
4514                                                                                 1.1
4515                                                                                                 * dml_ceil(
4516                                                                                                                 mode_lib->vba.BytePerPixelInDETC[k],
4517                                                                                                                 2.0)
4518                                                                                                 / 32.0
4519                                                                                                 * mode_lib->vba.HRatio[k]
4520                                                                                                 / 2.0
4521                                                                                                 * mode_lib->vba.PixelClock[k]
4522                                                                                                 / mode_lib->vba.NoOfDPP[i][j][k]);
4523                                         } else {
4524                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep =
4525                                                                 dml_max(
4526                                                                                 mode_lib->vba.ProjectedDCFCLKDeepSleep,
4527                                                                                 1.1
4528                                                                                                 * dml_ceil(
4529                                                                                                                 mode_lib->vba.BytePerPixelInDETC[k],
4530                                                                                                                 2.0)
4531                                                                                                 / 32.0
4532                                                                                                 * mode_lib->vba.PSCL_FACTOR_CHROMA[k]
4533                                                                                                 * mode_lib->vba.RequiredDPPCLK[i][j][k]);
4534                                         }
4535                                 }
4536                         }
4537                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4538                                 mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
4539                                                 mode_lib,
4540                                                 mode_lib->vba.DCCEnable[k],
4541                                                 mode_lib->vba.Read256BlockHeightY[k],
4542                                                 mode_lib->vba.Read256BlockWidthY[k],
4543                                                 mode_lib->vba.SourcePixelFormat[k],
4544                                                 mode_lib->vba.SurfaceTiling[k],
4545                                                 dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
4546                                                 mode_lib->vba.SourceScan[k],
4547                                                 mode_lib->vba.ViewportWidth[k],
4548                                                 mode_lib->vba.ViewportHeight[k],
4549                                                 mode_lib->vba.SwathWidthYPerState[i][j][k],
4550                                                 mode_lib->vba.GPUVMEnable,
4551                                                 mode_lib->vba.VMMPageSize,
4552                                                 mode_lib->vba.PTEBufferSizeInRequestsLuma,
4553                                                 mode_lib->vba.PDEProcessingBufIn64KBReqs,
4554                                                 mode_lib->vba.PitchY[k],
4555                                                 mode_lib->vba.DCCMetaPitchY[k],
4556                                                 &mode_lib->vba.MacroTileWidthY[k],
4557                                                 &mode_lib->vba.MetaRowBytesY,
4558                                                 &mode_lib->vba.DPTEBytesPerRowY,
4559                                                 &mode_lib->vba.PTEBufferSizeNotExceededY[i][j][k],
4560                                                 &mode_lib->vba.dpte_row_height[k],
4561                                                 &mode_lib->vba.meta_row_height[k]);
4562                                 mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
4563                                                 mode_lib,
4564                                                 mode_lib->vba.VRatio[k],
4565                                                 mode_lib->vba.vtaps[k],
4566                                                 mode_lib->vba.Interlace[k],
4567                                                 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
4568                                                 mode_lib->vba.SwathHeightYPerState[i][j][k],
4569                                                 mode_lib->vba.ViewportYStartY[k],
4570                                                 &mode_lib->vba.PrefillY[k],
4571                                                 &mode_lib->vba.MaxNumSwY[k]);
4572                                 if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
4573                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
4574                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
4575                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
4576                                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
4577                                         mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
4578                                                         mode_lib,
4579                                                         mode_lib->vba.DCCEnable[k],
4580                                                         mode_lib->vba.Read256BlockHeightY[k],
4581                                                         mode_lib->vba.Read256BlockWidthY[k],
4582                                                         mode_lib->vba.SourcePixelFormat[k],
4583                                                         mode_lib->vba.SurfaceTiling[k],
4584                                                         dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
4585                                                         mode_lib->vba.SourceScan[k],
4586                                                         mode_lib->vba.ViewportWidth[k] / 2.0,
4587                                                         mode_lib->vba.ViewportHeight[k] / 2.0,
4588                                                         mode_lib->vba.SwathWidthYPerState[i][j][k] / 2.0,
4589                                                         mode_lib->vba.GPUVMEnable,
4590                                                         mode_lib->vba.VMMPageSize,
4591                                                         mode_lib->vba.PTEBufferSizeInRequestsLuma,
4592                                                         mode_lib->vba.PDEProcessingBufIn64KBReqs,
4593                                                         mode_lib->vba.PitchC[k],
4594                                                         0.0,
4595                                                         &mode_lib->vba.MacroTileWidthC[k],
4596                                                         &mode_lib->vba.MetaRowBytesC,
4597                                                         &mode_lib->vba.DPTEBytesPerRowC,
4598                                                         &mode_lib->vba.PTEBufferSizeNotExceededC[i][j][k],
4599                                                         &mode_lib->vba.dpte_row_height_chroma[k],
4600                                                         &mode_lib->vba.meta_row_height_chroma[k]);
4601                                         mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
4602                                                         mode_lib,
4603                                                         mode_lib->vba.VRatio[k] / 2.0,
4604                                                         mode_lib->vba.VTAPsChroma[k],
4605                                                         mode_lib->vba.Interlace[k],
4606                                                         mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
4607                                                         mode_lib->vba.SwathHeightCPerState[i][j][k],
4608                                                         mode_lib->vba.ViewportYStartC[k],
4609                                                         &mode_lib->vba.PrefillC[k],
4610                                                         &mode_lib->vba.MaxNumSwC[k]);
4611                                 } else {
4612                                         mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
4613                                         mode_lib->vba.MetaRowBytesC = 0.0;
4614                                         mode_lib->vba.DPTEBytesPerRowC = 0.0;
4615                                         locals->PrefetchLinesC[k] = 0.0;
4616                                         locals->PTEBufferSizeNotExceededC[i][j][k] = true;
4617                                         locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
4618                                 }
4619                                 locals->PDEAndMetaPTEBytesPerFrame[k] =
4620                                                 mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
4621                                 locals->MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
4622                                 locals->DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
4623
4624                                 CalculateActiveRowBandwidth(
4625                                                 mode_lib->vba.GPUVMEnable,
4626                                                 mode_lib->vba.SourcePixelFormat[k],
4627                                                 mode_lib->vba.VRatio[k],
4628                                                 mode_lib->vba.DCCEnable[k],
4629                                                 mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
4630                                                 mode_lib->vba.MetaRowBytesY,
4631                                                 mode_lib->vba.MetaRowBytesC,
4632                                                 mode_lib->vba.meta_row_height[k],
4633                                                 mode_lib->vba.meta_row_height_chroma[k],
4634                                                 mode_lib->vba.DPTEBytesPerRowY,
4635                                                 mode_lib->vba.DPTEBytesPerRowC,
4636                                                 mode_lib->vba.dpte_row_height[k],
4637                                                 mode_lib->vba.dpte_row_height_chroma[k],
4638                                                 &mode_lib->vba.meta_row_bw[k],
4639                                                 &mode_lib->vba.dpte_row_bw[k],
4640                                                 &mode_lib->vba.qual_row_bw[k]);
4641                         }
4642                         mode_lib->vba.ExtraLatency =
4643                                         mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
4644                                                         + (mode_lib->vba.TotalNumberOfActiveDPP[i][j]
4645                                                                         * mode_lib->vba.PixelChunkSizeInKByte
4646                                                                         + mode_lib->vba.TotalNumberOfDCCActiveDPP[i][j]
4647                                                                                         * mode_lib->vba.MetaChunkSize)
4648                                                                         * 1024.0
4649                                                                         / mode_lib->vba.ReturnBWPerState[i];
4650                         if (mode_lib->vba.GPUVMEnable == true) {
4651                                 mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
4652                                                 + mode_lib->vba.TotalNumberOfActiveDPP[i][j]
4653                                                                 * mode_lib->vba.PTEGroupSize
4654                                                                 / mode_lib->vba.ReturnBWPerState[i];
4655                         }
4656                         mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
4657
4658                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4659                                 if (mode_lib->vba.BlendingAndTiming[k] == k) {
4660                                         if (mode_lib->vba.WritebackEnable[k] == true) {
4661                                                 locals->WritebackDelay[i][k] = mode_lib->vba.WritebackLatency
4662                                                                 + CalculateWriteBackDelay(
4663                                                                                 mode_lib->vba.WritebackPixelFormat[k],
4664                                                                                 mode_lib->vba.WritebackHRatio[k],
4665                                                                                 mode_lib->vba.WritebackVRatio[k],
4666                                                                                 mode_lib->vba.WritebackLumaHTaps[k],
4667                                                                                 mode_lib->vba.WritebackLumaVTaps[k],
4668                                                                                 mode_lib->vba.WritebackChromaHTaps[k],
4669                                                                                 mode_lib->vba.WritebackChromaVTaps[k],
4670                                                                                 mode_lib->vba.WritebackDestinationWidth[k]) / locals->RequiredDISPCLK[i][j];
4671                                         } else {
4672                                                 locals->WritebackDelay[i][k] = 0.0;
4673                                         }
4674                                         for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
4675                                                 if (mode_lib->vba.BlendingAndTiming[m] == k
4676                                                                 && mode_lib->vba.WritebackEnable[m]
4677                                                                                 == true) {
4678                                                         locals->WritebackDelay[i][k] = dml_max(locals->WritebackDelay[i][k],
4679                                                                                         mode_lib->vba.WritebackLatency + CalculateWriteBackDelay(
4680                                                                                                         mode_lib->vba.WritebackPixelFormat[m],
4681                                                                                                         mode_lib->vba.WritebackHRatio[m],
4682                                                                                                         mode_lib->vba.WritebackVRatio[m],
4683                                                                                                         mode_lib->vba.WritebackLumaHTaps[m],
4684                                                                                                         mode_lib->vba.WritebackLumaVTaps[m],
4685                                                                                                         mode_lib->vba.WritebackChromaHTaps[m],
4686                                                                                                         mode_lib->vba.WritebackChromaVTaps[m],
4687                                                                                                         mode_lib->vba.WritebackDestinationWidth[m]) / locals->RequiredDISPCLK[i][j]);
4688                                                 }
4689                                         }
4690                                 }
4691                         }
4692                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4693                                 for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
4694                                         if (mode_lib->vba.BlendingAndTiming[k] == m) {
4695                                                 locals->WritebackDelay[i][k] = locals->WritebackDelay[i][m];
4696                                         }
4697                                 }
4698                         }
4699                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4700                                 for (m = 0; m < locals->NumberOfCursors[k]; m++)
4701                                         locals->cursor_bw[k] = locals->NumberOfCursors[k] * locals->CursorWidth[k][m] * locals->CursorBPP[k][m]
4702                                                 / 8 / (locals->HTotal[k] / locals->PixelClock[k]) * locals->VRatio[k];
4703                         }
4704
4705                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4706                                 locals->MaximumVStartup[k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
4707                                         - dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
4708                         }
4709
4710                         mode_lib->vba.NextPrefetchMode = mode_lib->vba.MinPrefetchMode;
4711                         do {
4712                                 mode_lib->vba.PrefetchMode[i][j] = mode_lib->vba.NextPrefetchMode;
4713                                 mode_lib->vba.NextPrefetchMode = mode_lib->vba.NextPrefetchMode + 1;
4714
4715                                 mode_lib->vba.TWait = CalculateTWait(
4716                                                 mode_lib->vba.PrefetchMode[i][j],
4717                                                 mode_lib->vba.DRAMClockChangeLatency,
4718                                                 mode_lib->vba.UrgentLatency,
4719                                                 mode_lib->vba.SREnterPlusExitTime);
4720                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4721
4722                                         if (mode_lib->vba.XFCEnabled[k] == true) {
4723                                                 mode_lib->vba.XFCRemoteSurfaceFlipDelay =
4724                                                                 CalculateRemoteSurfaceFlipDelay(
4725                                                                                 mode_lib,
4726                                                                                 mode_lib->vba.VRatio[k],
4727                                                                                 locals->SwathWidthYPerState[i][j][k],
4728                                                                                 dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
4729                                                                                 mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
4730                                                                                 mode_lib->vba.XFCTSlvVupdateOffset,
4731                                                                                 mode_lib->vba.XFCTSlvVupdateWidth,
4732                                                                                 mode_lib->vba.XFCTSlvVreadyOffset,
4733                                                                                 mode_lib->vba.XFCXBUFLatencyTolerance,
4734                                                                                 mode_lib->vba.XFCFillBWOverhead,
4735                                                                                 mode_lib->vba.XFCSlvChunkSize,
4736                                                                                 mode_lib->vba.XFCBusTransportTime,
4737                                                                                 mode_lib->vba.TimeCalc,
4738                                                                                 mode_lib->vba.TWait,
4739                                                                                 &mode_lib->vba.SrcActiveDrainRate,
4740                                                                                 &mode_lib->vba.TInitXFill,
4741                                                                                 &mode_lib->vba.TslvChk);
4742                                         } else {
4743                                                 mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
4744                                         }
4745
4746                                         CalculateDelayAfterScaler(mode_lib, mode_lib->vba.ReturnBWPerState[i], mode_lib->vba.ReadBandwidthLuma[k], mode_lib->vba.ReadBandwidthChroma[k], mode_lib->vba.MaxTotalVActiveRDBandwidth,
4747                                                 mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k],
4748                                                 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],
4749                                                 mode_lib->vba.DPPCLKDelaySubtotal, mode_lib->vba.DPPCLKDelaySCL, mode_lib->vba.DPPCLKDelaySCLLBOnly, mode_lib->vba.DPPCLKDelayCNVCFormater, mode_lib->vba.DPPCLKDelayCNVCCursor, mode_lib->vba.DISPCLKDelaySubtotal,
4750                                                 mode_lib->vba.SwathWidthYPerState[i][j][k] / mode_lib->vba.HRatio[k], mode_lib->vba.OutputFormat[k], mode_lib->vba.HTotal[k],
4751                                                 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,
4752                                                 &mode_lib->vba.DSTXAfterScaler[k], &mode_lib->vba.DSTYAfterScaler[k]);
4753
4754                                         mode_lib->vba.IsErrorResult[i][j][k] =
4755                                                         CalculatePrefetchSchedule(
4756                                                                         mode_lib,
4757                                                                         mode_lib->vba.RequiredDPPCLK[i][j][k],
4758                                                                         mode_lib->vba.RequiredDISPCLK[i][j],
4759                                                                         mode_lib->vba.PixelClock[k],
4760                                                                         mode_lib->vba.ProjectedDCFCLKDeepSleep,
4761                                                                         mode_lib->vba.NoOfDPP[i][j][k],
4762                                                                         mode_lib->vba.NumberOfCursors[k],
4763                                                                         mode_lib->vba.VTotal[k]
4764                                                                                         - mode_lib->vba.VActive[k],
4765                                                                         mode_lib->vba.HTotal[k],
4766                                                                         mode_lib->vba.MaxInterDCNTileRepeaters,
4767                                                                         mode_lib->vba.MaximumVStartup[k],
4768                                                                         mode_lib->vba.GPUVMMaxPageTableLevels,
4769                                                                         mode_lib->vba.GPUVMEnable,
4770                                                                         mode_lib->vba.DynamicMetadataEnable[k],
4771                                                                         mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
4772                                                                         mode_lib->vba.DynamicMetadataTransmittedBytes[k],
4773                                                                         mode_lib->vba.DCCEnable[k],
4774                                                                         mode_lib->vba.UrgentLatencyPixelDataOnly,
4775                                                                         mode_lib->vba.ExtraLatency,
4776                                                                         mode_lib->vba.TimeCalc,
4777                                                                         mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
4778                                                                         mode_lib->vba.MetaRowBytes[k],
4779                                                                         mode_lib->vba.DPTEBytesPerRow[k],
4780                                                                         mode_lib->vba.PrefetchLinesY[k],
4781                                                                         mode_lib->vba.SwathWidthYPerState[i][j][k],
4782                                                                         mode_lib->vba.BytePerPixelInDETY[k],
4783                                                                         mode_lib->vba.PrefillY[k],
4784                                                                         mode_lib->vba.MaxNumSwY[k],
4785                                                                         mode_lib->vba.PrefetchLinesC[k],
4786                                                                         mode_lib->vba.BytePerPixelInDETC[k],
4787                                                                         mode_lib->vba.PrefillC[k],
4788                                                                         mode_lib->vba.MaxNumSwC[k],
4789                                                                         mode_lib->vba.SwathHeightYPerState[i][j][k],
4790                                                                         mode_lib->vba.SwathHeightCPerState[i][j][k],
4791                                                                         mode_lib->vba.TWait,
4792                                                                         mode_lib->vba.XFCEnabled[k],
4793                                                                         mode_lib->vba.XFCRemoteSurfaceFlipDelay,
4794                                                                         mode_lib->vba.Interlace[k],
4795                                                                         mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
4796                                                                         mode_lib->vba.DSTXAfterScaler[k],
4797                                                                         mode_lib->vba.DSTYAfterScaler[k],
4798                                                                         &mode_lib->vba.LineTimesForPrefetch[k],
4799                                                                         &mode_lib->vba.PrefetchBW[k],
4800                                                                         &mode_lib->vba.LinesForMetaPTE[k],
4801                                                                         &mode_lib->vba.LinesForMetaAndDPTERow[k],
4802                                                                         &mode_lib->vba.VRatioPreY[i][j][k],
4803                                                                         &mode_lib->vba.VRatioPreC[i][j][k],
4804                                                                         &mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k],
4805                                                                         &mode_lib->vba.Tno_bw[k],
4806                                                                         &mode_lib->vba.VUpdateOffsetPix[k],
4807                                                                         &mode_lib->vba.VUpdateWidthPix[k],
4808                                                                         &mode_lib->vba.VReadyOffsetPix[k]);
4809                                 }
4810                                 mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = 0.0;
4811                                 mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
4812                                 locals->prefetch_vm_bw_valid = true;
4813                                 locals->prefetch_row_bw_valid = true;
4814                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4815                                         if (locals->PDEAndMetaPTEBytesPerFrame[k] == 0)
4816                                                 locals->prefetch_vm_bw[k] = 0;
4817                                         else if (locals->LinesForMetaPTE[k] > 0)
4818                                                 locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[k]
4819                                                         / (locals->LinesForMetaPTE[k] * locals->HTotal[k] / locals->PixelClock[k]);
4820                                         else {
4821                                                 locals->prefetch_vm_bw[k] = 0;
4822                                                 locals->prefetch_vm_bw_valid = false;
4823                                         }
4824                                         if (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k] == 0)
4825                                                 locals->prefetch_row_bw[k] = 0;
4826                                         else if (locals->LinesForMetaAndDPTERow[k] > 0)
4827                                                 locals->prefetch_row_bw[k] = (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k])
4828                                                         / (locals->LinesForMetaAndDPTERow[k] * locals->HTotal[k] / locals->PixelClock[k]);
4829                                         else {
4830                                                 locals->prefetch_row_bw[k] = 0;
4831                                                 locals->prefetch_row_bw_valid = false;
4832                                         }
4833
4834                                         mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = mode_lib->vba.MaximumReadBandwidthWithPrefetch
4835                                                         + 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];
4836                                         mode_lib->vba.MaximumReadBandwidthWithPrefetch =
4837                                                         mode_lib->vba.MaximumReadBandwidthWithPrefetch
4838                                                                         + mode_lib->vba.cursor_bw[k]
4839                                                                         + dml_max3(
4840                                                                                         mode_lib->vba.prefetch_vm_bw[k],
4841                                                                                         mode_lib->vba.prefetch_row_bw[k],
4842                                                                                         dml_max(mode_lib->vba.ReadBandwidth[k],
4843                                                                                         mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k])
4844                                                                                         + mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k]);
4845                                 }
4846                                 locals->BandwidthWithoutPrefetchSupported[i] = true;
4847                                 if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i]) {
4848                                         locals->BandwidthWithoutPrefetchSupported[i] = false;
4849                                 }
4850
4851                                 locals->PrefetchSupported[i][j] = true;
4852                                 if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i]) {
4853                                         locals->PrefetchSupported[i][j] = false;
4854                                 }
4855                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4856                                         if (locals->LineTimesForPrefetch[k] < 2.0
4857                                                         || locals->LinesForMetaPTE[k] >= 8.0
4858                                                         || locals->LinesForMetaAndDPTERow[k] >= 16.0
4859                                                         || mode_lib->vba.IsErrorResult[i][j][k] == true) {
4860                                                 locals->PrefetchSupported[i][j] = false;
4861                                         }
4862                                 }
4863                                 locals->VRatioInPrefetchSupported[i][j] = true;
4864                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4865                                         if (locals->VRatioPreY[i][j][k] > 4.0
4866                                                         || locals->VRatioPreC[i][j][k] > 4.0
4867                                                         || mode_lib->vba.IsErrorResult[i][j][k] == true) {
4868                                                 locals->VRatioInPrefetchSupported[i][j] = false;
4869                                         }
4870                                 }
4871                         } while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true)
4872                                         && mode_lib->vba.NextPrefetchMode < mode_lib->vba.MaxPrefetchMode);
4873
4874                         if (mode_lib->vba.PrefetchSupported[i][j] == true
4875                                         && mode_lib->vba.VRatioInPrefetchSupported[i][j] == true) {
4876                                 mode_lib->vba.BandwidthAvailableForImmediateFlip =
4877                                                 mode_lib->vba.ReturnBWPerState[i];
4878                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4879                                         mode_lib->vba.BandwidthAvailableForImmediateFlip =
4880                                                         mode_lib->vba.BandwidthAvailableForImmediateFlip
4881                                                                         - mode_lib->vba.cursor_bw[k]
4882                                                                         - dml_max(
4883                                                                                         mode_lib->vba.ReadBandwidth[k] + mode_lib->vba.qual_row_bw[k],
4884                                                                                         mode_lib->vba.PrefetchBW[k]);
4885                                 }
4886                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4887                                         mode_lib->vba.ImmediateFlipBytes[k] = 0.0;
4888                                         if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
4889                                                         && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
4890                                                 mode_lib->vba.ImmediateFlipBytes[k] =
4891                                                                 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
4892                                                                                 + mode_lib->vba.MetaRowBytes[k]
4893                                                                                 + mode_lib->vba.DPTEBytesPerRow[k];
4894                                         }
4895                                 }
4896                                 mode_lib->vba.TotImmediateFlipBytes = 0.0;
4897                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4898                                         if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
4899                                                         && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
4900                                                 mode_lib->vba.TotImmediateFlipBytes =
4901                                                                 mode_lib->vba.TotImmediateFlipBytes
4902                                                                                 + mode_lib->vba.ImmediateFlipBytes[k];
4903                                         }
4904                                 }
4905
4906                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4907                                         CalculateFlipSchedule(
4908                                                         mode_lib,
4909                                                         mode_lib->vba.ExtraLatency,
4910                                                         mode_lib->vba.UrgentLatencyPixelDataOnly,
4911                                                         mode_lib->vba.GPUVMMaxPageTableLevels,
4912                                                         mode_lib->vba.GPUVMEnable,
4913                                                         mode_lib->vba.BandwidthAvailableForImmediateFlip,
4914                                                         mode_lib->vba.TotImmediateFlipBytes,
4915                                                         mode_lib->vba.SourcePixelFormat[k],
4916                                                         mode_lib->vba.ImmediateFlipBytes[k],
4917                                                         mode_lib->vba.HTotal[k]
4918                                                                         / mode_lib->vba.PixelClock[k],
4919                                                         mode_lib->vba.VRatio[k],
4920                                                         mode_lib->vba.Tno_bw[k],
4921                                                         mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
4922                                                         mode_lib->vba.MetaRowBytes[k],
4923                                                         mode_lib->vba.DPTEBytesPerRow[k],
4924                                                         mode_lib->vba.DCCEnable[k],
4925                                                         mode_lib->vba.dpte_row_height[k],
4926                                                         mode_lib->vba.meta_row_height[k],
4927                                                         mode_lib->vba.qual_row_bw[k],
4928                                                         &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
4929                                                         &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
4930                                                         &mode_lib->vba.final_flip_bw[k],
4931                                                         &mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
4932                                 }
4933                                 mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
4934                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4935                                         mode_lib->vba.total_dcn_read_bw_with_flip =
4936                                                         mode_lib->vba.total_dcn_read_bw_with_flip
4937                                                                         + mode_lib->vba.cursor_bw[k]
4938                                                                         + dml_max3(
4939                                                                                         mode_lib->vba.prefetch_vm_bw[k],
4940                                                                                         mode_lib->vba.prefetch_row_bw[k],
4941                                                                                         mode_lib->vba.final_flip_bw[k]
4942                                                                                                         + dml_max(
4943                                                                                                                         mode_lib->vba.ReadBandwidth[k],
4944                                                                                                                         mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k]));
4945                                 }
4946                                 mode_lib->vba.ImmediateFlipSupportedForState[i][j] = true;
4947                                 if (mode_lib->vba.total_dcn_read_bw_with_flip
4948                                                 > mode_lib->vba.ReturnBWPerState[i]) {
4949                                         mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
4950                                 }
4951                                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4952                                         if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
4953                                                 mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
4954                                         }
4955                                 }
4956                         } else {
4957                                 mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
4958                         }
4959                 }
4960         }
4961
4962         /*Vertical Active BW support*/
4963         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4964                 mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i] = dml_min(mode_lib->vba.ReturnBusWidth *
4965                                 mode_lib->vba.DCFCLKPerState[i], mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000) *
4966                                 mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100;
4967                 if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i])
4968                         mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = true;
4969                 else
4970                         mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = false;
4971         }
4972
4973         /*PTE Buffer Size Check*/
4974
4975         for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
4976                 for (j = 0; j < 2; j++) {
4977                         locals->PTEBufferSizeNotExceeded[i][j] = true;
4978                         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4979                                 if (locals->PTEBufferSizeNotExceededY[i][j][k] == false
4980                                                 || locals->PTEBufferSizeNotExceededC[i][j][k] == false) {
4981                                         locals->PTEBufferSizeNotExceeded[i][j] = false;
4982                                 }
4983                         }
4984                 }
4985         }
4986         /*Cursor Support Check*/
4987         mode_lib->vba.CursorSupport = true;
4988         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4989                 for (j = 0; j < 2; j++) {
4990                         if (mode_lib->vba.CursorWidth[k][j] > 0.0) {
4991                                 if (dml_floor(
4992                                                 dml_floor(
4993                                                                 mode_lib->vba.CursorBufferSize
4994                                                                                 - mode_lib->vba.CursorChunkSize,
4995                                                                 mode_lib->vba.CursorChunkSize) * 1024.0
4996                                                                 / (mode_lib->vba.CursorWidth[k][j]
4997                                                                                 * mode_lib->vba.CursorBPP[k][j]
4998                                                                                 / 8.0),
4999                                                 1.0)
5000                                                 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
5001                                                 / mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatencyPixelDataOnly
5002                                                 || (mode_lib->vba.CursorBPP[k][j] == 64.0
5003                                                                 && mode_lib->vba.Cursor64BppSupport == false)) {
5004                                         mode_lib->vba.CursorSupport = false;
5005                                 }
5006                         }
5007                 }
5008         }
5009         /*Valid Pitch Check*/
5010
5011         mode_lib->vba.PitchSupport = true;
5012         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5013                 locals->AlignedYPitch[k] = dml_ceil(
5014                                 dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
5015                                 locals->MacroTileWidthY[k]);
5016                 if (locals->AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
5017                         mode_lib->vba.PitchSupport = false;
5018                 }
5019                 if (mode_lib->vba.DCCEnable[k] == true) {
5020                         locals->AlignedDCCMetaPitch[k] = dml_ceil(
5021                                         dml_max(
5022                                                         mode_lib->vba.DCCMetaPitchY[k],
5023                                                         mode_lib->vba.ViewportWidth[k]),
5024                                         64.0 * locals->Read256BlockWidthY[k]);
5025                 } else {
5026                         locals->AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
5027                 }
5028                 if (locals->AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
5029                         mode_lib->vba.PitchSupport = false;
5030                 }
5031                 if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
5032                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
5033                                 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
5034                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
5035                                 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
5036                         locals->AlignedCPitch[k] = dml_ceil(
5037                                         dml_max(
5038                                                         mode_lib->vba.PitchC[k],
5039                                                         mode_lib->vba.ViewportWidth[k] / 2.0),
5040                                         locals->MacroTileWidthC[k]);
5041                 } else {
5042                         locals->AlignedCPitch[k] = mode_lib->vba.PitchC[k];
5043                 }
5044                 if (locals->AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
5045                         mode_lib->vba.PitchSupport = false;
5046                 }
5047         }
5048         /*Mode Support, Voltage State and SOC Configuration*/
5049
5050         for (i = mode_lib->vba.soc.num_states; i >= 0; i--) {
5051                 for (j = 0; j < 2; j++) {
5052                         enum dm_validation_status status = DML_VALIDATION_OK;
5053
5054                         if (mode_lib->vba.ScaleRatioAndTapsSupport != true) {
5055                                 status = DML_FAIL_SCALE_RATIO_TAP;
5056                         } else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
5057                                 status = DML_FAIL_SOURCE_PIXEL_FORMAT;
5058                         } else if (locals->ViewportSizeSupport[i] != true) {
5059                                 status = DML_FAIL_VIEWPORT_SIZE;
5060                         } else if (locals->DIOSupport[i] != true) {
5061                                 status = DML_FAIL_DIO_SUPPORT;
5062                         } else if (locals->NotEnoughDSCUnits[i] != false) {
5063                                 status = DML_FAIL_NOT_ENOUGH_DSC;
5064                         } else if (locals->DSCCLKRequiredMoreThanSupported[i] != false) {
5065                                 status = DML_FAIL_DSC_CLK_REQUIRED;
5066                         } else if (locals->UrgentLatencySupport[i][j] != true) {
5067                                 status = DML_FAIL_URGENT_LATENCY;
5068                         } else if (locals->ROBSupport[i] != true) {
5069                                 status = DML_FAIL_REORDERING_BUFFER;
5070                         } else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
5071                                 status = DML_FAIL_DISPCLK_DPPCLK;
5072                         } else if (locals->TotalAvailablePipesSupport[i][j] != true) {
5073                                 status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
5074                         } else if (mode_lib->vba.NumberOfOTGSupport != true) {
5075                                 status = DML_FAIL_NUM_OTG;
5076                         } else if (mode_lib->vba.WritebackModeSupport != true) {
5077                                 status = DML_FAIL_WRITEBACK_MODE;
5078                         } else if (mode_lib->vba.WritebackLatencySupport != true) {
5079                                 status = DML_FAIL_WRITEBACK_LATENCY;
5080                         } else if (mode_lib->vba.WritebackScaleRatioAndTapsSupport != true) {
5081                                 status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
5082                         } else if (mode_lib->vba.CursorSupport != true) {
5083                                 status = DML_FAIL_CURSOR_SUPPORT;
5084                         } else if (mode_lib->vba.PitchSupport != true) {
5085                                 status = DML_FAIL_PITCH_SUPPORT;
5086                         } else if (locals->PrefetchSupported[i][j] != true) {
5087                                 status = DML_FAIL_PREFETCH_SUPPORT;
5088                         } else if (locals->TotalVerticalActiveBandwidthSupport[i] != true) {
5089                                 status = DML_FAIL_TOTAL_V_ACTIVE_BW;
5090                         } else if (locals->VRatioInPrefetchSupported[i][j] != true) {
5091                                 status = DML_FAIL_V_RATIO_PREFETCH;
5092                         } else if (locals->PTEBufferSizeNotExceeded[i][j] != true) {
5093                                 status = DML_FAIL_PTE_BUFFER_SIZE;
5094                         } else if (mode_lib->vba.NonsupportedDSCInputBPC != false) {
5095                                 status = DML_FAIL_DSC_INPUT_BPC;
5096                         }
5097
5098                         if (status == DML_VALIDATION_OK) {
5099                                 locals->ModeSupport[i][j] = true;
5100                         } else {
5101                                 locals->ModeSupport[i][j] = false;
5102                         }
5103                         locals->ValidationStatus[i] = status;
5104                 }
5105         }
5106         {
5107                 unsigned int MaximumMPCCombine = 0;
5108                 mode_lib->vba.VoltageLevel = mode_lib->vba.soc.num_states + 1;
5109                 for (i = mode_lib->vba.VoltageOverrideLevel; i <= mode_lib->vba.soc.num_states; i++) {
5110                         if (locals->ModeSupport[i][0] == true || locals->ModeSupport[i][1] == true) {
5111                                 mode_lib->vba.VoltageLevel = i;
5112                                 if (locals->ModeSupport[i][1] == true && (locals->ModeSupport[i][0] == false
5113                                                 || mode_lib->vba.WhenToDoMPCCombine == dm_mpc_always_when_possible)) {
5114                                         MaximumMPCCombine = 1;
5115                                 } else {
5116                                         MaximumMPCCombine = 0;
5117                                 }
5118                                 break;
5119                         }
5120                 }
5121                 mode_lib->vba.ImmediateFlipSupport =
5122                         locals->ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
5123                 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5124                         mode_lib->vba.DPPPerPlane[k] = locals->NoOfDPP[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
5125                         locals->DPPCLK[k] = locals->RequiredDPPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
5126                 }
5127                 mode_lib->vba.DISPCLK = locals->RequiredDISPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
5128                 mode_lib->vba.maxMpcComb = MaximumMPCCombine;
5129         }
5130         mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
5131         mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
5132         mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
5133         mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
5134         mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel];
5135         mode_lib->vba.FabricAndDRAMBandwidth = locals->FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
5136         for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5137                 if (mode_lib->vba.BlendingAndTiming[k] == k) {
5138                         mode_lib->vba.ODMCombineEnabled[k] =
5139                                         locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
5140                 } else {
5141                         mode_lib->vba.ODMCombineEnabled[k] = 0;
5142                 }
5143                 mode_lib->vba.DSCEnabled[k] =
5144                                 locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
5145                 mode_lib->vba.OutputBpp[k] =
5146                                 locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
5147         }
5148 }