// SPDX-License-Identifier: MIT /* * Copyright 2023 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 *
*/ #include"resource.h" #include"dcn35_fpu.h" #include"dcn31/dcn31_resource.h" #include"dcn32/dcn32_resource.h" #include"dcn35/dcn35_resource.h" #include"dml/dcn31/dcn31_fpu.h" #include"dml/dml_inline_defs.h"
/* * dcn35_update_bw_bounding_box * * This would override some dcn3_5 ip_or_soc initial parameters hardcoded from * spreadsheet with actual values as per dGPU SKU: * - with passed few options from dc->config * - with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might * need to get it from PM FW) * - with passed latency values (passed in ns units) in dc-> bb override for * debugging purposes * - with passed latencies from VBIOS (in 100_ns units) if available for * certain dGPU SKU * - with number of DRAM channels from VBIOS (which differ for certain dGPU SKU * of the same ASIC) * - clocks levels with passed clk_table entries from Clk Mgr as reported by PM * FW for different clocks (which might differ for certain dGPU SKU of the * same ASIC)
*/ void dcn35_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{ unsignedint i, closest_clk_lvl; int j; struct clk_limit_table *clk_table = &bw_params->clk_table; struct _vcs_dpi_voltage_scaling_st *clock_limits =
dc->scratch.update_bw_bounding_box.clock_limits; int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
/* 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_5_soc.num_states - 1;
j >= 0; j--) { if (dcn3_5_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_5_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_5_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { /*SMU fix not released yet*/
clock_limits[i].dcfclk_mhz =
dcn3_5_soc.clock_limits[closest_clk_lvl].dcfclk_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);
/* * 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;
/*for psr1/psr-su, we allow z8 and z10 based on latency, for replay with IPS enabled, it will enter ips2*/ if (is_pwrseq0 && allow_z10)
support = DCN_ZSTATE_SUPPORT_ALLOW; elseif (is_pwrseq0 && (is_psr || is_replay))
support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY; elseif (allow_z8)
support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY;
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.