// SPDX-License-Identifier: MIT /* * Copyright 2022 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: AMD *
*/
void dcn314_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{ struct clk_limit_table *clk_table = &bw_params->clk_table; struct _vcs_dpi_voltage_scaling_st *clock_limits =
dcn3_14_soc.clock_limits; unsignedint i, closest_clk_lvl; int max_dispclk_mhz = 0, max_dppclk_mhz = 0; int j;
dc_assert_fp_enabled();
// Default clock levels are used for diags, which may lead to overclocking. if (dc->config.use_default_clock_table == false) {
dcn3_14_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator;
dcn3_14_ip.max_num_dpp = dc->res_pool->pipe_count;
if (bw_params->dram_channel_width_bytes > 0)
dcn3_14_soc.dram_channel_width_bytes = bw_params->dram_channel_width_bytes;
if (bw_params->num_channels > 0)
dcn3_14_soc.num_chans = bw_params->num_channels;
/* Prepass to find max clocks independent of voltage level. */ for (i = 0; i < clk_table->num_entries; ++i) { if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) { /* loop backwards*/ for (closest_clk_lvl = 0, j = dcn3_14_soc.num_states - 1; j >= 0; j--) { if ((unsignedint) dcn3_14_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j; break;
}
} if (clk_table->num_entries == 1) { /*smu gives one DPM level, let's take the highest one*/
closest_clk_lvl = dcn3_14_soc.num_states - 1;
}
clock_limits[i].state = i;
/* Clocks dependent on voltage level. */
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; if (clk_table->num_entries == 1 &&
clock_limits[i].dcfclk_mhz < dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { /*SMU fix not released yet*/
clock_limits[i].dcfclk_mhz = dcn3_14_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
}
clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
staticbool is_dual_plane(enum surface_pixel_format format)
{ return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
}
/* * micro_sec_to_vert_lines () - converts time to number of vertical lines for a given timing * * @param: num_us: number of microseconds * @return: number of vertical lines. If exact number of vertical lines is not found then * it will round up to next number of lines to guarantee num_us
*/ staticunsignedint micro_sec_to_vert_lines(unsignedint num_us, struct dc_crtc_timing *timing)
{ unsignedint num_lines = 0; unsignedint lines_time_in_ns = 1000.0 *
(((float)timing->h_total * 1000.0) /
((float)timing->pix_clk_100hz / 10.0));
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, num_lines); // vblank_nom should not smaller than (VSync (timing->v_sync_width + v_back_porch) + 2) // + 2 is because // 1 -> VStartup_start should be 1 line before VSync // 1 -> always reserve 1 line between start of vblank to vstartup signal
pipes[pipe_cnt].pipe.dest.vblank_nom =
max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width + v_back_porch + 2);
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom);
/* Apply HostVM policy - either based on hypervisor globally enabled, or rIOMMU active */ if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE)
pipes[i].pipe.src.hostvm = dc->vm_pa_config.is_hvm_enabled || dc->res_pool->hubbub->riommu_active;
/* * Immediate flip can be set dynamically after enabling the plane. * We need to require support for immediate flip or underflow can be * intermittently experienced depending on peak b/w requirements.
*/
pipes[pipe_cnt].pipe.src.immediate_flip = true;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.