Commit 797f203f authored by Alex Deucher's avatar Alex Deucher

drm/radeon/dpm: adjust power state properly for UVD on SI

There are some hardware issue with reclocking on SI when
UVD is active, so use a stable power state when UVD is
active.  Fixes possible hangs and performance issues when
using UVD on SI.
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b841ce7b
...@@ -2903,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -2903,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
{ {
struct ni_ps *ps = ni_get_ps(rps); struct ni_ps *ps = ni_get_ps(rps);
struct radeon_clock_and_voltage_limits *max_limits; struct radeon_clock_and_voltage_limits *max_limits;
bool disable_mclk_switching; bool disable_mclk_switching = false;
bool disable_sclk_switching = false;
u32 mclk, sclk; u32 mclk, sclk;
u16 vddc, vddci; u16 vddc, vddci;
int i; int i;
...@@ -2911,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -2911,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
if ((rdev->pm.dpm.new_active_crtc_count > 1) || if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
ni_dpm_vblank_too_short(rdev)) ni_dpm_vblank_too_short(rdev))
disable_mclk_switching = true; disable_mclk_switching = true;
else
disable_mclk_switching = false; if (rps->vclk || rps->dclk) {
disable_mclk_switching = true;
disable_sclk_switching = true;
}
if (rdev->pm.dpm.ac_power) if (rdev->pm.dpm.ac_power)
max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
...@@ -2940,28 +2944,44 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, ...@@ -2940,28 +2944,44 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
if (disable_mclk_switching) { if (disable_mclk_switching) {
mclk = ps->performance_levels[ps->performance_level_count - 1].mclk; mclk = ps->performance_levels[ps->performance_level_count - 1].mclk;
sclk = ps->performance_levels[0].sclk;
vddc = ps->performance_levels[0].vddc;
vddci = ps->performance_levels[ps->performance_level_count - 1].vddci; vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
} else { } else {
sclk = ps->performance_levels[0].sclk;
mclk = ps->performance_levels[0].mclk; mclk = ps->performance_levels[0].mclk;
vddc = ps->performance_levels[0].vddc;
vddci = ps->performance_levels[0].vddci; vddci = ps->performance_levels[0].vddci;
} }
if (disable_sclk_switching) {
sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;
vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;
} else {
sclk = ps->performance_levels[0].sclk;
vddc = ps->performance_levels[0].vddc;
}
/* adjusted low state */ /* adjusted low state */
ps->performance_levels[0].sclk = sclk; ps->performance_levels[0].sclk = sclk;
ps->performance_levels[0].mclk = mclk; ps->performance_levels[0].mclk = mclk;
ps->performance_levels[0].vddc = vddc; ps->performance_levels[0].vddc = vddc;
ps->performance_levels[0].vddci = vddci; ps->performance_levels[0].vddci = vddci;
if (disable_sclk_switching) {
sclk = ps->performance_levels[0].sclk;
for (i = 1; i < ps->performance_level_count; i++) {
if (sclk < ps->performance_levels[i].sclk)
sclk = ps->performance_levels[i].sclk;
}
for (i = 0; i < ps->performance_level_count; i++) {
ps->performance_levels[i].sclk = sclk;
ps->performance_levels[i].vddc = vddc;
}
} else {
for (i = 1; i < ps->performance_level_count; i++) { for (i = 1; i < ps->performance_level_count; i++) {
if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk) if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk; ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc) if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc; ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
} }
}
if (disable_mclk_switching) { if (disable_mclk_switching) {
mclk = ps->performance_levels[0].mclk; mclk = ps->performance_levels[0].mclk;
......
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