Commit f16d523f authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher

drm/amd/display: Support uclk switching for DCN2

[Why]
We were previously forcing the uclk for every state to max and reducing
the switch time to prevent uclk switching from occuring. This workaround
was previously needed in order to avoid hangs + underflow under certain
display configurations.

Now that DC has the proper fix complete we can drop the hacks and
improve power for most display configurations.

[How]
We still need the function pointers hooked up to grab the real uclk
states from pplib. The rest of the prior hack can be reverted.

The key requirements here are really just DC support, updated firmware,
and support for disabling p-state support when needed in pplib/smu.

When these requirements are met uclk switching works without underflow
or hangs.

Fixes: 02316e96 ("drm/amd/display: Force uclk to max for every state")
Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fb6959ae
...@@ -2819,9 +2819,6 @@ static void cap_soc_clocks( ...@@ -2819,9 +2819,6 @@ static void cap_soc_clocks(
&& max_clocks.uClockInKhz != 0) && max_clocks.uClockInKhz != 0)
bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16; bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
// HACK: Force every uclk to max for now to "disable" uclk switching.
bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000)) if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
&& max_clocks.fabricClockInKhz != 0) && max_clocks.fabricClockInKhz != 0)
bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000); bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);
...@@ -3037,8 +3034,6 @@ static bool init_soc_bounding_box(struct dc *dc, ...@@ -3037,8 +3034,6 @@ static bool init_soc_bounding_box(struct dc *dc,
le32_to_cpu(bb->vmm_page_size_bytes); le32_to_cpu(bb->vmm_page_size_bytes);
dcn2_0_soc.dram_clock_change_latency_us = dcn2_0_soc.dram_clock_change_latency_us =
fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us); fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us);
// HACK!! Lower uclock latency switch time so we don't switch
dcn2_0_soc.dram_clock_change_latency_us = 10;
dcn2_0_soc.writeback_dram_clock_change_latency_us = dcn2_0_soc.writeback_dram_clock_change_latency_us =
fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us); fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us);
dcn2_0_soc.return_bus_width_bytes = dcn2_0_soc.return_bus_width_bytes =
...@@ -3080,7 +3075,6 @@ static bool init_soc_bounding_box(struct dc *dc, ...@@ -3080,7 +3075,6 @@ static bool init_soc_bounding_box(struct dc *dc,
struct pp_smu_nv_clock_table max_clocks = {0}; struct pp_smu_nv_clock_table max_clocks = {0};
unsigned int uclk_states[8] = {0}; unsigned int uclk_states[8] = {0};
unsigned int num_states = 0; unsigned int num_states = 0;
int i;
enum pp_smu_status status; enum pp_smu_status status;
bool clock_limits_available = false; bool clock_limits_available = false;
bool uclk_states_available = false; bool uclk_states_available = false;
...@@ -3102,10 +3096,6 @@ static bool init_soc_bounding_box(struct dc *dc, ...@@ -3102,10 +3096,6 @@ static bool init_soc_bounding_box(struct dc *dc,
clock_limits_available = (status == PP_SMU_RESULT_OK); clock_limits_available = (status == PP_SMU_RESULT_OK);
} }
// HACK: Use the max uclk_states value for all elements.
for (i = 0; i < num_states; i++)
uclk_states[i] = uclk_states[num_states - 1];
if (clock_limits_available && uclk_states_available && num_states) if (clock_limits_available && uclk_states_available && num_states)
update_bounding_box(dc, &dcn2_0_soc, &max_clocks, uclk_states, num_states); update_bounding_box(dc, &dcn2_0_soc, &max_clocks, uclk_states, num_states);
else if (clock_limits_available) else if (clock_limits_available)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment