summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dcn21
diff options
context:
space:
mode:
authorIlya Bakoulin <Ilya.Bakoulin@amd.com>2021-04-26 14:27:38 -0400
committerAlex Deucher <alexander.deucher@amd.com>2021-05-10 18:10:49 -0400
commitc31bef1cb1203b26f901a511a3246204cfaf8a57 (patch)
tree68af19ffec33060e5c94fc84ad4f8136104de60e /drivers/gpu/drm/amd/display/dc/dcn21
parentebc22cbdc058d474210343ec87955711546183ad (diff)
downloadlwn-c31bef1cb1203b26f901a511a3246204cfaf8a57.tar.gz
lwn-c31bef1cb1203b26f901a511a3246204cfaf8a57.zip
drm/amd/display: Fix clock table filling logic
[Why] Currently, the code that fills the clock table can miss filling information about some of the higher voltage states advertised by the SMU. This, in turn, may cause some of the higher pixel clock modes (e.g. 8k60) to fail validation. [How] Fill the table with one entry per DCFCLK level instead of one entry per FCLK level. This is needed because the maximum FCLK does not necessarily need maximum voltage, whereas DCFCLK values from SMU cover the full voltage range. Signed-off-by: Ilya Bakoulin <Ilya.Bakoulin@amd.com> Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> Acked-by: Stylon Wang <stylon.wang@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn21')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index 8e3f1d0b4cc3..38a2aa87f5f5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -1575,10 +1575,12 @@ static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_li
low_pstate_lvl.phyclk_d18_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_d18_mhz;
low_pstate_lvl.phyclk_mhz = dcn2_1_soc.clock_limits[high_voltage_lvl].phyclk_mhz;
- for (i = clk_table->num_entries; i > 1; i--)
- clk_table->entries[i] = clk_table->entries[i-1];
- clk_table->entries[1] = clk_table->entries[0];
- clk_table->num_entries++;
+ if (clk_table->num_entries < MAX_NUM_DPM_LVL) {
+ for (i = clk_table->num_entries; i > 1; i--)
+ clk_table->entries[i] = clk_table->entries[i-1];
+ clk_table->entries[1] = clk_table->entries[0];
+ clk_table->num_entries++;
+ }
return low_pstate_lvl;
}
@@ -1610,10 +1612,6 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
}
}
- /* clk_table[1] is reserved for min DF PState. skip here to fill in later. */
- if (i == 1)
- k++;
-
clock_limits[k].state = k;
clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
@@ -1630,14 +1628,25 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
k++;
}
- for (i = 0; i < clk_table->num_entries + 1; i++)
- dcn2_1_soc.clock_limits[i] = clock_limits[i];
+
+ if (clk_table->num_entries >= MAX_NUM_DPM_LVL) {
+ for (i = 0; i < clk_table->num_entries + 1; i++)
+ dcn2_1_soc.clock_limits[i] = clock_limits[i];
+ } else {
+ dcn2_1_soc.clock_limits[0] = clock_limits[0];
+ for (i = 2; i < clk_table->num_entries + 1; i++) {
+ dcn2_1_soc.clock_limits[i] = clock_limits[i - 1];
+ dcn2_1_soc.clock_limits[i].state = i;
+ }
+ }
+
if (clk_table->num_entries) {
- dcn2_1_soc.num_states = clk_table->num_entries + 1;
/* fill in min DF PState */
dcn2_1_soc.clock_limits[1] = construct_low_pstate_lvl(clk_table, closest_clk_lvl);
+ 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] =
+ 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;
}