From deecc3ce203b49b5ba95d7af0a78c58a4f9014eb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 30 Aug 2013 15:46:29 -0400 Subject: [PATCH] drm/radeon/dpm: make sure dc performance level limits are valid (BTC-SI) Check to make sure the dc limits are valid before using them. Some systems may not have a dc limits table. In that case just use the ac limits. This fixes hangs on systems when the power state is changed when on battery (dc) due to invalid performance state parameters. Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=68708 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/btc_dpm.c | 12 +++++++----- drivers/gpu/drm/radeon/ni_dpm.c | 12 +++++++----- drivers/gpu/drm/radeon/si_dpm.c | 12 +++++++----- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 9953e1f..4b70f4b 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -2076,7 +2076,8 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, struct radeon_ps *rps) { struct rv7xx_ps *ps = rv770_get_ps(rps); - struct radeon_clock_and_voltage_limits *max_limits; + struct radeon_clock_and_voltage_limits *max_limits = + &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; bool disable_mclk_switching; u32 mclk, sclk; u16 vddc, vddci; @@ -2087,10 +2088,11 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, else disable_mclk_switching = false; - if (rdev->pm.dpm.ac_power) - max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; - else - max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc; + if (rdev->pm.dpm.ac_power == false) { + if (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk && + rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk) + max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc; + } if (rdev->pm.dpm.ac_power == false) { if (ps->high.mclk > max_limits->mclk) diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 88aa41e..fd1747d 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -783,7 +783,8 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev, struct radeon_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 = + &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; bool disable_mclk_switching; u32 mclk, sclk; u16 vddc, vddci; @@ -795,10 +796,11 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev, else disable_mclk_switching = false; - if (rdev->pm.dpm.ac_power) - max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; - else - max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc; + if (rdev->pm.dpm.ac_power == false) { + if (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk && + rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk) + max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc; + } if (rdev->pm.dpm.ac_power == false) { for (i = 0; i < ps->performance_level_count; i++) { diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 51966f4..19d89c3 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2905,7 +2905,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, struct radeon_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 = + &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; bool disable_mclk_switching = false; bool disable_sclk_switching = false; u32 mclk, sclk; @@ -2921,10 +2922,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, disable_sclk_switching = true; } - if (rdev->pm.dpm.ac_power) - max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; - else - max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc; + if (rdev->pm.dpm.ac_power == false) { + if (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk && + rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk) + max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc; + } for (i = ps->performance_level_count - 2; i >= 0; i--) { if (ps->performance_levels[i].vddc > ps->performance_levels[i+1].vddc) -- 1.8.3.1