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