Merge tag 'drm-intel-gt-next-2023-06-08' of git://anongit.freedesktop.org/drm/drm...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / display / dc / dml / dcn31 / display_mode_vba_31.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 #include "dc.h"
27 #include "../display_mode_lib.h"
28 #include "../dcn30/display_mode_vba_30.h"
29 #include "display_mode_vba_31.h"
30 #include "../dml_inline_defs.h"
31
32 /*
33  * NOTE:
34  *   This file is gcc-parsable HW gospel, coming straight from HW engineers.
35  *
36  * It doesn't adhere to Linux kernel style and sometimes will do things in odd
37  * ways. Unless there is something clearly wrong with it the code should
38  * remain as-is as it provides us with a guarantee from HW that it is correct.
39  */
40
41 #define BPP_INVALID 0
42 #define BPP_BLENDED_PIPE 0xffffffff
43 #define DCN31_MAX_DSC_IMAGE_WIDTH 5184
44 #define DCN31_MAX_FMT_420_BUFFER_WIDTH 4096
45 #define DCN3_15_MIN_COMPBUF_SIZE_KB 128
46 #define DCN3_15_MAX_DET_SIZE 384
47
48 // For DML-C changes that hasn't been propagated to VBA yet
49 //#define __DML_VBA_ALLOW_DELTA__
50
51 // Move these to ip paramaters/constant
52
53 // At which vstartup the DML start to try if the mode can be supported
54 #define __DML_VBA_MIN_VSTARTUP__    9
55
56 // Delay in DCFCLK from ARB to DET (1st num is ARB to SDPIF, 2nd number is SDPIF to DET)
57 #define __DML_ARB_TO_RET_DELAY__    (7 + 95)
58
59 // fudge factor for min dcfclk calclation
60 #define __DML_MIN_DCFCLK_FACTOR__   1.15
61
62 typedef struct {
63         double DPPCLK;
64         double DISPCLK;
65         double PixelClock;
66         double DCFCLKDeepSleep;
67         unsigned int DPPPerPlane;
68         bool ScalerEnabled;
69         double VRatio;
70         double VRatioChroma;
71         enum scan_direction_class SourceScan;
72         unsigned int BlockWidth256BytesY;
73         unsigned int BlockHeight256BytesY;
74         unsigned int BlockWidth256BytesC;
75         unsigned int BlockHeight256BytesC;
76         unsigned int InterlaceEnable;
77         unsigned int NumberOfCursors;
78         unsigned int VBlank;
79         unsigned int HTotal;
80         unsigned int DCCEnable;
81         bool ODMCombineIsEnabled;
82         enum source_format_class SourcePixelFormat;
83         int BytePerPixelY;
84         int BytePerPixelC;
85         bool ProgressiveToInterlaceUnitInOPP;
86 } Pipe;
87
88 #define BPP_INVALID 0
89 #define BPP_BLENDED_PIPE 0xffffffff
90
91 static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
92 static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib);
93 static unsigned int dscceComputeDelay(
94                 unsigned int bpc,
95                 double BPP,
96                 unsigned int sliceWidth,
97                 unsigned int numSlices,
98                 enum output_format_class pixelFormat,
99                 enum output_encoder_class Output);
100 static unsigned int dscComputeDelay(enum output_format_class pixelFormat, enum output_encoder_class Output);
101 static bool CalculatePrefetchSchedule(
102                 struct display_mode_lib *mode_lib,
103                 double HostVMInefficiencyFactor,
104                 Pipe *myPipe,
105                 unsigned int DSCDelay,
106                 double DPPCLKDelaySubtotalPlusCNVCFormater,
107                 double DPPCLKDelaySCL,
108                 double DPPCLKDelaySCLLBOnly,
109                 double DPPCLKDelayCNVCCursor,
110                 double DISPCLKDelaySubtotal,
111                 unsigned int DPP_RECOUT_WIDTH,
112                 enum output_format_class OutputFormat,
113                 unsigned int MaxInterDCNTileRepeaters,
114                 unsigned int VStartup,
115                 unsigned int MaxVStartup,
116                 unsigned int GPUVMPageTableLevels,
117                 bool GPUVMEnable,
118                 bool HostVMEnable,
119                 unsigned int HostVMMaxNonCachedPageTableLevels,
120                 double HostVMMinPageSize,
121                 bool DynamicMetadataEnable,
122                 bool DynamicMetadataVMEnabled,
123                 int DynamicMetadataLinesBeforeActiveRequired,
124                 unsigned int DynamicMetadataTransmittedBytes,
125                 double UrgentLatency,
126                 double UrgentExtraLatency,
127                 double TCalc,
128                 unsigned int PDEAndMetaPTEBytesFrame,
129                 unsigned int MetaRowByte,
130                 unsigned int PixelPTEBytesPerRow,
131                 double PrefetchSourceLinesY,
132                 unsigned int SwathWidthY,
133                 double VInitPreFillY,
134                 unsigned int MaxNumSwathY,
135                 double PrefetchSourceLinesC,
136                 unsigned int SwathWidthC,
137                 double VInitPreFillC,
138                 unsigned int MaxNumSwathC,
139                 int swath_width_luma_ub,
140                 int swath_width_chroma_ub,
141                 unsigned int SwathHeightY,
142                 unsigned int SwathHeightC,
143                 double TWait,
144                 double *DSTXAfterScaler,
145                 double *DSTYAfterScaler,
146                 double *DestinationLinesForPrefetch,
147                 double *PrefetchBandwidth,
148                 double *DestinationLinesToRequestVMInVBlank,
149                 double *DestinationLinesToRequestRowInVBlank,
150                 double *VRatioPrefetchY,
151                 double *VRatioPrefetchC,
152                 double *RequiredPrefetchPixDataBWLuma,
153                 double *RequiredPrefetchPixDataBWChroma,
154                 bool *NotEnoughTimeForDynamicMetadata,
155                 double *Tno_bw,
156                 double *prefetch_vmrow_bw,
157                 double *Tdmdl_vm,
158                 double *Tdmdl,
159                 double *TSetup,
160                 int *VUpdateOffsetPix,
161                 double *VUpdateWidthPix,
162                 double *VReadyOffsetPix);
163 static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
164 static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
165 static void CalculateDCCConfiguration(
166                 bool DCCEnabled,
167                 bool DCCProgrammingAssumesScanDirectionUnknown,
168                 enum source_format_class SourcePixelFormat,
169                 unsigned int SurfaceWidthLuma,
170                 unsigned int SurfaceWidthChroma,
171                 unsigned int SurfaceHeightLuma,
172                 unsigned int SurfaceHeightChroma,
173                 double DETBufferSize,
174                 unsigned int RequestHeight256ByteLuma,
175                 unsigned int RequestHeight256ByteChroma,
176                 enum dm_swizzle_mode TilingFormat,
177                 unsigned int BytePerPixelY,
178                 unsigned int BytePerPixelC,
179                 double BytePerPixelDETY,
180                 double BytePerPixelDETC,
181                 enum scan_direction_class ScanOrientation,
182                 unsigned int *MaxUncompressedBlockLuma,
183                 unsigned int *MaxUncompressedBlockChroma,
184                 unsigned int *MaxCompressedBlockLuma,
185                 unsigned int *MaxCompressedBlockChroma,
186                 unsigned int *IndependentBlockLuma,
187                 unsigned int *IndependentBlockChroma);
188 static double CalculatePrefetchSourceLines(
189                 struct display_mode_lib *mode_lib,
190                 double VRatio,
191                 double vtaps,
192                 bool Interlace,
193                 bool ProgressiveToInterlaceUnitInOPP,
194                 unsigned int SwathHeight,
195                 unsigned int ViewportYStart,
196                 double *VInitPreFill,
197                 unsigned int *MaxNumSwath);
198 static unsigned int CalculateVMAndRowBytes(
199                 struct display_mode_lib *mode_lib,
200                 bool DCCEnable,
201                 unsigned int BlockHeight256Bytes,
202                 unsigned int BlockWidth256Bytes,
203                 enum source_format_class SourcePixelFormat,
204                 unsigned int SurfaceTiling,
205                 unsigned int BytePerPixel,
206                 enum scan_direction_class ScanDirection,
207                 unsigned int SwathWidth,
208                 unsigned int ViewportHeight,
209                 bool GPUVMEnable,
210                 bool HostVMEnable,
211                 unsigned int HostVMMaxNonCachedPageTableLevels,
212                 unsigned int GPUVMMinPageSize,
213                 unsigned int HostVMMinPageSize,
214                 unsigned int PTEBufferSizeInRequests,
215                 unsigned int Pitch,
216                 unsigned int DCCMetaPitch,
217                 unsigned int *MacroTileWidth,
218                 unsigned int *MetaRowByte,
219                 unsigned int *PixelPTEBytesPerRow,
220                 bool *PTEBufferSizeNotExceeded,
221                 int *dpte_row_width_ub,
222                 unsigned int *dpte_row_height,
223                 unsigned int *MetaRequestWidth,
224                 unsigned int *MetaRequestHeight,
225                 unsigned int *meta_row_width,
226                 unsigned int *meta_row_height,
227                 int *vm_group_bytes,
228                 unsigned int *dpte_group_bytes,
229                 unsigned int *PixelPTEReqWidth,
230                 unsigned int *PixelPTEReqHeight,
231                 unsigned int *PTERequestSize,
232                 int *DPDE0BytesFrame,
233                 int *MetaPTEBytesFrame);
234 static double CalculateTWait(unsigned int PrefetchMode, double DRAMClockChangeLatency, double UrgentLatency, double SREnterPlusExitTime);
235 static void CalculateRowBandwidth(
236                 bool GPUVMEnable,
237                 enum source_format_class SourcePixelFormat,
238                 double VRatio,
239                 double VRatioChroma,
240                 bool DCCEnable,
241                 double LineTime,
242                 unsigned int MetaRowByteLuma,
243                 unsigned int MetaRowByteChroma,
244                 unsigned int meta_row_height_luma,
245                 unsigned int meta_row_height_chroma,
246                 unsigned int PixelPTEBytesPerRowLuma,
247                 unsigned int PixelPTEBytesPerRowChroma,
248                 unsigned int dpte_row_height_luma,
249                 unsigned int dpte_row_height_chroma,
250                 double *meta_row_bw,
251                 double *dpte_row_bw);
252
253 static void CalculateFlipSchedule(
254                 struct display_mode_lib *mode_lib,
255                 unsigned int k,
256                 double HostVMInefficiencyFactor,
257                 double UrgentExtraLatency,
258                 double UrgentLatency,
259                 double PDEAndMetaPTEBytesPerFrame,
260                 double MetaRowBytes,
261                 double DPTEBytesPerRow);
262 static double CalculateWriteBackDelay(
263                 enum source_format_class WritebackPixelFormat,
264                 double WritebackHRatio,
265                 double WritebackVRatio,
266                 unsigned int WritebackVTaps,
267                 int WritebackDestinationWidth,
268                 int WritebackDestinationHeight,
269                 int WritebackSourceHeight,
270                 unsigned int HTotal);
271
272 static void CalculateVupdateAndDynamicMetadataParameters(
273                 int MaxInterDCNTileRepeaters,
274                 double DPPCLK,
275                 double DISPCLK,
276                 double DCFClkDeepSleep,
277                 double PixelClock,
278                 int HTotal,
279                 int VBlank,
280                 int DynamicMetadataTransmittedBytes,
281                 int DynamicMetadataLinesBeforeActiveRequired,
282                 int InterlaceEnable,
283                 bool ProgressiveToInterlaceUnitInOPP,
284                 double *TSetup,
285                 double *Tdmbf,
286                 double *Tdmec,
287                 double *Tdmsks,
288                 int *VUpdateOffsetPix,
289                 double *VUpdateWidthPix,
290                 double *VReadyOffsetPix);
291
292 static void CalculateWatermarksAndDRAMSpeedChangeSupport(
293                 struct display_mode_lib *mode_lib,
294                 unsigned int PrefetchMode,
295                 double DCFCLK,
296                 double ReturnBW,
297                 double UrgentLatency,
298                 double ExtraLatency,
299                 double SOCCLK,
300                 double DCFCLKDeepSleep,
301                 unsigned int DETBufferSizeY[],
302                 unsigned int DETBufferSizeC[],
303                 unsigned int SwathHeightY[],
304                 unsigned int SwathHeightC[],
305                 double SwathWidthY[],
306                 double SwathWidthC[],
307                 unsigned int DPPPerPlane[],
308                 double BytePerPixelDETY[],
309                 double BytePerPixelDETC[],
310                 bool UnboundedRequestEnabled,
311                 int unsigned CompressedBufferSizeInkByte,
312                 enum clock_change_support *DRAMClockChangeSupport,
313                 double *StutterExitWatermark,
314                 double *StutterEnterPlusExitWatermark,
315                 double *Z8StutterExitWatermark,
316                 double *Z8StutterEnterPlusExitWatermark);
317
318 static void CalculateDCFCLKDeepSleep(
319                 struct display_mode_lib *mode_lib,
320                 unsigned int NumberOfActivePlanes,
321                 int BytePerPixelY[],
322                 int BytePerPixelC[],
323                 double VRatio[],
324                 double VRatioChroma[],
325                 double SwathWidthY[],
326                 double SwathWidthC[],
327                 unsigned int DPPPerPlane[],
328                 double HRatio[],
329                 double HRatioChroma[],
330                 double PixelClock[],
331                 double PSCL_THROUGHPUT[],
332                 double PSCL_THROUGHPUT_CHROMA[],
333                 double DPPCLK[],
334                 double ReadBandwidthLuma[],
335                 double ReadBandwidthChroma[],
336                 int ReturnBusWidth,
337                 double *DCFCLKDeepSleep);
338
339 static void CalculateUrgentBurstFactor(
340                 int swath_width_luma_ub,
341                 int swath_width_chroma_ub,
342                 unsigned int SwathHeightY,
343                 unsigned int SwathHeightC,
344                 double LineTime,
345                 double UrgentLatency,
346                 double CursorBufferSize,
347                 unsigned int CursorWidth,
348                 unsigned int CursorBPP,
349                 double VRatio,
350                 double VRatioC,
351                 double BytePerPixelInDETY,
352                 double BytePerPixelInDETC,
353                 double DETBufferSizeY,
354                 double DETBufferSizeC,
355                 double *UrgentBurstFactorCursor,
356                 double *UrgentBurstFactorLuma,
357                 double *UrgentBurstFactorChroma,
358                 bool *NotEnoughUrgentLatencyHiding);
359
360 static void UseMinimumDCFCLK(
361                 struct display_mode_lib *mode_lib,
362                 int MaxPrefetchMode,
363                 int ReorderingBytes);
364
365 static void CalculatePixelDeliveryTimes(
366                 unsigned int NumberOfActivePlanes,
367                 double VRatio[],
368                 double VRatioChroma[],
369                 double VRatioPrefetchY[],
370                 double VRatioPrefetchC[],
371                 unsigned int swath_width_luma_ub[],
372                 unsigned int swath_width_chroma_ub[],
373                 unsigned int DPPPerPlane[],
374                 double HRatio[],
375                 double HRatioChroma[],
376                 double PixelClock[],
377                 double PSCL_THROUGHPUT[],
378                 double PSCL_THROUGHPUT_CHROMA[],
379                 double DPPCLK[],
380                 int BytePerPixelC[],
381                 enum scan_direction_class SourceScan[],
382                 unsigned int NumberOfCursors[],
383                 unsigned int CursorWidth[][DC__NUM_CURSOR__MAX],
384                 unsigned int CursorBPP[][DC__NUM_CURSOR__MAX],
385                 unsigned int BlockWidth256BytesY[],
386                 unsigned int BlockHeight256BytesY[],
387                 unsigned int BlockWidth256BytesC[],
388                 unsigned int BlockHeight256BytesC[],
389                 double DisplayPipeLineDeliveryTimeLuma[],
390                 double DisplayPipeLineDeliveryTimeChroma[],
391                 double DisplayPipeLineDeliveryTimeLumaPrefetch[],
392                 double DisplayPipeLineDeliveryTimeChromaPrefetch[],
393                 double DisplayPipeRequestDeliveryTimeLuma[],
394                 double DisplayPipeRequestDeliveryTimeChroma[],
395                 double DisplayPipeRequestDeliveryTimeLumaPrefetch[],
396                 double DisplayPipeRequestDeliveryTimeChromaPrefetch[],
397                 double CursorRequestDeliveryTime[],
398                 double CursorRequestDeliveryTimePrefetch[]);
399
400 static void CalculateMetaAndPTETimes(
401                 int NumberOfActivePlanes,
402                 bool GPUVMEnable,
403                 int MetaChunkSize,
404                 int MinMetaChunkSizeBytes,
405                 int HTotal[],
406                 double VRatio[],
407                 double VRatioChroma[],
408                 double DestinationLinesToRequestRowInVBlank[],
409                 double DestinationLinesToRequestRowInImmediateFlip[],
410                 bool DCCEnable[],
411                 double PixelClock[],
412                 int BytePerPixelY[],
413                 int BytePerPixelC[],
414                 enum scan_direction_class SourceScan[],
415                 int dpte_row_height[],
416                 int dpte_row_height_chroma[],
417                 int meta_row_width[],
418                 int meta_row_width_chroma[],
419                 int meta_row_height[],
420                 int meta_row_height_chroma[],
421                 int meta_req_width[],
422                 int meta_req_width_chroma[],
423                 int meta_req_height[],
424                 int meta_req_height_chroma[],
425                 int dpte_group_bytes[],
426                 int PTERequestSizeY[],
427                 int PTERequestSizeC[],
428                 int PixelPTEReqWidthY[],
429                 int PixelPTEReqHeightY[],
430                 int PixelPTEReqWidthC[],
431                 int PixelPTEReqHeightC[],
432                 int dpte_row_width_luma_ub[],
433                 int dpte_row_width_chroma_ub[],
434                 double DST_Y_PER_PTE_ROW_NOM_L[],
435                 double DST_Y_PER_PTE_ROW_NOM_C[],
436                 double DST_Y_PER_META_ROW_NOM_L[],
437                 double DST_Y_PER_META_ROW_NOM_C[],
438                 double TimePerMetaChunkNominal[],
439                 double TimePerChromaMetaChunkNominal[],
440                 double TimePerMetaChunkVBlank[],
441                 double TimePerChromaMetaChunkVBlank[],
442                 double TimePerMetaChunkFlip[],
443                 double TimePerChromaMetaChunkFlip[],
444                 double time_per_pte_group_nom_luma[],
445                 double time_per_pte_group_vblank_luma[],
446                 double time_per_pte_group_flip_luma[],
447                 double time_per_pte_group_nom_chroma[],
448                 double time_per_pte_group_vblank_chroma[],
449                 double time_per_pte_group_flip_chroma[]);
450
451 static void CalculateVMGroupAndRequestTimes(
452                 unsigned int NumberOfActivePlanes,
453                 bool GPUVMEnable,
454                 unsigned int GPUVMMaxPageTableLevels,
455                 unsigned int HTotal[],
456                 int BytePerPixelC[],
457                 double DestinationLinesToRequestVMInVBlank[],
458                 double DestinationLinesToRequestVMInImmediateFlip[],
459                 bool DCCEnable[],
460                 double PixelClock[],
461                 int dpte_row_width_luma_ub[],
462                 int dpte_row_width_chroma_ub[],
463                 int vm_group_bytes[],
464                 unsigned int dpde0_bytes_per_frame_ub_l[],
465                 unsigned int dpde0_bytes_per_frame_ub_c[],
466                 int meta_pte_bytes_per_frame_ub_l[],
467                 int meta_pte_bytes_per_frame_ub_c[],
468                 double TimePerVMGroupVBlank[],
469                 double TimePerVMGroupFlip[],
470                 double TimePerVMRequestVBlank[],
471                 double TimePerVMRequestFlip[]);
472
473 static void CalculateStutterEfficiency(
474                 struct display_mode_lib *mode_lib,
475                 int CompressedBufferSizeInkByte,
476                 bool UnboundedRequestEnabled,
477                 int ConfigReturnBufferSizeInKByte,
478                 int MetaFIFOSizeInKEntries,
479                 int ZeroSizeBufferEntries,
480                 int NumberOfActivePlanes,
481                 int ROBBufferSizeInKByte,
482                 double TotalDataReadBandwidth,
483                 double DCFCLK,
484                 double ReturnBW,
485                 double COMPBUF_RESERVED_SPACE_64B,
486                 double COMPBUF_RESERVED_SPACE_ZS,
487                 double SRExitTime,
488                 double SRExitZ8Time,
489                 bool SynchronizedVBlank,
490                 double Z8StutterEnterPlusExitWatermark,
491                 double StutterEnterPlusExitWatermark,
492                 bool ProgressiveToInterlaceUnitInOPP,
493                 bool Interlace[],
494                 double MinTTUVBlank[],
495                 int DPPPerPlane[],
496                 unsigned int DETBufferSizeY[],
497                 int BytePerPixelY[],
498                 double BytePerPixelDETY[],
499                 double SwathWidthY[],
500                 int SwathHeightY[],
501                 int SwathHeightC[],
502                 double NetDCCRateLuma[],
503                 double NetDCCRateChroma[],
504                 double DCCFractionOfZeroSizeRequestsLuma[],
505                 double DCCFractionOfZeroSizeRequestsChroma[],
506                 int HTotal[],
507                 int VTotal[],
508                 double PixelClock[],
509                 double VRatio[],
510                 enum scan_direction_class SourceScan[],
511                 int BlockHeight256BytesY[],
512                 int BlockWidth256BytesY[],
513                 int BlockHeight256BytesC[],
514                 int BlockWidth256BytesC[],
515                 int DCCYMaxUncompressedBlock[],
516                 int DCCCMaxUncompressedBlock[],
517                 int VActive[],
518                 bool DCCEnable[],
519                 bool WritebackEnable[],
520                 double ReadBandwidthPlaneLuma[],
521                 double ReadBandwidthPlaneChroma[],
522                 double meta_row_bw[],
523                 double dpte_row_bw[],
524                 double *StutterEfficiencyNotIncludingVBlank,
525                 double *StutterEfficiency,
526                 int *NumberOfStutterBurstsPerFrame,
527                 double *Z8StutterEfficiencyNotIncludingVBlank,
528                 double *Z8StutterEfficiency,
529                 int *Z8NumberOfStutterBurstsPerFrame,
530                 double *StutterPeriod);
531
532 static void CalculateSwathAndDETConfiguration(
533                 bool ForceSingleDPP,
534                 int NumberOfActivePlanes,
535                 unsigned int DETBufferSizeInKByte,
536                 double MaximumSwathWidthLuma[],
537                 double MaximumSwathWidthChroma[],
538                 enum scan_direction_class SourceScan[],
539                 enum source_format_class SourcePixelFormat[],
540                 enum dm_swizzle_mode SurfaceTiling[],
541                 int ViewportWidth[],
542                 int ViewportHeight[],
543                 int SurfaceWidthY[],
544                 int SurfaceWidthC[],
545                 int SurfaceHeightY[],
546                 int SurfaceHeightC[],
547                 int Read256BytesBlockHeightY[],
548                 int Read256BytesBlockHeightC[],
549                 int Read256BytesBlockWidthY[],
550                 int Read256BytesBlockWidthC[],
551                 enum odm_combine_mode ODMCombineEnabled[],
552                 int BlendingAndTiming[],
553                 int BytePerPixY[],
554                 int BytePerPixC[],
555                 double BytePerPixDETY[],
556                 double BytePerPixDETC[],
557                 int HActive[],
558                 double HRatio[],
559                 double HRatioChroma[],
560                 int DPPPerPlane[],
561                 int swath_width_luma_ub[],
562                 int swath_width_chroma_ub[],
563                 double SwathWidth[],
564                 double SwathWidthChroma[],
565                 int SwathHeightY[],
566                 int SwathHeightC[],
567                 unsigned int DETBufferSizeY[],
568                 unsigned int DETBufferSizeC[],
569                 bool ViewportSizeSupportPerPlane[],
570                 bool *ViewportSizeSupport);
571 static void CalculateSwathWidth(
572                 bool ForceSingleDPP,
573                 int NumberOfActivePlanes,
574                 enum source_format_class SourcePixelFormat[],
575                 enum scan_direction_class SourceScan[],
576                 int ViewportWidth[],
577                 int ViewportHeight[],
578                 int SurfaceWidthY[],
579                 int SurfaceWidthC[],
580                 int SurfaceHeightY[],
581                 int SurfaceHeightC[],
582                 enum odm_combine_mode ODMCombineEnabled[],
583                 int BytePerPixY[],
584                 int BytePerPixC[],
585                 int Read256BytesBlockHeightY[],
586                 int Read256BytesBlockHeightC[],
587                 int Read256BytesBlockWidthY[],
588                 int Read256BytesBlockWidthC[],
589                 int BlendingAndTiming[],
590                 int HActive[],
591                 double HRatio[],
592                 int DPPPerPlane[],
593                 double SwathWidthSingleDPPY[],
594                 double SwathWidthSingleDPPC[],
595                 double SwathWidthY[],
596                 double SwathWidthC[],
597                 int MaximumSwathHeightY[],
598                 int MaximumSwathHeightC[],
599                 int swath_width_luma_ub[],
600                 int swath_width_chroma_ub[]);
601
602 static double CalculateExtraLatency(
603                 int RoundTripPingLatencyCycles,
604                 int ReorderingBytes,
605                 double DCFCLK,
606                 int TotalNumberOfActiveDPP,
607                 int PixelChunkSizeInKByte,
608                 int TotalNumberOfDCCActiveDPP,
609                 int MetaChunkSize,
610                 double ReturnBW,
611                 bool GPUVMEnable,
612                 bool HostVMEnable,
613                 int NumberOfActivePlanes,
614                 int NumberOfDPP[],
615                 int dpte_group_bytes[],
616                 double HostVMInefficiencyFactor,
617                 double HostVMMinPageSize,
618                 int HostVMMaxNonCachedPageTableLevels);
619
620 static double CalculateExtraLatencyBytes(
621                 int ReorderingBytes,
622                 int TotalNumberOfActiveDPP,
623                 int PixelChunkSizeInKByte,
624                 int TotalNumberOfDCCActiveDPP,
625                 int MetaChunkSize,
626                 bool GPUVMEnable,
627                 bool HostVMEnable,
628                 int NumberOfActivePlanes,
629                 int NumberOfDPP[],
630                 int dpte_group_bytes[],
631                 double HostVMInefficiencyFactor,
632                 double HostVMMinPageSize,
633                 int HostVMMaxNonCachedPageTableLevels);
634
635 static double CalculateUrgentLatency(
636                 double UrgentLatencyPixelDataOnly,
637                 double UrgentLatencyPixelMixedWithVMData,
638                 double UrgentLatencyVMDataOnly,
639                 bool DoUrgentLatencyAdjustment,
640                 double UrgentLatencyAdjustmentFabricClockComponent,
641                 double UrgentLatencyAdjustmentFabricClockReference,
642                 double FabricClockSingle);
643
644 static void CalculateUnboundedRequestAndCompressedBufferSize(
645                 unsigned int DETBufferSizeInKByte,
646                 int ConfigReturnBufferSizeInKByte,
647                 enum unbounded_requesting_policy UseUnboundedRequestingFinal,
648                 int TotalActiveDPP,
649                 bool NoChromaPlanes,
650                 int MaxNumDPP,
651                 int CompressedBufferSegmentSizeInkByteFinal,
652                 enum output_encoder_class *Output,
653                 bool *UnboundedRequestEnabled,
654                 int *CompressedBufferSizeInkByte);
655
656 static bool UnboundedRequest(enum unbounded_requesting_policy UseUnboundedRequestingFinal, int TotalNumberOfActiveDPP, bool NoChroma, enum output_encoder_class Output);
657
658 void dml31_recalculate(struct display_mode_lib *mode_lib)
659 {
660         ModeSupportAndSystemConfiguration(mode_lib);
661         PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
662         DisplayPipeConfiguration(mode_lib);
663 #ifdef __DML_VBA_DEBUG__
664         dml_print("DML::%s: Calling DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation\n", __func__);
665 #endif
666         DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
667 }
668
669 static unsigned int dscceComputeDelay(
670                 unsigned int bpc,
671                 double BPP,
672                 unsigned int sliceWidth,
673                 unsigned int numSlices,
674                 enum output_format_class pixelFormat,
675                 enum output_encoder_class Output)
676 {
677         // valid bpc         = source bits per component in the set of {8, 10, 12}
678         // valid bpp         = increments of 1/16 of a bit
679         //                    min = 6/7/8 in N420/N422/444, respectively
680         //                    max = such that compression is 1:1
681         //valid sliceWidth  = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
682         //valid numSlices   = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
683         //valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
684
685         // fixed value
686         unsigned int rcModelSize = 8192;
687
688         // N422/N420 operate at 2 pixels per clock
689         unsigned int pixelsPerClock = 0, lstall, D, initalXmitDelay, w, s, ix, wx, P, l0, a, ax, L, Delay, pixels;
690
691         if (pixelFormat == dm_420)
692                 pixelsPerClock = 2;
693         else if (pixelFormat == dm_444)
694                 pixelsPerClock = 1;
695         else if (pixelFormat == dm_n422)
696                 pixelsPerClock = 2;
697         // #all other modes operate at 1 pixel per clock
698         else
699                 pixelsPerClock = 1;
700
701         //initial transmit delay as per PPS
702         initalXmitDelay = dml_round(rcModelSize / 2.0 / BPP / pixelsPerClock);
703
704         //compute ssm delay
705         if (bpc == 8)
706                 D = 81;
707         else if (bpc == 10)
708                 D = 89;
709         else
710                 D = 113;
711
712         //divide by pixel per cycle to compute slice width as seen by DSC
713         w = sliceWidth / pixelsPerClock;
714
715         //422 mode has an additional cycle of delay
716         if (pixelFormat == dm_420 || pixelFormat == dm_444 || pixelFormat == dm_n422)
717                 s = 0;
718         else
719                 s = 1;
720
721         //main calculation for the dscce
722         ix = initalXmitDelay + 45;
723         wx = (w + 2) / 3;
724         P = 3 * wx - w;
725         l0 = ix / w;
726         a = ix + P * l0;
727         ax = (a + 2) / 3 + D + 6 + 1;
728         L = (ax + wx - 1) / wx;
729         if ((ix % w) == 0 && P != 0)
730                 lstall = 1;
731         else
732                 lstall = 0;
733         Delay = L * wx * (numSlices - 1) + ax + s + lstall + 22;
734
735         //dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
736         pixels = Delay * 3 * pixelsPerClock;
737         return pixels;
738 }
739
740 static unsigned int dscComputeDelay(enum output_format_class pixelFormat, enum output_encoder_class Output)
741 {
742         unsigned int Delay = 0;
743
744         if (pixelFormat == dm_420) {
745                 //   sfr
746                 Delay = Delay + 2;
747                 //   dsccif
748                 Delay = Delay + 0;
749                 //   dscc - input deserializer
750                 Delay = Delay + 3;
751                 //   dscc gets pixels every other cycle
752                 Delay = Delay + 2;
753                 //   dscc - input cdc fifo
754                 Delay = Delay + 12;
755                 //   dscc gets pixels every other cycle
756                 Delay = Delay + 13;
757                 //   dscc - cdc uncertainty
758                 Delay = Delay + 2;
759                 //   dscc - output cdc fifo
760                 Delay = Delay + 7;
761                 //   dscc gets pixels every other cycle
762                 Delay = Delay + 3;
763                 //   dscc - cdc uncertainty
764                 Delay = Delay + 2;
765                 //   dscc - output serializer
766                 Delay = Delay + 1;
767                 //   sft
768                 Delay = Delay + 1;
769         } else if (pixelFormat == dm_n422) {
770                 //   sfr
771                 Delay = Delay + 2;
772                 //   dsccif
773                 Delay = Delay + 1;
774                 //   dscc - input deserializer
775                 Delay = Delay + 5;
776                 //  dscc - input cdc fifo
777                 Delay = Delay + 25;
778                 //   dscc - cdc uncertainty
779                 Delay = Delay + 2;
780                 //   dscc - output cdc fifo
781                 Delay = Delay + 10;
782                 //   dscc - cdc uncertainty
783                 Delay = Delay + 2;
784                 //   dscc - output serializer
785                 Delay = Delay + 1;
786                 //   sft
787                 Delay = Delay + 1;
788         } else {
789                 //   sfr
790                 Delay = Delay + 2;
791                 //   dsccif
792                 Delay = Delay + 0;
793                 //   dscc - input deserializer
794                 Delay = Delay + 3;
795                 //   dscc - input cdc fifo
796                 Delay = Delay + 12;
797                 //   dscc - cdc uncertainty
798                 Delay = Delay + 2;
799                 //   dscc - output cdc fifo
800                 Delay = Delay + 7;
801                 //   dscc - output serializer
802                 Delay = Delay + 1;
803                 //   dscc - cdc uncertainty
804                 Delay = Delay + 2;
805                 //   sft
806                 Delay = Delay + 1;
807         }
808
809         return Delay;
810 }
811
812 static bool CalculatePrefetchSchedule(
813                 struct display_mode_lib *mode_lib,
814                 double HostVMInefficiencyFactor,
815                 Pipe *myPipe,
816                 unsigned int DSCDelay,
817                 double DPPCLKDelaySubtotalPlusCNVCFormater,
818                 double DPPCLKDelaySCL,
819                 double DPPCLKDelaySCLLBOnly,
820                 double DPPCLKDelayCNVCCursor,
821                 double DISPCLKDelaySubtotal,
822                 unsigned int DPP_RECOUT_WIDTH,
823                 enum output_format_class OutputFormat,
824                 unsigned int MaxInterDCNTileRepeaters,
825                 unsigned int VStartup,
826                 unsigned int MaxVStartup,
827                 unsigned int GPUVMPageTableLevels,
828                 bool GPUVMEnable,
829                 bool HostVMEnable,
830                 unsigned int HostVMMaxNonCachedPageTableLevels,
831                 double HostVMMinPageSize,
832                 bool DynamicMetadataEnable,
833                 bool DynamicMetadataVMEnabled,
834                 int DynamicMetadataLinesBeforeActiveRequired,
835                 unsigned int DynamicMetadataTransmittedBytes,
836                 double UrgentLatency,
837                 double UrgentExtraLatency,
838                 double TCalc,
839                 unsigned int PDEAndMetaPTEBytesFrame,
840                 unsigned int MetaRowByte,
841                 unsigned int PixelPTEBytesPerRow,
842                 double PrefetchSourceLinesY,
843                 unsigned int SwathWidthY,
844                 double VInitPreFillY,
845                 unsigned int MaxNumSwathY,
846                 double PrefetchSourceLinesC,
847                 unsigned int SwathWidthC,
848                 double VInitPreFillC,
849                 unsigned int MaxNumSwathC,
850                 int swath_width_luma_ub,
851                 int swath_width_chroma_ub,
852                 unsigned int SwathHeightY,
853                 unsigned int SwathHeightC,
854                 double TWait,
855                 double *DSTXAfterScaler,
856                 double *DSTYAfterScaler,
857                 double *DestinationLinesForPrefetch,
858                 double *PrefetchBandwidth,
859                 double *DestinationLinesToRequestVMInVBlank,
860                 double *DestinationLinesToRequestRowInVBlank,
861                 double *VRatioPrefetchY,
862                 double *VRatioPrefetchC,
863                 double *RequiredPrefetchPixDataBWLuma,
864                 double *RequiredPrefetchPixDataBWChroma,
865                 bool *NotEnoughTimeForDynamicMetadata,
866                 double *Tno_bw,
867                 double *prefetch_vmrow_bw,
868                 double *Tdmdl_vm,
869                 double *Tdmdl,
870                 double *TSetup,
871                 int *VUpdateOffsetPix,
872                 double *VUpdateWidthPix,
873                 double *VReadyOffsetPix)
874 {
875         bool MyError = false;
876         unsigned int DPPCycles, DISPCLKCycles;
877         double DSTTotalPixelsAfterScaler;
878         double LineTime;
879         double dst_y_prefetch_equ;
880 #ifdef __DML_VBA_DEBUG__
881         double Tsw_oto;
882 #endif
883         double prefetch_bw_oto;
884         double prefetch_bw_pr;
885         double Tvm_oto;
886         double Tr0_oto;
887         double Tvm_oto_lines;
888         double Tr0_oto_lines;
889         double dst_y_prefetch_oto;
890         double TimeForFetchingMetaPTE = 0;
891         double TimeForFetchingRowInVBlank = 0;
892         double LinesToRequestPrefetchPixelData = 0;
893         unsigned int HostVMDynamicLevelsTrips;
894         double trip_to_mem;
895         double Tvm_trips;
896         double Tr0_trips;
897         double Tvm_trips_rounded;
898         double Tr0_trips_rounded;
899         double Lsw_oto;
900         double Tpre_rounded;
901         double prefetch_bw_equ;
902         double Tvm_equ;
903         double Tr0_equ;
904         double Tdmbf;
905         double Tdmec;
906         double Tdmsks;
907         double prefetch_sw_bytes;
908         double bytes_pp;
909         double dep_bytes;
910         int max_vratio_pre = 4;
911         double min_Lsw;
912         double Tsw_est1 = 0;
913         double Tsw_est3 = 0;
914         double  max_Tsw = 0;
915
916         if (GPUVMEnable == true && HostVMEnable == true) {
917                 HostVMDynamicLevelsTrips = HostVMMaxNonCachedPageTableLevels;
918         } else {
919                 HostVMDynamicLevelsTrips = 0;
920         }
921 #ifdef __DML_VBA_DEBUG__
922         dml_print("DML::%s: GPUVMEnable=%d HostVMEnable=%d HostVMInefficiencyFactor=%f\n", __func__, GPUVMEnable, HostVMEnable, HostVMInefficiencyFactor);
923 #endif
924         CalculateVupdateAndDynamicMetadataParameters(
925                         MaxInterDCNTileRepeaters,
926                         myPipe->DPPCLK,
927                         myPipe->DISPCLK,
928                         myPipe->DCFCLKDeepSleep,
929                         myPipe->PixelClock,
930                         myPipe->HTotal,
931                         myPipe->VBlank,
932                         DynamicMetadataTransmittedBytes,
933                         DynamicMetadataLinesBeforeActiveRequired,
934                         myPipe->InterlaceEnable,
935                         myPipe->ProgressiveToInterlaceUnitInOPP,
936                         TSetup,
937                         &Tdmbf,
938                         &Tdmec,
939                         &Tdmsks,
940                         VUpdateOffsetPix,
941                         VUpdateWidthPix,
942                         VReadyOffsetPix);
943
944         LineTime = myPipe->HTotal / myPipe->PixelClock;
945         trip_to_mem = UrgentLatency;
946         Tvm_trips = UrgentExtraLatency + trip_to_mem * (GPUVMPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1);
947
948 #ifdef __DML_VBA_ALLOW_DELTA__
949         if (DynamicMetadataVMEnabled == true && GPUVMEnable == true) {
950 #else
951         if (DynamicMetadataVMEnabled == true) {
952 #endif
953                 *Tdmdl = TWait + Tvm_trips + trip_to_mem;
954         } else {
955                 *Tdmdl = TWait + UrgentExtraLatency;
956         }
957
958 #ifdef __DML_VBA_ALLOW_DELTA__
959         if (DynamicMetadataEnable == false) {
960                 *Tdmdl = 0.0;
961         }
962 #endif
963
964         if (DynamicMetadataEnable == true) {
965                 if (VStartup * LineTime < *TSetup + *Tdmdl + Tdmbf + Tdmec + Tdmsks) {
966                         *NotEnoughTimeForDynamicMetadata = true;
967                         dml_print("DML::%s: Not Enough Time for Dynamic Meta!\n", __func__);
968                         dml_print("DML::%s: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", __func__, Tdmbf);
969                         dml_print("DML::%s: Tdmec: %fus - time dio takes to transfer dmd\n", __func__, Tdmec);
970                         dml_print("DML::%s: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", __func__, Tdmsks);
971                         dml_print("DML::%s: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", __func__, *Tdmdl);
972                 } else {
973                         *NotEnoughTimeForDynamicMetadata = false;
974                 }
975         } else {
976                 *NotEnoughTimeForDynamicMetadata = false;
977         }
978
979         *Tdmdl_vm = (DynamicMetadataEnable == true && DynamicMetadataVMEnabled == true && GPUVMEnable == true ? TWait + Tvm_trips : 0);
980
981         if (myPipe->ScalerEnabled)
982                 DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCL;
983         else
984                 DPPCycles = DPPCLKDelaySubtotalPlusCNVCFormater + DPPCLKDelaySCLLBOnly;
985
986         DPPCycles = DPPCycles + myPipe->NumberOfCursors * DPPCLKDelayCNVCCursor;
987
988         DISPCLKCycles = DISPCLKDelaySubtotal;
989
990         if (myPipe->DPPCLK == 0.0 || myPipe->DISPCLK == 0.0)
991                 return true;
992
993         *DSTXAfterScaler = DPPCycles * myPipe->PixelClock / myPipe->DPPCLK + DISPCLKCycles * myPipe->PixelClock / myPipe->DISPCLK + DSCDelay;
994
995 #ifdef __DML_VBA_DEBUG__
996         dml_print("DML::%s: DPPCycles: %d\n", __func__, DPPCycles);
997         dml_print("DML::%s: PixelClock: %f\n", __func__, myPipe->PixelClock);
998         dml_print("DML::%s: DPPCLK: %f\n", __func__, myPipe->DPPCLK);
999         dml_print("DML::%s: DISPCLKCycles: %d\n", __func__, DISPCLKCycles);
1000         dml_print("DML::%s: DISPCLK: %f\n", __func__, myPipe->DISPCLK);
1001         dml_print("DML::%s: DSCDelay: %d\n", __func__, DSCDelay);
1002         dml_print("DML::%s: DSTXAfterScaler: %d\n", __func__, *DSTXAfterScaler);
1003         dml_print("DML::%s: ODMCombineIsEnabled: %d\n", __func__, myPipe->ODMCombineIsEnabled);
1004 #endif
1005
1006         *DSTXAfterScaler = *DSTXAfterScaler + ((myPipe->ODMCombineIsEnabled) ? 18 : 0) + (myPipe->DPPPerPlane - 1) * DPP_RECOUT_WIDTH;
1007
1008         if (OutputFormat == dm_420 || (myPipe->InterlaceEnable && myPipe->ProgressiveToInterlaceUnitInOPP))
1009                 *DSTYAfterScaler = 1;
1010         else
1011                 *DSTYAfterScaler = 0;
1012
1013         DSTTotalPixelsAfterScaler = *DSTYAfterScaler * myPipe->HTotal + *DSTXAfterScaler;
1014         *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / myPipe->HTotal, 1);
1015         *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * myPipe->HTotal));
1016
1017 #ifdef __DML_VBA_DEBUG__
1018         dml_print("DML::%s: DSTXAfterScaler: %d (final)\n", __func__, *DSTXAfterScaler);
1019 #endif
1020
1021         MyError = false;
1022
1023         Tr0_trips = trip_to_mem * (HostVMDynamicLevelsTrips + 1);
1024         Tvm_trips_rounded = dml_ceil(4.0 * Tvm_trips / LineTime, 1) / 4 * LineTime;
1025         Tr0_trips_rounded = dml_ceil(4.0 * Tr0_trips / LineTime, 1) / 4 * LineTime;
1026
1027 #ifdef __DML_VBA_ALLOW_DELTA__
1028         if (!myPipe->DCCEnable) {
1029                 Tr0_trips = 0.0;
1030                 Tr0_trips_rounded = 0.0;
1031         }
1032 #endif
1033
1034         if (!GPUVMEnable) {
1035                 Tvm_trips = 0.0;
1036                 Tvm_trips_rounded = 0.0;
1037         }
1038
1039         if (GPUVMEnable) {
1040                 if (GPUVMPageTableLevels >= 3) {
1041                         *Tno_bw = UrgentExtraLatency + trip_to_mem * ((GPUVMPageTableLevels - 2) - 1);
1042                 } else {
1043                         *Tno_bw = 0;
1044                 }
1045         } else if (!myPipe->DCCEnable) {
1046                 *Tno_bw = LineTime;
1047         } else {
1048                 *Tno_bw = LineTime / 4;
1049         }
1050
1051         if (myPipe->SourcePixelFormat == dm_420_8 || myPipe->SourcePixelFormat == dm_420_10 || myPipe->SourcePixelFormat == dm_420_12)
1052                 bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC / 4;
1053         else
1054                 bytes_pp = myPipe->BytePerPixelY + myPipe->BytePerPixelC;
1055         /*rev 99*/
1056         prefetch_bw_pr = bytes_pp * myPipe->PixelClock / (double) myPipe->DPPPerPlane;
1057         prefetch_bw_pr = dml_min(1, myPipe->VRatio) * prefetch_bw_pr;
1058         max_Tsw = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
1059         prefetch_sw_bytes = PrefetchSourceLinesY * swath_width_luma_ub * myPipe->BytePerPixelY + PrefetchSourceLinesC * swath_width_chroma_ub * myPipe->BytePerPixelC;
1060         prefetch_bw_oto = dml_max(prefetch_bw_pr, prefetch_sw_bytes / max_Tsw);
1061
1062         min_Lsw = dml_max(1, dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) / max_vratio_pre);
1063         Lsw_oto = dml_ceil(4 * dml_max(prefetch_sw_bytes / prefetch_bw_oto / LineTime, min_Lsw), 1) / 4;
1064 #ifdef __DML_VBA_DEBUG__
1065         Tsw_oto = Lsw_oto * LineTime;
1066 #endif
1067
1068
1069 #ifdef __DML_VBA_DEBUG__
1070         dml_print("DML: HTotal: %d\n", myPipe->HTotal);
1071         dml_print("DML: prefetch_bw_oto: %f\n", prefetch_bw_oto);
1072         dml_print("DML: PrefetchSourceLinesY: %f\n", PrefetchSourceLinesY);
1073         dml_print("DML: swath_width_luma_ub: %d\n", swath_width_luma_ub);
1074         dml_print("DML: BytePerPixelY: %d\n", myPipe->BytePerPixelY);
1075         dml_print("DML: Tsw_oto: %f\n", Tsw_oto);
1076 #endif
1077
1078         if (GPUVMEnable == true)
1079                 Tvm_oto = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_oto, Tvm_trips, LineTime / 4.0);
1080         else
1081                 Tvm_oto = LineTime / 4.0;
1082
1083         if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
1084                 Tr0_oto = dml_max4((MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_oto, Tr0_trips, // PREVIOUS_ERROR (missing this term)
1085                                 LineTime - Tvm_oto,
1086                                 LineTime / 4);
1087         } else {
1088                 Tr0_oto = (LineTime - Tvm_oto) / 2.0;
1089         }
1090
1091 #ifdef __DML_VBA_DEBUG__
1092         dml_print("DML::%s: Tvm_trips = %f\n", __func__, Tvm_trips);
1093         dml_print("DML::%s: Tr0_trips = %f\n", __func__, Tr0_trips);
1094         dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, MetaRowByte);
1095         dml_print("DML::%s: MetaRowByte = %d\n", __func__, MetaRowByte);
1096         dml_print("DML::%s: PixelPTEBytesPerRow = %d\n", __func__, PixelPTEBytesPerRow);
1097         dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
1098         dml_print("DML::%s: prefetch_bw_oto = %f\n", __func__, prefetch_bw_oto);
1099         dml_print("DML::%s: Tr0_oto = %f\n", __func__, Tr0_oto);
1100         dml_print("DML::%s: Tvm_oto = %f\n", __func__, Tvm_oto);
1101 #endif
1102
1103         Tvm_oto_lines = dml_ceil(4.0 * Tvm_oto / LineTime, 1) / 4.0;
1104         Tr0_oto_lines = dml_ceil(4.0 * Tr0_oto / LineTime, 1) / 4.0;
1105         dst_y_prefetch_oto = Tvm_oto_lines + 2 * Tr0_oto_lines + Lsw_oto;
1106         dst_y_prefetch_equ =  VStartup - (*TSetup + dml_max(TWait + TCalc, *Tdmdl)) / LineTime - (*DSTYAfterScaler + *DSTXAfterScaler / myPipe->HTotal);
1107         dst_y_prefetch_equ = dml_floor(4.0 * (dst_y_prefetch_equ + 0.125), 1) / 4.0;
1108         Tpre_rounded = dst_y_prefetch_equ * LineTime;
1109
1110         dep_bytes = dml_max(PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor, MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor);
1111
1112         if (prefetch_sw_bytes < dep_bytes)
1113                 prefetch_sw_bytes = 2 * dep_bytes;
1114
1115         dml_print("DML: dst_y_prefetch_oto: %f\n", dst_y_prefetch_oto);
1116         dml_print("DML: Tvm_oto_lines: %f\n", Tvm_oto_lines);
1117         dml_print("DML: Tr0_oto_lines: %f\n", Tr0_oto_lines);
1118         dml_print("DML: Lsw_oto: %f\n", Lsw_oto);
1119         dml_print("DML: LineTime: %f\n", LineTime);
1120         dml_print("DML: dst_y_prefetch_equ: %f (after round)\n", dst_y_prefetch_equ);
1121
1122         dml_print("DML: LineTime: %f\n", LineTime);
1123         dml_print("DML: VStartup: %d\n", VStartup);
1124         dml_print("DML: Tvstartup: %fus - time between vstartup and first pixel of active\n", VStartup * LineTime);
1125         dml_print("DML: TSetup: %fus - time from vstartup to vready\n", *TSetup);
1126         dml_print("DML: TCalc: %fus - time for calculations in dchub starting at vready\n", TCalc);
1127         dml_print("DML: TWait: %fus - time for fabric to become ready max(pstate exit,cstate enter/exit, urgent latency) after TCalc\n", TWait);
1128         dml_print("DML: Tdmbf: %fus - time for dmd transfer from dchub to dio output buffer\n", Tdmbf);
1129         dml_print("DML: Tdmec: %fus - time dio takes to transfer dmd\n", Tdmec);
1130         dml_print("DML: Tdmsks: %fus - time before active dmd must complete transmission at dio\n", Tdmsks);
1131         dml_print("DML: Tdmdl_vm: %fus - time for vm stages of dmd \n", *Tdmdl_vm);
1132         dml_print("DML: Tdmdl: %fus - time for fabric to become ready and fetch dmd \n", *Tdmdl);
1133         dml_print("DML: DSTXAfterScaler: %f pixels - number of pixel clocks pipeline and buffer delay after scaler \n", *DSTXAfterScaler);
1134         dml_print("DML: DSTYAfterScaler: %f lines - number of lines of pipeline and buffer delay after scaler \n", *DSTYAfterScaler);
1135
1136         *PrefetchBandwidth = 0;
1137         *DestinationLinesToRequestVMInVBlank = 0;
1138         *DestinationLinesToRequestRowInVBlank = 0;
1139         *VRatioPrefetchY = 0;
1140         *VRatioPrefetchC = 0;
1141         *RequiredPrefetchPixDataBWLuma = 0;
1142         if (dst_y_prefetch_equ > 1) {
1143                 double PrefetchBandwidth1;
1144                 double PrefetchBandwidth2;
1145                 double PrefetchBandwidth3;
1146                 double PrefetchBandwidth4;
1147
1148                 if (Tpre_rounded - *Tno_bw > 0) {
1149                         PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
1150                                         + prefetch_sw_bytes) / (Tpre_rounded - *Tno_bw);
1151                         Tsw_est1 = prefetch_sw_bytes / PrefetchBandwidth1;
1152                 } else {
1153                         PrefetchBandwidth1 = 0;
1154                 }
1155
1156                 if (VStartup == MaxVStartup && Tsw_est1 / LineTime < min_Lsw && Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - *Tno_bw > 0) {
1157                         PrefetchBandwidth1 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + 2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor)
1158                                         / (Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - *Tno_bw);
1159                 }
1160
1161                 if (Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded > 0)
1162                         PrefetchBandwidth2 = (PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor + prefetch_sw_bytes) / (Tpre_rounded - *Tno_bw - 2 * Tr0_trips_rounded);
1163                 else
1164                         PrefetchBandwidth2 = 0;
1165
1166                 if (Tpre_rounded - Tvm_trips_rounded > 0) {
1167                         PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor
1168                                         + prefetch_sw_bytes) / (Tpre_rounded - Tvm_trips_rounded);
1169                         Tsw_est3 = prefetch_sw_bytes / PrefetchBandwidth3;
1170                 } else {
1171                         PrefetchBandwidth3 = 0;
1172                 }
1173
1174 #ifdef __DML_VBA_DEBUG__
1175                 dml_print("DML::%s: Tpre_rounded: %f\n", __func__, Tpre_rounded);
1176                 dml_print("DML::%s: Tvm_trips_rounded: %f\n", __func__, Tvm_trips_rounded);
1177                 dml_print("DML::%s: PrefetchBandwidth3: %f\n", __func__, PrefetchBandwidth3);
1178 #endif
1179                 if (VStartup == MaxVStartup && Tsw_est3 / LineTime < min_Lsw && Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - Tvm_trips_rounded > 0) {
1180                         PrefetchBandwidth3 = (2 * MetaRowByte + 2 * PixelPTEBytesPerRow * HostVMInefficiencyFactor)
1181                                         / (Tpre_rounded - min_Lsw * LineTime - 0.75 * LineTime - Tvm_trips_rounded);
1182                 }
1183
1184                 if (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded > 0)
1185                         PrefetchBandwidth4 = prefetch_sw_bytes / (Tpre_rounded - Tvm_trips_rounded - 2 * Tr0_trips_rounded);
1186                 else
1187                         PrefetchBandwidth4 = 0;
1188
1189                 {
1190                         bool Case1OK;
1191                         bool Case2OK;
1192                         bool Case3OK;
1193
1194                         if (PrefetchBandwidth1 > 0) {
1195                                 if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth1 >= Tvm_trips_rounded
1196                                                 && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth1 >= Tr0_trips_rounded) {
1197                                         Case1OK = true;
1198                                 } else {
1199                                         Case1OK = false;
1200                                 }
1201                         } else {
1202                                 Case1OK = false;
1203                         }
1204
1205                         if (PrefetchBandwidth2 > 0) {
1206                                 if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth2 >= Tvm_trips_rounded
1207                                                 && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth2 < Tr0_trips_rounded) {
1208                                         Case2OK = true;
1209                                 } else {
1210                                         Case2OK = false;
1211                                 }
1212                         } else {
1213                                 Case2OK = false;
1214                         }
1215
1216                         if (PrefetchBandwidth3 > 0) {
1217                                 if (*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / PrefetchBandwidth3 < Tvm_trips_rounded
1218                                                 && (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / PrefetchBandwidth3 >= Tr0_trips_rounded) {
1219                                         Case3OK = true;
1220                                 } else {
1221                                         Case3OK = false;
1222                                 }
1223                         } else {
1224                                 Case3OK = false;
1225                         }
1226
1227                         if (Case1OK) {
1228                                 prefetch_bw_equ = PrefetchBandwidth1;
1229                         } else if (Case2OK) {
1230                                 prefetch_bw_equ = PrefetchBandwidth2;
1231                         } else if (Case3OK) {
1232                                 prefetch_bw_equ = PrefetchBandwidth3;
1233                         } else {
1234                                 prefetch_bw_equ = PrefetchBandwidth4;
1235                         }
1236
1237 #ifdef __DML_VBA_DEBUG__
1238                         dml_print("DML::%s: Case1OK: %d\n", __func__, Case1OK);
1239                         dml_print("DML::%s: Case2OK: %d\n", __func__, Case2OK);
1240                         dml_print("DML::%s: Case3OK: %d\n", __func__, Case3OK);
1241                         dml_print("DML::%s: prefetch_bw_equ: %f\n", __func__, prefetch_bw_equ);
1242 #endif
1243
1244                         if (prefetch_bw_equ > 0) {
1245                                 if (GPUVMEnable == true) {
1246                                         Tvm_equ = dml_max3(*Tno_bw + PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / prefetch_bw_equ, Tvm_trips, LineTime / 4);
1247                                 } else {
1248                                         Tvm_equ = LineTime / 4;
1249                                 }
1250
1251                                 if ((GPUVMEnable == true || myPipe->DCCEnable == true)) {
1252                                         Tr0_equ = dml_max4(
1253                                                         (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / prefetch_bw_equ,
1254                                                         Tr0_trips,
1255                                                         (LineTime - Tvm_equ) / 2,
1256                                                         LineTime / 4);
1257                                 } else {
1258                                         Tr0_equ = (LineTime - Tvm_equ) / 2;
1259                                 }
1260                         } else {
1261                                 Tvm_equ = 0;
1262                                 Tr0_equ = 0;
1263                                 dml_print("DML: prefetch_bw_equ equals 0! %s:%d\n", __FILE__, __LINE__);
1264                         }
1265                 }
1266
1267                 if (dst_y_prefetch_oto < dst_y_prefetch_equ) {
1268                         *DestinationLinesForPrefetch = dst_y_prefetch_oto;
1269                         TimeForFetchingMetaPTE = Tvm_oto;
1270                         TimeForFetchingRowInVBlank = Tr0_oto;
1271                         *PrefetchBandwidth = prefetch_bw_oto;
1272                 } else {
1273                         *DestinationLinesForPrefetch = dst_y_prefetch_equ;
1274                         TimeForFetchingMetaPTE = Tvm_equ;
1275                         TimeForFetchingRowInVBlank = Tr0_equ;
1276                         *PrefetchBandwidth = prefetch_bw_equ;
1277                 }
1278
1279                 *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0;
1280
1281                 *DestinationLinesToRequestRowInVBlank = dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0;
1282
1283 #ifdef __DML_VBA_ALLOW_DELTA__
1284                 LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch
1285                 // See note above dated 5/30/2018
1286                 //                      - ((NumberOfCursors > 0 || GPUVMEnable || DCCEnable) ?
1287                                 - ((GPUVMEnable || myPipe->DCCEnable) ? (*DestinationLinesToRequestVMInVBlank + 2 * *DestinationLinesToRequestRowInVBlank) : 0.0); // TODO: Did someone else add this??
1288 #else
1289                                 LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch - *DestinationLinesToRequestVMInVBlank - 2 * *DestinationLinesToRequestRowInVBlank;
1290 #endif
1291
1292 #ifdef __DML_VBA_DEBUG__
1293                 dml_print("DML::%s: DestinationLinesForPrefetch = %f\n", __func__, *DestinationLinesForPrefetch);
1294                 dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n", __func__, *DestinationLinesToRequestVMInVBlank);
1295                 dml_print("DML::%s: TimeForFetchingRowInVBlank = %f\n", __func__, TimeForFetchingRowInVBlank);
1296                 dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
1297                 dml_print("DML::%s: DestinationLinesToRequestRowInVBlank = %f\n", __func__, *DestinationLinesToRequestRowInVBlank);
1298                 dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, PrefetchSourceLinesY);
1299                 dml_print("DML::%s: LinesToRequestPrefetchPixelData = %f\n", __func__, LinesToRequestPrefetchPixelData);
1300 #endif
1301
1302                 if (LinesToRequestPrefetchPixelData > 0 && prefetch_bw_equ > 0) {
1303
1304                         *VRatioPrefetchY = (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData;
1305                         *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1306 #ifdef __DML_VBA_DEBUG__
1307                         dml_print("DML::%s: VRatioPrefetchY = %f\n", __func__, *VRatioPrefetchY);
1308                         dml_print("DML::%s: SwathHeightY = %d\n", __func__, SwathHeightY);
1309                         dml_print("DML::%s: VInitPreFillY = %f\n", __func__, VInitPreFillY);
1310 #endif
1311                         if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
1312                                 if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
1313                                         *VRatioPrefetchY = dml_max(
1314                                                         (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData,
1315                                                         (double) MaxNumSwathY * SwathHeightY / (LinesToRequestPrefetchPixelData - (VInitPreFillY - 3.0) / 2.0));
1316                                         *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1317                                 } else {
1318                                         MyError = true;
1319                                         dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1320                                         *VRatioPrefetchY = 0;
1321                                 }
1322 #ifdef __DML_VBA_DEBUG__
1323                                 dml_print("DML::%s: VRatioPrefetchY = %f\n", __func__, *VRatioPrefetchY);
1324                                 dml_print("DML::%s: PrefetchSourceLinesY = %f\n", __func__, PrefetchSourceLinesY);
1325                                 dml_print("DML::%s: MaxNumSwathY = %d\n", __func__, MaxNumSwathY);
1326 #endif
1327                         }
1328
1329                         *VRatioPrefetchC = (double) PrefetchSourceLinesC / LinesToRequestPrefetchPixelData;
1330                         *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1331
1332 #ifdef __DML_VBA_DEBUG__
1333                         dml_print("DML::%s: VRatioPrefetchC = %f\n", __func__, *VRatioPrefetchC);
1334                         dml_print("DML::%s: SwathHeightC = %d\n", __func__, SwathHeightC);
1335                         dml_print("DML::%s: VInitPreFillC = %f\n", __func__, VInitPreFillC);
1336 #endif
1337                         if ((SwathHeightC > 4) || VInitPreFillC > 3) {
1338                                 if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
1339                                         *VRatioPrefetchC = dml_max(
1340                                                         *VRatioPrefetchC,
1341                                                         (double) MaxNumSwathC * SwathHeightC / (LinesToRequestPrefetchPixelData - (VInitPreFillC - 3.0) / 2.0));
1342                                         *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1343                                 } else {
1344                                         MyError = true;
1345                                         dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1346                                         *VRatioPrefetchC = 0;
1347                                 }
1348 #ifdef __DML_VBA_DEBUG__
1349                                 dml_print("DML::%s: VRatioPrefetchC = %f\n", __func__, *VRatioPrefetchC);
1350                                 dml_print("DML::%s: PrefetchSourceLinesC = %f\n", __func__, PrefetchSourceLinesC);
1351                                 dml_print("DML::%s: MaxNumSwathC = %d\n", __func__, MaxNumSwathC);
1352 #endif
1353                         }
1354
1355 #ifdef __DML_VBA_DEBUG__
1356                         dml_print("DML::%s: BytePerPixelY = %d\n", __func__, myPipe->BytePerPixelY);
1357                         dml_print("DML::%s: swath_width_luma_ub = %d\n", __func__, swath_width_luma_ub);
1358                         dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
1359 #endif
1360
1361                         *RequiredPrefetchPixDataBWLuma = (double) PrefetchSourceLinesY / LinesToRequestPrefetchPixelData * myPipe->BytePerPixelY * swath_width_luma_ub / LineTime;
1362
1363 #ifdef __DML_VBA_DEBUG__
1364                         dml_print("DML::%s: RequiredPrefetchPixDataBWLuma = %f\n", __func__, *RequiredPrefetchPixDataBWLuma);
1365 #endif
1366
1367                         *RequiredPrefetchPixDataBWChroma = (double) PrefetchSourceLinesC / LinesToRequestPrefetchPixelData * myPipe->BytePerPixelC * swath_width_chroma_ub
1368                                         / LineTime;
1369                 } else {
1370                         MyError = true;
1371                         dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1372                         dml_print("DML: LinesToRequestPrefetchPixelData: %f, should be > 0\n", LinesToRequestPrefetchPixelData);
1373                         *VRatioPrefetchY = 0;
1374                         *VRatioPrefetchC = 0;
1375                         *RequiredPrefetchPixDataBWLuma = 0;
1376                         *RequiredPrefetchPixDataBWChroma = 0;
1377                 }
1378
1379                 dml_print(
1380                                 "DML: Tpre: %fus - sum of time to request meta pte, 2 x data pte + meta data, swaths\n",
1381                                 (double) LinesToRequestPrefetchPixelData * LineTime + 2.0 * TimeForFetchingRowInVBlank + TimeForFetchingMetaPTE);
1382                 dml_print("DML:  Tvm: %fus - time to fetch page tables for meta surface\n", TimeForFetchingMetaPTE);
1383                 dml_print("DML:  Tr0: %fus - time to fetch first row of data pagetables and first row of meta data (done in parallel)\n", TimeForFetchingRowInVBlank);
1384                 dml_print(
1385                                 "DML:  Tsw: %fus = time to fetch enough pixel data and cursor data to feed the scalers init position and detile\n",
1386                                 (double) LinesToRequestPrefetchPixelData * LineTime);
1387                 dml_print("DML: To: %fus - time for propagation from scaler to optc\n",
1388                           (*DSTYAfterScaler + ((double) (*DSTXAfterScaler) /
1389                           (double) myPipe->HTotal)) * LineTime);
1390                 dml_print("DML: Tvstartup - TSetup - Tcalc - Twait - Tpre - To > 0\n");
1391                 dml_print("DML: Tslack(pre): %fus - time left over in schedule\n",
1392                                 VStartup * LineTime - TimeForFetchingMetaPTE - 2 * TimeForFetchingRowInVBlank
1393                                                 - (*DSTYAfterScaler + ((double) (*DSTXAfterScaler) / (double) myPipe->HTotal)) * LineTime - TWait - TCalc - *TSetup);
1394                 dml_print("DML: row_bytes = dpte_row_bytes (per_pipe) = PixelPTEBytesPerRow = : %d\n", PixelPTEBytesPerRow);
1395
1396         } else {
1397                 MyError = true;
1398                 dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1399         }
1400
1401         {
1402                 double prefetch_vm_bw;
1403                 double prefetch_row_bw;
1404
1405                 if (PDEAndMetaPTEBytesFrame == 0) {
1406                         prefetch_vm_bw = 0;
1407                 } else if (*DestinationLinesToRequestVMInVBlank > 0) {
1408 #ifdef __DML_VBA_DEBUG__
1409                         dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, PDEAndMetaPTEBytesFrame);
1410                         dml_print("DML::%s: HostVMInefficiencyFactor = %f\n", __func__, HostVMInefficiencyFactor);
1411                         dml_print("DML::%s: DestinationLinesToRequestVMInVBlank = %f\n", __func__, *DestinationLinesToRequestVMInVBlank);
1412                         dml_print("DML::%s: LineTime = %f\n", __func__, LineTime);
1413 #endif
1414                         prefetch_vm_bw = PDEAndMetaPTEBytesFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInVBlank * LineTime);
1415 #ifdef __DML_VBA_DEBUG__
1416                         dml_print("DML::%s: prefetch_vm_bw = %f\n", __func__, prefetch_vm_bw);
1417 #endif
1418                 } else {
1419                         prefetch_vm_bw = 0;
1420                         MyError = true;
1421                         dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1422                 }
1423
1424                 if (MetaRowByte + PixelPTEBytesPerRow == 0) {
1425                         prefetch_row_bw = 0;
1426                 } else if (*DestinationLinesToRequestRowInVBlank > 0) {
1427                         prefetch_row_bw = (MetaRowByte + PixelPTEBytesPerRow * HostVMInefficiencyFactor) / (*DestinationLinesToRequestRowInVBlank * LineTime);
1428
1429 #ifdef __DML_VBA_DEBUG__
1430                         dml_print("DML::%s: MetaRowByte = %d\n", __func__, MetaRowByte);
1431                         dml_print("DML::%s: PixelPTEBytesPerRow = %d\n", __func__, PixelPTEBytesPerRow);
1432                         dml_print("DML::%s: DestinationLinesToRequestRowInVBlank = %f\n", __func__, *DestinationLinesToRequestRowInVBlank);
1433                         dml_print("DML::%s: prefetch_row_bw = %f\n", __func__, prefetch_row_bw);
1434 #endif
1435                 } else {
1436                         prefetch_row_bw = 0;
1437                         MyError = true;
1438                         dml_print("DML: MyErr set %s:%d\n", __FILE__, __LINE__);
1439                 }
1440
1441                 *prefetch_vmrow_bw = dml_max(prefetch_vm_bw, prefetch_row_bw);
1442         }
1443
1444         if (MyError) {
1445                 *PrefetchBandwidth = 0;
1446                 TimeForFetchingMetaPTE = 0;
1447                 TimeForFetchingRowInVBlank = 0;
1448                 *DestinationLinesToRequestVMInVBlank = 0;
1449                 *DestinationLinesToRequestRowInVBlank = 0;
1450                 *DestinationLinesForPrefetch = 0;
1451                 LinesToRequestPrefetchPixelData = 0;
1452                 *VRatioPrefetchY = 0;
1453                 *VRatioPrefetchC = 0;
1454                 *RequiredPrefetchPixDataBWLuma = 0;
1455                 *RequiredPrefetchPixDataBWChroma = 0;
1456         }
1457
1458         return MyError;
1459 }
1460
1461 static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
1462 {
1463         return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
1464 }
1465
1466 static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
1467 {
1468         return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4.0 / Clock, 1);
1469 }
1470
1471 static void CalculateDCCConfiguration(
1472                 bool DCCEnabled,
1473                 bool DCCProgrammingAssumesScanDirectionUnknown,
1474                 enum source_format_class SourcePixelFormat,
1475                 unsigned int SurfaceWidthLuma,
1476                 unsigned int SurfaceWidthChroma,
1477                 unsigned int SurfaceHeightLuma,
1478                 unsigned int SurfaceHeightChroma,
1479                 double DETBufferSize,
1480                 unsigned int RequestHeight256ByteLuma,
1481                 unsigned int RequestHeight256ByteChroma,
1482                 enum dm_swizzle_mode TilingFormat,
1483                 unsigned int BytePerPixelY,
1484                 unsigned int BytePerPixelC,
1485                 double BytePerPixelDETY,
1486                 double BytePerPixelDETC,
1487                 enum scan_direction_class ScanOrientation,
1488                 unsigned int *MaxUncompressedBlockLuma,
1489                 unsigned int *MaxUncompressedBlockChroma,
1490                 unsigned int *MaxCompressedBlockLuma,
1491                 unsigned int *MaxCompressedBlockChroma,
1492                 unsigned int *IndependentBlockLuma,
1493                 unsigned int *IndependentBlockChroma)
1494 {
1495         int yuv420;
1496         int horz_div_l;
1497         int horz_div_c;
1498         int vert_div_l;
1499         int vert_div_c;
1500
1501         int swath_buf_size;
1502         double detile_buf_vp_horz_limit;
1503         double detile_buf_vp_vert_limit;
1504
1505         int MAS_vp_horz_limit;
1506         int MAS_vp_vert_limit;
1507         int max_vp_horz_width;
1508         int max_vp_vert_height;
1509         int eff_surf_width_l;
1510         int eff_surf_width_c;
1511         int eff_surf_height_l;
1512         int eff_surf_height_c;
1513
1514         int full_swath_bytes_horz_wc_l;
1515         int full_swath_bytes_horz_wc_c;
1516         int full_swath_bytes_vert_wc_l;
1517         int full_swath_bytes_vert_wc_c;
1518         int req128_horz_wc_l;
1519         int req128_horz_wc_c;
1520         int req128_vert_wc_l;
1521         int req128_vert_wc_c;
1522         int segment_order_horz_contiguous_luma;
1523         int segment_order_horz_contiguous_chroma;
1524         int segment_order_vert_contiguous_luma;
1525         int segment_order_vert_contiguous_chroma;
1526
1527         typedef enum {
1528                 REQ_256Bytes, REQ_128BytesNonContiguous, REQ_128BytesContiguous, REQ_NA
1529         } RequestType;
1530         RequestType RequestLuma;
1531         RequestType RequestChroma;
1532
1533         yuv420 = ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12) ? 1 : 0);
1534         horz_div_l = 1;
1535         horz_div_c = 1;
1536         vert_div_l = 1;
1537         vert_div_c = 1;
1538
1539         if (BytePerPixelY == 1)
1540                 vert_div_l = 0;
1541         if (BytePerPixelC == 1)
1542                 vert_div_c = 0;
1543         if (BytePerPixelY == 8 && (TilingFormat == dm_sw_64kb_s || TilingFormat == dm_sw_64kb_s_t || TilingFormat == dm_sw_64kb_s_x))
1544                 horz_div_l = 0;
1545         if (BytePerPixelC == 8 && (TilingFormat == dm_sw_64kb_s || TilingFormat == dm_sw_64kb_s_t || TilingFormat == dm_sw_64kb_s_x))
1546                 horz_div_c = 0;
1547
1548         if (BytePerPixelC == 0) {
1549                 swath_buf_size = DETBufferSize / 2 - 2 * 256;
1550                 detile_buf_vp_horz_limit = (double) swath_buf_size / ((double) RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l));
1551                 detile_buf_vp_vert_limit = (double) swath_buf_size / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l));
1552         } else {
1553                 swath_buf_size = DETBufferSize / 2 - 2 * 2 * 256;
1554                 detile_buf_vp_horz_limit = (double) swath_buf_size
1555                                 / ((double) RequestHeight256ByteLuma * BytePerPixelY / (1 + horz_div_l)
1556                                                 + (double) RequestHeight256ByteChroma * BytePerPixelC / (1 + horz_div_c) / (1 + yuv420));
1557                 detile_buf_vp_vert_limit = (double) swath_buf_size
1558                                 / (256.0 / RequestHeight256ByteLuma / (1 + vert_div_l) + 256.0 / RequestHeight256ByteChroma / (1 + vert_div_c) / (1 + yuv420));
1559         }
1560
1561         if (SourcePixelFormat == dm_420_10) {
1562                 detile_buf_vp_horz_limit = 1.5 * detile_buf_vp_horz_limit;
1563                 detile_buf_vp_vert_limit = 1.5 * detile_buf_vp_vert_limit;
1564         }
1565
1566         detile_buf_vp_horz_limit = dml_floor(detile_buf_vp_horz_limit - 1, 16);
1567         detile_buf_vp_vert_limit = dml_floor(detile_buf_vp_vert_limit - 1, 16);
1568
1569         MAS_vp_horz_limit = SourcePixelFormat == dm_rgbe_alpha ? 3840 : 5760;
1570         MAS_vp_vert_limit = (BytePerPixelC > 0 ? 2880 : 5760);
1571         max_vp_horz_width = dml_min((double) MAS_vp_horz_limit, detile_buf_vp_horz_limit);
1572         max_vp_vert_height = dml_min((double) MAS_vp_vert_limit, detile_buf_vp_vert_limit);
1573         eff_surf_width_l = (SurfaceWidthLuma > max_vp_horz_width ? max_vp_horz_width : SurfaceWidthLuma);
1574         eff_surf_width_c = eff_surf_width_l / (1 + yuv420);
1575         eff_surf_height_l = (SurfaceHeightLuma > max_vp_vert_height ? max_vp_vert_height : SurfaceHeightLuma);
1576         eff_surf_height_c = eff_surf_height_l / (1 + yuv420);
1577
1578         full_swath_bytes_horz_wc_l = eff_surf_width_l * RequestHeight256ByteLuma * BytePerPixelY;
1579         full_swath_bytes_vert_wc_l = eff_surf_height_l * 256 / RequestHeight256ByteLuma;
1580         if (BytePerPixelC > 0) {
1581                 full_swath_bytes_horz_wc_c = eff_surf_width_c * RequestHeight256ByteChroma * BytePerPixelC;
1582                 full_swath_bytes_vert_wc_c = eff_surf_height_c * 256 / RequestHeight256ByteChroma;
1583         } else {
1584                 full_swath_bytes_horz_wc_c = 0;
1585                 full_swath_bytes_vert_wc_c = 0;
1586         }
1587
1588         if (SourcePixelFormat == dm_420_10) {
1589                 full_swath_bytes_horz_wc_l = dml_ceil(full_swath_bytes_horz_wc_l * 2 / 3, 256);
1590                 full_swath_bytes_horz_wc_c = dml_ceil(full_swath_bytes_horz_wc_c * 2 / 3, 256);
1591                 full_swath_bytes_vert_wc_l = dml_ceil(full_swath_bytes_vert_wc_l * 2 / 3, 256);
1592                 full_swath_bytes_vert_wc_c = dml_ceil(full_swath_bytes_vert_wc_c * 2 / 3, 256);
1593         }
1594
1595         if (2 * full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSize) {
1596                 req128_horz_wc_l = 0;
1597                 req128_horz_wc_c = 0;
1598         } else if (full_swath_bytes_horz_wc_l < 1.5 * full_swath_bytes_horz_wc_c && 2 * full_swath_bytes_horz_wc_l + full_swath_bytes_horz_wc_c <= DETBufferSize) {
1599                 req128_horz_wc_l = 0;
1600                 req128_horz_wc_c = 1;
1601         } else if (full_swath_bytes_horz_wc_l >= 1.5 * full_swath_bytes_horz_wc_c && full_swath_bytes_horz_wc_l + 2 * full_swath_bytes_horz_wc_c <= DETBufferSize) {
1602                 req128_horz_wc_l = 1;
1603                 req128_horz_wc_c = 0;
1604         } else {
1605                 req128_horz_wc_l = 1;
1606                 req128_horz_wc_c = 1;
1607         }
1608
1609         if (2 * full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSize) {
1610                 req128_vert_wc_l = 0;
1611                 req128_vert_wc_c = 0;
1612         } else if (full_swath_bytes_vert_wc_l < 1.5 * full_swath_bytes_vert_wc_c && 2 * full_swath_bytes_vert_wc_l + full_swath_bytes_vert_wc_c <= DETBufferSize) {
1613                 req128_vert_wc_l = 0;
1614                 req128_vert_wc_c = 1;
1615         } else if (full_swath_bytes_vert_wc_l >= 1.5 * full_swath_bytes_vert_wc_c && full_swath_bytes_vert_wc_l + 2 * full_swath_bytes_vert_wc_c <= DETBufferSize) {
1616                 req128_vert_wc_l = 1;
1617                 req128_vert_wc_c = 0;
1618         } else {
1619                 req128_vert_wc_l = 1;
1620                 req128_vert_wc_c = 1;
1621         }
1622
1623         if (BytePerPixelY == 2 || (BytePerPixelY == 4 && TilingFormat != dm_sw_64kb_r_x)) {
1624                 segment_order_horz_contiguous_luma = 0;
1625         } else {
1626                 segment_order_horz_contiguous_luma = 1;
1627         }
1628         if ((BytePerPixelY == 8 && (TilingFormat == dm_sw_64kb_d || TilingFormat == dm_sw_64kb_d_x || TilingFormat == dm_sw_64kb_d_t || TilingFormat == dm_sw_64kb_r_x))
1629                         || (BytePerPixelY == 4 && TilingFormat == dm_sw_64kb_r_x)) {
1630                 segment_order_vert_contiguous_luma = 0;
1631         } else {
1632                 segment_order_vert_contiguous_luma = 1;
1633         }
1634         if (BytePerPixelC == 2 || (BytePerPixelC == 4 && TilingFormat != dm_sw_64kb_r_x)) {
1635                 segment_order_horz_contiguous_chroma = 0;
1636         } else {
1637                 segment_order_horz_contiguous_chroma = 1;
1638         }
1639         if ((BytePerPixelC == 8 && (TilingFormat == dm_sw_64kb_d || TilingFormat == dm_sw_64kb_d_x || TilingFormat == dm_sw_64kb_d_t || TilingFormat == dm_sw_64kb_r_x))
1640                         || (BytePerPixelC == 4 && TilingFormat == dm_sw_64kb_r_x)) {
1641                 segment_order_vert_contiguous_chroma = 0;
1642         } else {
1643                 segment_order_vert_contiguous_chroma = 1;
1644         }
1645
1646         if (DCCProgrammingAssumesScanDirectionUnknown == true) {
1647                 if (req128_horz_wc_l == 0 && req128_vert_wc_l == 0) {
1648                         RequestLuma = REQ_256Bytes;
1649                 } else if ((req128_horz_wc_l == 1 && segment_order_horz_contiguous_luma == 0) || (req128_vert_wc_l == 1 && segment_order_vert_contiguous_luma == 0)) {
1650                         RequestLuma = REQ_128BytesNonContiguous;
1651                 } else {
1652                         RequestLuma = REQ_128BytesContiguous;
1653                 }
1654                 if (req128_horz_wc_c == 0 && req128_vert_wc_c == 0) {
1655                         RequestChroma = REQ_256Bytes;
1656                 } else if ((req128_horz_wc_c == 1 && segment_order_horz_contiguous_chroma == 0) || (req128_vert_wc_c == 1 && segment_order_vert_contiguous_chroma == 0)) {
1657                         RequestChroma = REQ_128BytesNonContiguous;
1658                 } else {
1659                         RequestChroma = REQ_128BytesContiguous;
1660                 }
1661         } else if (ScanOrientation != dm_vert) {
1662                 if (req128_horz_wc_l == 0) {
1663                         RequestLuma = REQ_256Bytes;
1664                 } else if (segment_order_horz_contiguous_luma == 0) {
1665                         RequestLuma = REQ_128BytesNonContiguous;
1666                 } else {
1667                         RequestLuma = REQ_128BytesContiguous;
1668                 }
1669                 if (req128_horz_wc_c == 0) {
1670                         RequestChroma = REQ_256Bytes;
1671                 } else if (segment_order_horz_contiguous_chroma == 0) {
1672                         RequestChroma = REQ_128BytesNonContiguous;
1673                 } else {
1674                         RequestChroma = REQ_128BytesContiguous;
1675                 }
1676         } else {
1677                 if (req128_vert_wc_l == 0) {
1678                         RequestLuma = REQ_256Bytes;
1679                 } else if (segment_order_vert_contiguous_luma == 0) {
1680                         RequestLuma = REQ_128BytesNonContiguous;
1681                 } else {
1682                         RequestLuma = REQ_128BytesContiguous;
1683                 }
1684                 if (req128_vert_wc_c == 0) {
1685                         RequestChroma = REQ_256Bytes;
1686                 } else if (segment_order_vert_contiguous_chroma == 0) {
1687                         RequestChroma = REQ_128BytesNonContiguous;
1688                 } else {
1689                         RequestChroma = REQ_128BytesContiguous;
1690                 }
1691         }
1692
1693         if (RequestLuma == REQ_256Bytes) {
1694                 *MaxUncompressedBlockLuma = 256;
1695                 *MaxCompressedBlockLuma = 256;
1696                 *IndependentBlockLuma = 0;
1697         } else if (RequestLuma == REQ_128BytesContiguous) {
1698                 *MaxUncompressedBlockLuma = 256;
1699                 *MaxCompressedBlockLuma = 128;
1700                 *IndependentBlockLuma = 128;
1701         } else {
1702                 *MaxUncompressedBlockLuma = 256;
1703                 *MaxCompressedBlockLuma = 64;
1704                 *IndependentBlockLuma = 64;
1705         }
1706
1707         if (RequestChroma == REQ_256Bytes) {
1708                 *MaxUncompressedBlockChroma = 256;
1709                 *MaxCompressedBlockChroma = 256;
1710                 *IndependentBlockChroma = 0;
1711         } else if (RequestChroma == REQ_128BytesContiguous) {
1712                 *MaxUncompressedBlockChroma = 256;
1713                 *MaxCompressedBlockChroma = 128;
1714                 *IndependentBlockChroma = 128;
1715         } else {
1716                 *MaxUncompressedBlockChroma = 256;
1717                 *MaxCompressedBlockChroma = 64;
1718                 *IndependentBlockChroma = 64;
1719         }
1720
1721         if (DCCEnabled != true || BytePerPixelC == 0) {
1722                 *MaxUncompressedBlockChroma = 0;
1723                 *MaxCompressedBlockChroma = 0;
1724                 *IndependentBlockChroma = 0;
1725         }
1726
1727         if (DCCEnabled != true) {
1728                 *MaxUncompressedBlockLuma = 0;
1729                 *MaxCompressedBlockLuma = 0;
1730                 *IndependentBlockLuma = 0;
1731         }
1732 }
1733
1734 static double CalculatePrefetchSourceLines(
1735                 struct display_mode_lib *mode_lib,
1736                 double VRatio,
1737                 double vtaps,
1738                 bool Interlace,
1739                 bool ProgressiveToInterlaceUnitInOPP,
1740                 unsigned int SwathHeight,
1741                 unsigned int ViewportYStart,
1742                 double *VInitPreFill,
1743                 unsigned int *MaxNumSwath)
1744 {
1745         struct vba_vars_st *v = &mode_lib->vba;
1746         unsigned int MaxPartialSwath;
1747
1748         if (ProgressiveToInterlaceUnitInOPP)
1749                 *VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
1750         else
1751                 *VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
1752
1753         if (!v->IgnoreViewportPositioning) {
1754
1755                 *MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
1756
1757                 if (*VInitPreFill > 1.0)
1758                         MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
1759                 else
1760                         MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2) % SwathHeight;
1761                 MaxPartialSwath = dml_max(1U, MaxPartialSwath);
1762
1763         } else {
1764
1765                 if (ViewportYStart != 0)
1766                         dml_print("WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
1767
1768                 *MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
1769
1770                 if (*VInitPreFill > 1.0)
1771                         MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
1772                 else
1773                         MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1) % SwathHeight;
1774         }
1775
1776 #ifdef __DML_VBA_DEBUG__
1777         dml_print("DML::%s: VRatio = %f\n", __func__, VRatio);
1778         dml_print("DML::%s: vtaps = %f\n", __func__, vtaps);
1779         dml_print("DML::%s: VInitPreFill = %f\n", __func__, *VInitPreFill);
1780         dml_print("DML::%s: ProgressiveToInterlaceUnitInOPP = %d\n", __func__, ProgressiveToInterlaceUnitInOPP);
1781         dml_print("DML::%s: IgnoreViewportPositioning = %d\n", __func__, v->IgnoreViewportPositioning);
1782         dml_print("DML::%s: SwathHeight = %d\n", __func__, SwathHeight);
1783         dml_print("DML::%s: MaxPartialSwath = %d\n", __func__, MaxPartialSwath);
1784         dml_print("DML::%s: MaxNumSwath = %d\n", __func__, *MaxNumSwath);
1785         dml_print("DML::%s: Prefetch source lines = %d\n", __func__, *MaxNumSwath * SwathHeight + MaxPartialSwath);
1786 #endif
1787         return *MaxNumSwath * SwathHeight + MaxPartialSwath;
1788 }
1789
1790 static unsigned int CalculateVMAndRowBytes(
1791                 struct display_mode_lib *mode_lib,
1792                 bool DCCEnable,
1793                 unsigned int BlockHeight256Bytes,
1794                 unsigned int BlockWidth256Bytes,
1795                 enum source_format_class SourcePixelFormat,
1796                 unsigned int SurfaceTiling,
1797                 unsigned int BytePerPixel,
1798                 enum scan_direction_class ScanDirection,
1799                 unsigned int SwathWidth,
1800                 unsigned int ViewportHeight,
1801                 bool GPUVMEnable,
1802                 bool HostVMEnable,
1803                 unsigned int HostVMMaxNonCachedPageTableLevels,
1804                 unsigned int GPUVMMinPageSize,
1805                 unsigned int HostVMMinPageSize,
1806                 unsigned int PTEBufferSizeInRequests,
1807                 unsigned int Pitch,
1808                 unsigned int DCCMetaPitch,
1809                 unsigned int *MacroTileWidth,
1810                 unsigned int *MetaRowByte,
1811                 unsigned int *PixelPTEBytesPerRow,
1812                 bool *PTEBufferSizeNotExceeded,
1813                 int *dpte_row_width_ub,
1814                 unsigned int *dpte_row_height,
1815                 unsigned int *MetaRequestWidth,
1816                 unsigned int *MetaRequestHeight,
1817                 unsigned int *meta_row_width,
1818                 unsigned int *meta_row_height,
1819                 int *vm_group_bytes,
1820                 unsigned int *dpte_group_bytes,
1821                 unsigned int *PixelPTEReqWidth,
1822                 unsigned int *PixelPTEReqHeight,
1823                 unsigned int *PTERequestSize,
1824                 int *DPDE0BytesFrame,
1825                 int *MetaPTEBytesFrame)
1826 {
1827         struct vba_vars_st *v = &mode_lib->vba;
1828         unsigned int MPDEBytesFrame;
1829         unsigned int DCCMetaSurfaceBytes;
1830         unsigned int MacroTileSizeBytes;
1831         unsigned int MacroTileHeight;
1832         unsigned int ExtraDPDEBytesFrame;
1833         unsigned int PDEAndMetaPTEBytesFrame;
1834         unsigned int PixelPTEReqHeightPTEs = 0;
1835         unsigned int HostVMDynamicLevels = 0;
1836         double FractionOfPTEReturnDrop;
1837
1838         if (GPUVMEnable == true && HostVMEnable == true) {
1839                 if (HostVMMinPageSize < 2048) {
1840                         HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
1841                 } else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576) {
1842                         HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 1);
1843                 } else {
1844                         HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 2);
1845                 }
1846         }
1847
1848         *MetaRequestHeight = 8 * BlockHeight256Bytes;
1849         *MetaRequestWidth = 8 * BlockWidth256Bytes;
1850         if (ScanDirection != dm_vert) {
1851                 *meta_row_height = *MetaRequestHeight;
1852                 *meta_row_width = dml_ceil((double) SwathWidth - 1, *MetaRequestWidth) + *MetaRequestWidth;
1853                 *MetaRowByte = *meta_row_width * *MetaRequestHeight * BytePerPixel / 256.0;
1854         } else {
1855                 *meta_row_height = *MetaRequestWidth;
1856                 *meta_row_width = dml_ceil((double) SwathWidth - 1, *MetaRequestHeight) + *MetaRequestHeight;
1857                 *MetaRowByte = *meta_row_width * *MetaRequestWidth * BytePerPixel / 256.0;
1858         }
1859         DCCMetaSurfaceBytes = DCCMetaPitch * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes) + 64 * BlockHeight256Bytes) * BytePerPixel / 256;
1860         if (GPUVMEnable == true) {
1861                 *MetaPTEBytesFrame = (dml_ceil((double) (DCCMetaSurfaceBytes - 4.0 * 1024.0) / (8 * 4.0 * 1024), 1) + 1) * 64;
1862                 MPDEBytesFrame = 128 * (v->GPUVMMaxPageTableLevels - 1);
1863         } else {
1864                 *MetaPTEBytesFrame = 0;
1865                 MPDEBytesFrame = 0;
1866         }
1867
1868         if (DCCEnable != true) {
1869                 *MetaPTEBytesFrame = 0;
1870                 MPDEBytesFrame = 0;
1871                 *MetaRowByte = 0;
1872         }
1873
1874         if (SurfaceTiling == dm_sw_linear) {
1875                 MacroTileSizeBytes = 256;
1876                 MacroTileHeight = BlockHeight256Bytes;
1877         } else {
1878                 MacroTileSizeBytes = 65536;
1879                 MacroTileHeight = 16 * BlockHeight256Bytes;
1880         }
1881         *MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
1882
1883         if (GPUVMEnable == true && v->GPUVMMaxPageTableLevels > 1) {
1884                 if (ScanDirection != dm_vert) {
1885                         *DPDE0BytesFrame = 64
1886                                         * (dml_ceil(
1887                                                         ((Pitch * (dml_ceil(ViewportHeight - 1, MacroTileHeight) + MacroTileHeight) * BytePerPixel) - MacroTileSizeBytes)
1888                                                                         / (8 * 2097152),
1889                                                         1) + 1);
1890                 } else {
1891                         *DPDE0BytesFrame = 64
1892                                         * (dml_ceil(
1893                                                         ((Pitch * (dml_ceil((double) SwathWidth - 1, MacroTileHeight) + MacroTileHeight) * BytePerPixel) - MacroTileSizeBytes)
1894                                                                         / (8 * 2097152),
1895                                                         1) + 1);
1896                 }
1897                 ExtraDPDEBytesFrame = 128 * (v->GPUVMMaxPageTableLevels - 2);
1898         } else {
1899                 *DPDE0BytesFrame = 0;
1900                 ExtraDPDEBytesFrame = 0;
1901         }
1902
1903         PDEAndMetaPTEBytesFrame = *MetaPTEBytesFrame + MPDEBytesFrame + *DPDE0BytesFrame + ExtraDPDEBytesFrame;
1904
1905 #ifdef __DML_VBA_DEBUG__
1906         dml_print("DML::%s: MetaPTEBytesFrame = %d\n", __func__, *MetaPTEBytesFrame);
1907         dml_print("DML::%s: MPDEBytesFrame = %d\n", __func__, MPDEBytesFrame);
1908         dml_print("DML::%s: DPDE0BytesFrame = %d\n", __func__, *DPDE0BytesFrame);
1909         dml_print("DML::%s: ExtraDPDEBytesFrame= %d\n", __func__, ExtraDPDEBytesFrame);
1910         dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, PDEAndMetaPTEBytesFrame);
1911 #endif
1912
1913         if (HostVMEnable == true) {
1914                 PDEAndMetaPTEBytesFrame = PDEAndMetaPTEBytesFrame * (1 + 8 * HostVMDynamicLevels);
1915         }
1916 #ifdef __DML_VBA_DEBUG__
1917         dml_print("DML::%s: PDEAndMetaPTEBytesFrame = %d\n", __func__, PDEAndMetaPTEBytesFrame);
1918 #endif
1919
1920         if (SurfaceTiling == dm_sw_linear) {
1921                 PixelPTEReqHeightPTEs = 1;
1922                 *PixelPTEReqHeight = 1;
1923                 *PixelPTEReqWidth = 32768.0 / BytePerPixel;
1924                 *PTERequestSize = 64;
1925                 FractionOfPTEReturnDrop = 0;
1926         } else if (MacroTileSizeBytes == 4096) {
1927                 PixelPTEReqHeightPTEs = 1;
1928                 *PixelPTEReqHeight = MacroTileHeight;
1929                 *PixelPTEReqWidth = 8 * *MacroTileWidth;
1930                 *PTERequestSize = 64;
1931                 if (ScanDirection != dm_vert)
1932                         FractionOfPTEReturnDrop = 0;
1933                 else
1934                         FractionOfPTEReturnDrop = 7 / 8;
1935         } else if (GPUVMMinPageSize == 4 && MacroTileSizeBytes > 4096) {
1936                 PixelPTEReqHeightPTEs = 16;
1937                 *PixelPTEReqHeight = 16 * BlockHeight256Bytes;
1938                 *PixelPTEReqWidth = 16 * BlockWidth256Bytes;
1939                 *PTERequestSize = 128;
1940                 FractionOfPTEReturnDrop = 0;
1941         } else {
1942                 PixelPTEReqHeightPTEs = 1;
1943                 *PixelPTEReqHeight = MacroTileHeight;
1944                 *PixelPTEReqWidth = 8 * *MacroTileWidth;
1945                 *PTERequestSize = 64;
1946                 FractionOfPTEReturnDrop = 0;
1947         }
1948
1949         if (SurfaceTiling == dm_sw_linear) {
1950                 *dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1));
1951                 *dpte_row_width_ub = (dml_ceil((double)(Pitch * *dpte_row_height - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
1952                 *PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
1953         } else if (ScanDirection != dm_vert) {
1954                 *dpte_row_height = *PixelPTEReqHeight;
1955                 *dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth;
1956                 *PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize;
1957         } else {
1958                 *dpte_row_height = dml_min(*PixelPTEReqWidth, *MacroTileWidth);
1959                 *dpte_row_width_ub = (dml_ceil((double) (SwathWidth - 1) / *PixelPTEReqHeight, 1) + 1) * *PixelPTEReqHeight;
1960                 *PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqHeight * *PTERequestSize;
1961         }
1962
1963         if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop) <= 64 * PTEBufferSizeInRequests) {
1964                 *PTEBufferSizeNotExceeded = true;
1965         } else {
1966                 *PTEBufferSizeNotExceeded = false;
1967         }
1968
1969         if (GPUVMEnable != true) {
1970                 *PixelPTEBytesPerRow = 0;
1971                 *PTEBufferSizeNotExceeded = true;
1972         }
1973
1974         dml_print("DML: vm_bytes = meta_pte_bytes_per_frame (per_pipe) = MetaPTEBytesFrame = : %i\n", *MetaPTEBytesFrame);
1975
1976         if (HostVMEnable == true) {
1977                 *PixelPTEBytesPerRow = *PixelPTEBytesPerRow * (1 + 8 * HostVMDynamicLevels);
1978         }
1979
1980         if (HostVMEnable == true) {
1981                 *vm_group_bytes = 512;
1982                 *dpte_group_bytes = 512;
1983         } else if (GPUVMEnable == true) {
1984                 *vm_group_bytes = 2048;
1985                 if (SurfaceTiling != dm_sw_linear && PixelPTEReqHeightPTEs == 1 && ScanDirection == dm_vert) {
1986                         *dpte_group_bytes = 512;
1987                 } else {
1988                         *dpte_group_bytes = 2048;
1989                 }
1990         } else {
1991                 *vm_group_bytes = 0;
1992                 *dpte_group_bytes = 0;
1993         }
1994         return PDEAndMetaPTEBytesFrame;
1995 }
1996
1997 static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(struct display_mode_lib *mode_lib)
1998 {
1999         struct vba_vars_st *v = &mode_lib->vba;
2000         unsigned int j, k;
2001         double HostVMInefficiencyFactor = 1.0;
2002         bool NoChromaPlanes = true;
2003         int ReorderBytes;
2004         double VMDataOnlyReturnBW;
2005         double MaxTotalRDBandwidth = 0;
2006         int PrefetchMode = v->PrefetchModePerState[v->VoltageLevel][v->maxMpcComb];
2007
2008         v->WritebackDISPCLK = 0.0;
2009         v->DISPCLKWithRamping = 0;
2010         v->DISPCLKWithoutRamping = 0;
2011         v->GlobalDPPCLK = 0.0;
2012         /* DAL custom code: need to update ReturnBW in case min dcfclk is overriden */
2013         {
2014         double IdealFabricAndSDPPortBandwidthPerState = dml_min(
2015                         v->ReturnBusWidth * v->DCFCLKState[v->VoltageLevel][v->maxMpcComb],
2016                         v->FabricClockPerState[v->VoltageLevel] * v->FabricDatapathToDCNDataReturn);
2017         double IdealDRAMBandwidthPerState = v->DRAMSpeedPerState[v->VoltageLevel] * v->NumberOfChannels * v->DRAMChannelWidth;
2018         if (v->HostVMEnable != true) {
2019                 v->ReturnBW = dml_min(
2020                                 IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
2021                                 IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly / 100.0);
2022         } else {
2023                 v->ReturnBW = dml_min(
2024                                 IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
2025                                 IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0);
2026         }
2027         }
2028         /* End DAL custom code */
2029
2030         // DISPCLK and DPPCLK Calculation
2031         //
2032         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2033                 if (v->WritebackEnable[k]) {
2034                         v->WritebackDISPCLK = dml_max(
2035                                         v->WritebackDISPCLK,
2036                                         dml31_CalculateWriteBackDISPCLK(
2037                                                         v->WritebackPixelFormat[k],
2038                                                         v->PixelClock[k],
2039                                                         v->WritebackHRatio[k],
2040                                                         v->WritebackVRatio[k],
2041                                                         v->WritebackHTaps[k],
2042                                                         v->WritebackVTaps[k],
2043                                                         v->WritebackSourceWidth[k],
2044                                                         v->WritebackDestinationWidth[k],
2045                                                         v->HTotal[k],
2046                                                         v->WritebackLineBufferSize));
2047                 }
2048         }
2049
2050         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2051                 if (v->HRatio[k] > 1) {
2052                         v->PSCL_THROUGHPUT_LUMA[k] = dml_min(
2053                                         v->MaxDCHUBToPSCLThroughput,
2054                                         v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1));
2055                 } else {
2056                         v->PSCL_THROUGHPUT_LUMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
2057                 }
2058
2059                 v->DPPCLKUsingSingleDPPLuma = v->PixelClock[k]
2060                                 * dml_max(
2061                                                 v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
2062                                                 dml_max(v->HRatio[k] * v->VRatio[k] / v->PSCL_THROUGHPUT_LUMA[k], 1.0));
2063
2064                 if ((v->htaps[k] > 6 || v->vtaps[k] > 6) && v->DPPCLKUsingSingleDPPLuma < 2 * v->PixelClock[k]) {
2065                         v->DPPCLKUsingSingleDPPLuma = 2 * v->PixelClock[k];
2066                 }
2067
2068                 if ((v->SourcePixelFormat[k] != dm_420_8 && v->SourcePixelFormat[k] != dm_420_10 && v->SourcePixelFormat[k] != dm_420_12
2069                                 && v->SourcePixelFormat[k] != dm_rgbe_alpha)) {
2070                         v->PSCL_THROUGHPUT_CHROMA[k] = 0.0;
2071                         v->DPPCLKUsingSingleDPP[k] = v->DPPCLKUsingSingleDPPLuma;
2072                 } else {
2073                         if (v->HRatioChroma[k] > 1) {
2074                                 v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(
2075                                                 v->MaxDCHUBToPSCLThroughput,
2076                                                 v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
2077                         } else {
2078                                 v->PSCL_THROUGHPUT_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
2079                         }
2080                         v->DPPCLKUsingSingleDPPChroma = v->PixelClock[k]
2081                                         * dml_max3(
2082                                                         v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
2083                                                         v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_THROUGHPUT_CHROMA[k],
2084                                                         1.0);
2085
2086                         if ((v->HTAPsChroma[k] > 6 || v->VTAPsChroma[k] > 6) && v->DPPCLKUsingSingleDPPChroma < 2 * v->PixelClock[k]) {
2087                                 v->DPPCLKUsingSingleDPPChroma = 2 * v->PixelClock[k];
2088                         }
2089
2090                         v->DPPCLKUsingSingleDPP[k] = dml_max(v->DPPCLKUsingSingleDPPLuma, v->DPPCLKUsingSingleDPPChroma);
2091                 }
2092         }
2093
2094         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2095                 if (v->BlendingAndTiming[k] != k)
2096                         continue;
2097                 if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1) {
2098                         v->DISPCLKWithRamping = dml_max(
2099                                         v->DISPCLKWithRamping,
2100                                         v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
2101                                                         * (1 + v->DISPCLKRampingMargin / 100));
2102                         v->DISPCLKWithoutRamping = dml_max(
2103                                         v->DISPCLKWithoutRamping,
2104                                         v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2105                 } else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
2106                         v->DISPCLKWithRamping = dml_max(
2107                                         v->DISPCLKWithRamping,
2108                                         v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100)
2109                                                         * (1 + v->DISPCLKRampingMargin / 100));
2110                         v->DISPCLKWithoutRamping = dml_max(
2111                                         v->DISPCLKWithoutRamping,
2112                                         v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2113                 } else {
2114                         v->DISPCLKWithRamping = dml_max(
2115                                         v->DISPCLKWithRamping,
2116                                         v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100) * (1 + v->DISPCLKRampingMargin / 100));
2117                         v->DISPCLKWithoutRamping = dml_max(
2118                                         v->DISPCLKWithoutRamping,
2119                                         v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100));
2120                 }
2121         }
2122
2123         v->DISPCLKWithRamping = dml_max(v->DISPCLKWithRamping, v->WritebackDISPCLK);
2124         v->DISPCLKWithoutRamping = dml_max(v->DISPCLKWithoutRamping, v->WritebackDISPCLK);
2125
2126         ASSERT(v->DISPCLKDPPCLKVCOSpeed != 0);
2127         v->DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(v->DISPCLKWithRamping, v->DISPCLKDPPCLKVCOSpeed);
2128         v->DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(v->DISPCLKWithoutRamping, v->DISPCLKDPPCLKVCOSpeed);
2129         v->MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
2130                         v->soc.clock_limits[v->soc.num_states - 1].dispclk_mhz,
2131                         v->DISPCLKDPPCLKVCOSpeed);
2132         if (v->DISPCLKWithoutRampingRoundedToDFSGranularity > v->MaxDispclkRoundedToDFSGranularity) {
2133                 v->DISPCLK_calculated = v->DISPCLKWithoutRampingRoundedToDFSGranularity;
2134         } else if (v->DISPCLKWithRampingRoundedToDFSGranularity > v->MaxDispclkRoundedToDFSGranularity) {
2135                 v->DISPCLK_calculated = v->MaxDispclkRoundedToDFSGranularity;
2136         } else {
2137                 v->DISPCLK_calculated = v->DISPCLKWithRampingRoundedToDFSGranularity;
2138         }
2139         v->DISPCLK = v->DISPCLK_calculated;
2140         DTRACE("   dispclk_mhz (calculated) = %f", v->DISPCLK_calculated);
2141
2142         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2143                 v->DPPCLK_calculated[k] = v->DPPCLKUsingSingleDPP[k] / v->DPPPerPlane[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2144                 v->GlobalDPPCLK = dml_max(v->GlobalDPPCLK, v->DPPCLK_calculated[k]);
2145         }
2146         v->GlobalDPPCLK = RoundToDFSGranularityUp(v->GlobalDPPCLK, v->DISPCLKDPPCLKVCOSpeed);
2147         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2148                 v->DPPCLK_calculated[k] = v->GlobalDPPCLK / 255 * dml_ceil(v->DPPCLK_calculated[k] * 255.0 / v->GlobalDPPCLK, 1);
2149                 DTRACE("   dppclk_mhz[%i] (calculated) = %f", k, v->DPPCLK_calculated[k]);
2150         }
2151
2152         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2153                 v->DPPCLK[k] = v->DPPCLK_calculated[k];
2154         }
2155
2156         // Urgent and B P-State/DRAM Clock Change Watermark
2157         DTRACE("   dcfclk_mhz         = %f", v->DCFCLK);
2158         DTRACE("   return_bus_bw      = %f", v->ReturnBW);
2159
2160         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2161                 dml30_CalculateBytePerPixelAnd256BBlockSizes(
2162                                 v->SourcePixelFormat[k],
2163                                 v->SurfaceTiling[k],
2164                                 &v->BytePerPixelY[k],
2165                                 &v->BytePerPixelC[k],
2166                                 &v->BytePerPixelDETY[k],
2167                                 &v->BytePerPixelDETC[k],
2168                                 &v->BlockHeight256BytesY[k],
2169                                 &v->BlockHeight256BytesC[k],
2170                                 &v->BlockWidth256BytesY[k],
2171                                 &v->BlockWidth256BytesC[k]);
2172         }
2173
2174         CalculateSwathWidth(
2175                         false,
2176                         v->NumberOfActivePlanes,
2177                         v->SourcePixelFormat,
2178                         v->SourceScan,
2179                         v->ViewportWidth,
2180                         v->ViewportHeight,
2181                         v->SurfaceWidthY,
2182                         v->SurfaceWidthC,
2183                         v->SurfaceHeightY,
2184                         v->SurfaceHeightC,
2185                         v->ODMCombineEnabled,
2186                         v->BytePerPixelY,
2187                         v->BytePerPixelC,
2188                         v->BlockHeight256BytesY,
2189                         v->BlockHeight256BytesC,
2190                         v->BlockWidth256BytesY,
2191                         v->BlockWidth256BytesC,
2192                         v->BlendingAndTiming,
2193                         v->HActive,
2194                         v->HRatio,
2195                         v->DPPPerPlane,
2196                         v->SwathWidthSingleDPPY,
2197                         v->SwathWidthSingleDPPC,
2198                         v->SwathWidthY,
2199                         v->SwathWidthC,
2200                         v->dummyinteger3,
2201                         v->dummyinteger4,
2202                         v->swath_width_luma_ub,
2203                         v->swath_width_chroma_ub);
2204
2205         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2206                 v->ReadBandwidthPlaneLuma[k] = v->SwathWidthSingleDPPY[k] * v->BytePerPixelY[k] / (v->HTotal[k] / v->PixelClock[k])
2207                                 * v->VRatio[k];
2208                 v->ReadBandwidthPlaneChroma[k] = v->SwathWidthSingleDPPC[k] * v->BytePerPixelC[k] / (v->HTotal[k] / v->PixelClock[k])
2209                                 * v->VRatioChroma[k];
2210                 DTRACE("   read_bw[%i] = %fBps", k, v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k]);
2211         }
2212
2213         // DCFCLK Deep Sleep
2214         CalculateDCFCLKDeepSleep(
2215                         mode_lib,
2216                         v->NumberOfActivePlanes,
2217                         v->BytePerPixelY,
2218                         v->BytePerPixelC,
2219                         v->VRatio,
2220                         v->VRatioChroma,
2221                         v->SwathWidthY,
2222                         v->SwathWidthC,
2223                         v->DPPPerPlane,
2224                         v->HRatio,
2225                         v->HRatioChroma,
2226                         v->PixelClock,
2227                         v->PSCL_THROUGHPUT_LUMA,
2228                         v->PSCL_THROUGHPUT_CHROMA,
2229                         v->DPPCLK,
2230                         v->ReadBandwidthPlaneLuma,
2231                         v->ReadBandwidthPlaneChroma,
2232                         v->ReturnBusWidth,
2233                         &v->DCFCLKDeepSleep);
2234
2235         // DSCCLK
2236         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2237                 if ((v->BlendingAndTiming[k] != k) || !v->DSCEnabled[k]) {
2238                         v->DSCCLK_calculated[k] = 0.0;
2239                 } else {
2240                         if (v->OutputFormat[k] == dm_420)
2241                                 v->DSCFormatFactor = 2;
2242                         else if (v->OutputFormat[k] == dm_444)
2243                                 v->DSCFormatFactor = 1;
2244                         else if (v->OutputFormat[k] == dm_n422)
2245                                 v->DSCFormatFactor = 2;
2246                         else
2247                                 v->DSCFormatFactor = 1;
2248                         if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1)
2249                                 v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 12 / v->DSCFormatFactor
2250                                                 / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2251                         else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
2252                                 v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 6 / v->DSCFormatFactor
2253                                                 / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2254                         else
2255                                 v->DSCCLK_calculated[k] = v->PixelClockBackEnd[k] / 3 / v->DSCFormatFactor
2256                                                 / (1 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100);
2257                 }
2258         }
2259
2260         // DSC Delay
2261         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2262                 double BPP = v->OutputBpp[k];
2263
2264                 if (v->DSCEnabled[k] && BPP != 0) {
2265                         if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_disabled) {
2266                                 v->DSCDelay[k] = dscceComputeDelay(
2267                                                 v->DSCInputBitPerComponent[k],
2268                                                 BPP,
2269                                                 dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2270                                                 v->NumberOfDSCSlices[k],
2271                                                 v->OutputFormat[k],
2272                                                 v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
2273                         } else if (v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
2274                                 v->DSCDelay[k] = 2
2275                                                 * (dscceComputeDelay(
2276                                                                 v->DSCInputBitPerComponent[k],
2277                                                                 BPP,
2278                                                                 dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2279                                                                 v->NumberOfDSCSlices[k] / 2.0,
2280                                                                 v->OutputFormat[k],
2281                                                                 v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
2282                         } else {
2283                                 v->DSCDelay[k] = 4
2284                                                 * (dscceComputeDelay(
2285                                                                 v->DSCInputBitPerComponent[k],
2286                                                                 BPP,
2287                                                                 dml_ceil((double) v->HActive[k] / v->NumberOfDSCSlices[k], 1),
2288                                                                 v->NumberOfDSCSlices[k] / 4.0,
2289                                                                 v->OutputFormat[k],
2290                                                                 v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
2291                         }
2292                         v->DSCDelay[k] = v->DSCDelay[k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
2293                 } else {
2294                         v->DSCDelay[k] = 0;
2295                 }
2296         }
2297
2298         for (k = 0; k < v->NumberOfActivePlanes; ++k)
2299                 for (j = 0; j < v->NumberOfActivePlanes; ++j) // NumberOfPlanes
2300                         if (j != k && v->BlendingAndTiming[k] == j && v->DSCEnabled[j])
2301                                 v->DSCDelay[k] = v->DSCDelay[j];
2302
2303         // Prefetch
2304         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2305                 unsigned int PDEAndMetaPTEBytesFrameY;
2306                 unsigned int PixelPTEBytesPerRowY;
2307                 unsigned int MetaRowByteY;
2308                 unsigned int MetaRowByteC;
2309                 unsigned int PDEAndMetaPTEBytesFrameC;
2310                 unsigned int PixelPTEBytesPerRowC;
2311                 bool PTEBufferSizeNotExceededY;
2312                 bool PTEBufferSizeNotExceededC;
2313
2314                 if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
2315                                 || v->SourcePixelFormat[k] == dm_rgbe_alpha) {
2316                         if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) && v->SourceScan[k] != dm_vert) {
2317                                 v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma) / 2;
2318                                 v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
2319                         } else {
2320                                 v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
2321                                 v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
2322                         }
2323
2324                         PDEAndMetaPTEBytesFrameC = CalculateVMAndRowBytes(
2325                                         mode_lib,
2326                                         v->DCCEnable[k],
2327                                         v->BlockHeight256BytesC[k],
2328                                         v->BlockWidth256BytesC[k],
2329                                         v->SourcePixelFormat[k],
2330                                         v->SurfaceTiling[k],
2331                                         v->BytePerPixelC[k],
2332                                         v->SourceScan[k],
2333                                         v->SwathWidthC[k],
2334                                         v->ViewportHeightChroma[k],
2335                                         v->GPUVMEnable,
2336                                         v->HostVMEnable,
2337                                         v->HostVMMaxNonCachedPageTableLevels,
2338                                         v->GPUVMMinPageSize,
2339                                         v->HostVMMinPageSize,
2340                                         v->PTEBufferSizeInRequestsForChroma,
2341                                         v->PitchC[k],
2342                                         v->DCCMetaPitchC[k],
2343                                         &v->MacroTileWidthC[k],
2344                                         &MetaRowByteC,
2345                                         &PixelPTEBytesPerRowC,
2346                                         &PTEBufferSizeNotExceededC,
2347                                         &v->dpte_row_width_chroma_ub[k],
2348                                         &v->dpte_row_height_chroma[k],
2349                                         &v->meta_req_width_chroma[k],
2350                                         &v->meta_req_height_chroma[k],
2351                                         &v->meta_row_width_chroma[k],
2352                                         &v->meta_row_height_chroma[k],
2353                                         &v->dummyinteger1,
2354                                         &v->dummyinteger2,
2355                                         &v->PixelPTEReqWidthC[k],
2356                                         &v->PixelPTEReqHeightC[k],
2357                                         &v->PTERequestSizeC[k],
2358                                         &v->dpde0_bytes_per_frame_ub_c[k],
2359                                         &v->meta_pte_bytes_per_frame_ub_c[k]);
2360
2361                         v->PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
2362                                         mode_lib,
2363                                         v->VRatioChroma[k],
2364                                         v->VTAPsChroma[k],
2365                                         v->Interlace[k],
2366                                         v->ProgressiveToInterlaceUnitInOPP,
2367                                         v->SwathHeightC[k],
2368                                         v->ViewportYStartC[k],
2369                                         &v->VInitPreFillC[k],
2370                                         &v->MaxNumSwathC[k]);
2371                 } else {
2372                         v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
2373                         v->PTEBufferSizeInRequestsForChroma = 0;
2374                         PixelPTEBytesPerRowC = 0;
2375                         PDEAndMetaPTEBytesFrameC = 0;
2376                         MetaRowByteC = 0;
2377                         v->MaxNumSwathC[k] = 0;
2378                         v->PrefetchSourceLinesC[k] = 0;
2379                 }
2380
2381                 PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
2382                                 mode_lib,
2383                                 v->DCCEnable[k],
2384                                 v->BlockHeight256BytesY[k],
2385                                 v->BlockWidth256BytesY[k],
2386                                 v->SourcePixelFormat[k],
2387                                 v->SurfaceTiling[k],
2388                                 v->BytePerPixelY[k],
2389                                 v->SourceScan[k],
2390                                 v->SwathWidthY[k],
2391                                 v->ViewportHeight[k],
2392                                 v->GPUVMEnable,
2393                                 v->HostVMEnable,
2394                                 v->HostVMMaxNonCachedPageTableLevels,
2395                                 v->GPUVMMinPageSize,
2396                                 v->HostVMMinPageSize,
2397                                 v->PTEBufferSizeInRequestsForLuma,
2398                                 v->PitchY[k],
2399                                 v->DCCMetaPitchY[k],
2400                                 &v->MacroTileWidthY[k],
2401                                 &MetaRowByteY,
2402                                 &PixelPTEBytesPerRowY,
2403                                 &PTEBufferSizeNotExceededY,
2404                                 &v->dpte_row_width_luma_ub[k],
2405                                 &v->dpte_row_height[k],
2406                                 &v->meta_req_width[k],
2407                                 &v->meta_req_height[k],
2408                                 &v->meta_row_width[k],
2409                                 &v->meta_row_height[k],
2410                                 &v->vm_group_bytes[k],
2411                                 &v->dpte_group_bytes[k],
2412                                 &v->PixelPTEReqWidthY[k],
2413                                 &v->PixelPTEReqHeightY[k],
2414                                 &v->PTERequestSizeY[k],
2415                                 &v->dpde0_bytes_per_frame_ub_l[k],
2416                                 &v->meta_pte_bytes_per_frame_ub_l[k]);
2417
2418                 v->PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
2419                                 mode_lib,
2420                                 v->VRatio[k],
2421                                 v->vtaps[k],
2422                                 v->Interlace[k],
2423                                 v->ProgressiveToInterlaceUnitInOPP,
2424                                 v->SwathHeightY[k],
2425                                 v->ViewportYStartY[k],
2426                                 &v->VInitPreFillY[k],
2427                                 &v->MaxNumSwathY[k]);
2428                 v->PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
2429                 v->PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY + PDEAndMetaPTEBytesFrameC;
2430                 v->MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
2431
2432                 CalculateRowBandwidth(
2433                                 v->GPUVMEnable,
2434                                 v->SourcePixelFormat[k],
2435                                 v->VRatio[k],
2436                                 v->VRatioChroma[k],
2437                                 v->DCCEnable[k],
2438                                 v->HTotal[k] / v->PixelClock[k],
2439                                 MetaRowByteY,
2440                                 MetaRowByteC,
2441                                 v->meta_row_height[k],
2442                                 v->meta_row_height_chroma[k],
2443                                 PixelPTEBytesPerRowY,
2444                                 PixelPTEBytesPerRowC,
2445                                 v->dpte_row_height[k],
2446                                 v->dpte_row_height_chroma[k],
2447                                 &v->meta_row_bw[k],
2448                                 &v->dpte_row_bw[k]);
2449         }
2450
2451         v->TotalDCCActiveDPP = 0;
2452         v->TotalActiveDPP = 0;
2453         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2454                 v->TotalActiveDPP = v->TotalActiveDPP + v->DPPPerPlane[k];
2455                 if (v->DCCEnable[k])
2456                         v->TotalDCCActiveDPP = v->TotalDCCActiveDPP + v->DPPPerPlane[k];
2457                 if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12
2458                                 || v->SourcePixelFormat[k] == dm_rgbe_alpha)
2459                         NoChromaPlanes = false;
2460         }
2461
2462         ReorderBytes = v->NumberOfChannels
2463                         * dml_max3(
2464                                         v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
2465                                         v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
2466                                         v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
2467
2468         VMDataOnlyReturnBW = dml_min(
2469                         dml_min(v->ReturnBusWidth * v->DCFCLK, v->FabricClock * v->FabricDatapathToDCNDataReturn)
2470                                         * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
2471                         v->DRAMSpeed * v->NumberOfChannels * v->DRAMChannelWidth
2472                                         * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly / 100.0);
2473
2474 #ifdef __DML_VBA_DEBUG__
2475         dml_print("DML::%s: v->ReturnBusWidth = %f\n", __func__, v->ReturnBusWidth);
2476         dml_print("DML::%s: v->DCFCLK = %f\n", __func__, v->DCFCLK);
2477         dml_print("DML::%s: v->FabricClock = %f\n", __func__, v->FabricClock);
2478         dml_print("DML::%s: v->FabricDatapathToDCNDataReturn = %f\n", __func__, v->FabricDatapathToDCNDataReturn);
2479         dml_print("DML::%s: v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = %f\n", __func__, v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency);
2480         dml_print("DML::%s: v->DRAMSpeed = %f\n", __func__, v->DRAMSpeed);
2481         dml_print("DML::%s: v->NumberOfChannels = %f\n", __func__, v->NumberOfChannels);
2482         dml_print("DML::%s: v->DRAMChannelWidth = %f\n", __func__, v->DRAMChannelWidth);
2483         dml_print("DML::%s: v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = %f\n", __func__, v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly);
2484         dml_print("DML::%s: VMDataOnlyReturnBW = %f\n", __func__, VMDataOnlyReturnBW);
2485         dml_print("DML::%s: ReturnBW = %f\n", __func__, v->ReturnBW);
2486 #endif
2487
2488         if (v->GPUVMEnable && v->HostVMEnable)
2489                 HostVMInefficiencyFactor = v->ReturnBW / VMDataOnlyReturnBW;
2490
2491         v->UrgentExtraLatency = CalculateExtraLatency(
2492                         v->RoundTripPingLatencyCycles,
2493                         ReorderBytes,
2494                         v->DCFCLK,
2495                         v->TotalActiveDPP,
2496                         v->PixelChunkSizeInKByte,
2497                         v->TotalDCCActiveDPP,
2498                         v->MetaChunkSize,
2499                         v->ReturnBW,
2500                         v->GPUVMEnable,
2501                         v->HostVMEnable,
2502                         v->NumberOfActivePlanes,
2503                         v->DPPPerPlane,
2504                         v->dpte_group_bytes,
2505                         HostVMInefficiencyFactor,
2506                         v->HostVMMinPageSize,
2507                         v->HostVMMaxNonCachedPageTableLevels);
2508
2509         v->TCalc = 24.0 / v->DCFCLKDeepSleep;
2510
2511         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2512                 if (v->BlendingAndTiming[k] == k) {
2513                         if (v->WritebackEnable[k] == true) {
2514                                 v->WritebackDelay[v->VoltageLevel][k] = v->WritebackLatency
2515                                                 + CalculateWriteBackDelay(
2516                                                                 v->WritebackPixelFormat[k],
2517                                                                 v->WritebackHRatio[k],
2518                                                                 v->WritebackVRatio[k],
2519                                                                 v->WritebackVTaps[k],
2520                                                                 v->WritebackDestinationWidth[k],
2521                                                                 v->WritebackDestinationHeight[k],
2522                                                                 v->WritebackSourceHeight[k],
2523                                                                 v->HTotal[k]) / v->DISPCLK;
2524                         } else
2525                                 v->WritebackDelay[v->VoltageLevel][k] = 0;
2526                         for (j = 0; j < v->NumberOfActivePlanes; ++j) {
2527                                 if (v->BlendingAndTiming[j] == k && v->WritebackEnable[j] == true) {
2528                                         v->WritebackDelay[v->VoltageLevel][k] = dml_max(
2529                                                         v->WritebackDelay[v->VoltageLevel][k],
2530                                                         v->WritebackLatency
2531                                                                         + CalculateWriteBackDelay(
2532                                                                                         v->WritebackPixelFormat[j],
2533                                                                                         v->WritebackHRatio[j],
2534                                                                                         v->WritebackVRatio[j],
2535                                                                                         v->WritebackVTaps[j],
2536                                                                                         v->WritebackDestinationWidth[j],
2537                                                                                         v->WritebackDestinationHeight[j],
2538                                                                                         v->WritebackSourceHeight[j],
2539                                                                                         v->HTotal[k]) / v->DISPCLK);
2540                                 }
2541                         }
2542                 }
2543         }
2544
2545         for (k = 0; k < v->NumberOfActivePlanes; ++k)
2546                 for (j = 0; j < v->NumberOfActivePlanes; ++j)
2547                         if (v->BlendingAndTiming[k] == j)
2548                                 v->WritebackDelay[v->VoltageLevel][k] = v->WritebackDelay[v->VoltageLevel][j];
2549
2550         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2551                 v->MaxVStartupLines[k] =
2552                                 (v->Interlace[k] && !v->ProgressiveToInterlaceUnitInOPP) ?
2553                                                 dml_floor((v->VTotal[k] - v->VActive[k]) / 2.0, 1.0) :
2554                                                 v->VTotal[k] - v->VActive[k]
2555                                                                 - dml_max(
2556                                                                                 1.0,
2557                                                                                 dml_ceil(
2558                                                                                                 (double) v->WritebackDelay[v->VoltageLevel][k]
2559                                                                                                                 / (v->HTotal[k] / v->PixelClock[k]),
2560                                                                                                 1));
2561                 if (v->MaxVStartupLines[k] > 1023)
2562                         v->MaxVStartupLines[k] = 1023;
2563
2564 #ifdef __DML_VBA_DEBUG__
2565                 dml_print("DML::%s: k=%d MaxVStartupLines = %d\n", __func__, k, v->MaxVStartupLines[k]);
2566                 dml_print("DML::%s: k=%d VoltageLevel = %d\n", __func__, k, v->VoltageLevel);
2567                 dml_print("DML::%s: k=%d WritebackDelay = %f\n", __func__, k, v->WritebackDelay[v->VoltageLevel][k]);
2568 #endif
2569         }
2570
2571         v->MaximumMaxVStartupLines = 0;
2572         for (k = 0; k < v->NumberOfActivePlanes; ++k)
2573                 v->MaximumMaxVStartupLines = dml_max(v->MaximumMaxVStartupLines, v->MaxVStartupLines[k]);
2574
2575         // VBA_DELTA
2576         // We don't really care to iterate between the various prefetch modes
2577         //v->PrefetchERROR = CalculateMinAndMaxPrefetchMode(v->AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &v->MinPrefetchMode, &v->MaxPrefetchMode);
2578
2579         v->UrgentLatency = CalculateUrgentLatency(
2580                         v->UrgentLatencyPixelDataOnly,
2581                         v->UrgentLatencyPixelMixedWithVMData,
2582                         v->UrgentLatencyVMDataOnly,
2583                         v->DoUrgentLatencyAdjustment,
2584                         v->UrgentLatencyAdjustmentFabricClockComponent,
2585                         v->UrgentLatencyAdjustmentFabricClockReference,
2586                         v->FabricClock);
2587
2588         v->FractionOfUrgentBandwidth = 0.0;
2589         v->FractionOfUrgentBandwidthImmediateFlip = 0.0;
2590
2591         v->VStartupLines = __DML_VBA_MIN_VSTARTUP__;
2592
2593         do {
2594                 double MaxTotalRDBandwidthNoUrgentBurst = 0.0;
2595                 bool DestinationLineTimesForPrefetchLessThan2 = false;
2596                 bool VRatioPrefetchMoreThan4 = false;
2597                 double TWait = CalculateTWait(PrefetchMode, v->DRAMClockChangeLatency, v->UrgentLatency, v->SREnterPlusExitTime);
2598                 MaxTotalRDBandwidth = 0;
2599
2600                 dml_print("DML::%s: Start loop: VStartup = %d\n", __func__, v->VStartupLines);
2601
2602                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2603                         Pipe myPipe;
2604
2605                         myPipe.DPPCLK = v->DPPCLK[k];
2606                         myPipe.DISPCLK = v->DISPCLK;
2607                         myPipe.PixelClock = v->PixelClock[k];
2608                         myPipe.DCFCLKDeepSleep = v->DCFCLKDeepSleep;
2609                         myPipe.DPPPerPlane = v->DPPPerPlane[k];
2610                         myPipe.ScalerEnabled = v->ScalerEnabled[k];
2611                         myPipe.VRatio = v->VRatio[k];
2612                         myPipe.VRatioChroma = v->VRatioChroma[k];
2613                         myPipe.SourceScan = v->SourceScan[k];
2614                         myPipe.BlockWidth256BytesY = v->BlockWidth256BytesY[k];
2615                         myPipe.BlockHeight256BytesY = v->BlockHeight256BytesY[k];
2616                         myPipe.BlockWidth256BytesC = v->BlockWidth256BytesC[k];
2617                         myPipe.BlockHeight256BytesC = v->BlockHeight256BytesC[k];
2618                         myPipe.InterlaceEnable = v->Interlace[k];
2619                         myPipe.NumberOfCursors = v->NumberOfCursors[k];
2620                         myPipe.VBlank = v->VTotal[k] - v->VActive[k];
2621                         myPipe.HTotal = v->HTotal[k];
2622                         myPipe.DCCEnable = v->DCCEnable[k];
2623                         myPipe.ODMCombineIsEnabled = v->ODMCombineEnabled[k] == dm_odm_combine_mode_4to1
2624                                         || v->ODMCombineEnabled[k] == dm_odm_combine_mode_2to1;
2625                         myPipe.SourcePixelFormat = v->SourcePixelFormat[k];
2626                         myPipe.BytePerPixelY = v->BytePerPixelY[k];
2627                         myPipe.BytePerPixelC = v->BytePerPixelC[k];
2628                         myPipe.ProgressiveToInterlaceUnitInOPP = v->ProgressiveToInterlaceUnitInOPP;
2629                         v->ErrorResult[k] = CalculatePrefetchSchedule(
2630                                         mode_lib,
2631                                         HostVMInefficiencyFactor,
2632                                         &myPipe,
2633                                         v->DSCDelay[k],
2634                                         v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater,
2635                                         v->DPPCLKDelaySCL,
2636                                         v->DPPCLKDelaySCLLBOnly,
2637                                         v->DPPCLKDelayCNVCCursor,
2638                                         v->DISPCLKDelaySubtotal,
2639                                         (unsigned int) (v->SwathWidthY[k] / v->HRatio[k]),
2640                                         v->OutputFormat[k],
2641                                         v->MaxInterDCNTileRepeaters,
2642                                         dml_min(v->VStartupLines, v->MaxVStartupLines[k]),
2643                                         v->MaxVStartupLines[k],
2644                                         v->GPUVMMaxPageTableLevels,
2645                                         v->GPUVMEnable,
2646                                         v->HostVMEnable,
2647                                         v->HostVMMaxNonCachedPageTableLevels,
2648                                         v->HostVMMinPageSize,
2649                                         v->DynamicMetadataEnable[k],
2650                                         v->DynamicMetadataVMEnabled,
2651                                         v->DynamicMetadataLinesBeforeActiveRequired[k],
2652                                         v->DynamicMetadataTransmittedBytes[k],
2653                                         v->UrgentLatency,
2654                                         v->UrgentExtraLatency,
2655                                         v->TCalc,
2656                                         v->PDEAndMetaPTEBytesFrame[k],
2657                                         v->MetaRowByte[k],
2658                                         v->PixelPTEBytesPerRow[k],
2659                                         v->PrefetchSourceLinesY[k],
2660                                         v->SwathWidthY[k],
2661                                         v->VInitPreFillY[k],
2662                                         v->MaxNumSwathY[k],
2663                                         v->PrefetchSourceLinesC[k],
2664                                         v->SwathWidthC[k],
2665                                         v->VInitPreFillC[k],
2666                                         v->MaxNumSwathC[k],
2667                                         v->swath_width_luma_ub[k],
2668                                         v->swath_width_chroma_ub[k],
2669                                         v->SwathHeightY[k],
2670                                         v->SwathHeightC[k],
2671                                         TWait,
2672                                         &v->DSTXAfterScaler[k],
2673                                         &v->DSTYAfterScaler[k],
2674                                         &v->DestinationLinesForPrefetch[k],
2675                                         &v->PrefetchBandwidth[k],
2676                                         &v->DestinationLinesToRequestVMInVBlank[k],
2677                                         &v->DestinationLinesToRequestRowInVBlank[k],
2678                                         &v->VRatioPrefetchY[k],
2679                                         &v->VRatioPrefetchC[k],
2680                                         &v->RequiredPrefetchPixDataBWLuma[k],
2681                                         &v->RequiredPrefetchPixDataBWChroma[k],
2682                                         &v->NotEnoughTimeForDynamicMetadata[k],
2683                                         &v->Tno_bw[k],
2684                                         &v->prefetch_vmrow_bw[k],
2685                                         &v->Tdmdl_vm[k],
2686                                         &v->Tdmdl[k],
2687                                         &v->TSetup[k],
2688                                         &v->VUpdateOffsetPix[k],
2689                                         &v->VUpdateWidthPix[k],
2690                                         &v->VReadyOffsetPix[k]);
2691
2692 #ifdef __DML_VBA_DEBUG__
2693                         dml_print("DML::%s: k=%0d Prefetch cal result=%0d\n", __func__, k, v->ErrorResult[k]);
2694 #endif
2695                         v->VStartup[k] = dml_min(v->VStartupLines, v->MaxVStartupLines[k]);
2696                 }
2697
2698                 v->NoEnoughUrgentLatencyHiding = false;
2699                 v->NoEnoughUrgentLatencyHidingPre = false;
2700
2701                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2702                         v->cursor_bw[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
2703                                         / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
2704                         v->cursor_bw_pre[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
2705                                         / (v->HTotal[k] / v->PixelClock[k]) * v->VRatioPrefetchY[k];
2706
2707                         CalculateUrgentBurstFactor(
2708                                         v->swath_width_luma_ub[k],
2709                                         v->swath_width_chroma_ub[k],
2710                                         v->SwathHeightY[k],
2711                                         v->SwathHeightC[k],
2712                                         v->HTotal[k] / v->PixelClock[k],
2713                                         v->UrgentLatency,
2714                                         v->CursorBufferSize,
2715                                         v->CursorWidth[k][0],
2716                                         v->CursorBPP[k][0],
2717                                         v->VRatio[k],
2718                                         v->VRatioChroma[k],
2719                                         v->BytePerPixelDETY[k],
2720                                         v->BytePerPixelDETC[k],
2721                                         v->DETBufferSizeY[k],
2722                                         v->DETBufferSizeC[k],
2723                                         &v->UrgBurstFactorCursor[k],
2724                                         &v->UrgBurstFactorLuma[k],
2725                                         &v->UrgBurstFactorChroma[k],
2726                                         &v->NoUrgentLatencyHiding[k]);
2727
2728                         CalculateUrgentBurstFactor(
2729                                         v->swath_width_luma_ub[k],
2730                                         v->swath_width_chroma_ub[k],
2731                                         v->SwathHeightY[k],
2732                                         v->SwathHeightC[k],
2733                                         v->HTotal[k] / v->PixelClock[k],
2734                                         v->UrgentLatency,
2735                                         v->CursorBufferSize,
2736                                         v->CursorWidth[k][0],
2737                                         v->CursorBPP[k][0],
2738                                         v->VRatioPrefetchY[k],
2739                                         v->VRatioPrefetchC[k],
2740                                         v->BytePerPixelDETY[k],
2741                                         v->BytePerPixelDETC[k],
2742                                         v->DETBufferSizeY[k],
2743                                         v->DETBufferSizeC[k],
2744                                         &v->UrgBurstFactorCursorPre[k],
2745                                         &v->UrgBurstFactorLumaPre[k],
2746                                         &v->UrgBurstFactorChromaPre[k],
2747                                         &v->NoUrgentLatencyHidingPre[k]);
2748
2749                         MaxTotalRDBandwidth = MaxTotalRDBandwidth
2750                                         + dml_max3(
2751                                                         v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2752                                                         v->ReadBandwidthPlaneLuma[k] * v->UrgBurstFactorLuma[k]
2753                                                                         + v->ReadBandwidthPlaneChroma[k] * v->UrgBurstFactorChroma[k]
2754                                                                         + v->cursor_bw[k] * v->UrgBurstFactorCursor[k]
2755                                                                         + v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
2756                                                         v->DPPPerPlane[k]
2757                                                                         * (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
2758                                                                                         + v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
2759                                                                         + v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
2760
2761                         MaxTotalRDBandwidthNoUrgentBurst = MaxTotalRDBandwidthNoUrgentBurst
2762                                         + dml_max3(
2763                                                         v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2764                                                         v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k]
2765                                                                         + v->DPPPerPlane[k] * (v->meta_row_bw[k] + v->dpte_row_bw[k]),
2766                                                         v->DPPPerPlane[k] * (v->RequiredPrefetchPixDataBWLuma[k] + v->RequiredPrefetchPixDataBWChroma[k])
2767                                                                         + v->cursor_bw_pre[k]);
2768
2769 #ifdef __DML_VBA_DEBUG__
2770                         dml_print("DML::%s: k=%0d DPPPerPlane=%d\n", __func__, k, v->DPPPerPlane[k]);
2771                         dml_print("DML::%s: k=%0d UrgBurstFactorLuma=%f\n", __func__, k, v->UrgBurstFactorLuma[k]);
2772                         dml_print("DML::%s: k=%0d UrgBurstFactorChroma=%f\n", __func__, k, v->UrgBurstFactorChroma[k]);
2773                         dml_print("DML::%s: k=%0d UrgBurstFactorLumaPre=%f\n", __func__, k, v->UrgBurstFactorLumaPre[k]);
2774                         dml_print("DML::%s: k=%0d UrgBurstFactorChromaPre=%f\n", __func__, k, v->UrgBurstFactorChromaPre[k]);
2775
2776                         dml_print("DML::%s: k=%0d VRatioPrefetchY=%f\n", __func__, k, v->VRatioPrefetchY[k]);
2777                         dml_print("DML::%s: k=%0d VRatioY=%f\n", __func__, k, v->VRatio[k]);
2778
2779                         dml_print("DML::%s: k=%0d prefetch_vmrow_bw=%f\n", __func__, k, v->prefetch_vmrow_bw[k]);
2780                         dml_print("DML::%s: k=%0d ReadBandwidthPlaneLuma=%f\n", __func__, k, v->ReadBandwidthPlaneLuma[k]);
2781                         dml_print("DML::%s: k=%0d ReadBandwidthPlaneChroma=%f\n", __func__, k, v->ReadBandwidthPlaneChroma[k]);
2782                         dml_print("DML::%s: k=%0d cursor_bw=%f\n", __func__, k, v->cursor_bw[k]);
2783                         dml_print("DML::%s: k=%0d meta_row_bw=%f\n", __func__, k, v->meta_row_bw[k]);
2784                         dml_print("DML::%s: k=%0d dpte_row_bw=%f\n", __func__, k, v->dpte_row_bw[k]);
2785                         dml_print("DML::%s: k=%0d RequiredPrefetchPixDataBWLuma=%f\n", __func__, k, v->RequiredPrefetchPixDataBWLuma[k]);
2786                         dml_print("DML::%s: k=%0d RequiredPrefetchPixDataBWChroma=%f\n", __func__, k, v->RequiredPrefetchPixDataBWChroma[k]);
2787                         dml_print("DML::%s: k=%0d cursor_bw_pre=%f\n", __func__, k, v->cursor_bw_pre[k]);
2788                         dml_print("DML::%s: k=%0d MaxTotalRDBandwidthNoUrgentBurst=%f\n", __func__, k, MaxTotalRDBandwidthNoUrgentBurst);
2789 #endif
2790
2791                         if (v->DestinationLinesForPrefetch[k] < 2)
2792                                 DestinationLineTimesForPrefetchLessThan2 = true;
2793
2794                         if (v->VRatioPrefetchY[k] > 4 || v->VRatioPrefetchC[k] > 4)
2795                                 VRatioPrefetchMoreThan4 = true;
2796
2797                         if (v->NoUrgentLatencyHiding[k] == true)
2798                                 v->NoEnoughUrgentLatencyHiding = true;
2799
2800                         if (v->NoUrgentLatencyHidingPre[k] == true)
2801                                 v->NoEnoughUrgentLatencyHidingPre = true;
2802                 }
2803
2804                 v->FractionOfUrgentBandwidth = MaxTotalRDBandwidthNoUrgentBurst / v->ReturnBW;
2805
2806 #ifdef __DML_VBA_DEBUG__
2807                 dml_print("DML::%s: MaxTotalRDBandwidthNoUrgentBurst=%f \n", __func__, MaxTotalRDBandwidthNoUrgentBurst);
2808                 dml_print("DML::%s: ReturnBW=%f \n", __func__, v->ReturnBW);
2809                 dml_print("DML::%s: FractionOfUrgentBandwidth=%f \n", __func__, v->FractionOfUrgentBandwidth);
2810 #endif
2811
2812                 if (MaxTotalRDBandwidth <= v->ReturnBW && v->NoEnoughUrgentLatencyHiding == 0 && v->NoEnoughUrgentLatencyHidingPre == 0
2813                                 && !VRatioPrefetchMoreThan4 && !DestinationLineTimesForPrefetchLessThan2)
2814                         v->PrefetchModeSupported = true;
2815                 else {
2816                         v->PrefetchModeSupported = false;
2817                         dml_print("DML::%s: ***failed***. Bandwidth violation. Results are NOT valid\n", __func__);
2818                         dml_print("DML::%s: MaxTotalRDBandwidth:%f AvailReturnBandwidth:%f\n", __func__, MaxTotalRDBandwidth, v->ReturnBW);
2819                         dml_print("DML::%s: VRatioPrefetch %s more than 4\n", __func__, (VRatioPrefetchMoreThan4) ? "is" : "is not");
2820                         dml_print("DML::%s: DestinationLines for Prefetch %s less than 2\n", __func__, (DestinationLineTimesForPrefetchLessThan2) ? "is" : "is not");
2821                 }
2822
2823                 // PREVIOUS_ERROR
2824                 // This error result check was done after the PrefetchModeSupported. So we will
2825                 // still try to calculate flip schedule even prefetch mode not supported
2826                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2827                         if (v->ErrorResult[k] == true || v->NotEnoughTimeForDynamicMetadata[k] == true) {
2828                                 v->PrefetchModeSupported = false;
2829                                 dml_print("DML::%s: ***failed***. Prefetch schedule violation. Results are NOT valid\n", __func__);
2830                         }
2831                 }
2832
2833                 if (v->PrefetchModeSupported == true && v->ImmediateFlipSupport == true) {
2834                         v->BandwidthAvailableForImmediateFlip = v->ReturnBW;
2835                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2836                                 v->BandwidthAvailableForImmediateFlip = v->BandwidthAvailableForImmediateFlip
2837                                                 - dml_max(
2838                                                                 v->ReadBandwidthPlaneLuma[k] * v->UrgBurstFactorLuma[k]
2839                                                                                 + v->ReadBandwidthPlaneChroma[k] * v->UrgBurstFactorChroma[k]
2840                                                                                 + v->cursor_bw[k] * v->UrgBurstFactorCursor[k],
2841                                                                 v->DPPPerPlane[k]
2842                                                                                 * (v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
2843                                                                                                 + v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
2844                                                                                 + v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
2845                         }
2846
2847                         v->TotImmediateFlipBytes = 0;
2848                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2849                                 v->TotImmediateFlipBytes = v->TotImmediateFlipBytes
2850                                                 + v->DPPPerPlane[k] * (v->PDEAndMetaPTEBytesFrame[k] + v->MetaRowByte[k] + v->PixelPTEBytesPerRow[k]);
2851                         }
2852                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2853                                 CalculateFlipSchedule(
2854                                                 mode_lib,
2855                                                 k,
2856                                                 HostVMInefficiencyFactor,
2857                                                 v->UrgentExtraLatency,
2858                                                 v->UrgentLatency,
2859                                                 v->PDEAndMetaPTEBytesFrame[k],
2860                                                 v->MetaRowByte[k],
2861                                                 v->PixelPTEBytesPerRow[k]);
2862                         }
2863
2864                         v->total_dcn_read_bw_with_flip = 0.0;
2865                         v->total_dcn_read_bw_with_flip_no_urgent_burst = 0.0;
2866                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2867                                 v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip
2868                                                 + dml_max3(
2869                                                                 v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2870                                                                 v->DPPPerPlane[k] * v->final_flip_bw[k]
2871                                                                                 + v->ReadBandwidthLuma[k] * v->UrgBurstFactorLuma[k]
2872                                                                                 + v->ReadBandwidthChroma[k] * v->UrgBurstFactorChroma[k]
2873                                                                                 + v->cursor_bw[k] * v->UrgBurstFactorCursor[k],
2874                                                                 v->DPPPerPlane[k]
2875                                                                                 * (v->final_flip_bw[k]
2876                                                                                                 + v->RequiredPrefetchPixDataBWLuma[k] * v->UrgBurstFactorLumaPre[k]
2877                                                                                                 + v->RequiredPrefetchPixDataBWChroma[k] * v->UrgBurstFactorChromaPre[k])
2878                                                                                 + v->cursor_bw_pre[k] * v->UrgBurstFactorCursorPre[k]);
2879                                 v->total_dcn_read_bw_with_flip_no_urgent_burst = v->total_dcn_read_bw_with_flip_no_urgent_burst
2880                                                 + dml_max3(
2881                                                                 v->DPPPerPlane[k] * v->prefetch_vmrow_bw[k],
2882                                                                 v->DPPPerPlane[k] * v->final_flip_bw[k] + v->ReadBandwidthPlaneLuma[k]
2883                                                                                 + v->ReadBandwidthPlaneChroma[k] + v->cursor_bw[k],
2884                                                                 v->DPPPerPlane[k]
2885                                                                                 * (v->final_flip_bw[k] + v->RequiredPrefetchPixDataBWLuma[k]
2886                                                                                                 + v->RequiredPrefetchPixDataBWChroma[k]) + v->cursor_bw_pre[k]);
2887                         }
2888                         v->FractionOfUrgentBandwidthImmediateFlip = v->total_dcn_read_bw_with_flip_no_urgent_burst / v->ReturnBW;
2889
2890                         v->ImmediateFlipSupported = true;
2891                         if (v->total_dcn_read_bw_with_flip > v->ReturnBW) {
2892 #ifdef __DML_VBA_DEBUG__
2893                                 dml_print("DML::%s: total_dcn_read_bw_with_flip %f (bw w/ flip too high!)\n", __func__, v->total_dcn_read_bw_with_flip);
2894 #endif
2895                                 v->ImmediateFlipSupported = false;
2896                                 v->total_dcn_read_bw_with_flip = MaxTotalRDBandwidth;
2897                         }
2898                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2899                                 if (v->ImmediateFlipSupportedForPipe[k] == false) {
2900 #ifdef __DML_VBA_DEBUG__
2901                                         dml_print("DML::%s: Pipe %0d not supporting iflip\n",
2902                                                   __func__, k);
2903 #endif
2904                                         v->ImmediateFlipSupported = false;
2905                                 }
2906                         }
2907                 } else {
2908                         v->ImmediateFlipSupported = false;
2909                 }
2910
2911                 v->PrefetchAndImmediateFlipSupported =
2912                                 (v->PrefetchModeSupported == true && ((!v->ImmediateFlipSupport && !v->HostVMEnable
2913                                 && v->ImmediateFlipRequirement[0] != dm_immediate_flip_required) ||
2914                                 v->ImmediateFlipSupported)) ? true : false;
2915 #ifdef __DML_VBA_DEBUG__
2916                 dml_print("DML::%s: PrefetchModeSupported %d\n", __func__, v->PrefetchModeSupported);
2917                 dml_print("DML::%s: ImmediateFlipRequirement[0] %d\n", __func__, v->ImmediateFlipRequirement[0] == dm_immediate_flip_required);
2918                 dml_print("DML::%s: ImmediateFlipSupported %d\n", __func__, v->ImmediateFlipSupported);
2919                 dml_print("DML::%s: ImmediateFlipSupport %d\n", __func__, v->ImmediateFlipSupport);
2920                 dml_print("DML::%s: HostVMEnable %d\n", __func__, v->HostVMEnable);
2921                 dml_print("DML::%s: PrefetchAndImmediateFlipSupported %d\n", __func__, v->PrefetchAndImmediateFlipSupported);
2922 #endif
2923                 dml_print("DML::%s: Done loop: Vstartup=%d, Max Vstartup is %d\n", __func__, v->VStartupLines, v->MaximumMaxVStartupLines);
2924
2925                 v->VStartupLines = v->VStartupLines + 1;
2926         } while (!v->PrefetchAndImmediateFlipSupported && v->VStartupLines <= v->MaximumMaxVStartupLines);
2927         ASSERT(v->PrefetchAndImmediateFlipSupported);
2928
2929         // Unbounded Request Enabled
2930         CalculateUnboundedRequestAndCompressedBufferSize(
2931                         v->DETBufferSizeInKByte[0],
2932                         v->ConfigReturnBufferSizeInKByte,
2933                         v->UseUnboundedRequesting,
2934                         v->TotalActiveDPP,
2935                         NoChromaPlanes,
2936                         v->MaxNumDPP,
2937                         v->CompressedBufferSegmentSizeInkByte,
2938                         v->Output,
2939                         &v->UnboundedRequestEnabled,
2940                         &v->CompressedBufferSizeInkByte);
2941
2942         //Watermarks and NB P-State/DRAM Clock Change Support
2943         {
2944                 enum clock_change_support DRAMClockChangeSupport; // dummy
2945                 CalculateWatermarksAndDRAMSpeedChangeSupport(
2946                                 mode_lib,
2947                                 PrefetchMode,
2948                                 v->DCFCLK,
2949                                 v->ReturnBW,
2950                                 v->UrgentLatency,
2951                                 v->UrgentExtraLatency,
2952                                 v->SOCCLK,
2953                                 v->DCFCLKDeepSleep,
2954                                 v->DETBufferSizeY,
2955                                 v->DETBufferSizeC,
2956                                 v->SwathHeightY,
2957                                 v->SwathHeightC,
2958                                 v->SwathWidthY,
2959                                 v->SwathWidthC,
2960                                 v->DPPPerPlane,
2961                                 v->BytePerPixelDETY,
2962                                 v->BytePerPixelDETC,
2963                                 v->UnboundedRequestEnabled,
2964                                 v->CompressedBufferSizeInkByte,
2965                                 &DRAMClockChangeSupport,
2966                                 &v->StutterExitWatermark,
2967                                 &v->StutterEnterPlusExitWatermark,
2968                                 &v->Z8StutterExitWatermark,
2969                                 &v->Z8StutterEnterPlusExitWatermark);
2970
2971                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
2972                         if (v->WritebackEnable[k] == true) {
2973                                 v->WritebackAllowDRAMClockChangeEndPosition[k] = dml_max(
2974                                                 0,
2975                                                 v->VStartup[k] * v->HTotal[k] / v->PixelClock[k] - v->WritebackDRAMClockChangeWatermark);
2976                         } else {
2977                                 v->WritebackAllowDRAMClockChangeEndPosition[k] = 0;
2978                         }
2979                 }
2980         }
2981
2982         //Display Pipeline Delivery Time in Prefetch, Groups
2983         CalculatePixelDeliveryTimes(
2984                         v->NumberOfActivePlanes,
2985                         v->VRatio,
2986                         v->VRatioChroma,
2987                         v->VRatioPrefetchY,
2988                         v->VRatioPrefetchC,
2989                         v->swath_width_luma_ub,
2990                         v->swath_width_chroma_ub,
2991                         v->DPPPerPlane,
2992                         v->HRatio,
2993                         v->HRatioChroma,
2994                         v->PixelClock,
2995                         v->PSCL_THROUGHPUT_LUMA,
2996                         v->PSCL_THROUGHPUT_CHROMA,
2997                         v->DPPCLK,
2998                         v->BytePerPixelC,
2999                         v->SourceScan,
3000                         v->NumberOfCursors,
3001                         v->CursorWidth,
3002                         v->CursorBPP,
3003                         v->BlockWidth256BytesY,
3004                         v->BlockHeight256BytesY,
3005                         v->BlockWidth256BytesC,
3006                         v->BlockHeight256BytesC,
3007                         v->DisplayPipeLineDeliveryTimeLuma,
3008                         v->DisplayPipeLineDeliveryTimeChroma,
3009                         v->DisplayPipeLineDeliveryTimeLumaPrefetch,
3010                         v->DisplayPipeLineDeliveryTimeChromaPrefetch,
3011                         v->DisplayPipeRequestDeliveryTimeLuma,
3012                         v->DisplayPipeRequestDeliveryTimeChroma,
3013                         v->DisplayPipeRequestDeliveryTimeLumaPrefetch,
3014                         v->DisplayPipeRequestDeliveryTimeChromaPrefetch,
3015                         v->CursorRequestDeliveryTime,
3016                         v->CursorRequestDeliveryTimePrefetch);
3017
3018         CalculateMetaAndPTETimes(
3019                         v->NumberOfActivePlanes,
3020                         v->GPUVMEnable,
3021                         v->MetaChunkSize,
3022                         v->MinMetaChunkSizeBytes,
3023                         v->HTotal,
3024                         v->VRatio,
3025                         v->VRatioChroma,
3026                         v->DestinationLinesToRequestRowInVBlank,
3027                         v->DestinationLinesToRequestRowInImmediateFlip,
3028                         v->DCCEnable,
3029                         v->PixelClock,
3030                         v->BytePerPixelY,
3031                         v->BytePerPixelC,
3032                         v->SourceScan,
3033                         v->dpte_row_height,
3034                         v->dpte_row_height_chroma,
3035                         v->meta_row_width,
3036                         v->meta_row_width_chroma,
3037                         v->meta_row_height,
3038                         v->meta_row_height_chroma,
3039                         v->meta_req_width,
3040                         v->meta_req_width_chroma,
3041                         v->meta_req_height,
3042                         v->meta_req_height_chroma,
3043                         v->dpte_group_bytes,
3044                         v->PTERequestSizeY,
3045                         v->PTERequestSizeC,
3046                         v->PixelPTEReqWidthY,
3047                         v->PixelPTEReqHeightY,
3048                         v->PixelPTEReqWidthC,
3049                         v->PixelPTEReqHeightC,
3050                         v->dpte_row_width_luma_ub,
3051                         v->dpte_row_width_chroma_ub,
3052                         v->DST_Y_PER_PTE_ROW_NOM_L,
3053                         v->DST_Y_PER_PTE_ROW_NOM_C,
3054                         v->DST_Y_PER_META_ROW_NOM_L,
3055                         v->DST_Y_PER_META_ROW_NOM_C,
3056                         v->TimePerMetaChunkNominal,
3057                         v->TimePerChromaMetaChunkNominal,
3058                         v->TimePerMetaChunkVBlank,
3059                         v->TimePerChromaMetaChunkVBlank,
3060                         v->TimePerMetaChunkFlip,
3061                         v->TimePerChromaMetaChunkFlip,
3062                         v->time_per_pte_group_nom_luma,
3063                         v->time_per_pte_group_vblank_luma,
3064                         v->time_per_pte_group_flip_luma,
3065                         v->time_per_pte_group_nom_chroma,
3066                         v->time_per_pte_group_vblank_chroma,
3067                         v->time_per_pte_group_flip_chroma);
3068
3069         CalculateVMGroupAndRequestTimes(
3070                         v->NumberOfActivePlanes,
3071                         v->GPUVMEnable,
3072                         v->GPUVMMaxPageTableLevels,
3073                         v->HTotal,
3074                         v->BytePerPixelC,
3075                         v->DestinationLinesToRequestVMInVBlank,
3076                         v->DestinationLinesToRequestVMInImmediateFlip,
3077                         v->DCCEnable,
3078                         v->PixelClock,
3079                         v->dpte_row_width_luma_ub,
3080                         v->dpte_row_width_chroma_ub,
3081                         v->vm_group_bytes,
3082                         v->dpde0_bytes_per_frame_ub_l,
3083                         v->dpde0_bytes_per_frame_ub_c,
3084                         v->meta_pte_bytes_per_frame_ub_l,
3085                         v->meta_pte_bytes_per_frame_ub_c,
3086                         v->TimePerVMGroupVBlank,
3087                         v->TimePerVMGroupFlip,
3088                         v->TimePerVMRequestVBlank,
3089                         v->TimePerVMRequestFlip);
3090
3091         // Min TTUVBlank
3092         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3093                 if (PrefetchMode == 0) {
3094                         v->AllowDRAMClockChangeDuringVBlank[k] = true;
3095                         v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
3096                         v->MinTTUVBlank[k] = dml_max(
3097                                         v->DRAMClockChangeWatermark,
3098                                         dml_max(v->StutterEnterPlusExitWatermark, v->UrgentWatermark));
3099                 } else if (PrefetchMode == 1) {
3100                         v->AllowDRAMClockChangeDuringVBlank[k] = false;
3101                         v->AllowDRAMSelfRefreshDuringVBlank[k] = true;
3102                         v->MinTTUVBlank[k] = dml_max(v->StutterEnterPlusExitWatermark, v->UrgentWatermark);
3103                 } else {
3104                         v->AllowDRAMClockChangeDuringVBlank[k] = false;
3105                         v->AllowDRAMSelfRefreshDuringVBlank[k] = false;
3106                         v->MinTTUVBlank[k] = v->UrgentWatermark;
3107                 }
3108                 if (!v->DynamicMetadataEnable[k])
3109                         v->MinTTUVBlank[k] = v->TCalc + v->MinTTUVBlank[k];
3110         }
3111
3112         // DCC Configuration
3113         v->ActiveDPPs = 0;
3114         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3115                 CalculateDCCConfiguration(v->DCCEnable[k], false, // We should always know the direction DCCProgrammingAssumesScanDirectionUnknown,
3116                                 v->SourcePixelFormat[k],
3117                                 v->SurfaceWidthY[k],
3118                                 v->SurfaceWidthC[k],
3119                                 v->SurfaceHeightY[k],
3120                                 v->SurfaceHeightC[k],
3121                                 v->DETBufferSizeInKByte[0] * 1024,
3122                                 v->BlockHeight256BytesY[k],
3123                                 v->BlockHeight256BytesC[k],
3124                                 v->SurfaceTiling[k],
3125                                 v->BytePerPixelY[k],
3126                                 v->BytePerPixelC[k],
3127                                 v->BytePerPixelDETY[k],
3128                                 v->BytePerPixelDETC[k],
3129                                 v->SourceScan[k],
3130                                 &v->DCCYMaxUncompressedBlock[k],
3131                                 &v->DCCCMaxUncompressedBlock[k],
3132                                 &v->DCCYMaxCompressedBlock[k],
3133                                 &v->DCCCMaxCompressedBlock[k],
3134                                 &v->DCCYIndependentBlock[k],
3135                                 &v->DCCCIndependentBlock[k]);
3136         }
3137
3138         // VStartup Adjustment
3139         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3140                 bool isInterlaceTiming;
3141                 double Tvstartup_margin = (v->MaxVStartupLines[k] - v->VStartup[k]) * v->HTotal[k] / v->PixelClock[k];
3142 #ifdef __DML_VBA_DEBUG__
3143                 dml_print("DML::%s: k=%d, MinTTUVBlank = %f (before margin)\n", __func__, k, v->MinTTUVBlank[k]);
3144 #endif
3145
3146                 v->MinTTUVBlank[k] = v->MinTTUVBlank[k] + Tvstartup_margin;
3147
3148 #ifdef __DML_VBA_DEBUG__
3149                 dml_print("DML::%s: k=%d, Tvstartup_margin = %f\n", __func__, k, Tvstartup_margin);
3150                 dml_print("DML::%s: k=%d, MaxVStartupLines = %d\n", __func__, k, v->MaxVStartupLines[k]);
3151                 dml_print("DML::%s: k=%d, VStartup = %d\n", __func__, k, v->VStartup[k]);
3152                 dml_print("DML::%s: k=%d, MinTTUVBlank = %f\n", __func__, k, v->MinTTUVBlank[k]);
3153 #endif
3154
3155                 v->Tdmdl[k] = v->Tdmdl[k] + Tvstartup_margin;
3156                 if (v->DynamicMetadataEnable[k] && v->DynamicMetadataVMEnabled) {
3157                         v->Tdmdl_vm[k] = v->Tdmdl_vm[k] + Tvstartup_margin;
3158                 }
3159
3160                 isInterlaceTiming = (v->Interlace[k] && !v->ProgressiveToInterlaceUnitInOPP);
3161
3162                 v->MIN_DST_Y_NEXT_START[k] = ((isInterlaceTiming ? dml_floor((v->VTotal[k] - v->VFrontPorch[k]) / 2.0, 1.0) : v->VTotal[k])
3163                                 - v->VFrontPorch[k])
3164                                 + dml_max(1.0, dml_ceil(v->WritebackDelay[v->VoltageLevel][k] / (v->HTotal[k] / v->PixelClock[k]), 1.0))
3165                                 + dml_floor(4.0 * v->TSetup[k] / (v->HTotal[k] / v->PixelClock[k]), 1.0) / 4.0;
3166
3167                 v->VStartup[k] = (isInterlaceTiming ? (2 * v->MaxVStartupLines[k]) : v->MaxVStartupLines[k]);
3168
3169                 if (((v->VUpdateOffsetPix[k] + v->VUpdateWidthPix[k] + v->VReadyOffsetPix[k]) / v->HTotal[k])
3170                                 <= (isInterlaceTiming ?
3171                                                 dml_floor((v->VTotal[k] - v->VActive[k] - v->VFrontPorch[k] - v->VStartup[k]) / 2.0, 1.0) :
3172                                                 (int) (v->VTotal[k] - v->VActive[k] - v->VFrontPorch[k] - v->VStartup[k]))) {
3173                         v->VREADY_AT_OR_AFTER_VSYNC[k] = true;
3174                 } else {
3175                         v->VREADY_AT_OR_AFTER_VSYNC[k] = false;
3176                 }
3177 #ifdef __DML_VBA_DEBUG__
3178                 dml_print("DML::%s: k=%d, VStartup = %d (max)\n", __func__, k, v->VStartup[k]);
3179                 dml_print("DML::%s: k=%d, VUpdateOffsetPix = %d\n", __func__, k, v->VUpdateOffsetPix[k]);
3180                 dml_print("DML::%s: k=%d, VUpdateWidthPix = %d\n", __func__, k, v->VUpdateWidthPix[k]);
3181                 dml_print("DML::%s: k=%d, VReadyOffsetPix = %d\n", __func__, k, v->VReadyOffsetPix[k]);
3182                 dml_print("DML::%s: k=%d, HTotal = %d\n", __func__, k, v->HTotal[k]);
3183                 dml_print("DML::%s: k=%d, VTotal = %d\n", __func__, k, v->VTotal[k]);
3184                 dml_print("DML::%s: k=%d, VActive = %d\n", __func__, k, v->VActive[k]);
3185                 dml_print("DML::%s: k=%d, VFrontPorch = %d\n", __func__, k, v->VFrontPorch[k]);
3186                 dml_print("DML::%s: k=%d, VStartup = %d\n", __func__, k, v->VStartup[k]);
3187                 dml_print("DML::%s: k=%d, MIN_DST_Y_NEXT_START = %f\n", __func__, k, v->MIN_DST_Y_NEXT_START[k]);
3188                 dml_print("DML::%s: k=%d, VREADY_AT_OR_AFTER_VSYNC = %d\n", __func__, k, v->VREADY_AT_OR_AFTER_VSYNC[k]);
3189 #endif
3190         }
3191
3192         {
3193                 //Maximum Bandwidth Used
3194                 double TotalWRBandwidth = 0;
3195                 double MaxPerPlaneVActiveWRBandwidth = 0;
3196                 double WRBandwidth = 0;
3197                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3198                         if (v->WritebackEnable[k] == true && v->WritebackPixelFormat[k] == dm_444_32) {
3199                                 WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3200                                                 / (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 4;
3201                         } else if (v->WritebackEnable[k] == true) {
3202                                 WRBandwidth = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3203                                                 / (v->HTotal[k] * v->WritebackSourceHeight[k] / v->PixelClock[k]) * 8;
3204                         }
3205                         TotalWRBandwidth = TotalWRBandwidth + WRBandwidth;
3206                         MaxPerPlaneVActiveWRBandwidth = dml_max(MaxPerPlaneVActiveWRBandwidth, WRBandwidth);
3207                 }
3208
3209                 v->TotalDataReadBandwidth = 0;
3210                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3211                         v->TotalDataReadBandwidth = v->TotalDataReadBandwidth + v->ReadBandwidthPlaneLuma[k] + v->ReadBandwidthPlaneChroma[k];
3212                 }
3213         }
3214         // Stutter Efficiency
3215         CalculateStutterEfficiency(
3216                         mode_lib,
3217                         v->CompressedBufferSizeInkByte,
3218                         v->UnboundedRequestEnabled,
3219                         v->ConfigReturnBufferSizeInKByte,
3220                         v->MetaFIFOSizeInKEntries,
3221                         v->ZeroSizeBufferEntries,
3222                         v->NumberOfActivePlanes,
3223                         v->ROBBufferSizeInKByte,
3224                         v->TotalDataReadBandwidth,
3225                         v->DCFCLK,
3226                         v->ReturnBW,
3227                         v->COMPBUF_RESERVED_SPACE_64B,
3228                         v->COMPBUF_RESERVED_SPACE_ZS,
3229                         v->SRExitTime,
3230                         v->SRExitZ8Time,
3231                         v->SynchronizedVBlank,
3232                         v->StutterEnterPlusExitWatermark,
3233                         v->Z8StutterEnterPlusExitWatermark,
3234                         v->ProgressiveToInterlaceUnitInOPP,
3235                         v->Interlace,
3236                         v->MinTTUVBlank,
3237                         v->DPPPerPlane,
3238                         v->DETBufferSizeY,
3239                         v->BytePerPixelY,
3240                         v->BytePerPixelDETY,
3241                         v->SwathWidthY,
3242                         v->SwathHeightY,
3243                         v->SwathHeightC,
3244                         v->DCCRateLuma,
3245                         v->DCCRateChroma,
3246                         v->DCCFractionOfZeroSizeRequestsLuma,
3247                         v->DCCFractionOfZeroSizeRequestsChroma,
3248                         v->HTotal,
3249                         v->VTotal,
3250                         v->PixelClock,
3251                         v->VRatio,
3252                         v->SourceScan,
3253                         v->BlockHeight256BytesY,
3254                         v->BlockWidth256BytesY,
3255                         v->BlockHeight256BytesC,
3256                         v->BlockWidth256BytesC,
3257                         v->DCCYMaxUncompressedBlock,
3258                         v->DCCCMaxUncompressedBlock,
3259                         v->VActive,
3260                         v->DCCEnable,
3261                         v->WritebackEnable,
3262                         v->ReadBandwidthPlaneLuma,
3263                         v->ReadBandwidthPlaneChroma,
3264                         v->meta_row_bw,
3265                         v->dpte_row_bw,
3266                         &v->StutterEfficiencyNotIncludingVBlank,
3267                         &v->StutterEfficiency,
3268                         &v->NumberOfStutterBurstsPerFrame,
3269                         &v->Z8StutterEfficiencyNotIncludingVBlank,
3270                         &v->Z8StutterEfficiency,
3271                         &v->Z8NumberOfStutterBurstsPerFrame,
3272                         &v->StutterPeriod);
3273 }
3274
3275 static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
3276 {
3277         struct vba_vars_st *v = &mode_lib->vba;
3278         // Display Pipe Configuration
3279         double BytePerPixDETY[DC__NUM_DPP__MAX];
3280         double BytePerPixDETC[DC__NUM_DPP__MAX];
3281         int BytePerPixY[DC__NUM_DPP__MAX];
3282         int BytePerPixC[DC__NUM_DPP__MAX];
3283         int Read256BytesBlockHeightY[DC__NUM_DPP__MAX];
3284         int Read256BytesBlockHeightC[DC__NUM_DPP__MAX];
3285         int Read256BytesBlockWidthY[DC__NUM_DPP__MAX];
3286         int Read256BytesBlockWidthC[DC__NUM_DPP__MAX];
3287         double dummy1[DC__NUM_DPP__MAX];
3288         double dummy2[DC__NUM_DPP__MAX];
3289         double dummy3[DC__NUM_DPP__MAX];
3290         double dummy4[DC__NUM_DPP__MAX];
3291         int dummy5[DC__NUM_DPP__MAX];
3292         int dummy6[DC__NUM_DPP__MAX];
3293         bool dummy7[DC__NUM_DPP__MAX];
3294         bool dummysinglestring;
3295
3296         unsigned int k;
3297
3298         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
3299
3300                 dml30_CalculateBytePerPixelAnd256BBlockSizes(
3301                                 v->SourcePixelFormat[k],
3302                                 v->SurfaceTiling[k],
3303                                 &BytePerPixY[k],
3304                                 &BytePerPixC[k],
3305                                 &BytePerPixDETY[k],
3306                                 &BytePerPixDETC[k],
3307                                 &Read256BytesBlockHeightY[k],
3308                                 &Read256BytesBlockHeightC[k],
3309                                 &Read256BytesBlockWidthY[k],
3310                                 &Read256BytesBlockWidthC[k]);
3311         }
3312
3313         CalculateSwathAndDETConfiguration(
3314                         false,
3315                         v->NumberOfActivePlanes,
3316                         v->DETBufferSizeInKByte[0],
3317                         dummy1,
3318                         dummy2,
3319                         v->SourceScan,
3320                         v->SourcePixelFormat,
3321                         v->SurfaceTiling,
3322                         v->ViewportWidth,
3323                         v->ViewportHeight,
3324                         v->SurfaceWidthY,
3325                         v->SurfaceWidthC,
3326                         v->SurfaceHeightY,
3327                         v->SurfaceHeightC,
3328                         Read256BytesBlockHeightY,
3329                         Read256BytesBlockHeightC,
3330                         Read256BytesBlockWidthY,
3331                         Read256BytesBlockWidthC,
3332                         v->ODMCombineEnabled,
3333                         v->BlendingAndTiming,
3334                         BytePerPixY,
3335                         BytePerPixC,
3336                         BytePerPixDETY,
3337                         BytePerPixDETC,
3338                         v->HActive,
3339                         v->HRatio,
3340                         v->HRatioChroma,
3341                         v->DPPPerPlane,
3342                         dummy5,
3343                         dummy6,
3344                         dummy3,
3345                         dummy4,
3346                         v->SwathHeightY,
3347                         v->SwathHeightC,
3348                         v->DETBufferSizeY,
3349                         v->DETBufferSizeC,
3350                         dummy7,
3351                         &dummysinglestring);
3352 }
3353
3354 static double CalculateTWait(unsigned int PrefetchMode, double DRAMClockChangeLatency, double UrgentLatency, double SREnterPlusExitTime)
3355 {
3356         if (PrefetchMode == 0) {
3357                 return dml_max(DRAMClockChangeLatency + UrgentLatency, dml_max(SREnterPlusExitTime, UrgentLatency));
3358         } else if (PrefetchMode == 1) {
3359                 return dml_max(SREnterPlusExitTime, UrgentLatency);
3360         } else {
3361                 return UrgentLatency;
3362         }
3363 }
3364
3365 double dml31_CalculateWriteBackDISPCLK(
3366                 enum source_format_class WritebackPixelFormat,
3367                 double PixelClock,
3368                 double WritebackHRatio,
3369                 double WritebackVRatio,
3370                 unsigned int WritebackHTaps,
3371                 unsigned int WritebackVTaps,
3372                 long WritebackSourceWidth,
3373                 long WritebackDestinationWidth,
3374                 unsigned int HTotal,
3375                 unsigned int WritebackLineBufferSize)
3376 {
3377         double DISPCLK_H, DISPCLK_V, DISPCLK_HB;
3378
3379         DISPCLK_H = PixelClock * dml_ceil(WritebackHTaps / 8.0, 1) / WritebackHRatio;
3380         DISPCLK_V = PixelClock * (WritebackVTaps * dml_ceil(WritebackDestinationWidth / 6.0, 1) + 8.0) / HTotal;
3381         DISPCLK_HB = PixelClock * WritebackVTaps * (WritebackDestinationWidth * WritebackVTaps - WritebackLineBufferSize / 57.0) / 6.0 / WritebackSourceWidth;
3382         return dml_max3(DISPCLK_H, DISPCLK_V, DISPCLK_HB);
3383 }
3384
3385 static double CalculateWriteBackDelay(
3386                 enum source_format_class WritebackPixelFormat,
3387                 double WritebackHRatio,
3388                 double WritebackVRatio,
3389                 unsigned int WritebackVTaps,
3390                 int WritebackDestinationWidth,
3391                 int WritebackDestinationHeight,
3392                 int WritebackSourceHeight,
3393                 unsigned int HTotal)
3394 {
3395         double CalculateWriteBackDelay;
3396         double Line_length;
3397         double Output_lines_last_notclamped;
3398         double WritebackVInit;
3399
3400         WritebackVInit = (WritebackVRatio + WritebackVTaps + 1) / 2;
3401         Line_length = dml_max((double) WritebackDestinationWidth, dml_ceil(WritebackDestinationWidth / 6.0, 1) * WritebackVTaps);
3402         Output_lines_last_notclamped = WritebackDestinationHeight - 1 - dml_ceil((WritebackSourceHeight - WritebackVInit) / WritebackVRatio, 1);
3403         if (Output_lines_last_notclamped < 0) {
3404                 CalculateWriteBackDelay = 0;
3405         } else {
3406                 CalculateWriteBackDelay = Output_lines_last_notclamped * Line_length + (HTotal - WritebackDestinationWidth) + 80;
3407         }
3408         return CalculateWriteBackDelay;
3409 }
3410
3411 static void CalculateVupdateAndDynamicMetadataParameters(
3412                 int MaxInterDCNTileRepeaters,
3413                 double DPPCLK,
3414                 double DISPCLK,
3415                 double DCFClkDeepSleep,
3416                 double PixelClock,
3417                 int HTotal,
3418                 int VBlank,
3419                 int DynamicMetadataTransmittedBytes,
3420                 int DynamicMetadataLinesBeforeActiveRequired,
3421                 int InterlaceEnable,
3422                 bool ProgressiveToInterlaceUnitInOPP,
3423                 double *TSetup,
3424                 double *Tdmbf,
3425                 double *Tdmec,
3426                 double *Tdmsks,
3427                 int *VUpdateOffsetPix,
3428                 double *VUpdateWidthPix,
3429                 double *VReadyOffsetPix)
3430 {
3431         double TotalRepeaterDelayTime;
3432
3433         TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2 / DPPCLK + 3 / DISPCLK);
3434         *VUpdateWidthPix = dml_ceil((14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime) * PixelClock, 1.0);
3435         *VReadyOffsetPix = dml_ceil(dml_max(150.0 / DPPCLK, TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK) * PixelClock, 1.0);
3436         *VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
3437         *TSetup = (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
3438         *Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
3439         *Tdmec = HTotal / PixelClock;
3440         if (DynamicMetadataLinesBeforeActiveRequired == 0) {
3441                 *Tdmsks = VBlank * HTotal / PixelClock / 2.0;
3442         } else {
3443                 *Tdmsks = DynamicMetadataLinesBeforeActiveRequired * HTotal / PixelClock;
3444         }
3445         if (InterlaceEnable == 1 && ProgressiveToInterlaceUnitInOPP == false) {
3446                 *Tdmsks = *Tdmsks / 2;
3447         }
3448 #ifdef __DML_VBA_DEBUG__
3449         dml_print("DML::%s: VUpdateWidthPix = %d\n", __func__, *VUpdateWidthPix);
3450         dml_print("DML::%s: VReadyOffsetPix = %d\n", __func__, *VReadyOffsetPix);
3451         dml_print("DML::%s: VUpdateOffsetPix = %d\n", __func__, *VUpdateOffsetPix);
3452 #endif
3453 }
3454
3455 static void CalculateRowBandwidth(
3456                 bool GPUVMEnable,
3457                 enum source_format_class SourcePixelFormat,
3458                 double VRatio,
3459                 double VRatioChroma,
3460                 bool DCCEnable,
3461                 double LineTime,
3462                 unsigned int MetaRowByteLuma,
3463                 unsigned int MetaRowByteChroma,
3464                 unsigned int meta_row_height_luma,
3465                 unsigned int meta_row_height_chroma,
3466                 unsigned int PixelPTEBytesPerRowLuma,
3467                 unsigned int PixelPTEBytesPerRowChroma,
3468                 unsigned int dpte_row_height_luma,
3469                 unsigned int dpte_row_height_chroma,
3470                 double *meta_row_bw,
3471                 double *dpte_row_bw)
3472 {
3473         if (DCCEnable != true) {
3474                 *meta_row_bw = 0;
3475         } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
3476                 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime) + VRatioChroma * MetaRowByteChroma / (meta_row_height_chroma * LineTime);
3477         } else {
3478                 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
3479         }
3480
3481         if (GPUVMEnable != true) {
3482                 *dpte_row_bw = 0;
3483         } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10 || SourcePixelFormat == dm_420_12 || SourcePixelFormat == dm_rgbe_alpha) {
3484                 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
3485                                 + VRatioChroma * PixelPTEBytesPerRowChroma / (dpte_row_height_chroma * LineTime);
3486         } else {
3487                 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
3488         }
3489 }
3490
3491 static void CalculateFlipSchedule(
3492                 struct display_mode_lib *mode_lib,
3493                 unsigned int k,
3494                 double HostVMInefficiencyFactor,
3495                 double UrgentExtraLatency,
3496                 double UrgentLatency,
3497                 double PDEAndMetaPTEBytesPerFrame,
3498                 double MetaRowBytes,
3499                 double DPTEBytesPerRow)
3500 {
3501         struct vba_vars_st *v = &mode_lib->vba;
3502         double min_row_time = 0.0;
3503         unsigned int HostVMDynamicLevelsTrips;
3504         double TimeForFetchingMetaPTEImmediateFlip;
3505         double TimeForFetchingRowInVBlankImmediateFlip;
3506         double ImmediateFlipBW;
3507         double LineTime = v->HTotal[k] / v->PixelClock[k];
3508
3509         if (v->GPUVMEnable == true && v->HostVMEnable == true) {
3510                 HostVMDynamicLevelsTrips = v->HostVMMaxNonCachedPageTableLevels;
3511         } else {
3512                 HostVMDynamicLevelsTrips = 0;
3513         }
3514
3515         if (v->GPUVMEnable == true || v->DCCEnable[k] == true) {
3516                 ImmediateFlipBW = (PDEAndMetaPTEBytesPerFrame + MetaRowBytes + DPTEBytesPerRow) * v->BandwidthAvailableForImmediateFlip / v->TotImmediateFlipBytes;
3517         }
3518
3519         if (v->GPUVMEnable == true) {
3520                 TimeForFetchingMetaPTEImmediateFlip = dml_max3(
3521                                 v->Tno_bw[k] + PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / ImmediateFlipBW,
3522                                 UrgentExtraLatency + UrgentLatency * (v->GPUVMMaxPageTableLevels * (HostVMDynamicLevelsTrips + 1) - 1),
3523                                 LineTime / 4.0);
3524         } else {
3525                 TimeForFetchingMetaPTEImmediateFlip = 0;
3526         }
3527
3528         v->DestinationLinesToRequestVMInImmediateFlip[k] = dml_ceil(4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime), 1) / 4.0;
3529         if ((v->GPUVMEnable == true || v->DCCEnable[k] == true)) {
3530                 TimeForFetchingRowInVBlankImmediateFlip = dml_max3(
3531                                 (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / ImmediateFlipBW,
3532                                 UrgentLatency * (HostVMDynamicLevelsTrips + 1),
3533                                 LineTime / 4);
3534         } else {
3535                 TimeForFetchingRowInVBlankImmediateFlip = 0;
3536         }
3537
3538         v->DestinationLinesToRequestRowInImmediateFlip[k] = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0;
3539
3540         if (v->GPUVMEnable == true) {
3541                 v->final_flip_bw[k] = dml_max(
3542                                 PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (v->DestinationLinesToRequestVMInImmediateFlip[k] * LineTime),
3543                                 (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (v->DestinationLinesToRequestRowInImmediateFlip[k] * LineTime));
3544         } else if ((v->GPUVMEnable == true || v->DCCEnable[k] == true)) {
3545                 v->final_flip_bw[k] = (MetaRowBytes + DPTEBytesPerRow * HostVMInefficiencyFactor) / (v->DestinationLinesToRequestRowInImmediateFlip[k] * LineTime);
3546         } else {
3547                 v->final_flip_bw[k] = 0;
3548         }
3549
3550         if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_rgbe_alpha) {
3551                 if (v->GPUVMEnable == true && v->DCCEnable[k] != true) {
3552                         min_row_time = dml_min(v->dpte_row_height[k] * LineTime / v->VRatio[k], v->dpte_row_height_chroma[k] * LineTime / v->VRatioChroma[k]);
3553                 } else if (v->GPUVMEnable != true && v->DCCEnable[k] == true) {
3554                         min_row_time = dml_min(v->meta_row_height[k] * LineTime / v->VRatio[k], v->meta_row_height_chroma[k] * LineTime / v->VRatioChroma[k]);
3555                 } else {
3556                         min_row_time = dml_min4(
3557                                         v->dpte_row_height[k] * LineTime / v->VRatio[k],
3558                                         v->meta_row_height[k] * LineTime / v->VRatio[k],
3559                                         v->dpte_row_height_chroma[k] * LineTime / v->VRatioChroma[k],
3560                                         v->meta_row_height_chroma[k] * LineTime / v->VRatioChroma[k]);
3561                 }
3562         } else {
3563                 if (v->GPUVMEnable == true && v->DCCEnable[k] != true) {
3564                         min_row_time = v->dpte_row_height[k] * LineTime / v->VRatio[k];
3565                 } else if (v->GPUVMEnable != true && v->DCCEnable[k] == true) {
3566                         min_row_time = v->meta_row_height[k] * LineTime / v->VRatio[k];
3567                 } else {
3568                         min_row_time = dml_min(v->dpte_row_height[k] * LineTime / v->VRatio[k], v->meta_row_height[k] * LineTime / v->VRatio[k]);
3569                 }
3570         }
3571
3572         if (v->DestinationLinesToRequestVMInImmediateFlip[k] >= 32 || v->DestinationLinesToRequestRowInImmediateFlip[k] >= 16
3573                         || TimeForFetchingMetaPTEImmediateFlip + 2 * TimeForFetchingRowInVBlankImmediateFlip > min_row_time) {
3574                 v->ImmediateFlipSupportedForPipe[k] = false;
3575         } else {
3576                 v->ImmediateFlipSupportedForPipe[k] = true;
3577         }
3578
3579 #ifdef __DML_VBA_DEBUG__
3580         dml_print("DML::%s: DestinationLinesToRequestVMInImmediateFlip = %f\n", __func__, v->DestinationLinesToRequestVMInImmediateFlip[k]);
3581         dml_print("DML::%s: DestinationLinesToRequestRowInImmediateFlip = %f\n", __func__, v->DestinationLinesToRequestRowInImmediateFlip[k]);
3582         dml_print("DML::%s: TimeForFetchingMetaPTEImmediateFlip = %f\n", __func__, TimeForFetchingMetaPTEImmediateFlip);
3583         dml_print("DML::%s: TimeForFetchingRowInVBlankImmediateFlip = %f\n", __func__, TimeForFetchingRowInVBlankImmediateFlip);
3584         dml_print("DML::%s: min_row_time = %f\n", __func__, min_row_time);
3585         dml_print("DML::%s: ImmediateFlipSupportedForPipe = %d\n", __func__, v->ImmediateFlipSupportedForPipe[k]);
3586 #endif
3587
3588 }
3589
3590 static double TruncToValidBPP(
3591                 double LinkBitRate,
3592                 int Lanes,
3593                 int HTotal,
3594                 int HActive,
3595                 double PixelClock,
3596                 double DesiredBPP,
3597                 bool DSCEnable,
3598                 enum output_encoder_class Output,
3599                 enum output_format_class Format,
3600                 unsigned int DSCInputBitPerComponent,
3601                 int DSCSlices,
3602                 int AudioRate,
3603                 int AudioLayout,
3604                 enum odm_combine_mode ODMCombine)
3605 {
3606         double MaxLinkBPP;
3607         int MinDSCBPP;
3608         double MaxDSCBPP;
3609         int NonDSCBPP0;
3610         int NonDSCBPP1;
3611         int NonDSCBPP2;
3612
3613         if (Format == dm_420) {
3614                 NonDSCBPP0 = 12;
3615                 NonDSCBPP1 = 15;
3616                 NonDSCBPP2 = 18;
3617                 MinDSCBPP = 6;
3618                 MaxDSCBPP = 1.5 * DSCInputBitPerComponent - 1 / 16;
3619         } else if (Format == dm_444) {
3620                 NonDSCBPP0 = 24;
3621                 NonDSCBPP1 = 30;
3622                 NonDSCBPP2 = 36;
3623                 MinDSCBPP = 8;
3624                 MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16;
3625         } else {
3626
3627                 NonDSCBPP0 = 16;
3628                 NonDSCBPP1 = 20;
3629                 NonDSCBPP2 = 24;
3630
3631                 if (Format == dm_n422) {
3632                         MinDSCBPP = 7;
3633                         MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0;
3634                 } else {
3635                         MinDSCBPP = 8;
3636                         MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16.0;
3637                 }
3638         }
3639
3640         if (DSCEnable && Output == dm_dp) {
3641                 MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock * (1 - 2.4 / 100);
3642         } else {
3643                 MaxLinkBPP = LinkBitRate / 10 * 8 * Lanes / PixelClock;
3644         }
3645
3646         if (ODMCombine == dm_odm_combine_mode_4to1 && MaxLinkBPP > 16) {
3647                 MaxLinkBPP = 16;
3648         } else if (ODMCombine == dm_odm_combine_mode_2to1 && MaxLinkBPP > 32) {
3649                 MaxLinkBPP = 32;
3650         }
3651
3652         if (DesiredBPP == 0) {
3653                 if (DSCEnable) {
3654                         if (MaxLinkBPP < MinDSCBPP) {
3655                                 return BPP_INVALID;
3656                         } else if (MaxLinkBPP >= MaxDSCBPP) {
3657                                 return MaxDSCBPP;
3658                         } else {
3659                                 return dml_floor(16.0 * MaxLinkBPP, 1.0) / 16.0;
3660                         }
3661                 } else {
3662                         if (MaxLinkBPP >= NonDSCBPP2) {
3663                                 return NonDSCBPP2;
3664                         } else if (MaxLinkBPP >= NonDSCBPP1) {
3665                                 return NonDSCBPP1;
3666                         } else if (MaxLinkBPP >= NonDSCBPP0) {
3667                                 return 16.0;
3668                         } else {
3669                                 return BPP_INVALID;
3670                         }
3671                 }
3672         } else {
3673                 if (!((DSCEnable == false && (DesiredBPP == NonDSCBPP2 || DesiredBPP == NonDSCBPP1 || DesiredBPP <= NonDSCBPP0))
3674                                 || (DSCEnable && DesiredBPP >= MinDSCBPP && DesiredBPP <= MaxDSCBPP))) {
3675                         return BPP_INVALID;
3676                 } else {
3677                         return DesiredBPP;
3678                 }
3679         }
3680         return BPP_INVALID;
3681 }
3682
3683 static noinline void CalculatePrefetchSchedulePerPlane(
3684                 struct display_mode_lib *mode_lib,
3685                 double HostVMInefficiencyFactor,
3686                 int i,
3687                 unsigned j,
3688                 unsigned k)
3689 {
3690         struct vba_vars_st *v = &mode_lib->vba;
3691         Pipe myPipe;
3692
3693         myPipe.DPPCLK = v->RequiredDPPCLK[i][j][k];
3694         myPipe.DISPCLK = v->RequiredDISPCLK[i][j];
3695         myPipe.PixelClock = v->PixelClock[k];
3696         myPipe.DCFCLKDeepSleep = v->ProjectedDCFCLKDeepSleep[i][j];
3697         myPipe.DPPPerPlane = v->NoOfDPP[i][j][k];
3698         myPipe.ScalerEnabled = v->ScalerEnabled[k];
3699         myPipe.VRatio = mode_lib->vba.VRatio[k];
3700         myPipe.VRatioChroma = mode_lib->vba.VRatioChroma[k];
3701
3702         myPipe.SourceScan = v->SourceScan[k];
3703         myPipe.BlockWidth256BytesY = v->Read256BlockWidthY[k];
3704         myPipe.BlockHeight256BytesY = v->Read256BlockHeightY[k];
3705         myPipe.BlockWidth256BytesC = v->Read256BlockWidthC[k];
3706         myPipe.BlockHeight256BytesC = v->Read256BlockHeightC[k];
3707         myPipe.InterlaceEnable = v->Interlace[k];
3708         myPipe.NumberOfCursors = v->NumberOfCursors[k];
3709         myPipe.VBlank = v->VTotal[k] - v->VActive[k];
3710         myPipe.HTotal = v->HTotal[k];
3711         myPipe.DCCEnable = v->DCCEnable[k];
3712         myPipe.ODMCombineIsEnabled = v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1
3713                 || v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1;
3714         myPipe.SourcePixelFormat = v->SourcePixelFormat[k];
3715         myPipe.BytePerPixelY = v->BytePerPixelY[k];
3716         myPipe.BytePerPixelC = v->BytePerPixelC[k];
3717         myPipe.ProgressiveToInterlaceUnitInOPP = v->ProgressiveToInterlaceUnitInOPP;
3718         v->NoTimeForPrefetch[i][j][k] = CalculatePrefetchSchedule(
3719                 mode_lib,
3720                 HostVMInefficiencyFactor,
3721                 &myPipe,
3722                 v->DSCDelayPerState[i][k],
3723                 v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater,
3724                 v->DPPCLKDelaySCL,
3725                 v->DPPCLKDelaySCLLBOnly,
3726                 v->DPPCLKDelayCNVCCursor,
3727                 v->DISPCLKDelaySubtotal,
3728                 v->SwathWidthYThisState[k] / v->HRatio[k],
3729                 v->OutputFormat[k],
3730                 v->MaxInterDCNTileRepeaters,
3731                 dml_min(v->MaxVStartup, v->MaximumVStartup[i][j][k]),
3732                 v->MaximumVStartup[i][j][k],
3733                 v->GPUVMMaxPageTableLevels,
3734                 v->GPUVMEnable,
3735                 v->HostVMEnable,
3736                 v->HostVMMaxNonCachedPageTableLevels,
3737                 v->HostVMMinPageSize,
3738                 v->DynamicMetadataEnable[k],
3739                 v->DynamicMetadataVMEnabled,
3740                 v->DynamicMetadataLinesBeforeActiveRequired[k],
3741                 v->DynamicMetadataTransmittedBytes[k],
3742                 v->UrgLatency[i],
3743                 v->ExtraLatency,
3744                 v->TimeCalc,
3745                 v->PDEAndMetaPTEBytesPerFrame[i][j][k],
3746                 v->MetaRowBytes[i][j][k],
3747                 v->DPTEBytesPerRow[i][j][k],
3748                 v->PrefetchLinesY[i][j][k],
3749                 v->SwathWidthYThisState[k],
3750                 v->PrefillY[k],
3751                 v->MaxNumSwY[k],
3752                 v->PrefetchLinesC[i][j][k],
3753                 v->SwathWidthCThisState[k],
3754                 v->PrefillC[k],
3755                 v->MaxNumSwC[k],
3756                 v->swath_width_luma_ub_this_state[k],
3757                 v->swath_width_chroma_ub_this_state[k],
3758                 v->SwathHeightYThisState[k],
3759                 v->SwathHeightCThisState[k],
3760                 v->TWait,
3761                 &v->DSTXAfterScaler[k],
3762                 &v->DSTYAfterScaler[k],
3763                 &v->LineTimesForPrefetch[k],
3764                 &v->PrefetchBW[k],
3765                 &v->LinesForMetaPTE[k],
3766                 &v->LinesForMetaAndDPTERow[k],
3767                 &v->VRatioPreY[i][j][k],
3768                 &v->VRatioPreC[i][j][k],
3769                 &v->RequiredPrefetchPixelDataBWLuma[i][j][k],
3770                 &v->RequiredPrefetchPixelDataBWChroma[i][j][k],
3771                 &v->NoTimeForDynamicMetadata[i][j][k],
3772                 &v->Tno_bw[k],
3773                 &v->prefetch_vmrow_bw[k],
3774                 &v->dummy7[k],
3775                 &v->dummy8[k],
3776                 &v->dummy13[k],
3777                 &v->VUpdateOffsetPix[k],
3778                 &v->VUpdateWidthPix[k],
3779                 &v->VReadyOffsetPix[k]);
3780 }
3781
3782 static void PatchDETBufferSizeInKByte(unsigned int NumberOfActivePlanes, int NoOfDPPThisState[], unsigned int config_return_buffer_size_in_kbytes, unsigned int *DETBufferSizeInKByte)
3783 {
3784         int i, total_pipes = 0;
3785         for (i = 0; i < NumberOfActivePlanes; i++)
3786                 total_pipes += NoOfDPPThisState[i];
3787         *DETBufferSizeInKByte = ((config_return_buffer_size_in_kbytes - DCN3_15_MIN_COMPBUF_SIZE_KB) / 64 / total_pipes) * 64;
3788         if (*DETBufferSizeInKByte > DCN3_15_MAX_DET_SIZE)
3789                 *DETBufferSizeInKByte = DCN3_15_MAX_DET_SIZE;
3790 }
3791
3792
3793 void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
3794 {
3795         struct vba_vars_st *v = &mode_lib->vba;
3796
3797         int i, j;
3798         unsigned int k, m;
3799         int ReorderingBytes;
3800         int MinPrefetchMode = 0, MaxPrefetchMode = 2;
3801         bool NoChroma = true;
3802         bool EnoughWritebackUnits = true;
3803         bool P2IWith420 = false;
3804         bool DSCOnlyIfNecessaryWithBPP = false;
3805         bool DSC422NativeNotSupported = false;
3806         double MaxTotalVActiveRDBandwidth;
3807         bool ViewportExceedsSurface = false;
3808         bool FMTBufferExceeded = false;
3809
3810         /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
3811
3812         CalculateMinAndMaxPrefetchMode(
3813                 mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank,
3814                 &MinPrefetchMode, &MaxPrefetchMode);
3815
3816         /*Scale Ratio, taps Support Check*/
3817
3818         v->ScaleRatioAndTapsSupport = true;
3819         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3820                 if (v->ScalerEnabled[k] == false
3821                                 && ((v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32
3822                                                 && v->SourcePixelFormat[k] != dm_444_16 && v->SourcePixelFormat[k] != dm_mono_16
3823                                                 && v->SourcePixelFormat[k] != dm_mono_8 && v->SourcePixelFormat[k] != dm_rgbe
3824                                                 && v->SourcePixelFormat[k] != dm_rgbe_alpha) || v->HRatio[k] != 1.0 || v->htaps[k] != 1.0
3825                                                 || v->VRatio[k] != 1.0 || v->vtaps[k] != 1.0)) {
3826                         v->ScaleRatioAndTapsSupport = false;
3827                 } else if (v->vtaps[k] < 1.0 || v->vtaps[k] > 8.0 || v->htaps[k] < 1.0 || v->htaps[k] > 8.0
3828                                 || (v->htaps[k] > 1.0 && (v->htaps[k] % 2) == 1) || v->HRatio[k] > v->MaxHSCLRatio
3829                                 || v->VRatio[k] > v->MaxVSCLRatio || v->HRatio[k] > v->htaps[k]
3830                                 || v->VRatio[k] > v->vtaps[k]
3831                                 || (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32
3832                                                 && v->SourcePixelFormat[k] != dm_444_16 && v->SourcePixelFormat[k] != dm_mono_16
3833                                                 && v->SourcePixelFormat[k] != dm_mono_8 && v->SourcePixelFormat[k] != dm_rgbe
3834                                                 && (v->VTAPsChroma[k] < 1 || v->VTAPsChroma[k] > 8 || v->HTAPsChroma[k] < 1
3835                                                                 || v->HTAPsChroma[k] > 8 || (v->HTAPsChroma[k] > 1 && v->HTAPsChroma[k] % 2 == 1)
3836                                                                 || v->HRatioChroma[k] > v->MaxHSCLRatio
3837                                                                 || v->VRatioChroma[k] > v->MaxVSCLRatio
3838                                                                 || v->HRatioChroma[k] > v->HTAPsChroma[k]
3839                                                                 || v->VRatioChroma[k] > v->VTAPsChroma[k]))) {
3840                         v->ScaleRatioAndTapsSupport = false;
3841                 }
3842         }
3843         /*Source Format, Pixel Format and Scan Support Check*/
3844
3845         v->SourceFormatPixelAndScanSupport = true;
3846         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3847                 if ((v->SurfaceTiling[k] == dm_sw_linear && (!(v->SourceScan[k] != dm_vert) || v->DCCEnable[k] == true))
3848                                 || ((v->SurfaceTiling[k] == dm_sw_64kb_d || v->SurfaceTiling[k] == dm_sw_64kb_d_t
3849                                                 || v->SurfaceTiling[k] == dm_sw_64kb_d_x) && !(v->SourcePixelFormat[k] == dm_444_64))) {
3850                         v->SourceFormatPixelAndScanSupport = false;
3851                 }
3852         }
3853         /*Bandwidth Support Check*/
3854
3855         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3856                 dml30_CalculateBytePerPixelAnd256BBlockSizes(
3857                                 v->SourcePixelFormat[k],
3858                                 v->SurfaceTiling[k],
3859                                 &v->BytePerPixelY[k],
3860                                 &v->BytePerPixelC[k],
3861                                 &v->BytePerPixelInDETY[k],
3862                                 &v->BytePerPixelInDETC[k],
3863                                 &v->Read256BlockHeightY[k],
3864                                 &v->Read256BlockHeightC[k],
3865                                 &v->Read256BlockWidthY[k],
3866                                 &v->Read256BlockWidthC[k]);
3867         }
3868         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3869                 if (v->SourceScan[k] != dm_vert) {
3870                         v->SwathWidthYSingleDPP[k] = v->ViewportWidth[k];
3871                         v->SwathWidthCSingleDPP[k] = v->ViewportWidthChroma[k];
3872                 } else {
3873                         v->SwathWidthYSingleDPP[k] = v->ViewportHeight[k];
3874                         v->SwathWidthCSingleDPP[k] = v->ViewportHeightChroma[k];
3875                 }
3876         }
3877         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3878                 v->ReadBandwidthLuma[k] = v->SwathWidthYSingleDPP[k] * dml_ceil(v->BytePerPixelInDETY[k], 1.0)
3879                                 / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
3880                 v->ReadBandwidthChroma[k] = v->SwathWidthYSingleDPP[k] / 2 * dml_ceil(v->BytePerPixelInDETC[k], 2.0)
3881                                 / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k] / 2.0;
3882         }
3883         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3884                 if (v->WritebackEnable[k] == true && v->WritebackPixelFormat[k] == dm_444_64) {
3885                         v->WriteBandwidth[k] = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3886                                         / (v->WritebackSourceHeight[k] * v->HTotal[k] / v->PixelClock[k]) * 8.0;
3887                 } else if (v->WritebackEnable[k] == true) {
3888                         v->WriteBandwidth[k] = v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k]
3889                                         / (v->WritebackSourceHeight[k] * v->HTotal[k] / v->PixelClock[k]) * 4.0;
3890                 } else {
3891                         v->WriteBandwidth[k] = 0.0;
3892                 }
3893         }
3894
3895         /*Writeback Latency support check*/
3896
3897         v->WritebackLatencySupport = true;
3898         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3899                 if (v->WritebackEnable[k] == true && (v->WriteBandwidth[k] > v->WritebackInterfaceBufferSize * 1024 / v->WritebackLatency)) {
3900                         v->WritebackLatencySupport = false;
3901                 }
3902         }
3903
3904         /*Writeback Mode Support Check*/
3905
3906         v->TotalNumberOfActiveWriteback = 0;
3907         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3908                 if (v->WritebackEnable[k] == true) {
3909                         v->TotalNumberOfActiveWriteback = v->TotalNumberOfActiveWriteback + 1;
3910                 }
3911         }
3912
3913         if (v->TotalNumberOfActiveWriteback > v->MaxNumWriteback) {
3914                 EnoughWritebackUnits = false;
3915         }
3916
3917         /*Writeback Scale Ratio and Taps Support Check*/
3918
3919         v->WritebackScaleRatioAndTapsSupport = true;
3920         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3921                 if (v->WritebackEnable[k] == true) {
3922                         if (v->WritebackHRatio[k] > v->WritebackMaxHSCLRatio || v->WritebackVRatio[k] > v->WritebackMaxVSCLRatio
3923                                         || v->WritebackHRatio[k] < v->WritebackMinHSCLRatio
3924                                         || v->WritebackVRatio[k] < v->WritebackMinVSCLRatio
3925                                         || v->WritebackHTaps[k] > v->WritebackMaxHSCLTaps
3926                                         || v->WritebackVTaps[k] > v->WritebackMaxVSCLTaps
3927                                         || v->WritebackHRatio[k] > v->WritebackHTaps[k] || v->WritebackVRatio[k] > v->WritebackVTaps[k]
3928                                         || (v->WritebackHTaps[k] > 2.0 && ((v->WritebackHTaps[k] % 2) == 1))) {
3929                                 v->WritebackScaleRatioAndTapsSupport = false;
3930                         }
3931                         if (2.0 * v->WritebackDestinationWidth[k] * (v->WritebackVTaps[k] - 1) * 57 > v->WritebackLineBufferSize) {
3932                                 v->WritebackScaleRatioAndTapsSupport = false;
3933                         }
3934                 }
3935         }
3936         /*Maximum DISPCLK/DPPCLK Support check*/
3937
3938         v->WritebackRequiredDISPCLK = 0.0;
3939         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3940                 if (v->WritebackEnable[k] == true) {
3941                         v->WritebackRequiredDISPCLK = dml_max(
3942                                         v->WritebackRequiredDISPCLK,
3943                                         dml31_CalculateWriteBackDISPCLK(
3944                                                         v->WritebackPixelFormat[k],
3945                                                         v->PixelClock[k],
3946                                                         v->WritebackHRatio[k],
3947                                                         v->WritebackVRatio[k],
3948                                                         v->WritebackHTaps[k],
3949                                                         v->WritebackVTaps[k],
3950                                                         v->WritebackSourceWidth[k],
3951                                                         v->WritebackDestinationWidth[k],
3952                                                         v->HTotal[k],
3953                                                         v->WritebackLineBufferSize));
3954                 }
3955         }
3956         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3957                 if (v->HRatio[k] > 1.0) {
3958                         v->PSCL_FACTOR[k] = dml_min(
3959                                         v->MaxDCHUBToPSCLThroughput,
3960                                         v->MaxPSCLToLBThroughput * v->HRatio[k] / dml_ceil(v->htaps[k] / 6.0, 1.0));
3961                 } else {
3962                         v->PSCL_FACTOR[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
3963                 }
3964                 if (v->BytePerPixelC[k] == 0.0) {
3965                         v->PSCL_FACTOR_CHROMA[k] = 0.0;
3966                         v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k]
3967                                         * dml_max3(
3968                                                         v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
3969                                                         v->HRatio[k] * v->VRatio[k] / v->PSCL_FACTOR[k],
3970                                                         1.0);
3971                         if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0) && v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
3972                                 v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
3973                         }
3974                 } else {
3975                         if (v->HRatioChroma[k] > 1.0) {
3976                                 v->PSCL_FACTOR_CHROMA[k] = dml_min(
3977                                                 v->MaxDCHUBToPSCLThroughput,
3978                                                 v->MaxPSCLToLBThroughput * v->HRatioChroma[k] / dml_ceil(v->HTAPsChroma[k] / 6.0, 1.0));
3979                         } else {
3980                                 v->PSCL_FACTOR_CHROMA[k] = dml_min(v->MaxDCHUBToPSCLThroughput, v->MaxPSCLToLBThroughput);
3981                         }
3982                         v->MinDPPCLKUsingSingleDPP[k] = v->PixelClock[k]
3983                                         * dml_max5(
3984                                                         v->vtaps[k] / 6.0 * dml_min(1.0, v->HRatio[k]),
3985                                                         v->HRatio[k] * v->VRatio[k] / v->PSCL_FACTOR[k],
3986                                                         v->VTAPsChroma[k] / 6.0 * dml_min(1.0, v->HRatioChroma[k]),
3987                                                         v->HRatioChroma[k] * v->VRatioChroma[k] / v->PSCL_FACTOR_CHROMA[k],
3988                                                         1.0);
3989                         if ((v->htaps[k] > 6.0 || v->vtaps[k] > 6.0 || v->HTAPsChroma[k] > 6.0 || v->VTAPsChroma[k] > 6.0)
3990                                         && v->MinDPPCLKUsingSingleDPP[k] < 2.0 * v->PixelClock[k]) {
3991                                 v->MinDPPCLKUsingSingleDPP[k] = 2.0 * v->PixelClock[k];
3992                         }
3993                 }
3994         }
3995         for (k = 0; k < v->NumberOfActivePlanes; k++) {
3996                 int MaximumSwathWidthSupportLuma;
3997                 int MaximumSwathWidthSupportChroma;
3998
3999                 if (v->SurfaceTiling[k] == dm_sw_linear) {
4000                         MaximumSwathWidthSupportLuma = 8192.0;
4001                 } else if (v->SourceScan[k] == dm_vert && v->BytePerPixelC[k] > 0) {
4002                         MaximumSwathWidthSupportLuma = 2880.0;
4003                 } else if (v->SourcePixelFormat[k] == dm_rgbe_alpha) {
4004                         MaximumSwathWidthSupportLuma = 3840.0;
4005                 } else {
4006                         MaximumSwathWidthSupportLuma = 5760.0;
4007                 }
4008
4009                 if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12) {
4010                         MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma / 2.0;
4011                 } else {
4012                         MaximumSwathWidthSupportChroma = MaximumSwathWidthSupportLuma;
4013                 }
4014                 v->MaximumSwathWidthInLineBufferLuma = v->LineBufferSize * dml_max(v->HRatio[k], 1.0) / v->LBBitPerPixel[k]
4015                                 / (v->vtaps[k] + dml_max(dml_ceil(v->VRatio[k], 1.0) - 2, 0.0));
4016                 if (v->BytePerPixelC[k] == 0.0) {
4017                         v->MaximumSwathWidthInLineBufferChroma = 0;
4018                 } else {
4019                         v->MaximumSwathWidthInLineBufferChroma = v->LineBufferSize * dml_max(v->HRatioChroma[k], 1.0) / v->LBBitPerPixel[k]
4020                                         / (v->VTAPsChroma[k] + dml_max(dml_ceil(v->VRatioChroma[k], 1.0) - 2, 0.0));
4021                 }
4022                 v->MaximumSwathWidthLuma[k] = dml_min(MaximumSwathWidthSupportLuma, v->MaximumSwathWidthInLineBufferLuma);
4023                 v->MaximumSwathWidthChroma[k] = dml_min(MaximumSwathWidthSupportChroma, v->MaximumSwathWidthInLineBufferChroma);
4024         }
4025
4026         CalculateSwathAndDETConfiguration(
4027                         true,
4028                         v->NumberOfActivePlanes,
4029                         v->DETBufferSizeInKByte[0],
4030                         v->MaximumSwathWidthLuma,
4031                         v->MaximumSwathWidthChroma,
4032                         v->SourceScan,
4033                         v->SourcePixelFormat,
4034                         v->SurfaceTiling,
4035                         v->ViewportWidth,
4036                         v->ViewportHeight,
4037                         v->SurfaceWidthY,
4038                         v->SurfaceWidthC,
4039                         v->SurfaceHeightY,
4040                         v->SurfaceHeightC,
4041                         v->Read256BlockHeightY,
4042                         v->Read256BlockHeightC,
4043                         v->Read256BlockWidthY,
4044                         v->Read256BlockWidthC,
4045                         v->odm_combine_dummy,
4046                         v->BlendingAndTiming,
4047                         v->BytePerPixelY,
4048                         v->BytePerPixelC,
4049                         v->BytePerPixelInDETY,
4050                         v->BytePerPixelInDETC,
4051                         v->HActive,
4052                         v->HRatio,
4053                         v->HRatioChroma,
4054                         v->NoOfDPPThisState,
4055                         v->swath_width_luma_ub_this_state,
4056                         v->swath_width_chroma_ub_this_state,
4057                         v->SwathWidthYThisState,
4058                         v->SwathWidthCThisState,
4059                         v->SwathHeightYThisState,
4060                         v->SwathHeightCThisState,
4061                         v->DETBufferSizeYThisState,
4062                         v->DETBufferSizeCThisState,
4063                         v->SingleDPPViewportSizeSupportPerPlane,
4064                         &v->ViewportSizeSupport[0][0]);
4065
4066         for (i = 0; i < v->soc.num_states; i++) {
4067                 for (j = 0; j < 2; j++) {
4068                         v->MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDispclk[i], v->DISPCLKDPPCLKVCOSpeed);
4069                         v->MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(v->MaxDppclk[i], v->DISPCLKDPPCLKVCOSpeed);
4070                         v->RequiredDISPCLK[i][j] = 0.0;
4071                         v->DISPCLK_DPPCLK_Support[i][j] = true;
4072                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
4073                                 v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4074                                                 * (1.0 + v->DISPCLKRampingMargin / 100.0);
4075                                 if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i]
4076                                                 && v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4077                                                 && v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4078                                         v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k]
4079                                                         * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4080                                 }
4081                                 v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4082                                                 * (1 + v->DISPCLKRampingMargin / 100.0);
4083                                 if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i]
4084                                                 && v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4085                                                 && v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4086                                         v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2
4087                                                         * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4088                                 }
4089                                 v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4090                                                 * (1 + v->DISPCLKRampingMargin / 100.0);
4091                                 if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i]
4092                                                 && v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4093                                                 && v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4094                                         v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4
4095                                                         * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4096                                 }
4097
4098                                 if (v->ODMCombinePolicy == dm_odm_combine_policy_none
4099                                                 || !(v->Output[k] == dm_dp ||
4100                                                      v->Output[k] == dm_dp2p0 ||
4101                                                      v->Output[k] == dm_edp)) {
4102                                         v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
4103                                         v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
4104
4105                                         if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH)
4106                                                 FMTBufferExceeded = true;
4107                                 } else if (v->ODMCombinePolicy == dm_odm_combine_policy_2to1) {
4108                                         v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4109                                         v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4110                                 } else if (v->ODMCombinePolicy == dm_odm_combine_policy_4to1
4111                                                 || v->PlaneRequiredDISPCLKWithODMCombine2To1 > v->MaxDispclkRoundedDownToDFSGranularity) {
4112                                         v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4113                                         v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4114                                 } else if (v->PlaneRequiredDISPCLKWithoutODMCombine > v->MaxDispclkRoundedDownToDFSGranularity) {
4115                                         v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4116                                         v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4117                                 } else {
4118                                         v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
4119                                         v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine;
4120                                 }
4121                                 if (v->DSCEnabled[k] && v->HActive[k] > DCN31_MAX_DSC_IMAGE_WIDTH
4122                                                 && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
4123                                         if (v->HActive[k] / 2 > DCN31_MAX_DSC_IMAGE_WIDTH) {
4124                                                 v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4125                                                 v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4126                                         } else {
4127                                                 v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4128                                                 v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4129                                         }
4130                                 }
4131                                 if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN31_MAX_FMT_420_BUFFER_WIDTH
4132                                                 && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
4133                                         if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH) {
4134                                                 v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
4135                                                 v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
4136
4137                                                 if (v->HActive[k] / 4 > DCN31_MAX_FMT_420_BUFFER_WIDTH)
4138                                                         FMTBufferExceeded = true;
4139                                         } else {
4140                                                 v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1;
4141                                                 v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1;
4142                                         }
4143                                 }
4144                                 if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
4145                                         v->MPCCombine[i][j][k] = false;
4146                                         v->NoOfDPP[i][j][k] = 4;
4147                                         v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 4;
4148                                 } else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4149                                         v->MPCCombine[i][j][k] = false;
4150                                         v->NoOfDPP[i][j][k] = 2;
4151                                         v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2;
4152                                 } else if ((v->WhenToDoMPCCombine == dm_mpc_never
4153                                                 || (v->MinDPPCLKUsingSingleDPP[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4154                                                                 <= v->MaxDppclkRoundedDownToDFSGranularity && v->SingleDPPViewportSizeSupportPerPlane[k] == true))) {
4155                                         v->MPCCombine[i][j][k] = false;
4156                                         v->NoOfDPP[i][j][k] = 1;
4157                                         v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4158                                 } else {
4159                                         v->MPCCombine[i][j][k] = true;
4160                                         v->NoOfDPP[i][j][k] = 2;
4161                                         v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
4162                                 }
4163                                 v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
4164                                 if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4165                                                 > v->MaxDppclkRoundedDownToDFSGranularity)
4166                                                 || (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
4167                                         v->DISPCLK_DPPCLK_Support[i][j] = false;
4168                                 }
4169                         }
4170                         v->TotalNumberOfActiveDPP[i][j] = 0;
4171                         v->TotalNumberOfSingleDPPPlanes[i][j] = 0;
4172                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
4173                                 v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4174                                 if (v->NoOfDPP[i][j][k] == 1)
4175                                         v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] + 1;
4176                                 if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10
4177                                                 || v->SourcePixelFormat[k] == dm_420_12 || v->SourcePixelFormat[k] == dm_rgbe_alpha)
4178                                         NoChroma = false;
4179                         }
4180
4181                         // UPTO
4182                         if (j == 1 && v->WhenToDoMPCCombine != dm_mpc_never
4183                                         && !UnboundedRequest(v->UseUnboundedRequesting, v->TotalNumberOfActiveDPP[i][j], NoChroma, v->Output[0])) {
4184                                 while (!(v->TotalNumberOfActiveDPP[i][j] >= v->MaxNumDPP || v->TotalNumberOfSingleDPPPlanes[i][j] == 0)) {
4185                                         double BWOfNonSplitPlaneOfMaximumBandwidth;
4186                                         unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
4187                                         BWOfNonSplitPlaneOfMaximumBandwidth = 0;
4188                                         NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
4189                                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4190                                                 if (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k] > BWOfNonSplitPlaneOfMaximumBandwidth
4191                                                                 && v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled && v->MPCCombine[i][j][k] == false) {
4192                                                         BWOfNonSplitPlaneOfMaximumBandwidth = v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
4193                                                         NumberOfNonSplitPlaneOfMaximumBandwidth = k;
4194                                                 }
4195                                         }
4196                                         v->MPCCombine[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = true;
4197                                         v->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
4198                                         v->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
4199                                                         v->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
4200                                                                         * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
4201                                         v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + 1;
4202                                         v->TotalNumberOfSingleDPPPlanes[i][j] = v->TotalNumberOfSingleDPPPlanes[i][j] - 1;
4203                                 }
4204                         }
4205                         if (v->TotalNumberOfActiveDPP[i][j] > v->MaxNumDPP) {
4206                                 v->RequiredDISPCLK[i][j] = 0.0;
4207                                 v->DISPCLK_DPPCLK_Support[i][j] = true;
4208                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
4209                                         v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled;
4210                                         if (v->SingleDPPViewportSizeSupportPerPlane[k] == false && v->WhenToDoMPCCombine != dm_mpc_never) {
4211                                                 v->MPCCombine[i][j][k] = true;
4212                                                 v->NoOfDPP[i][j][k] = 2;
4213                                                 v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k]
4214                                                                 * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
4215                                         } else {
4216                                                 v->MPCCombine[i][j][k] = false;
4217                                                 v->NoOfDPP[i][j][k] = 1;
4218                                                 v->RequiredDPPCLK[i][j][k] = v->MinDPPCLKUsingSingleDPP[k]
4219                                                                 * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4220                                         }
4221                                         if (!(v->MaxDispclk[i] == v->MaxDispclk[v->soc.num_states - 1]
4222                                                         && v->MaxDppclk[i] == v->MaxDppclk[v->soc.num_states - 1])) {
4223                                                 v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4224                                                                 * (1.0 + v->DISPCLKRampingMargin / 100.0);
4225                                         } else {
4226                                                 v->PlaneRequiredDISPCLK = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
4227                                         }
4228                                         v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->PlaneRequiredDISPCLK);
4229                                         if ((v->MinDPPCLKUsingSingleDPP[k] / v->NoOfDPP[i][j][k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
4230                                                         > v->MaxDppclkRoundedDownToDFSGranularity)
4231                                                         || (v->PlaneRequiredDISPCLK > v->MaxDispclkRoundedDownToDFSGranularity)) {
4232                                                 v->DISPCLK_DPPCLK_Support[i][j] = false;
4233                                         }
4234                                 }
4235                                 v->TotalNumberOfActiveDPP[i][j] = 0.0;
4236                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
4237                                         v->TotalNumberOfActiveDPP[i][j] = v->TotalNumberOfActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4238                                 }
4239                         }
4240                         v->RequiredDISPCLK[i][j] = dml_max(v->RequiredDISPCLK[i][j], v->WritebackRequiredDISPCLK);
4241                         if (v->MaxDispclkRoundedDownToDFSGranularity < v->WritebackRequiredDISPCLK) {
4242                                 v->DISPCLK_DPPCLK_Support[i][j] = false;
4243                         }
4244                 }
4245         }
4246
4247         /*Total Available Pipes Support Check*/
4248
4249         for (i = 0; i < v->soc.num_states; i++) {
4250                 for (j = 0; j < 2; j++) {
4251                         if (v->TotalNumberOfActiveDPP[i][j] <= v->MaxNumDPP) {
4252                                 v->TotalAvailablePipesSupport[i][j] = true;
4253                         } else {
4254                                 v->TotalAvailablePipesSupport[i][j] = false;
4255                         }
4256                 }
4257         }
4258         /*Display IO and DSC Support Check*/
4259
4260         v->NonsupportedDSCInputBPC = false;
4261         for (k = 0; k < v->NumberOfActivePlanes; k++) {
4262                 if (!(v->DSCInputBitPerComponent[k] == 12.0 || v->DSCInputBitPerComponent[k] == 10.0 || v->DSCInputBitPerComponent[k] == 8.0)
4263                                 || v->DSCInputBitPerComponent[k] > v->MaximumDSCBitsPerComponent) {
4264                         v->NonsupportedDSCInputBPC = true;
4265                 }
4266         }
4267
4268         /*Number Of DSC Slices*/
4269         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4270                 if (v->BlendingAndTiming[k] == k) {
4271                         if (v->PixelClockBackEnd[k] > 3200) {
4272                                 v->NumberOfDSCSlices[k] = dml_ceil(v->PixelClockBackEnd[k] / 400.0, 4.0);
4273                         } else if (v->PixelClockBackEnd[k] > 1360) {
4274                                 v->NumberOfDSCSlices[k] = 8;
4275                         } else if (v->PixelClockBackEnd[k] > 680) {
4276                                 v->NumberOfDSCSlices[k] = 4;
4277                         } else if (v->PixelClockBackEnd[k] > 340) {
4278                                 v->NumberOfDSCSlices[k] = 2;
4279                         } else {
4280                                 v->NumberOfDSCSlices[k] = 1;
4281                         }
4282                 } else {
4283                         v->NumberOfDSCSlices[k] = 0;
4284                 }
4285         }
4286
4287         for (i = 0; i < v->soc.num_states; i++) {
4288                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
4289                         v->RequiresDSC[i][k] = false;
4290                         v->RequiresFEC[i][k] = false;
4291                         if (v->BlendingAndTiming[k] == k) {
4292                                 if (v->Output[k] == dm_hdmi) {
4293                                         v->RequiresDSC[i][k] = false;
4294                                         v->RequiresFEC[i][k] = false;
4295                                         v->OutputBppPerState[i][k] = TruncToValidBPP(
4296                                                         dml_min(600.0, v->PHYCLKPerState[i]) * 10,
4297                                                         3,
4298                                                         v->HTotal[k],
4299                                                         v->HActive[k],
4300                                                         v->PixelClockBackEnd[k],
4301                                                         v->ForcedOutputLinkBPP[k],
4302                                                         false,
4303                                                         v->Output[k],
4304                                                         v->OutputFormat[k],
4305                                                         v->DSCInputBitPerComponent[k],
4306                                                         v->NumberOfDSCSlices[k],
4307                                                         v->AudioSampleRate[k],
4308                                                         v->AudioSampleLayout[k],
4309                                                         v->ODMCombineEnablePerState[i][k]);
4310                                 } else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
4311                                         if (v->DSCEnable[k] == true) {
4312                                                 v->RequiresDSC[i][k] = true;
4313                                                 v->LinkDSCEnable = true;
4314                                                 if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
4315                                                         v->RequiresFEC[i][k] = true;
4316                                                 } else {
4317                                                         v->RequiresFEC[i][k] = false;
4318                                                 }
4319                                         } else {
4320                                                 v->RequiresDSC[i][k] = false;
4321                                                 v->LinkDSCEnable = false;
4322                                                 if (v->Output[k] == dm_dp2p0) {
4323                                                         v->RequiresFEC[i][k] = true;
4324                                                 } else {
4325                                                         v->RequiresFEC[i][k] = false;
4326                                                 }
4327                                         }
4328                                         if (v->Output[k] == dm_dp2p0) {
4329                                                 v->Outbpp = BPP_INVALID;
4330                                                 if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
4331                                                         v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
4332                                                         v->Outbpp = TruncToValidBPP(
4333                                                                         (1.0 - v->Downspreading / 100.0) * 10000,
4334                                                                         v->OutputLinkDPLanes[k],
4335                                                                         v->HTotal[k],
4336                                                                         v->HActive[k],
4337                                                                         v->PixelClockBackEnd[k],
4338                                                                         v->ForcedOutputLinkBPP[k],
4339                                                                         v->LinkDSCEnable,
4340                                                                         v->Output[k],
4341                                                                         v->OutputFormat[k],
4342                                                                         v->DSCInputBitPerComponent[k],
4343                                                                         v->NumberOfDSCSlices[k],
4344                                                                         v->AudioSampleRate[k],
4345                                                                         v->AudioSampleLayout[k],
4346                                                                         v->ODMCombineEnablePerState[i][k]);
4347                                                         if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
4348                                                                 v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
4349                                                                 v->RequiresDSC[i][k] = true;
4350                                                                 v->LinkDSCEnable = true;
4351                                                                 v->Outbpp = TruncToValidBPP(
4352                                                                                 (1.0 - v->Downspreading / 100.0) * 10000,
4353                                                                                 v->OutputLinkDPLanes[k],
4354                                                                                 v->HTotal[k],
4355                                                                                 v->HActive[k],
4356                                                                                 v->PixelClockBackEnd[k],
4357                                                                                 v->ForcedOutputLinkBPP[k],
4358                                                                                 v->LinkDSCEnable,
4359                                                                                 v->Output[k],
4360                                                                                 v->OutputFormat[k],
4361                                                                                 v->DSCInputBitPerComponent[k],
4362                                                                                 v->NumberOfDSCSlices[k],
4363                                                                                 v->AudioSampleRate[k],
4364                                                                                 v->AudioSampleLayout[k],
4365                                                                                 v->ODMCombineEnablePerState[i][k]);
4366                                                         }
4367                                                         v->OutputBppPerState[i][k] = v->Outbpp;
4368                                                         // TODO: Need some other way to handle this nonsense
4369                                                         // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
4370                                                 }
4371                                                 if (v->Outbpp == BPP_INVALID &&
4372                                                         (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
4373                                                         v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
4374                                                         v->Outbpp = TruncToValidBPP(
4375                                                                         (1.0 - v->Downspreading / 100.0) * 13500,
4376                                                                         v->OutputLinkDPLanes[k],
4377                                                                         v->HTotal[k],
4378                                                                         v->HActive[k],
4379                                                                         v->PixelClockBackEnd[k],
4380                                                                         v->ForcedOutputLinkBPP[k],
4381                                                                         v->LinkDSCEnable,
4382                                                                         v->Output[k],
4383                                                                         v->OutputFormat[k],
4384                                                                         v->DSCInputBitPerComponent[k],
4385                                                                         v->NumberOfDSCSlices[k],
4386                                                                         v->AudioSampleRate[k],
4387                                                                         v->AudioSampleLayout[k],
4388                                                                         v->ODMCombineEnablePerState[i][k]);
4389                                                         if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
4390                                                                 v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
4391                                                                 v->RequiresDSC[i][k] = true;
4392                                                                 v->LinkDSCEnable = true;
4393                                                                 v->Outbpp = TruncToValidBPP(
4394                                                                                 (1.0 - v->Downspreading / 100.0) * 13500,
4395                                                                                 v->OutputLinkDPLanes[k],
4396                                                                                 v->HTotal[k],
4397                                                                                 v->HActive[k],
4398                                                                                 v->PixelClockBackEnd[k],
4399                                                                                 v->ForcedOutputLinkBPP[k],
4400                                                                                 v->LinkDSCEnable,
4401                                                                                 v->Output[k],
4402                                                                                 v->OutputFormat[k],
4403                                                                                 v->DSCInputBitPerComponent[k],
4404                                                                                 v->NumberOfDSCSlices[k],
4405                                                                                 v->AudioSampleRate[k],
4406                                                                                 v->AudioSampleLayout[k],
4407                                                                                 v->ODMCombineEnablePerState[i][k]);
4408                                                         }
4409                                                         v->OutputBppPerState[i][k] = v->Outbpp;
4410                                                         // TODO: Need some other way to handle this nonsense
4411                                                         // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
4412                                                 }
4413                                                 if (v->Outbpp == BPP_INVALID &&
4414                                                         (v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
4415                                                         v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
4416                                                         v->Outbpp = TruncToValidBPP(
4417                                                                         (1.0 - v->Downspreading / 100.0) * 20000,
4418                                                                         v->OutputLinkDPLanes[k],
4419                                                                         v->HTotal[k],
4420                                                                         v->HActive[k],
4421                                                                         v->PixelClockBackEnd[k],
4422                                                                         v->ForcedOutputLinkBPP[k],
4423                                                                         v->LinkDSCEnable,
4424                                                                         v->Output[k],
4425                                                                         v->OutputFormat[k],
4426                                                                         v->DSCInputBitPerComponent[k],
4427                                                                         v->NumberOfDSCSlices[k],
4428                                                                         v->AudioSampleRate[k],
4429                                                                         v->AudioSampleLayout[k],
4430                                                                         v->ODMCombineEnablePerState[i][k]);
4431                                                         if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
4432                                                                 v->ForcedOutputLinkBPP[k] == 0) {
4433                                                                 v->RequiresDSC[i][k] = true;
4434                                                                 v->LinkDSCEnable = true;
4435                                                                 v->Outbpp = TruncToValidBPP(
4436                                                                                 (1.0 - v->Downspreading / 100.0) * 20000,
4437                                                                                 v->OutputLinkDPLanes[k],
4438                                                                                 v->HTotal[k],
4439                                                                                 v->HActive[k],
4440                                                                                 v->PixelClockBackEnd[k],
4441                                                                                 v->ForcedOutputLinkBPP[k],
4442                                                                                 v->LinkDSCEnable,
4443                                                                                 v->Output[k],
4444                                                                                 v->OutputFormat[k],
4445                                                                                 v->DSCInputBitPerComponent[k],
4446                                                                                 v->NumberOfDSCSlices[k],
4447                                                                                 v->AudioSampleRate[k],
4448                                                                                 v->AudioSampleLayout[k],
4449                                                                                 v->ODMCombineEnablePerState[i][k]);
4450                                                         }
4451                                                         v->OutputBppPerState[i][k] = v->Outbpp;
4452                                                         // TODO: Need some other way to handle this nonsense
4453                                                         // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
4454                                                 }
4455                                         } else {
4456                                                 v->Outbpp = BPP_INVALID;
4457                                                 if (v->PHYCLKPerState[i] >= 270.0) {
4458                                                         v->Outbpp = TruncToValidBPP(
4459                                                                         (1.0 - v->Downspreading / 100.0) * 2700,
4460                                                                         v->OutputLinkDPLanes[k],
4461                                                                         v->HTotal[k],
4462                                                                         v->HActive[k],
4463                                                                         v->PixelClockBackEnd[k],
4464                                                                         v->ForcedOutputLinkBPP[k],
4465                                                                         v->LinkDSCEnable,
4466                                                                         v->Output[k],
4467                                                                         v->OutputFormat[k],
4468                                                                         v->DSCInputBitPerComponent[k],
4469                                                                         v->NumberOfDSCSlices[k],
4470                                                                         v->AudioSampleRate[k],
4471                                                                         v->AudioSampleLayout[k],
4472                                                                         v->ODMCombineEnablePerState[i][k]);
4473                                                         v->OutputBppPerState[i][k] = v->Outbpp;
4474                                                         // TODO: Need some other way to handle this nonsense
4475                                                         // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
4476                                                 }
4477                                                 if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
4478                                                         v->Outbpp = TruncToValidBPP(
4479                                                                         (1.0 - v->Downspreading / 100.0) * 5400,
4480                                                                         v->OutputLinkDPLanes[k],
4481                                                                         v->HTotal[k],
4482                                                                         v->HActive[k],
4483                                                                         v->PixelClockBackEnd[k],
4484                                                                         v->ForcedOutputLinkBPP[k],
4485                                                                         v->LinkDSCEnable,
4486                                                                         v->Output[k],
4487                                                                         v->OutputFormat[k],
4488                                                                         v->DSCInputBitPerComponent[k],
4489                                                                         v->NumberOfDSCSlices[k],
4490                                                                         v->AudioSampleRate[k],
4491                                                                         v->AudioSampleLayout[k],
4492                                                                         v->ODMCombineEnablePerState[i][k]);
4493                                                         v->OutputBppPerState[i][k] = v->Outbpp;
4494                                                         // TODO: Need some other way to handle this nonsense
4495                                                         // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
4496                                                 }
4497                                                 if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
4498                                                         v->Outbpp = TruncToValidBPP(
4499                                                                         (1.0 - v->Downspreading / 100.0) * 8100,
4500                                                                         v->OutputLinkDPLanes[k],
4501                                                                         v->HTotal[k],
4502                                                                         v->HActive[k],
4503                                                                         v->PixelClockBackEnd[k],
4504                                                                         v->ForcedOutputLinkBPP[k],
4505                                                                         v->LinkDSCEnable,
4506                                                                         v->Output[k],
4507                                                                         v->OutputFormat[k],
4508                                                                         v->DSCInputBitPerComponent[k],
4509                                                                         v->NumberOfDSCSlices[k],
4510                                                                         v->AudioSampleRate[k],
4511                                                                         v->AudioSampleLayout[k],
4512                                                                         v->ODMCombineEnablePerState[i][k]);
4513                                                         v->OutputBppPerState[i][k] = v->Outbpp;
4514                                                         // TODO: Need some other way to handle this nonsense
4515                                                         // v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
4516                                                 }
4517                                         }
4518                                 }
4519                         } else {
4520                                 v->OutputBppPerState[i][k] = 0;
4521                         }
4522                 }
4523         }
4524
4525         for (i = 0; i < v->soc.num_states; i++) {
4526                 v->LinkCapacitySupport[i] = true;
4527                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
4528                         if (v->BlendingAndTiming[k] == k
4529                                         && (v->Output[k] == dm_dp ||
4530                                             v->Output[k] == dm_edp ||
4531                                             v->Output[k] == dm_hdmi) && v->OutputBppPerState[i][k] == 0) {
4532                                 v->LinkCapacitySupport[i] = false;
4533                         }
4534                 }
4535         }
4536
4537         // UPTO 2172
4538         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4539                 if (v->BlendingAndTiming[k] == k
4540                                 && (v->Output[k] == dm_dp ||
4541                                     v->Output[k] == dm_edp ||
4542                                     v->Output[k] == dm_hdmi)) {
4543                         if (v->OutputFormat[k] == dm_420 && v->Interlace[k] == 1 && v->ProgressiveToInterlaceUnitInOPP == true) {
4544                                 P2IWith420 = true;
4545                         }
4546                         if (v->DSCEnable[k] == true && v->OutputFormat[k] == dm_n422
4547                                         && !v->DSC422NativeSupport) {
4548                                 DSC422NativeNotSupported = true;
4549                         }
4550                 }
4551         }
4552
4553         for (i = 0; i < v->soc.num_states; ++i) {
4554                 v->ODMCombine4To1SupportCheckOK[i] = true;
4555                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4556                         if (v->BlendingAndTiming[k] == k && v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1
4557                                         && (v->ODMCombine4To1Supported == false || v->Output[k] == dm_dp || v->Output[k] == dm_edp
4558                                                         || v->Output[k] == dm_hdmi)) {
4559                                 v->ODMCombine4To1SupportCheckOK[i] = false;
4560                         }
4561                 }
4562         }
4563
4564         /* Skip dscclk validation: as long as dispclk is supported, dscclk is also implicitly supported */
4565
4566         for (i = 0; i < v->soc.num_states; i++) {
4567                 v->NotEnoughDSCUnits[i] = false;
4568                 v->TotalDSCUnitsRequired = 0.0;
4569                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
4570                         if (v->RequiresDSC[i][k] == true) {
4571                                 if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) {
4572                                         v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 4.0;
4573                                 } else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4574                                         v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 2.0;
4575                                 } else {
4576                                         v->TotalDSCUnitsRequired = v->TotalDSCUnitsRequired + 1.0;
4577                                 }
4578                         }
4579                 }
4580                 if (v->TotalDSCUnitsRequired > v->NumberOfDSC) {
4581                         v->NotEnoughDSCUnits[i] = true;
4582                 }
4583         }
4584         /*DSC Delay per state*/
4585
4586         for (i = 0; i < v->soc.num_states; i++) {
4587                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
4588                         if (v->OutputBppPerState[i][k] == BPP_INVALID) {
4589                                 v->BPP = 0.0;
4590                         } else {
4591                                 v->BPP = v->OutputBppPerState[i][k];
4592                         }
4593                         if (v->RequiresDSC[i][k] == true && v->BPP != 0.0) {
4594                                 if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
4595                                         v->DSCDelayPerState[i][k] = dscceComputeDelay(
4596                                                         v->DSCInputBitPerComponent[k],
4597                                                         v->BPP,
4598                                                         dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4599                                                         v->NumberOfDSCSlices[k],
4600                                                         v->OutputFormat[k],
4601                                                         v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]);
4602                                 } else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
4603                                         v->DSCDelayPerState[i][k] = 2.0
4604                                                         * (dscceComputeDelay(
4605                                                                         v->DSCInputBitPerComponent[k],
4606                                                                         v->BPP,
4607                                                                         dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4608                                                                         v->NumberOfDSCSlices[k] / 2,
4609                                                                         v->OutputFormat[k],
4610                                                                         v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
4611                                 } else {
4612                                         v->DSCDelayPerState[i][k] = 4.0
4613                                                         * (dscceComputeDelay(
4614                                                                         v->DSCInputBitPerComponent[k],
4615                                                                         v->BPP,
4616                                                                         dml_ceil(1.0 * v->HActive[k] / v->NumberOfDSCSlices[k], 1.0),
4617                                                                         v->NumberOfDSCSlices[k] / 4,
4618                                                                         v->OutputFormat[k],
4619                                                                         v->Output[k]) + dscComputeDelay(v->OutputFormat[k], v->Output[k]));
4620                                 }
4621                                 v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][k] * v->PixelClock[k] / v->PixelClockBackEnd[k];
4622                         } else {
4623                                 v->DSCDelayPerState[i][k] = 0.0;
4624                         }
4625                 }
4626                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
4627                         for (m = 0; m < v->NumberOfActivePlanes; m++) {
4628                                 if (v->BlendingAndTiming[k] == m && v->RequiresDSC[i][m] == true) {
4629                                         v->DSCDelayPerState[i][k] = v->DSCDelayPerState[i][m];
4630                                 }
4631                         }
4632                 }
4633         }
4634
4635         //Calculate Swath, DET Configuration, DCFCLKDeepSleep
4636         //
4637         for (i = 0; i < v->soc.num_states; ++i) {
4638                 for (j = 0; j <= 1; ++j) {
4639                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4640                                 v->RequiredDPPCLKThisState[k] = v->RequiredDPPCLK[i][j][k];
4641                                 v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
4642                                 v->ODMCombineEnableThisState[k] = v->ODMCombineEnablePerState[i][k];
4643                         }
4644
4645                         if (v->NumberOfActivePlanes > 1 && mode_lib->project == DML_PROJECT_DCN315)
4646                                 PatchDETBufferSizeInKByte(v->NumberOfActivePlanes, v->NoOfDPPThisState, v->ip.config_return_buffer_size_in_kbytes, &v->DETBufferSizeInKByte[0]);
4647                         CalculateSwathAndDETConfiguration(
4648                                         false,
4649                                         v->NumberOfActivePlanes,
4650                                         v->DETBufferSizeInKByte[0],
4651                                         v->MaximumSwathWidthLuma,
4652                                         v->MaximumSwathWidthChroma,
4653                                         v->SourceScan,
4654                                         v->SourcePixelFormat,
4655                                         v->SurfaceTiling,
4656                                         v->ViewportWidth,
4657                                         v->ViewportHeight,
4658                                         v->SurfaceWidthY,
4659                                         v->SurfaceWidthC,
4660                                         v->SurfaceHeightY,
4661                                         v->SurfaceHeightC,
4662                                         v->Read256BlockHeightY,
4663                                         v->Read256BlockHeightC,
4664                                         v->Read256BlockWidthY,
4665                                         v->Read256BlockWidthC,
4666                                         v->ODMCombineEnableThisState,
4667                                         v->BlendingAndTiming,
4668                                         v->BytePerPixelY,
4669                                         v->BytePerPixelC,
4670                                         v->BytePerPixelInDETY,
4671                                         v->BytePerPixelInDETC,
4672                                         v->HActive,
4673                                         v->HRatio,
4674                                         v->HRatioChroma,
4675                                         v->NoOfDPPThisState,
4676                                         v->swath_width_luma_ub_this_state,
4677                                         v->swath_width_chroma_ub_this_state,
4678                                         v->SwathWidthYThisState,
4679                                         v->SwathWidthCThisState,
4680                                         v->SwathHeightYThisState,
4681                                         v->SwathHeightCThisState,
4682                                         v->DETBufferSizeYThisState,
4683                                         v->DETBufferSizeCThisState,
4684                                         v->dummystring,
4685                                         &v->ViewportSizeSupport[i][j]);
4686
4687                         CalculateDCFCLKDeepSleep(
4688                                         mode_lib,
4689                                         v->NumberOfActivePlanes,
4690                                         v->BytePerPixelY,
4691                                         v->BytePerPixelC,
4692                                         v->VRatio,
4693                                         v->VRatioChroma,
4694                                         v->SwathWidthYThisState,
4695                                         v->SwathWidthCThisState,
4696                                         v->NoOfDPPThisState,
4697                                         v->HRatio,
4698                                         v->HRatioChroma,
4699                                         v->PixelClock,
4700                                         v->PSCL_FACTOR,
4701                                         v->PSCL_FACTOR_CHROMA,
4702                                         v->RequiredDPPCLKThisState,
4703                                         v->ReadBandwidthLuma,
4704                                         v->ReadBandwidthChroma,
4705                                         v->ReturnBusWidth,
4706                                         &v->ProjectedDCFCLKDeepSleep[i][j]);
4707
4708                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4709                                 v->swath_width_luma_ub_all_states[i][j][k] = v->swath_width_luma_ub_this_state[k];
4710                                 v->swath_width_chroma_ub_all_states[i][j][k] = v->swath_width_chroma_ub_this_state[k];
4711                                 v->SwathWidthYAllStates[i][j][k] = v->SwathWidthYThisState[k];
4712                                 v->SwathWidthCAllStates[i][j][k] = v->SwathWidthCThisState[k];
4713                                 v->SwathHeightYAllStates[i][j][k] = v->SwathHeightYThisState[k];
4714                                 v->SwathHeightCAllStates[i][j][k] = v->SwathHeightCThisState[k];
4715                                 v->DETBufferSizeYAllStates[i][j][k] = v->DETBufferSizeYThisState[k];
4716                                 v->DETBufferSizeCAllStates[i][j][k] = v->DETBufferSizeCThisState[k];
4717                         }
4718                 }
4719         }
4720
4721         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4722                 v->cursor_bw[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
4723                                 / (v->HTotal[k] / v->PixelClock[k]) * v->VRatio[k];
4724         }
4725
4726         for (i = 0; i < v->soc.num_states; i++) {
4727                 for (j = 0; j < 2; j++) {
4728                         bool NotUrgentLatencyHiding[DC__NUM_DPP__MAX];
4729
4730                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
4731                                 v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
4732                                 v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
4733                                 v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
4734                                 v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
4735                                 v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
4736                                 v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
4737                                 v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
4738                                 v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
4739                         }
4740
4741                         v->TotalNumberOfDCCActiveDPP[i][j] = 0;
4742                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4743                                 if (v->DCCEnable[k] == true) {
4744                                         v->TotalNumberOfDCCActiveDPP[i][j] = v->TotalNumberOfDCCActiveDPP[i][j] + v->NoOfDPP[i][j][k];
4745                                 }
4746                         }
4747
4748                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
4749                                 if (v->SourcePixelFormat[k] == dm_420_8 || v->SourcePixelFormat[k] == dm_420_10
4750                                                 || v->SourcePixelFormat[k] == dm_420_12 || v->SourcePixelFormat[k] == dm_rgbe_alpha) {
4751
4752                                         if ((v->SourcePixelFormat[k] == dm_420_10 || v->SourcePixelFormat[k] == dm_420_12)
4753                                                         && v->SourceScan[k] != dm_vert) {
4754                                                 v->PTEBufferSizeInRequestsForLuma = (v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma)
4755                                                                 / 2;
4756                                                 v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsForLuma;
4757                                         } else {
4758                                                 v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma;
4759                                                 v->PTEBufferSizeInRequestsForChroma = v->PTEBufferSizeInRequestsChroma;
4760                                         }
4761
4762                                         v->PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
4763                                                         mode_lib,
4764                                                         v->DCCEnable[k],
4765                                                         v->Read256BlockHeightC[k],
4766                                                         v->Read256BlockWidthC[k],
4767                                                         v->SourcePixelFormat[k],
4768                                                         v->SurfaceTiling[k],
4769                                                         v->BytePerPixelC[k],
4770                                                         v->SourceScan[k],
4771                                                         v->SwathWidthCThisState[k],
4772                                                         v->ViewportHeightChroma[k],
4773                                                         v->GPUVMEnable,
4774                                                         v->HostVMEnable,
4775                                                         v->HostVMMaxNonCachedPageTableLevels,
4776                                                         v->GPUVMMinPageSize,
4777                                                         v->HostVMMinPageSize,
4778                                                         v->PTEBufferSizeInRequestsForChroma,
4779                                                         v->PitchC[k],
4780                                                         0.0,
4781                                                         &v->MacroTileWidthC[k],
4782                                                         &v->MetaRowBytesC,
4783                                                         &v->DPTEBytesPerRowC,
4784                                                         &v->PTEBufferSizeNotExceededC[i][j][k],
4785                                                         &v->dummyinteger7,
4786                                                         &v->dpte_row_height_chroma[k],
4787                                                         &v->dummyinteger28,
4788                                                         &v->dummyinteger26,
4789                                                         &v->dummyinteger23,
4790                                                         &v->meta_row_height_chroma[k],
4791                                                         &v->dummyinteger8,
4792                                                         &v->dummyinteger9,
4793                                                         &v->dummyinteger19,
4794                                                         &v->dummyinteger20,
4795                                                         &v->dummyinteger17,
4796                                                         &v->dummyinteger10,
4797                                                         &v->dummyinteger11);
4798
4799                                         v->PrefetchLinesC[i][j][k] = CalculatePrefetchSourceLines(
4800                                                         mode_lib,
4801                                                         v->VRatioChroma[k],
4802                                                         v->VTAPsChroma[k],
4803                                                         v->Interlace[k],
4804                                                         v->ProgressiveToInterlaceUnitInOPP,
4805                                                         v->SwathHeightCThisState[k],
4806                                                         v->ViewportYStartC[k],
4807                                                         &v->PrefillC[k],
4808                                                         &v->MaxNumSwC[k]);
4809                                 } else {
4810                                         v->PTEBufferSizeInRequestsForLuma = v->PTEBufferSizeInRequestsLuma + v->PTEBufferSizeInRequestsChroma;
4811                                         v->PTEBufferSizeInRequestsForChroma = 0;
4812                                         v->PDEAndMetaPTEBytesPerFrameC = 0.0;
4813                                         v->MetaRowBytesC = 0.0;
4814                                         v->DPTEBytesPerRowC = 0.0;
4815                                         v->PrefetchLinesC[i][j][k] = 0.0;
4816                                         v->PTEBufferSizeNotExceededC[i][j][k] = true;
4817                                 }
4818                                 v->PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
4819                                                 mode_lib,
4820                                                 v->DCCEnable[k],
4821                                                 v->Read256BlockHeightY[k],
4822                                                 v->Read256BlockWidthY[k],
4823                                                 v->SourcePixelFormat[k],
4824                                                 v->SurfaceTiling[k],
4825                                                 v->BytePerPixelY[k],
4826                                                 v->SourceScan[k],
4827                                                 v->SwathWidthYThisState[k],
4828                                                 v->ViewportHeight[k],
4829                                                 v->GPUVMEnable,
4830                                                 v->HostVMEnable,
4831                                                 v->HostVMMaxNonCachedPageTableLevels,
4832                                                 v->GPUVMMinPageSize,
4833                                                 v->HostVMMinPageSize,
4834                                                 v->PTEBufferSizeInRequestsForLuma,
4835                                                 v->PitchY[k],
4836                                                 v->DCCMetaPitchY[k],
4837                                                 &v->MacroTileWidthY[k],
4838                                                 &v->MetaRowBytesY,
4839                                                 &v->DPTEBytesPerRowY,
4840                                                 &v->PTEBufferSizeNotExceededY[i][j][k],
4841                                                 &v->dummyinteger7,
4842                                                 &v->dpte_row_height[k],
4843                                                 &v->dummyinteger29,
4844                                                 &v->dummyinteger27,
4845                                                 &v->dummyinteger24,
4846                                                 &v->meta_row_height[k],
4847                                                 &v->dummyinteger25,
4848                                                 &v->dpte_group_bytes[k],
4849                                                 &v->dummyinteger21,
4850                                                 &v->dummyinteger22,
4851                                                 &v->dummyinteger18,
4852                                                 &v->dummyinteger5,
4853                                                 &v->dummyinteger6);
4854                                 v->PrefetchLinesY[i][j][k] = CalculatePrefetchSourceLines(
4855                                                 mode_lib,
4856                                                 v->VRatio[k],
4857                                                 v->vtaps[k],
4858                                                 v->Interlace[k],
4859                                                 v->ProgressiveToInterlaceUnitInOPP,
4860                                                 v->SwathHeightYThisState[k],
4861                                                 v->ViewportYStartY[k],
4862                                                 &v->PrefillY[k],
4863                                                 &v->MaxNumSwY[k]);
4864                                 v->PDEAndMetaPTEBytesPerFrame[i][j][k] = v->PDEAndMetaPTEBytesPerFrameY + v->PDEAndMetaPTEBytesPerFrameC;
4865                                 v->MetaRowBytes[i][j][k] = v->MetaRowBytesY + v->MetaRowBytesC;
4866                                 v->DPTEBytesPerRow[i][j][k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC;
4867
4868                                 CalculateRowBandwidth(
4869                                                 v->GPUVMEnable,
4870                                                 v->SourcePixelFormat[k],
4871                                                 v->VRatio[k],
4872                                                 v->VRatioChroma[k],
4873                                                 v->DCCEnable[k],
4874                                                 v->HTotal[k] / v->PixelClock[k],
4875                                                 v->MetaRowBytesY,
4876                                                 v->MetaRowBytesC,
4877                                                 v->meta_row_height[k],
4878                                                 v->meta_row_height_chroma[k],
4879                                                 v->DPTEBytesPerRowY,
4880                                                 v->DPTEBytesPerRowC,
4881                                                 v->dpte_row_height[k],
4882                                                 v->dpte_row_height_chroma[k],
4883                                                 &v->meta_row_bandwidth[i][j][k],
4884                                                 &v->dpte_row_bandwidth[i][j][k]);
4885                         }
4886                         /*DCCMetaBufferSizeSupport(i, j) = True
4887                         For k = 0 To NumberOfActivePlanes - 1
4888                         If MetaRowBytes(i, j, k) > 24064 Then
4889                         DCCMetaBufferSizeSupport(i, j) = False
4890                         End If
4891                         Next k*/
4892                         v->DCCMetaBufferSizeSupport[i][j] = true;
4893                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4894                                 if (v->MetaRowBytes[i][j][k] > 24064)
4895                                         v->DCCMetaBufferSizeSupport[i][j] = false;
4896                         }
4897                         v->UrgLatency[i] = CalculateUrgentLatency(
4898                                         v->UrgentLatencyPixelDataOnly,
4899                                         v->UrgentLatencyPixelMixedWithVMData,
4900                                         v->UrgentLatencyVMDataOnly,
4901                                         v->DoUrgentLatencyAdjustment,
4902                                         v->UrgentLatencyAdjustmentFabricClockComponent,
4903                                         v->UrgentLatencyAdjustmentFabricClockReference,
4904                                         v->FabricClockPerState[i]);
4905
4906                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4907                                 CalculateUrgentBurstFactor(
4908                                                 v->swath_width_luma_ub_this_state[k],
4909                                                 v->swath_width_chroma_ub_this_state[k],
4910                                                 v->SwathHeightYThisState[k],
4911                                                 v->SwathHeightCThisState[k],
4912                                                 v->HTotal[k] / v->PixelClock[k],
4913                                                 v->UrgLatency[i],
4914                                                 v->CursorBufferSize,
4915                                                 v->CursorWidth[k][0],
4916                                                 v->CursorBPP[k][0],
4917                                                 v->VRatio[k],
4918                                                 v->VRatioChroma[k],
4919                                                 v->BytePerPixelInDETY[k],
4920                                                 v->BytePerPixelInDETC[k],
4921                                                 v->DETBufferSizeYThisState[k],
4922                                                 v->DETBufferSizeCThisState[k],
4923                                                 &v->UrgentBurstFactorCursor[k],
4924                                                 &v->UrgentBurstFactorLuma[k],
4925                                                 &v->UrgentBurstFactorChroma[k],
4926                                                 &NotUrgentLatencyHiding[k]);
4927                         }
4928
4929                         v->NotEnoughUrgentLatencyHidingA[i][j] = false;
4930                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4931                                 if (NotUrgentLatencyHiding[k]) {
4932                                         v->NotEnoughUrgentLatencyHidingA[i][j] = true;
4933                                 }
4934                         }
4935
4936                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4937                                 v->VActivePixelBandwidth[i][j][k] = v->ReadBandwidthLuma[k] * v->UrgentBurstFactorLuma[k]
4938                                                 + v->ReadBandwidthChroma[k] * v->UrgentBurstFactorChroma[k];
4939                                 v->VActiveCursorBandwidth[i][j][k] = v->cursor_bw[k] * v->UrgentBurstFactorCursor[k];
4940                         }
4941
4942                         v->TotalVActivePixelBandwidth[i][j] = 0;
4943                         v->TotalVActiveCursorBandwidth[i][j] = 0;
4944                         v->TotalMetaRowBandwidth[i][j] = 0;
4945                         v->TotalDPTERowBandwidth[i][j] = 0;
4946                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
4947                                 v->TotalVActivePixelBandwidth[i][j] = v->TotalVActivePixelBandwidth[i][j] + v->VActivePixelBandwidth[i][j][k];
4948                                 v->TotalVActiveCursorBandwidth[i][j] = v->TotalVActiveCursorBandwidth[i][j] + v->VActiveCursorBandwidth[i][j][k];
4949                                 v->TotalMetaRowBandwidth[i][j] = v->TotalMetaRowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->meta_row_bandwidth[i][j][k];
4950                                 v->TotalDPTERowBandwidth[i][j] = v->TotalDPTERowBandwidth[i][j] + v->NoOfDPP[i][j][k] * v->dpte_row_bandwidth[i][j][k];
4951                         }
4952                 }
4953         }
4954
4955         //Calculate Return BW
4956         for (i = 0; i < v->soc.num_states; ++i) {
4957                 for (j = 0; j <= 1; ++j) {
4958                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
4959                                 if (v->BlendingAndTiming[k] == k) {
4960                                         if (v->WritebackEnable[k] == true) {
4961                                                 v->WritebackDelayTime[k] = v->WritebackLatency
4962                                                                 + CalculateWriteBackDelay(
4963                                                                                 v->WritebackPixelFormat[k],
4964                                                                                 v->WritebackHRatio[k],
4965                                                                                 v->WritebackVRatio[k],
4966                                                                                 v->WritebackVTaps[k],
4967                                                                                 v->WritebackDestinationWidth[k],
4968                                                                                 v->WritebackDestinationHeight[k],
4969                                                                                 v->WritebackSourceHeight[k],
4970                                                                                 v->HTotal[k]) / v->RequiredDISPCLK[i][j];
4971                                         } else {
4972                                                 v->WritebackDelayTime[k] = 0.0;
4973                                         }
4974                                         for (m = 0; m < v->NumberOfActivePlanes; m++) {
4975                                                 if (v->BlendingAndTiming[m] == k && v->WritebackEnable[m] == true) {
4976                                                         v->WritebackDelayTime[k] = dml_max(
4977                                                                         v->WritebackDelayTime[k],
4978                                                                         v->WritebackLatency
4979                                                                                         + CalculateWriteBackDelay(
4980                                                                                                         v->WritebackPixelFormat[m],
4981                                                                                                         v->WritebackHRatio[m],
4982                                                                                                         v->WritebackVRatio[m],
4983                                                                                                         v->WritebackVTaps[m],
4984                                                                                                         v->WritebackDestinationWidth[m],
4985                                                                                                         v->WritebackDestinationHeight[m],
4986                                                                                                         v->WritebackSourceHeight[m],
4987                                                                                                         v->HTotal[m]) / v->RequiredDISPCLK[i][j]);
4988                                                 }
4989                                         }
4990                                 }
4991                         }
4992                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
4993                                 for (m = 0; m < v->NumberOfActivePlanes; m++) {
4994                                         if (v->BlendingAndTiming[k] == m) {
4995                                                 v->WritebackDelayTime[k] = v->WritebackDelayTime[m];
4996                                         }
4997                                 }
4998                         }
4999                         v->MaxMaxVStartup[i][j] = 0;
5000                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5001                                 v->MaximumVStartup[i][j][k] =
5002                                                 (v->Interlace[k] && !v->ProgressiveToInterlaceUnitInOPP) ?
5003                                                                 dml_floor((v->VTotal[k] - v->VActive[k]) / 2.0, 1.0) :
5004                                                                 v->VTotal[k] - v->VActive[k]
5005                                                                                 - dml_max(
5006                                                                                                 1.0,
5007                                                                                                 dml_ceil(
5008                                                                                                                 1.0 * v->WritebackDelayTime[k]
5009                                                                                                                                 / (v->HTotal[k]
5010                                                                                                                                                 / v->PixelClock[k]),
5011                                                                                                                 1.0));
5012                                 if (v->MaximumVStartup[i][j][k] > 1023)
5013                                         v->MaximumVStartup[i][j][k] = 1023;
5014                                 v->MaxMaxVStartup[i][j] = dml_max(v->MaxMaxVStartup[i][j], v->MaximumVStartup[i][j][k]);
5015                         }
5016                 }
5017         }
5018
5019         ReorderingBytes = v->NumberOfChannels
5020                         * dml_max3(
5021                                         v->UrgentOutOfOrderReturnPerChannelPixelDataOnly,
5022                                         v->UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
5023                                         v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
5024
5025         for (i = 0; i < v->soc.num_states; ++i) {
5026                 for (j = 0; j <= 1; ++j) {
5027                         v->DCFCLKState[i][j] = v->DCFCLKPerState[i];
5028                 }
5029         }
5030
5031         if (v->UseMinimumRequiredDCFCLK == true)
5032                 UseMinimumDCFCLK(mode_lib, MaxPrefetchMode, ReorderingBytes);
5033
5034         for (i = 0; i < v->soc.num_states; ++i) {
5035                 for (j = 0; j <= 1; ++j) {
5036                         double IdealFabricAndSDPPortBandwidthPerState = dml_min(
5037                                         v->ReturnBusWidth * v->DCFCLKState[i][j],
5038                                         v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn);
5039                         double IdealDRAMBandwidthPerState = v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth;
5040                         double PixelDataOnlyReturnBWPerState = dml_min(
5041                                         IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
5042                                         IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly / 100.0);
5043                         double PixelMixedWithVMDataReturnBWPerState = dml_min(
5044                                         IdealFabricAndSDPPortBandwidthPerState * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
5045                                         IdealDRAMBandwidthPerState * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0);
5046
5047                         if (v->HostVMEnable != true) {
5048                                 v->ReturnBWPerState[i][j] = PixelDataOnlyReturnBWPerState;
5049                         } else {
5050                                 v->ReturnBWPerState[i][j] = PixelMixedWithVMDataReturnBWPerState;
5051                         }
5052                 }
5053         }
5054
5055         //Re-ordering Buffer Support Check
5056         for (i = 0; i < v->soc.num_states; ++i) {
5057                 for (j = 0; j <= 1; ++j) {
5058                         if ((v->ROBBufferSizeInKByte - v->PixelChunkSizeInKByte) * 1024 / v->ReturnBWPerState[i][j]
5059                                         > (v->RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__) / v->DCFCLKState[i][j] + ReorderingBytes / v->ReturnBWPerState[i][j]) {
5060                                 v->ROBSupport[i][j] = true;
5061                         } else {
5062                                 v->ROBSupport[i][j] = false;
5063                         }
5064                 }
5065         }
5066
5067         //Vertical Active BW support check
5068
5069         MaxTotalVActiveRDBandwidth = 0;
5070         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5071                 MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
5072         }
5073
5074         for (i = 0; i < v->soc.num_states; ++i) {
5075                 for (j = 0; j <= 1; ++j) {
5076                         v->MaxTotalVerticalActiveAvailableBandwidth[i][j] = dml_min(
5077                                         dml_min(
5078                                                         v->ReturnBusWidth * v->DCFCLKState[i][j],
5079                                                         v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn)
5080                                                         * v->MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation / 100,
5081                                         v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth
5082                                                         * v->MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100);
5083
5084                         if (MaxTotalVActiveRDBandwidth <= v->MaxTotalVerticalActiveAvailableBandwidth[i][j]) {
5085                                 v->TotalVerticalActiveBandwidthSupport[i][j] = true;
5086                         } else {
5087                                 v->TotalVerticalActiveBandwidthSupport[i][j] = false;
5088                         }
5089                 }
5090         }
5091
5092         v->UrgentLatency = CalculateUrgentLatency(
5093                         v->UrgentLatencyPixelDataOnly,
5094                         v->UrgentLatencyPixelMixedWithVMData,
5095                         v->UrgentLatencyVMDataOnly,
5096                         v->DoUrgentLatencyAdjustment,
5097                         v->UrgentLatencyAdjustmentFabricClockComponent,
5098                         v->UrgentLatencyAdjustmentFabricClockReference,
5099                         v->FabricClock);
5100         //Prefetch Check
5101         for (i = 0; i < v->soc.num_states; ++i) {
5102                 for (j = 0; j <= 1; ++j) {
5103                         double VMDataOnlyReturnBWPerState;
5104                         double HostVMInefficiencyFactor = 1;
5105                         int NextPrefetchModeState = MinPrefetchMode;
5106                         bool UnboundedRequestEnabledThisState = false;
5107                         int CompressedBufferSizeInkByteThisState = 0;
5108                         double dummy;
5109
5110                         v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep[i][j];
5111
5112                         v->BandwidthWithoutPrefetchSupported[i][j] = true;
5113                         if (v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j]
5114                                         + v->TotalDPTERowBandwidth[i][j] > v->ReturnBWPerState[i][j] || v->NotEnoughUrgentLatencyHidingA[i][j]) {
5115                                 v->BandwidthWithoutPrefetchSupported[i][j] = false;
5116                         }
5117
5118                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5119                                 v->NoOfDPPThisState[k] = v->NoOfDPP[i][j][k];
5120                                 v->swath_width_luma_ub_this_state[k] = v->swath_width_luma_ub_all_states[i][j][k];
5121                                 v->swath_width_chroma_ub_this_state[k] = v->swath_width_chroma_ub_all_states[i][j][k];
5122                                 v->SwathWidthYThisState[k] = v->SwathWidthYAllStates[i][j][k];
5123                                 v->SwathWidthCThisState[k] = v->SwathWidthCAllStates[i][j][k];
5124                                 v->SwathHeightYThisState[k] = v->SwathHeightYAllStates[i][j][k];
5125                                 v->SwathHeightCThisState[k] = v->SwathHeightCAllStates[i][j][k];
5126                                 v->DETBufferSizeYThisState[k] = v->DETBufferSizeYAllStates[i][j][k];
5127                                 v->DETBufferSizeCThisState[k] = v->DETBufferSizeCAllStates[i][j][k];
5128                         }
5129
5130                         VMDataOnlyReturnBWPerState = dml_min(
5131                                         dml_min(
5132                                                         v->ReturnBusWidth * v->DCFCLKState[i][j],
5133                                                         v->FabricClockPerState[i] * v->FabricDatapathToDCNDataReturn)
5134                                                         * v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0,
5135                                         v->DRAMSpeedPerState[i] * v->NumberOfChannels * v->DRAMChannelWidth
5136                                                         * v->PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly / 100.0);
5137                         if (v->GPUVMEnable && v->HostVMEnable)
5138                                 HostVMInefficiencyFactor = v->ReturnBWPerState[i][j] / VMDataOnlyReturnBWPerState;
5139
5140                         v->ExtraLatency = CalculateExtraLatency(
5141                                         v->RoundTripPingLatencyCycles,
5142                                         ReorderingBytes,
5143                                         v->DCFCLKState[i][j],
5144                                         v->TotalNumberOfActiveDPP[i][j],
5145                                         v->PixelChunkSizeInKByte,
5146                                         v->TotalNumberOfDCCActiveDPP[i][j],
5147                                         v->MetaChunkSize,
5148                                         v->ReturnBWPerState[i][j],
5149                                         v->GPUVMEnable,
5150                                         v->HostVMEnable,
5151                                         v->NumberOfActivePlanes,
5152                                         v->NoOfDPPThisState,
5153                                         v->dpte_group_bytes,
5154                                         HostVMInefficiencyFactor,
5155                                         v->HostVMMinPageSize,
5156                                         v->HostVMMaxNonCachedPageTableLevels);
5157
5158                         v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
5159                         do {
5160                                 v->PrefetchModePerState[i][j] = NextPrefetchModeState;
5161                                 v->MaxVStartup = v->NextMaxVStartup;
5162
5163                                 v->TWait = CalculateTWait(
5164                                                 v->PrefetchModePerState[i][j],
5165                                                 v->DRAMClockChangeLatency,
5166                                                 v->UrgLatency[i],
5167                                                 v->SREnterPlusExitTime);
5168
5169                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
5170                                         CalculatePrefetchSchedulePerPlane(mode_lib,
5171                                                                           HostVMInefficiencyFactor,
5172                                                                           i, j, k);
5173                                 }
5174
5175                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
5176                                         CalculateUrgentBurstFactor(
5177                                                         v->swath_width_luma_ub_this_state[k],
5178                                                         v->swath_width_chroma_ub_this_state[k],
5179                                                         v->SwathHeightYThisState[k],
5180                                                         v->SwathHeightCThisState[k],
5181                                                         v->HTotal[k] / v->PixelClock[k],
5182                                                         v->UrgLatency[i],
5183                                                         v->CursorBufferSize,
5184                                                         v->CursorWidth[k][0],
5185                                                         v->CursorBPP[k][0],
5186                                                         v->VRatioPreY[i][j][k],
5187                                                         v->VRatioPreC[i][j][k],
5188                                                         v->BytePerPixelInDETY[k],
5189                                                         v->BytePerPixelInDETC[k],
5190                                                         v->DETBufferSizeYThisState[k],
5191                                                         v->DETBufferSizeCThisState[k],
5192                                                         &v->UrgentBurstFactorCursorPre[k],
5193                                                         &v->UrgentBurstFactorLumaPre[k],
5194                                                         &v->UrgentBurstFactorChromaPre[k],
5195                                                         &v->NotUrgentLatencyHidingPre[k]);
5196                                 }
5197
5198                                 v->MaximumReadBandwidthWithPrefetch = 0.0;
5199                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
5200                                         v->cursor_bw_pre[k] = v->NumberOfCursors[k] * v->CursorWidth[k][0] * v->CursorBPP[k][0] / 8.0
5201                                                         / (v->HTotal[k] / v->PixelClock[k]) * v->VRatioPreY[i][j][k];
5202
5203                                         v->MaximumReadBandwidthWithPrefetch =
5204                                                         v->MaximumReadBandwidthWithPrefetch
5205                                                                         + dml_max3(
5206                                                                                         v->VActivePixelBandwidth[i][j][k]
5207                                                                                                         + v->VActiveCursorBandwidth[i][j][k]
5208                                                                                                         + v->NoOfDPP[i][j][k]
5209                                                                                                                         * (v->meta_row_bandwidth[i][j][k]
5210                                                                                                                                         + v->dpte_row_bandwidth[i][j][k]),
5211                                                                                         v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
5212                                                                                         v->NoOfDPP[i][j][k]
5213                                                                                                         * (v->RequiredPrefetchPixelDataBWLuma[i][j][k]
5214                                                                                                                         * v->UrgentBurstFactorLumaPre[k]
5215                                                                                                                         + v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5216                                                                                                                                         * v->UrgentBurstFactorChromaPre[k])
5217                                                                                                         + v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5218                                 }
5219
5220                                 v->NotEnoughUrgentLatencyHidingPre = false;
5221                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
5222                                         if (v->NotUrgentLatencyHidingPre[k] == true) {
5223                                                 v->NotEnoughUrgentLatencyHidingPre = true;
5224                                         }
5225                                 }
5226
5227                                 v->PrefetchSupported[i][j] = true;
5228                                 if (v->BandwidthWithoutPrefetchSupported[i][j] == false || v->MaximumReadBandwidthWithPrefetch > v->ReturnBWPerState[i][j]
5229                                                 || v->NotEnoughUrgentLatencyHidingPre == 1) {
5230                                         v->PrefetchSupported[i][j] = false;
5231                                 }
5232                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
5233                                         if (v->LineTimesForPrefetch[k] < 2.0 || v->LinesForMetaPTE[k] >= 32.0 || v->LinesForMetaAndDPTERow[k] >= 16.0
5234                                                         || v->NoTimeForPrefetch[i][j][k] == true) {
5235                                                 v->PrefetchSupported[i][j] = false;
5236                                         }
5237                                 }
5238
5239                                 v->DynamicMetadataSupported[i][j] = true;
5240                                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5241                                         if (v->NoTimeForDynamicMetadata[i][j][k] == true) {
5242                                                 v->DynamicMetadataSupported[i][j] = false;
5243                                         }
5244                                 }
5245
5246                                 v->VRatioInPrefetchSupported[i][j] = true;
5247                                 for (k = 0; k < v->NumberOfActivePlanes; k++) {
5248                                         if (v->VRatioPreY[i][j][k] > 4.0 || v->VRatioPreC[i][j][k] > 4.0 || v->NoTimeForPrefetch[i][j][k] == true) {
5249                                                 v->VRatioInPrefetchSupported[i][j] = false;
5250                                         }
5251                                 }
5252                                 v->AnyLinesForVMOrRowTooLarge = false;
5253                                 for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5254                                         if (v->LinesForMetaAndDPTERow[k] >= 16 || v->LinesForMetaPTE[k] >= 32) {
5255                                                 v->AnyLinesForVMOrRowTooLarge = true;
5256                                         }
5257                                 }
5258
5259                                 v->NextPrefetchMode = v->NextPrefetchMode + 1;
5260
5261                                 if (v->PrefetchSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true) {
5262                                         v->BandwidthAvailableForImmediateFlip = v->ReturnBWPerState[i][j];
5263                                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5264                                                 v->BandwidthAvailableForImmediateFlip = v->BandwidthAvailableForImmediateFlip
5265                                                                 - dml_max(
5266                                                                                 v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k],
5267                                                                                 v->NoOfDPP[i][j][k]
5268                                                                                                 * (v->RequiredPrefetchPixelDataBWLuma[i][j][k]
5269                                                                                                                 * v->UrgentBurstFactorLumaPre[k]
5270                                                                                                                 + v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5271                                                                                                                                 * v->UrgentBurstFactorChromaPre[k])
5272                                                                                                 + v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5273                                         }
5274                                         v->TotImmediateFlipBytes = 0.0;
5275                                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5276                                                 v->TotImmediateFlipBytes = v->TotImmediateFlipBytes
5277                                                                 + v->NoOfDPP[i][j][k] * v->PDEAndMetaPTEBytesPerFrame[i][j][k] + v->MetaRowBytes[i][j][k]
5278                                                                 + v->DPTEBytesPerRow[i][j][k];
5279                                         }
5280
5281                                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5282                                                 CalculateFlipSchedule(
5283                                                                 mode_lib,
5284                                                                 k,
5285                                                                 HostVMInefficiencyFactor,
5286                                                                 v->ExtraLatency,
5287                                                                 v->UrgLatency[i],
5288                                                                 v->PDEAndMetaPTEBytesPerFrame[i][j][k],
5289                                                                 v->MetaRowBytes[i][j][k],
5290                                                                 v->DPTEBytesPerRow[i][j][k]);
5291                                         }
5292                                         v->total_dcn_read_bw_with_flip = 0.0;
5293                                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5294                                                 v->total_dcn_read_bw_with_flip = v->total_dcn_read_bw_with_flip
5295                                                                 + dml_max3(
5296                                                                                 v->NoOfDPP[i][j][k] * v->prefetch_vmrow_bw[k],
5297                                                                                 v->NoOfDPP[i][j][k] * v->final_flip_bw[k] + v->VActivePixelBandwidth[i][j][k]
5298                                                                                                 + v->VActiveCursorBandwidth[i][j][k],
5299                                                                                 v->NoOfDPP[i][j][k]
5300                                                                                                 * (v->final_flip_bw[k]
5301                                                                                                                 + v->RequiredPrefetchPixelDataBWLuma[i][j][k]
5302                                                                                                                                 * v->UrgentBurstFactorLumaPre[k]
5303                                                                                                                 + v->RequiredPrefetchPixelDataBWChroma[i][j][k]
5304                                                                                                                                 * v->UrgentBurstFactorChromaPre[k])
5305                                                                                                 + v->cursor_bw_pre[k] * v->UrgentBurstFactorCursorPre[k]);
5306                                         }
5307                                         v->ImmediateFlipSupportedForState[i][j] = true;
5308                                         if (v->total_dcn_read_bw_with_flip > v->ReturnBWPerState[i][j]) {
5309                                                 v->ImmediateFlipSupportedForState[i][j] = false;
5310                                         }
5311                                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5312                                                 if (v->ImmediateFlipSupportedForPipe[k] == false) {
5313                                                         v->ImmediateFlipSupportedForState[i][j] = false;
5314                                                 }
5315                                         }
5316                                 } else {
5317                                         v->ImmediateFlipSupportedForState[i][j] = false;
5318                                 }
5319
5320                                 if (v->MaxVStartup <= __DML_VBA_MIN_VSTARTUP__ || v->AnyLinesForVMOrRowTooLarge == false) {
5321                                         v->NextMaxVStartup = v->MaxMaxVStartup[i][j];
5322                                         NextPrefetchModeState = NextPrefetchModeState + 1;
5323                                 } else {
5324                                         v->NextMaxVStartup = v->NextMaxVStartup - 1;
5325                                 }
5326                                 v->NextPrefetchMode = v->NextPrefetchMode + 1;
5327                         } while (!((v->PrefetchSupported[i][j] == true && v->DynamicMetadataSupported[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true
5328                                         && ((v->HostVMEnable == false &&
5329                                                         v->ImmediateFlipRequirement[0] != dm_immediate_flip_required)
5330                                                         || v->ImmediateFlipSupportedForState[i][j] == true))
5331                                         || (v->NextMaxVStartup == v->MaxMaxVStartup[i][j] && NextPrefetchModeState > MaxPrefetchMode)));
5332
5333                         CalculateUnboundedRequestAndCompressedBufferSize(
5334                                         v->DETBufferSizeInKByte[0],
5335                                         v->ConfigReturnBufferSizeInKByte,
5336                                         v->UseUnboundedRequesting,
5337                                         v->TotalNumberOfActiveDPP[i][j],
5338                                         NoChroma,
5339                                         v->MaxNumDPP,
5340                                         v->CompressedBufferSegmentSizeInkByte,
5341                                         v->Output,
5342                                         &UnboundedRequestEnabledThisState,
5343                                         &CompressedBufferSizeInkByteThisState);
5344
5345                         CalculateWatermarksAndDRAMSpeedChangeSupport(
5346                                         mode_lib,
5347                                         v->PrefetchModePerState[i][j],
5348                                         v->DCFCLKState[i][j],
5349                                         v->ReturnBWPerState[i][j],
5350                                         v->UrgLatency[i],
5351                                         v->ExtraLatency,
5352                                         v->SOCCLKPerState[i],
5353                                         v->ProjectedDCFCLKDeepSleep[i][j],
5354                                         v->DETBufferSizeYThisState,
5355                                         v->DETBufferSizeCThisState,
5356                                         v->SwathHeightYThisState,
5357                                         v->SwathHeightCThisState,
5358                                         v->SwathWidthYThisState,
5359                                         v->SwathWidthCThisState,
5360                                         v->NoOfDPPThisState,
5361                                         v->BytePerPixelInDETY,
5362                                         v->BytePerPixelInDETC,
5363                                         UnboundedRequestEnabledThisState,
5364                                         CompressedBufferSizeInkByteThisState,
5365                                         &v->DRAMClockChangeSupport[i][j],
5366                                         &dummy,
5367                                         &dummy,
5368                                         &dummy,
5369                                         &dummy);
5370                 }
5371         }
5372
5373         /*PTE Buffer Size Check*/
5374         for (i = 0; i < v->soc.num_states; i++) {
5375                 for (j = 0; j < 2; j++) {
5376                         v->PTEBufferSizeNotExceeded[i][j] = true;
5377                         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5378                                 if (v->PTEBufferSizeNotExceededY[i][j][k] == false || v->PTEBufferSizeNotExceededC[i][j][k] == false) {
5379                                         v->PTEBufferSizeNotExceeded[i][j] = false;
5380                                 }
5381                         }
5382                 }
5383         }
5384
5385         /*Cursor Support Check*/
5386         v->CursorSupport = true;
5387         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5388                 if (v->CursorWidth[k][0] > 0.0) {
5389                         if (v->CursorBPP[k][0] == 64 && v->Cursor64BppSupport == false) {
5390                                 v->CursorSupport = false;
5391                         }
5392                 }
5393         }
5394
5395         /*Valid Pitch Check*/
5396         v->PitchSupport = true;
5397         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5398                 v->AlignedYPitch[k] = dml_ceil(dml_max(v->PitchY[k], v->SurfaceWidthY[k]), v->MacroTileWidthY[k]);
5399                 if (v->DCCEnable[k] == true) {
5400                         v->AlignedDCCMetaPitchY[k] = dml_ceil(dml_max(v->DCCMetaPitchY[k], v->SurfaceWidthY[k]), 64.0 * v->Read256BlockWidthY[k]);
5401                 } else {
5402                         v->AlignedDCCMetaPitchY[k] = v->DCCMetaPitchY[k];
5403                 }
5404                 if (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32 && v->SourcePixelFormat[k] != dm_444_16
5405                                 && v->SourcePixelFormat[k] != dm_mono_16 && v->SourcePixelFormat[k] != dm_rgbe
5406                                 && v->SourcePixelFormat[k] != dm_mono_8) {
5407                         v->AlignedCPitch[k] = dml_ceil(dml_max(v->PitchC[k], v->SurfaceWidthC[k]), v->MacroTileWidthC[k]);
5408                         if (v->DCCEnable[k] == true) {
5409                                 v->AlignedDCCMetaPitchC[k] = dml_ceil(
5410                                                 dml_max(v->DCCMetaPitchC[k], v->SurfaceWidthC[k]),
5411                                                 64.0 * v->Read256BlockWidthC[k]);
5412                         } else {
5413                                 v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
5414                         }
5415                 } else {
5416                         v->AlignedCPitch[k] = v->PitchC[k];
5417                         v->AlignedDCCMetaPitchC[k] = v->DCCMetaPitchC[k];
5418                 }
5419                 if (v->AlignedYPitch[k] > v->PitchY[k] || v->AlignedCPitch[k] > v->PitchC[k]
5420                                 || v->AlignedDCCMetaPitchY[k] > v->DCCMetaPitchY[k] || v->AlignedDCCMetaPitchC[k] > v->DCCMetaPitchC[k]) {
5421                         v->PitchSupport = false;
5422                 }
5423         }
5424
5425         for (k = 0; k < v->NumberOfActivePlanes; k++) {
5426                 if (v->ViewportWidth[k] > v->SurfaceWidthY[k] || v->ViewportHeight[k] > v->SurfaceHeightY[k]) {
5427                         ViewportExceedsSurface = true;
5428                         if (v->SourcePixelFormat[k] != dm_444_64 && v->SourcePixelFormat[k] != dm_444_32
5429                                         && v->SourcePixelFormat[k] != dm_444_16 && v->SourcePixelFormat[k] != dm_444_8
5430                                         && v->SourcePixelFormat[k] != dm_rgbe) {
5431                                 if (v->ViewportWidthChroma[k] > v->SurfaceWidthC[k]
5432                                                 || v->ViewportHeightChroma[k] > v->SurfaceHeightC[k]) {
5433                                         ViewportExceedsSurface = true;
5434                                 }
5435                         }
5436                 }
5437         }
5438
5439         /*Mode Support, Voltage State and SOC Configuration*/
5440         for (i = v->soc.num_states - 1; i >= 0; i--) {
5441                 for (j = 0; j < 2; j++) {
5442                         if (v->ScaleRatioAndTapsSupport == true && v->SourceFormatPixelAndScanSupport == true && v->ViewportSizeSupport[i][j] == true
5443                                         && v->LinkCapacitySupport[i] == true && !P2IWith420 && !DSCOnlyIfNecessaryWithBPP
5444                                         && !DSC422NativeNotSupported && v->ODMCombine4To1SupportCheckOK[i] == true && v->NotEnoughDSCUnits[i] == false
5445                                         && v->DTBCLKRequiredMoreThanSupported[i] == false
5446                                         && v->ROBSupport[i][j] == true && v->DISPCLK_DPPCLK_Support[i][j] == true
5447                                         && v->TotalAvailablePipesSupport[i][j] == true && EnoughWritebackUnits == true
5448                                         && v->WritebackLatencySupport == true && v->WritebackScaleRatioAndTapsSupport == true
5449                                         && v->CursorSupport == true && v->PitchSupport == true && ViewportExceedsSurface == false
5450                                         && v->PrefetchSupported[i][j] == true && v->DynamicMetadataSupported[i][j] == true
5451                                         && v->TotalVerticalActiveBandwidthSupport[i][j] == true && v->VRatioInPrefetchSupported[i][j] == true
5452                                         && v->PTEBufferSizeNotExceeded[i][j] == true && v->NonsupportedDSCInputBPC == false
5453                                         && ((v->HostVMEnable == false
5454                                         && v->ImmediateFlipRequirement[0] != dm_immediate_flip_required)
5455                                                         || v->ImmediateFlipSupportedForState[i][j] == true)
5456                                         && FMTBufferExceeded == false) {
5457                                 v->ModeSupport[i][j] = true;
5458                         } else {
5459                                 v->ModeSupport[i][j] = false;
5460 #ifdef __DML_VBA_DEBUG__
5461                                 if (v->ScaleRatioAndTapsSupport == false)
5462                                         dml_print("DML SUPPORT:     ScaleRatioAndTapsSupport failed");
5463                                 if (v->SourceFormatPixelAndScanSupport == false)
5464                                         dml_print("DML SUPPORT:     SourceFormatPixelAndScanSupport failed");
5465                                 if (v->ViewportSizeSupport[i][j] == false)
5466                                         dml_print("DML SUPPORT:     ViewportSizeSupport failed");
5467                                 if (v->LinkCapacitySupport[i] == false)
5468                                         dml_print("DML SUPPORT:     LinkCapacitySupport failed");
5469                                 if (v->ODMCombine4To1SupportCheckOK[i] == false)
5470                                         dml_print("DML SUPPORT:     DSC422NativeNotSupported failed");
5471                                 if (v->NotEnoughDSCUnits[i] == true)
5472                                         dml_print("DML SUPPORT:     NotEnoughDSCUnits");
5473                                 if (v->DTBCLKRequiredMoreThanSupported[i] == true)
5474                                         dml_print("DML SUPPORT:     DTBCLKRequiredMoreThanSupported");
5475                                 if (v->ROBSupport[i][j] == false)
5476                                         dml_print("DML SUPPORT:     ROBSupport failed");
5477                                 if (v->DISPCLK_DPPCLK_Support[i][j] == false)
5478                                         dml_print("DML SUPPORT:     DISPCLK_DPPCLK_Support failed");
5479                                 if (v->TotalAvailablePipesSupport[i][j] == false)
5480                                         dml_print("DML SUPPORT:     DSC422NativeNotSupported failed");
5481                                 if (EnoughWritebackUnits == false)
5482                                         dml_print("DML SUPPORT:     DSC422NativeNotSupported failed");
5483                                 if (v->WritebackLatencySupport == false)
5484                                         dml_print("DML SUPPORT:     WritebackLatencySupport failed");
5485                                 if (v->WritebackScaleRatioAndTapsSupport == false)
5486                                         dml_print("DML SUPPORT:     DSC422NativeNotSupported ");
5487                                 if (v->CursorSupport == false)
5488                                         dml_print("DML SUPPORT:     DSC422NativeNotSupported failed");
5489                                 if (v->PitchSupport == false)
5490                                         dml_print("DML SUPPORT:     PitchSupport failed");
5491                                 if (ViewportExceedsSurface == true)
5492                                         dml_print("DML SUPPORT:     ViewportExceedsSurface failed");
5493                                 if (v->PrefetchSupported[i][j] == false)
5494                                         dml_print("DML SUPPORT:     PrefetchSupported failed");
5495                                 if (v->DynamicMetadataSupported[i][j] == false)
5496                                         dml_print("DML SUPPORT:     DSC422NativeNotSupported failed");
5497                                 if (v->TotalVerticalActiveBandwidthSupport[i][j] == false)
5498                                         dml_print("DML SUPPORT:     TotalVerticalActiveBandwidthSupport failed");
5499                                 if (v->VRatioInPrefetchSupported[i][j] == false)
5500                                         dml_print("DML SUPPORT:     VRatioInPrefetchSupported failed");
5501                                 if (v->PTEBufferSizeNotExceeded[i][j] == false)
5502                                         dml_print("DML SUPPORT:     PTEBufferSizeNotExceeded failed");
5503                                 if (v->NonsupportedDSCInputBPC == true)
5504                                         dml_print("DML SUPPORT:     NonsupportedDSCInputBPC failed");
5505                                 if (!((v->HostVMEnable == false
5506                                         && v->ImmediateFlipRequirement[0] != dm_immediate_flip_required)
5507                                                         || v->ImmediateFlipSupportedForState[i][j] == true))
5508                                         dml_print("DML SUPPORT:     ImmediateFlipRequirement failed");
5509                                 if (FMTBufferExceeded == true)
5510                                         dml_print("DML SUPPORT:     FMTBufferExceeded failed");
5511 #endif
5512                         }
5513                 }
5514         }
5515
5516         {
5517                 unsigned int MaximumMPCCombine = 0;
5518                 for (i = v->soc.num_states; i >= 0; i--) {
5519                         if (i == v->soc.num_states || v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true) {
5520                                 v->VoltageLevel = i;
5521                                 v->ModeIsSupported = v->ModeSupport[i][0] == true || v->ModeSupport[i][1] == true;
5522                                 if (v->ModeSupport[i][0] == true) {
5523                                         MaximumMPCCombine = 0;
5524                                 } else {
5525                                         MaximumMPCCombine = 1;
5526                                 }
5527                         }
5528                 }
5529                 v->ImmediateFlipSupport = v->ImmediateFlipSupportedForState[v->VoltageLevel][MaximumMPCCombine];
5530                 for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
5531                         v->MPCCombineEnable[k] = v->MPCCombine[v->VoltageLevel][MaximumMPCCombine][k];
5532                         v->DPPPerPlane[k] = v->NoOfDPP[v->VoltageLevel][MaximumMPCCombine][k];
5533                 }
5534                 v->DCFCLK = v->DCFCLKState[v->VoltageLevel][MaximumMPCCombine];
5535                 v->DRAMSpeed = v->DRAMSpeedPerState[v->VoltageLevel];
5536                 v->FabricClock = v->FabricClockPerState[v->VoltageLevel];
5537                 v->SOCCLK = v->SOCCLKPerState[v->VoltageLevel];
5538                 v->ReturnBW = v->ReturnBWPerState[v->VoltageLevel][MaximumMPCCombine];
5539                 v->maxMpcComb = MaximumMPCCombine;
5540         }
5541 }
5542
5543 static void CalculateWatermarksAndDRAMSpeedChangeSupport(
5544                 struct display_mode_lib *mode_lib,
5545                 unsigned int PrefetchMode,
5546                 double DCFCLK,
5547                 double ReturnBW,
5548                 double UrgentLatency,
5549                 double ExtraLatency,
5550                 double SOCCLK,
5551                 double DCFCLKDeepSleep,
5552                 unsigned int DETBufferSizeY[],
5553                 unsigned int DETBufferSizeC[],
5554                 unsigned int SwathHeightY[],
5555                 unsigned int SwathHeightC[],
5556                 double SwathWidthY[],
5557                 double SwathWidthC[],
5558                 unsigned int DPPPerPlane[],
5559                 double BytePerPixelDETY[],
5560                 double BytePerPixelDETC[],
5561                 bool UnboundedRequestEnabled,
5562                 int unsigned CompressedBufferSizeInkByte,
5563                 enum clock_change_support *DRAMClockChangeSupport,
5564                 double *StutterExitWatermark,
5565                 double *StutterEnterPlusExitWatermark,
5566                 double *Z8StutterExitWatermark,
5567                 double *Z8StutterEnterPlusExitWatermark)
5568 {
5569         struct vba_vars_st *v = &mode_lib->vba;
5570         double EffectiveLBLatencyHidingY;
5571         double EffectiveLBLatencyHidingC;
5572         double LinesInDETY[DC__NUM_DPP__MAX];
5573         double LinesInDETC;
5574         unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX];
5575         unsigned int LinesInDETCRoundedDownToSwath;
5576         double FullDETBufferingTimeY;
5577         double FullDETBufferingTimeC;
5578         double ActiveDRAMClockChangeLatencyMarginY;
5579         double ActiveDRAMClockChangeLatencyMarginC;
5580         double WritebackDRAMClockChangeLatencyMargin;
5581         double PlaneWithMinActiveDRAMClockChangeMargin;
5582         double SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank;
5583         double WritebackDRAMClockChangeLatencyHiding;
5584         double TotalPixelBW = 0.0;
5585         int k, j;
5586
5587         v->UrgentWatermark = UrgentLatency + ExtraLatency;
5588
5589 #ifdef __DML_VBA_DEBUG__
5590         dml_print("DML::%s: UrgentLatency = %f\n", __func__, UrgentLatency);
5591         dml_print("DML::%s: ExtraLatency = %f\n", __func__, ExtraLatency);
5592         dml_print("DML::%s: UrgentWatermark = %f\n", __func__, v->UrgentWatermark);
5593 #endif
5594
5595         v->DRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->UrgentWatermark;
5596
5597 #ifdef __DML_VBA_DEBUG__
5598         dml_print("DML::%s: v->DRAMClockChangeLatency = %f\n", __func__, v->DRAMClockChangeLatency);
5599         dml_print("DML::%s: DRAMClockChangeWatermark = %f\n", __func__, v->DRAMClockChangeWatermark);
5600 #endif
5601
5602         v->TotalActiveWriteback = 0;
5603         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5604                 if (v->WritebackEnable[k] == true) {
5605                         v->TotalActiveWriteback = v->TotalActiveWriteback + 1;
5606                 }
5607         }
5608
5609         if (v->TotalActiveWriteback <= 1) {
5610                 v->WritebackUrgentWatermark = v->WritebackLatency;
5611         } else {
5612                 v->WritebackUrgentWatermark = v->WritebackLatency + v->WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
5613         }
5614
5615         if (v->TotalActiveWriteback <= 1) {
5616                 v->WritebackDRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->WritebackLatency;
5617         } else {
5618                 v->WritebackDRAMClockChangeWatermark = v->DRAMClockChangeLatency + v->WritebackLatency + v->WritebackChunkSize * 1024.0 / 32.0 / SOCCLK;
5619         }
5620
5621         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5622                 TotalPixelBW = TotalPixelBW
5623                                 + DPPPerPlane[k] * (SwathWidthY[k] * BytePerPixelDETY[k] * v->VRatio[k] + SwathWidthC[k] * BytePerPixelDETC[k] * v->VRatioChroma[k])
5624                                                 / (v->HTotal[k] / v->PixelClock[k]);
5625         }
5626
5627         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5628                 double EffectiveDETBufferSizeY = DETBufferSizeY[k];
5629
5630                 v->LBLatencyHidingSourceLinesY = dml_min(
5631                                 (double) v->MaxLineBufferLines,
5632                                 dml_floor(v->LineBufferSize / v->LBBitPerPixel[k] / (SwathWidthY[k] / dml_max(v->HRatio[k], 1.0)), 1)) - (v->vtaps[k] - 1);
5633
5634                 v->LBLatencyHidingSourceLinesC = dml_min(
5635                                 (double) v->MaxLineBufferLines,
5636                                 dml_floor(v->LineBufferSize / v->LBBitPerPixel[k] / (SwathWidthC[k] / dml_max(v->HRatioChroma[k], 1.0)), 1)) - (v->VTAPsChroma[k] - 1);
5637
5638                 EffectiveLBLatencyHidingY = v->LBLatencyHidingSourceLinesY / v->VRatio[k] * (v->HTotal[k] / v->PixelClock[k]);
5639
5640                 EffectiveLBLatencyHidingC = v->LBLatencyHidingSourceLinesC / v->VRatioChroma[k] * (v->HTotal[k] / v->PixelClock[k]);
5641
5642                 if (UnboundedRequestEnabled) {
5643                         EffectiveDETBufferSizeY = EffectiveDETBufferSizeY
5644                                         + CompressedBufferSizeInkByte * 1024 * SwathWidthY[k] * BytePerPixelDETY[k] * v->VRatio[k] / (v->HTotal[k] / v->PixelClock[k]) / TotalPixelBW;
5645                 }
5646
5647                 LinesInDETY[k] = (double) EffectiveDETBufferSizeY / BytePerPixelDETY[k] / SwathWidthY[k];
5648                 LinesInDETYRoundedDownToSwath[k] = dml_floor(LinesInDETY[k], SwathHeightY[k]);
5649                 FullDETBufferingTimeY = LinesInDETYRoundedDownToSwath[k] * (v->HTotal[k] / v->PixelClock[k]) / v->VRatio[k];
5650                 if (BytePerPixelDETC[k] > 0) {
5651                         LinesInDETC = v->DETBufferSizeC[k] / BytePerPixelDETC[k] / SwathWidthC[k];
5652                         LinesInDETCRoundedDownToSwath = dml_floor(LinesInDETC, SwathHeightC[k]);
5653                         FullDETBufferingTimeC = LinesInDETCRoundedDownToSwath * (v->HTotal[k] / v->PixelClock[k]) / v->VRatioChroma[k];
5654                 } else {
5655                         LinesInDETC = 0;
5656                         FullDETBufferingTimeC = 999999;
5657                 }
5658
5659                 ActiveDRAMClockChangeLatencyMarginY = EffectiveLBLatencyHidingY + FullDETBufferingTimeY
5660                                 - ((double) v->DSTXAfterScaler[k] / v->HTotal[k] + v->DSTYAfterScaler[k]) * v->HTotal[k] / v->PixelClock[k] - v->UrgentWatermark - v->DRAMClockChangeWatermark;
5661
5662                 if (v->NumberOfActivePlanes > 1) {
5663                         ActiveDRAMClockChangeLatencyMarginY = ActiveDRAMClockChangeLatencyMarginY
5664                                         - (1 - 1.0 / v->NumberOfActivePlanes) * SwathHeightY[k] * v->HTotal[k] / v->PixelClock[k] / v->VRatio[k];
5665                 }
5666
5667                 if (BytePerPixelDETC[k] > 0) {
5668                         ActiveDRAMClockChangeLatencyMarginC = EffectiveLBLatencyHidingC + FullDETBufferingTimeC
5669                                         - ((double) v->DSTXAfterScaler[k] / v->HTotal[k] + v->DSTYAfterScaler[k]) * v->HTotal[k] / v->PixelClock[k] - v->UrgentWatermark - v->DRAMClockChangeWatermark;
5670
5671                         if (v->NumberOfActivePlanes > 1) {
5672                                 ActiveDRAMClockChangeLatencyMarginC = ActiveDRAMClockChangeLatencyMarginC
5673                                                 - (1 - 1.0 / v->NumberOfActivePlanes) * SwathHeightC[k] * v->HTotal[k] / v->PixelClock[k] / v->VRatioChroma[k];
5674                         }
5675                         v->ActiveDRAMClockChangeLatencyMargin[k] = dml_min(ActiveDRAMClockChangeLatencyMarginY, ActiveDRAMClockChangeLatencyMarginC);
5676                 } else {
5677                         v->ActiveDRAMClockChangeLatencyMargin[k] = ActiveDRAMClockChangeLatencyMarginY;
5678                 }
5679
5680                 if (v->WritebackEnable[k] == true) {
5681                         WritebackDRAMClockChangeLatencyHiding = v->WritebackInterfaceBufferSize * 1024
5682                                         / (v->WritebackDestinationWidth[k] * v->WritebackDestinationHeight[k] / (v->WritebackSourceHeight[k] * v->HTotal[k] / v->PixelClock[k]) * 4);
5683                         if (v->WritebackPixelFormat[k] == dm_444_64) {
5684                                 WritebackDRAMClockChangeLatencyHiding = WritebackDRAMClockChangeLatencyHiding / 2;
5685                         }
5686                         WritebackDRAMClockChangeLatencyMargin = WritebackDRAMClockChangeLatencyHiding - v->WritebackDRAMClockChangeWatermark;
5687                         v->ActiveDRAMClockChangeLatencyMargin[k] = dml_min(v->ActiveDRAMClockChangeLatencyMargin[k], WritebackDRAMClockChangeLatencyMargin);
5688                 }
5689         }
5690
5691         v->MinActiveDRAMClockChangeMargin = 999999;
5692         PlaneWithMinActiveDRAMClockChangeMargin = 0;
5693         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5694                 if (v->ActiveDRAMClockChangeLatencyMargin[k] < v->MinActiveDRAMClockChangeMargin) {
5695                         v->MinActiveDRAMClockChangeMargin = v->ActiveDRAMClockChangeLatencyMargin[k];
5696                         if (v->BlendingAndTiming[k] == k) {
5697                                 PlaneWithMinActiveDRAMClockChangeMargin = k;
5698                         } else {
5699                                 for (j = 0; j < v->NumberOfActivePlanes; ++j) {
5700                                         if (v->BlendingAndTiming[k] == j) {
5701                                                 PlaneWithMinActiveDRAMClockChangeMargin = j;
5702                                         }
5703                                 }
5704                         }
5705                 }
5706         }
5707
5708         v->MinActiveDRAMClockChangeLatencySupported = v->MinActiveDRAMClockChangeMargin + v->DRAMClockChangeLatency ;
5709
5710         SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999;
5711         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5712                 if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (v->BlendingAndTiming[k] == k)) && !(v->BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin)
5713                                 && v->ActiveDRAMClockChangeLatencyMargin[k] < SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) {
5714                         SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = v->ActiveDRAMClockChangeLatencyMargin[k];
5715                 }
5716         }
5717
5718         v->TotalNumberOfActiveOTG = 0;
5719
5720         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
5721                 if (v->BlendingAndTiming[k] == k) {
5722                         v->TotalNumberOfActiveOTG = v->TotalNumberOfActiveOTG + 1;
5723                 }
5724         }
5725
5726         if (v->MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) {
5727                 *DRAMClockChangeSupport = dm_dram_clock_change_vactive;
5728         } else if ((v->SynchronizedVBlank == true || v->TotalNumberOfActiveOTG == 1
5729                         || SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0) && PrefetchMode == 0) {
5730                 *DRAMClockChangeSupport = dm_dram_clock_change_vblank;
5731         } else {
5732                 *DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
5733         }
5734
5735         *StutterExitWatermark = v->SRExitTime + ExtraLatency + 10 / DCFCLKDeepSleep;
5736         *StutterEnterPlusExitWatermark = (v->SREnterPlusExitTime + ExtraLatency + 10 / DCFCLKDeepSleep);
5737         *Z8StutterExitWatermark = v->SRExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep;
5738         *Z8StutterEnterPlusExitWatermark = v->SREnterPlusExitZ8Time + ExtraLatency + 10 / DCFCLKDeepSleep;
5739
5740 #ifdef __DML_VBA_DEBUG__
5741         dml_print("DML::%s: StutterExitWatermark = %f\n", __func__, *StutterExitWatermark);
5742         dml_print("DML::%s: StutterEnterPlusExitWatermark = %f\n", __func__, *StutterEnterPlusExitWatermark);
5743         dml_print("DML::%s: Z8StutterExitWatermark = %f\n", __func__, *Z8StutterExitWatermark);
5744         dml_print("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, *Z8StutterEnterPlusExitWatermark);
5745 #endif
5746 }
5747
5748 static void CalculateDCFCLKDeepSleep(
5749                 struct display_mode_lib *mode_lib,
5750                 unsigned int NumberOfActivePlanes,
5751                 int BytePerPixelY[],
5752                 int BytePerPixelC[],
5753                 double VRatio[],
5754                 double VRatioChroma[],
5755                 double SwathWidthY[],
5756                 double SwathWidthC[],
5757                 unsigned int DPPPerPlane[],
5758                 double HRatio[],
5759                 double HRatioChroma[],
5760                 double PixelClock[],
5761                 double PSCL_THROUGHPUT[],
5762                 double PSCL_THROUGHPUT_CHROMA[],
5763                 double DPPCLK[],
5764                 double ReadBandwidthLuma[],
5765                 double ReadBandwidthChroma[],
5766                 int ReturnBusWidth,
5767                 double *DCFCLKDeepSleep)
5768 {
5769         struct vba_vars_st *v = &mode_lib->vba;
5770         double DisplayPipeLineDeliveryTimeLuma;
5771         double DisplayPipeLineDeliveryTimeChroma;
5772         double ReadBandwidth = 0.0;
5773         int k;
5774
5775         for (k = 0; k < NumberOfActivePlanes; ++k) {
5776
5777                 if (VRatio[k] <= 1) {
5778                         DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
5779                 } else {
5780                         DisplayPipeLineDeliveryTimeLuma = SwathWidthY[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
5781                 }
5782                 if (BytePerPixelC[k] == 0) {
5783                         DisplayPipeLineDeliveryTimeChroma = 0;
5784                 } else {
5785                         if (VRatioChroma[k] <= 1) {
5786                                 DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
5787                         } else {
5788                                 DisplayPipeLineDeliveryTimeChroma = SwathWidthC[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
5789                         }
5790                 }
5791
5792                 if (BytePerPixelC[k] > 0) {
5793                         v->DCFCLKDeepSleepPerPlane[k] = dml_max(__DML_MIN_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 32.0 / DisplayPipeLineDeliveryTimeLuma,
5794                         __DML_MIN_DCFCLK_FACTOR__ * SwathWidthC[k] * BytePerPixelC[k] / 32.0 / DisplayPipeLineDeliveryTimeChroma);
5795                 } else {
5796                         v->DCFCLKDeepSleepPerPlane[k] = __DML_MIN_DCFCLK_FACTOR__ * SwathWidthY[k] * BytePerPixelY[k] / 64.0 / DisplayPipeLineDeliveryTimeLuma;
5797                 }
5798                 v->DCFCLKDeepSleepPerPlane[k] = dml_max(v->DCFCLKDeepSleepPerPlane[k], PixelClock[k] / 16);
5799
5800         }
5801
5802         for (k = 0; k < NumberOfActivePlanes; ++k) {
5803                 ReadBandwidth = ReadBandwidth + ReadBandwidthLuma[k] + ReadBandwidthChroma[k];
5804         }
5805
5806         *DCFCLKDeepSleep = dml_max(8.0, __DML_MIN_DCFCLK_FACTOR__ * ReadBandwidth / ReturnBusWidth);
5807
5808         for (k = 0; k < NumberOfActivePlanes; ++k) {
5809                 *DCFCLKDeepSleep = dml_max(*DCFCLKDeepSleep, v->DCFCLKDeepSleepPerPlane[k]);
5810         }
5811 }
5812
5813 static void CalculateUrgentBurstFactor(
5814                 int swath_width_luma_ub,
5815                 int swath_width_chroma_ub,
5816                 unsigned int SwathHeightY,
5817                 unsigned int SwathHeightC,
5818                 double LineTime,
5819                 double UrgentLatency,
5820                 double CursorBufferSize,
5821                 unsigned int CursorWidth,
5822                 unsigned int CursorBPP,
5823                 double VRatio,
5824                 double VRatioC,
5825                 double BytePerPixelInDETY,
5826                 double BytePerPixelInDETC,
5827                 double DETBufferSizeY,
5828                 double DETBufferSizeC,
5829                 double *UrgentBurstFactorCursor,
5830                 double *UrgentBurstFactorLuma,
5831                 double *UrgentBurstFactorChroma,
5832                 bool *NotEnoughUrgentLatencyHiding)
5833 {
5834         double LinesInDETLuma;
5835         double LinesInDETChroma;
5836         unsigned int LinesInCursorBuffer;
5837         double CursorBufferSizeInTime;
5838         double DETBufferSizeInTimeLuma;
5839         double DETBufferSizeInTimeChroma;
5840
5841         *NotEnoughUrgentLatencyHiding = 0;
5842
5843         if (CursorWidth > 0) {
5844                 LinesInCursorBuffer = 1 << (unsigned int) dml_floor(dml_log2(CursorBufferSize * 1024.0 / (CursorWidth * CursorBPP / 8.0)), 1.0);
5845                 if (VRatio > 0) {
5846                         CursorBufferSizeInTime = LinesInCursorBuffer * LineTime / VRatio;
5847                         if (CursorBufferSizeInTime - UrgentLatency <= 0) {
5848                                 *NotEnoughUrgentLatencyHiding = 1;
5849                                 *UrgentBurstFactorCursor = 0;
5850                         } else {
5851                                 *UrgentBurstFactorCursor = CursorBufferSizeInTime / (CursorBufferSizeInTime - UrgentLatency);
5852                         }
5853                 } else {
5854                         *UrgentBurstFactorCursor = 1;
5855                 }
5856         }
5857
5858         LinesInDETLuma = DETBufferSizeY / BytePerPixelInDETY / swath_width_luma_ub;
5859         if (VRatio > 0) {
5860                 DETBufferSizeInTimeLuma = dml_floor(LinesInDETLuma, SwathHeightY) * LineTime / VRatio;
5861                 if (DETBufferSizeInTimeLuma - UrgentLatency <= 0) {
5862                         *NotEnoughUrgentLatencyHiding = 1;
5863                         *UrgentBurstFactorLuma = 0;
5864                 } else {
5865                         *UrgentBurstFactorLuma = DETBufferSizeInTimeLuma / (DETBufferSizeInTimeLuma - UrgentLatency);
5866                 }
5867         } else {
5868                 *UrgentBurstFactorLuma = 1;
5869         }
5870
5871         if (BytePerPixelInDETC > 0) {
5872                 LinesInDETChroma = DETBufferSizeC / BytePerPixelInDETC / swath_width_chroma_ub;
5873                 if (VRatio > 0) {
5874                         DETBufferSizeInTimeChroma = dml_floor(LinesInDETChroma, SwathHeightC) * LineTime / VRatio;
5875                         if (DETBufferSizeInTimeChroma - UrgentLatency <= 0) {
5876                                 *NotEnoughUrgentLatencyHiding = 1;
5877                                 *UrgentBurstFactorChroma = 0;
5878                         } else {
5879                                 *UrgentBurstFactorChroma = DETBufferSizeInTimeChroma / (DETBufferSizeInTimeChroma - UrgentLatency);
5880                         }
5881                 } else {
5882                         *UrgentBurstFactorChroma = 1;
5883                 }
5884         }
5885 }
5886
5887 static void CalculatePixelDeliveryTimes(
5888                 unsigned int NumberOfActivePlanes,
5889                 double VRatio[],
5890                 double VRatioChroma[],
5891                 double VRatioPrefetchY[],
5892                 double VRatioPrefetchC[],
5893                 unsigned int swath_width_luma_ub[],
5894                 unsigned int swath_width_chroma_ub[],
5895                 unsigned int DPPPerPlane[],
5896                 double HRatio[],
5897                 double HRatioChroma[],
5898                 double PixelClock[],
5899                 double PSCL_THROUGHPUT[],
5900                 double PSCL_THROUGHPUT_CHROMA[],
5901                 double DPPCLK[],
5902                 int BytePerPixelC[],
5903                 enum scan_direction_class SourceScan[],
5904                 unsigned int NumberOfCursors[],
5905                 unsigned int CursorWidth[][DC__NUM_CURSOR__MAX],
5906                 unsigned int CursorBPP[][DC__NUM_CURSOR__MAX],
5907                 unsigned int BlockWidth256BytesY[],
5908                 unsigned int BlockHeight256BytesY[],
5909                 unsigned int BlockWidth256BytesC[],
5910                 unsigned int BlockHeight256BytesC[],
5911                 double DisplayPipeLineDeliveryTimeLuma[],
5912                 double DisplayPipeLineDeliveryTimeChroma[],
5913                 double DisplayPipeLineDeliveryTimeLumaPrefetch[],
5914                 double DisplayPipeLineDeliveryTimeChromaPrefetch[],
5915                 double DisplayPipeRequestDeliveryTimeLuma[],
5916                 double DisplayPipeRequestDeliveryTimeChroma[],
5917                 double DisplayPipeRequestDeliveryTimeLumaPrefetch[],
5918                 double DisplayPipeRequestDeliveryTimeChromaPrefetch[],
5919                 double CursorRequestDeliveryTime[],
5920                 double CursorRequestDeliveryTimePrefetch[])
5921 {
5922         double req_per_swath_ub;
5923         int k;
5924
5925         for (k = 0; k < NumberOfActivePlanes; ++k) {
5926                 if (VRatio[k] <= 1) {
5927                         DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
5928                 } else {
5929                         DisplayPipeLineDeliveryTimeLuma[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
5930                 }
5931
5932                 if (BytePerPixelC[k] == 0) {
5933                         DisplayPipeLineDeliveryTimeChroma[k] = 0;
5934                 } else {
5935                         if (VRatioChroma[k] <= 1) {
5936                                 DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
5937                         } else {
5938                                 DisplayPipeLineDeliveryTimeChroma[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
5939                         }
5940                 }
5941
5942                 if (VRatioPrefetchY[k] <= 1) {
5943                         DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] * DPPPerPlane[k] / HRatio[k] / PixelClock[k];
5944                 } else {
5945                         DisplayPipeLineDeliveryTimeLumaPrefetch[k] = swath_width_luma_ub[k] / PSCL_THROUGHPUT[k] / DPPCLK[k];
5946                 }
5947
5948                 if (BytePerPixelC[k] == 0) {
5949                         DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
5950                 } else {
5951                         if (VRatioPrefetchC[k] <= 1) {
5952                                 DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] * DPPPerPlane[k] / HRatioChroma[k] / PixelClock[k];
5953                         } else {
5954                                 DisplayPipeLineDeliveryTimeChromaPrefetch[k] = swath_width_chroma_ub[k] / PSCL_THROUGHPUT_CHROMA[k] / DPPCLK[k];
5955                         }
5956                 }
5957         }
5958
5959         for (k = 0; k < NumberOfActivePlanes; ++k) {
5960                 if (SourceScan[k] != dm_vert) {
5961                         req_per_swath_ub = swath_width_luma_ub[k] / BlockWidth256BytesY[k];
5962                 } else {
5963                         req_per_swath_ub = swath_width_luma_ub[k] / BlockHeight256BytesY[k];
5964                 }
5965                 DisplayPipeRequestDeliveryTimeLuma[k] = DisplayPipeLineDeliveryTimeLuma[k] / req_per_swath_ub;
5966                 DisplayPipeRequestDeliveryTimeLumaPrefetch[k] = DisplayPipeLineDeliveryTimeLumaPrefetch[k] / req_per_swath_ub;
5967                 if (BytePerPixelC[k] == 0) {
5968                         DisplayPipeRequestDeliveryTimeChroma[k] = 0;
5969                         DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = 0;
5970                 } else {
5971                         if (SourceScan[k] != dm_vert) {
5972                                 req_per_swath_ub = swath_width_chroma_ub[k] / BlockWidth256BytesC[k];
5973                         } else {
5974                                 req_per_swath_ub = swath_width_chroma_ub[k] / BlockHeight256BytesC[k];
5975                         }
5976                         DisplayPipeRequestDeliveryTimeChroma[k] = DisplayPipeLineDeliveryTimeChroma[k] / req_per_swath_ub;
5977                         DisplayPipeRequestDeliveryTimeChromaPrefetch[k] = DisplayPipeLineDeliveryTimeChromaPrefetch[k] / req_per_swath_ub;
5978                 }
5979 #ifdef __DML_VBA_DEBUG__
5980                 dml_print("DML::%s: k=%d : HRatio = %f\n", __func__, k, HRatio[k]);
5981                 dml_print("DML::%s: k=%d : VRatio = %f\n", __func__, k, VRatio[k]);
5982                 dml_print("DML::%s: k=%d : HRatioChroma = %f\n", __func__, k, HRatioChroma[k]);
5983                 dml_print("DML::%s: k=%d : VRatioChroma = %f\n", __func__, k, VRatioChroma[k]);
5984                 dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLuma[k]);
5985                 dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeLumaPrefetch[k]);
5986                 dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChroma[k]);
5987                 dml_print("DML::%s: k=%d : DisplayPipeLineDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeLineDeliveryTimeChromaPrefetch[k]);
5988                 dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeLuma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLuma[k]);
5989                 dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeLumaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeLumaPrefetch[k]);
5990                 dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeChroma = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChroma[k]);
5991                 dml_print("DML::%s: k=%d : DisplayPipeRequestDeliveryTimeChromaPrefetch = %f\n", __func__, k, DisplayPipeRequestDeliveryTimeChromaPrefetch[k]);
5992 #endif
5993         }
5994
5995         for (k = 0; k < NumberOfActivePlanes; ++k) {
5996                 int cursor_req_per_width;
5997                 cursor_req_per_width = dml_ceil(CursorWidth[k][0] * CursorBPP[k][0] / 256 / 8, 1);
5998                 if (NumberOfCursors[k] > 0) {
5999                         if (VRatio[k] <= 1) {
6000                                 CursorRequestDeliveryTime[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
6001                         } else {
6002                                 CursorRequestDeliveryTime[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
6003                         }
6004                         if (VRatioPrefetchY[k] <= 1) {
6005                                 CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / HRatio[k] / PixelClock[k] / cursor_req_per_width;
6006                         } else {
6007                                 CursorRequestDeliveryTimePrefetch[k] = CursorWidth[k][0] / PSCL_THROUGHPUT[k] / DPPCLK[k] / cursor_req_per_width;
6008                         }
6009                 } else {
6010                         CursorRequestDeliveryTime[k] = 0;
6011                         CursorRequestDeliveryTimePrefetch[k] = 0;
6012                 }
6013 #ifdef __DML_VBA_DEBUG__
6014                 dml_print("DML::%s: k=%d : NumberOfCursors = %d\n", __func__, k, NumberOfCursors[k]);
6015                 dml_print("DML::%s: k=%d : CursorRequestDeliveryTime = %f\n", __func__, k, CursorRequestDeliveryTime[k]);
6016                 dml_print("DML::%s: k=%d : CursorRequestDeliveryTimePrefetch = %f\n", __func__, k, CursorRequestDeliveryTimePrefetch[k]);
6017 #endif
6018         }
6019 }
6020
6021 static void CalculateMetaAndPTETimes(
6022                 int NumberOfActivePlanes,
6023                 bool GPUVMEnable,
6024                 int MetaChunkSize,
6025                 int MinMetaChunkSizeBytes,
6026                 int HTotal[],
6027                 double VRatio[],
6028                 double VRatioChroma[],
6029                 double DestinationLinesToRequestRowInVBlank[],
6030                 double DestinationLinesToRequestRowInImmediateFlip[],
6031                 bool DCCEnable[],
6032                 double PixelClock[],
6033                 int BytePerPixelY[],
6034                 int BytePerPixelC[],
6035                 enum scan_direction_class SourceScan[],
6036                 int dpte_row_height[],
6037                 int dpte_row_height_chroma[],
6038                 int meta_row_width[],
6039                 int meta_row_width_chroma[],
6040                 int meta_row_height[],
6041                 int meta_row_height_chroma[],
6042                 int meta_req_width[],
6043                 int meta_req_width_chroma[],
6044                 int meta_req_height[],
6045                 int meta_req_height_chroma[],
6046                 int dpte_group_bytes[],
6047                 int PTERequestSizeY[],
6048                 int PTERequestSizeC[],
6049                 int PixelPTEReqWidthY[],
6050                 int PixelPTEReqHeightY[],
6051                 int PixelPTEReqWidthC[],
6052                 int PixelPTEReqHeightC[],
6053                 int dpte_row_width_luma_ub[],
6054                 int dpte_row_width_chroma_ub[],
6055                 double DST_Y_PER_PTE_ROW_NOM_L[],
6056                 double DST_Y_PER_PTE_ROW_NOM_C[],
6057                 double DST_Y_PER_META_ROW_NOM_L[],
6058                 double DST_Y_PER_META_ROW_NOM_C[],
6059                 double TimePerMetaChunkNominal[],
6060                 double TimePerChromaMetaChunkNominal[],
6061                 double TimePerMetaChunkVBlank[],
6062                 double TimePerChromaMetaChunkVBlank[],
6063                 double TimePerMetaChunkFlip[],
6064                 double TimePerChromaMetaChunkFlip[],
6065                 double time_per_pte_group_nom_luma[],
6066                 double time_per_pte_group_vblank_luma[],
6067                 double time_per_pte_group_flip_luma[],
6068                 double time_per_pte_group_nom_chroma[],
6069                 double time_per_pte_group_vblank_chroma[],
6070                 double time_per_pte_group_flip_chroma[])
6071 {
6072         unsigned int meta_chunk_width;
6073         unsigned int min_meta_chunk_width;
6074         unsigned int meta_chunk_per_row_int;
6075         unsigned int meta_row_remainder;
6076         unsigned int meta_chunk_threshold;
6077         unsigned int meta_chunks_per_row_ub;
6078         unsigned int meta_chunk_width_chroma;
6079         unsigned int min_meta_chunk_width_chroma;
6080         unsigned int meta_chunk_per_row_int_chroma;
6081         unsigned int meta_row_remainder_chroma;
6082         unsigned int meta_chunk_threshold_chroma;
6083         unsigned int meta_chunks_per_row_ub_chroma;
6084         unsigned int dpte_group_width_luma;
6085         unsigned int dpte_groups_per_row_luma_ub;
6086         unsigned int dpte_group_width_chroma;
6087         unsigned int dpte_groups_per_row_chroma_ub;
6088         int k;
6089
6090         for (k = 0; k < NumberOfActivePlanes; ++k) {
6091                 DST_Y_PER_PTE_ROW_NOM_L[k] = dpte_row_height[k] / VRatio[k];
6092                 if (BytePerPixelC[k] == 0) {
6093                         DST_Y_PER_PTE_ROW_NOM_C[k] = 0;
6094                 } else {
6095                         DST_Y_PER_PTE_ROW_NOM_C[k] = dpte_row_height_chroma[k] / VRatioChroma[k];
6096                 }
6097                 DST_Y_PER_META_ROW_NOM_L[k] = meta_row_height[k] / VRatio[k];
6098                 if (BytePerPixelC[k] == 0) {
6099                         DST_Y_PER_META_ROW_NOM_C[k] = 0;
6100                 } else {
6101                         DST_Y_PER_META_ROW_NOM_C[k] = meta_row_height_chroma[k] / VRatioChroma[k];
6102                 }
6103         }
6104
6105         for (k = 0; k < NumberOfActivePlanes; ++k) {
6106                 if (DCCEnable[k] == true) {
6107                         meta_chunk_width = MetaChunkSize * 1024 * 256 / BytePerPixelY[k] / meta_row_height[k];
6108                         min_meta_chunk_width = MinMetaChunkSizeBytes * 256 / BytePerPixelY[k] / meta_row_height[k];
6109                         meta_chunk_per_row_int = meta_row_width[k] / meta_chunk_width;
6110                         meta_row_remainder = meta_row_width[k] % meta_chunk_width;
6111                         if (SourceScan[k] != dm_vert) {
6112                                 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width[k];
6113                         } else {
6114                                 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height[k];
6115                         }
6116                         if (meta_row_remainder <= meta_chunk_threshold) {
6117                                 meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
6118                         } else {
6119                                 meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
6120                         }
6121                         TimePerMetaChunkNominal[k] = meta_row_height[k] / VRatio[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
6122                         TimePerMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
6123                         TimePerMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub;
6124                         if (BytePerPixelC[k] == 0) {
6125                                 TimePerChromaMetaChunkNominal[k] = 0;
6126                                 TimePerChromaMetaChunkVBlank[k] = 0;
6127                                 TimePerChromaMetaChunkFlip[k] = 0;
6128                         } else {
6129                                 meta_chunk_width_chroma = MetaChunkSize * 1024 * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
6130                                 min_meta_chunk_width_chroma = MinMetaChunkSizeBytes * 256 / BytePerPixelC[k] / meta_row_height_chroma[k];
6131                                 meta_chunk_per_row_int_chroma = (double) meta_row_width_chroma[k] / meta_chunk_width_chroma;
6132                                 meta_row_remainder_chroma = meta_row_width_chroma[k] % meta_chunk_width_chroma;
6133                                 if (SourceScan[k] != dm_vert) {
6134                                         meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_width_chroma[k];
6135                                 } else {
6136                                         meta_chunk_threshold_chroma = 2 * min_meta_chunk_width_chroma - meta_req_height_chroma[k];
6137                                 }
6138                                 if (meta_row_remainder_chroma <= meta_chunk_threshold_chroma) {
6139                                         meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 1;
6140                                 } else {
6141                                         meta_chunks_per_row_ub_chroma = meta_chunk_per_row_int_chroma + 2;
6142                                 }
6143                                 TimePerChromaMetaChunkNominal[k] = meta_row_height_chroma[k] / VRatioChroma[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
6144                                 TimePerChromaMetaChunkVBlank[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
6145                                 TimePerChromaMetaChunkFlip[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / meta_chunks_per_row_ub_chroma;
6146                         }
6147                 } else {
6148                         TimePerMetaChunkNominal[k] = 0;
6149                         TimePerMetaChunkVBlank[k] = 0;
6150                         TimePerMetaChunkFlip[k] = 0;
6151                         TimePerChromaMetaChunkNominal[k] = 0;
6152                         TimePerChromaMetaChunkVBlank[k] = 0;
6153                         TimePerChromaMetaChunkFlip[k] = 0;
6154                 }
6155         }
6156
6157         for (k = 0; k < NumberOfActivePlanes; ++k) {
6158                 if (GPUVMEnable == true) {
6159                         if (SourceScan[k] != dm_vert) {
6160                                 dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k] * PixelPTEReqWidthY[k];
6161                         } else {
6162                                 dpte_group_width_luma = dpte_group_bytes[k] / PTERequestSizeY[k] * PixelPTEReqHeightY[k];
6163                         }
6164                         dpte_groups_per_row_luma_ub = dml_ceil(1.0 * dpte_row_width_luma_ub[k] / dpte_group_width_luma, 1);
6165                         time_per_pte_group_nom_luma[k] = DST_Y_PER_PTE_ROW_NOM_L[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
6166                         time_per_pte_group_vblank_luma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
6167                         time_per_pte_group_flip_luma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_luma_ub;
6168                         if (BytePerPixelC[k] == 0) {
6169                                 time_per_pte_group_nom_chroma[k] = 0;
6170                                 time_per_pte_group_vblank_chroma[k] = 0;
6171                                 time_per_pte_group_flip_chroma[k] = 0;
6172                         } else {
6173                                 if (SourceScan[k] != dm_vert) {
6174                                         dpte_group_width_chroma = dpte_group_bytes[k] / PTERequestSizeC[k] * PixelPTEReqWidthC[k];
6175                                 } else {
6176                                         dpte_group_width_chroma = dpte_group_bytes[k] / PTERequestSizeC[k] * PixelPTEReqHeightC[k];
6177                                 }
6178                                 dpte_groups_per_row_chroma_ub = dml_ceil(1.0 * dpte_row_width_chroma_ub[k] / dpte_group_width_chroma, 1);
6179                                 time_per_pte_group_nom_chroma[k] = DST_Y_PER_PTE_ROW_NOM_C[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
6180                                 time_per_pte_group_vblank_chroma[k] = DestinationLinesToRequestRowInVBlank[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
6181                                 time_per_pte_group_flip_chroma[k] = DestinationLinesToRequestRowInImmediateFlip[k] * HTotal[k] / PixelClock[k] / dpte_groups_per_row_chroma_ub;
6182                         }
6183                 } else {
6184                         time_per_pte_group_nom_luma[k] = 0;
6185                         time_per_pte_group_vblank_luma[k] = 0;
6186                         time_per_pte_group_flip_luma[k] = 0;
6187                         time_per_pte_group_nom_chroma[k] = 0;
6188                         time_per_pte_group_vblank_chroma[k] = 0;
6189                         time_per_pte_group_flip_chroma[k] = 0;
6190                 }
6191         }
6192 }
6193
6194 static void CalculateVMGroupAndRequestTimes(
6195                 unsigned int NumberOfActivePlanes,
6196                 bool GPUVMEnable,
6197                 unsigned int GPUVMMaxPageTableLevels,
6198                 unsigned int HTotal[],
6199                 int BytePerPixelC[],
6200                 double DestinationLinesToRequestVMInVBlank[],
6201                 double DestinationLinesToRequestVMInImmediateFlip[],
6202                 bool DCCEnable[],
6203                 double PixelClock[],
6204                 int dpte_row_width_luma_ub[],
6205                 int dpte_row_width_chroma_ub[],
6206                 int vm_group_bytes[],
6207                 unsigned int dpde0_bytes_per_frame_ub_l[],
6208                 unsigned int dpde0_bytes_per_frame_ub_c[],
6209                 int meta_pte_bytes_per_frame_ub_l[],
6210                 int meta_pte_bytes_per_frame_ub_c[],
6211                 double TimePerVMGroupVBlank[],
6212                 double TimePerVMGroupFlip[],
6213                 double TimePerVMRequestVBlank[],
6214                 double TimePerVMRequestFlip[])
6215 {
6216         int num_group_per_lower_vm_stage;
6217         int num_req_per_lower_vm_stage;
6218         int k;
6219
6220         for (k = 0; k < NumberOfActivePlanes; ++k) {
6221                 if (GPUVMEnable == true && (DCCEnable[k] == true || GPUVMMaxPageTableLevels > 1)) {
6222                         if (DCCEnable[k] == false) {
6223                                 if (BytePerPixelC[k] > 0) {
6224                                         num_group_per_lower_vm_stage = dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6225                                                         + dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
6226                                 } else {
6227                                         num_group_per_lower_vm_stage = dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
6228                                 }
6229                         } else {
6230                                 if (GPUVMMaxPageTableLevels == 1) {
6231                                         if (BytePerPixelC[k] > 0) {
6232                                                 num_group_per_lower_vm_stage = dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6233                                                                 + dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
6234                                         } else {
6235                                                 num_group_per_lower_vm_stage = dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
6236                                         }
6237                                 } else {
6238                                         if (BytePerPixelC[k] > 0) {
6239                                                 num_group_per_lower_vm_stage = 2 + dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6240                                                                 + dml_ceil((double) (dpde0_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1)
6241                                                                 + dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6242                                                                 + dml_ceil((double) (meta_pte_bytes_per_frame_ub_c[k]) / (double) (vm_group_bytes[k]), 1);
6243                                         } else {
6244                                                 num_group_per_lower_vm_stage = 1 + dml_ceil((double) (dpde0_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1)
6245                                                                 + dml_ceil((double) (meta_pte_bytes_per_frame_ub_l[k]) / (double) (vm_group_bytes[k]), 1);
6246                                         }
6247                                 }
6248                         }
6249
6250                         if (DCCEnable[k] == false) {
6251                                 if (BytePerPixelC[k] > 0) {
6252                                         num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + dpde0_bytes_per_frame_ub_c[k] / 64;
6253                                 } else {
6254                                         num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64;
6255                                 }
6256                         } else {
6257                                 if (GPUVMMaxPageTableLevels == 1) {
6258                                         if (BytePerPixelC[k] > 0) {
6259                                                 num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_c[k] / 64;
6260                                         } else {
6261                                                 num_req_per_lower_vm_stage = meta_pte_bytes_per_frame_ub_l[k] / 64;
6262                                         }
6263                                 } else {
6264                                         if (BytePerPixelC[k] > 0) {
6265                                                 num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + dpde0_bytes_per_frame_ub_c[k] / 64
6266                                                                 + meta_pte_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_c[k] / 64;
6267                                         } else {
6268                                                 num_req_per_lower_vm_stage = dpde0_bytes_per_frame_ub_l[k] / 64 + meta_pte_bytes_per_frame_ub_l[k] / 64;
6269                                         }
6270                                 }
6271                         }
6272
6273                         TimePerVMGroupVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k] / num_group_per_lower_vm_stage;
6274                         TimePerVMGroupFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k] / num_group_per_lower_vm_stage;
6275                         TimePerVMRequestVBlank[k] = DestinationLinesToRequestVMInVBlank[k] * HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
6276                         TimePerVMRequestFlip[k] = DestinationLinesToRequestVMInImmediateFlip[k] * HTotal[k] / PixelClock[k] / num_req_per_lower_vm_stage;
6277
6278                         if (GPUVMMaxPageTableLevels > 2) {
6279                                 TimePerVMGroupVBlank[k] = TimePerVMGroupVBlank[k] / 2;
6280                                 TimePerVMGroupFlip[k] = TimePerVMGroupFlip[k] / 2;
6281                                 TimePerVMRequestVBlank[k] = TimePerVMRequestVBlank[k] / 2;
6282                                 TimePerVMRequestFlip[k] = TimePerVMRequestFlip[k] / 2;
6283                         }
6284
6285                 } else {
6286                         TimePerVMGroupVBlank[k] = 0;
6287                         TimePerVMGroupFlip[k] = 0;
6288                         TimePerVMRequestVBlank[k] = 0;
6289                         TimePerVMRequestFlip[k] = 0;
6290                 }
6291         }
6292 }
6293
6294 static void CalculateStutterEfficiency(
6295                 struct display_mode_lib *mode_lib,
6296                 int CompressedBufferSizeInkByte,
6297                 bool UnboundedRequestEnabled,
6298                 int ConfigReturnBufferSizeInKByte,
6299                 int MetaFIFOSizeInKEntries,
6300                 int ZeroSizeBufferEntries,
6301                 int NumberOfActivePlanes,
6302                 int ROBBufferSizeInKByte,
6303                 double TotalDataReadBandwidth,
6304                 double DCFCLK,
6305                 double ReturnBW,
6306                 double COMPBUF_RESERVED_SPACE_64B,
6307                 double COMPBUF_RESERVED_SPACE_ZS,
6308                 double SRExitTime,
6309                 double SRExitZ8Time,
6310                 bool SynchronizedVBlank,
6311                 double Z8StutterEnterPlusExitWatermark,
6312                 double StutterEnterPlusExitWatermark,
6313                 bool ProgressiveToInterlaceUnitInOPP,
6314                 bool Interlace[],
6315                 double MinTTUVBlank[],
6316                 int DPPPerPlane[],
6317                 unsigned int DETBufferSizeY[],
6318                 int BytePerPixelY[],
6319                 double BytePerPixelDETY[],
6320                 double SwathWidthY[],
6321                 int SwathHeightY[],
6322                 int SwathHeightC[],
6323                 double NetDCCRateLuma[],
6324                 double NetDCCRateChroma[],
6325                 double DCCFractionOfZeroSizeRequestsLuma[],
6326                 double DCCFractionOfZeroSizeRequestsChroma[],
6327                 int HTotal[],
6328                 int VTotal[],
6329                 double PixelClock[],
6330                 double VRatio[],
6331                 enum scan_direction_class SourceScan[],
6332                 int BlockHeight256BytesY[],
6333                 int BlockWidth256BytesY[],
6334                 int BlockHeight256BytesC[],
6335                 int BlockWidth256BytesC[],
6336                 int DCCYMaxUncompressedBlock[],
6337                 int DCCCMaxUncompressedBlock[],
6338                 int VActive[],
6339                 bool DCCEnable[],
6340                 bool WritebackEnable[],
6341                 double ReadBandwidthPlaneLuma[],
6342                 double ReadBandwidthPlaneChroma[],
6343                 double meta_row_bw[],
6344                 double dpte_row_bw[],
6345                 double *StutterEfficiencyNotIncludingVBlank,
6346                 double *StutterEfficiency,
6347                 int *NumberOfStutterBurstsPerFrame,
6348                 double *Z8StutterEfficiencyNotIncludingVBlank,
6349                 double *Z8StutterEfficiency,
6350                 int *Z8NumberOfStutterBurstsPerFrame,
6351                 double *StutterPeriod)
6352 {
6353         struct vba_vars_st *v = &mode_lib->vba;
6354
6355         double DETBufferingTimeY;
6356         double SwathWidthYCriticalPlane = 0;
6357         double VActiveTimeCriticalPlane = 0;
6358         double FrameTimeCriticalPlane = 0;
6359         int BytePerPixelYCriticalPlane = 0;
6360         double LinesToFinishSwathTransferStutterCriticalPlane = 0;
6361         double MinTTUVBlankCriticalPlane = 0;
6362         double TotalCompressedReadBandwidth;
6363         double TotalRowReadBandwidth;
6364         double AverageDCCCompressionRate;
6365         double EffectiveCompressedBufferSize;
6366         double PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer;
6367         double StutterBurstTime;
6368         int TotalActiveWriteback;
6369         double LinesInDETY;
6370         double LinesInDETYRoundedDownToSwath;
6371         double MaximumEffectiveCompressionLuma;
6372         double MaximumEffectiveCompressionChroma;
6373         double TotalZeroSizeRequestReadBandwidth;
6374         double TotalZeroSizeCompressedReadBandwidth;
6375         double AverageDCCZeroSizeFraction;
6376         double AverageZeroSizeCompressionRate;
6377         int TotalNumberOfActiveOTG = 0;
6378         double LastStutterPeriod = 0.0;
6379         double LastZ8StutterPeriod = 0.0;
6380         int k;
6381
6382         TotalZeroSizeRequestReadBandwidth = 0;
6383         TotalZeroSizeCompressedReadBandwidth = 0;
6384         TotalRowReadBandwidth = 0;
6385         TotalCompressedReadBandwidth = 0;
6386
6387         for (k = 0; k < NumberOfActivePlanes; ++k) {
6388                 if (DCCEnable[k] == true) {
6389                         if ((SourceScan[k] == dm_vert && BlockWidth256BytesY[k] > SwathHeightY[k]) || (SourceScan[k] != dm_vert && BlockHeight256BytesY[k] > SwathHeightY[k])
6390                                         || DCCYMaxUncompressedBlock[k] < 256) {
6391                                 MaximumEffectiveCompressionLuma = 2;
6392                         } else {
6393                                 MaximumEffectiveCompressionLuma = 4;
6394                         }
6395                         TotalCompressedReadBandwidth = TotalCompressedReadBandwidth + ReadBandwidthPlaneLuma[k] / dml_min(NetDCCRateLuma[k], MaximumEffectiveCompressionLuma);
6396                         TotalZeroSizeRequestReadBandwidth = TotalZeroSizeRequestReadBandwidth + ReadBandwidthPlaneLuma[k] * DCCFractionOfZeroSizeRequestsLuma[k];
6397                         TotalZeroSizeCompressedReadBandwidth = TotalZeroSizeCompressedReadBandwidth
6398                                         + ReadBandwidthPlaneLuma[k] * DCCFractionOfZeroSizeRequestsLuma[k] / MaximumEffectiveCompressionLuma;
6399                         if (ReadBandwidthPlaneChroma[k] > 0) {
6400                                 if ((SourceScan[k] == dm_vert && BlockWidth256BytesC[k] > SwathHeightC[k])
6401                                                 || (SourceScan[k] != dm_vert && BlockHeight256BytesC[k] > SwathHeightC[k]) || DCCCMaxUncompressedBlock[k] < 256) {
6402                                         MaximumEffectiveCompressionChroma = 2;
6403                                 } else {
6404                                         MaximumEffectiveCompressionChroma = 4;
6405                                 }
6406                                 TotalCompressedReadBandwidth = TotalCompressedReadBandwidth
6407                                                 + ReadBandwidthPlaneChroma[k] / dml_min(NetDCCRateChroma[k], MaximumEffectiveCompressionChroma);
6408                                 TotalZeroSizeRequestReadBandwidth = TotalZeroSizeRequestReadBandwidth + ReadBandwidthPlaneChroma[k] * DCCFractionOfZeroSizeRequestsChroma[k];
6409                                 TotalZeroSizeCompressedReadBandwidth = TotalZeroSizeCompressedReadBandwidth
6410                                                 + ReadBandwidthPlaneChroma[k] * DCCFractionOfZeroSizeRequestsChroma[k] / MaximumEffectiveCompressionChroma;
6411                         }
6412                 } else {
6413                         TotalCompressedReadBandwidth = TotalCompressedReadBandwidth + ReadBandwidthPlaneLuma[k] + ReadBandwidthPlaneChroma[k];
6414                 }
6415                 TotalRowReadBandwidth = TotalRowReadBandwidth + DPPPerPlane[k] * (meta_row_bw[k] + dpte_row_bw[k]);
6416         }
6417
6418         AverageDCCCompressionRate = TotalDataReadBandwidth / TotalCompressedReadBandwidth;
6419         AverageDCCZeroSizeFraction = TotalZeroSizeRequestReadBandwidth / TotalDataReadBandwidth;
6420
6421 #ifdef __DML_VBA_DEBUG__
6422         dml_print("DML::%s: TotalCompressedReadBandwidth = %f\n", __func__, TotalCompressedReadBandwidth);
6423         dml_print("DML::%s: TotalZeroSizeRequestReadBandwidth = %f\n", __func__, TotalZeroSizeRequestReadBandwidth);
6424         dml_print("DML::%s: TotalZeroSizeCompressedReadBandwidth = %f\n", __func__, TotalZeroSizeCompressedReadBandwidth);
6425         dml_print("DML::%s: MaximumEffectiveCompressionLuma = %f\n", __func__, MaximumEffectiveCompressionLuma);
6426         dml_print("DML::%s: MaximumEffectiveCompressionChroma = %f\n", __func__, MaximumEffectiveCompressionChroma);
6427         dml_print("DML::%s: AverageDCCCompressionRate = %f\n", __func__, AverageDCCCompressionRate);
6428         dml_print("DML::%s: AverageDCCZeroSizeFraction = %f\n", __func__, AverageDCCZeroSizeFraction);
6429         dml_print("DML::%s: CompressedBufferSizeInkByte = %d\n", __func__, CompressedBufferSizeInkByte);
6430 #endif
6431
6432         if (AverageDCCZeroSizeFraction == 1) {
6433                 AverageZeroSizeCompressionRate = TotalZeroSizeRequestReadBandwidth / TotalZeroSizeCompressedReadBandwidth;
6434                 EffectiveCompressedBufferSize = MetaFIFOSizeInKEntries * 1024 * 64 * AverageZeroSizeCompressionRate + (ZeroSizeBufferEntries - COMPBUF_RESERVED_SPACE_ZS) * 64 * AverageZeroSizeCompressionRate;
6435         } else if (AverageDCCZeroSizeFraction > 0) {
6436                 AverageZeroSizeCompressionRate = TotalZeroSizeRequestReadBandwidth / TotalZeroSizeCompressedReadBandwidth;
6437                 EffectiveCompressedBufferSize = dml_min(
6438                                 CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate,
6439                                 MetaFIFOSizeInKEntries * 1024 * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate + 1 / AverageDCCCompressionRate))
6440                                         + dml_min((ROBBufferSizeInKByte * 1024 - COMPBUF_RESERVED_SPACE_64B * 64) * AverageDCCCompressionRate,
6441                                                 (ZeroSizeBufferEntries - COMPBUF_RESERVED_SPACE_ZS) * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate));
6442                 dml_print("DML::%s: min 1 = %f\n", __func__, CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate);
6443                 dml_print(
6444                                 "DML::%s: min 2 = %f\n",
6445                                 __func__,
6446                                 MetaFIFOSizeInKEntries * 1024 * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate + 1 / AverageDCCCompressionRate));
6447                 dml_print("DML::%s: min 3 = %f\n", __func__, ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate);
6448                 dml_print("DML::%s: min 4 = %f\n", __func__, ZeroSizeBufferEntries * 64 / (AverageDCCZeroSizeFraction / AverageZeroSizeCompressionRate));
6449         } else {
6450                 EffectiveCompressedBufferSize = dml_min(
6451                                 CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate,
6452                                 MetaFIFOSizeInKEntries * 1024 * 64 * AverageDCCCompressionRate) + (ROBBufferSizeInKByte * 1024 - COMPBUF_RESERVED_SPACE_64B * 64) * AverageDCCCompressionRate;
6453                 dml_print("DML::%s: min 1 = %f\n", __func__, CompressedBufferSizeInkByte * 1024 * AverageDCCCompressionRate);
6454                 dml_print("DML::%s: min 2 = %f\n", __func__, MetaFIFOSizeInKEntries * 1024 * 64 * AverageDCCCompressionRate);
6455         }
6456
6457 #ifdef __DML_VBA_DEBUG__
6458         dml_print("DML::%s: MetaFIFOSizeInKEntries = %d\n", __func__, MetaFIFOSizeInKEntries);
6459         dml_print("DML::%s: AverageZeroSizeCompressionRate = %f\n", __func__, AverageZeroSizeCompressionRate);
6460         dml_print("DML::%s: EffectiveCompressedBufferSize = %f\n", __func__, EffectiveCompressedBufferSize);
6461 #endif
6462
6463         *StutterPeriod = 0;
6464         for (k = 0; k < NumberOfActivePlanes; ++k) {
6465                 LinesInDETY = (DETBufferSizeY[k] + (UnboundedRequestEnabled == true ? EffectiveCompressedBufferSize : 0) * ReadBandwidthPlaneLuma[k] / TotalDataReadBandwidth)
6466                                 / BytePerPixelDETY[k] / SwathWidthY[k];
6467                 LinesInDETYRoundedDownToSwath = dml_floor(LinesInDETY, SwathHeightY[k]);
6468                 DETBufferingTimeY = LinesInDETYRoundedDownToSwath * (HTotal[k] / PixelClock[k]) / VRatio[k];
6469 #ifdef __DML_VBA_DEBUG__
6470                 dml_print("DML::%s: k=%0d DETBufferSizeY = %f\n", __func__, k, DETBufferSizeY[k]);
6471                 dml_print("DML::%s: k=%0d BytePerPixelDETY = %f\n", __func__, k, BytePerPixelDETY[k]);
6472                 dml_print("DML::%s: k=%0d SwathWidthY = %f\n", __func__, k, SwathWidthY[k]);
6473                 dml_print("DML::%s: k=%0d ReadBandwidthPlaneLuma = %f\n", __func__, k, ReadBandwidthPlaneLuma[k]);
6474                 dml_print("DML::%s: k=%0d TotalDataReadBandwidth = %f\n", __func__, k, TotalDataReadBandwidth);
6475                 dml_print("DML::%s: k=%0d LinesInDETY = %f\n", __func__, k, LinesInDETY);
6476                 dml_print("DML::%s: k=%0d LinesInDETYRoundedDownToSwath = %f\n", __func__, k, LinesInDETYRoundedDownToSwath);
6477                 dml_print("DML::%s: k=%0d HTotal = %d\n", __func__, k, HTotal[k]);
6478                 dml_print("DML::%s: k=%0d PixelClock = %f\n", __func__, k, PixelClock[k]);
6479                 dml_print("DML::%s: k=%0d VRatio = %f\n", __func__, k, VRatio[k]);
6480                 dml_print("DML::%s: k=%0d DETBufferingTimeY = %f\n", __func__, k, DETBufferingTimeY);
6481                 dml_print("DML::%s: k=%0d PixelClock = %f\n", __func__, k, PixelClock[k]);
6482 #endif
6483
6484                 if (k == 0 || DETBufferingTimeY < *StutterPeriod) {
6485                         bool isInterlaceTiming = Interlace[k] && !ProgressiveToInterlaceUnitInOPP;
6486
6487                         *StutterPeriod = DETBufferingTimeY;
6488                         FrameTimeCriticalPlane = (isInterlaceTiming ? dml_floor(VTotal[k] / 2.0, 1.0) : VTotal[k]) * HTotal[k] / PixelClock[k];
6489                         VActiveTimeCriticalPlane = (isInterlaceTiming ? dml_floor(VActive[k] / 2.0, 1.0) : VActive[k]) * HTotal[k] / PixelClock[k];
6490                         BytePerPixelYCriticalPlane = BytePerPixelY[k];
6491                         SwathWidthYCriticalPlane = SwathWidthY[k];
6492                         LinesToFinishSwathTransferStutterCriticalPlane = SwathHeightY[k] - (LinesInDETY - LinesInDETYRoundedDownToSwath);
6493                         MinTTUVBlankCriticalPlane = MinTTUVBlank[k];
6494
6495 #ifdef __DML_VBA_DEBUG__
6496                         dml_print("DML::%s: StutterPeriod = %f\n", __func__, *StutterPeriod);
6497                         dml_print("DML::%s: MinTTUVBlankCriticalPlane = %f\n", __func__, MinTTUVBlankCriticalPlane);
6498                         dml_print("DML::%s: FrameTimeCriticalPlane = %f\n", __func__, FrameTimeCriticalPlane);
6499                         dml_print("DML::%s: VActiveTimeCriticalPlane = %f\n", __func__, VActiveTimeCriticalPlane);
6500                         dml_print("DML::%s: BytePerPixelYCriticalPlane = %d\n", __func__, BytePerPixelYCriticalPlane);
6501                         dml_print("DML::%s: SwathWidthYCriticalPlane = %f\n", __func__, SwathWidthYCriticalPlane);
6502                         dml_print("DML::%s: LinesToFinishSwathTransferStutterCriticalPlane = %f\n", __func__, LinesToFinishSwathTransferStutterCriticalPlane);
6503 #endif
6504                 }
6505         }
6506
6507         PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = dml_min(*StutterPeriod * TotalDataReadBandwidth, EffectiveCompressedBufferSize);
6508 #ifdef __DML_VBA_DEBUG__
6509         dml_print("DML::%s: ROBBufferSizeInKByte = %d\n", __func__, ROBBufferSizeInKByte);
6510         dml_print("DML::%s: AverageDCCCompressionRate = %f\n", __func__, AverageDCCCompressionRate);
6511         dml_print("DML::%s: StutterPeriod * TotalDataReadBandwidth = %f\n", __func__, *StutterPeriod * TotalDataReadBandwidth);
6512         dml_print("DML::%s: ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate + EffectiveCompressedBufferSize = %f\n", __func__, ROBBufferSizeInKByte * 1024 * AverageDCCCompressionRate + EffectiveCompressedBufferSize);
6513         dml_print("DML::%s: EffectiveCompressedBufferSize = %f\n", __func__, EffectiveCompressedBufferSize);
6514         dml_print("DML::%s: PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer = %f\n", __func__, PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer);
6515         dml_print("DML::%s: ReturnBW = %f\n", __func__, ReturnBW);
6516         dml_print("DML::%s: TotalDataReadBandwidth = %f\n", __func__, TotalDataReadBandwidth);
6517         dml_print("DML::%s: TotalRowReadBandwidth = %f\n", __func__, TotalRowReadBandwidth);
6518         dml_print("DML::%s: DCFCLK = %f\n", __func__, DCFCLK);
6519 #endif
6520
6521         StutterBurstTime = PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / AverageDCCCompressionRate / ReturnBW
6522                         + (*StutterPeriod * TotalDataReadBandwidth - PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (DCFCLK * 64)
6523                         + *StutterPeriod * TotalRowReadBandwidth / ReturnBW;
6524 #ifdef __DML_VBA_DEBUG__
6525         dml_print("DML::%s: Part 1 = %f\n", __func__, PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer / AverageDCCCompressionRate / ReturnBW);
6526         dml_print("DML::%s: StutterPeriod * TotalDataReadBandwidth = %f\n", __func__, (*StutterPeriod * TotalDataReadBandwidth));
6527         dml_print("DML::%s: Part 2 = %f\n", __func__, (*StutterPeriod * TotalDataReadBandwidth - PartOfUncompressedPixelBurstThatFitsInROBAndCompressedBuffer) / (DCFCLK * 64));
6528         dml_print("DML::%s: Part 3 = %f\n", __func__, *StutterPeriod * TotalRowReadBandwidth / ReturnBW);
6529         dml_print("DML::%s: StutterBurstTime = %f\n", __func__, StutterBurstTime);
6530 #endif
6531         StutterBurstTime = dml_max(StutterBurstTime, LinesToFinishSwathTransferStutterCriticalPlane * BytePerPixelYCriticalPlane * SwathWidthYCriticalPlane / ReturnBW);
6532
6533         dml_print(
6534                         "DML::%s: Time to finish residue swath=%f\n",
6535                         __func__,
6536                         LinesToFinishSwathTransferStutterCriticalPlane * BytePerPixelYCriticalPlane * SwathWidthYCriticalPlane / ReturnBW);
6537
6538         TotalActiveWriteback = 0;
6539         for (k = 0; k < NumberOfActivePlanes; ++k) {
6540                 if (WritebackEnable[k]) {
6541                         TotalActiveWriteback = TotalActiveWriteback + 1;
6542                 }
6543         }
6544
6545         if (TotalActiveWriteback == 0) {
6546 #ifdef __DML_VBA_DEBUG__
6547                 dml_print("DML::%s: SRExitTime = %f\n", __func__, SRExitTime);
6548                 dml_print("DML::%s: SRExitZ8Time = %f\n", __func__, SRExitZ8Time);
6549                 dml_print("DML::%s: StutterBurstTime = %f (final)\n", __func__, StutterBurstTime);
6550                 dml_print("DML::%s: StutterPeriod = %f\n", __func__, *StutterPeriod);
6551 #endif
6552                 *StutterEfficiencyNotIncludingVBlank = dml_max(0., 1 - (SRExitTime + StutterBurstTime) / *StutterPeriod) * 100;
6553                 *Z8StutterEfficiencyNotIncludingVBlank = dml_max(0., 1 - (SRExitZ8Time + StutterBurstTime) / *StutterPeriod) * 100;
6554                 *NumberOfStutterBurstsPerFrame = (*StutterEfficiencyNotIncludingVBlank > 0 ? dml_ceil(VActiveTimeCriticalPlane / *StutterPeriod, 1) : 0);
6555                 *Z8NumberOfStutterBurstsPerFrame = (*Z8StutterEfficiencyNotIncludingVBlank > 0 ? dml_ceil(VActiveTimeCriticalPlane / *StutterPeriod, 1) : 0);
6556         } else {
6557                 *StutterEfficiencyNotIncludingVBlank = 0.;
6558                 *Z8StutterEfficiencyNotIncludingVBlank = 0.;
6559                 *NumberOfStutterBurstsPerFrame = 0;
6560                 *Z8NumberOfStutterBurstsPerFrame = 0;
6561         }
6562 #ifdef __DML_VBA_DEBUG__
6563         dml_print("DML::%s: VActiveTimeCriticalPlane = %f\n", __func__, VActiveTimeCriticalPlane);
6564         dml_print("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *StutterEfficiencyNotIncludingVBlank);
6565         dml_print("DML::%s: Z8StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *Z8StutterEfficiencyNotIncludingVBlank);
6566         dml_print("DML::%s: NumberOfStutterBurstsPerFrame = %d\n", __func__, *NumberOfStutterBurstsPerFrame);
6567         dml_print("DML::%s: Z8NumberOfStutterBurstsPerFrame = %d\n", __func__, *Z8NumberOfStutterBurstsPerFrame);
6568 #endif
6569
6570         for (k = 0; k < NumberOfActivePlanes; ++k) {
6571                 if (v->BlendingAndTiming[k] == k) {
6572                         TotalNumberOfActiveOTG = TotalNumberOfActiveOTG + 1;
6573                 }
6574         }
6575
6576         if (*StutterEfficiencyNotIncludingVBlank > 0) {
6577                 LastStutterPeriod = VActiveTimeCriticalPlane - (*NumberOfStutterBurstsPerFrame - 1) * *StutterPeriod;
6578
6579                 if ((SynchronizedVBlank || TotalNumberOfActiveOTG == 1) && LastStutterPeriod + MinTTUVBlankCriticalPlane > StutterEnterPlusExitWatermark) {
6580                         *StutterEfficiency = (1 - (*NumberOfStutterBurstsPerFrame * SRExitTime + StutterBurstTime * VActiveTimeCriticalPlane
6581                                         / *StutterPeriod) / FrameTimeCriticalPlane) * 100;
6582                 } else {
6583                         *StutterEfficiency = *StutterEfficiencyNotIncludingVBlank;
6584                 }
6585         } else {
6586                 *StutterEfficiency = 0;
6587         }
6588
6589         if (*Z8StutterEfficiencyNotIncludingVBlank > 0) {
6590                 LastZ8StutterPeriod = VActiveTimeCriticalPlane - (*NumberOfStutterBurstsPerFrame - 1) * *StutterPeriod;
6591                 if ((SynchronizedVBlank || TotalNumberOfActiveOTG == 1) && LastZ8StutterPeriod + MinTTUVBlankCriticalPlane > Z8StutterEnterPlusExitWatermark) {
6592                         *Z8StutterEfficiency = (1 - (*NumberOfStutterBurstsPerFrame * SRExitZ8Time + StutterBurstTime * VActiveTimeCriticalPlane
6593                                         / *StutterPeriod) / FrameTimeCriticalPlane) * 100;
6594                 } else {
6595                         *Z8StutterEfficiency = *Z8StutterEfficiencyNotIncludingVBlank;
6596                 }
6597         } else {
6598                 *Z8StutterEfficiency = 0.;
6599         }
6600
6601         dml_print("DML::%s: LastZ8StutterPeriod = %f\n", __func__, LastZ8StutterPeriod);
6602         dml_print("DML::%s: Z8StutterEnterPlusExitWatermark = %f\n", __func__, Z8StutterEnterPlusExitWatermark);
6603         dml_print("DML::%s: StutterBurstTime = %f\n", __func__, StutterBurstTime);
6604         dml_print("DML::%s: StutterPeriod = %f\n", __func__, *StutterPeriod);
6605         dml_print("DML::%s: StutterEfficiency = %f\n", __func__, *StutterEfficiency);
6606         dml_print("DML::%s: Z8StutterEfficiency = %f\n", __func__, *Z8StutterEfficiency);
6607         dml_print("DML::%s: StutterEfficiencyNotIncludingVBlank = %f\n", __func__, *StutterEfficiencyNotIncludingVBlank);
6608         dml_print("DML::%s: Z8NumberOfStutterBurstsPerFrame = %d\n", __func__, *Z8NumberOfStutterBurstsPerFrame);
6609 }
6610
6611 static void CalculateSwathAndDETConfiguration(
6612                 bool ForceSingleDPP,
6613                 int NumberOfActivePlanes,
6614                 unsigned int DETBufferSizeInKByte,
6615                 double MaximumSwathWidthLuma[],
6616                 double MaximumSwathWidthChroma[],
6617                 enum scan_direction_class SourceScan[],
6618                 enum source_format_class SourcePixelFormat[],
6619                 enum dm_swizzle_mode SurfaceTiling[],
6620                 int ViewportWidth[],
6621                 int ViewportHeight[],
6622                 int SurfaceWidthY[],
6623                 int SurfaceWidthC[],
6624                 int SurfaceHeightY[],
6625                 int SurfaceHeightC[],
6626                 int Read256BytesBlockHeightY[],
6627                 int Read256BytesBlockHeightC[],
6628                 int Read256BytesBlockWidthY[],
6629                 int Read256BytesBlockWidthC[],
6630                 enum odm_combine_mode ODMCombineEnabled[],
6631                 int BlendingAndTiming[],
6632                 int BytePerPixY[],
6633                 int BytePerPixC[],
6634                 double BytePerPixDETY[],
6635                 double BytePerPixDETC[],
6636                 int HActive[],
6637                 double HRatio[],
6638                 double HRatioChroma[],
6639                 int DPPPerPlane[],
6640                 int swath_width_luma_ub[],
6641                 int swath_width_chroma_ub[],
6642                 double SwathWidth[],
6643                 double SwathWidthChroma[],
6644                 int SwathHeightY[],
6645                 int SwathHeightC[],
6646                 unsigned int DETBufferSizeY[],
6647                 unsigned int DETBufferSizeC[],
6648                 bool ViewportSizeSupportPerPlane[],
6649                 bool *ViewportSizeSupport)
6650 {
6651         int MaximumSwathHeightY[DC__NUM_DPP__MAX];
6652         int MaximumSwathHeightC[DC__NUM_DPP__MAX];
6653         int MinimumSwathHeightY;
6654         int MinimumSwathHeightC;
6655         int RoundedUpMaxSwathSizeBytesY;
6656         int RoundedUpMaxSwathSizeBytesC;
6657         int RoundedUpMinSwathSizeBytesY;
6658         int RoundedUpMinSwathSizeBytesC;
6659         int RoundedUpSwathSizeBytesY;
6660         int RoundedUpSwathSizeBytesC;
6661         double SwathWidthSingleDPP[DC__NUM_DPP__MAX];
6662         double SwathWidthSingleDPPChroma[DC__NUM_DPP__MAX];
6663         int k;
6664
6665         CalculateSwathWidth(
6666                         ForceSingleDPP,
6667                         NumberOfActivePlanes,
6668                         SourcePixelFormat,
6669                         SourceScan,
6670                         ViewportWidth,
6671                         ViewportHeight,
6672                         SurfaceWidthY,
6673                         SurfaceWidthC,
6674                         SurfaceHeightY,
6675                         SurfaceHeightC,
6676                         ODMCombineEnabled,
6677                         BytePerPixY,
6678                         BytePerPixC,
6679                         Read256BytesBlockHeightY,
6680                         Read256BytesBlockHeightC,
6681                         Read256BytesBlockWidthY,
6682                         Read256BytesBlockWidthC,
6683                         BlendingAndTiming,
6684                         HActive,
6685                         HRatio,
6686                         DPPPerPlane,
6687                         SwathWidthSingleDPP,
6688                         SwathWidthSingleDPPChroma,
6689                         SwathWidth,
6690                         SwathWidthChroma,
6691                         MaximumSwathHeightY,
6692                         MaximumSwathHeightC,
6693                         swath_width_luma_ub,
6694                         swath_width_chroma_ub);
6695
6696         *ViewportSizeSupport = true;
6697         for (k = 0; k < NumberOfActivePlanes; ++k) {
6698                 if ((SourcePixelFormat[k] == dm_444_64 || SourcePixelFormat[k] == dm_444_32 || SourcePixelFormat[k] == dm_444_16 || SourcePixelFormat[k] == dm_mono_16
6699                                 || SourcePixelFormat[k] == dm_mono_8 || SourcePixelFormat[k] == dm_rgbe)) {
6700                         if (SurfaceTiling[k] == dm_sw_linear
6701                                         || (SourcePixelFormat[k] == dm_444_64
6702                                                         && (SurfaceTiling[k] == dm_sw_64kb_s || SurfaceTiling[k] == dm_sw_64kb_s_t || SurfaceTiling[k] == dm_sw_64kb_s_x)
6703                                                         && SourceScan[k] != dm_vert)) {
6704                                 MinimumSwathHeightY = MaximumSwathHeightY[k];
6705                         } else if (SourcePixelFormat[k] == dm_444_8 && SourceScan[k] == dm_vert) {
6706                                 MinimumSwathHeightY = MaximumSwathHeightY[k];
6707                         } else {
6708                                 MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6709                         }
6710                         MinimumSwathHeightC = MaximumSwathHeightC[k];
6711                 } else {
6712                         if (SurfaceTiling[k] == dm_sw_linear) {
6713                                 MinimumSwathHeightY = MaximumSwathHeightY[k];
6714                                 MinimumSwathHeightC = MaximumSwathHeightC[k];
6715                         } else if (SourcePixelFormat[k] == dm_rgbe_alpha && SourceScan[k] == dm_vert) {
6716                                 MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6717                                 MinimumSwathHeightC = MaximumSwathHeightC[k];
6718                         } else if (SourcePixelFormat[k] == dm_rgbe_alpha) {
6719                                 MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6720                                 MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6721                         } else if (SourcePixelFormat[k] == dm_420_8 && SourceScan[k] == dm_vert) {
6722                                 MinimumSwathHeightY = MaximumSwathHeightY[k];
6723                                 MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6724                         } else {
6725                                 MinimumSwathHeightC = MaximumSwathHeightC[k] / 2;
6726                                 MinimumSwathHeightY = MaximumSwathHeightY[k] / 2;
6727                         }
6728                 }
6729
6730                 RoundedUpMaxSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k] * MaximumSwathHeightY[k];
6731                 RoundedUpMinSwathSizeBytesY = swath_width_luma_ub[k] * BytePerPixDETY[k] * MinimumSwathHeightY;
6732                 if (SourcePixelFormat[k] == dm_420_10) {
6733                         RoundedUpMaxSwathSizeBytesY = dml_ceil((double) RoundedUpMaxSwathSizeBytesY, 256);
6734                         RoundedUpMinSwathSizeBytesY = dml_ceil((double) RoundedUpMinSwathSizeBytesY, 256);
6735                 }
6736                 RoundedUpMaxSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k] * MaximumSwathHeightC[k];
6737                 RoundedUpMinSwathSizeBytesC = swath_width_chroma_ub[k] * BytePerPixDETC[k] * MinimumSwathHeightC;
6738                 if (SourcePixelFormat[k] == dm_420_10) {
6739                         RoundedUpMaxSwathSizeBytesC = dml_ceil(RoundedUpMaxSwathSizeBytesC, 256);
6740                         RoundedUpMinSwathSizeBytesC = dml_ceil(RoundedUpMinSwathSizeBytesC, 256);
6741                 }
6742
6743                 if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC <= DETBufferSizeInKByte * 1024 / 2) {
6744                         SwathHeightY[k] = MaximumSwathHeightY[k];
6745                         SwathHeightC[k] = MaximumSwathHeightC[k];
6746                         RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
6747                         RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
6748                 } else if (RoundedUpMaxSwathSizeBytesY >= 1.5 * RoundedUpMaxSwathSizeBytesC
6749                                 && RoundedUpMinSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC <= DETBufferSizeInKByte * 1024 / 2) {
6750                         SwathHeightY[k] = MinimumSwathHeightY;
6751                         SwathHeightC[k] = MaximumSwathHeightC[k];
6752                         RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
6753                         RoundedUpSwathSizeBytesC = RoundedUpMaxSwathSizeBytesC;
6754                 } else if (RoundedUpMaxSwathSizeBytesY < 1.5 * RoundedUpMaxSwathSizeBytesC
6755                                 && RoundedUpMaxSwathSizeBytesY + RoundedUpMinSwathSizeBytesC <= DETBufferSizeInKByte * 1024 / 2) {
6756                         SwathHeightY[k] = MaximumSwathHeightY[k];
6757                         SwathHeightC[k] = MinimumSwathHeightC;
6758                         RoundedUpSwathSizeBytesY = RoundedUpMaxSwathSizeBytesY;
6759                         RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
6760                 } else {
6761                         SwathHeightY[k] = MinimumSwathHeightY;
6762                         SwathHeightC[k] = MinimumSwathHeightC;
6763                         RoundedUpSwathSizeBytesY = RoundedUpMinSwathSizeBytesY;
6764                         RoundedUpSwathSizeBytesC = RoundedUpMinSwathSizeBytesC;
6765                 }
6766                 {
6767                 double actDETBufferSizeInKByte = dml_ceil(DETBufferSizeInKByte, 64);
6768                 if (SwathHeightC[k] == 0) {
6769                         DETBufferSizeY[k] = actDETBufferSizeInKByte * 1024;
6770                         DETBufferSizeC[k] = 0;
6771                 } else if (RoundedUpSwathSizeBytesY <= 1.5 * RoundedUpSwathSizeBytesC) {
6772                         DETBufferSizeY[k] = actDETBufferSizeInKByte * 1024 / 2;
6773                         DETBufferSizeC[k] = actDETBufferSizeInKByte * 1024 / 2;
6774                 } else {
6775                         DETBufferSizeY[k] = dml_floor(actDETBufferSizeInKByte * 1024 * 2 / 3, 1024);
6776                         DETBufferSizeC[k] = actDETBufferSizeInKByte * 1024 / 3;
6777                 }
6778
6779                 if (RoundedUpMinSwathSizeBytesY + RoundedUpMinSwathSizeBytesC > actDETBufferSizeInKByte * 1024 / 2 || SwathWidth[k] > MaximumSwathWidthLuma[k]
6780                                 || (SwathHeightC[k] > 0 && SwathWidthChroma[k] > MaximumSwathWidthChroma[k])) {
6781                         *ViewportSizeSupport = false;
6782                         ViewportSizeSupportPerPlane[k] = false;
6783                 } else {
6784                         ViewportSizeSupportPerPlane[k] = true;
6785                 }
6786                 }
6787         }
6788 }
6789
6790 static void CalculateSwathWidth(
6791                 bool ForceSingleDPP,
6792                 int NumberOfActivePlanes,
6793                 enum source_format_class SourcePixelFormat[],
6794                 enum scan_direction_class SourceScan[],
6795                 int ViewportWidth[],
6796                 int ViewportHeight[],
6797                 int SurfaceWidthY[],
6798                 int SurfaceWidthC[],
6799                 int SurfaceHeightY[],
6800                 int SurfaceHeightC[],
6801                 enum odm_combine_mode ODMCombineEnabled[],
6802                 int BytePerPixY[],
6803                 int BytePerPixC[],
6804                 int Read256BytesBlockHeightY[],
6805                 int Read256BytesBlockHeightC[],
6806                 int Read256BytesBlockWidthY[],
6807                 int Read256BytesBlockWidthC[],
6808                 int BlendingAndTiming[],
6809                 int HActive[],
6810                 double HRatio[],
6811                 int DPPPerPlane[],
6812                 double SwathWidthSingleDPPY[],
6813                 double SwathWidthSingleDPPC[],
6814                 double SwathWidthY[],
6815                 double SwathWidthC[],
6816                 int MaximumSwathHeightY[],
6817                 int MaximumSwathHeightC[],
6818                 int swath_width_luma_ub[],
6819                 int swath_width_chroma_ub[])
6820 {
6821         enum odm_combine_mode MainPlaneODMCombine;
6822         int j, k;
6823
6824 #ifdef __DML_VBA_DEBUG__
6825         dml_print("DML::%s: NumberOfActivePlanes = %d\n", __func__, NumberOfActivePlanes);
6826 #endif
6827
6828         for (k = 0; k < NumberOfActivePlanes; ++k) {
6829                 if (SourceScan[k] != dm_vert) {
6830                         SwathWidthSingleDPPY[k] = ViewportWidth[k];
6831                 } else {
6832                         SwathWidthSingleDPPY[k] = ViewportHeight[k];
6833                 }
6834
6835 #ifdef __DML_VBA_DEBUG__
6836                 dml_print("DML::%s: k=%d ViewportWidth=%d\n", __func__, k, ViewportWidth[k]);
6837                 dml_print("DML::%s: k=%d ViewportHeight=%d\n", __func__, k, ViewportHeight[k]);
6838 #endif
6839
6840                 MainPlaneODMCombine = ODMCombineEnabled[k];
6841                 for (j = 0; j < NumberOfActivePlanes; ++j) {
6842                         if (BlendingAndTiming[k] == j) {
6843                                 MainPlaneODMCombine = ODMCombineEnabled[j];
6844                         }
6845                 }
6846
6847                 if (MainPlaneODMCombine == dm_odm_combine_mode_4to1) {
6848                         SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 4.0 * HRatio[k]));
6849                 } else if (MainPlaneODMCombine == dm_odm_combine_mode_2to1) {
6850                         SwathWidthY[k] = dml_min(SwathWidthSingleDPPY[k], dml_round(HActive[k] / 2.0 * HRatio[k]));
6851                 } else if (DPPPerPlane[k] == 2) {
6852                         SwathWidthY[k] = SwathWidthSingleDPPY[k] / 2;
6853                 } else {
6854                         SwathWidthY[k] = SwathWidthSingleDPPY[k];
6855                 }
6856
6857 #ifdef __DML_VBA_DEBUG__
6858                 dml_print("DML::%s: k=%d SwathWidthSingleDPPY=%f\n", __func__, k, SwathWidthSingleDPPY[k]);
6859                 dml_print("DML::%s: k=%d SwathWidthY=%f\n", __func__, k, SwathWidthY[k]);
6860 #endif
6861
6862                 if (SourcePixelFormat[k] == dm_420_8 || SourcePixelFormat[k] == dm_420_10 || SourcePixelFormat[k] == dm_420_12) {
6863                         SwathWidthC[k] = SwathWidthY[k] / 2;
6864                         SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k] / 2;
6865                 } else {
6866                         SwathWidthC[k] = SwathWidthY[k];
6867                         SwathWidthSingleDPPC[k] = SwathWidthSingleDPPY[k];
6868                 }
6869
6870                 if (ForceSingleDPP == true) {
6871                         SwathWidthY[k] = SwathWidthSingleDPPY[k];
6872                         SwathWidthC[k] = SwathWidthSingleDPPC[k];
6873                 }
6874                 {
6875                 int surface_width_ub_l = dml_ceil(SurfaceWidthY[k], Read256BytesBlockWidthY[k]);
6876                 int surface_height_ub_l = dml_ceil(SurfaceHeightY[k], Read256BytesBlockHeightY[k]);
6877
6878 #ifdef __DML_VBA_DEBUG__
6879                 dml_print("DML::%s: k=%d surface_width_ub_l=%0d\n", __func__, k, surface_width_ub_l);
6880 #endif
6881
6882                 if (SourceScan[k] != dm_vert) {
6883                         MaximumSwathHeightY[k] = Read256BytesBlockHeightY[k];
6884                         MaximumSwathHeightC[k] = Read256BytesBlockHeightC[k];
6885                         swath_width_luma_ub[k] = dml_min(surface_width_ub_l, (int) dml_ceil(SwathWidthY[k] - 1, Read256BytesBlockWidthY[k]) + Read256BytesBlockWidthY[k]);
6886                         if (BytePerPixC[k] > 0) {
6887                                 int surface_width_ub_c = dml_ceil(SurfaceWidthC[k], Read256BytesBlockWidthC[k]);
6888
6889                                 swath_width_chroma_ub[k] = dml_min(
6890                                                 surface_width_ub_c,
6891                                                 (int) dml_ceil(SwathWidthC[k] - 1, Read256BytesBlockWidthC[k]) + Read256BytesBlockWidthC[k]);
6892                         } else {
6893                                 swath_width_chroma_ub[k] = 0;
6894                         }
6895                 } else {
6896                         MaximumSwathHeightY[k] = Read256BytesBlockWidthY[k];
6897                         MaximumSwathHeightC[k] = Read256BytesBlockWidthC[k];
6898                         swath_width_luma_ub[k] = dml_min(surface_height_ub_l, (int) dml_ceil(SwathWidthY[k] - 1, Read256BytesBlockHeightY[k]) + Read256BytesBlockHeightY[k]);
6899                         if (BytePerPixC[k] > 0) {
6900                                 int surface_height_ub_c = dml_ceil(SurfaceHeightC[k], Read256BytesBlockHeightC[k]);
6901
6902                                 swath_width_chroma_ub[k] = dml_min(
6903                                                 surface_height_ub_c,
6904                                                 (int) dml_ceil(SwathWidthC[k] - 1, Read256BytesBlockHeightC[k]) + Read256BytesBlockHeightC[k]);
6905                         } else {
6906                                 swath_width_chroma_ub[k] = 0;
6907                         }
6908                 }
6909                 }
6910         }
6911 }
6912
6913 static double CalculateExtraLatency(
6914                 int RoundTripPingLatencyCycles,
6915                 int ReorderingBytes,
6916                 double DCFCLK,
6917                 int TotalNumberOfActiveDPP,
6918                 int PixelChunkSizeInKByte,
6919                 int TotalNumberOfDCCActiveDPP,
6920                 int MetaChunkSize,
6921                 double ReturnBW,
6922                 bool GPUVMEnable,
6923                 bool HostVMEnable,
6924                 int NumberOfActivePlanes,
6925                 int NumberOfDPP[],
6926                 int dpte_group_bytes[],
6927                 double HostVMInefficiencyFactor,
6928                 double HostVMMinPageSize,
6929                 int HostVMMaxNonCachedPageTableLevels)
6930 {
6931         double ExtraLatencyBytes;
6932         double ExtraLatency;
6933
6934         ExtraLatencyBytes = CalculateExtraLatencyBytes(
6935                         ReorderingBytes,
6936                         TotalNumberOfActiveDPP,
6937                         PixelChunkSizeInKByte,
6938                         TotalNumberOfDCCActiveDPP,
6939                         MetaChunkSize,
6940                         GPUVMEnable,
6941                         HostVMEnable,
6942                         NumberOfActivePlanes,
6943                         NumberOfDPP,
6944                         dpte_group_bytes,
6945                         HostVMInefficiencyFactor,
6946                         HostVMMinPageSize,
6947                         HostVMMaxNonCachedPageTableLevels);
6948
6949         ExtraLatency = (RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__) / DCFCLK + ExtraLatencyBytes / ReturnBW;
6950
6951 #ifdef __DML_VBA_DEBUG__
6952         dml_print("DML::%s: RoundTripPingLatencyCycles=%d\n", __func__, RoundTripPingLatencyCycles);
6953         dml_print("DML::%s: DCFCLK=%f\n", __func__, DCFCLK);
6954         dml_print("DML::%s: ExtraLatencyBytes=%f\n", __func__, ExtraLatencyBytes);
6955         dml_print("DML::%s: ReturnBW=%f\n", __func__, ReturnBW);
6956         dml_print("DML::%s: ExtraLatency=%f\n", __func__, ExtraLatency);
6957 #endif
6958
6959         return ExtraLatency;
6960 }
6961
6962 static double CalculateExtraLatencyBytes(
6963                 int ReorderingBytes,
6964                 int TotalNumberOfActiveDPP,
6965                 int PixelChunkSizeInKByte,
6966                 int TotalNumberOfDCCActiveDPP,
6967                 int MetaChunkSize,
6968                 bool GPUVMEnable,
6969                 bool HostVMEnable,
6970                 int NumberOfActivePlanes,
6971                 int NumberOfDPP[],
6972                 int dpte_group_bytes[],
6973                 double HostVMInefficiencyFactor,
6974                 double HostVMMinPageSize,
6975                 int HostVMMaxNonCachedPageTableLevels)
6976 {
6977         double ret;
6978         int HostVMDynamicLevels = 0, k;
6979
6980         if (GPUVMEnable == true && HostVMEnable == true) {
6981                 if (HostVMMinPageSize < 2048) {
6982                         HostVMDynamicLevels = HostVMMaxNonCachedPageTableLevels;
6983                 } else if (HostVMMinPageSize >= 2048 && HostVMMinPageSize < 1048576) {
6984                         HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 1);
6985                 } else {
6986                         HostVMDynamicLevels = dml_max(0, (int) HostVMMaxNonCachedPageTableLevels - 2);
6987                 }
6988         } else {
6989                 HostVMDynamicLevels = 0;
6990         }
6991
6992         ret = ReorderingBytes + (TotalNumberOfActiveDPP * PixelChunkSizeInKByte + TotalNumberOfDCCActiveDPP * MetaChunkSize) * 1024.0;
6993
6994         if (GPUVMEnable == true) {
6995                 for (k = 0; k < NumberOfActivePlanes; ++k) {
6996                         ret = ret + NumberOfDPP[k] * dpte_group_bytes[k] * (1 + 8 * HostVMDynamicLevels) * HostVMInefficiencyFactor;
6997                 }
6998         }
6999         return ret;
7000 }
7001
7002 static double CalculateUrgentLatency(
7003                 double UrgentLatencyPixelDataOnly,
7004                 double UrgentLatencyPixelMixedWithVMData,
7005                 double UrgentLatencyVMDataOnly,
7006                 bool DoUrgentLatencyAdjustment,
7007                 double UrgentLatencyAdjustmentFabricClockComponent,
7008                 double UrgentLatencyAdjustmentFabricClockReference,
7009                 double FabricClock)
7010 {
7011         double ret;
7012
7013         ret = dml_max3(UrgentLatencyPixelDataOnly, UrgentLatencyPixelMixedWithVMData, UrgentLatencyVMDataOnly);
7014         if (DoUrgentLatencyAdjustment == true) {
7015                 ret = ret + UrgentLatencyAdjustmentFabricClockComponent * (UrgentLatencyAdjustmentFabricClockReference / FabricClock - 1);
7016         }
7017         return ret;
7018 }
7019
7020 static void UseMinimumDCFCLK(
7021                 struct display_mode_lib *mode_lib,
7022                 int MaxPrefetchMode,
7023                 int ReorderingBytes)
7024 {
7025         struct vba_vars_st *v = &mode_lib->vba;
7026         int dummy1, i, j, k;
7027         double NormalEfficiency,  dummy2, dummy3;
7028         double TotalMaxPrefetchFlipDPTERowBandwidth[DC__VOLTAGE_STATES][2];
7029
7030         NormalEfficiency = v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0;
7031         for (i = 0; i < v->soc.num_states; ++i) {
7032                 for (j = 0; j <= 1; ++j) {
7033                         double PixelDCFCLKCyclesRequiredInPrefetch[DC__NUM_DPP__MAX];
7034                         double PrefetchPixelLinesTime[DC__NUM_DPP__MAX];
7035                         double DCFCLKRequiredForPeakBandwidthPerPlane[DC__NUM_DPP__MAX];
7036                         double DynamicMetadataVMExtraLatency[DC__NUM_DPP__MAX];
7037                         double MinimumTWait;
7038                         double NonDPTEBandwidth;
7039                         double DPTEBandwidth;
7040                         double DCFCLKRequiredForAverageBandwidth;
7041                         double ExtraLatencyBytes;
7042                         double ExtraLatencyCycles;
7043                         double DCFCLKRequiredForPeakBandwidth;
7044                         int NoOfDPPState[DC__NUM_DPP__MAX];
7045                         double MinimumTvmPlus2Tr0;
7046
7047                         TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = 0;
7048                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
7049                                 TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = TotalMaxPrefetchFlipDPTERowBandwidth[i][j]
7050                                                 + v->NoOfDPP[i][j][k] * v->DPTEBytesPerRow[i][j][k] / (15.75 * v->HTotal[k] / v->PixelClock[k]);
7051                         }
7052
7053                         for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k) {
7054                                 NoOfDPPState[k] = v->NoOfDPP[i][j][k];
7055                         }
7056
7057                         MinimumTWait = CalculateTWait(MaxPrefetchMode, v->FinalDRAMClockChangeLatency, v->UrgLatency[i], v->SREnterPlusExitTime);
7058                         NonDPTEBandwidth = v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j];
7059                         DPTEBandwidth = (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) ?
7060                                         TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : v->TotalDPTERowBandwidth[i][j];
7061                         DCFCLKRequiredForAverageBandwidth = dml_max3(
7062                                         v->ProjectedDCFCLKDeepSleep[i][j],
7063                                         (NonDPTEBandwidth + v->TotalDPTERowBandwidth[i][j]) / v->ReturnBusWidth
7064                                                         / (v->MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation / 100),
7065                                         (NonDPTEBandwidth + DPTEBandwidth / NormalEfficiency) / NormalEfficiency / v->ReturnBusWidth);
7066
7067                         ExtraLatencyBytes = CalculateExtraLatencyBytes(
7068                                         ReorderingBytes,
7069                                         v->TotalNumberOfActiveDPP[i][j],
7070                                         v->PixelChunkSizeInKByte,
7071                                         v->TotalNumberOfDCCActiveDPP[i][j],
7072                                         v->MetaChunkSize,
7073                                         v->GPUVMEnable,
7074                                         v->HostVMEnable,
7075                                         v->NumberOfActivePlanes,
7076                                         NoOfDPPState,
7077                                         v->dpte_group_bytes,
7078                                         1,
7079                                         v->HostVMMinPageSize,
7080                                         v->HostVMMaxNonCachedPageTableLevels);
7081                         ExtraLatencyCycles = v->RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__ + ExtraLatencyBytes / NormalEfficiency / v->ReturnBusWidth;
7082                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
7083                                 double DCFCLKCyclesRequiredInPrefetch;
7084                                 double ExpectedPrefetchBWAcceleration;
7085                                 double PrefetchTime;
7086
7087                                 PixelDCFCLKCyclesRequiredInPrefetch[k] = (v->PrefetchLinesY[i][j][k] * v->swath_width_luma_ub_all_states[i][j][k] * v->BytePerPixelY[k]
7088                                                 + v->PrefetchLinesC[i][j][k] * v->swath_width_chroma_ub_all_states[i][j][k] * v->BytePerPixelC[k]) / NormalEfficiency / v->ReturnBusWidth;
7089                                 DCFCLKCyclesRequiredInPrefetch = 2 * ExtraLatencyCycles / NoOfDPPState[k]
7090                                                 + v->PDEAndMetaPTEBytesPerFrame[i][j][k] / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth * (v->GPUVMMaxPageTableLevels > 2 ? 1 : 0)
7091                                                 + 2 * v->DPTEBytesPerRow[i][j][k] / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth
7092                                                 + 2 * v->MetaRowBytes[i][j][k] / NormalEfficiency / v->ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k];
7093                                 PrefetchPixelLinesTime[k] = dml_max(v->PrefetchLinesY[i][j][k], v->PrefetchLinesC[i][j][k]) * v->HTotal[k] / v->PixelClock[k];
7094                                 ExpectedPrefetchBWAcceleration = (v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k])
7095                                                 / (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k]);
7096                                 DynamicMetadataVMExtraLatency[k] =
7097                                                 (v->GPUVMEnable == true && v->DynamicMetadataEnable[k] == true && v->DynamicMetadataVMEnabled == true) ?
7098                                                                 v->UrgLatency[i] * v->GPUVMMaxPageTableLevels * (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0;
7099                                 PrefetchTime = (v->MaximumVStartup[i][j][k] - 1) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait
7100                                                 - v->UrgLatency[i]
7101                                                                 * ((v->GPUVMMaxPageTableLevels <= 2 ? v->GPUVMMaxPageTableLevels : v->GPUVMMaxPageTableLevels - 2)
7102                                                                                 * (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1)
7103                                                 - DynamicMetadataVMExtraLatency[k];
7104
7105                                 if (PrefetchTime > 0) {
7106                                         double ExpectedVRatioPrefetch;
7107                                         ExpectedVRatioPrefetch = PrefetchPixelLinesTime[k]
7108                                                         / (PrefetchTime * PixelDCFCLKCyclesRequiredInPrefetch[k] / DCFCLKCyclesRequiredInPrefetch);
7109                                         DCFCLKRequiredForPeakBandwidthPerPlane[k] = NoOfDPPState[k] * PixelDCFCLKCyclesRequiredInPrefetch[k] / PrefetchPixelLinesTime[k]
7110                                                         * dml_max(1.0, ExpectedVRatioPrefetch) * dml_max(1.0, ExpectedVRatioPrefetch / 4) * ExpectedPrefetchBWAcceleration;
7111                                         if (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) {
7112                                                 DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKRequiredForPeakBandwidthPerPlane[k]
7113                                                                 + NoOfDPPState[k] * DPTEBandwidth / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth;
7114                                         }
7115                                 } else {
7116                                         DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i];
7117                                 }
7118                                 if (v->DynamicMetadataEnable[k] == true) {
7119                                         double TSetupPipe;
7120                                         double TdmbfPipe;
7121                                         double TdmsksPipe;
7122                                         double TdmecPipe;
7123                                         double AllowedTimeForUrgentExtraLatency;
7124
7125                                         CalculateVupdateAndDynamicMetadataParameters(
7126                                                         v->MaxInterDCNTileRepeaters,
7127                                                         v->RequiredDPPCLK[i][j][k],
7128                                                         v->RequiredDISPCLK[i][j],
7129                                                         v->ProjectedDCFCLKDeepSleep[i][j],
7130                                                         v->PixelClock[k],
7131                                                         v->HTotal[k],
7132                                                         v->VTotal[k] - v->VActive[k],
7133                                                         v->DynamicMetadataTransmittedBytes[k],
7134                                                         v->DynamicMetadataLinesBeforeActiveRequired[k],
7135                                                         v->Interlace[k],
7136                                                         v->ProgressiveToInterlaceUnitInOPP,
7137                                                         &TSetupPipe,
7138                                                         &TdmbfPipe,
7139                                                         &TdmecPipe,
7140                                                         &TdmsksPipe,
7141                                                         &dummy1,
7142                                                         &dummy2,
7143                                                         &dummy3);
7144                                         AllowedTimeForUrgentExtraLatency = v->MaximumVStartup[i][j][k] * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - TSetupPipe - TdmbfPipe - TdmecPipe
7145                                                         - TdmsksPipe - DynamicMetadataVMExtraLatency[k];
7146                                         if (AllowedTimeForUrgentExtraLatency > 0) {
7147                                                 DCFCLKRequiredForPeakBandwidthPerPlane[k] = dml_max(
7148                                                                 DCFCLKRequiredForPeakBandwidthPerPlane[k],
7149                                                                 ExtraLatencyCycles / AllowedTimeForUrgentExtraLatency);
7150                                         } else {
7151                                                 DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i];
7152                                         }
7153                                 }
7154                         }
7155                         DCFCLKRequiredForPeakBandwidth = 0;
7156                         for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k) {
7157                                 DCFCLKRequiredForPeakBandwidth = DCFCLKRequiredForPeakBandwidth + DCFCLKRequiredForPeakBandwidthPerPlane[k];
7158                         }
7159                         MinimumTvmPlus2Tr0 = v->UrgLatency[i]
7160                                         * (v->GPUVMEnable == true ?
7161                                                         (v->HostVMEnable == true ?
7162                                                                         (v->GPUVMMaxPageTableLevels + 2) * (v->HostVMMaxNonCachedPageTableLevels + 1) - 1 : v->GPUVMMaxPageTableLevels + 1) :
7163                                                         0);
7164                         for (k = 0; k < v->NumberOfActivePlanes; ++k) {
7165                                 double MaximumTvmPlus2Tr0PlusTsw;
7166                                 MaximumTvmPlus2Tr0PlusTsw = (v->MaximumVStartup[i][j][k] - 2) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k];
7167                                 if (MaximumTvmPlus2Tr0PlusTsw <= MinimumTvmPlus2Tr0 + PrefetchPixelLinesTime[k] / 4) {
7168                                         DCFCLKRequiredForPeakBandwidth = v->DCFCLKPerState[i];
7169                                 } else {
7170                                         DCFCLKRequiredForPeakBandwidth = dml_max3(
7171                                                         DCFCLKRequiredForPeakBandwidth,
7172                                                         2 * ExtraLatencyCycles / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0 - PrefetchPixelLinesTime[k] / 4),
7173                                                         (2 * ExtraLatencyCycles + PixelDCFCLKCyclesRequiredInPrefetch[k]) / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0));
7174                                 }
7175                         }
7176                         v->DCFCLKState[i][j] = dml_min(v->DCFCLKPerState[i], 1.05 * dml_max(DCFCLKRequiredForAverageBandwidth, DCFCLKRequiredForPeakBandwidth));
7177                 }
7178         }
7179 }
7180
7181 static void CalculateUnboundedRequestAndCompressedBufferSize(
7182                 unsigned int DETBufferSizeInKByte,
7183                 int ConfigReturnBufferSizeInKByte,
7184                 enum unbounded_requesting_policy UseUnboundedRequestingFinal,
7185                 int TotalActiveDPP,
7186                 bool NoChromaPlanes,
7187                 int MaxNumDPP,
7188                 int CompressedBufferSegmentSizeInkByteFinal,
7189                 enum output_encoder_class *Output,
7190                 bool *UnboundedRequestEnabled,
7191                 int *CompressedBufferSizeInkByte)
7192 {
7193         double actDETBufferSizeInKByte = dml_ceil(DETBufferSizeInKByte, 64);
7194
7195         *UnboundedRequestEnabled = UnboundedRequest(UseUnboundedRequestingFinal, TotalActiveDPP, NoChromaPlanes, Output[0]);
7196         *CompressedBufferSizeInkByte = (
7197                         *UnboundedRequestEnabled == true ?
7198                                         ConfigReturnBufferSizeInKByte - TotalActiveDPP * actDETBufferSizeInKByte :
7199                                         ConfigReturnBufferSizeInKByte - MaxNumDPP * actDETBufferSizeInKByte);
7200         *CompressedBufferSizeInkByte = *CompressedBufferSizeInkByte * CompressedBufferSegmentSizeInkByteFinal / 64;
7201
7202 #ifdef __DML_VBA_DEBUG__
7203         dml_print("DML::%s: TotalActiveDPP = %d\n", __func__, TotalActiveDPP);
7204         dml_print("DML::%s: DETBufferSizeInKByte = %d\n", __func__, DETBufferSizeInKByte);
7205         dml_print("DML::%s: ConfigReturnBufferSizeInKByte = %d\n", __func__, ConfigReturnBufferSizeInKByte);
7206         dml_print("DML::%s: UseUnboundedRequestingFinal = %d\n", __func__, UseUnboundedRequestingFinal);
7207         dml_print("DML::%s: actDETBufferSizeInKByte = %f\n", __func__, actDETBufferSizeInKByte);
7208         dml_print("DML::%s: UnboundedRequestEnabled = %d\n", __func__, *UnboundedRequestEnabled);
7209         dml_print("DML::%s: CompressedBufferSizeInkByte = %d\n", __func__, *CompressedBufferSizeInkByte);
7210 #endif
7211 }
7212
7213 static bool UnboundedRequest(enum unbounded_requesting_policy UseUnboundedRequestingFinal, int TotalNumberOfActiveDPP, bool NoChroma, enum output_encoder_class Output)
7214 {
7215         bool ret_val = false;
7216
7217         ret_val = (UseUnboundedRequestingFinal != dm_unbounded_requesting_disable && TotalNumberOfActiveDPP == 1 && NoChroma);
7218         if (UseUnboundedRequestingFinal == dm_unbounded_requesting_edp_only && Output != dm_edp) {
7219                 ret_val = false;
7220         }
7221         return (ret_val);
7222 }
7223