[PATCH 47/53] drm/radeon/dpm: implement force performance level for KB/KV

Alex Deucher alexdeucher at gmail.com
Mon Aug 12 09:43:39 PDT 2013


Allows you to force the selected performance level via sysfs.

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/kv_dpm.c      | 43 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_asic.c |  1 +
 drivers/gpu/drm/radeon/radeon_asic.h |  2 ++
 3 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index d584ee4..c26c4e3 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;
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index b25172b..1dad80c 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -2641,6 +2641,7 @@ static struct radeon_asic kv_asic = {
 		.get_mclk = &kv_dpm_get_mclk,
 		.print_power_state = &kv_dpm_print_power_state,
 		.debugfs_print_current_performance_level = &kv_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &kv_dpm_force_performance_level,
 	},
 	.pflip = {
 		.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 80ad5d8..1e386c4 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -784,5 +784,7 @@ void kv_dpm_print_power_state(struct radeon_device *rdev,
 			      struct radeon_ps *ps);
 void kv_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
 						    struct seq_file *m);
+int kv_dpm_force_performance_level(struct radeon_device *rdev,
+				   enum radeon_dpm_forced_level level);
 
 #endif
-- 
1.8.3.1



More information about the dri-devel mailing list