Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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