diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-07-02 18:46:28 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-07-05 18:09:48 -0400 |
commit | a160a6a3367611351624fca06838000b02aae2c7 (patch) | |
tree | ae2df22ceda0bdb3957f3e692d677ab1e578acc8 /drivers/gpu | |
parent | 170a47f010182152bed6f44f3878dd0423df2b78 (diff) |
drm/radeon/dpm: implement force performance level for SI
Allows you to force the selected performance level via sysfs.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.c | 42 |
3 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 9c1b7b1c0268..6ec4831fdb58 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -2287,6 +2287,7 @@ static struct radeon_asic si_asic = { | |||
2287 | .get_mclk = &ni_dpm_get_mclk, | 2287 | .get_mclk = &ni_dpm_get_mclk, |
2288 | .print_power_state = &ni_dpm_print_power_state, | 2288 | .print_power_state = &ni_dpm_print_power_state, |
2289 | .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level, | 2289 | .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level, |
2290 | .force_performance_level = &si_dpm_force_performance_level, | ||
2290 | }, | 2291 | }, |
2291 | .pflip = { | 2292 | .pflip = { |
2292 | .pre_page_flip = &evergreen_pre_page_flip, | 2293 | .pre_page_flip = &evergreen_pre_page_flip, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 2bacc777d549..7efa51a13b3c 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -683,6 +683,8 @@ void si_dpm_fini(struct radeon_device *rdev); | |||
683 | void si_dpm_display_configuration_changed(struct radeon_device *rdev); | 683 | void si_dpm_display_configuration_changed(struct radeon_device *rdev); |
684 | void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 684 | void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
685 | struct seq_file *m); | 685 | struct seq_file *m); |
686 | int si_dpm_force_performance_level(struct radeon_device *rdev, | ||
687 | enum radeon_dpm_forced_level level); | ||
686 | 688 | ||
687 | /* DCE8 - CIK */ | 689 | /* DCE8 - CIK */ |
688 | void dce8_bandwidth_update(struct radeon_device *rdev); | 690 | void dce8_bandwidth_update(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index a7e97cd05e96..700a167be369 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -3231,16 +3231,38 @@ static int si_restrict_performance_levels_before_switch(struct radeon_device *rd | |||
3231 | 0 : -EINVAL; | 3231 | 0 : -EINVAL; |
3232 | } | 3232 | } |
3233 | 3233 | ||
3234 | #if 0 | 3234 | int si_dpm_force_performance_level(struct radeon_device *rdev, |
3235 | static int si_unrestrict_performance_levels_after_switch(struct radeon_device *rdev) | 3235 | enum radeon_dpm_forced_level level) |
3236 | { | 3236 | { |
3237 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) | 3237 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; |
3238 | return -EINVAL; | 3238 | struct ni_ps *ps = ni_get_ps(rps); |
3239 | u32 levels; | ||
3239 | 3240 | ||
3240 | return (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) == PPSMC_Result_OK) ? | 3241 | if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { |
3241 | 0 : -EINVAL; | 3242 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) |
3243 | return -EINVAL; | ||
3244 | |||
3245 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK) | ||
3246 | return -EINVAL; | ||
3247 | } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) { | ||
3248 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) | ||
3249 | return -EINVAL; | ||
3250 | |||
3251 | levels = ps->performance_level_count - 1; | ||
3252 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) | ||
3253 | return -EINVAL; | ||
3254 | } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { | ||
3255 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) | ||
3256 | return -EINVAL; | ||
3257 | |||
3258 | if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) | ||
3259 | return -EINVAL; | ||
3260 | } | ||
3261 | |||
3262 | rdev->pm.dpm.forced_level = level; | ||
3263 | |||
3264 | return 0; | ||
3242 | } | 3265 | } |
3243 | #endif | ||
3244 | 3266 | ||
3245 | static int si_set_boot_state(struct radeon_device *rdev) | 3267 | static int si_set_boot_state(struct radeon_device *rdev) |
3246 | { | 3268 | { |
@@ -5992,11 +6014,13 @@ int si_dpm_set_power_state(struct radeon_device *rdev) | |||
5992 | 6014 | ||
5993 | #if 0 | 6015 | #if 0 |
5994 | /* XXX */ | 6016 | /* XXX */ |
5995 | ret = si_unrestrict_performance_levels_after_switch(rdev); | 6017 | ret = si_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); |
5996 | if (ret) { | 6018 | if (ret) { |
5997 | DRM_ERROR("si_unrestrict_performance_levels_after_switch failed\n"); | 6019 | DRM_ERROR("si_dpm_force_performance_level failed\n"); |
5998 | return ret; | 6020 | return ret; |
5999 | } | 6021 | } |
6022 | #else | ||
6023 | rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO; | ||
6000 | #endif | 6024 | #endif |
6001 | 6025 | ||
6002 | return 0; | 6026 | return 0; |