aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_pm.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-06-30 18:07:09 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-06-30 18:07:09 -0400
commit08fa16b6b75005c120b59d00ae42a0b7cc68db45 (patch)
treec5f22412467f72dd0c7291bbb958a9485e894f02 /drivers/gpu/drm/radeon/radeon_pm.c
parent1796b983cc4cbbed5e9e478b03591609a2c21987 (diff)
parent7e27d6e778cd87b6f2415515d7127eba53fe5d02 (diff)
Merge commit 'v2.6.35-rc3' into next
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c170
1 files changed, 102 insertions, 68 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index a8d162c6f82..63f679a04b2 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -33,6 +33,14 @@
33#define RADEON_WAIT_VBLANK_TIMEOUT 200 33#define RADEON_WAIT_VBLANK_TIMEOUT 200
34#define RADEON_WAIT_IDLE_TIMEOUT 200 34#define RADEON_WAIT_IDLE_TIMEOUT 200
35 35
36static const char *radeon_pm_state_type_name[5] = {
37 "Default",
38 "Powersave",
39 "Battery",
40 "Balanced",
41 "Performance",
42};
43
36static void radeon_dynpm_idle_work_handler(struct work_struct *work); 44static void radeon_dynpm_idle_work_handler(struct work_struct *work);
37static int radeon_debugfs_pm_init(struct radeon_device *rdev); 45static int radeon_debugfs_pm_init(struct radeon_device *rdev);
38static bool radeon_pm_in_vbl(struct radeon_device *rdev); 46static bool radeon_pm_in_vbl(struct radeon_device *rdev);
@@ -84,9 +92,9 @@ static void radeon_pm_update_profile(struct radeon_device *rdev)
84 rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX; 92 rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX;
85 } else { 93 } else {
86 if (rdev->pm.active_crtc_count > 1) 94 if (rdev->pm.active_crtc_count > 1)
87 rdev->pm.profile_index = PM_PROFILE_LOW_MH_IDX; 95 rdev->pm.profile_index = PM_PROFILE_MID_MH_IDX;
88 else 96 else
89 rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX; 97 rdev->pm.profile_index = PM_PROFILE_MID_SH_IDX;
90 } 98 }
91 break; 99 break;
92 case PM_PROFILE_LOW: 100 case PM_PROFILE_LOW:
@@ -95,6 +103,12 @@ static void radeon_pm_update_profile(struct radeon_device *rdev)
95 else 103 else
96 rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX; 104 rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX;
97 break; 105 break;
106 case PM_PROFILE_MID:
107 if (rdev->pm.active_crtc_count > 1)
108 rdev->pm.profile_index = PM_PROFILE_MID_MH_IDX;
109 else
110 rdev->pm.profile_index = PM_PROFILE_MID_SH_IDX;
111 break;
98 case PM_PROFILE_HIGH: 112 case PM_PROFILE_HIGH:
99 if (rdev->pm.active_crtc_count > 1) 113 if (rdev->pm.active_crtc_count > 1)
100 rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX; 114 rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX;
@@ -127,15 +141,6 @@ static void radeon_unmap_vram_bos(struct radeon_device *rdev)
127 if (bo->tbo.mem.mem_type == TTM_PL_VRAM) 141 if (bo->tbo.mem.mem_type == TTM_PL_VRAM)
128 ttm_bo_unmap_virtual(&bo->tbo); 142 ttm_bo_unmap_virtual(&bo->tbo);
129 } 143 }
130
131 if (rdev->gart.table.vram.robj)
132 ttm_bo_unmap_virtual(&rdev->gart.table.vram.robj->tbo);
133
134 if (rdev->stollen_vga_memory)
135 ttm_bo_unmap_virtual(&rdev->stollen_vga_memory->tbo);
136
137 if (rdev->r600_blit.shader_obj)
138 ttm_bo_unmap_virtual(&rdev->r600_blit.shader_obj->tbo);
139} 144}
140 145
141static void radeon_sync_with_vblank(struct radeon_device *rdev) 146static void radeon_sync_with_vblank(struct radeon_device *rdev)
@@ -151,6 +156,7 @@ static void radeon_sync_with_vblank(struct radeon_device *rdev)
151static void radeon_set_power_state(struct radeon_device *rdev) 156static void radeon_set_power_state(struct radeon_device *rdev)
152{ 157{
153 u32 sclk, mclk; 158 u32 sclk, mclk;
159 bool misc_after = false;
154 160
155 if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && 161 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)) 162 (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
@@ -167,55 +173,47 @@ static void radeon_set_power_state(struct radeon_device *rdev)
167 if (mclk > rdev->clock.default_mclk) 173 if (mclk > rdev->clock.default_mclk)
168 mclk = rdev->clock.default_mclk; 174 mclk = rdev->clock.default_mclk;
169 175
170 /* voltage, pcie lanes, etc.*/ 176 /* upvolt before raising clocks, downvolt after lowering clocks */
171 radeon_pm_misc(rdev); 177 if (sclk < rdev->pm.current_sclk)
178 misc_after = true;
172 179
173 if (rdev->pm.pm_method == PM_METHOD_DYNPM) { 180 radeon_sync_with_vblank(rdev);
174 radeon_sync_with_vblank(rdev);
175 181
182 if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
176 if (!radeon_pm_in_vbl(rdev)) 183 if (!radeon_pm_in_vbl(rdev))
177 return; 184 return;
185 }
178 186
179 radeon_pm_prepare(rdev); 187 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_DEBUG("Setting: e: %d\n", sclk);
187 }
188 188
189 /* set memory clock */ 189 if (!misc_after)
190 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { 190 /* voltage, pcie lanes, etc.*/
191 radeon_pm_debug_check_in_vbl(rdev, false); 191 radeon_pm_misc(rdev);
192 radeon_set_memory_clock(rdev, mclk); 192
193 radeon_pm_debug_check_in_vbl(rdev, true); 193 /* set engine clock */
194 rdev->pm.current_mclk = mclk; 194 if (sclk != rdev->pm.current_sclk) {
195 DRM_DEBUG("Setting: m: %d\n", mclk); 195 radeon_pm_debug_check_in_vbl(rdev, false);
196 } 196 radeon_set_engine_clock(rdev, sclk);
197 radeon_pm_finish(rdev); 197 radeon_pm_debug_check_in_vbl(rdev, true);
198 } else { 198 rdev->pm.current_sclk = sclk;
199 /* set engine clock */ 199 DRM_DEBUG("Setting: e: %d\n", sclk);
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_DEBUG("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_DEBUG("Setting: m: %d\n", mclk);
216 }
217 } 200 }
218 201
202 /* set memory clock */
203 if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) {
204 radeon_pm_debug_check_in_vbl(rdev, false);
205 radeon_set_memory_clock(rdev, mclk);
206 radeon_pm_debug_check_in_vbl(rdev, true);
207 rdev->pm.current_mclk = mclk;
208 DRM_DEBUG("Setting: m: %d\n", mclk);
209 }
210
211 if (misc_after)
212 /* voltage, pcie lanes, etc.*/
213 radeon_pm_misc(rdev);
214
215 radeon_pm_finish(rdev);
216
219 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; 217 rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index;
220 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; 218 rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index;
221 } else 219 } else
@@ -288,6 +286,42 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
288 mutex_unlock(&rdev->ddev->struct_mutex); 286 mutex_unlock(&rdev->ddev->struct_mutex);
289} 287}
290 288
289static void radeon_pm_print_states(struct radeon_device *rdev)
290{
291 int i, j;
292 struct radeon_power_state *power_state;
293 struct radeon_pm_clock_info *clock_info;
294
295 DRM_DEBUG("%d Power State(s)\n", rdev->pm.num_power_states);
296 for (i = 0; i < rdev->pm.num_power_states; i++) {
297 power_state = &rdev->pm.power_state[i];
298 DRM_DEBUG("State %d: %s\n", i,
299 radeon_pm_state_type_name[power_state->type]);
300 if (i == rdev->pm.default_power_state_index)
301 DRM_DEBUG("\tDefault");
302 if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP))
303 DRM_DEBUG("\t%d PCIE Lanes\n", power_state->pcie_lanes);
304 if (power_state->flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
305 DRM_DEBUG("\tSingle display only\n");
306 DRM_DEBUG("\t%d Clock Mode(s)\n", power_state->num_clock_modes);
307 for (j = 0; j < power_state->num_clock_modes; j++) {
308 clock_info = &(power_state->clock_info[j]);
309 if (rdev->flags & RADEON_IS_IGP)
310 DRM_DEBUG("\t\t%d e: %d%s\n",
311 j,
312 clock_info->sclk * 10,
313 clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : "");
314 else
315 DRM_DEBUG("\t\t%d e: %d\tm: %d\tv: %d%s\n",
316 j,
317 clock_info->sclk * 10,
318 clock_info->mclk * 10,
319 clock_info->voltage.voltage,
320 clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : "");
321 }
322 }
323}
324
291static ssize_t radeon_get_pm_profile(struct device *dev, 325static ssize_t radeon_get_pm_profile(struct device *dev,
292 struct device_attribute *attr, 326 struct device_attribute *attr,
293 char *buf) 327 char *buf)
@@ -318,6 +352,8 @@ static ssize_t radeon_set_pm_profile(struct device *dev,
318 rdev->pm.profile = PM_PROFILE_AUTO; 352 rdev->pm.profile = PM_PROFILE_AUTO;
319 else if (strncmp("low", buf, strlen("low")) == 0) 353 else if (strncmp("low", buf, strlen("low")) == 0)
320 rdev->pm.profile = PM_PROFILE_LOW; 354 rdev->pm.profile = PM_PROFILE_LOW;
355 else if (strncmp("mid", buf, strlen("mid")) == 0)
356 rdev->pm.profile = PM_PROFILE_MID;
321 else if (strncmp("high", buf, strlen("high")) == 0) 357 else if (strncmp("high", buf, strlen("high")) == 0)
322 rdev->pm.profile = PM_PROFILE_HIGH; 358 rdev->pm.profile = PM_PROFILE_HIGH;
323 else { 359 else {
@@ -384,15 +420,19 @@ void radeon_pm_suspend(struct radeon_device *rdev)
384{ 420{
385 mutex_lock(&rdev->pm.mutex); 421 mutex_lock(&rdev->pm.mutex);
386 cancel_delayed_work(&rdev->pm.dynpm_idle_work); 422 cancel_delayed_work(&rdev->pm.dynpm_idle_work);
387 rdev->pm.current_power_state_index = -1;
388 rdev->pm.current_clock_mode_index = -1;
389 rdev->pm.current_sclk = 0;
390 rdev->pm.current_mclk = 0;
391 mutex_unlock(&rdev->pm.mutex); 423 mutex_unlock(&rdev->pm.mutex);
392} 424}
393 425
394void radeon_pm_resume(struct radeon_device *rdev) 426void radeon_pm_resume(struct radeon_device *rdev)
395{ 427{
428 /* asic init will reset the default power state */
429 mutex_lock(&rdev->pm.mutex);
430 rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
431 rdev->pm.current_clock_mode_index = 0;
432 rdev->pm.current_sclk = rdev->clock.default_sclk;
433 rdev->pm.current_mclk = rdev->clock.default_mclk;
434 rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
435 mutex_unlock(&rdev->pm.mutex);
396 radeon_pm_compute_clocks(rdev); 436 radeon_pm_compute_clocks(rdev);
397} 437}
398 438
@@ -401,32 +441,24 @@ int radeon_pm_init(struct radeon_device *rdev)
401 int ret; 441 int ret;
402 /* default to profile method */ 442 /* default to profile method */
403 rdev->pm.pm_method = PM_METHOD_PROFILE; 443 rdev->pm.pm_method = PM_METHOD_PROFILE;
444 rdev->pm.profile = PM_PROFILE_DEFAULT;
404 rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; 445 rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
405 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; 446 rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
406 rdev->pm.dynpm_can_upclock = true; 447 rdev->pm.dynpm_can_upclock = true;
407 rdev->pm.dynpm_can_downclock = true; 448 rdev->pm.dynpm_can_downclock = true;
408 rdev->pm.current_sclk = 0; 449 rdev->pm.current_sclk = rdev->clock.default_sclk;
409 rdev->pm.current_mclk = 0; 450 rdev->pm.current_mclk = rdev->clock.default_mclk;
410 451
411 if (rdev->bios) { 452 if (rdev->bios) {
412 if (rdev->is_atom_bios) 453 if (rdev->is_atom_bios)
413 radeon_atombios_get_power_modes(rdev); 454 radeon_atombios_get_power_modes(rdev);
414 else 455 else
415 radeon_combios_get_power_modes(rdev); 456 radeon_combios_get_power_modes(rdev);
457 radeon_pm_print_states(rdev);
416 radeon_pm_init_profile(rdev); 458 radeon_pm_init_profile(rdev);
417 rdev->pm.current_power_state_index = -1;
418 rdev->pm.current_clock_mode_index = -1;
419 } 459 }
420 460
421 if (rdev->pm.num_power_states > 1) { 461 if (rdev->pm.num_power_states > 1) {
422 if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
423 mutex_lock(&rdev->pm.mutex);
424 rdev->pm.profile = PM_PROFILE_DEFAULT;
425 radeon_pm_update_profile(rdev);
426 radeon_pm_set_clocks(rdev);
427 mutex_unlock(&rdev->pm.mutex);
428 }
429
430 /* where's the best place to put these? */ 462 /* where's the best place to put these? */
431 ret = device_create_file(rdev->dev, &dev_attr_power_profile); 463 ret = device_create_file(rdev->dev, &dev_attr_power_profile);
432 if (ret) 464 if (ret)
@@ -712,6 +744,8 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
712 seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); 744 seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk);
713 if (rdev->asic->get_memory_clock) 745 if (rdev->asic->get_memory_clock)
714 seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); 746 seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
747 if (rdev->pm.current_vddc)
748 seq_printf(m, "voltage: %u mV\n", rdev->pm.current_vddc);
715 if (rdev->asic->get_pcie_lanes) 749 if (rdev->asic->get_pcie_lanes)
716 seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev)); 750 seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev));
717 751