display_mode_vba.c (46308B)
1/* 2 * Copyright 2017 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 27#include "display_mode_lib.h" 28#include "display_mode_vba.h" 29#include "dml_inline_defs.h" 30 31/* 32 * NOTE: 33 * This file is gcc-parsable 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 41static void fetch_socbb_params(struct display_mode_lib *mode_lib); 42static void fetch_ip_params(struct display_mode_lib *mode_lib); 43static void fetch_pipe_params(struct display_mode_lib *mode_lib); 44static void recalculate_params( 45 struct display_mode_lib *mode_lib, 46 const display_e2e_pipe_params_st *pipes, 47 unsigned int num_pipes); 48 49static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp); 50static void cache_debug_params(struct display_mode_lib *mode_lib); 51 52unsigned int dml_get_voltage_level( 53 struct display_mode_lib *mode_lib, 54 const display_e2e_pipe_params_st *pipes, 55 unsigned int num_pipes) 56{ 57 bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0 58 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 59 || num_pipes != mode_lib->vba.cache_num_pipes 60 || memcmp(pipes, mode_lib->vba.cache_pipes, 61 sizeof(display_e2e_pipe_params_st) * num_pipes) != 0; 62 63 mode_lib->vba.soc = mode_lib->soc; 64 mode_lib->vba.ip = mode_lib->ip; 65 memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); 66 mode_lib->vba.cache_num_pipes = num_pipes; 67 68 if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0) 69 mode_lib->funcs.recalculate(mode_lib); 70 else { 71 fetch_socbb_params(mode_lib); 72 fetch_ip_params(mode_lib); 73 fetch_pipe_params(mode_lib); 74 PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib); 75 } 76 mode_lib->funcs.validate(mode_lib); 77 cache_debug_params(mode_lib); 78 79 return mode_lib->vba.VoltageLevel; 80} 81 82#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) \ 83{ \ 84 recalculate_params(mode_lib, pipes, num_pipes); \ 85 return var; \ 86} 87 88dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFCLKDeepSleep); 89dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark); 90dml_get_attr_func(wm_memory_trip, mode_lib->vba.UrgentLatency); 91dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark); 92dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark); 93dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark); 94dml_get_attr_func(wm_z8_stutter_exit, mode_lib->vba.Z8StutterExitWatermark); 95dml_get_attr_func(wm_z8_stutter_enter_exit, mode_lib->vba.Z8StutterEnterPlusExitWatermark); 96dml_get_attr_func(stutter_efficiency_z8, mode_lib->vba.Z8StutterEfficiency); 97dml_get_attr_func(stutter_num_bursts_z8, mode_lib->vba.Z8NumberOfStutterBurstsPerFrame); 98dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark); 99dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark); 100dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency); 101dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank); 102dml_get_attr_func(stutter_period, mode_lib->vba.StutterPeriod); 103dml_get_attr_func(urgent_latency, mode_lib->vba.UrgentLatency); 104dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency); 105dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance); 106dml_get_attr_func(dram_clock_change_latency, mode_lib->vba.MinActiveDRAMClockChangeLatencySupported); 107dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated); 108dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth); 109dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW); 110dml_get_attr_func(tcalc, mode_lib->vba.TCalc); 111dml_get_attr_func(fraction_of_urgent_bandwidth, mode_lib->vba.FractionOfUrgentBandwidth); 112dml_get_attr_func(fraction_of_urgent_bandwidth_imm_flip, mode_lib->vba.FractionOfUrgentBandwidthImmediateFlip); 113 114#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) \ 115{\ 116 unsigned int which_plane; \ 117 recalculate_params(mode_lib, pipes, num_pipes); \ 118 which_plane = mode_lib->vba.pipe_plane[which_pipe]; \ 119 return var[which_plane]; \ 120} 121 122dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay); 123dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated); 124dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated); 125dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank); 126dml_get_pipe_attr_func(min_ttu_vblank_in_us, mode_lib->vba.MinTTUVBlank); 127dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY); 128dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC); 129dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler); 130dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler); 131dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank); 132dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank); 133dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch); 134dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip); 135dml_get_pipe_attr_func(dst_y_per_row_flip, mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip); 136dml_get_pipe_attr_func(refcyc_per_vm_group_vblank, mode_lib->vba.TimePerVMGroupVBlank); 137dml_get_pipe_attr_func(refcyc_per_vm_group_flip, mode_lib->vba.TimePerVMGroupFlip); 138dml_get_pipe_attr_func(refcyc_per_vm_req_vblank, mode_lib->vba.TimePerVMRequestVBlank); 139dml_get_pipe_attr_func(refcyc_per_vm_req_flip, mode_lib->vba.TimePerVMRequestFlip); 140dml_get_pipe_attr_func(refcyc_per_vm_group_vblank_in_us, mode_lib->vba.TimePerVMGroupVBlank); 141dml_get_pipe_attr_func(refcyc_per_vm_group_flip_in_us, mode_lib->vba.TimePerVMGroupFlip); 142dml_get_pipe_attr_func(refcyc_per_vm_req_vblank_in_us, mode_lib->vba.TimePerVMRequestVBlank); 143dml_get_pipe_attr_func(refcyc_per_vm_req_flip_in_us, mode_lib->vba.TimePerVMRequestFlip); 144dml_get_pipe_attr_func(refcyc_per_vm_dmdata_in_us, mode_lib->vba.Tdmdl_vm); 145dml_get_pipe_attr_func(dmdata_dl_delta_in_us, mode_lib->vba.Tdmdl); 146dml_get_pipe_attr_func(refcyc_per_line_delivery_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLuma); 147dml_get_pipe_attr_func(refcyc_per_line_delivery_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChroma); 148dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch); 149dml_get_pipe_attr_func(refcyc_per_line_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch); 150dml_get_pipe_attr_func(refcyc_per_req_delivery_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLuma); 151dml_get_pipe_attr_func(refcyc_per_req_delivery_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChroma); 152dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_l_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeLumaPrefetch); 153dml_get_pipe_attr_func(refcyc_per_req_delivery_pre_c_in_us, mode_lib->vba.DisplayPipeRequestDeliveryTimeChromaPrefetch); 154dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_in_us, mode_lib->vba.CursorRequestDeliveryTime); 155dml_get_pipe_attr_func(refcyc_per_cursor_req_delivery_pre_in_us, mode_lib->vba.CursorRequestDeliveryTimePrefetch); 156dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_l_in_us, mode_lib->vba.TimePerMetaChunkNominal); 157dml_get_pipe_attr_func(refcyc_per_meta_chunk_nom_c_in_us, mode_lib->vba.TimePerChromaMetaChunkNominal); 158dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_l_in_us, mode_lib->vba.TimePerMetaChunkVBlank); 159dml_get_pipe_attr_func(refcyc_per_meta_chunk_vblank_c_in_us, mode_lib->vba.TimePerChromaMetaChunkVBlank); 160dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_l_in_us, mode_lib->vba.TimePerMetaChunkFlip); 161dml_get_pipe_attr_func(refcyc_per_meta_chunk_flip_c_in_us, mode_lib->vba.TimePerChromaMetaChunkFlip); 162dml_get_pipe_attr_func(vstartup, mode_lib->vba.VStartup); 163dml_get_pipe_attr_func(vupdate_offset, mode_lib->vba.VUpdateOffsetPix); 164dml_get_pipe_attr_func(vupdate_width, mode_lib->vba.VUpdateWidthPix); 165dml_get_pipe_attr_func(vready_offset, mode_lib->vba.VReadyOffsetPix); 166dml_get_pipe_attr_func(vready_at_or_after_vsync, mode_lib->vba.VREADY_AT_OR_AFTER_VSYNC); 167dml_get_pipe_attr_func(min_dst_y_next_start, mode_lib->vba.MIN_DST_Y_NEXT_START); 168 169double get_total_immediate_flip_bytes( 170 struct display_mode_lib *mode_lib, 171 const display_e2e_pipe_params_st *pipes, 172 unsigned int num_pipes) 173{ 174 recalculate_params(mode_lib, pipes, num_pipes); 175 return mode_lib->vba.TotImmediateFlipBytes; 176} 177 178double get_total_immediate_flip_bw( 179 struct display_mode_lib *mode_lib, 180 const display_e2e_pipe_params_st *pipes, 181 unsigned int num_pipes) 182{ 183 unsigned int k; 184 double immediate_flip_bw = 0.0; 185 recalculate_params(mode_lib, pipes, num_pipes); 186 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) 187 immediate_flip_bw += mode_lib->vba.ImmediateFlipBW[k]; 188 return immediate_flip_bw; 189} 190 191double get_total_prefetch_bw( 192 struct display_mode_lib *mode_lib, 193 const display_e2e_pipe_params_st *pipes, 194 unsigned int num_pipes) 195{ 196 unsigned int k; 197 double total_prefetch_bw = 0.0; 198 199 recalculate_params(mode_lib, pipes, num_pipes); 200 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) 201 total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k]; 202 return total_prefetch_bw; 203} 204 205static void fetch_socbb_params(struct display_mode_lib *mode_lib) 206{ 207 soc_bounding_box_st *soc = &mode_lib->vba.soc; 208 int i; 209 210 // SOC Bounding Box Parameters 211 mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes; 212 mode_lib->vba.NumberOfChannels = soc->num_chans; 213 mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly = 214 soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only; // there's always that one bastard variable that's so long it throws everything out of alignment! 215 mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData = 216 soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm; 217 mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly = 218 soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only; 219 mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation = 220 soc->max_avg_sdp_bw_use_normal_percent; 221 mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation = 222 soc->max_avg_dram_bw_use_normal_percent; 223 mode_lib->vba.UrgentLatencyPixelDataOnly = soc->urgent_latency_pixel_data_only_us; 224 mode_lib->vba.UrgentLatencyPixelMixedWithVMData = soc->urgent_latency_pixel_mixed_with_vm_data_us; 225 mode_lib->vba.UrgentLatencyVMDataOnly = soc->urgent_latency_vm_data_only_us; 226 mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles; 227 mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly = 228 soc->urgent_out_of_order_return_per_channel_pixel_only_bytes; 229 mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData = 230 soc->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes; 231 mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly = 232 soc->urgent_out_of_order_return_per_channel_vm_only_bytes; 233 mode_lib->vba.WritebackLatency = soc->writeback_latency_us; 234 mode_lib->vba.SRExitTime = soc->sr_exit_time_us; 235 mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us; 236 mode_lib->vba.PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency = soc->pct_ideal_sdp_bw_after_urgent; 237 mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelMixedWithVMData = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm; 238 mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyPixelDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_pixel_only; 239 mode_lib->vba.PercentOfIdealDRAMBWReceivedAfterUrgLatencyVMDataOnly = soc->pct_ideal_dram_sdp_bw_after_urgent_vm_only; 240 mode_lib->vba.MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation = 241 soc->max_avg_sdp_bw_use_normal_percent; 242 mode_lib->vba.SRExitZ8Time = soc->sr_exit_z8_time_us; 243 mode_lib->vba.SREnterPlusExitZ8Time = soc->sr_enter_plus_exit_z8_time_us; 244 mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us; 245 mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us; 246 mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support || 247 mode_lib->vba.DummyPStateCheck; 248 mode_lib->vba.AllowDramClockChangeOneDisplayVactive = soc->allow_dram_clock_one_display_vactive; 249 mode_lib->vba.AllowDRAMSelfRefreshOrDRAMClockChangeInVblank = 250 soc->allow_dram_self_refresh_or_dram_clock_change_in_vblank; 251 252 mode_lib->vba.Downspreading = soc->downspread_percent; 253 mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new! 254 mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new! 255 mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new 256 mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new 257 mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes; 258 mode_lib->vba.GPUVMMinPageSize = soc->gpuvm_min_page_size_bytes / 1024; 259 mode_lib->vba.HostVMMinPageSize = soc->hostvm_min_page_size_bytes / 1024; 260 // Set the voltage scaling clocks as the defaults. Most of these will 261 // be set to different values by the test 262 for (i = 0; i < mode_lib->vba.soc.num_states; i++) 263 if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel) 264 break; 265 266 mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz; 267 mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz; 268 mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mts; 269 mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz; 270 271 mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us; 272 mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us; 273 mode_lib->vba.UseUrgentBurstBandwidth = soc->use_urgent_burst_bw; 274 275 mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false; 276 mode_lib->vba.WritebackLumaAndChromaScalingSupported = true; 277 mode_lib->vba.MaxHSCLRatio = 4; 278 mode_lib->vba.MaxVSCLRatio = 4; 279 mode_lib->vba.Cursor64BppSupport = true; 280 for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { 281 mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz; 282 mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz; 283 mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz; 284 mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz; 285 mode_lib->vba.PHYCLKD18PerState[i] = soc->clock_limits[i].phyclk_d18_mhz; 286 mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz; 287 mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz; 288 mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mts; 289 //mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz; 290 mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz; 291 mode_lib->vba.DTBCLKPerState[i] = soc->clock_limits[i].dtbclk_mhz; 292 } 293 294 mode_lib->vba.DoUrgentLatencyAdjustment = 295 soc->do_urgent_latency_adjustment; 296 mode_lib->vba.UrgentLatencyAdjustmentFabricClockComponent = 297 soc->urgent_latency_adjustment_fabric_clock_component_us; 298 mode_lib->vba.UrgentLatencyAdjustmentFabricClockReference = 299 soc->urgent_latency_adjustment_fabric_clock_reference_mhz; 300} 301 302static void fetch_ip_params(struct display_mode_lib *mode_lib) 303{ 304 ip_params_st *ip = &mode_lib->vba.ip; 305 306 // IP Parameters 307 mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk; 308 mode_lib->vba.ClampMinDCFCLK = ip->clamp_min_dcfclk; 309 mode_lib->vba.MaxNumDPP = ip->max_num_dpp; 310 mode_lib->vba.MaxNumOTG = ip->max_num_otg; 311 mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs; 312 mode_lib->vba.MaxNumWriteback = ip->max_num_wb; 313 mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size; 314 mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size; 315 316 mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk; 317 mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk; 318 mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes; 319 mode_lib->vba.DETBufferSizeInKByte[0] = ip->det_buffer_size_kbytes; 320 mode_lib->vba.ConfigReturnBufferSizeInKByte = ip->config_return_buffer_size_in_kbytes; 321 mode_lib->vba.CompressedBufferSegmentSizeInkByte = ip->compressed_buffer_segment_size_in_kbytes; 322 mode_lib->vba.MetaFIFOSizeInKEntries = ip->meta_fifo_size_in_kentries; 323 mode_lib->vba.ZeroSizeBufferEntries = ip->zero_size_buffer_entries; 324 mode_lib->vba.COMPBUF_RESERVED_SPACE_64B = ip->compbuf_reserved_space_64b; 325 mode_lib->vba.COMPBUF_RESERVED_SPACE_ZS = ip->compbuf_reserved_space_zs; 326 mode_lib->vba.MaximumDSCBitsPerComponent = ip->maximum_dsc_bits_per_component; 327 mode_lib->vba.DSC422NativeSupport = ip->dsc422_native_support; 328 329 mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes; 330 mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes; 331 mode_lib->vba.MinMetaChunkSizeBytes = ip->min_meta_chunk_size_bytes; 332 mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes; 333 mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits; 334 mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines; 335 mode_lib->vba.PTEBufferSizeInRequestsLuma = ip->dpte_buffer_size_in_pte_reqs_luma; 336 mode_lib->vba.PTEBufferSizeInRequestsChroma = ip->dpte_buffer_size_in_pte_reqs_chroma; 337 mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels; 338 mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines; 339 mode_lib->vba.MaxHSCLRatio = ip->max_hscl_ratio; 340 mode_lib->vba.MaxVSCLRatio = ip->max_vscl_ratio; 341 mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes * 1024; 342 mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes * 1024; 343 344 mode_lib->vba.WritebackInterfaceBufferSize = ip->writeback_interface_buffer_size_kbytes; 345 mode_lib->vba.WritebackLineBufferSize = ip->writeback_line_buffer_buffer_size; 346 347 mode_lib->vba.WritebackChromaLineBufferWidth = 348 ip->writeback_chroma_line_buffer_width_pixels; 349 mode_lib->vba.WritebackLineBufferLumaBufferSize = 350 ip->writeback_line_buffer_luma_buffer_size; 351 mode_lib->vba.WritebackLineBufferChromaBufferSize = 352 ip->writeback_line_buffer_chroma_buffer_size; 353 mode_lib->vba.Writeback10bpc420Supported = ip->writeback_10bpc420_supported; 354 mode_lib->vba.WritebackMaxHSCLRatio = ip->writeback_max_hscl_ratio; 355 mode_lib->vba.WritebackMaxVSCLRatio = ip->writeback_max_vscl_ratio; 356 mode_lib->vba.WritebackMinHSCLRatio = ip->writeback_min_hscl_ratio; 357 mode_lib->vba.WritebackMinVSCLRatio = ip->writeback_min_vscl_ratio; 358 mode_lib->vba.WritebackMaxHSCLTaps = ip->writeback_max_hscl_taps; 359 mode_lib->vba.WritebackMaxVSCLTaps = ip->writeback_max_vscl_taps; 360 mode_lib->vba.WritebackConfiguration = dm_normal; 361 mode_lib->vba.GPUVMMaxPageTableLevels = ip->gpuvm_max_page_table_levels; 362 mode_lib->vba.HostVMMaxNonCachedPageTableLevels = ip->hostvm_max_page_table_levels; 363 mode_lib->vba.HostVMMaxPageTableLevels = ip->hostvm_max_page_table_levels; 364 mode_lib->vba.HostVMCachedPageTableLevels = ip->hostvm_cached_page_table_levels; 365 mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters; 366 mode_lib->vba.NumberOfDSC = ip->num_dsc; 367 mode_lib->vba.ODMCapability = ip->odm_capable; 368 mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent; 369 370 mode_lib->vba.XFCSupported = ip->xfc_supported; 371 mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent; 372 mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes; 373 mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal; 374 mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl; 375 mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only; 376 mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter; 377 mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor; 378 mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal; 379 mode_lib->vba.DynamicMetadataVMEnabled = ip->dynamic_metadata_vm_enabled; 380 mode_lib->vba.ODMCombine4To1Supported = ip->odm_combine_4to1_supported; 381 mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported; 382 mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs; 383 mode_lib->vba.PTEGroupSize = ip->pte_group_size_bytes; 384 mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = ip->gfx7_compat_tiling_supported; 385} 386 387static void fetch_pipe_params(struct display_mode_lib *mode_lib) 388{ 389 display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes; 390 ip_params_st *ip = &mode_lib->vba.ip; 391 392 unsigned int OTGInstPlane[DC__NUM_DPP__MAX]; 393 unsigned int j, k; 394 bool PlaneVisited[DC__NUM_DPP__MAX]; 395 bool visited[DC__NUM_DPP__MAX]; 396 397 // Convert Pipes to Planes 398 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) 399 visited[k] = false; 400 401 mode_lib->vba.NumberOfActivePlanes = 0; 402 mode_lib->vba.ImmediateFlipSupport = false; 403 for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) { 404 display_pipe_source_params_st *src = &pipes[j].pipe.src; 405 display_pipe_dest_params_st *dst = &pipes[j].pipe.dest; 406 scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth; 407 scaler_taps_st *taps = &pipes[j].pipe.scale_taps; 408 display_output_params_st *dout = &pipes[j].dout; 409 display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg; 410 411 if (visited[j]) 412 continue; 413 visited[j] = true; 414 415 mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_not_required; 416 mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes; 417 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1; 418 mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] = 419 (enum scan_direction_class) (src->source_scan); 420 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = 421 src->viewport_width; 422 mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = 423 src->viewport_width_c; 424 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = 425 src->viewport_height; 426 mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = 427 src->viewport_height_c; 428 mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] = 429 src->viewport_y_y; 430 mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] = 431 src->viewport_y_c; 432 mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch; 433 mode_lib->vba.SurfaceWidthY[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_y; 434 mode_lib->vba.SurfaceHeightY[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_y; 435 mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c; 436 mode_lib->vba.SurfaceHeightC[mode_lib->vba.NumberOfActivePlanes] = src->surface_height_c; 437 mode_lib->vba.SurfaceWidthC[mode_lib->vba.NumberOfActivePlanes] = src->surface_width_c; 438 mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch; 439 mode_lib->vba.DCCMetaPitchC[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch_c; 440 mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio; 441 mode_lib->vba.HRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio_c; 442 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio; 443 mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio_c; 444 mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable; 445 mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced; 446 if (dst->interlaced && !ip->ptoi_supported) { 447 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0; 448 mode_lib->vba.VRatioChroma[mode_lib->vba.NumberOfActivePlanes] *= 2.0; 449 } 450 mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps; 451 mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps; 452 mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c; 453 mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c; 454 mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal; 455 mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal; 456 mode_lib->vba.VFrontPorch[mode_lib->vba.NumberOfActivePlanes] = dst->vfront_porch; 457 mode_lib->vba.DCCFractionOfZeroSizeRequestsLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_luma; 458 mode_lib->vba.DCCFractionOfZeroSizeRequestsChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_fraction_of_zs_req_chroma; 459 mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] = 460 src->dcc_use_global ? 461 ip->dcc_supported : src->dcc && ip->dcc_supported; 462 mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate; 463 /* TODO: Needs to be set based on src->dcc_rate_luma/chroma */ 464 mode_lib->vba.DCCRateLuma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate; 465 mode_lib->vba.DCCRateChroma[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate_chroma; 466 mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] = (enum source_format_class) (src->source_format); 467 mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive; 468 mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive; 469 mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] = 470 (enum dm_swizzle_mode) (src->sw_mode); 471 mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] = 472 dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode? 473 mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] = 474 dst->odm_combine; 475 mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = 476 (enum output_format_class) (dout->output_format); 477 mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = 478 dout->output_bpp; 479 mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = 480 (enum output_encoder_class) (dout->output_type); 481 mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] = 482 dout->is_virtual; 483 484 if (!dout->dsc_enable) 485 mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; 486 else 487 mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0; 488 489 mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] = 490 dout->dp_lanes; 491 /* TODO: Needs to be set based on dout->audio.audio_sample_rate_khz/sample_layout */ 492 mode_lib->vba.AudioSampleRate[mode_lib->vba.NumberOfActivePlanes] = 493 dout->max_audio_sample_rate; 494 mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] = 495 1; 496 mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0; 497 mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; 498 mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; 499 mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] = 500 dout->dsc_slices; 501 if (!dout->dsc_input_bpc) { 502 mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = 503 ip->maximum_dsc_bits_per_component; 504 } else { 505 mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = 506 dout->dsc_input_bpc; 507 } 508 mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable; 509 mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] = 510 dout->num_active_wb; 511 mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] = 512 dout->wb.wb_src_height; 513 mode_lib->vba.WritebackSourceWidth[mode_lib->vba.NumberOfActivePlanes] = 514 dout->wb.wb_src_width; 515 mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] = 516 dout->wb.wb_dst_width; 517 mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] = 518 dout->wb.wb_dst_height; 519 mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] = 520 dout->wb.wb_hratio; 521 mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] = 522 dout->wb.wb_vratio; 523 mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] = 524 (enum source_format_class) (dout->wb.wb_pixel_format); 525 mode_lib->vba.WritebackHTaps[mode_lib->vba.NumberOfActivePlanes] = 526 dout->wb.wb_htaps_luma; 527 mode_lib->vba.WritebackVTaps[mode_lib->vba.NumberOfActivePlanes] = 528 dout->wb.wb_vtaps_luma; 529 mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] = 530 dout->wb.wb_htaps_luma; 531 mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] = 532 dout->wb.wb_vtaps_luma; 533 mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] = 534 dout->wb.wb_htaps_chroma; 535 mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] = 536 dout->wb.wb_vtaps_chroma; 537 mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] = 538 dout->wb.wb_hratio; 539 mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] = 540 dout->wb.wb_vratio; 541 542 mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] = 543 src->dynamic_metadata_enable; 544 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] = 545 src->dynamic_metadata_lines_before_active; 546 mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] = 547 src->dynamic_metadata_xmit_bytes; 548 549 mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable 550 && ip->xfc_supported; 551 mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes; 552 mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us; 553 mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us; 554 mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us; 555 mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz; 556 mode_lib->vba.PixelClockBackEnd[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz; 557 mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz; 558 if (ip->is_line_buffer_bpp_fixed) 559 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = 560 ip->line_buffer_fixed_bpp; 561 else { 562 unsigned int lb_depth; 563 564 switch (scl->lb_depth) { 565 case dm_lb_6: 566 lb_depth = 18; 567 break; 568 case dm_lb_8: 569 lb_depth = 24; 570 break; 571 case dm_lb_10: 572 lb_depth = 30; 573 break; 574 case dm_lb_12: 575 lb_depth = 36; 576 break; 577 case dm_lb_16: 578 lb_depth = 48; 579 break; 580 case dm_lb_19: 581 lb_depth = 57; 582 break; 583 default: 584 lb_depth = 36; 585 } 586 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth; 587 } 588 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0; 589 // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll 590 // calculate things a little more accurately 591 for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) { 592 switch (k) { 593 case 0: 594 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] = 595 CursorBppEnumToBits( 596 (enum cursor_bpp) (src->cur0_bpp)); 597 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] = 598 src->cur0_src_width; 599 if (src->cur0_src_width > 0) 600 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; 601 break; 602 case 1: 603 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] = 604 CursorBppEnumToBits( 605 (enum cursor_bpp) (src->cur1_bpp)); 606 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] = 607 src->cur1_src_width; 608 if (src->cur1_src_width > 0) 609 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++; 610 break; 611 default: 612 dml_print( 613 "ERROR: Number of cursors specified exceeds supported maximum\n") 614 ; 615 } 616 } 617 618 OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst; 619 620 if (j == 0) 621 mode_lib->vba.UseMaximumVStartup = dst->use_maximum_vstartup; 622 else 623 mode_lib->vba.UseMaximumVStartup = mode_lib->vba.UseMaximumVStartup 624 || dst->use_maximum_vstartup; 625 626 if (dst->odm_combine && !src->is_hsplit) 627 dml_print( 628 "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n", 629 j); 630 631 if (src->is_hsplit) { 632 for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) { 633 display_pipe_source_params_st *src_k = &pipes[k].pipe.src; 634 display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest; 635 636 if (src_k->is_hsplit && !visited[k] 637 && src->hsplit_grp == src_k->hsplit_grp) { 638 mode_lib->vba.pipe_plane[k] = 639 mode_lib->vba.NumberOfActivePlanes; 640 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++; 641 if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] 642 == dm_horz) { 643 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] += 644 src_k->viewport_width; 645 mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] += 646 src_k->viewport_width_c; 647 mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] += 648 dst_k->recout_width; 649 } else { 650 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] += 651 src_k->viewport_height; 652 mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] += 653 src_k->viewport_height_c; 654 } 655 656 visited[k] = true; 657 } 658 } 659 } 660 if (src->viewport_width_max) { 661 int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1; 662 int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1; 663 664 if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max) 665 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max; 666 if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max) 667 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max; 668 if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c) 669 mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c; 670 if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c) 671 mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c; 672 } 673 674 if (pipes[j].pipe.src.immediate_flip) { 675 mode_lib->vba.ImmediateFlipSupport = true; 676 mode_lib->vba.ImmediateFlipRequirement[j] = dm_immediate_flip_required; 677 } 678 679 mode_lib->vba.NumberOfActivePlanes++; 680 } 681 682 // handle overlays through BlendingAndTiming 683 // BlendingAndTiming tells you which instance to look at to get timing, the so called 'master' 684 685 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) 686 PlaneVisited[j] = false; 687 688 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) { 689 for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) { 690 if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) { 691 // doesn't matter, so choose the smaller one 692 mode_lib->vba.BlendingAndTiming[j] = j; 693 PlaneVisited[j] = true; 694 mode_lib->vba.BlendingAndTiming[k] = j; 695 PlaneVisited[k] = true; 696 } 697 } 698 699 if (!PlaneVisited[j]) { 700 mode_lib->vba.BlendingAndTiming[j] = j; 701 PlaneVisited[j] = true; 702 } 703 } 704 705 mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting; 706 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) { 707 if (pipes[k].pipe.src.unbounded_req_mode == 0) 708 mode_lib->vba.UseUnboundedRequesting = dm_unbounded_requesting_disable; 709 } 710 // TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified 711 // Do we want the dscclk to automatically be halved? Guess not since the value is specified 712 mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes; 713 for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) { 714 ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes); 715 } 716 717 mode_lib->vba.GPUVMEnable = false; 718 mode_lib->vba.HostVMEnable = false; 719 mode_lib->vba.OverrideGPUVMPageTableLevels = 0; 720 mode_lib->vba.OverrideHostVMPageTableLevels = 0; 721 722 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) { 723 mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable || !!pipes[k].pipe.src.gpuvm || !!pipes[k].pipe.src.vm; 724 mode_lib->vba.OverrideGPUVMPageTableLevels = 725 (pipes[k].pipe.src.gpuvm_levels_force_en 726 && mode_lib->vba.OverrideGPUVMPageTableLevels 727 < pipes[k].pipe.src.gpuvm_levels_force) ? 728 pipes[k].pipe.src.gpuvm_levels_force : 729 mode_lib->vba.OverrideGPUVMPageTableLevels; 730 731 mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable || !!pipes[k].pipe.src.hostvm || !!pipes[k].pipe.src.vm; 732 mode_lib->vba.OverrideHostVMPageTableLevels = 733 (pipes[k].pipe.src.hostvm_levels_force_en 734 && mode_lib->vba.OverrideHostVMPageTableLevels 735 < pipes[k].pipe.src.hostvm_levels_force) ? 736 pipes[k].pipe.src.hostvm_levels_force : 737 mode_lib->vba.OverrideHostVMPageTableLevels; 738 } 739 740 if (mode_lib->vba.OverrideGPUVMPageTableLevels) 741 mode_lib->vba.GPUVMMaxPageTableLevels = mode_lib->vba.OverrideGPUVMPageTableLevels; 742 743 if (mode_lib->vba.OverrideHostVMPageTableLevels) 744 mode_lib->vba.HostVMMaxPageTableLevels = mode_lib->vba.OverrideHostVMPageTableLevels; 745 746 mode_lib->vba.GPUVMEnable = mode_lib->vba.GPUVMEnable && !!ip->gpuvm_enable; 747 mode_lib->vba.HostVMEnable = mode_lib->vba.HostVMEnable && !!ip->hostvm_enable; 748} 749 750/** 751 * ******************************************************************************************** 752 * cache_debug_params: Cache any params that needed to be maintained from the initial validation 753 * for debug purposes. 754 * 755 * The DML getters can modify some of the VBA params that we are interested in (for example when 756 * calculating with dummy p-state latency), so cache any params here that we want for debugging 757 * 758 * @param [in] mode_lib: mode_lib input/output of validate call 759 * 760 * @return: void 761 * 762 * ******************************************************************************************** 763 */ 764static void cache_debug_params(struct display_mode_lib *mode_lib) 765{ 766 int k = 0; 767 768 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) 769 mode_lib->vba.CachedActiveDRAMClockChangeLatencyMargin[k] = mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]; 770} 771 772// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs 773// rather than working them out as in recalculate_ms 774static void recalculate_params( 775 struct display_mode_lib *mode_lib, 776 const display_e2e_pipe_params_st *pipes, 777 unsigned int num_pipes) 778{ 779 // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib 780 if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0 781 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0 782 || num_pipes != mode_lib->vba.cache_num_pipes 783 || memcmp( 784 pipes, 785 mode_lib->vba.cache_pipes, 786 sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) { 787 mode_lib->vba.soc = mode_lib->soc; 788 mode_lib->vba.ip = mode_lib->ip; 789 memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes); 790 mode_lib->vba.cache_num_pipes = num_pipes; 791 mode_lib->funcs.recalculate(mode_lib); 792 } 793} 794 795bool Calculate256BBlockSizes( 796 enum source_format_class SourcePixelFormat, 797 enum dm_swizzle_mode SurfaceTiling, 798 unsigned int BytePerPixelY, 799 unsigned int BytePerPixelC, 800 unsigned int *BlockHeight256BytesY, 801 unsigned int *BlockHeight256BytesC, 802 unsigned int *BlockWidth256BytesY, 803 unsigned int *BlockWidth256BytesC) 804{ 805 if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32 806 || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8)) { 807 if (SurfaceTiling == dm_sw_linear) { 808 *BlockHeight256BytesY = 1; 809 } else if (SourcePixelFormat == dm_444_64) { 810 *BlockHeight256BytesY = 4; 811 } else if (SourcePixelFormat == dm_444_8) { 812 *BlockHeight256BytesY = 16; 813 } else { 814 *BlockHeight256BytesY = 8; 815 } 816 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY; 817 *BlockHeight256BytesC = 0; 818 *BlockWidth256BytesC = 0; 819 } else { 820 if (SurfaceTiling == dm_sw_linear) { 821 *BlockHeight256BytesY = 1; 822 *BlockHeight256BytesC = 1; 823 } else if (SourcePixelFormat == dm_420_8) { 824 *BlockHeight256BytesY = 16; 825 *BlockHeight256BytesC = 8; 826 } else { 827 *BlockHeight256BytesY = 8; 828 *BlockHeight256BytesC = 8; 829 } 830 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY; 831 *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC; 832 } 833 return true; 834} 835 836bool CalculateMinAndMaxPrefetchMode( 837 enum self_refresh_affinity AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, 838 unsigned int *MinPrefetchMode, 839 unsigned int *MaxPrefetchMode) 840{ 841 if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank 842 == dm_neither_self_refresh_nor_mclk_switch) { 843 *MinPrefetchMode = 2; 844 *MaxPrefetchMode = 2; 845 return false; 846 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank == dm_allow_self_refresh) { 847 *MinPrefetchMode = 1; 848 *MaxPrefetchMode = 1; 849 return false; 850 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank 851 == dm_allow_self_refresh_and_mclk_switch) { 852 *MinPrefetchMode = 0; 853 *MaxPrefetchMode = 0; 854 return false; 855 } else if (AllowDRAMSelfRefreshOrDRAMClockChangeInVblank 856 == dm_try_to_allow_self_refresh_and_mclk_switch) { 857 *MinPrefetchMode = 0; 858 *MaxPrefetchMode = 2; 859 return false; 860 } 861 *MinPrefetchMode = 0; 862 *MaxPrefetchMode = 2; 863 return true; 864} 865 866void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib) 867{ 868 unsigned int k; 869 870 //Progressive To Interlace Unit Effect 871 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { 872 mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k]; 873 if (mode_lib->vba.Interlace[k] == 1 874 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) { 875 mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k]; 876 } 877 } 878} 879 880static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp) 881{ 882 switch (ebpp) { 883 case dm_cur_2bit: 884 return 2; 885 case dm_cur_32bit: 886 return 32; 887 case dm_cur_64bit: 888 return 64; 889 default: 890 return 0; 891 } 892} 893 894void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib) 895{ 896 soc_bounding_box_st *soc = &mode_lib->vba.soc; 897 unsigned int k; 898 unsigned int total_pipes = 0; 899 900 mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage; 901 mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb]; 902 if (mode_lib->vba.ReturnBW == 0) 903 mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBWPerState[mode_lib->vba.VoltageLevel][0]; 904 mode_lib->vba.FabricAndDRAMBandwidth = mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel]; 905 906 fetch_socbb_params(mode_lib); 907 fetch_ip_params(mode_lib); 908 fetch_pipe_params(mode_lib); 909 910 mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz; 911 mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz; 912 if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0) 913 mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz; 914 else 915 mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz; 916 917 // Total Available Pipes Support Check 918 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { 919 total_pipes += mode_lib->vba.DPPPerPlane[k]; 920 } 921 ASSERT(total_pipes <= DC__NUM_DPP__MAX); 922} 923 924double CalculateWriteBackDISPCLK( 925 enum source_format_class WritebackPixelFormat, 926 double PixelClock, 927 double WritebackHRatio, 928 double WritebackVRatio, 929 unsigned int WritebackLumaHTaps, 930 unsigned int WritebackLumaVTaps, 931 unsigned int WritebackChromaHTaps, 932 unsigned int WritebackChromaVTaps, 933 double WritebackDestinationWidth, 934 unsigned int HTotal, 935 unsigned int WritebackChromaLineBufferWidth) 936{ 937 double CalculateWriteBackDISPCLK = 1.01 * PixelClock * dml_max( 938 dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio, 939 dml_max((WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1) * dml_ceil(WritebackDestinationWidth / 4.0, 1) 940 + dml_ceil(WritebackDestinationWidth / 4.0, 1)) / (double) HTotal + dml_ceil(1.0 / WritebackVRatio, 1) 941 * (dml_ceil(WritebackLumaVTaps / 4.0, 1) + 4.0) / (double) HTotal, 942 dml_ceil(1.0 / WritebackVRatio, 1) * WritebackDestinationWidth / (double) HTotal)); 943 if (WritebackPixelFormat != dm_444_32) { 944 CalculateWriteBackDISPCLK = dml_max(CalculateWriteBackDISPCLK, 1.01 * PixelClock * dml_max( 945 dml_ceil(WritebackChromaHTaps / 2.0, 1) / (2 * WritebackHRatio), 946 dml_max((WritebackChromaVTaps * dml_ceil(1 / (2 * WritebackVRatio), 1) * dml_ceil(WritebackDestinationWidth / 2.0 / 2.0, 1) 947 + dml_ceil(WritebackDestinationWidth / 2.0 / WritebackChromaLineBufferWidth, 1)) / HTotal 948 + dml_ceil(1 / (2 * WritebackVRatio), 1) * (dml_ceil(WritebackChromaVTaps / 4.0, 1) + 4) / HTotal, 949 dml_ceil(1.0 / (2 * WritebackVRatio), 1) * WritebackDestinationWidth / 2.0 / HTotal))); 950 } 951 return CalculateWriteBackDISPCLK; 952} 953