drm/amd/display: fix rn soc bb update
Currently RN SOC bounding box update assumes we will get at least 2 clock states from SMU. This isn't always true and because of special casing on first clock state we end up with low disp, dpp, dsc and phy clocks. This change removes the special casing allowing the first state to acquire correct clocks. Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> Reviewed-by: Eric Yang <eric.yang2@amd.com> Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Acked-by: Tony Cheng <Tony.Cheng@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
3ebd17f535
commit
2383877742
@ -1379,64 +1379,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
|||||||
{
|
{
|
||||||
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
||||||
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
||||||
unsigned int i, j, k;
|
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
|
||||||
int closest_clk_lvl;
|
unsigned int i, j, closest_clk_lvl;
|
||||||
|
|
||||||
// Default clock levels are used for diags, which may lead to overclocking.
|
// Default clock levels are used for diags, which may lead to overclocking.
|
||||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) {
|
if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||||
dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
|
dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
|
||||||
dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
|
dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
|
||||||
dcn2_1_soc.num_chans = bw_params->num_channels;
|
dcn2_1_soc.num_chans = bw_params->num_channels;
|
||||||
|
|
||||||
/* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */
|
ASSERT(clk_table->num_entries);
|
||||||
dcn2_1_soc.clock_limits[0].state = 0;
|
for (i = 0; i < clk_table->num_entries; i++) {
|
||||||
dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
|
/* loop backwards*/
|
||||||
dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz;
|
for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
|
||||||
dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz;
|
|
||||||
dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other levels: find closest DCN clocks that fit the given clock limit using dcfclk
|
|
||||||
* as indicator
|
|
||||||
*/
|
|
||||||
|
|
||||||
closest_clk_lvl = -1;
|
|
||||||
/* index currently being filled */
|
|
||||||
k = 1;
|
|
||||||
for (i = 1; i < clk_table->num_entries; i++) {
|
|
||||||
/* loop backwards, skip duplicate state*/
|
|
||||||
for (j = dcn2_1_soc.num_states - 1; j >= k; j--) {
|
|
||||||
if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
|
if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
|
||||||
closest_clk_lvl = j;
|
closest_clk_lvl = j;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/
|
clock_limits[i].state = i;
|
||||||
if (closest_clk_lvl != -1) {
|
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].state = i;
|
clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
||||||
dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
|
||||||
dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
|
||||||
|
|
||||||
dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
||||||
dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
||||||
dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
||||||
k++;
|
}
|
||||||
}
|
for (i = 0; i < clk_table->num_entries; i++)
|
||||||
|
dcn2_1_soc.clock_limits[i] = clock_limits[i];
|
||||||
|
if (clk_table->num_entries) {
|
||||||
|
dcn2_1_soc.num_states = clk_table->num_entries;
|
||||||
|
/* duplicate last level */
|
||||||
|
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
||||||
|
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
||||||
}
|
}
|
||||||
dcn2_1_soc.num_states = k;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* duplicate last level */
|
|
||||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
|
||||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
|
||||||
|
|
||||||
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user