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