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 | |
| 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>
| -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 ef47879c5d40..c4ded396b78d 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 6225e1977700..0f31c43b07b5 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 9a71f445c36b..f158c11c9065 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 8d64138b95f3..bc2e7050a9d8 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 | ||
