aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-09-04 05:04:34 -0400
committerDave Airlie <airlied@redhat.com>2010-10-05 21:38:08 -0400
commitd0f8a854c340986359a3b0a97e380c71def7a440 (patch)
tree4f4065bb8c920badc92f56c25b5b105066ae6fc2 /drivers/gpu/drm
parent724c80e1d630296d1324859e964d80d35007d83c (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')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c42
-rw-r--r--drivers/gpu/drm/radeon/r600d.h21
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c6
6 files changed, 64 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index e47d221e24ac..4c82cc830271 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1594,6 +1594,7 @@ int evergreen_irq_set(struct radeon_device *rdev)
1594 if (rdev->irq.sw_int) { 1594 if (rdev->irq.sw_int) {
1595 DRM_DEBUG("evergreen_irq_set: sw int\n"); 1595 DRM_DEBUG("evergreen_irq_set: sw int\n");
1596 cp_int_cntl |= RB_INT_ENABLE; 1596 cp_int_cntl |= RB_INT_ENABLE;
1597 cp_int_cntl |= TIME_STAMP_INT_ENABLE;
1597 } 1598 }
1598 if (rdev->irq.crtc_vblank_int[0]) { 1599 if (rdev->irq.crtc_vblank_int[0]) {
1599 DRM_DEBUG("evergreen_irq_set: vblank 0\n"); 1600 DRM_DEBUG("evergreen_irq_set: vblank 0\n");
@@ -2012,6 +2013,7 @@ restart_ih:
2012 break; 2013 break;
2013 case 181: /* CP EOP event */ 2014 case 181: /* CP EOP event */
2014 DRM_DEBUG("IH: CP EOP\n"); 2015 DRM_DEBUG("IH: CP EOP\n");
2016 radeon_fence_process(rdev);
2015 break; 2017 break;
2016 case 233: /* GUI IDLE */ 2018 case 233: /* GUI IDLE */
2017 DRM_DEBUG("IH: CP EOP\n"); 2019 DRM_DEBUG("IH: CP EOP\n");
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)
2279void r600_fence_ring_emit(struct radeon_device *rdev, 2279void 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
2299int r600_copy_blit(struct radeon_device *rdev, 2309int 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");
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 858a1920c0d7..966a793e225b 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -474,6 +474,7 @@
474#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 474#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58
475#define VTX_REUSE_DEPTH_MASK 0x000000FF 475#define VTX_REUSE_DEPTH_MASK 0x000000FF
476#define VGT_EVENT_INITIATOR 0x28a90 476#define VGT_EVENT_INITIATOR 0x28a90
477# define CACHE_FLUSH_AND_INV_EVENT_TS (0x14 << 0)
477# define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) 478# define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0)
478 479
479#define VM_CONTEXT0_CNTL 0x1410 480#define VM_CONTEXT0_CNTL 0x1410
@@ -775,7 +776,27 @@
775#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) 776#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
776#define PACKET3_COND_WRITE 0x45 777#define PACKET3_COND_WRITE 0x45
777#define PACKET3_EVENT_WRITE 0x46 778#define PACKET3_EVENT_WRITE 0x46
779#define EVENT_TYPE(x) ((x) << 0)
780#define EVENT_INDEX(x) ((x) << 8)
781 /* 0 - any non-TS event
782 * 1 - ZPASS_DONE
783 * 2 - SAMPLE_PIPELINESTAT
784 * 3 - SAMPLE_STREAMOUTSTAT*
785 * 4 - *S_PARTIAL_FLUSH
786 * 5 - TS events
787 */
778#define PACKET3_EVENT_WRITE_EOP 0x47 788#define PACKET3_EVENT_WRITE_EOP 0x47
789#define DATA_SEL(x) ((x) << 29)
790 /* 0 - discard
791 * 1 - send low 32bit data
792 * 2 - send 64bit data
793 * 3 - send 64bit counter value
794 */
795#define INT_SEL(x) ((x) << 24)
796 /* 0 - none
797 * 1 - interrupt only (DATA_SEL = 0)
798 * 2 - interrupt when data write is confirmed
799 */
779#define PACKET3_ONE_REG_WRITE 0x57 800#define PACKET3_ONE_REG_WRITE 0x57
780#define PACKET3_SET_CONFIG_REG 0x68 801#define PACKET3_SET_CONFIG_REG 0x68
781#define PACKET3_SET_CONFIG_REG_OFFSET 0x00008000 802#define PACKET3_SET_CONFIG_REG_OFFSET 0x00008000
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4e10938d8dd1..2bfae5679135 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -595,11 +595,13 @@ struct radeon_wb {
595 volatile uint32_t *wb; 595 volatile uint32_t *wb;
596 uint64_t gpu_addr; 596 uint64_t gpu_addr;
597 bool enabled; 597 bool enabled;
598 bool use_event;
598}; 599};
599 600
600#define RADEON_WB_SCRATCH_OFFSET 0 601#define RADEON_WB_SCRATCH_OFFSET 0
601#define RADEON_WB_CP_RPTR_OFFSET 1024 602#define RADEON_WB_CP_RPTR_OFFSET 1024
602#define R600_WB_IH_WPTR_OFFSET 2048 603#define R600_WB_IH_WPTR_OFFSET 2048
604#define R600_WB_EVENT_OFFSET 3072
603 605
604/** 606/**
605 * struct radeon_pm - power management datas 607 * struct radeon_pm - power management datas
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index cfc162d05010..8adfedfe547f 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -208,6 +208,8 @@ int radeon_wb_init(struct radeon_device *rdev)
208 return r; 208 return r;
209 } 209 }
210 210
211 /* disable event_write fences */
212 rdev->wb.use_event = false;
211 /* disabled via module param */ 213 /* disabled via module param */
212 if (radeon_no_wb == 1) 214 if (radeon_no_wb == 1)
213 rdev->wb.enabled = false; 215 rdev->wb.enabled = false;
@@ -215,8 +217,12 @@ int radeon_wb_init(struct radeon_device *rdev)
215 /* often unreliable on AGP */ 217 /* often unreliable on AGP */
216 if (rdev->flags & RADEON_IS_AGP) { 218 if (rdev->flags & RADEON_IS_AGP) {
217 rdev->wb.enabled = false; 219 rdev->wb.enabled = false;
218 } else 220 } else {
219 rdev->wb.enabled = true; 221 rdev->wb.enabled = true;
222 /* event_write fences are only available on r600+ */
223 if (rdev->family >= CHIP_R600)
224 rdev->wb.use_event = true;
225 }
220 } 226 }
221 227
222 dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis"); 228 dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis");
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 698a7ed3a6a1..216392d0353b 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -73,7 +73,11 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
73 unsigned long cjiffies; 73 unsigned long cjiffies;
74 74
75 if (rdev->wb.enabled) { 75 if (rdev->wb.enabled) {
76 u32 scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; 76 u32 scratch_index;
77 if (rdev->wb.use_event)
78 scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
79 else
80 scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
77 seq = rdev->wb.wb[scratch_index/4]; 81 seq = rdev->wb.wb[scratch_index/4];
78 } else 82 } else
79 seq = RREG32(rdev->fence_drv.scratch_reg); 83 seq = RREG32(rdev->fence_drv.scratch_reg);