Commit 00092107 authored by Alex Deucher's avatar Alex Deucher Committed by Luis Henriques

drm/radeon/dpm: fix 120hz handling harder

commit 3899ca84 upstream.

Need to expand the check to handle short circuiting
if the selected state is the same as current state.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=87796Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 96fbe89f
...@@ -1512,6 +1512,7 @@ struct radeon_dpm { ...@@ -1512,6 +1512,7 @@ struct radeon_dpm {
int new_active_crtc_count; int new_active_crtc_count;
u32 current_active_crtcs; u32 current_active_crtcs;
int current_active_crtc_count; int current_active_crtc_count;
bool single_display;
struct radeon_dpm_dynamic_state dyn_state; struct radeon_dpm_dynamic_state dyn_state;
struct radeon_dpm_fan fan; struct radeon_dpm_fan fan;
u32 tdp_limit; u32 tdp_limit;
......
...@@ -704,12 +704,8 @@ static void radeon_dpm_thermal_work_handler(struct work_struct *work) ...@@ -704,12 +704,8 @@ static void radeon_dpm_thermal_work_handler(struct work_struct *work)
radeon_pm_compute_clocks(rdev); radeon_pm_compute_clocks(rdev);
} }
static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, static bool radeon_dpm_single_display(struct radeon_device *rdev)
enum radeon_pm_state_type dpm_state)
{ {
int i;
struct radeon_ps *ps;
u32 ui_class;
bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ? bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ?
true : false; true : false;
...@@ -719,6 +715,17 @@ static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, ...@@ -719,6 +715,17 @@ static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
single_display = false; single_display = false;
} }
return single_display;
}
static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
enum radeon_pm_state_type dpm_state)
{
int i;
struct radeon_ps *ps;
u32 ui_class;
bool single_display = radeon_dpm_single_display(rdev);
/* certain older asics have a separare 3D performance state, /* certain older asics have a separare 3D performance state,
* so try that first if the user selected performance * so try that first if the user selected performance
*/ */
...@@ -844,6 +851,7 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) ...@@ -844,6 +851,7 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
struct radeon_ps *ps; struct radeon_ps *ps;
enum radeon_pm_state_type dpm_state; enum radeon_pm_state_type dpm_state;
int ret; int ret;
bool single_display = radeon_dpm_single_display(rdev);
/* if dpm init failed */ /* if dpm init failed */
if (!rdev->pm.dpm_enabled) if (!rdev->pm.dpm_enabled)
...@@ -868,6 +876,9 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) ...@@ -868,6 +876,9 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
/* vce just modifies an existing state so force a change */ /* vce just modifies an existing state so force a change */
if (ps->vce_active != rdev->pm.dpm.vce_active) if (ps->vce_active != rdev->pm.dpm.vce_active)
goto force; goto force;
/* user has made a display change (such as timing) */
if (rdev->pm.dpm.single_display != single_display)
goto force;
if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) { if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) {
/* for pre-BTC and APUs if the num crtcs changed but state is the same, /* for pre-BTC and APUs if the num crtcs changed but state is the same,
* all we need to do is update the display configuration. * all we need to do is update the display configuration.
...@@ -930,6 +941,7 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) ...@@ -930,6 +941,7 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
rdev->pm.dpm.single_display = single_display;
/* wait for the rings to drain */ /* wait for the rings to drain */
for (i = 0; i < RADEON_NUM_RINGS; i++) { for (i = 0; i < RADEON_NUM_RINGS; i++) {
......
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