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