diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2010-03-02 16:06:52 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-03-14 20:23:36 -0400 |
commit | d0d6cb81e7eb34d83461070ca3e919fba1db437c (patch) | |
tree | 02695def839a251fd087f778d71179085f44713b /drivers | |
parent | 839461d3b0e3082eb382f17a3e3899372f28649a (diff) |
drm/radeon/kms: prepare for more reclocking operations
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index d800b86af4d6..4f37b524de7e 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #define RADEON_RECLOCK_DELAY_MS 200 | 28 | #define RADEON_RECLOCK_DELAY_MS 200 |
29 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 | 29 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 |
30 | 30 | ||
31 | static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); | ||
31 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); | 32 | static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); |
32 | static void radeon_pm_set_clocks(struct radeon_device *rdev); | 33 | static void radeon_pm_set_clocks(struct radeon_device *rdev); |
33 | static void radeon_pm_idle_work_handler(struct work_struct *work); | 34 | static void radeon_pm_idle_work_handler(struct work_struct *work); |
@@ -179,6 +180,16 @@ static void radeon_get_power_state(struct radeon_device *rdev, | |||
179 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); | 180 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); |
180 | } | 181 | } |
181 | 182 | ||
183 | static inline void radeon_sync_with_vblank(struct radeon_device *rdev) | ||
184 | { | ||
185 | if (rdev->pm.active_crtcs) { | ||
186 | rdev->pm.vblank_sync = false; | ||
187 | wait_event_timeout( | ||
188 | rdev->irq.vblank_queue, rdev->pm.vblank_sync, | ||
189 | msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); | ||
190 | } | ||
191 | } | ||
192 | |||
182 | static void radeon_set_power_state(struct radeon_device *rdev) | 193 | static void radeon_set_power_state(struct radeon_device *rdev) |
183 | { | 194 | { |
184 | /* if *_clock_mode are the same, *_power_state are as well */ | 195 | /* if *_clock_mode are the same, *_power_state are as well */ |
@@ -189,11 +200,28 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
189 | rdev->pm.requested_clock_mode->sclk, | 200 | rdev->pm.requested_clock_mode->sclk, |
190 | rdev->pm.requested_clock_mode->mclk, | 201 | rdev->pm.requested_clock_mode->mclk, |
191 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); | 202 | rdev->pm.requested_power_state->non_clock_info.pcie_lanes); |
203 | |||
192 | /* set pcie lanes */ | 204 | /* set pcie lanes */ |
205 | /* TODO */ | ||
206 | |||
193 | /* set voltage */ | 207 | /* set voltage */ |
208 | /* TODO */ | ||
209 | |||
194 | /* set engine clock */ | 210 | /* set engine clock */ |
211 | radeon_sync_with_vblank(rdev); | ||
212 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
195 | radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); | 213 | radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); |
214 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
215 | |||
216 | #if 0 | ||
196 | /* set memory clock */ | 217 | /* set memory clock */ |
218 | if (rdev->asic->set_memory_clock) { | ||
219 | radeon_sync_with_vblank(rdev); | ||
220 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
221 | radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); | ||
222 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
223 | } | ||
224 | #endif | ||
197 | 225 | ||
198 | rdev->pm.current_power_state = rdev->pm.requested_power_state; | 226 | rdev->pm.current_power_state = rdev->pm.requested_power_state; |
199 | rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; | 227 | rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; |
@@ -333,10 +361,7 @@ static void radeon_pm_set_clocks_locked(struct radeon_device *rdev) | |||
333 | break; | 361 | break; |
334 | } | 362 | } |
335 | 363 | ||
336 | /* check if we are in vblank */ | ||
337 | radeon_pm_debug_check_in_vbl(rdev, false); | ||
338 | radeon_set_power_state(rdev); | 364 | radeon_set_power_state(rdev); |
339 | radeon_pm_debug_check_in_vbl(rdev, true); | ||
340 | rdev->pm.planned_action = PM_ACTION_NONE; | 365 | rdev->pm.planned_action = PM_ACTION_NONE; |
341 | } | 366 | } |
342 | 367 | ||
@@ -353,12 +378,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
353 | rdev->pm.req_vblank |= (1 << 1); | 378 | rdev->pm.req_vblank |= (1 << 1); |
354 | drm_vblank_get(rdev->ddev, 1); | 379 | drm_vblank_get(rdev->ddev, 1); |
355 | } | 380 | } |
356 | if (rdev->pm.active_crtcs) { | 381 | radeon_pm_set_clocks_locked(rdev); |
357 | rdev->pm.vblank_sync = false; | ||
358 | wait_event_timeout( | ||
359 | rdev->irq.vblank_queue, rdev->pm.vblank_sync, | ||
360 | msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); | ||
361 | } | ||
362 | if (rdev->pm.req_vblank & (1 << 0)) { | 382 | if (rdev->pm.req_vblank & (1 << 0)) { |
363 | rdev->pm.req_vblank &= ~(1 << 0); | 383 | rdev->pm.req_vblank &= ~(1 << 0); |
364 | drm_vblank_put(rdev->ddev, 0); | 384 | drm_vblank_put(rdev->ddev, 0); |
@@ -368,7 +388,6 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
368 | drm_vblank_put(rdev->ddev, 1); | 388 | drm_vblank_put(rdev->ddev, 1); |
369 | } | 389 | } |
370 | 390 | ||
371 | radeon_pm_set_clocks_locked(rdev); | ||
372 | mutex_unlock(&rdev->cp.mutex); | 391 | mutex_unlock(&rdev->cp.mutex); |
373 | } | 392 | } |
374 | 393 | ||