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