diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-04-22 13:38:05 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-18 04:20:57 -0400 |
commit | bae6b5627387a950a8faf366d6027bd0a7a93078 (patch) | |
tree | b69ef13dcec3808efc53a7daf7041a88d3e6427a /drivers/gpu/drm/radeon/radeon_pm.c | |
parent | 03214bd5c6e59c83703238227254deef8810513d (diff) |
drm/radeon/kms/pm: add asic specific callbacks for setting power state (v2)
(v2) Add evergreen vbl checks
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 100 |
1 files changed, 52 insertions, 48 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index ff3abd8c896..129956d003a 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 | 29 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 |
30 | #define RADEON_WAIT_IDLE_TIMEOUT 200 | 30 | #define RADEON_WAIT_IDLE_TIMEOUT 200 |
31 | 31 | ||
32 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); | ||
33 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); | 32 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); |
34 | static void radeon_pm_set_clocks(struct radeon_device *rdev); | 33 | static void radeon_pm_set_clocks(struct radeon_device *rdev); |
35 | static void radeon_pm_idle_work_handler(struct work_struct *work); | 34 | static void radeon_pm_idle_work_handler(struct work_struct *work); |
@@ -181,7 +180,7 @@ static void radeon_get_power_state(struct radeon_device *rdev, | |||
181 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); | 180 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); |
182 | } | 181 | } |
183 | 182 | ||
184 | static inline void radeon_sync_with_vblank(struct radeon_device *rdev) | 183 | void radeon_sync_with_vblank(struct radeon_device *rdev) |
185 | { | 184 | { |
186 | if (rdev->pm.active_crtcs) { | 185 | if (rdev->pm.active_crtcs) { |
187 | rdev->pm.vblank_sync = false; | 186 | rdev->pm.vblank_sync = false; |
@@ -191,43 +190,6 @@ static inline void radeon_sync_with_vblank(struct radeon_device *rdev) | |||
191 | } | 190 | } |
192 | } | 191 | } |
193 | 192 | ||
194 | static void radeon_set_power_state(struct radeon_device *rdev) | ||
195 | { | ||
196 | /* if *_clock_mode are the same, *_power_state are as well */ | ||
197 | if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode) | ||
198 | return; | ||
199 | |||
200 | DRM_INFO("Setting: e: %d m: %d p: %d\n", | ||
201 | rdev->pm.requested_clock_mode->sclk, | ||
202 | rdev->pm.requested_clock_mode->mclk, | ||
203 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); | ||
204 | |||
205 | /* set pcie lanes */ | ||
206 | /* TODO */ | ||
207 | |||
208 | /* set voltage */ | ||
209 | /* TODO */ | ||
210 | |||
211 | /* set engine clock */ | ||
212 | radeon_sync_with_vblank(rdev); | ||
213 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
214 | radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); | ||
215 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
216 | |||
217 | #if 0 | ||
218 | /* set memory clock */ | ||
219 | if (rdev->asic->set_memory_clock) { | ||
220 | radeon_sync_with_vblank(rdev); | ||
221 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
222 | radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); | ||
223 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
224 | } | ||
225 | #endif | ||
226 | |||
227 | rdev->pm.current_power_state = rdev->pm.requested_power_state; | ||
228 | rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; | ||
229 | } | ||
230 | |||
231 | int radeon_pm_init(struct radeon_device *rdev) | 193 | int radeon_pm_init(struct radeon_device *rdev) |
232 | { | 194 | { |
233 | rdev->pm.state = PM_STATE_DISABLED; | 195 | rdev->pm.state = PM_STATE_DISABLED; |
@@ -330,26 +292,68 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) | |||
330 | mutex_unlock(&rdev->pm.mutex); | 292 | mutex_unlock(&rdev->pm.mutex); |
331 | } | 293 | } |
332 | 294 | ||
333 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) | 295 | bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) |
334 | { | 296 | { |
335 | u32 stat_crtc1 = 0, stat_crtc2 = 0; | 297 | u32 stat_crtc = 0; |
336 | bool in_vbl = true; | 298 | bool in_vbl = true; |
337 | 299 | ||
338 | if (ASIC_IS_AVIVO(rdev)) { | 300 | if (ASIC_IS_DCE4(rdev)) { |
301 | if (rdev->pm.active_crtcs & (1 << 0)) { | ||
302 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
303 | if (!(stat_crtc & 1)) | ||
304 | in_vbl = false; | ||
305 | } | ||
306 | if (rdev->pm.active_crtcs & (1 << 1)) { | ||
307 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
308 | if (!(stat_crtc & 1)) | ||
309 | in_vbl = false; | ||
310 | } | ||
311 | if (rdev->pm.active_crtcs & (1 << 2)) { | ||
312 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
313 | if (!(stat_crtc & 1)) | ||
314 | in_vbl = false; | ||
315 | } | ||
316 | if (rdev->pm.active_crtcs & (1 << 3)) { | ||
317 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
318 | if (!(stat_crtc & 1)) | ||
319 | in_vbl = false; | ||
320 | } | ||
321 | if (rdev->pm.active_crtcs & (1 << 4)) { | ||
322 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
323 | if (!(stat_crtc & 1)) | ||
324 | in_vbl = false; | ||
325 | } | ||
326 | if (rdev->pm.active_crtcs & (1 << 5)) { | ||
327 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
328 | if (!(stat_crtc & 1)) | ||
329 | in_vbl = false; | ||
330 | } | ||
331 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
332 | if (rdev->pm.active_crtcs & (1 << 0)) { | ||
333 | stat_crtc = RREG32(D1CRTC_STATUS); | ||
334 | if (!(stat_crtc & 1)) | ||
335 | in_vbl = false; | ||
336 | } | ||
337 | if (rdev->pm.active_crtcs & (1 << 1)) { | ||
338 | stat_crtc = RREG32(D2CRTC_STATUS); | ||
339 | if (!(stat_crtc & 1)) | ||
340 | in_vbl = false; | ||
341 | } | ||
342 | } else { | ||
339 | if (rdev->pm.active_crtcs & (1 << 0)) { | 343 | if (rdev->pm.active_crtcs & (1 << 0)) { |
340 | stat_crtc1 = RREG32(D1CRTC_STATUS); | 344 | stat_crtc = RREG32(RADEON_CRTC_STATUS); |
341 | if (!(stat_crtc1 & 1)) | 345 | if (!(stat_crtc & 1)) |
342 | in_vbl = false; | 346 | in_vbl = false; |
343 | } | 347 | } |
344 | if (rdev->pm.active_crtcs & (1 << 1)) { | 348 | if (rdev->pm.active_crtcs & (1 << 1)) { |
345 | stat_crtc2 = RREG32(D2CRTC_STATUS); | 349 | stat_crtc = RREG32(RADEON_CRTC2_STATUS); |
346 | if (!(stat_crtc2 & 1)) | 350 | if (!(stat_crtc & 1)) |
347 | in_vbl = false; | 351 | in_vbl = false; |
348 | } | 352 | } |
349 | } | 353 | } |
350 | if (in_vbl == false) | 354 | if (in_vbl == false) |
351 | DRM_INFO("not in vbl for pm change %08x %08x at %s\n", stat_crtc1, | 355 | DRM_INFO("not in vbl for pm change %08x at %s\n", stat_crtc, |
352 | stat_crtc2, finish ? "exit" : "entry"); | 356 | finish ? "exit" : "entry"); |
353 | return in_vbl; | 357 | return in_vbl; |
354 | } | 358 | } |
355 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev) | 359 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev) |