aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-05-07 15:10:16 -0400
committerDave Airlie <airlied@redhat.com>2010-05-18 04:21:52 -0400
commitce8f53709bf440100cb9d31b1303291551cf517f (patch)
tree6785882522ae04486ae900b5c8dbc700dadad2f3 /drivers/gpu
parentd7311171c4cc8d6231427f7ac5056b939a184b80 (diff)
drm/radeon/kms/pm: rework power management
- Separate dynpm and profile based power management methods. You can select the pm method by echoing the selected method ("dynpm" or "profile") to power_method in sysfs. - Expose basic 4 profile in profile method "default" - default clocks "auto" - select between low and high based on ac/dc state "low" - DC, low power mode "high" - AC, performance mode The current base profile is "default", but it should switched to "auto" once we've tested on more systems. Switching the state is a matter of echoing the requested profile to power_profile in sysfs. The lowest power states are selected automatically when dpms turns the monitors off in all states but default. - Remove dynamic fence-based reclocking for the moment. We can revisit this later once we have basic pm in. - Move pm init/fini to modesetting path. pm is tightly coupled with display state. Make sure display side is initialized before pm. - Add pm suspend/resume functions to make sure pm state is properly reinitialized on resume. - Remove dynpm module option. It's now selectable via sysfs. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/Kconfig1
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c3
-rw-r--r--drivers/gpu/drm/radeon/r100.c128
-rw-r--r--drivers/gpu/drm/radeon/r300.c3
-rw-r--r--drivers/gpu/drm/radeon/r420.c32
-rw-r--r--drivers/gpu/drm/radeon/r520.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c332
-rw-r--r--drivers/gpu/drm/radeon/radeon.h87
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c56
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c628
-rw-r--r--drivers/gpu/drm/radeon/rs400.c3
-rw-r--r--drivers/gpu/drm/radeon/rs600.c3
-rw-r--r--drivers/gpu/drm/radeon/rs690.c3
-rw-r--r--drivers/gpu/drm/radeon/rv515.c3
-rw-r--r--drivers/gpu/drm/radeon/rv770.c3
19 files changed, 790 insertions, 519 deletions
diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index 1c02d23f6fcc..80c5b3ea28b4 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -1,6 +1,7 @@
1config DRM_RADEON_KMS 1config DRM_RADEON_KMS
2 bool "Enable modesetting on radeon by default - NEW DRIVER" 2 bool "Enable modesetting on radeon by default - NEW DRIVER"
3 depends on DRM_RADEON 3 depends on DRM_RADEON
4 depends on POWER_SUPPLY
4 help 5 help
5 Choose this option if you want kernel modesetting enabled by default. 6 Choose this option if you want kernel modesetting enabled by default.
6 7
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 8d86d0568d97..8c8e4d3cbaa3 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2115,8 +2115,6 @@ int evergreen_init(struct radeon_device *rdev)
2115 r = radeon_clocks_init(rdev); 2115 r = radeon_clocks_init(rdev);
2116 if (r) 2116 if (r)
2117 return r; 2117 return r;
2118 /* Initialize power management */
2119 radeon_pm_init(rdev);
2120 /* Fence driver */ 2118 /* Fence driver */
2121 r = radeon_fence_driver_init(rdev); 2119 r = radeon_fence_driver_init(rdev);
2122 if (r) 2120 if (r)
@@ -2178,7 +2176,6 @@ int evergreen_init(struct radeon_device *rdev)
2178 2176
2179void evergreen_fini(struct radeon_device *rdev) 2177void evergreen_fini(struct radeon_device *rdev)
2180{ 2178{
2181 radeon_pm_fini(rdev);
2182 /*r600_blit_fini(rdev);*/ 2179 /*r600_blit_fini(rdev);*/
2183 r700_cp_fini(rdev); 2180 r700_cp_fini(rdev);
2184 r600_wb_fini(rdev); 2181 r600_wb_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 4161a35dd3d3..4c5d21bfa2c4 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -68,22 +68,21 @@ MODULE_FIRMWARE(FIRMWARE_R520);
68 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 68 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
69 */ 69 */
70 70
71void r100_get_power_state(struct radeon_device *rdev, 71void r100_pm_get_dynpm_state(struct radeon_device *rdev)
72 enum radeon_pm_action action)
73{ 72{
74 int i; 73 int i;
75 rdev->pm.can_upclock = true; 74 rdev->pm.dynpm_can_upclock = true;
76 rdev->pm.can_downclock = true; 75 rdev->pm.dynpm_can_downclock = true;
77 76
78 switch (action) { 77 switch (rdev->pm.dynpm_planned_action) {
79 case PM_ACTION_MINIMUM: 78 case DYNPM_ACTION_MINIMUM:
80 rdev->pm.requested_power_state_index = 0; 79 rdev->pm.requested_power_state_index = 0;
81 rdev->pm.can_downclock = false; 80 rdev->pm.dynpm_can_downclock = false;
82 break; 81 break;
83 case PM_ACTION_DOWNCLOCK: 82 case DYNPM_ACTION_DOWNCLOCK:
84 if (rdev->pm.current_power_state_index == 0) { 83 if (rdev->pm.current_power_state_index == 0) {
85 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; 84 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
86 rdev->pm.can_downclock = false; 85 rdev->pm.dynpm_can_downclock = false;
87 } else { 86 } else {
88 if (rdev->pm.active_crtc_count > 1) { 87 if (rdev->pm.active_crtc_count > 1) {
89 for (i = 0; i < rdev->pm.num_power_states; i++) { 88 for (i = 0; i < rdev->pm.num_power_states; i++) {
@@ -108,10 +107,10 @@ void r100_get_power_state(struct radeon_device *rdev,
108 rdev->pm.requested_power_state_index++; 107 rdev->pm.requested_power_state_index++;
109 } 108 }
110 break; 109 break;
111 case PM_ACTION_UPCLOCK: 110 case DYNPM_ACTION_UPCLOCK:
112 if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) { 111 if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) {
113 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; 112 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
114 rdev->pm.can_upclock = false; 113 rdev->pm.dynpm_can_upclock = false;
115 } else { 114 } else {
116 if (rdev->pm.active_crtc_count > 1) { 115 if (rdev->pm.active_crtc_count > 1) {
117 for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) { 116 for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) {
@@ -130,11 +129,11 @@ void r100_get_power_state(struct radeon_device *rdev,
130 rdev->pm.current_power_state_index + 1; 129 rdev->pm.current_power_state_index + 1;
131 } 130 }
132 break; 131 break;
133 case PM_ACTION_DEFAULT: 132 case DYNPM_ACTION_DEFAULT:
134 rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; 133 rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index;
135 rdev->pm.can_upclock = false; 134 rdev->pm.dynpm_can_upclock = false;
136 break; 135 break;
137 case PM_ACTION_NONE: 136 case DYNPM_ACTION_NONE:
138 default: 137 default:
139 DRM_ERROR("Requested mode for not defined action\n"); 138 DRM_ERROR("Requested mode for not defined action\n");
140 return; 139 return;
@@ -151,77 +150,33 @@ void r100_get_power_state(struct radeon_device *rdev,
151 pcie_lanes); 150 pcie_lanes);
152} 151}
153 152
154void r100_set_power_state(struct radeon_device *rdev, bool static_switch) 153void r100_pm_init_profile(struct radeon_device *rdev)
155{ 154{
156 u32 sclk, mclk; 155 /* default */
157 156 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
158 if (rdev->pm.current_power_state_index == rdev->pm.requested_power_state_index) 157 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
159 return; 158 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
160 159 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
161 if (radeon_gui_idle(rdev)) { 160 /* low sh */
162 161 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0;
163 sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. 162 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0;
164 clock_info[rdev->pm.requested_clock_mode_index].sclk; 163 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
165 if (sclk > rdev->clock.default_sclk) 164 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
166 sclk = rdev->clock.default_sclk; 165 /* high sh */
167 166 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0;
168 mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. 167 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
169 clock_info[rdev->pm.requested_clock_mode_index].mclk; 168 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
170 if (mclk > rdev->clock.default_mclk) 169 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
171 mclk = rdev->clock.default_mclk; 170 /* low mh */
172 /* don't change the mclk with multiple crtcs */ 171 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0;
173 if (rdev->pm.active_crtc_count > 1) 172 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
174 mclk = rdev->clock.default_mclk; 173 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
175 174 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
176 /* voltage, pcie lanes, etc.*/ 175 /* high mh */
177 radeon_pm_misc(rdev); 176 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0;
178 177 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
179 if (static_switch) { 178 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
180 radeon_pm_prepare(rdev); 179 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
181 /* set engine clock */
182 if (sclk != rdev->pm.current_sclk) {
183 radeon_set_engine_clock(rdev, sclk);
184 rdev->pm.current_sclk = sclk;
185 DRM_INFO("Setting: e: %d\n", sclk);
186 }
187 /* set memory clock */
188 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
189 radeon_set_memory_clock(rdev, mclk);
190 rdev->pm.current_mclk = mclk;
191 DRM_INFO("Setting: m: %d\n", mclk);
192 }
193 radeon_pm_finish(rdev);
194 } else {
195 radeon_sync_with_vblank(rdev);
196
197 if (!radeon_pm_in_vbl(rdev))
198 return;
199
200 radeon_pm_prepare(rdev);
201 /* set engine clock */
202 if (sclk != rdev->pm.current_sclk) {
203 radeon_pm_debug_check_in_vbl(rdev, false);
204 radeon_set_engine_clock(rdev, sclk);
205 radeon_pm_debug_check_in_vbl(rdev, true);
206 rdev->pm.current_sclk = sclk;
207 DRM_INFO("Setting: e: %d\n", sclk);
208 }
209
210 /* set memory clock */
211 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
212 radeon_pm_debug_check_in_vbl(rdev, false);
213 radeon_set_memory_clock(rdev, mclk);
214 radeon_pm_debug_check_in_vbl(rdev, true);
215 rdev->pm.current_mclk = mclk;
216 DRM_INFO("Setting: m: %d\n", mclk);
217 }
218 radeon_pm_finish(rdev);
219 }
220
221 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
222 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
223 } else
224 DRM_INFO("pm: GUI not idle!!!\n");
225} 180}
226 181
227void r100_pm_misc(struct radeon_device *rdev) 182void r100_pm_misc(struct radeon_device *rdev)
@@ -3815,7 +3770,6 @@ int r100_suspend(struct radeon_device *rdev)
3815 3770
3816void r100_fini(struct radeon_device *rdev) 3771void r100_fini(struct radeon_device *rdev)
3817{ 3772{
3818 radeon_pm_fini(rdev);
3819 r100_cp_fini(rdev); 3773 r100_cp_fini(rdev);
3820 r100_wb_fini(rdev); 3774 r100_wb_fini(rdev);
3821 r100_ib_fini(rdev); 3775 r100_ib_fini(rdev);
@@ -3871,8 +3825,6 @@ int r100_init(struct radeon_device *rdev)
3871 r100_errata(rdev); 3825 r100_errata(rdev);
3872 /* Initialize clocks */ 3826 /* Initialize clocks */
3873 radeon_get_clock_info(rdev->ddev); 3827 radeon_get_clock_info(rdev->ddev);
3874 /* Initialize power management */
3875 radeon_pm_init(rdev);
3876 /* initialize AGP */ 3828 /* initialize AGP */
3877 if (rdev->flags & RADEON_IS_AGP) { 3829 if (rdev->flags & RADEON_IS_AGP) {
3878 r = radeon_agp_init(rdev); 3830 r = radeon_agp_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 5d622cb39b33..5c54db51de85 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1345,7 +1345,6 @@ int r300_suspend(struct radeon_device *rdev)
1345 1345
1346void r300_fini(struct radeon_device *rdev) 1346void r300_fini(struct radeon_device *rdev)
1347{ 1347{
1348 radeon_pm_fini(rdev);
1349 r100_cp_fini(rdev); 1348 r100_cp_fini(rdev);
1350 r100_wb_fini(rdev); 1349 r100_wb_fini(rdev);
1351 r100_ib_fini(rdev); 1350 r100_ib_fini(rdev);
@@ -1401,8 +1400,6 @@ int r300_init(struct radeon_device *rdev)
1401 r300_errata(rdev); 1400 r300_errata(rdev);
1402 /* Initialize clocks */ 1401 /* Initialize clocks */
1403 radeon_get_clock_info(rdev->ddev); 1402 radeon_get_clock_info(rdev->ddev);
1404 /* Initialize power management */
1405 radeon_pm_init(rdev);
1406 /* initialize AGP */ 1403 /* initialize AGP */
1407 if (rdev->flags & RADEON_IS_AGP) { 1404 if (rdev->flags & RADEON_IS_AGP) {
1408 r = radeon_agp_init(rdev); 1405 r = radeon_agp_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 3759d8384294..87c0e3840034 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -36,6 +36,35 @@
36#include "r420d.h" 36#include "r420d.h"
37#include "r420_reg_safe.h" 37#include "r420_reg_safe.h"
38 38
39void r420_pm_init_profile(struct radeon_device *rdev)
40{
41 /* default */
42 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
43 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
44 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
45 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
46 /* low sh */
47 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0;
48 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1;
49 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
50 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
51 /* high sh */
52 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0;
53 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
54 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
55 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
56 /* low mh */
57 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0;
58 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
59 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
60 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
61 /* high mh */
62 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0;
63 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
64 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
65 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
66}
67
39static void r420_set_reg_safe(struct radeon_device *rdev) 68static void r420_set_reg_safe(struct radeon_device *rdev)
40{ 69{
41 rdev->config.r300.reg_safe_bm = r420_reg_safe_bm; 70 rdev->config.r300.reg_safe_bm = r420_reg_safe_bm;
@@ -268,7 +297,6 @@ int r420_suspend(struct radeon_device *rdev)
268 297
269void r420_fini(struct radeon_device *rdev) 298void r420_fini(struct radeon_device *rdev)
270{ 299{
271 radeon_pm_fini(rdev);
272 r100_cp_fini(rdev); 300 r100_cp_fini(rdev);
273 r100_wb_fini(rdev); 301 r100_wb_fini(rdev);
274 r100_ib_fini(rdev); 302 r100_ib_fini(rdev);
@@ -328,8 +356,6 @@ int r420_init(struct radeon_device *rdev)
328 356
329 /* Initialize clocks */ 357 /* Initialize clocks */
330 radeon_get_clock_info(rdev->ddev); 358 radeon_get_clock_info(rdev->ddev);
331 /* Initialize power management */
332 radeon_pm_init(rdev);
333 /* initialize AGP */ 359 /* initialize AGP */
334 if (rdev->flags & RADEON_IS_AGP) { 360 if (rdev->flags & RADEON_IS_AGP) {
335 r = radeon_agp_init(rdev); 361 r = radeon_agp_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 870111e26bd1..34330df28483 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -261,8 +261,6 @@ int r520_init(struct radeon_device *rdev)
261 } 261 }
262 /* Initialize clocks */ 262 /* Initialize clocks */
263 radeon_get_clock_info(rdev->ddev); 263 radeon_get_clock_info(rdev->ddev);
264 /* Initialize power management */
265 radeon_pm_init(rdev);
266 /* initialize AGP */ 264 /* initialize AGP */
267 if (rdev->flags & RADEON_IS_AGP) { 265 if (rdev->flags & RADEON_IS_AGP) {
268 r = radeon_agp_init(rdev); 266 r = radeon_agp_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 08a328c4165a..618d76d366a4 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -92,13 +92,12 @@ void r600_gpu_init(struct radeon_device *rdev);
92void r600_fini(struct radeon_device *rdev); 92void r600_fini(struct radeon_device *rdev);
93void r600_irq_disable(struct radeon_device *rdev); 93void r600_irq_disable(struct radeon_device *rdev);
94 94
95void r600_get_power_state(struct radeon_device *rdev, 95void r600_pm_get_dynpm_state(struct radeon_device *rdev)
96 enum radeon_pm_action action)
97{ 96{
98 int i; 97 int i;
99 98
100 rdev->pm.can_upclock = true; 99 rdev->pm.dynpm_can_upclock = true;
101 rdev->pm.can_downclock = true; 100 rdev->pm.dynpm_can_downclock = true;
102 101
103 /* power state array is low to high, default is first */ 102 /* power state array is low to high, default is first */
104 if ((rdev->flags & RADEON_IS_IGP) || (rdev->family == CHIP_R600)) { 103 if ((rdev->flags & RADEON_IS_IGP) || (rdev->family == CHIP_R600)) {
@@ -107,16 +106,16 @@ void r600_get_power_state(struct radeon_device *rdev,
107 if (rdev->pm.num_power_states > 2) 106 if (rdev->pm.num_power_states > 2)
108 min_power_state_index = 1; 107 min_power_state_index = 1;
109 108
110 switch (action) { 109 switch (rdev->pm.dynpm_planned_action) {
111 case PM_ACTION_MINIMUM: 110 case DYNPM_ACTION_MINIMUM:
112 rdev->pm.requested_power_state_index = min_power_state_index; 111 rdev->pm.requested_power_state_index = min_power_state_index;
113 rdev->pm.requested_clock_mode_index = 0; 112 rdev->pm.requested_clock_mode_index = 0;
114 rdev->pm.can_downclock = false; 113 rdev->pm.dynpm_can_downclock = false;
115 break; 114 break;
116 case PM_ACTION_DOWNCLOCK: 115 case DYNPM_ACTION_DOWNCLOCK:
117 if (rdev->pm.current_power_state_index == min_power_state_index) { 116 if (rdev->pm.current_power_state_index == min_power_state_index) {
118 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; 117 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
119 rdev->pm.can_downclock = false; 118 rdev->pm.dynpm_can_downclock = false;
120 } else { 119 } else {
121 if (rdev->pm.active_crtc_count > 1) { 120 if (rdev->pm.active_crtc_count > 1) {
122 for (i = 0; i < rdev->pm.num_power_states; i++) { 121 for (i = 0; i < rdev->pm.num_power_states; i++) {
@@ -144,10 +143,10 @@ void r600_get_power_state(struct radeon_device *rdev,
144 rdev->pm.requested_power_state_index++; 143 rdev->pm.requested_power_state_index++;
145 } 144 }
146 break; 145 break;
147 case PM_ACTION_UPCLOCK: 146 case DYNPM_ACTION_UPCLOCK:
148 if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) { 147 if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) {
149 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; 148 rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
150 rdev->pm.can_upclock = false; 149 rdev->pm.dynpm_can_upclock = false;
151 } else { 150 } else {
152 if (rdev->pm.active_crtc_count > 1) { 151 if (rdev->pm.active_crtc_count > 1) {
153 for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) { 152 for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) {
@@ -168,12 +167,12 @@ void r600_get_power_state(struct radeon_device *rdev,
168 } 167 }
169 rdev->pm.requested_clock_mode_index = 0; 168 rdev->pm.requested_clock_mode_index = 0;
170 break; 169 break;
171 case PM_ACTION_DEFAULT: 170 case DYNPM_ACTION_DEFAULT:
172 rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; 171 rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index;
173 rdev->pm.requested_clock_mode_index = 0; 172 rdev->pm.requested_clock_mode_index = 0;
174 rdev->pm.can_upclock = false; 173 rdev->pm.dynpm_can_upclock = false;
175 break; 174 break;
176 case PM_ACTION_NONE: 175 case DYNPM_ACTION_NONE:
177 default: 176 default:
178 DRM_ERROR("Requested mode for not defined action\n"); 177 DRM_ERROR("Requested mode for not defined action\n");
179 return; 178 return;
@@ -200,22 +199,22 @@ void r600_get_power_state(struct radeon_device *rdev,
200 } else 199 } else
201 rdev->pm.requested_power_state_index = 1; 200 rdev->pm.requested_power_state_index = 1;
202 201
203 switch (action) { 202 switch (rdev->pm.dynpm_planned_action) {
204 case PM_ACTION_MINIMUM: 203 case DYNPM_ACTION_MINIMUM:
205 rdev->pm.requested_clock_mode_index = 0; 204 rdev->pm.requested_clock_mode_index = 0;
206 rdev->pm.can_downclock = false; 205 rdev->pm.dynpm_can_downclock = false;
207 break; 206 break;
208 case PM_ACTION_DOWNCLOCK: 207 case DYNPM_ACTION_DOWNCLOCK:
209 if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) { 208 if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) {
210 if (rdev->pm.current_clock_mode_index == 0) { 209 if (rdev->pm.current_clock_mode_index == 0) {
211 rdev->pm.requested_clock_mode_index = 0; 210 rdev->pm.requested_clock_mode_index = 0;
212 rdev->pm.can_downclock = false; 211 rdev->pm.dynpm_can_downclock = false;
213 } else 212 } else
214 rdev->pm.requested_clock_mode_index = 213 rdev->pm.requested_clock_mode_index =
215 rdev->pm.current_clock_mode_index - 1; 214 rdev->pm.current_clock_mode_index - 1;
216 } else { 215 } else {
217 rdev->pm.requested_clock_mode_index = 0; 216 rdev->pm.requested_clock_mode_index = 0;
218 rdev->pm.can_downclock = false; 217 rdev->pm.dynpm_can_downclock = false;
219 } 218 }
220 /* don't use the power state if crtcs are active and no display flag is set */ 219 /* don't use the power state if crtcs are active and no display flag is set */
221 if ((rdev->pm.active_crtc_count > 0) && 220 if ((rdev->pm.active_crtc_count > 0) &&
@@ -225,27 +224,27 @@ void r600_get_power_state(struct radeon_device *rdev,
225 rdev->pm.requested_clock_mode_index++; 224 rdev->pm.requested_clock_mode_index++;
226 } 225 }
227 break; 226 break;
228 case PM_ACTION_UPCLOCK: 227 case DYNPM_ACTION_UPCLOCK:
229 if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) { 228 if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) {
230 if (rdev->pm.current_clock_mode_index == 229 if (rdev->pm.current_clock_mode_index ==
231 (rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1)) { 230 (rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1)) {
232 rdev->pm.requested_clock_mode_index = rdev->pm.current_clock_mode_index; 231 rdev->pm.requested_clock_mode_index = rdev->pm.current_clock_mode_index;
233 rdev->pm.can_upclock = false; 232 rdev->pm.dynpm_can_upclock = false;
234 } else 233 } else
235 rdev->pm.requested_clock_mode_index = 234 rdev->pm.requested_clock_mode_index =
236 rdev->pm.current_clock_mode_index + 1; 235 rdev->pm.current_clock_mode_index + 1;
237 } else { 236 } else {
238 rdev->pm.requested_clock_mode_index = 237 rdev->pm.requested_clock_mode_index =
239 rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1; 238 rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1;
240 rdev->pm.can_upclock = false; 239 rdev->pm.dynpm_can_upclock = false;
241 } 240 }
242 break; 241 break;
243 case PM_ACTION_DEFAULT: 242 case DYNPM_ACTION_DEFAULT:
244 rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; 243 rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index;
245 rdev->pm.requested_clock_mode_index = 0; 244 rdev->pm.requested_clock_mode_index = 0;
246 rdev->pm.can_upclock = false; 245 rdev->pm.dynpm_can_upclock = false;
247 break; 246 break;
248 case PM_ACTION_NONE: 247 case DYNPM_ACTION_NONE:
249 default: 248 default:
250 DRM_ERROR("Requested mode for not defined action\n"); 249 DRM_ERROR("Requested mode for not defined action\n");
251 return; 250 return;
@@ -261,73 +260,225 @@ void r600_get_power_state(struct radeon_device *rdev,
261 pcie_lanes); 260 pcie_lanes);
262} 261}
263 262
264void r600_set_power_state(struct radeon_device *rdev, bool static_switch) 263static int r600_pm_get_type_index(struct radeon_device *rdev,
264 enum radeon_pm_state_type ps_type,
265 int instance)
265{ 266{
266 u32 sclk, mclk; 267 int i;
267 268 int found_instance = -1;
268 if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&
269 (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
270 return;
271
272 if (radeon_gui_idle(rdev)) {
273 sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
274 clock_info[rdev->pm.requested_clock_mode_index].sclk;
275 if (sclk > rdev->clock.default_sclk)
276 sclk = rdev->clock.default_sclk;
277
278 mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
279 clock_info[rdev->pm.requested_clock_mode_index].mclk;
280 if (mclk > rdev->clock.default_mclk)
281 mclk = rdev->clock.default_mclk;
282
283 /* voltage, pcie lanes, etc.*/
284 radeon_pm_misc(rdev);
285 269
286 if (static_switch) { 270 for (i = 0; i < rdev->pm.num_power_states; i++) {
287 radeon_pm_prepare(rdev); 271 if (rdev->pm.power_state[i].type == ps_type) {
288 /* set engine clock */ 272 found_instance++;
289 if (sclk != rdev->pm.current_sclk) { 273 if (found_instance == instance)
290 radeon_set_engine_clock(rdev, sclk); 274 return i;
291 rdev->pm.current_sclk = sclk; 275 }
292 DRM_INFO("Setting: e: %d\n", sclk); 276 }
293 } 277 /* return default if no match */
294 /* set memory clock */ 278 return rdev->pm.default_power_state_index;
295 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 279}
296 radeon_set_memory_clock(rdev, mclk); 280
297 rdev->pm.current_mclk = mclk; 281void rs780_pm_init_profile(struct radeon_device *rdev)
298 DRM_INFO("Setting: m: %d\n", mclk); 282{
299 } 283 if (rdev->pm.num_power_states == 2) {
300 radeon_pm_finish(rdev); 284 /* default */
285 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
286 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
287 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
288 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
289 /* low sh */
290 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0;
291 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0;
292 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
293 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
294 /* high sh */
295 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0;
296 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1;
297 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
298 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
299 /* low mh */
300 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0;
301 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0;
302 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
303 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
304 /* high mh */
305 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0;
306 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 1;
307 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
308 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
309 } else if (rdev->pm.num_power_states == 3) {
310 /* default */
311 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
312 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
313 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
314 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
315 /* low sh */
316 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1;
317 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1;
318 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
319 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
320 /* high sh */
321 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1;
322 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 2;
323 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
324 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
325 /* low mh */
326 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 1;
327 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 1;
328 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
329 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
330 /* high mh */
331 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 1;
332 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2;
333 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
334 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
335 } else {
336 /* default */
337 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
338 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
339 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
340 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
341 /* low sh */
342 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 2;
343 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 2;
344 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
345 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
346 /* high sh */
347 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 2;
348 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 3;
349 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
350 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
351 /* low mh */
352 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2;
353 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0;
354 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
355 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
356 /* high mh */
357 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2;
358 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 3;
359 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
360 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
361 }
362}
363
364void r600_pm_init_profile(struct radeon_device *rdev)
365{
366 if (rdev->family == CHIP_R600) {
367 /* XXX */
368 /* default */
369 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
370 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
371 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
372 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
373 /* low sh */
374 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
375 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
376 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
377 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 2;
378 /* high sh */
379 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
380 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
381 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
382 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
383 /* low mh */
384 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
385 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
386 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
387 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 2;
388 /* high mh */
389 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
390 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
391 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
392 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
393 } else if (rdev->flags & RADEON_IS_MOBILITY) {
394 /* default */
395 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
396 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
397 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
398 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
399 /* low sh */
400 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx =
401 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
402 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx =
403 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
404 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
405 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 2;
406 /* high sh */
407 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx =
408 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
409 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx =
410 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
411 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
412 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
413 /* low mh */
414 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx =
415 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
416 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx =
417 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
418 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
419 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 2;
420 /* high mh */
421 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx =
422 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
423 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx =
424 r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
425 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
426 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
427 } else {
428 if (rdev->pm.num_power_states < 4) {
429 /* default */
430 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
431 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
432 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
433 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
434 /* low sh */
435 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
436 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
437 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
438 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 2;
439 /* high sh */
440 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
441 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
442 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
443 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
444 /* low mh */
445 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
446 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
447 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
448 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 2;
449 /* high mh */
450 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
451 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
452 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
453 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
301 } else { 454 } else {
302 radeon_sync_with_vblank(rdev); 455 /* default */
303 456 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
304 if (!radeon_pm_in_vbl(rdev)) 457 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
305 return; 458 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
306 459 rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
307 radeon_pm_prepare(rdev); 460 /* low sh */
308 if (sclk != rdev->pm.current_sclk) { 461 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1;
309 radeon_pm_debug_check_in_vbl(rdev, false); 462 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1;
310 radeon_set_engine_clock(rdev, sclk); 463 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
311 radeon_pm_debug_check_in_vbl(rdev, true); 464 rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 2;
312 rdev->pm.current_sclk = sclk; 465 /* high sh */
313 DRM_INFO("Setting: e: %d\n", sclk); 466 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1;
314 } 467 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1;
315 468 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
316 /* set memory clock */ 469 rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
317 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 470 /* low mh */
318 radeon_pm_debug_check_in_vbl(rdev, false); 471 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 3;
319 radeon_set_memory_clock(rdev, mclk); 472 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 3;
320 radeon_pm_debug_check_in_vbl(rdev, true); 473 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
321 rdev->pm.current_mclk = mclk; 474 rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 2;
322 DRM_INFO("Setting: m: %d\n", mclk); 475 /* high mh */
323 } 476 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 3;
324 radeon_pm_finish(rdev); 477 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 3;
478 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
479 rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
325 } 480 }
326 481 }
327 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
328 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
329 } else
330 DRM_INFO("GUI not idle!!!\n");
331} 482}
332 483
333void r600_pm_misc(struct radeon_device *rdev) 484void r600_pm_misc(struct radeon_device *rdev)
@@ -2320,8 +2471,6 @@ int r600_init(struct radeon_device *rdev)
2320 r = radeon_clocks_init(rdev); 2471 r = radeon_clocks_init(rdev);
2321 if (r) 2472 if (r)
2322 return r; 2473 return r;
2323 /* Initialize power management */
2324 radeon_pm_init(rdev);
2325 /* Fence driver */ 2474 /* Fence driver */
2326 r = radeon_fence_driver_init(rdev); 2475 r = radeon_fence_driver_init(rdev);
2327 if (r) 2476 if (r)
@@ -2386,7 +2535,6 @@ int r600_init(struct radeon_device *rdev)
2386 2535
2387void r600_fini(struct radeon_device *rdev) 2536void r600_fini(struct radeon_device *rdev)
2388{ 2537{
2389 radeon_pm_fini(rdev);
2390 r600_audio_fini(rdev); 2538 r600_audio_fini(rdev);
2391 r600_blit_fini(rdev); 2539 r600_blit_fini(rdev);
2392 r600_cp_fini(rdev); 2540 r600_cp_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 480a83ff54d5..5c9ce2beaca3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -89,7 +89,6 @@ extern int radeon_testing;
89extern int radeon_connector_table; 89extern int radeon_connector_table;
90extern int radeon_tv; 90extern int radeon_tv;
91extern int radeon_new_pll; 91extern int radeon_new_pll;
92extern int radeon_dynpm;
93extern int radeon_audio; 92extern int radeon_audio;
94extern int radeon_disp_priority; 93extern int radeon_disp_priority;
95extern int radeon_hw_i2c; 94extern int radeon_hw_i2c;
@@ -173,11 +172,10 @@ struct radeon_clock {
173int radeon_pm_init(struct radeon_device *rdev); 172int radeon_pm_init(struct radeon_device *rdev);
174void radeon_pm_fini(struct radeon_device *rdev); 173void radeon_pm_fini(struct radeon_device *rdev);
175void radeon_pm_compute_clocks(struct radeon_device *rdev); 174void radeon_pm_compute_clocks(struct radeon_device *rdev);
175void radeon_pm_suspend(struct radeon_device *rdev);
176void radeon_pm_resume(struct radeon_device *rdev);
176void radeon_combios_get_power_modes(struct radeon_device *rdev); 177void radeon_combios_get_power_modes(struct radeon_device *rdev);
177void radeon_atombios_get_power_modes(struct radeon_device *rdev); 178void radeon_atombios_get_power_modes(struct radeon_device *rdev);
178bool radeon_pm_in_vbl(struct radeon_device *rdev);
179bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
180void radeon_sync_with_vblank(struct radeon_device *rdev);
181 179
182/* 180/*
183 * Fences. 181 * Fences.
@@ -608,18 +606,24 @@ struct radeon_wb {
608 * Equation between gpu/memory clock and available bandwidth is hw dependent 606 * Equation between gpu/memory clock and available bandwidth is hw dependent
609 * (type of memory, bus size, efficiency, ...) 607 * (type of memory, bus size, efficiency, ...)
610 */ 608 */
611enum radeon_pm_state { 609
612 PM_STATE_DISABLED, 610enum radeon_pm_method {
613 PM_STATE_MINIMUM, 611 PM_METHOD_PROFILE,
614 PM_STATE_PAUSED, 612 PM_METHOD_DYNPM,
615 PM_STATE_ACTIVE 613};
614
615enum radeon_dynpm_state {
616 DYNPM_STATE_DISABLED,
617 DYNPM_STATE_MINIMUM,
618 DYNPM_STATE_PAUSED,
619 DYNPM_STATE_ACTIVE
616}; 620};
617enum radeon_pm_action { 621enum radeon_dynpm_action {
618 PM_ACTION_NONE, 622 DYNPM_ACTION_NONE,
619 PM_ACTION_MINIMUM, 623 DYNPM_ACTION_MINIMUM,
620 PM_ACTION_DOWNCLOCK, 624 DYNPM_ACTION_DOWNCLOCK,
621 PM_ACTION_UPCLOCK, 625 DYNPM_ACTION_UPCLOCK,
622 PM_ACTION_DEFAULT 626 DYNPM_ACTION_DEFAULT
623}; 627};
624 628
625enum radeon_voltage_type { 629enum radeon_voltage_type {
@@ -637,11 +641,25 @@ enum radeon_pm_state_type {
637 POWER_STATE_TYPE_PERFORMANCE, 641 POWER_STATE_TYPE_PERFORMANCE,
638}; 642};
639 643
640enum radeon_pm_clock_mode_type { 644enum radeon_pm_profile_type {
641 POWER_MODE_TYPE_DEFAULT, 645 PM_PROFILE_DEFAULT,
642 POWER_MODE_TYPE_LOW, 646 PM_PROFILE_AUTO,
643 POWER_MODE_TYPE_MID, 647 PM_PROFILE_LOW,
644 POWER_MODE_TYPE_HIGH, 648 PM_PROFILE_HIGH,
649};
650
651#define PM_PROFILE_DEFAULT_IDX 0
652#define PM_PROFILE_LOW_SH_IDX 1
653#define PM_PROFILE_HIGH_SH_IDX 2
654#define PM_PROFILE_LOW_MH_IDX 3
655#define PM_PROFILE_HIGH_MH_IDX 4
656#define PM_PROFILE_MAX 5
657
658struct radeon_pm_profile {
659 int dpms_off_ps_idx;
660 int dpms_on_ps_idx;
661 int dpms_off_cm_idx;
662 int dpms_on_cm_idx;
645}; 663};
646 664
647struct radeon_voltage { 665struct radeon_voltage {
@@ -696,12 +714,6 @@ struct radeon_power_state {
696 714
697struct radeon_pm { 715struct radeon_pm {
698 struct mutex mutex; 716 struct mutex mutex;
699 struct delayed_work idle_work;
700 enum radeon_pm_state state;
701 enum radeon_pm_action planned_action;
702 unsigned long action_timeout;
703 bool can_upclock;
704 bool can_downclock;
705 u32 active_crtcs; 717 u32 active_crtcs;
706 int active_crtc_count; 718 int active_crtc_count;
707 int req_vblank; 719 int req_vblank;
@@ -731,6 +743,19 @@ struct radeon_pm {
731 u32 current_sclk; 743 u32 current_sclk;
732 u32 current_mclk; 744 u32 current_mclk;
733 struct radeon_i2c_chan *i2c_bus; 745 struct radeon_i2c_chan *i2c_bus;
746 /* selected pm method */
747 enum radeon_pm_method pm_method;
748 /* dynpm power management */
749 struct delayed_work dynpm_idle_work;
750 enum radeon_dynpm_state dynpm_state;
751 enum radeon_dynpm_action dynpm_planned_action;
752 unsigned long dynpm_action_timeout;
753 bool dynpm_can_upclock;
754 bool dynpm_can_downclock;
755 /* profile-based power management */
756 enum radeon_pm_profile_type profile;
757 int profile_index;
758 struct radeon_pm_profile profiles[PM_PROFILE_MAX];
734}; 759};
735 760
736 761
@@ -819,11 +844,12 @@ struct radeon_asic {
819 */ 844 */
820 void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo); 845 void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo);
821 bool (*gui_idle)(struct radeon_device *rdev); 846 bool (*gui_idle)(struct radeon_device *rdev);
822 void (*get_power_state)(struct radeon_device *rdev, enum radeon_pm_action action); 847 /* power management */
823 void (*set_power_state)(struct radeon_device *rdev, bool static_switch);
824 void (*pm_misc)(struct radeon_device *rdev); 848 void (*pm_misc)(struct radeon_device *rdev);
825 void (*pm_prepare)(struct radeon_device *rdev); 849 void (*pm_prepare)(struct radeon_device *rdev);
826 void (*pm_finish)(struct radeon_device *rdev); 850 void (*pm_finish)(struct radeon_device *rdev);
851 void (*pm_init_profile)(struct radeon_device *rdev);
852 void (*pm_get_dynpm_state)(struct radeon_device *rdev);
827}; 853};
828 854
829/* 855/*
@@ -1041,6 +1067,7 @@ struct radeon_device {
1041 uint8_t audio_category_code; 1067 uint8_t audio_category_code;
1042 1068
1043 bool powered_down; 1069 bool powered_down;
1070 struct notifier_block acpi_nb;
1044}; 1071};
1045 1072
1046int radeon_device_init(struct radeon_device *rdev, 1073int radeon_device_init(struct radeon_device *rdev,
@@ -1232,11 +1259,11 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
1232#define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) 1259#define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd))
1233#define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) 1260#define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd))
1234#define radeon_gui_idle(rdev) (rdev)->asic->gui_idle((rdev)) 1261#define radeon_gui_idle(rdev) (rdev)->asic->gui_idle((rdev))
1235#define radeon_get_power_state(rdev, a) (rdev)->asic->get_power_state((rdev), (a))
1236#define radeon_set_power_state(rdev, s) (rdev)->asic->set_power_state((rdev), (s))
1237#define radeon_pm_misc(rdev) (rdev)->asic->pm_misc((rdev)) 1262#define radeon_pm_misc(rdev) (rdev)->asic->pm_misc((rdev))
1238#define radeon_pm_prepare(rdev) (rdev)->asic->pm_prepare((rdev)) 1263#define radeon_pm_prepare(rdev) (rdev)->asic->pm_prepare((rdev))
1239#define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev)) 1264#define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev))
1265#define radeon_pm_init_profile(rdev) (rdev)->asic->pm_init_profile((rdev))
1266#define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm_get_dynpm_state((rdev))
1240 1267
1241/* Common functions */ 1268/* Common functions */
1242/* AGP */ 1269/* AGP */
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 1e6f17bf54fd..e57df08d4aeb 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -166,11 +166,11 @@ static struct radeon_asic r100_asic = {
166 .hpd_set_polarity = &r100_hpd_set_polarity, 166 .hpd_set_polarity = &r100_hpd_set_polarity,
167 .ioctl_wait_idle = NULL, 167 .ioctl_wait_idle = NULL,
168 .gui_idle = &r100_gui_idle, 168 .gui_idle = &r100_gui_idle,
169 .get_power_state = &r100_get_power_state,
170 .set_power_state = &r100_set_power_state,
171 .pm_misc = &r100_pm_misc, 169 .pm_misc = &r100_pm_misc,
172 .pm_prepare = &r100_pm_prepare, 170 .pm_prepare = &r100_pm_prepare,
173 .pm_finish = &r100_pm_finish, 171 .pm_finish = &r100_pm_finish,
172 .pm_init_profile = &r100_pm_init_profile,
173 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
174}; 174};
175 175
176static struct radeon_asic r200_asic = { 176static struct radeon_asic r200_asic = {
@@ -210,11 +210,11 @@ static struct radeon_asic r200_asic = {
210 .hpd_set_polarity = &r100_hpd_set_polarity, 210 .hpd_set_polarity = &r100_hpd_set_polarity,
211 .ioctl_wait_idle = NULL, 211 .ioctl_wait_idle = NULL,
212 .gui_idle = &r100_gui_idle, 212 .gui_idle = &r100_gui_idle,
213 .get_power_state = &r100_get_power_state,
214 .set_power_state = &r100_set_power_state,
215 .pm_misc = &r100_pm_misc, 213 .pm_misc = &r100_pm_misc,
216 .pm_prepare = &r100_pm_prepare, 214 .pm_prepare = &r100_pm_prepare,
217 .pm_finish = &r100_pm_finish, 215 .pm_finish = &r100_pm_finish,
216 .pm_init_profile = &r100_pm_init_profile,
217 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
218}; 218};
219 219
220static struct radeon_asic r300_asic = { 220static struct radeon_asic r300_asic = {
@@ -255,11 +255,11 @@ static struct radeon_asic r300_asic = {
255 .hpd_set_polarity = &r100_hpd_set_polarity, 255 .hpd_set_polarity = &r100_hpd_set_polarity,
256 .ioctl_wait_idle = NULL, 256 .ioctl_wait_idle = NULL,
257 .gui_idle = &r100_gui_idle, 257 .gui_idle = &r100_gui_idle,
258 .get_power_state = &r100_get_power_state,
259 .set_power_state = &r100_set_power_state,
260 .pm_misc = &r100_pm_misc, 258 .pm_misc = &r100_pm_misc,
261 .pm_prepare = &r100_pm_prepare, 259 .pm_prepare = &r100_pm_prepare,
262 .pm_finish = &r100_pm_finish, 260 .pm_finish = &r100_pm_finish,
261 .pm_init_profile = &r100_pm_init_profile,
262 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
263}; 263};
264 264
265static struct radeon_asic r300_asic_pcie = { 265static struct radeon_asic r300_asic_pcie = {
@@ -299,11 +299,11 @@ static struct radeon_asic r300_asic_pcie = {
299 .hpd_set_polarity = &r100_hpd_set_polarity, 299 .hpd_set_polarity = &r100_hpd_set_polarity,
300 .ioctl_wait_idle = NULL, 300 .ioctl_wait_idle = NULL,
301 .gui_idle = &r100_gui_idle, 301 .gui_idle = &r100_gui_idle,
302 .get_power_state = &r100_get_power_state,
303 .set_power_state = &r100_set_power_state,
304 .pm_misc = &r100_pm_misc, 302 .pm_misc = &r100_pm_misc,
305 .pm_prepare = &r100_pm_prepare, 303 .pm_prepare = &r100_pm_prepare,
306 .pm_finish = &r100_pm_finish, 304 .pm_finish = &r100_pm_finish,
305 .pm_init_profile = &r100_pm_init_profile,
306 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
307}; 307};
308 308
309static struct radeon_asic r420_asic = { 309static struct radeon_asic r420_asic = {
@@ -344,11 +344,11 @@ static struct radeon_asic r420_asic = {
344 .hpd_set_polarity = &r100_hpd_set_polarity, 344 .hpd_set_polarity = &r100_hpd_set_polarity,
345 .ioctl_wait_idle = NULL, 345 .ioctl_wait_idle = NULL,
346 .gui_idle = &r100_gui_idle, 346 .gui_idle = &r100_gui_idle,
347 .get_power_state = &r100_get_power_state,
348 .set_power_state = &r100_set_power_state,
349 .pm_misc = &r100_pm_misc, 347 .pm_misc = &r100_pm_misc,
350 .pm_prepare = &r100_pm_prepare, 348 .pm_prepare = &r100_pm_prepare,
351 .pm_finish = &r100_pm_finish, 349 .pm_finish = &r100_pm_finish,
350 .pm_init_profile = &r420_pm_init_profile,
351 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
352}; 352};
353 353
354static struct radeon_asic rs400_asic = { 354static struct radeon_asic rs400_asic = {
@@ -389,11 +389,11 @@ static struct radeon_asic rs400_asic = {
389 .hpd_set_polarity = &r100_hpd_set_polarity, 389 .hpd_set_polarity = &r100_hpd_set_polarity,
390 .ioctl_wait_idle = NULL, 390 .ioctl_wait_idle = NULL,
391 .gui_idle = &r100_gui_idle, 391 .gui_idle = &r100_gui_idle,
392 .get_power_state = &r100_get_power_state,
393 .set_power_state = &r100_set_power_state,
394 .pm_misc = &r100_pm_misc, 392 .pm_misc = &r100_pm_misc,
395 .pm_prepare = &r100_pm_prepare, 393 .pm_prepare = &r100_pm_prepare,
396 .pm_finish = &r100_pm_finish, 394 .pm_finish = &r100_pm_finish,
395 .pm_init_profile = &r100_pm_init_profile,
396 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
397}; 397};
398 398
399static struct radeon_asic rs600_asic = { 399static struct radeon_asic rs600_asic = {
@@ -434,11 +434,11 @@ static struct radeon_asic rs600_asic = {
434 .hpd_set_polarity = &rs600_hpd_set_polarity, 434 .hpd_set_polarity = &rs600_hpd_set_polarity,
435 .ioctl_wait_idle = NULL, 435 .ioctl_wait_idle = NULL,
436 .gui_idle = &r100_gui_idle, 436 .gui_idle = &r100_gui_idle,
437 .get_power_state = &r100_get_power_state,
438 .set_power_state = &r100_set_power_state,
439 .pm_misc = &rs600_pm_misc, 437 .pm_misc = &rs600_pm_misc,
440 .pm_prepare = &rs600_pm_prepare, 438 .pm_prepare = &rs600_pm_prepare,
441 .pm_finish = &rs600_pm_finish, 439 .pm_finish = &rs600_pm_finish,
440 .pm_init_profile = &r420_pm_init_profile,
441 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
442}; 442};
443 443
444static struct radeon_asic rs690_asic = { 444static struct radeon_asic rs690_asic = {
@@ -479,11 +479,11 @@ static struct radeon_asic rs690_asic = {
479 .hpd_set_polarity = &rs600_hpd_set_polarity, 479 .hpd_set_polarity = &rs600_hpd_set_polarity,
480 .ioctl_wait_idle = NULL, 480 .ioctl_wait_idle = NULL,
481 .gui_idle = &r100_gui_idle, 481 .gui_idle = &r100_gui_idle,
482 .get_power_state = &r100_get_power_state,
483 .set_power_state = &r100_set_power_state,
484 .pm_misc = &rs600_pm_misc, 482 .pm_misc = &rs600_pm_misc,
485 .pm_prepare = &rs600_pm_prepare, 483 .pm_prepare = &rs600_pm_prepare,
486 .pm_finish = &rs600_pm_finish, 484 .pm_finish = &rs600_pm_finish,
485 .pm_init_profile = &r420_pm_init_profile,
486 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
487}; 487};
488 488
489static struct radeon_asic rv515_asic = { 489static struct radeon_asic rv515_asic = {
@@ -524,11 +524,11 @@ static struct radeon_asic rv515_asic = {
524 .hpd_set_polarity = &rs600_hpd_set_polarity, 524 .hpd_set_polarity = &rs600_hpd_set_polarity,
525 .ioctl_wait_idle = NULL, 525 .ioctl_wait_idle = NULL,
526 .gui_idle = &r100_gui_idle, 526 .gui_idle = &r100_gui_idle,
527 .get_power_state = &r100_get_power_state,
528 .set_power_state = &r100_set_power_state,
529 .pm_misc = &rs600_pm_misc, 527 .pm_misc = &rs600_pm_misc,
530 .pm_prepare = &rs600_pm_prepare, 528 .pm_prepare = &rs600_pm_prepare,
531 .pm_finish = &rs600_pm_finish, 529 .pm_finish = &rs600_pm_finish,
530 .pm_init_profile = &r420_pm_init_profile,
531 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
532}; 532};
533 533
534static struct radeon_asic r520_asic = { 534static struct radeon_asic r520_asic = {
@@ -569,11 +569,11 @@ static struct radeon_asic r520_asic = {
569 .hpd_set_polarity = &rs600_hpd_set_polarity, 569 .hpd_set_polarity = &rs600_hpd_set_polarity,
570 .ioctl_wait_idle = NULL, 570 .ioctl_wait_idle = NULL,
571 .gui_idle = &r100_gui_idle, 571 .gui_idle = &r100_gui_idle,
572 .get_power_state = &r100_get_power_state,
573 .set_power_state = &r100_set_power_state,
574 .pm_misc = &rs600_pm_misc, 572 .pm_misc = &rs600_pm_misc,
575 .pm_prepare = &rs600_pm_prepare, 573 .pm_prepare = &rs600_pm_prepare,
576 .pm_finish = &rs600_pm_finish, 574 .pm_finish = &rs600_pm_finish,
575 .pm_init_profile = &r420_pm_init_profile,
576 .pm_get_dynpm_state = &r100_pm_get_dynpm_state,
577}; 577};
578 578
579static struct radeon_asic r600_asic = { 579static struct radeon_asic r600_asic = {
@@ -613,11 +613,11 @@ static struct radeon_asic r600_asic = {
613 .hpd_set_polarity = &r600_hpd_set_polarity, 613 .hpd_set_polarity = &r600_hpd_set_polarity,
614 .ioctl_wait_idle = r600_ioctl_wait_idle, 614 .ioctl_wait_idle = r600_ioctl_wait_idle,
615 .gui_idle = &r600_gui_idle, 615 .gui_idle = &r600_gui_idle,
616 .get_power_state = &r600_get_power_state,
617 .set_power_state = &r600_set_power_state,
618 .pm_misc = &r600_pm_misc, 616 .pm_misc = &r600_pm_misc,
619 .pm_prepare = &rs600_pm_prepare, 617 .pm_prepare = &rs600_pm_prepare,
620 .pm_finish = &rs600_pm_finish, 618 .pm_finish = &rs600_pm_finish,
619 .pm_init_profile = &r600_pm_init_profile,
620 .pm_get_dynpm_state = &r600_pm_get_dynpm_state,
621}; 621};
622 622
623static struct radeon_asic rs780_asic = { 623static struct radeon_asic rs780_asic = {
@@ -657,11 +657,11 @@ static struct radeon_asic rs780_asic = {
657 .hpd_set_polarity = &r600_hpd_set_polarity, 657 .hpd_set_polarity = &r600_hpd_set_polarity,
658 .ioctl_wait_idle = r600_ioctl_wait_idle, 658 .ioctl_wait_idle = r600_ioctl_wait_idle,
659 .gui_idle = &r600_gui_idle, 659 .gui_idle = &r600_gui_idle,
660 .get_power_state = &r600_get_power_state,
661 .set_power_state = &r600_set_power_state,
662 .pm_misc = &r600_pm_misc, 660 .pm_misc = &r600_pm_misc,
663 .pm_prepare = &rs600_pm_prepare, 661 .pm_prepare = &rs600_pm_prepare,
664 .pm_finish = &rs600_pm_finish, 662 .pm_finish = &rs600_pm_finish,
663 .pm_init_profile = &rs780_pm_init_profile,
664 .pm_get_dynpm_state = &r600_pm_get_dynpm_state,
665}; 665};
666 666
667static struct radeon_asic rv770_asic = { 667static struct radeon_asic rv770_asic = {
@@ -701,11 +701,11 @@ static struct radeon_asic rv770_asic = {
701 .hpd_set_polarity = &r600_hpd_set_polarity, 701 .hpd_set_polarity = &r600_hpd_set_polarity,
702 .ioctl_wait_idle = r600_ioctl_wait_idle, 702 .ioctl_wait_idle = r600_ioctl_wait_idle,
703 .gui_idle = &r600_gui_idle, 703 .gui_idle = &r600_gui_idle,
704 .get_power_state = &r600_get_power_state,
705 .set_power_state = &r600_set_power_state,
706 .pm_misc = &rv770_pm_misc, 704 .pm_misc = &rv770_pm_misc,
707 .pm_prepare = &rs600_pm_prepare, 705 .pm_prepare = &rs600_pm_prepare,
708 .pm_finish = &rs600_pm_finish, 706 .pm_finish = &rs600_pm_finish,
707 .pm_init_profile = &r600_pm_init_profile,
708 .pm_get_dynpm_state = &r600_pm_get_dynpm_state,
709}; 709};
710 710
711static struct radeon_asic evergreen_asic = { 711static struct radeon_asic evergreen_asic = {
@@ -743,11 +743,11 @@ static struct radeon_asic evergreen_asic = {
743 .hpd_sense = &evergreen_hpd_sense, 743 .hpd_sense = &evergreen_hpd_sense,
744 .hpd_set_polarity = &evergreen_hpd_set_polarity, 744 .hpd_set_polarity = &evergreen_hpd_set_polarity,
745 .gui_idle = &r600_gui_idle, 745 .gui_idle = &r600_gui_idle,
746 .get_power_state = &r600_get_power_state,
747 .set_power_state = &r600_set_power_state,
748 .pm_misc = &evergreen_pm_misc, 746 .pm_misc = &evergreen_pm_misc,
749 .pm_prepare = &evergreen_pm_prepare, 747 .pm_prepare = &evergreen_pm_prepare,
750 .pm_finish = &evergreen_pm_finish, 748 .pm_finish = &evergreen_pm_finish,
749 .pm_init_profile = &r600_pm_init_profile,
750 .pm_get_dynpm_state = &r600_pm_get_dynpm_state,
751}; 751};
752 752
753int radeon_asic_init(struct radeon_device *rdev) 753int radeon_asic_init(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 8a1278629994..5c40a3dfaca2 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -127,12 +127,11 @@ void r100_enable_bm(struct radeon_device *rdev);
127void r100_set_common_regs(struct radeon_device *rdev); 127void r100_set_common_regs(struct radeon_device *rdev);
128void r100_bm_disable(struct radeon_device *rdev); 128void r100_bm_disable(struct radeon_device *rdev);
129extern bool r100_gui_idle(struct radeon_device *rdev); 129extern bool r100_gui_idle(struct radeon_device *rdev);
130extern void r100_set_power_state(struct radeon_device *rdev, bool static_switch);
131extern void r100_get_power_state(struct radeon_device *rdev,
132 enum radeon_pm_action action);
133extern void r100_pm_misc(struct radeon_device *rdev); 130extern void r100_pm_misc(struct radeon_device *rdev);
134extern void r100_pm_prepare(struct radeon_device *rdev); 131extern void r100_pm_prepare(struct radeon_device *rdev);
135extern void r100_pm_finish(struct radeon_device *rdev); 132extern void r100_pm_finish(struct radeon_device *rdev);
133extern void r100_pm_init_profile(struct radeon_device *rdev);
134extern void r100_pm_get_dynpm_state(struct radeon_device *rdev);
136 135
137/* 136/*
138 * r200,rv250,rs300,rv280 137 * r200,rv250,rs300,rv280
@@ -170,6 +169,7 @@ extern int r420_init(struct radeon_device *rdev);
170extern void r420_fini(struct radeon_device *rdev); 169extern void r420_fini(struct radeon_device *rdev);
171extern int r420_suspend(struct radeon_device *rdev); 170extern int r420_suspend(struct radeon_device *rdev);
172extern int r420_resume(struct radeon_device *rdev); 171extern int r420_resume(struct radeon_device *rdev);
172extern void r420_pm_init_profile(struct radeon_device *rdev);
173 173
174/* 174/*
175 * rs400,rs480 175 * rs400,rs480
@@ -281,10 +281,10 @@ void r600_hpd_set_polarity(struct radeon_device *rdev,
281 enum radeon_hpd_id hpd); 281 enum radeon_hpd_id hpd);
282extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo); 282extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo);
283extern bool r600_gui_idle(struct radeon_device *rdev); 283extern bool r600_gui_idle(struct radeon_device *rdev);
284extern void r600_set_power_state(struct radeon_device *rdev, bool static_switch);
285extern void r600_get_power_state(struct radeon_device *rdev,
286 enum radeon_pm_action action);
287extern void r600_pm_misc(struct radeon_device *rdev); 284extern void r600_pm_misc(struct radeon_device *rdev);
285extern void r600_pm_init_profile(struct radeon_device *rdev);
286extern void rs780_pm_init_profile(struct radeon_device *rdev);
287extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
288 288
289/* 289/*
290 * rv770,rv730,rv710,rv740 290 * rv770,rv730,rv710,rv740
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index e249da81dbfc..a20b612ffe75 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -748,6 +748,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
748 748
749 radeon_save_bios_scratch_regs(rdev); 749 radeon_save_bios_scratch_regs(rdev);
750 750
751 radeon_pm_suspend(rdev);
751 radeon_suspend(rdev); 752 radeon_suspend(rdev);
752 radeon_hpd_fini(rdev); 753 radeon_hpd_fini(rdev);
753 /* evict remaining vram memory */ 754 /* evict remaining vram memory */
@@ -783,6 +784,7 @@ int radeon_resume_kms(struct drm_device *dev)
783 /* resume AGP if in use */ 784 /* resume AGP if in use */
784 radeon_agp_resume(rdev); 785 radeon_agp_resume(rdev);
785 radeon_resume(rdev); 786 radeon_resume(rdev);
787 radeon_pm_resume(rdev);
786 radeon_restore_bios_scratch_regs(rdev); 788 radeon_restore_bios_scratch_regs(rdev);
787 radeon_fbdev_set_suspend(rdev, 0); 789 radeon_fbdev_set_suspend(rdev, 0);
788 release_console_sem(); 790 release_console_sem();
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 10d70540fc50..f48f42454fbb 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1037,6 +1037,9 @@ int radeon_modeset_init(struct radeon_device *rdev)
1037 /* initialize hpd */ 1037 /* initialize hpd */
1038 radeon_hpd_init(rdev); 1038 radeon_hpd_init(rdev);
1039 1039
1040 /* Initialize power management */
1041 radeon_pm_init(rdev);
1042
1040 radeon_fbdev_init(rdev); 1043 radeon_fbdev_init(rdev);
1041 drm_kms_helper_poll_init(rdev->ddev); 1044 drm_kms_helper_poll_init(rdev->ddev);
1042 1045
@@ -1047,6 +1050,7 @@ void radeon_modeset_fini(struct radeon_device *rdev)
1047{ 1050{
1048 radeon_fbdev_fini(rdev); 1051 radeon_fbdev_fini(rdev);
1049 kfree(rdev->mode_info.bios_hardcoded_edid); 1052 kfree(rdev->mode_info.bios_hardcoded_edid);
1053 radeon_pm_fini(rdev);
1050 1054
1051 if (rdev->mode_info.mode_config_initialized) { 1055 if (rdev->mode_info.mode_config_initialized) {
1052 drm_kms_helper_poll_fini(rdev->ddev); 1056 drm_kms_helper_poll_fini(rdev->ddev);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 6e22815f7f07..4afba1eca2a7 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -92,7 +92,6 @@ int radeon_testing = 0;
92int radeon_connector_table = 0; 92int radeon_connector_table = 0;
93int radeon_tv = 1; 93int radeon_tv = 1;
94int radeon_new_pll = -1; 94int radeon_new_pll = -1;
95int radeon_dynpm = -1;
96int radeon_audio = 1; 95int radeon_audio = 1;
97int radeon_disp_priority = 0; 96int radeon_disp_priority = 0;
98int radeon_hw_i2c = 0; 97int radeon_hw_i2c = 0;
@@ -133,9 +132,6 @@ module_param_named(tv, radeon_tv, int, 0444);
133MODULE_PARM_DESC(new_pll, "Select new PLL code"); 132MODULE_PARM_DESC(new_pll, "Select new PLL code");
134module_param_named(new_pll, radeon_new_pll, int, 0444); 133module_param_named(new_pll, radeon_new_pll, int, 0444);
135 134
136MODULE_PARM_DESC(dynpm, "Disable/Enable dynamic power management (1 = enable)");
137module_param_named(dynpm, radeon_dynpm, int, 0444);
138
139MODULE_PARM_DESC(audio, "Audio enable (0 = disable)"); 135MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
140module_param_named(audio, radeon_audio, int, 0444); 136module_param_named(audio, radeon_audio, int, 0444);
141 137
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 0dfa508fe5f2..1827317704a2 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -23,14 +23,98 @@
23#include "drmP.h" 23#include "drmP.h"
24#include "radeon.h" 24#include "radeon.h"
25#include "avivod.h" 25#include "avivod.h"
26#ifdef CONFIG_ACPI
27#include <linux/acpi.h>
28#endif
29#include <linux/power_supply.h>
26 30
27#define RADEON_IDLE_LOOP_MS 100 31#define RADEON_IDLE_LOOP_MS 100
28#define RADEON_RECLOCK_DELAY_MS 200 32#define RADEON_RECLOCK_DELAY_MS 200
29#define RADEON_WAIT_VBLANK_TIMEOUT 200 33#define RADEON_WAIT_VBLANK_TIMEOUT 200
30#define RADEON_WAIT_IDLE_TIMEOUT 200 34#define RADEON_WAIT_IDLE_TIMEOUT 200
31 35
32static void radeon_pm_idle_work_handler(struct work_struct *work); 36static void radeon_dynpm_idle_work_handler(struct work_struct *work);
33static int radeon_debugfs_pm_init(struct radeon_device *rdev); 37static int radeon_debugfs_pm_init(struct radeon_device *rdev);
38static bool radeon_pm_in_vbl(struct radeon_device *rdev);
39static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
40static void radeon_pm_update_profile(struct radeon_device *rdev);
41static void radeon_pm_set_clocks(struct radeon_device *rdev);
42
43#define ACPI_AC_CLASS "ac_adapter"
44
45#ifdef CONFIG_ACPI
46static int radeon_acpi_event(struct notifier_block *nb,
47 unsigned long val,
48 void *data)
49{
50 struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb);
51 struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
52
53 if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
54 if (power_supply_is_system_supplied() > 0)
55 DRM_INFO("pm: AC\n");
56 else
57 DRM_INFO("pm: DC\n");
58
59 if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
60 if (rdev->pm.profile == PM_PROFILE_AUTO) {
61 mutex_lock(&rdev->pm.mutex);
62 radeon_pm_update_profile(rdev);
63 radeon_pm_set_clocks(rdev);
64 mutex_unlock(&rdev->pm.mutex);
65 }
66 }
67 }
68
69 return NOTIFY_OK;
70}
71#endif
72
73static void radeon_pm_update_profile(struct radeon_device *rdev)
74{
75 switch (rdev->pm.profile) {
76 case PM_PROFILE_DEFAULT:
77 rdev->pm.profile_index = PM_PROFILE_DEFAULT_IDX;
78 break;
79 case PM_PROFILE_AUTO:
80 if (power_supply_is_system_supplied() > 0) {
81 if (rdev->pm.active_crtc_count > 1)
82 rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX;
83 else
84 rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX;
85 } else {
86 if (rdev->pm.active_crtc_count > 1)
87 rdev->pm.profile_index = PM_PROFILE_LOW_MH_IDX;
88 else
89 rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX;
90 }
91 break;
92 case PM_PROFILE_LOW:
93 if (rdev->pm.active_crtc_count > 1)
94 rdev->pm.profile_index = PM_PROFILE_LOW_MH_IDX;
95 else
96 rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX;
97 break;
98 case PM_PROFILE_HIGH:
99 if (rdev->pm.active_crtc_count > 1)
100 rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX;
101 else
102 rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX;
103 break;
104 }
105
106 if (rdev->pm.active_crtc_count == 0) {
107 rdev->pm.requested_power_state_index =
108 rdev->pm.profiles[rdev->pm.profile_index].dpms_off_ps_idx;
109 rdev->pm.requested_clock_mode_index =
110 rdev->pm.profiles[rdev->pm.profile_index].dpms_off_cm_idx;
111 } else {
112 rdev->pm.requested_power_state_index =
113 rdev->pm.profiles[rdev->pm.profile_index].dpms_on_ps_idx;
114 rdev->pm.requested_clock_mode_index =
115 rdev->pm.profiles[rdev->pm.profile_index].dpms_on_cm_idx;
116 }
117}
34 118
35static void radeon_unmap_vram_bos(struct radeon_device *rdev) 119static void radeon_unmap_vram_bos(struct radeon_device *rdev)
36{ 120{
@@ -54,12 +138,93 @@ static void radeon_unmap_vram_bos(struct radeon_device *rdev)
54 ttm_bo_unmap_virtual(&rdev->r600_blit.shader_obj->tbo); 138 ttm_bo_unmap_virtual(&rdev->r600_blit.shader_obj->tbo);
55} 139}
56 140
57static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch) 141static void radeon_sync_with_vblank(struct radeon_device *rdev)
58{ 142{
59 int i; 143 if (rdev->pm.active_crtcs) {
144 rdev->pm.vblank_sync = false;
145 wait_event_timeout(
146 rdev->irq.vblank_queue, rdev->pm.vblank_sync,
147 msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
148 }
149}
150
151static void radeon_set_power_state(struct radeon_device *rdev)
152{
153 u32 sclk, mclk;
154
155 if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&
156 (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
157 return;
158
159 if (radeon_gui_idle(rdev)) {
160 sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
161 clock_info[rdev->pm.requested_clock_mode_index].sclk;
162 if (sclk > rdev->clock.default_sclk)
163 sclk = rdev->clock.default_sclk;
164
165 mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
166 clock_info[rdev->pm.requested_clock_mode_index].mclk;
167 if (mclk > rdev->clock.default_mclk)
168 mclk = rdev->clock.default_mclk;
169
170 /* voltage, pcie lanes, etc.*/
171 radeon_pm_misc(rdev);
172
173 if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
174 radeon_sync_with_vblank(rdev);
175
176 if (!radeon_pm_in_vbl(rdev))
177 return;
178
179 radeon_pm_prepare(rdev);
180 /* set engine clock */
181 if (sclk != rdev->pm.current_sclk) {
182 radeon_pm_debug_check_in_vbl(rdev, false);
183 radeon_set_engine_clock(rdev, sclk);
184 radeon_pm_debug_check_in_vbl(rdev, true);
185 rdev->pm.current_sclk = sclk;
186 DRM_INFO("Setting: e: %d\n", sclk);
187 }
188
189 /* set memory clock */
190 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
191 radeon_pm_debug_check_in_vbl(rdev, false);
192 radeon_set_memory_clock(rdev, mclk);
193 radeon_pm_debug_check_in_vbl(rdev, true);
194 rdev->pm.current_mclk = mclk;
195 DRM_INFO("Setting: m: %d\n", mclk);
196 }
197 radeon_pm_finish(rdev);
198 } else {
199 /* set engine clock */
200 if (sclk != rdev->pm.current_sclk) {
201 radeon_sync_with_vblank(rdev);
202 radeon_pm_prepare(rdev);
203 radeon_set_engine_clock(rdev, sclk);
204 radeon_pm_finish(rdev);
205 rdev->pm.current_sclk = sclk;
206 DRM_INFO("Setting: e: %d\n", sclk);
207 }
208 /* set memory clock */
209 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
210 radeon_sync_with_vblank(rdev);
211 radeon_pm_prepare(rdev);
212 radeon_set_memory_clock(rdev, mclk);
213 radeon_pm_finish(rdev);
214 rdev->pm.current_mclk = mclk;
215 DRM_INFO("Setting: m: %d\n", mclk);
216 }
217 }
60 218
61 if (rdev->pm.state != PM_STATE_DISABLED) 219 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
62 radeon_get_power_state(rdev, rdev->pm.planned_action); 220 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
221 } else
222 DRM_INFO("pm: GUI not idle!!!\n");
223}
224
225static void radeon_pm_set_clocks(struct radeon_device *rdev)
226{
227 int i;
63 228
64 mutex_lock(&rdev->ddev->struct_mutex); 229 mutex_lock(&rdev->ddev->struct_mutex);
65 mutex_lock(&rdev->vram_mutex); 230 mutex_lock(&rdev->vram_mutex);
@@ -67,27 +232,31 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
67 232
68 /* gui idle int has issues on older chips it seems */ 233 /* gui idle int has issues on older chips it seems */
69 if (rdev->family >= CHIP_R600) { 234 if (rdev->family >= CHIP_R600) {
70 /* wait for GPU idle */ 235 if (rdev->irq.installed) {
71 rdev->pm.gui_idle = false; 236 /* wait for GPU idle */
72 rdev->irq.gui_idle = true; 237 rdev->pm.gui_idle = false;
73 radeon_irq_set(rdev); 238 rdev->irq.gui_idle = true;
74 wait_event_interruptible_timeout( 239 radeon_irq_set(rdev);
75 rdev->irq.idle_queue, rdev->pm.gui_idle, 240 wait_event_interruptible_timeout(
76 msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); 241 rdev->irq.idle_queue, rdev->pm.gui_idle,
77 rdev->irq.gui_idle = false; 242 msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT));
78 radeon_irq_set(rdev); 243 rdev->irq.gui_idle = false;
244 radeon_irq_set(rdev);
245 }
79 } else { 246 } else {
80 struct radeon_fence *fence; 247 if (rdev->cp.ready) {
81 radeon_ring_alloc(rdev, 64); 248 struct radeon_fence *fence;
82 radeon_fence_create(rdev, &fence); 249 radeon_ring_alloc(rdev, 64);
83 radeon_fence_emit(rdev, fence); 250 radeon_fence_create(rdev, &fence);
84 radeon_ring_commit(rdev); 251 radeon_fence_emit(rdev, fence);
85 radeon_fence_wait(fence, false); 252 radeon_ring_commit(rdev);
86 radeon_fence_unref(&fence); 253 radeon_fence_wait(fence, false);
254 radeon_fence_unref(&fence);
255 }
87 } 256 }
88 radeon_unmap_vram_bos(rdev); 257 radeon_unmap_vram_bos(rdev);
89 258
90 if (!static_switch) { 259 if (rdev->irq.installed) {
91 for (i = 0; i < rdev->num_crtc; i++) { 260 for (i = 0; i < rdev->num_crtc; i++) {
92 if (rdev->pm.active_crtcs & (1 << i)) { 261 if (rdev->pm.active_crtcs & (1 << i)) {
93 rdev->pm.req_vblank |= (1 << i); 262 rdev->pm.req_vblank |= (1 << i);
@@ -96,9 +265,9 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
96 } 265 }
97 } 266 }
98 267
99 radeon_set_power_state(rdev, static_switch); 268 radeon_set_power_state(rdev);
100 269
101 if (!static_switch) { 270 if (rdev->irq.installed) {
102 for (i = 0; i < rdev->num_crtc; i++) { 271 for (i = 0; i < rdev->num_crtc; i++) {
103 if (rdev->pm.req_vblank & (1 << i)) { 272 if (rdev->pm.req_vblank & (1 << i)) {
104 rdev->pm.req_vblank &= ~(1 << i); 273 rdev->pm.req_vblank &= ~(1 << i);
@@ -112,230 +281,195 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch)
112 if (rdev->pm.active_crtc_count) 281 if (rdev->pm.active_crtc_count)
113 radeon_bandwidth_update(rdev); 282 radeon_bandwidth_update(rdev);
114 283
115 rdev->pm.planned_action = PM_ACTION_NONE; 284 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
116 285
117 mutex_unlock(&rdev->cp.mutex); 286 mutex_unlock(&rdev->cp.mutex);
118 mutex_unlock(&rdev->vram_mutex); 287 mutex_unlock(&rdev->vram_mutex);
119 mutex_unlock(&rdev->ddev->struct_mutex); 288 mutex_unlock(&rdev->ddev->struct_mutex);
120} 289}
121 290
122static ssize_t radeon_get_power_state_static(struct device *dev, 291static ssize_t radeon_get_pm_profile(struct device *dev,
123 struct device_attribute *attr, 292 struct device_attribute *attr,
124 char *buf) 293 char *buf)
125{ 294{
126 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); 295 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
127 struct radeon_device *rdev = ddev->dev_private; 296 struct radeon_device *rdev = ddev->dev_private;
297 int cp = rdev->pm.profile;
128 298
129 return snprintf(buf, PAGE_SIZE, "%d.%d\n", rdev->pm.current_power_state_index, 299 return snprintf(buf, PAGE_SIZE, "%s\n",
130 rdev->pm.current_clock_mode_index); 300 (cp == PM_PROFILE_AUTO) ? "auto" :
301 (cp == PM_PROFILE_LOW) ? "low" :
302 (cp == PM_PROFILE_HIGH) ? "high" : "default");
131} 303}
132 304
133static ssize_t radeon_set_power_state_static(struct device *dev, 305static ssize_t radeon_set_pm_profile(struct device *dev,
134 struct device_attribute *attr, 306 struct device_attribute *attr,
135 const char *buf, 307 const char *buf,
136 size_t count) 308 size_t count)
137{ 309{
138 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); 310 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
139 struct radeon_device *rdev = ddev->dev_private; 311 struct radeon_device *rdev = ddev->dev_private;
140 int ps, cm;
141
142 if (sscanf(buf, "%u.%u", &ps, &cm) != 2) {
143 DRM_ERROR("Invalid power state!\n");
144 return count;
145 }
146 312
147 mutex_lock(&rdev->pm.mutex); 313 mutex_lock(&rdev->pm.mutex);
148 if ((ps >= 0) && (ps < rdev->pm.num_power_states) && 314 if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
149 (cm >= 0) && (cm < rdev->pm.power_state[ps].num_clock_modes)) { 315 if (strncmp("default", buf, strlen("default")) == 0)
150 if ((rdev->pm.active_crtc_count > 0) && 316 rdev->pm.profile = PM_PROFILE_DEFAULT;
151 (rdev->pm.power_state[ps].clock_info[cm].flags & RADEON_PM_MODE_NO_DISPLAY)) { 317 else if (strncmp("auto", buf, strlen("auto")) == 0)
152 DRM_ERROR("Invalid power state for display: %d.%d\n", ps, cm); 318 rdev->pm.profile = PM_PROFILE_AUTO;
153 } else if ((rdev->pm.active_crtc_count > 1) && 319 else if (strncmp("low", buf, strlen("low")) == 0)
154 (rdev->pm.power_state[ps].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)) { 320 rdev->pm.profile = PM_PROFILE_LOW;
155 DRM_ERROR("Invalid power state for multi-head: %d.%d\n", ps, cm); 321 else if (strncmp("high", buf, strlen("high")) == 0)
156 } else { 322 rdev->pm.profile = PM_PROFILE_HIGH;
157 /* disable dynpm */ 323 else {
158 rdev->pm.state = PM_STATE_DISABLED; 324 DRM_ERROR("invalid power profile!\n");
159 rdev->pm.planned_action = PM_ACTION_NONE; 325 goto fail;
160 rdev->pm.requested_power_state_index = ps;
161 rdev->pm.requested_clock_mode_index = cm;
162 radeon_pm_set_clocks(rdev, true);
163 } 326 }
164 } else 327 radeon_pm_update_profile(rdev);
165 DRM_ERROR("Invalid power state: %d.%d\n\n", ps, cm); 328 radeon_pm_set_clocks(rdev);
329 }
330fail:
166 mutex_unlock(&rdev->pm.mutex); 331 mutex_unlock(&rdev->pm.mutex);
167 332
168 return count; 333 return count;
169} 334}
170 335
171static ssize_t radeon_get_dynpm(struct device *dev, 336static ssize_t radeon_get_pm_method(struct device *dev,
172 struct device_attribute *attr, 337 struct device_attribute *attr,
173 char *buf) 338 char *buf)
174{ 339{
175 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); 340 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
176 struct radeon_device *rdev = ddev->dev_private; 341 struct radeon_device *rdev = ddev->dev_private;
342 int pm = rdev->pm.pm_method;
177 343
178 return snprintf(buf, PAGE_SIZE, "%s\n", 344 return snprintf(buf, PAGE_SIZE, "%s\n",
179 (rdev->pm.state == PM_STATE_DISABLED) ? "disabled" : "enabled"); 345 (pm == PM_METHOD_DYNPM) ? "dynpm" : "profile");
180} 346}
181 347
182static ssize_t radeon_set_dynpm(struct device *dev, 348static ssize_t radeon_set_pm_method(struct device *dev,
183 struct device_attribute *attr, 349 struct device_attribute *attr,
184 const char *buf, 350 const char *buf,
185 size_t count) 351 size_t count)
186{ 352{
187 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); 353 struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
188 struct radeon_device *rdev = ddev->dev_private; 354 struct radeon_device *rdev = ddev->dev_private;
189 int tmp = simple_strtoul(buf, NULL, 10);
190 355
191 if (tmp == 0) { 356
192 /* update power mode info */ 357 if (strncmp("dynpm", buf, strlen("dynpm")) == 0) {
193 radeon_pm_compute_clocks(rdev);
194 /* disable dynpm */
195 mutex_lock(&rdev->pm.mutex); 358 mutex_lock(&rdev->pm.mutex);
196 rdev->pm.state = PM_STATE_DISABLED; 359 rdev->pm.pm_method = PM_METHOD_DYNPM;
197 rdev->pm.planned_action = PM_ACTION_NONE; 360 rdev->pm.dynpm_state = DYNPM_STATE_PAUSED;
361 rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT;
198 mutex_unlock(&rdev->pm.mutex); 362 mutex_unlock(&rdev->pm.mutex);
199 DRM_INFO("radeon: dynamic power management disabled\n"); 363 } else if (strncmp("profile", buf, strlen("profile")) == 0) {
200 } else if (tmp == 1) { 364 mutex_lock(&rdev->pm.mutex);
201 if (rdev->pm.num_power_states > 1) { 365 rdev->pm.pm_method = PM_METHOD_PROFILE;
202 /* enable dynpm */ 366 /* disable dynpm */
203 mutex_lock(&rdev->pm.mutex); 367 rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
204 rdev->pm.state = PM_STATE_PAUSED; 368 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
205 rdev->pm.planned_action = PM_ACTION_DEFAULT; 369 cancel_delayed_work(&rdev->pm.dynpm_idle_work);
206 radeon_get_power_state(rdev, rdev->pm.planned_action); 370 mutex_unlock(&rdev->pm.mutex);
207 mutex_unlock(&rdev->pm.mutex); 371 } else {
208 /* update power mode info */ 372 DRM_ERROR("invalid power method!\n");
209 radeon_pm_compute_clocks(rdev); 373 goto fail;
210 DRM_INFO("radeon: dynamic power management enabled\n"); 374 }
211 } else 375 radeon_pm_compute_clocks(rdev);
212 DRM_ERROR("dynpm not valid on this system\n"); 376fail:
213 } else
214 DRM_ERROR("Invalid setting: %d\n", tmp);
215
216 return count; 377 return count;
217} 378}
218 379
219static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, radeon_get_power_state_static, radeon_set_power_state_static); 380static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile);
220static DEVICE_ATTR(dynpm, S_IRUGO | S_IWUSR, radeon_get_dynpm, radeon_set_dynpm); 381static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method);
221
222 382
223static const char *pm_state_names[4] = { 383void radeon_pm_suspend(struct radeon_device *rdev)
224 "PM_STATE_DISABLED",
225 "PM_STATE_MINIMUM",
226 "PM_STATE_PAUSED",
227 "PM_STATE_ACTIVE"
228};
229
230static const char *pm_state_types[5] = {
231 "",
232 "Powersave",
233 "Battery",
234 "Balanced",
235 "Performance",
236};
237
238static void radeon_print_power_mode_info(struct radeon_device *rdev)
239{ 384{
240 int i, j; 385 mutex_lock(&rdev->pm.mutex);
241 bool is_default; 386 cancel_delayed_work(&rdev->pm.dynpm_idle_work);
242 387 rdev->pm.current_power_state_index = -1;
243 DRM_INFO("%d Power State(s)\n", rdev->pm.num_power_states); 388 rdev->pm.current_clock_mode_index = -1;
244 for (i = 0; i < rdev->pm.num_power_states; i++) { 389 rdev->pm.current_sclk = 0;
245 if (rdev->pm.default_power_state_index == i) 390 rdev->pm.current_mclk = 0;
246 is_default = true; 391 mutex_unlock(&rdev->pm.mutex);
247 else
248 is_default = false;
249 DRM_INFO("State %d %s %s\n", i,
250 pm_state_types[rdev->pm.power_state[i].type],
251 is_default ? "(default)" : "");
252 if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
253 DRM_INFO("\t%d PCIE Lanes\n", rdev->pm.power_state[i].pcie_lanes);
254 if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
255 DRM_INFO("\tSingle display only\n");
256 DRM_INFO("\t%d Clock Mode(s)\n", rdev->pm.power_state[i].num_clock_modes);
257 for (j = 0; j < rdev->pm.power_state[i].num_clock_modes; j++) {
258 if (rdev->flags & RADEON_IS_IGP)
259 DRM_INFO("\t\t%d engine: %d\n",
260 j,
261 rdev->pm.power_state[i].clock_info[j].sclk * 10);
262 else
263 DRM_INFO("\t\t%d engine/memory: %d/%d\n",
264 j,
265 rdev->pm.power_state[i].clock_info[j].sclk * 10,
266 rdev->pm.power_state[i].clock_info[j].mclk * 10);
267 if (rdev->pm.power_state[i].clock_info[j].flags & RADEON_PM_MODE_NO_DISPLAY)
268 DRM_INFO("\t\tNo display only\n");
269 }
270 }
271} 392}
272 393
273void radeon_sync_with_vblank(struct radeon_device *rdev) 394void radeon_pm_resume(struct radeon_device *rdev)
274{ 395{
275 if (rdev->pm.active_crtcs) { 396 radeon_pm_compute_clocks(rdev);
276 rdev->pm.vblank_sync = false;
277 wait_event_timeout(
278 rdev->irq.vblank_queue, rdev->pm.vblank_sync,
279 msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
280 }
281} 397}
282 398
283int radeon_pm_init(struct radeon_device *rdev) 399int radeon_pm_init(struct radeon_device *rdev)
284{ 400{
285 rdev->pm.state = PM_STATE_DISABLED; 401 /* default to profile method */
286 rdev->pm.planned_action = PM_ACTION_NONE; 402 rdev->pm.pm_method = PM_METHOD_PROFILE;
287 rdev->pm.can_upclock = true; 403 rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
288 rdev->pm.can_downclock = true; 404 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
405 rdev->pm.dynpm_can_upclock = true;
406 rdev->pm.dynpm_can_downclock = true;
407 rdev->pm.current_sclk = 0;
408 rdev->pm.current_mclk = 0;
289 409
290 if (rdev->bios) { 410 if (rdev->bios) {
291 if (rdev->is_atom_bios) 411 if (rdev->is_atom_bios)
292 radeon_atombios_get_power_modes(rdev); 412 radeon_atombios_get_power_modes(rdev);
293 else 413 else
294 radeon_combios_get_power_modes(rdev); 414 radeon_combios_get_power_modes(rdev);
295 radeon_print_power_mode_info(rdev); 415 radeon_pm_init_profile(rdev);
416 rdev->pm.current_power_state_index = -1;
417 rdev->pm.current_clock_mode_index = -1;
296 } 418 }
297 419
298 if (radeon_debugfs_pm_init(rdev)) { 420 if (rdev->pm.num_power_states > 1) {
299 DRM_ERROR("Failed to register debugfs file for PM!\n"); 421 if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
300 } 422 mutex_lock(&rdev->pm.mutex);
423 rdev->pm.profile = PM_PROFILE_DEFAULT;
424 radeon_pm_update_profile(rdev);
425 radeon_pm_set_clocks(rdev);
426 mutex_unlock(&rdev->pm.mutex);
427 }
301 428
302 /* where's the best place to put this? */ 429 /* where's the best place to put these? */
303 device_create_file(rdev->dev, &dev_attr_power_state); 430 device_create_file(rdev->dev, &dev_attr_power_profile);
304 device_create_file(rdev->dev, &dev_attr_dynpm); 431 device_create_file(rdev->dev, &dev_attr_power_method);
305 432
306 INIT_DELAYED_WORK(&rdev->pm.idle_work, radeon_pm_idle_work_handler); 433#ifdef CONFIG_ACPI
434 rdev->acpi_nb.notifier_call = radeon_acpi_event;
435 register_acpi_notifier(&rdev->acpi_nb);
436#endif
437 INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
307 438
308 if ((radeon_dynpm != -1 && radeon_dynpm) && (rdev->pm.num_power_states > 1)) { 439 if (radeon_debugfs_pm_init(rdev)) {
309 rdev->pm.state = PM_STATE_PAUSED; 440 DRM_ERROR("Failed to register debugfs file for PM!\n");
310 DRM_INFO("radeon: dynamic power management enabled\n"); 441 }
311 }
312 442
313 DRM_INFO("radeon: power management initialized\n"); 443 DRM_INFO("radeon: power management initialized\n");
444 }
314 445
315 return 0; 446 return 0;
316} 447}
317 448
318void radeon_pm_fini(struct radeon_device *rdev) 449void radeon_pm_fini(struct radeon_device *rdev)
319{ 450{
320 if (rdev->pm.state != PM_STATE_DISABLED) { 451 if (rdev->pm.num_power_states > 1) {
321 /* cancel work */
322 cancel_delayed_work_sync(&rdev->pm.idle_work);
323 /* reset default clocks */
324 rdev->pm.state = PM_STATE_DISABLED;
325 rdev->pm.planned_action = PM_ACTION_DEFAULT;
326 radeon_pm_set_clocks(rdev, true);
327 } else if ((rdev->pm.current_power_state_index !=
328 rdev->pm.default_power_state_index) ||
329 (rdev->pm.current_clock_mode_index != 0)) {
330 rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index;
331 rdev->pm.requested_clock_mode_index = 0;
332 mutex_lock(&rdev->pm.mutex); 452 mutex_lock(&rdev->pm.mutex);
333 radeon_pm_set_clocks(rdev, true); 453 if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
454 rdev->pm.profile = PM_PROFILE_DEFAULT;
455 radeon_pm_update_profile(rdev);
456 radeon_pm_set_clocks(rdev);
457 } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
458 /* cancel work */
459 cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
460 /* reset default clocks */
461 rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
462 rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT;
463 radeon_pm_set_clocks(rdev);
464 }
334 mutex_unlock(&rdev->pm.mutex); 465 mutex_unlock(&rdev->pm.mutex);
335 }
336 466
337 device_remove_file(rdev->dev, &dev_attr_power_state); 467 device_remove_file(rdev->dev, &dev_attr_power_profile);
338 device_remove_file(rdev->dev, &dev_attr_dynpm); 468 device_remove_file(rdev->dev, &dev_attr_power_method);
469#ifdef CONFIG_ACPI
470 unregister_acpi_notifier(&rdev->acpi_nb);
471#endif
472 }
339 473
340 if (rdev->pm.i2c_bus) 474 if (rdev->pm.i2c_bus)
341 radeon_i2c_destroy(rdev->pm.i2c_bus); 475 radeon_i2c_destroy(rdev->pm.i2c_bus);
@@ -347,6 +481,9 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
347 struct drm_crtc *crtc; 481 struct drm_crtc *crtc;
348 struct radeon_crtc *radeon_crtc; 482 struct radeon_crtc *radeon_crtc;
349 483
484 if (rdev->pm.num_power_states < 2)
485 return;
486
350 mutex_lock(&rdev->pm.mutex); 487 mutex_lock(&rdev->pm.mutex);
351 488
352 rdev->pm.active_crtcs = 0; 489 rdev->pm.active_crtcs = 0;
@@ -360,55 +497,56 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
360 } 497 }
361 } 498 }
362 499
363 if (rdev->pm.state == PM_STATE_DISABLED) { 500 if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
364 mutex_unlock(&rdev->pm.mutex); 501 radeon_pm_update_profile(rdev);
365 return; 502 radeon_pm_set_clocks(rdev);
366 } 503 } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
367 504 if (rdev->pm.dynpm_state != DYNPM_STATE_DISABLED) {
368 /* Note, radeon_pm_set_clocks is called with static_switch set 505 if (rdev->pm.active_crtc_count > 1) {
369 * to true since we always want to statically set the clocks, 506 if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) {
370 * not wait for vbl. 507 cancel_delayed_work(&rdev->pm.dynpm_idle_work);
371 */ 508
372 if (rdev->pm.active_crtc_count > 1) { 509 rdev->pm.dynpm_state = DYNPM_STATE_PAUSED;
373 if (rdev->pm.state == PM_STATE_ACTIVE) { 510 rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT;
374 cancel_delayed_work(&rdev->pm.idle_work); 511 radeon_pm_get_dynpm_state(rdev);
375 512 radeon_pm_set_clocks(rdev);
376 rdev->pm.state = PM_STATE_PAUSED; 513
377 rdev->pm.planned_action = PM_ACTION_DEFAULT; 514 DRM_DEBUG("radeon: dynamic power management deactivated\n");
378 radeon_pm_set_clocks(rdev, true); 515 }
379 516 } else if (rdev->pm.active_crtc_count == 1) {
380 DRM_DEBUG("radeon: dynamic power management deactivated\n"); 517 /* TODO: Increase clocks if needed for current mode */
381 } 518
382 } else if (rdev->pm.active_crtc_count == 1) { 519 if (rdev->pm.dynpm_state == DYNPM_STATE_MINIMUM) {
383 /* TODO: Increase clocks if needed for current mode */ 520 rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
384 521 rdev->pm.dynpm_planned_action = DYNPM_ACTION_UPCLOCK;
385 if (rdev->pm.state == PM_STATE_MINIMUM) { 522 radeon_pm_get_dynpm_state(rdev);
386 rdev->pm.state = PM_STATE_ACTIVE; 523 radeon_pm_set_clocks(rdev);
387 rdev->pm.planned_action = PM_ACTION_UPCLOCK; 524
388 radeon_pm_set_clocks(rdev, true); 525 queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
389 526 msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
390 queue_delayed_work(rdev->wq, &rdev->pm.idle_work, 527 } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) {
391 msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); 528 rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
392 } else if (rdev->pm.state == PM_STATE_PAUSED) { 529 queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
393 rdev->pm.state = PM_STATE_ACTIVE; 530 msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
394 queue_delayed_work(rdev->wq, &rdev->pm.idle_work, 531 DRM_DEBUG("radeon: dynamic power management activated\n");
395 msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); 532 }
396 DRM_DEBUG("radeon: dynamic power management activated\n"); 533 } else { /* count == 0 */
397 } 534 if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) {
398 } else { /* count == 0 */ 535 cancel_delayed_work(&rdev->pm.dynpm_idle_work);
399 if (rdev->pm.state != PM_STATE_MINIMUM) { 536
400 cancel_delayed_work(&rdev->pm.idle_work); 537 rdev->pm.dynpm_state = DYNPM_STATE_MINIMUM;
401 538 rdev->pm.dynpm_planned_action = DYNPM_ACTION_MINIMUM;
402 rdev->pm.state = PM_STATE_MINIMUM; 539 radeon_pm_get_dynpm_state(rdev);
403 rdev->pm.planned_action = PM_ACTION_MINIMUM; 540 radeon_pm_set_clocks(rdev);
404 radeon_pm_set_clocks(rdev, true); 541 }
542 }
405 } 543 }
406 } 544 }
407 545
408 mutex_unlock(&rdev->pm.mutex); 546 mutex_unlock(&rdev->pm.mutex);
409} 547}
410 548
411bool radeon_pm_in_vbl(struct radeon_device *rdev) 549static bool radeon_pm_in_vbl(struct radeon_device *rdev)
412{ 550{
413 u32 stat_crtc = 0, vbl = 0, position = 0; 551 u32 stat_crtc = 0, vbl = 0, position = 0;
414 bool in_vbl = true; 552 bool in_vbl = true;
@@ -480,7 +618,7 @@ bool radeon_pm_in_vbl(struct radeon_device *rdev)
480 return in_vbl; 618 return in_vbl;
481} 619}
482 620
483bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) 621static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish)
484{ 622{
485 u32 stat_crtc = 0; 623 u32 stat_crtc = 0;
486 bool in_vbl = radeon_pm_in_vbl(rdev); 624 bool in_vbl = radeon_pm_in_vbl(rdev);
@@ -491,16 +629,16 @@ bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish)
491 return in_vbl; 629 return in_vbl;
492} 630}
493 631
494static void radeon_pm_idle_work_handler(struct work_struct *work) 632static void radeon_dynpm_idle_work_handler(struct work_struct *work)
495{ 633{
496 struct radeon_device *rdev; 634 struct radeon_device *rdev;
497 int resched; 635 int resched;
498 rdev = container_of(work, struct radeon_device, 636 rdev = container_of(work, struct radeon_device,
499 pm.idle_work.work); 637 pm.dynpm_idle_work.work);
500 638
501 resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); 639 resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
502 mutex_lock(&rdev->pm.mutex); 640 mutex_lock(&rdev->pm.mutex);
503 if (rdev->pm.state == PM_STATE_ACTIVE) { 641 if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) {
504 unsigned long irq_flags; 642 unsigned long irq_flags;
505 int not_processed = 0; 643 int not_processed = 0;
506 644
@@ -516,23 +654,23 @@ static void radeon_pm_idle_work_handler(struct work_struct *work)
516 read_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 654 read_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
517 655
518 if (not_processed >= 3) { /* should upclock */ 656 if (not_processed >= 3) { /* should upclock */
519 if (rdev->pm.planned_action == PM_ACTION_DOWNCLOCK) { 657 if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_DOWNCLOCK) {
520 rdev->pm.planned_action = PM_ACTION_NONE; 658 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
521 } else if (rdev->pm.planned_action == PM_ACTION_NONE && 659 } else if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_NONE &&
522 rdev->pm.can_upclock) { 660 rdev->pm.dynpm_can_upclock) {
523 rdev->pm.planned_action = 661 rdev->pm.dynpm_planned_action =
524 PM_ACTION_UPCLOCK; 662 DYNPM_ACTION_UPCLOCK;
525 rdev->pm.action_timeout = jiffies + 663 rdev->pm.dynpm_action_timeout = jiffies +
526 msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); 664 msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS);
527 } 665 }
528 } else if (not_processed == 0) { /* should downclock */ 666 } else if (not_processed == 0) { /* should downclock */
529 if (rdev->pm.planned_action == PM_ACTION_UPCLOCK) { 667 if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_UPCLOCK) {
530 rdev->pm.planned_action = PM_ACTION_NONE; 668 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
531 } else if (rdev->pm.planned_action == PM_ACTION_NONE && 669 } else if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_NONE &&
532 rdev->pm.can_downclock) { 670 rdev->pm.dynpm_can_downclock) {
533 rdev->pm.planned_action = 671 rdev->pm.dynpm_planned_action =
534 PM_ACTION_DOWNCLOCK; 672 DYNPM_ACTION_DOWNCLOCK;
535 rdev->pm.action_timeout = jiffies + 673 rdev->pm.dynpm_action_timeout = jiffies +
536 msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); 674 msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS);
537 } 675 }
538 } 676 }
@@ -540,15 +678,16 @@ static void radeon_pm_idle_work_handler(struct work_struct *work)
540 /* Note, radeon_pm_set_clocks is called with static_switch set 678 /* Note, radeon_pm_set_clocks is called with static_switch set
541 * to false since we want to wait for vbl to avoid flicker. 679 * to false since we want to wait for vbl to avoid flicker.
542 */ 680 */
543 if (rdev->pm.planned_action != PM_ACTION_NONE && 681 if (rdev->pm.dynpm_planned_action != DYNPM_ACTION_NONE &&
544 jiffies > rdev->pm.action_timeout) { 682 jiffies > rdev->pm.dynpm_action_timeout) {
545 radeon_pm_set_clocks(rdev, false); 683 radeon_pm_get_dynpm_state(rdev);
684 radeon_pm_set_clocks(rdev);
546 } 685 }
547 } 686 }
548 mutex_unlock(&rdev->pm.mutex); 687 mutex_unlock(&rdev->pm.mutex);
549 ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); 688 ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
550 689
551 queue_delayed_work(rdev->wq, &rdev->pm.idle_work, 690 queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
552 msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); 691 msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
553} 692}
554 693
@@ -563,7 +702,6 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
563 struct drm_device *dev = node->minor->dev; 702 struct drm_device *dev = node->minor->dev;
564 struct radeon_device *rdev = dev->dev_private; 703 struct radeon_device *rdev = dev->dev_private;
565 704
566 seq_printf(m, "state: %s\n", pm_state_names[rdev->pm.state]);
567 seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk); 705 seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk);
568 seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); 706 seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
569 seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); 707 seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk);
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index dc76fe76eb25..9e4240b3bf0b 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -456,7 +456,6 @@ int rs400_suspend(struct radeon_device *rdev)
456 456
457void rs400_fini(struct radeon_device *rdev) 457void rs400_fini(struct radeon_device *rdev)
458{ 458{
459 radeon_pm_fini(rdev);
460 r100_cp_fini(rdev); 459 r100_cp_fini(rdev);
461 r100_wb_fini(rdev); 460 r100_wb_fini(rdev);
462 r100_ib_fini(rdev); 461 r100_ib_fini(rdev);
@@ -507,8 +506,6 @@ int rs400_init(struct radeon_device *rdev)
507 506
508 /* Initialize clocks */ 507 /* Initialize clocks */
509 radeon_get_clock_info(rdev->ddev); 508 radeon_get_clock_info(rdev->ddev);
510 /* Initialize power management */
511 radeon_pm_init(rdev);
512 /* initialize memory controller */ 509 /* initialize memory controller */
513 rs400_mc_init(rdev); 510 rs400_mc_init(rdev);
514 /* Fence driver */ 511 /* Fence driver */
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 8e0c46060b3a..e8c68e9c0a1e 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -846,7 +846,6 @@ int rs600_suspend(struct radeon_device *rdev)
846 846
847void rs600_fini(struct radeon_device *rdev) 847void rs600_fini(struct radeon_device *rdev)
848{ 848{
849 radeon_pm_fini(rdev);
850 r100_cp_fini(rdev); 849 r100_cp_fini(rdev);
851 r100_wb_fini(rdev); 850 r100_wb_fini(rdev);
852 r100_ib_fini(rdev); 851 r100_ib_fini(rdev);
@@ -896,8 +895,6 @@ int rs600_init(struct radeon_device *rdev)
896 895
897 /* Initialize clocks */ 896 /* Initialize clocks */
898 radeon_get_clock_info(rdev->ddev); 897 radeon_get_clock_info(rdev->ddev);
899 /* Initialize power management */
900 radeon_pm_init(rdev);
901 /* initialize memory controller */ 898 /* initialize memory controller */
902 rs600_mc_init(rdev); 899 rs600_mc_init(rdev);
903 rs600_debugfs(rdev); 900 rs600_debugfs(rdev);
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index e8edfe617286..bcc33195ebc2 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -676,7 +676,6 @@ int rs690_suspend(struct radeon_device *rdev)
676 676
677void rs690_fini(struct radeon_device *rdev) 677void rs690_fini(struct radeon_device *rdev)
678{ 678{
679 radeon_pm_fini(rdev);
680 r100_cp_fini(rdev); 679 r100_cp_fini(rdev);
681 r100_wb_fini(rdev); 680 r100_wb_fini(rdev);
682 r100_ib_fini(rdev); 681 r100_ib_fini(rdev);
@@ -727,8 +726,6 @@ int rs690_init(struct radeon_device *rdev)
727 726
728 /* Initialize clocks */ 727 /* Initialize clocks */
729 radeon_get_clock_info(rdev->ddev); 728 radeon_get_clock_info(rdev->ddev);
730 /* Initialize power management */
731 radeon_pm_init(rdev);
732 /* initialize memory controller */ 729 /* initialize memory controller */
733 rs690_mc_init(rdev); 730 rs690_mc_init(rdev);
734 rv515_debugfs(rdev); 731 rv515_debugfs(rdev);
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 2009f4b20c28..7d9a7b0a180a 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -445,7 +445,6 @@ void rv515_set_safe_registers(struct radeon_device *rdev)
445 445
446void rv515_fini(struct radeon_device *rdev) 446void rv515_fini(struct radeon_device *rdev)
447{ 447{
448 radeon_pm_fini(rdev);
449 r100_cp_fini(rdev); 448 r100_cp_fini(rdev);
450 r100_wb_fini(rdev); 449 r100_wb_fini(rdev);
451 r100_ib_fini(rdev); 450 r100_ib_fini(rdev);
@@ -494,8 +493,6 @@ int rv515_init(struct radeon_device *rdev)
494 return -EINVAL; 493 return -EINVAL;
495 /* Initialize clocks */ 494 /* Initialize clocks */
496 radeon_get_clock_info(rdev->ddev); 495 radeon_get_clock_info(rdev->ddev);
497 /* Initialize power management */
498 radeon_pm_init(rdev);
499 /* initialize AGP */ 496 /* initialize AGP */
500 if (rdev->flags & RADEON_IS_AGP) { 497 if (rdev->flags & RADEON_IS_AGP) {
501 r = radeon_agp_init(rdev); 498 r = radeon_agp_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 7c55182a9dd7..253f24aec031 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1091,8 +1091,6 @@ int rv770_init(struct radeon_device *rdev)
1091 r = radeon_clocks_init(rdev); 1091 r = radeon_clocks_init(rdev);
1092 if (r) 1092 if (r)
1093 return r; 1093 return r;
1094 /* Initialize power management */
1095 radeon_pm_init(rdev);
1096 /* Fence driver */ 1094 /* Fence driver */
1097 r = radeon_fence_driver_init(rdev); 1095 r = radeon_fence_driver_init(rdev);
1098 if (r) 1096 if (r)
@@ -1161,7 +1159,6 @@ int rv770_init(struct radeon_device *rdev)
1161 1159
1162void rv770_fini(struct radeon_device *rdev) 1160void rv770_fini(struct radeon_device *rdev)
1163{ 1161{
1164 radeon_pm_fini(rdev);
1165 r600_blit_fini(rdev); 1162 r600_blit_fini(rdev);
1166 r700_cp_fini(rdev); 1163 r700_cp_fini(rdev);
1167 r600_wb_fini(rdev); 1164 r600_wb_fini(rdev);