summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/kv_dpm.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-07-19 00:48:46 +0400
committerAlex Deucher <alexander.deucher@amd.com>2013-08-31 00:30:33 +0400
commit2b4c8022fa95de43f590629b3af611e531e7199a (patch)
tree0caa36332b13589f91c7d8b3bb811ca01eea6091 /drivers/gpu/drm/radeon/kv_dpm.c
parentae3e40e8712414321ef2b61e8bb26a5d9701643b (diff)
downloadlinux-2b4c8022fa95de43f590629b3af611e531e7199a.tar.xz
drm/radeon/dpm: implement force performance level for KB/KV
Allows you to force the selected performance level via sysfs. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/kv_dpm.c')
-rw-r--r--drivers/gpu/drm/radeon/kv_dpm.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index d584ee4a09ad..c26c4e3005e7 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -40,6 +40,7 @@ static void kv_enable_new_levels(struct radeon_device *rdev);
static void kv_program_nbps_index_settings(struct radeon_device *rdev,
struct radeon_ps *new_rps);
static int kv_set_enabled_levels(struct radeon_device *rdev);
+static int kv_force_dpm_highest(struct radeon_device *rdev);
static int kv_force_dpm_lowest(struct radeon_device *rdev);
static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
struct radeon_ps *new_rps,
@@ -1641,6 +1642,30 @@ static int kv_enable_nb_dpm(struct radeon_device *rdev)
return ret;
}
+int kv_dpm_force_performance_level(struct radeon_device *rdev,
+ enum radeon_dpm_forced_level level)
+{
+ int ret;
+
+ if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
+ ret = kv_force_dpm_highest(rdev);
+ if (ret)
+ return ret;
+ } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
+ ret = kv_force_dpm_lowest(rdev);
+ if (ret)
+ return ret;
+ } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
+ ret = kv_unforce_levels(rdev);
+ if (ret)
+ return ret;
+ }
+
+ rdev->pm.dpm.forced_level = level;
+
+ return 0;
+}
+
int kv_dpm_pre_set_power_state(struct radeon_device *rdev)
{
struct kv_power_info *pi = kv_get_pi(rdev);
@@ -1720,6 +1745,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
kv_enable_nb_dpm(rdev);
}
}
+ rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO;
return 0;
}
@@ -1796,6 +1822,23 @@ static void kv_construct_boot_state(struct radeon_device *rdev)
pi->boot_pl.vce_wm = 0;
}
+static int kv_force_dpm_highest(struct radeon_device *rdev)
+{
+ int ret;
+ u32 enable_mask, i;
+
+ ret = kv_dpm_get_enable_mask(rdev, &enable_mask);
+ if (ret)
+ return ret;
+
+ for (i = SMU7_MAX_LEVELS_GRAPHICS - 1; i >= 0; i--) {
+ if (enable_mask & (1 << i))
+ break;
+ }
+
+ return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i);
+}
+
static int kv_force_dpm_lowest(struct radeon_device *rdev)
{
int ret;