diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-08-01 11:54:07 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-07 17:37:11 -0400 |
commit | 797f203f622164a322b9a0f962ce431e3f6ca48e (patch) | |
tree | ad8f52c3f1ea9beeb2a53f585f710a3ed83c8395 | |
parent | b841ce7b41ffbecf84285b381b3ac23f05256d31 (diff) |
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: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 71a993f1c8c4..88699e3cd868 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -2903,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2903 | { | 2903 | { |
2904 | struct ni_ps *ps = ni_get_ps(rps); | 2904 | struct ni_ps *ps = ni_get_ps(rps); |
2905 | struct radeon_clock_and_voltage_limits *max_limits; | 2905 | struct radeon_clock_and_voltage_limits *max_limits; |
2906 | bool disable_mclk_switching; | 2906 | bool disable_mclk_switching = false; |
2907 | bool disable_sclk_switching = false; | ||
2907 | u32 mclk, sclk; | 2908 | u32 mclk, sclk; |
2908 | u16 vddc, vddci; | 2909 | u16 vddc, vddci; |
2909 | int i; | 2910 | int i; |
@@ -2911,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2911 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 2912 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
2912 | ni_dpm_vblank_too_short(rdev)) | 2913 | ni_dpm_vblank_too_short(rdev)) |
2913 | disable_mclk_switching = true; | 2914 | disable_mclk_switching = true; |
2914 | else | 2915 | |
2915 | disable_mclk_switching = false; | 2916 | if (rps->vclk || rps->dclk) { |
2917 | disable_mclk_switching = true; | ||
2918 | disable_sclk_switching = true; | ||
2919 | } | ||
2916 | 2920 | ||
2917 | if (rdev->pm.dpm.ac_power) | 2921 | if (rdev->pm.dpm.ac_power) |
2918 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 2922 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
@@ -2940,27 +2944,43 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2940 | 2944 | ||
2941 | if (disable_mclk_switching) { | 2945 | if (disable_mclk_switching) { |
2942 | mclk = ps->performance_levels[ps->performance_level_count - 1].mclk; | 2946 | mclk = ps->performance_levels[ps->performance_level_count - 1].mclk; |
2943 | sclk = ps->performance_levels[0].sclk; | ||
2944 | vddc = ps->performance_levels[0].vddc; | ||
2945 | vddci = ps->performance_levels[ps->performance_level_count - 1].vddci; | 2947 | vddci = ps->performance_levels[ps->performance_level_count - 1].vddci; |
2946 | } else { | 2948 | } else { |
2947 | sclk = ps->performance_levels[0].sclk; | ||
2948 | mclk = ps->performance_levels[0].mclk; | 2949 | mclk = ps->performance_levels[0].mclk; |
2949 | vddc = ps->performance_levels[0].vddc; | ||
2950 | vddci = ps->performance_levels[0].vddci; | 2950 | vddci = ps->performance_levels[0].vddci; |
2951 | } | 2951 | } |
2952 | 2952 | ||
2953 | if (disable_sclk_switching) { | ||
2954 | sclk = ps->performance_levels[ps->performance_level_count - 1].sclk; | ||
2955 | vddc = ps->performance_levels[ps->performance_level_count - 1].vddc; | ||
2956 | } else { | ||
2957 | sclk = ps->performance_levels[0].sclk; | ||
2958 | vddc = ps->performance_levels[0].vddc; | ||
2959 | } | ||
2960 | |||
2953 | /* adjusted low state */ | 2961 | /* adjusted low state */ |
2954 | ps->performance_levels[0].sclk = sclk; | 2962 | ps->performance_levels[0].sclk = sclk; |
2955 | ps->performance_levels[0].mclk = mclk; | 2963 | ps->performance_levels[0].mclk = mclk; |
2956 | ps->performance_levels[0].vddc = vddc; | 2964 | ps->performance_levels[0].vddc = vddc; |
2957 | ps->performance_levels[0].vddci = vddci; | 2965 | ps->performance_levels[0].vddci = vddci; |
2958 | 2966 | ||
2959 | for (i = 1; i < ps->performance_level_count; i++) { | 2967 | if (disable_sclk_switching) { |
2960 | if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk) | 2968 | sclk = ps->performance_levels[0].sclk; |
2961 | ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk; | 2969 | for (i = 1; i < ps->performance_level_count; i++) { |
2962 | if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc) | 2970 | if (sclk < ps->performance_levels[i].sclk) |
2963 | ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc; | 2971 | sclk = ps->performance_levels[i].sclk; |
2972 | } | ||
2973 | for (i = 0; i < ps->performance_level_count; i++) { | ||
2974 | ps->performance_levels[i].sclk = sclk; | ||
2975 | ps->performance_levels[i].vddc = vddc; | ||
2976 | } | ||
2977 | } else { | ||
2978 | for (i = 1; i < ps->performance_level_count; i++) { | ||
2979 | if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk) | ||
2980 | ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk; | ||
2981 | if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc) | ||
2982 | ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc; | ||
2983 | } | ||
2964 | } | 2984 | } |
2965 | 2985 | ||
2966 | if (disable_mclk_switching) { | 2986 | if (disable_mclk_switching) { |