diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-04-29 00:22:43 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-18 04:21:35 -0400 |
commit | 539d24181753e40174746d576d415bfb56131975 (patch) | |
tree | 0aead71d6217f1e58a9a021c4c37131e930b6f6c /drivers/gpu | |
parent | 68adac5e49436992e9c999fbae879d9ac5b72d4e (diff) |
drm/radeon/kms: more pm fixes
- disable gui idle interrupt use
Seems to hang some r5xx chips
- move vbl range check into
existing vbl check function in
radeon_pm.c
- disable crtc mc acccess for the
whole reclocking process
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_reg.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 65 |
4 files changed, 45 insertions, 63 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 93aab2ebd9d0..af86af836f13 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -164,10 +164,12 @@ | |||
164 | #define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0) | 164 | #define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0) |
165 | 165 | ||
166 | /* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */ | 166 | /* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */ |
167 | #define EVERGREEN_CRTC_V_BLANK_START_END 0x6e34 | ||
167 | #define EVERGREEN_CRTC_CONTROL 0x6e70 | 168 | #define EVERGREEN_CRTC_CONTROL 0x6e70 |
168 | # define EVERGREEN_CRTC_MASTER_EN (1 << 0) | 169 | # define EVERGREEN_CRTC_MASTER_EN (1 << 0) |
169 | # define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) | 170 | # define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) |
170 | #define EVERGREEN_CRTC_STATUS 0x6e8c | 171 | #define EVERGREEN_CRTC_STATUS 0x6e8c |
172 | #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 | ||
171 | #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 | 173 | #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 |
172 | 174 | ||
173 | #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 | 175 | #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index a5f11c300f6a..493b9b48da30 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -178,14 +178,12 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch) | |||
178 | rdev->pm.current_sclk = sclk; | 178 | rdev->pm.current_sclk = sclk; |
179 | DRM_INFO("Setting: e: %d\n", sclk); | 179 | DRM_INFO("Setting: e: %d\n", sclk); |
180 | } | 180 | } |
181 | #if 0 | ||
182 | /* set memory clock */ | 181 | /* set memory clock */ |
183 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { | 182 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { |
184 | radeon_set_memory_clock(rdev, mclk); | 183 | radeon_set_memory_clock(rdev, mclk); |
185 | rdev->pm.current_mclk = mclk; | 184 | rdev->pm.current_mclk = mclk; |
186 | DRM_INFO("Setting: m: %d\n", mclk); | 185 | DRM_INFO("Setting: m: %d\n", mclk); |
187 | } | 186 | } |
188 | #endif | ||
189 | radeon_pm_finish(rdev); | 187 | radeon_pm_finish(rdev); |
190 | } else { | 188 | } else { |
191 | radeon_sync_with_vblank(rdev); | 189 | radeon_sync_with_vblank(rdev); |
@@ -193,6 +191,7 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch) | |||
193 | if (!radeon_pm_in_vbl(rdev)) | 191 | if (!radeon_pm_in_vbl(rdev)) |
194 | return; | 192 | return; |
195 | 193 | ||
194 | radeon_pm_prepare(rdev); | ||
196 | /* set engine clock */ | 195 | /* set engine clock */ |
197 | if (sclk != rdev->pm.current_sclk) { | 196 | if (sclk != rdev->pm.current_sclk) { |
198 | radeon_pm_debug_check_in_vbl(rdev, false); | 197 | radeon_pm_debug_check_in_vbl(rdev, false); |
@@ -205,13 +204,12 @@ void r100_set_power_state(struct radeon_device *rdev, bool static_switch) | |||
205 | /* set memory clock */ | 204 | /* set memory clock */ |
206 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { | 205 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { |
207 | radeon_pm_debug_check_in_vbl(rdev, false); | 206 | radeon_pm_debug_check_in_vbl(rdev, false); |
208 | radeon_pm_prepare(rdev); | ||
209 | radeon_set_memory_clock(rdev, mclk); | 207 | radeon_set_memory_clock(rdev, mclk); |
210 | radeon_pm_finish(rdev); | ||
211 | radeon_pm_debug_check_in_vbl(rdev, true); | 208 | radeon_pm_debug_check_in_vbl(rdev, true); |
212 | rdev->pm.current_mclk = mclk; | 209 | rdev->pm.current_mclk = mclk; |
213 | DRM_INFO("Setting: m: %d\n", mclk); | 210 | DRM_INFO("Setting: m: %d\n", mclk); |
214 | } | 211 | } |
212 | radeon_pm_finish(rdev); | ||
215 | } | 213 | } |
216 | 214 | ||
217 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; | 215 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d3a79e0a9125..75c825cb8790 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -256,7 +256,6 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch) | |||
256 | return; | 256 | return; |
257 | 257 | ||
258 | if (radeon_gui_idle(rdev)) { | 258 | if (radeon_gui_idle(rdev)) { |
259 | |||
260 | sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 259 | sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
261 | clock_info[rdev->pm.requested_clock_mode_index].sclk; | 260 | clock_info[rdev->pm.requested_clock_mode_index].sclk; |
262 | if (sclk > rdev->clock.default_sclk) | 261 | if (sclk > rdev->clock.default_sclk) |
@@ -271,52 +270,27 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch) | |||
271 | radeon_pm_misc(rdev); | 270 | radeon_pm_misc(rdev); |
272 | 271 | ||
273 | if (static_switch) { | 272 | if (static_switch) { |
274 | 273 | radeon_pm_prepare(rdev); | |
275 | /* set engine clock */ | 274 | /* set engine clock */ |
276 | if (sclk != rdev->pm.current_sclk) { | 275 | if (sclk != rdev->pm.current_sclk) { |
277 | radeon_set_engine_clock(rdev, sclk); | 276 | radeon_set_engine_clock(rdev, sclk); |
278 | rdev->pm.current_sclk = sclk; | 277 | rdev->pm.current_sclk = sclk; |
279 | DRM_INFO("Setting: e: %d\n", sclk); | 278 | DRM_INFO("Setting: e: %d\n", sclk); |
280 | } | 279 | } |
281 | |||
282 | /* set memory clock */ | 280 | /* set memory clock */ |
283 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { | 281 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { |
284 | radeon_pm_prepare(rdev); | ||
285 | radeon_set_memory_clock(rdev, mclk); | 282 | radeon_set_memory_clock(rdev, mclk); |
286 | radeon_pm_finish(rdev); | ||
287 | rdev->pm.current_mclk = mclk; | 283 | rdev->pm.current_mclk = mclk; |
288 | DRM_INFO("Setting: m: %d\n", mclk); | 284 | DRM_INFO("Setting: m: %d\n", mclk); |
289 | } | 285 | } |
290 | 286 | radeon_pm_finish(rdev); | |
291 | } else { | 287 | } else { |
292 | u32 position; | ||
293 | u32 vbl; | ||
294 | |||
295 | radeon_sync_with_vblank(rdev); | 288 | radeon_sync_with_vblank(rdev); |
296 | 289 | ||
297 | if (!radeon_pm_in_vbl(rdev)) | 290 | if (!radeon_pm_in_vbl(rdev)) |
298 | return; | 291 | return; |
299 | 292 | ||
300 | if (rdev->pm.active_crtcs & (1 << 0)) { | 293 | radeon_pm_prepare(rdev); |
301 | vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); | ||
302 | position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); | ||
303 | position &= 0xfff; | ||
304 | vbl &= 0xfff; | ||
305 | |||
306 | if (position < vbl && position > 1) | ||
307 | return; | ||
308 | } | ||
309 | |||
310 | if (rdev->pm.active_crtcs & (1 << 1)) { | ||
311 | vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); | ||
312 | position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); | ||
313 | position &= 0xfff; | ||
314 | vbl &= 0xfff; | ||
315 | |||
316 | if (position < vbl && position > 1) | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | if (sclk != rdev->pm.current_sclk) { | 294 | if (sclk != rdev->pm.current_sclk) { |
321 | radeon_pm_debug_check_in_vbl(rdev, false); | 295 | radeon_pm_debug_check_in_vbl(rdev, false); |
322 | radeon_set_engine_clock(rdev, sclk); | 296 | radeon_set_engine_clock(rdev, sclk); |
@@ -328,13 +302,12 @@ void r600_set_power_state(struct radeon_device *rdev, bool static_switch) | |||
328 | /* set memory clock */ | 302 | /* set memory clock */ |
329 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { | 303 | if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { |
330 | radeon_pm_debug_check_in_vbl(rdev, false); | 304 | radeon_pm_debug_check_in_vbl(rdev, false); |
331 | radeon_pm_prepare(rdev); | ||
332 | radeon_set_memory_clock(rdev, mclk); | 305 | radeon_set_memory_clock(rdev, mclk); |
333 | radeon_pm_finish(rdev); | ||
334 | radeon_pm_debug_check_in_vbl(rdev, true); | 306 | radeon_pm_debug_check_in_vbl(rdev, true); |
335 | rdev->pm.current_mclk = mclk; | 307 | rdev->pm.current_mclk = mclk; |
336 | DRM_INFO("Setting: m: %d\n", mclk); | 308 | DRM_INFO("Setting: m: %d\n", mclk); |
337 | } | 309 | } |
310 | radeon_pm_finish(rdev); | ||
338 | } | 311 | } |
339 | 312 | ||
340 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; | 313 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 88163e043fcf..2eb675e78440 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -64,7 +64,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch) | |||
64 | mutex_lock(&rdev->ddev->struct_mutex); | 64 | mutex_lock(&rdev->ddev->struct_mutex); |
65 | mutex_lock(&rdev->vram_mutex); | 65 | mutex_lock(&rdev->vram_mutex); |
66 | mutex_lock(&rdev->cp.mutex); | 66 | mutex_lock(&rdev->cp.mutex); |
67 | 67 | #if 0 | |
68 | /* wait for GPU idle */ | 68 | /* wait for GPU idle */ |
69 | rdev->pm.gui_idle = false; | 69 | rdev->pm.gui_idle = false; |
70 | rdev->irq.gui_idle = true; | 70 | rdev->irq.gui_idle = true; |
@@ -74,7 +74,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch) | |||
74 | msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); | 74 | msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); |
75 | rdev->irq.gui_idle = false; | 75 | rdev->irq.gui_idle = false; |
76 | radeon_irq_set(rdev); | 76 | radeon_irq_set(rdev); |
77 | 77 | #endif | |
78 | radeon_unmap_vram_bos(rdev); | 78 | radeon_unmap_vram_bos(rdev); |
79 | 79 | ||
80 | if (!static_switch) { | 80 | if (!static_switch) { |
@@ -85,7 +85,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev, int static_switch) | |||
85 | } | 85 | } |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | radeon_set_power_state(rdev, static_switch); | 89 | radeon_set_power_state(rdev, static_switch); |
90 | 90 | ||
91 | if (!static_switch) { | 91 | if (!static_switch) { |
@@ -389,51 +389,57 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) | |||
389 | 389 | ||
390 | bool radeon_pm_in_vbl(struct radeon_device *rdev) | 390 | bool radeon_pm_in_vbl(struct radeon_device *rdev) |
391 | { | 391 | { |
392 | u32 stat_crtc = 0; | 392 | u32 stat_crtc = 0, vbl = 0, position = 0; |
393 | bool in_vbl = true; | 393 | bool in_vbl = true; |
394 | 394 | ||
395 | if (ASIC_IS_DCE4(rdev)) { | 395 | if (ASIC_IS_DCE4(rdev)) { |
396 | if (rdev->pm.active_crtcs & (1 << 0)) { | 396 | if (rdev->pm.active_crtcs & (1 << 0)) { |
397 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); | 397 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
398 | if (!(stat_crtc & 1)) | 398 | EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; |
399 | in_vbl = false; | 399 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
400 | EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; | ||
400 | } | 401 | } |
401 | if (rdev->pm.active_crtcs & (1 << 1)) { | 402 | if (rdev->pm.active_crtcs & (1 << 1)) { |
402 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); | 403 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
403 | if (!(stat_crtc & 1)) | 404 | EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; |
404 | in_vbl = false; | 405 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
406 | EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; | ||
405 | } | 407 | } |
406 | if (rdev->pm.active_crtcs & (1 << 2)) { | 408 | if (rdev->pm.active_crtcs & (1 << 2)) { |
407 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); | 409 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
408 | if (!(stat_crtc & 1)) | 410 | EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; |
409 | in_vbl = false; | 411 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
412 | EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; | ||
410 | } | 413 | } |
411 | if (rdev->pm.active_crtcs & (1 << 3)) { | 414 | if (rdev->pm.active_crtcs & (1 << 3)) { |
412 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); | 415 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
413 | if (!(stat_crtc & 1)) | 416 | EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; |
414 | in_vbl = false; | 417 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
418 | EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; | ||
415 | } | 419 | } |
416 | if (rdev->pm.active_crtcs & (1 << 4)) { | 420 | if (rdev->pm.active_crtcs & (1 << 4)) { |
417 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); | 421 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
418 | if (!(stat_crtc & 1)) | 422 | EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; |
419 | in_vbl = false; | 423 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
424 | EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; | ||
420 | } | 425 | } |
421 | if (rdev->pm.active_crtcs & (1 << 5)) { | 426 | if (rdev->pm.active_crtcs & (1 << 5)) { |
422 | stat_crtc = RREG32(EVERGREEN_CRTC_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | 427 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
423 | if (!(stat_crtc & 1)) | 428 | EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; |
424 | in_vbl = false; | 429 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
430 | EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; | ||
425 | } | 431 | } |
426 | } else if (ASIC_IS_AVIVO(rdev)) { | 432 | } else if (ASIC_IS_AVIVO(rdev)) { |
427 | if (rdev->pm.active_crtcs & (1 << 0)) { | 433 | if (rdev->pm.active_crtcs & (1 << 0)) { |
428 | stat_crtc = RREG32(D1CRTC_STATUS); | 434 | vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff; |
429 | if (!(stat_crtc & 1)) | 435 | position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff; |
430 | in_vbl = false; | ||
431 | } | 436 | } |
432 | if (rdev->pm.active_crtcs & (1 << 1)) { | 437 | if (rdev->pm.active_crtcs & (1 << 1)) { |
433 | stat_crtc = RREG32(D2CRTC_STATUS); | 438 | vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff; |
434 | if (!(stat_crtc & 1)) | 439 | position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff; |
435 | in_vbl = false; | ||
436 | } | 440 | } |
441 | if (position < vbl && position > 1) | ||
442 | in_vbl = false; | ||
437 | } else { | 443 | } else { |
438 | if (rdev->pm.active_crtcs & (1 << 0)) { | 444 | if (rdev->pm.active_crtcs & (1 << 0)) { |
439 | stat_crtc = RREG32(RADEON_CRTC_STATUS); | 445 | stat_crtc = RREG32(RADEON_CRTC_STATUS); |
@@ -447,6 +453,9 @@ bool radeon_pm_in_vbl(struct radeon_device *rdev) | |||
447 | } | 453 | } |
448 | } | 454 | } |
449 | 455 | ||
456 | if (position < vbl && position > 1) | ||
457 | in_vbl = false; | ||
458 | |||
450 | return in_vbl; | 459 | return in_vbl; |
451 | } | 460 | } |
452 | 461 | ||