diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-16 14:17:23 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-06-27 19:16:19 -0400 |
commit | e8a9539fa098623ae3af1e077b49794917ea073d (patch) | |
tree | 03ad49d920c3e668bb543e57fcac2527367a28a7 /drivers/gpu/drm/radeon/btc_dpm.c | |
parent | a284c48ae7217fc362b851c68f74d7b414061704 (diff) |
drm/radeon/dpm: add pre/post_set_power_state callback (BTC)
This properly implemented dynamic state adjustment by
using a working copy of the requested and current
power states.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/btc_dpm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/btc_dpm.c | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index e952aa14ae4c..f26cefe2432f 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
@@ -2062,18 +2062,12 @@ static void btc_init_stutter_mode(struct radeon_device *rdev) | |||
2062 | static void btc_apply_state_adjust_rules(struct radeon_device *rdev, | 2062 | static void btc_apply_state_adjust_rules(struct radeon_device *rdev, |
2063 | struct radeon_ps *rps) | 2063 | struct radeon_ps *rps) |
2064 | { | 2064 | { |
2065 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2066 | struct rv7xx_ps *ps = rv770_get_ps(rps); | 2065 | struct rv7xx_ps *ps = rv770_get_ps(rps); |
2067 | struct radeon_clock_and_voltage_limits *max_limits; | 2066 | struct radeon_clock_and_voltage_limits *max_limits; |
2068 | bool disable_mclk_switching; | 2067 | bool disable_mclk_switching; |
2069 | u32 mclk, sclk; | 2068 | u32 mclk, sclk; |
2070 | u16 vddc, vddci; | 2069 | u16 vddc, vddci; |
2071 | 2070 | ||
2072 | /* point to the hw copy since this function will modify the ps */ | ||
2073 | eg_pi->hw_ps = *ps; | ||
2074 | rdev->pm.dpm.hw_ps.ps_priv = &eg_pi->hw_ps; | ||
2075 | ps = &eg_pi->hw_ps; | ||
2076 | |||
2077 | if (rdev->pm.dpm.new_active_crtc_count > 1) | 2071 | if (rdev->pm.dpm.new_active_crtc_count > 1) |
2078 | disable_mclk_switching = true; | 2072 | disable_mclk_switching = true; |
2079 | else | 2073 | else |
@@ -2222,6 +2216,28 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2222 | ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2; | 2216 | ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2; |
2223 | } | 2217 | } |
2224 | 2218 | ||
2219 | static void btc_update_current_ps(struct radeon_device *rdev, | ||
2220 | struct radeon_ps *rps) | ||
2221 | { | ||
2222 | struct rv7xx_ps *new_ps = rv770_get_ps(rps); | ||
2223 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2224 | |||
2225 | eg_pi->current_rps = *rps; | ||
2226 | eg_pi->current_ps = *new_ps; | ||
2227 | eg_pi->current_rps.ps_priv = &eg_pi->current_ps; | ||
2228 | } | ||
2229 | |||
2230 | static void btc_update_requested_ps(struct radeon_device *rdev, | ||
2231 | struct radeon_ps *rps) | ||
2232 | { | ||
2233 | struct rv7xx_ps *new_ps = rv770_get_ps(rps); | ||
2234 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2235 | |||
2236 | eg_pi->requested_rps = *rps; | ||
2237 | eg_pi->requested_ps = *new_ps; | ||
2238 | eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps; | ||
2239 | } | ||
2240 | |||
2225 | void btc_dpm_reset_asic(struct radeon_device *rdev) | 2241 | void btc_dpm_reset_asic(struct radeon_device *rdev) |
2226 | { | 2242 | { |
2227 | rv770_restrict_performance_levels_before_switch(rdev); | 2243 | rv770_restrict_performance_levels_before_switch(rdev); |
@@ -2230,13 +2246,24 @@ void btc_dpm_reset_asic(struct radeon_device *rdev) | |||
2230 | rv770_set_boot_state(rdev); | 2246 | rv770_set_boot_state(rdev); |
2231 | } | 2247 | } |
2232 | 2248 | ||
2233 | int btc_dpm_set_power_state(struct radeon_device *rdev) | 2249 | int btc_dpm_pre_set_power_state(struct radeon_device *rdev) |
2234 | { | 2250 | { |
2235 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 2251 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
2236 | struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps; | 2252 | struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps; |
2237 | struct radeon_ps *old_ps = rdev->pm.dpm.current_ps; | 2253 | struct radeon_ps *new_ps = &requested_ps; |
2254 | |||
2255 | btc_update_requested_ps(rdev, new_ps); | ||
2256 | |||
2257 | btc_apply_state_adjust_rules(rdev, &eg_pi->requested_rps); | ||
2238 | 2258 | ||
2239 | btc_apply_state_adjust_rules(rdev, new_ps); | 2259 | return 0; |
2260 | } | ||
2261 | |||
2262 | int btc_dpm_set_power_state(struct radeon_device *rdev) | ||
2263 | { | ||
2264 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2265 | struct radeon_ps *new_ps = &eg_pi->requested_rps; | ||
2266 | struct radeon_ps *old_ps = &eg_pi->current_rps; | ||
2240 | 2267 | ||
2241 | btc_disable_ulv(rdev); | 2268 | btc_disable_ulv(rdev); |
2242 | btc_set_boot_state_timing(rdev); | 2269 | btc_set_boot_state_timing(rdev); |
@@ -2274,6 +2301,14 @@ int btc_dpm_set_power_state(struct radeon_device *rdev) | |||
2274 | return 0; | 2301 | return 0; |
2275 | } | 2302 | } |
2276 | 2303 | ||
2304 | void btc_dpm_post_set_power_state(struct radeon_device *rdev) | ||
2305 | { | ||
2306 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2307 | struct radeon_ps *new_ps = &eg_pi->requested_rps; | ||
2308 | |||
2309 | btc_update_current_ps(rdev, new_ps); | ||
2310 | } | ||
2311 | |||
2277 | int btc_dpm_enable(struct radeon_device *rdev) | 2312 | int btc_dpm_enable(struct radeon_device *rdev) |
2278 | { | 2313 | { |
2279 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | 2314 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
@@ -2369,6 +2404,8 @@ int btc_dpm_enable(struct radeon_device *rdev) | |||
2369 | 2404 | ||
2370 | btc_init_stutter_mode(rdev); | 2405 | btc_init_stutter_mode(rdev); |
2371 | 2406 | ||
2407 | btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps); | ||
2408 | |||
2372 | return 0; | 2409 | return 0; |
2373 | }; | 2410 | }; |
2374 | 2411 | ||
@@ -2407,6 +2444,8 @@ void btc_dpm_disable(struct radeon_device *rdev) | |||
2407 | btc_reset_to_default(rdev); | 2444 | btc_reset_to_default(rdev); |
2408 | btc_stop_smc(rdev); | 2445 | btc_stop_smc(rdev); |
2409 | cypress_enable_spread_spectrum(rdev, false); | 2446 | cypress_enable_spread_spectrum(rdev, false); |
2447 | |||
2448 | btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps); | ||
2410 | } | 2449 | } |
2411 | 2450 | ||
2412 | void btc_dpm_setup_asic(struct radeon_device *rdev) | 2451 | void btc_dpm_setup_asic(struct radeon_device *rdev) |
@@ -2591,3 +2630,25 @@ void btc_dpm_fini(struct radeon_device *rdev) | |||
2591 | kfree(rdev->pm.dpm.priv); | 2630 | kfree(rdev->pm.dpm.priv); |
2592 | r600_free_extended_power_table(rdev); | 2631 | r600_free_extended_power_table(rdev); |
2593 | } | 2632 | } |
2633 | |||
2634 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low) | ||
2635 | { | ||
2636 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2637 | struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps); | ||
2638 | |||
2639 | if (low) | ||
2640 | return requested_state->low.sclk; | ||
2641 | else | ||
2642 | return requested_state->high.sclk; | ||
2643 | } | ||
2644 | |||
2645 | u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low) | ||
2646 | { | ||
2647 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2648 | struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps); | ||
2649 | |||
2650 | if (low) | ||
2651 | return requested_state->low.mclk; | ||
2652 | else | ||
2653 | return requested_state->high.mclk; | ||
2654 | } | ||