Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/dpm: fix 120hz handling harder

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=87796

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org

+18 -5
+1
drivers/gpu/drm/radeon/radeon.h
··· 1565 1565 int new_active_crtc_count; 1566 1566 u32 current_active_crtcs; 1567 1567 int current_active_crtc_count; 1568 + bool single_display; 1568 1569 struct radeon_dpm_dynamic_state dyn_state; 1569 1570 struct radeon_dpm_fan fan; 1570 1571 u32 tdp_limit;
+17 -5
drivers/gpu/drm/radeon/radeon_pm.c
··· 837 837 radeon_pm_compute_clocks(rdev); 838 838 } 839 839 840 - static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, 841 - enum radeon_pm_state_type dpm_state) 840 + static bool radeon_dpm_single_display(struct radeon_device *rdev) 842 841 { 843 - int i; 844 - struct radeon_ps *ps; 845 - u32 ui_class; 846 842 bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ? 847 843 true : false; 848 844 ··· 853 857 */ 854 858 if (single_display && (r600_dpm_get_vrefresh(rdev) >= 120)) 855 859 single_display = false; 860 + 861 + return single_display; 862 + } 863 + 864 + static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, 865 + enum radeon_pm_state_type dpm_state) 866 + { 867 + int i; 868 + struct radeon_ps *ps; 869 + u32 ui_class; 870 + bool single_display = radeon_dpm_single_display(rdev); 856 871 857 872 /* certain older asics have a separare 3D performance state, 858 873 * so try that first if the user selected performance ··· 990 983 struct radeon_ps *ps; 991 984 enum radeon_pm_state_type dpm_state; 992 985 int ret; 986 + bool single_display = radeon_dpm_single_display(rdev); 993 987 994 988 /* if dpm init failed */ 995 989 if (!rdev->pm.dpm_enabled) ··· 1014 1006 if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) { 1015 1007 /* vce just modifies an existing state so force a change */ 1016 1008 if (ps->vce_active != rdev->pm.dpm.vce_active) 1009 + goto force; 1010 + /* user has made a display change (such as timing) */ 1011 + if (rdev->pm.dpm.single_display != single_display) 1017 1012 goto force; 1018 1013 if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) { 1019 1014 /* for pre-BTC and APUs if the num crtcs changed but state is the same, ··· 1080 1069 1081 1070 rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; 1082 1071 rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; 1072 + rdev->pm.dpm.single_display = single_display; 1083 1073 1084 1074 /* wait for the rings to drain */ 1085 1075 for (i = 0; i < RADEON_NUM_RINGS; i++) {