aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/btc_dpm.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-01-16 14:17:23 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-06-27 19:16:19 -0400
commite8a9539fa098623ae3af1e077b49794917ea073d (patch)
tree03ad49d920c3e668bb543e57fcac2527367a28a7 /drivers/gpu/drm/radeon/btc_dpm.c
parenta284c48ae7217fc362b851c68f74d7b414061704 (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.c81
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)
2062static void btc_apply_state_adjust_rules(struct radeon_device *rdev, 2062static 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
2219static 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
2230static 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
2225void btc_dpm_reset_asic(struct radeon_device *rdev) 2241void 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
2233int btc_dpm_set_power_state(struct radeon_device *rdev) 2249int 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
2262int 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
2304void 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
2277int btc_dpm_enable(struct radeon_device *rdev) 2312int 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
2412void btc_dpm_setup_asic(struct radeon_device *rdev) 2451void 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
2634u32 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
2645u32 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}