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