diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-09-04 05:04:34 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-10-05 21:38:08 -0400 |
commit | d0f8a854c340986359a3b0a97e380c71def7a440 (patch) | |
tree | 4f4065bb8c920badc92f56c25b5b105066ae6fc2 /drivers/gpu/drm/radeon/r600.c | |
parent | 724c80e1d630296d1324859e964d80d35007d83c (diff) |
drm/radeon/kms/r6xx+: use new style fencing (v3)
On r6xx+ a newer fence mechanism was implemented to replace
the old wait_until plus scratch regs setup. A single EOP event
will flush the destination caches, write a fence value, and generate
an interrupt. This is the recommended fence mechanism on r6xx+ asics.
This requires my previous writeback patch.
v2: fix typo that enabled event fence checking on all asics
rather than just r6xx+.
v3: properly enable EOP interrupts
Should fix:
https://bugs.freedesktop.org/show_bug.cgi?id=29972
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index fbce58b2cd04..7c5f855a43e6 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2279,21 +2279,31 @@ int r600_ring_test(struct radeon_device *rdev) | |||
2279 | void r600_fence_ring_emit(struct radeon_device *rdev, | 2279 | void r600_fence_ring_emit(struct radeon_device *rdev, |
2280 | struct radeon_fence *fence) | 2280 | struct radeon_fence *fence) |
2281 | { | 2281 | { |
2282 | /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */ | 2282 | if (rdev->wb.use_event) { |
2283 | 2283 | u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + | |
2284 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | 2284 | (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); |
2285 | radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); | 2285 | /* EVENT_WRITE_EOP - flush caches, send int */ |
2286 | /* wait for 3D idle clean */ | 2286 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); |
2287 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2287 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); |
2288 | radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 2288 | radeon_ring_write(rdev, addr & 0xffffffff); |
2289 | radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); | 2289 | radeon_ring_write(rdev, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); |
2290 | /* Emit fence sequence & fire IRQ */ | 2290 | radeon_ring_write(rdev, fence->seq); |
2291 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2291 | radeon_ring_write(rdev, 0); |
2292 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 2292 | } else { |
2293 | radeon_ring_write(rdev, fence->seq); | 2293 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); |
2294 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ | 2294 | radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); |
2295 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | 2295 | /* wait for 3D idle clean */ |
2296 | radeon_ring_write(rdev, RB_INT_STAT); | 2296 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
2297 | radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | ||
2298 | radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); | ||
2299 | /* Emit fence sequence & fire IRQ */ | ||
2300 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
2301 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | ||
2302 | radeon_ring_write(rdev, fence->seq); | ||
2303 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ | ||
2304 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | ||
2305 | radeon_ring_write(rdev, RB_INT_STAT); | ||
2306 | } | ||
2297 | } | 2307 | } |
2298 | 2308 | ||
2299 | int r600_copy_blit(struct radeon_device *rdev, | 2309 | int r600_copy_blit(struct radeon_device *rdev, |
@@ -3012,6 +3022,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3012 | if (rdev->irq.sw_int) { | 3022 | if (rdev->irq.sw_int) { |
3013 | DRM_DEBUG("r600_irq_set: sw int\n"); | 3023 | DRM_DEBUG("r600_irq_set: sw int\n"); |
3014 | cp_int_cntl |= RB_INT_ENABLE; | 3024 | cp_int_cntl |= RB_INT_ENABLE; |
3025 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | ||
3015 | } | 3026 | } |
3016 | if (rdev->irq.crtc_vblank_int[0]) { | 3027 | if (rdev->irq.crtc_vblank_int[0]) { |
3017 | DRM_DEBUG("r600_irq_set: vblank 0\n"); | 3028 | DRM_DEBUG("r600_irq_set: vblank 0\n"); |
@@ -3377,6 +3388,7 @@ restart_ih: | |||
3377 | break; | 3388 | break; |
3378 | case 181: /* CP EOP event */ | 3389 | case 181: /* CP EOP event */ |
3379 | DRM_DEBUG("IH: CP EOP\n"); | 3390 | DRM_DEBUG("IH: CP EOP\n"); |
3391 | radeon_fence_process(rdev); | ||
3380 | break; | 3392 | break; |
3381 | case 233: /* GUI IDLE */ | 3393 | case 233: /* GUI IDLE */ |
3382 | DRM_DEBUG("IH: CP EOP\n"); | 3394 | DRM_DEBUG("IH: CP EOP\n"); |