aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-07-02 18:52:10 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-07-05 18:10:06 -0400
commit9b5de59629d2e58eab41e2f0e5cc60b3c395f1c3 (patch)
tree58c2805c7a3e4e0bb1d7480bcd359719ebf5eca5 /drivers/gpu
parent5d5e559193afd516daae9816e892bf2d97be0988 (diff)
drm/radeon/dpm: implement force performance level for TN
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/ppsmc.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h2
-rw-r--r--drivers/gpu/drm/radeon/trinity_dpm.c32
-rw-r--r--drivers/gpu/drm/radeon/trinity_dpm.h1
-rw-r--r--drivers/gpu/drm/radeon/trinity_smc.c7
6 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h
index fc71ca6b04ca..b5564a3645d2 100644
--- a/drivers/gpu/drm/radeon/ppsmc.h
+++ b/drivers/gpu/drm/radeon/ppsmc.h
@@ -103,6 +103,7 @@ typedef uint8_t PPSMC_Result;
103#define PPSMC_MSG_DPM_Config ((uint32_t) 0x102) 103#define PPSMC_MSG_DPM_Config ((uint32_t) 0x102)
104#define PPSMC_MSG_DPM_ForceState ((uint32_t) 0x104) 104#define PPSMC_MSG_DPM_ForceState ((uint32_t) 0x104)
105#define PPSMC_MSG_PG_SIMD_Config ((uint32_t) 0x108) 105#define PPSMC_MSG_PG_SIMD_Config ((uint32_t) 0x108)
106#define PPSMC_MSG_DPM_N_LevelsDisabled ((uint32_t) 0x112)
106#define PPSMC_MSG_DCE_RemoveVoltageAdjustment ((uint32_t) 0x11d) 107#define PPSMC_MSG_DCE_RemoveVoltageAdjustment ((uint32_t) 0x11d)
107#define PPSMC_MSG_DCE_AllowVoltageAdjustment ((uint32_t) 0x11e) 108#define PPSMC_MSG_DCE_AllowVoltageAdjustment ((uint32_t) 0x11e)
108#define PPSMC_MSG_UVD_DPM_Config ((uint32_t) 0x124) 109#define PPSMC_MSG_UVD_DPM_Config ((uint32_t) 0x124)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 5d592aed1ee9..a6906d4ca734 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -2115,6 +2115,7 @@ static struct radeon_asic trinity_asic = {
2115 .get_mclk = &trinity_dpm_get_mclk, 2115 .get_mclk = &trinity_dpm_get_mclk,
2116 .print_power_state = &trinity_dpm_print_power_state, 2116 .print_power_state = &trinity_dpm_print_power_state,
2117 .debugfs_print_current_performance_level = &trinity_dpm_debugfs_print_current_performance_level, 2117 .debugfs_print_current_performance_level = &trinity_dpm_debugfs_print_current_performance_level,
2118 .force_performance_level = &trinity_dpm_force_performance_level,
2118 }, 2119 },
2119 .pflip = { 2120 .pflip = {
2120 .pre_page_flip = &evergreen_pre_page_flip, 2121 .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 1a89b3af04f3..4456f85a932e 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -636,6 +636,8 @@ void trinity_dpm_print_power_state(struct radeon_device *rdev,
636 struct radeon_ps *ps); 636 struct radeon_ps *ps);
637void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, 637void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
638 struct seq_file *m); 638 struct seq_file *m);
639int trinity_dpm_force_performance_level(struct radeon_device *rdev,
640 enum radeon_dpm_forced_level level);
639 641
640/* DCE6 - SI */ 642/* DCE6 - SI */
641void dce6_bandwidth_update(struct radeon_device *rdev); 643void dce6_bandwidth_update(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c
index 8a32bcc6bbb5..a1eb5f59939f 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -1158,6 +1158,37 @@ static void trinity_setup_nbp_sim(struct radeon_device *rdev,
1158 } 1158 }
1159} 1159}
1160 1160
1161int trinity_dpm_force_performance_level(struct radeon_device *rdev,
1162 enum radeon_dpm_forced_level level)
1163{
1164 struct trinity_power_info *pi = trinity_get_pi(rdev);
1165 struct radeon_ps *rps = &pi->current_rps;
1166 struct trinity_ps *ps = trinity_get_ps(rps);
1167 int i, ret;
1168
1169 if (ps->num_levels <= 1)
1170 return 0;
1171
1172 if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
1173 /* not supported by the hw */
1174 return -EINVAL;
1175 } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
1176 ret = trinity_dpm_n_levels_disabled(rdev, ps->num_levels - 1);
1177 if (ret)
1178 return ret;
1179 } else {
1180 for (i = 0; i < ps->num_levels; i++) {
1181 ret = trinity_dpm_n_levels_disabled(rdev, 0);
1182 if (ret)
1183 return ret;
1184 }
1185 }
1186
1187 rdev->pm.dpm.forced_level = level;
1188
1189 return 0;
1190}
1191
1161int trinity_dpm_pre_set_power_state(struct radeon_device *rdev) 1192int trinity_dpm_pre_set_power_state(struct radeon_device *rdev)
1162{ 1193{
1163 struct trinity_power_info *pi = trinity_get_pi(rdev); 1194 struct trinity_power_info *pi = trinity_get_pi(rdev);
@@ -1190,6 +1221,7 @@ int trinity_dpm_set_power_state(struct radeon_device *rdev)
1190 trinity_force_level_0(rdev); 1221 trinity_force_level_0(rdev);
1191 trinity_unforce_levels(rdev); 1222 trinity_unforce_levels(rdev);
1192 trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps); 1223 trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
1224 rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO;
1193 } 1225 }
1194 trinity_release_mutex(rdev); 1226 trinity_release_mutex(rdev);
1195 1227
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.h b/drivers/gpu/drm/radeon/trinity_dpm.h
index c621b843aab5..e82df071f8b3 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.h
+++ b/drivers/gpu/drm/radeon/trinity_dpm.h
@@ -121,6 +121,7 @@ struct trinity_power_info {
121int trinity_dpm_config(struct radeon_device *rdev, bool enable); 121int trinity_dpm_config(struct radeon_device *rdev, bool enable);
122int trinity_uvd_dpm_config(struct radeon_device *rdev); 122int trinity_uvd_dpm_config(struct radeon_device *rdev);
123int trinity_dpm_force_state(struct radeon_device *rdev, u32 n); 123int trinity_dpm_force_state(struct radeon_device *rdev, u32 n);
124int trinity_dpm_n_levels_disabled(struct radeon_device *rdev, u32 n);
124int trinity_dpm_no_forced_level(struct radeon_device *rdev); 125int trinity_dpm_no_forced_level(struct radeon_device *rdev);
125int trinity_dce_enable_voltage_adjustment(struct radeon_device *rdev, 126int trinity_dce_enable_voltage_adjustment(struct radeon_device *rdev,
126 bool enable); 127 bool enable);
diff --git a/drivers/gpu/drm/radeon/trinity_smc.c b/drivers/gpu/drm/radeon/trinity_smc.c
index 85f86a29513c..a42d89f1830c 100644
--- a/drivers/gpu/drm/radeon/trinity_smc.c
+++ b/drivers/gpu/drm/radeon/trinity_smc.c
@@ -73,6 +73,13 @@ int trinity_dpm_force_state(struct radeon_device *rdev, u32 n)
73 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_ForceState); 73 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_ForceState);
74} 74}
75 75
76int trinity_dpm_n_levels_disabled(struct radeon_device *rdev, u32 n)
77{
78 WREG32_SMC(SMU_SCRATCH0, n);
79
80 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_N_LevelsDisabled);
81}
82
76int trinity_uvd_dpm_config(struct radeon_device *rdev) 83int trinity_uvd_dpm_config(struct radeon_device *rdev)
77{ 84{
78 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_UVD_DPM_Config); 85 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_UVD_DPM_Config);