diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-10-01 19:25:11 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-10-02 10:27:51 -0400 |
commit | 27810fb2d2edacf2961dbedfe9e9f8d2e5080ea5 (patch) | |
tree | 5fc4c124a0982f8e4fe4e26a35126cd2c2c3154c /drivers/gpu | |
parent | eb2c27a02bcf6013cda5d9e6277d50f7b4cfc13d (diff) |
drm/radeon/pm: fix multi-head profile handling on BTC+ (v2)
Starting on BTC, there are no longer separate states for
single head and multi-head, we just use the high mclk/voltage
for all states for multi-head.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=49981
v2: fix typo
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 17 |
4 files changed, 76 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ef47879c5d4..c4ded396b78 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -326,6 +326,64 @@ void sumo_pm_init_profile(struct radeon_device *rdev) | |||
326 | } | 326 | } |
327 | 327 | ||
328 | /** | 328 | /** |
329 | * btc_pm_init_profile - Initialize power profiles callback. | ||
330 | * | ||
331 | * @rdev: radeon_device pointer | ||
332 | * | ||
333 | * Initialize the power states used in profile mode | ||
334 | * (BTC, cayman). | ||
335 | * Used for profile mode only. | ||
336 | */ | ||
337 | void btc_pm_init_profile(struct radeon_device *rdev) | ||
338 | { | ||
339 | int idx; | ||
340 | |||
341 | /* default */ | ||
342 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; | ||
343 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; | ||
344 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; | ||
345 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; | ||
346 | /* starting with BTC, there is one state that is used for both | ||
347 | * MH and SH. Difference is that we always use the high clock index for | ||
348 | * mclk. | ||
349 | */ | ||
350 | if (rdev->flags & RADEON_IS_MOBILITY) | ||
351 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | ||
352 | else | ||
353 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
354 | /* low sh */ | ||
355 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; | ||
356 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; | ||
357 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | ||
358 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | ||
359 | /* mid sh */ | ||
360 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; | ||
361 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; | ||
362 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
363 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; | ||
364 | /* high sh */ | ||
365 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; | ||
366 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; | ||
367 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; | ||
368 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; | ||
369 | /* low mh */ | ||
370 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; | ||
371 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; | ||
372 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | ||
373 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | ||
374 | /* mid mh */ | ||
375 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; | ||
376 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; | ||
377 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
378 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; | ||
379 | /* high mh */ | ||
380 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; | ||
381 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; | ||
382 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; | ||
383 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; | ||
384 | } | ||
385 | |||
386 | /** | ||
329 | * evergreen_pm_misc - set additional pm hw parameters callback. | 387 | * evergreen_pm_misc - set additional pm hw parameters callback. |
330 | * | 388 | * |
331 | * @rdev: radeon_device pointer | 389 | * @rdev: radeon_device pointer |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 6225e197770..0f31c43b07b 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1357,7 +1357,7 @@ static struct radeon_asic btc_asic = { | |||
1357 | .misc = &evergreen_pm_misc, | 1357 | .misc = &evergreen_pm_misc, |
1358 | .prepare = &evergreen_pm_prepare, | 1358 | .prepare = &evergreen_pm_prepare, |
1359 | .finish = &evergreen_pm_finish, | 1359 | .finish = &evergreen_pm_finish, |
1360 | .init_profile = &r600_pm_init_profile, | 1360 | .init_profile = &btc_pm_init_profile, |
1361 | .get_dynpm_state = &r600_pm_get_dynpm_state, | 1361 | .get_dynpm_state = &r600_pm_get_dynpm_state, |
1362 | .get_engine_clock = &radeon_atom_get_engine_clock, | 1362 | .get_engine_clock = &radeon_atom_get_engine_clock, |
1363 | .set_engine_clock = &radeon_atom_set_engine_clock, | 1363 | .set_engine_clock = &radeon_atom_set_engine_clock, |
@@ -1462,7 +1462,7 @@ static struct radeon_asic cayman_asic = { | |||
1462 | .misc = &evergreen_pm_misc, | 1462 | .misc = &evergreen_pm_misc, |
1463 | .prepare = &evergreen_pm_prepare, | 1463 | .prepare = &evergreen_pm_prepare, |
1464 | .finish = &evergreen_pm_finish, | 1464 | .finish = &evergreen_pm_finish, |
1465 | .init_profile = &r600_pm_init_profile, | 1465 | .init_profile = &btc_pm_init_profile, |
1466 | .get_dynpm_state = &r600_pm_get_dynpm_state, | 1466 | .get_dynpm_state = &r600_pm_get_dynpm_state, |
1467 | .get_engine_clock = &radeon_atom_get_engine_clock, | 1467 | .get_engine_clock = &radeon_atom_get_engine_clock, |
1468 | .set_engine_clock = &radeon_atom_set_engine_clock, | 1468 | .set_engine_clock = &radeon_atom_set_engine_clock, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 9a71f445c36..f158c11c906 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -420,6 +420,7 @@ extern void evergreen_pm_misc(struct radeon_device *rdev); | |||
420 | extern void evergreen_pm_prepare(struct radeon_device *rdev); | 420 | extern void evergreen_pm_prepare(struct radeon_device *rdev); |
421 | extern void evergreen_pm_finish(struct radeon_device *rdev); | 421 | extern void evergreen_pm_finish(struct radeon_device *rdev); |
422 | extern void sumo_pm_init_profile(struct radeon_device *rdev); | 422 | extern void sumo_pm_init_profile(struct radeon_device *rdev); |
423 | extern void btc_pm_init_profile(struct radeon_device *rdev); | ||
423 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); | 424 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); |
424 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | 425 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); |
425 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); | 426 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 8d64138b95f..bc2e7050a9d 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -167,8 +167,21 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
167 | if (sclk > rdev->pm.default_sclk) | 167 | if (sclk > rdev->pm.default_sclk) |
168 | sclk = rdev->pm.default_sclk; | 168 | sclk = rdev->pm.default_sclk; |
169 | 169 | ||
170 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 170 | /* starting with BTC, there is one state that is used for both |
171 | clock_info[rdev->pm.requested_clock_mode_index].mclk; | 171 | * MH and SH. Difference is that we always use the high clock index for |
172 | * mclk. | ||
173 | */ | ||
174 | if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && | ||
175 | (rdev->family >= CHIP_BARTS) && | ||
176 | rdev->pm.active_crtc_count && | ||
177 | ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) || | ||
178 | (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX))) | ||
179 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | ||
180 | clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].mclk; | ||
181 | else | ||
182 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | ||
183 | clock_info[rdev->pm.requested_clock_mode_index].mclk; | ||
184 | |||
172 | if (mclk > rdev->pm.default_mclk) | 185 | if (mclk > rdev->pm.default_mclk) |
173 | mclk = rdev->pm.default_mclk; | 186 | mclk = rdev->pm.default_mclk; |
174 | 187 | ||