aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2011-08-25 13:39:48 -0400
committerDave Airlie <airlied@redhat.com>2011-12-20 14:49:28 -0500
commit7465280c076d6440e5908c158c83b542dc063a30 (patch)
tree7781cffcc3784293e5bb97f20fb4a6c8109684ec /drivers/gpu/drm
parent851a6bd99edda0094def3b0b81bb1c7c0e886e65 (diff)
drm/radeon/kms: add support for multiple fence queues v2
For supporting multiple CP ring buffers, async DMA engines and UVD. We still need a way to synchronize between engines. v2 initialize unused fence driver ring to avoid issue in suspend/unload Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c6
-rw-r--r--drivers/gpu/drm/radeon/ni.c2
-rw-r--r--drivers/gpu/drm/radeon/r100.c6
-rw-r--r--drivers/gpu/drm/radeon/r300.c4
-rw-r--r--drivers/gpu/drm/radeon/r420.c2
-rw-r--r--drivers/gpu/drm/radeon/r520.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon.h28
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c232
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c2
-rw-r--r--drivers/gpu/drm/radeon/rs400.c2
-rw-r--r--drivers/gpu/drm/radeon/rs600.c4
-rw-r--r--drivers/gpu/drm/radeon/rs690.c2
-rw-r--r--drivers/gpu/drm/radeon/rv515.c2
-rw-r--r--drivers/gpu/drm/radeon/rv770.c2
20 files changed, 201 insertions, 150 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 5e00d1670aa9..1c7af5654336 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3018,11 +3018,11 @@ restart_ih:
3018 case 177: /* CP_INT in IB1 */ 3018 case 177: /* CP_INT in IB1 */
3019 case 178: /* CP_INT in IB2 */ 3019 case 178: /* CP_INT in IB2 */
3020 DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); 3020 DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
3021 radeon_fence_process(rdev); 3021 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
3022 break; 3022 break;
3023 case 181: /* CP EOP event */ 3023 case 181: /* CP EOP event */
3024 DRM_DEBUG("IH: CP EOP\n"); 3024 DRM_DEBUG("IH: CP EOP\n");
3025 radeon_fence_process(rdev); 3025 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
3026 break; 3026 break;
3027 case 233: /* GUI IDLE */ 3027 case 233: /* GUI IDLE */
3028 DRM_DEBUG("IH: GUI idle\n"); 3028 DRM_DEBUG("IH: GUI idle\n");
@@ -3221,7 +3221,7 @@ int evergreen_init(struct radeon_device *rdev)
3221 /* Initialize clocks */ 3221 /* Initialize clocks */
3222 radeon_get_clock_info(rdev->ddev); 3222 radeon_get_clock_info(rdev->ddev);
3223 /* Fence driver */ 3223 /* Fence driver */
3224 r = radeon_fence_driver_init(rdev); 3224 r = radeon_fence_driver_init(rdev, 1);
3225 if (r) 3225 if (r)
3226 return r; 3226 return r;
3227 /* initialize AGP */ 3227 /* initialize AGP */
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 0e5799857465..710ad8c82767 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1484,7 +1484,7 @@ int cayman_init(struct radeon_device *rdev)
1484 /* Initialize clocks */ 1484 /* Initialize clocks */
1485 radeon_get_clock_info(rdev->ddev); 1485 radeon_get_clock_info(rdev->ddev);
1486 /* Fence driver */ 1486 /* Fence driver */
1487 r = radeon_fence_driver_init(rdev); 1487 r = radeon_fence_driver_init(rdev, 3);
1488 if (r) 1488 if (r)
1489 return r; 1489 return r;
1490 /* initialize memory controller */ 1490 /* initialize memory controller */
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index bfc08f6320f8..d2dced5679b5 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -739,7 +739,7 @@ int r100_irq_process(struct radeon_device *rdev)
739 while (status) { 739 while (status) {
740 /* SW interrupt */ 740 /* SW interrupt */
741 if (status & RADEON_SW_INT_TEST) { 741 if (status & RADEON_SW_INT_TEST) {
742 radeon_fence_process(rdev); 742 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
743 } 743 }
744 /* gui idle interrupt */ 744 /* gui idle interrupt */
745 if (status & RADEON_GUI_IDLE_STAT) { 745 if (status & RADEON_GUI_IDLE_STAT) {
@@ -826,7 +826,7 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
826 radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); 826 radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
827 radeon_ring_write(rdev, rdev->config.r100.hdp_cntl); 827 radeon_ring_write(rdev, rdev->config.r100.hdp_cntl);
828 /* Emit fence sequence & fire IRQ */ 828 /* Emit fence sequence & fire IRQ */
829 radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); 829 radeon_ring_write(rdev, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0));
830 radeon_ring_write(rdev, fence->seq); 830 radeon_ring_write(rdev, fence->seq);
831 radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); 831 radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0));
832 radeon_ring_write(rdev, RADEON_SW_INT_FIRE); 832 radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
@@ -4048,7 +4048,7 @@ int r100_init(struct radeon_device *rdev)
4048 /* initialize VRAM */ 4048 /* initialize VRAM */
4049 r100_mc_init(rdev); 4049 r100_mc_init(rdev);
4050 /* Fence driver */ 4050 /* Fence driver */
4051 r = radeon_fence_driver_init(rdev); 4051 r = radeon_fence_driver_init(rdev, 1);
4052 if (r) 4052 if (r)
4053 return r; 4053 return r;
4054 r = radeon_irq_kms_init(rdev); 4054 r = radeon_irq_kms_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index c93bc64707e1..b04731206460 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -198,7 +198,7 @@ void r300_fence_ring_emit(struct radeon_device *rdev,
198 radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); 198 radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
199 radeon_ring_write(rdev, rdev->config.r300.hdp_cntl); 199 radeon_ring_write(rdev, rdev->config.r300.hdp_cntl);
200 /* Emit fence sequence & fire IRQ */ 200 /* Emit fence sequence & fire IRQ */
201 radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); 201 radeon_ring_write(rdev, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0));
202 radeon_ring_write(rdev, fence->seq); 202 radeon_ring_write(rdev, fence->seq);
203 radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); 203 radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0));
204 radeon_ring_write(rdev, RADEON_SW_INT_FIRE); 204 radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
@@ -1518,7 +1518,7 @@ int r300_init(struct radeon_device *rdev)
1518 /* initialize memory controller */ 1518 /* initialize memory controller */
1519 r300_mc_init(rdev); 1519 r300_mc_init(rdev);
1520 /* Fence driver */ 1520 /* Fence driver */
1521 r = radeon_fence_driver_init(rdev); 1521 r = radeon_fence_driver_init(rdev, 1);
1522 if (r) 1522 if (r)
1523 return r; 1523 return r;
1524 r = radeon_irq_kms_init(rdev); 1524 r = radeon_irq_kms_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 417fab81812f..5dbc378d3c2e 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -387,7 +387,7 @@ int r420_init(struct radeon_device *rdev)
387 r300_mc_init(rdev); 387 r300_mc_init(rdev);
388 r420_debugfs(rdev); 388 r420_debugfs(rdev);
389 /* Fence driver */ 389 /* Fence driver */
390 r = radeon_fence_driver_init(rdev); 390 r = radeon_fence_driver_init(rdev, 1);
391 if (r) { 391 if (r) {
392 return r; 392 return r;
393 } 393 }
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 3081d07f8de5..cb96a51f7f7c 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -278,7 +278,7 @@ int r520_init(struct radeon_device *rdev)
278 r520_mc_init(rdev); 278 r520_mc_init(rdev);
279 rv515_debugfs(rdev); 279 rv515_debugfs(rdev);
280 /* Fence driver */ 280 /* Fence driver */
281 r = radeon_fence_driver_init(rdev); 281 r = radeon_fence_driver_init(rdev, 1);
282 if (r) 282 if (r)
283 return r; 283 return r;
284 r = radeon_irq_kms_init(rdev); 284 r = radeon_irq_kms_init(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 9cdda0b3b081..2fff8cec723c 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2316,7 +2316,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
2316{ 2316{
2317 if (rdev->wb.use_event) { 2317 if (rdev->wb.use_event) {
2318 u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + 2318 u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET +
2319 (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); 2319 (u64)(rdev->fence_drv[fence->ring].scratch_reg - rdev->scratch.reg_base);
2320 /* flush read cache over gart */ 2320 /* flush read cache over gart */
2321 radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); 2321 radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
2322 radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | 2322 radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA |
@@ -2349,7 +2349,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
2349 radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); 2349 radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
2350 /* Emit fence sequence & fire IRQ */ 2350 /* Emit fence sequence & fire IRQ */
2351 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 2351 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
2352 radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); 2352 radeon_ring_write(rdev, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
2353 radeon_ring_write(rdev, fence->seq); 2353 radeon_ring_write(rdev, fence->seq);
2354 /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ 2354 /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
2355 radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); 2355 radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0));
@@ -2575,7 +2575,7 @@ int r600_init(struct radeon_device *rdev)
2575 /* Initialize clocks */ 2575 /* Initialize clocks */
2576 radeon_get_clock_info(rdev->ddev); 2576 radeon_get_clock_info(rdev->ddev);
2577 /* Fence driver */ 2577 /* Fence driver */
2578 r = radeon_fence_driver_init(rdev); 2578 r = radeon_fence_driver_init(rdev, 1);
2579 if (r) 2579 if (r)
2580 return r; 2580 return r;
2581 if (rdev->flags & RADEON_IS_AGP) { 2581 if (rdev->flags & RADEON_IS_AGP) {
@@ -3459,11 +3459,11 @@ restart_ih:
3459 case 177: /* CP_INT in IB1 */ 3459 case 177: /* CP_INT in IB1 */
3460 case 178: /* CP_INT in IB2 */ 3460 case 178: /* CP_INT in IB2 */
3461 DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); 3461 DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
3462 radeon_fence_process(rdev); 3462 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
3463 break; 3463 break;
3464 case 181: /* CP EOP event */ 3464 case 181: /* CP EOP event */
3465 DRM_DEBUG("IH: CP EOP\n"); 3465 DRM_DEBUG("IH: CP EOP\n");
3466 radeon_fence_process(rdev); 3466 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
3467 break; 3467 break;
3468 case 233: /* GUI IDLE */ 3468 case 233: /* GUI IDLE */
3469 DRM_DEBUG("IH: GUI idle\n"); 3469 DRM_DEBUG("IH: GUI idle\n");
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 33f3be369a27..8b93dec66ec6 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -197,7 +197,6 @@ struct radeon_fence_driver {
197 unsigned long last_jiffies; 197 unsigned long last_jiffies;
198 unsigned long last_timeout; 198 unsigned long last_timeout;
199 wait_queue_head_t queue; 199 wait_queue_head_t queue;
200 rwlock_t lock;
201 struct list_head created; 200 struct list_head created;
202 struct list_head emitted; 201 struct list_head emitted;
203 struct list_head signaled; 202 struct list_head signaled;
@@ -212,17 +211,19 @@ struct radeon_fence {
212 uint32_t seq; 211 uint32_t seq;
213 bool emitted; 212 bool emitted;
214 bool signaled; 213 bool signaled;
214 /* RB, DMA, etc. */
215 int ring;
215}; 216};
216 217
217int radeon_fence_driver_init(struct radeon_device *rdev); 218int radeon_fence_driver_init(struct radeon_device *rdev, int num_rings);
218void radeon_fence_driver_fini(struct radeon_device *rdev); 219void radeon_fence_driver_fini(struct radeon_device *rdev);
219int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence); 220int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence, int ring);
220int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence); 221int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence);
221void radeon_fence_process(struct radeon_device *rdev); 222void radeon_fence_process(struct radeon_device *rdev, int ring);
222bool radeon_fence_signaled(struct radeon_fence *fence); 223bool radeon_fence_signaled(struct radeon_fence *fence);
223int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); 224int radeon_fence_wait(struct radeon_fence *fence, bool interruptible);
224int radeon_fence_wait_next(struct radeon_device *rdev); 225int radeon_fence_wait_next(struct radeon_device *rdev, int ring);
225int radeon_fence_wait_last(struct radeon_device *rdev); 226int radeon_fence_wait_last(struct radeon_device *rdev, int ring);
226struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence); 227struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
227void radeon_fence_unref(struct radeon_fence **fence); 228void radeon_fence_unref(struct radeon_fence **fence);
228 229
@@ -459,6 +460,18 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc);
459/* 460/*
460 * CP & ring. 461 * CP & ring.
461 */ 462 */
463
464/* max number of rings */
465#define RADEON_NUM_RINGS 3
466
467/* internal ring indices */
468/* r1xx+ has gfx CP ring */
469#define RADEON_RING_TYPE_GFX_INDEX 0
470
471/* cayman has 2 compute CP rings */
472#define CAYMAN_RING_TYPE_CP1_INDEX 1
473#define CAYMAN_RING_TYPE_CP2_INDEX 2
474
462struct radeon_ib { 475struct radeon_ib {
463 struct list_head list; 476 struct list_head list;
464 unsigned idx; 477 unsigned idx;
@@ -1235,7 +1248,8 @@ struct radeon_device {
1235 struct radeon_mode_info mode_info; 1248 struct radeon_mode_info mode_info;
1236 struct radeon_scratch scratch; 1249 struct radeon_scratch scratch;
1237 struct radeon_mman mman; 1250 struct radeon_mman mman;
1238 struct radeon_fence_driver fence_drv; 1251 rwlock_t fence_lock;
1252 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS];
1239 struct radeon_cp cp; 1253 struct radeon_cp cp;
1240 /* cayman compute rings */ 1254 /* cayman compute rings */
1241 struct radeon_cp cp1; 1255 struct radeon_cp cp1;
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 17e1a9b2d8fb..4f749a69c9c5 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -43,7 +43,7 @@ static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size,
43 43
44 start_jiffies = jiffies; 44 start_jiffies = jiffies;
45 for (i = 0; i < n; i++) { 45 for (i = 0; i < n; i++) {
46 r = radeon_fence_create(rdev, &fence); 46 r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
47 if (r) 47 if (r)
48 return r; 48 return r;
49 49
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 4d66d6868571..4ed4eeb62cdf 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -725,7 +725,7 @@ int radeon_device_init(struct radeon_device *rdev,
725 mutex_init(&rdev->gem.mutex); 725 mutex_init(&rdev->gem.mutex);
726 mutex_init(&rdev->pm.mutex); 726 mutex_init(&rdev->pm.mutex);
727 mutex_init(&rdev->vram_mutex); 727 mutex_init(&rdev->vram_mutex);
728 rwlock_init(&rdev->fence_drv.lock); 728 rwlock_init(&rdev->fence_lock);
729 INIT_LIST_HEAD(&rdev->gem.objects); 729 INIT_LIST_HEAD(&rdev->gem.objects);
730 init_waitqueue_head(&rdev->irq.vblank_queue); 730 init_waitqueue_head(&rdev->irq.vblank_queue);
731 init_waitqueue_head(&rdev->irq.idle_queue); 731 init_waitqueue_head(&rdev->irq.idle_queue);
@@ -857,7 +857,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
857 struct radeon_device *rdev; 857 struct radeon_device *rdev;
858 struct drm_crtc *crtc; 858 struct drm_crtc *crtc;
859 struct drm_connector *connector; 859 struct drm_connector *connector;
860 int r; 860 int i, r;
861 861
862 if (dev == NULL || dev->dev_private == NULL) { 862 if (dev == NULL || dev->dev_private == NULL) {
863 return -ENODEV; 863 return -ENODEV;
@@ -896,7 +896,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
896 /* evict vram memory */ 896 /* evict vram memory */
897 radeon_bo_evict_vram(rdev); 897 radeon_bo_evict_vram(rdev);
898 /* wait for gpu to finish processing current batch */ 898 /* wait for gpu to finish processing current batch */
899 radeon_fence_wait_last(rdev); 899 for (i = 0; i < RADEON_NUM_RINGS; i++)
900 radeon_fence_wait_last(rdev, i);
900 901
901 radeon_save_bios_scratch_regs(rdev); 902 radeon_save_bios_scratch_regs(rdev);
902 903
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 7027766ec2a5..086b8a399118 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -40,32 +40,37 @@
40#include "radeon.h" 40#include "radeon.h"
41#include "radeon_trace.h" 41#include "radeon_trace.h"
42 42
43static void radeon_fence_write(struct radeon_device *rdev, u32 seq) 43static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
44{ 44{
45 u32 scratch_index;
46
45 if (rdev->wb.enabled) { 47 if (rdev->wb.enabled) {
46 u32 scratch_index;
47 if (rdev->wb.use_event) 48 if (rdev->wb.use_event)
48 scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; 49 scratch_index = R600_WB_EVENT_OFFSET +
50 rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base;
49 else 51 else
50 scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; 52 scratch_index = RADEON_WB_SCRATCH_OFFSET +
53 rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base;
51 rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq); 54 rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);
52 } else 55 } else
53 WREG32(rdev->fence_drv.scratch_reg, seq); 56 WREG32(rdev->fence_drv[ring].scratch_reg, seq);
54} 57}
55 58
56static u32 radeon_fence_read(struct radeon_device *rdev) 59static u32 radeon_fence_read(struct radeon_device *rdev, int ring)
57{ 60{
58 u32 seq; 61 u32 seq = 0;
62 u32 scratch_index;
59 63
60 if (rdev->wb.enabled) { 64 if (rdev->wb.enabled) {
61 u32 scratch_index;
62 if (rdev->wb.use_event) 65 if (rdev->wb.use_event)
63 scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; 66 scratch_index = R600_WB_EVENT_OFFSET +
67 rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base;
64 else 68 else
65 scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; 69 scratch_index = RADEON_WB_SCRATCH_OFFSET +
70 rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base;
66 seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); 71 seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
67 } else 72 } else
68 seq = RREG32(rdev->fence_drv.scratch_reg); 73 seq = RREG32(rdev->fence_drv[ring].scratch_reg);
69 return seq; 74 return seq;
70} 75}
71 76
@@ -73,28 +78,28 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
73{ 78{
74 unsigned long irq_flags; 79 unsigned long irq_flags;
75 80
76 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 81 write_lock_irqsave(&rdev->fence_lock, irq_flags);
77 if (fence->emitted) { 82 if (fence->emitted) {
78 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 83 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
79 return 0; 84 return 0;
80 } 85 }
81 fence->seq = atomic_add_return(1, &rdev->fence_drv.seq); 86 fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq);
82 if (!rdev->cp.ready) 87 if (!rdev->cp.ready)
83 /* FIXME: cp is not running assume everythings is done right 88 /* FIXME: cp is not running assume everythings is done right
84 * away 89 * away
85 */ 90 */
86 radeon_fence_write(rdev, fence->seq); 91 radeon_fence_write(rdev, fence->seq, fence->ring);
87 else 92 else
88 radeon_fence_ring_emit(rdev, fence); 93 radeon_fence_ring_emit(rdev, fence);
89 94
90 trace_radeon_fence_emit(rdev->ddev, fence->seq); 95 trace_radeon_fence_emit(rdev->ddev, fence->seq);
91 fence->emitted = true; 96 fence->emitted = true;
92 list_move_tail(&fence->list, &rdev->fence_drv.emitted); 97 list_move_tail(&fence->list, &rdev->fence_drv[fence->ring].emitted);
93 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 98 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
94 return 0; 99 return 0;
95} 100}
96 101
97static bool radeon_fence_poll_locked(struct radeon_device *rdev) 102static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring)
98{ 103{
99 struct radeon_fence *fence; 104 struct radeon_fence *fence;
100 struct list_head *i, *n; 105 struct list_head *i, *n;
@@ -102,34 +107,34 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
102 bool wake = false; 107 bool wake = false;
103 unsigned long cjiffies; 108 unsigned long cjiffies;
104 109
105 seq = radeon_fence_read(rdev); 110 seq = radeon_fence_read(rdev, ring);
106 if (seq != rdev->fence_drv.last_seq) { 111 if (seq != rdev->fence_drv[ring].last_seq) {
107 rdev->fence_drv.last_seq = seq; 112 rdev->fence_drv[ring].last_seq = seq;
108 rdev->fence_drv.last_jiffies = jiffies; 113 rdev->fence_drv[ring].last_jiffies = jiffies;
109 rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; 114 rdev->fence_drv[ring].last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
110 } else { 115 } else {
111 cjiffies = jiffies; 116 cjiffies = jiffies;
112 if (time_after(cjiffies, rdev->fence_drv.last_jiffies)) { 117 if (time_after(cjiffies, rdev->fence_drv[ring].last_jiffies)) {
113 cjiffies -= rdev->fence_drv.last_jiffies; 118 cjiffies -= rdev->fence_drv[ring].last_jiffies;
114 if (time_after(rdev->fence_drv.last_timeout, cjiffies)) { 119 if (time_after(rdev->fence_drv[ring].last_timeout, cjiffies)) {
115 /* update the timeout */ 120 /* update the timeout */
116 rdev->fence_drv.last_timeout -= cjiffies; 121 rdev->fence_drv[ring].last_timeout -= cjiffies;
117 } else { 122 } else {
118 /* the 500ms timeout is elapsed we should test 123 /* the 500ms timeout is elapsed we should test
119 * for GPU lockup 124 * for GPU lockup
120 */ 125 */
121 rdev->fence_drv.last_timeout = 1; 126 rdev->fence_drv[ring].last_timeout = 1;
122 } 127 }
123 } else { 128 } else {
124 /* wrap around update last jiffies, we will just wait 129 /* wrap around update last jiffies, we will just wait
125 * a little longer 130 * a little longer
126 */ 131 */
127 rdev->fence_drv.last_jiffies = cjiffies; 132 rdev->fence_drv[ring].last_jiffies = cjiffies;
128 } 133 }
129 return false; 134 return false;
130 } 135 }
131 n = NULL; 136 n = NULL;
132 list_for_each(i, &rdev->fence_drv.emitted) { 137 list_for_each(i, &rdev->fence_drv[ring].emitted) {
133 fence = list_entry(i, struct radeon_fence, list); 138 fence = list_entry(i, struct radeon_fence, list);
134 if (fence->seq == seq) { 139 if (fence->seq == seq) {
135 n = i; 140 n = i;
@@ -141,11 +146,11 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
141 i = n; 146 i = n;
142 do { 147 do {
143 n = i->prev; 148 n = i->prev;
144 list_move_tail(i, &rdev->fence_drv.signaled); 149 list_move_tail(i, &rdev->fence_drv[ring].signaled);
145 fence = list_entry(i, struct radeon_fence, list); 150 fence = list_entry(i, struct radeon_fence, list);
146 fence->signaled = true; 151 fence->signaled = true;
147 i = n; 152 i = n;
148 } while (i != &rdev->fence_drv.emitted); 153 } while (i != &rdev->fence_drv[ring].emitted);
149 wake = true; 154 wake = true;
150 } 155 }
151 return wake; 156 return wake;
@@ -157,14 +162,16 @@ static void radeon_fence_destroy(struct kref *kref)
157 struct radeon_fence *fence; 162 struct radeon_fence *fence;
158 163
159 fence = container_of(kref, struct radeon_fence, kref); 164 fence = container_of(kref, struct radeon_fence, kref);
160 write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags); 165 write_lock_irqsave(&fence->rdev->fence_lock, irq_flags);
161 list_del(&fence->list); 166 list_del(&fence->list);
162 fence->emitted = false; 167 fence->emitted = false;
163 write_unlock_irqrestore(&fence->rdev->fence_drv.lock, irq_flags); 168 write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags);
164 kfree(fence); 169 kfree(fence);
165} 170}
166 171
167int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence) 172int radeon_fence_create(struct radeon_device *rdev,
173 struct radeon_fence **fence,
174 int ring)
168{ 175{
169 unsigned long irq_flags; 176 unsigned long irq_flags;
170 177
@@ -177,15 +184,15 @@ int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence)
177 (*fence)->emitted = false; 184 (*fence)->emitted = false;
178 (*fence)->signaled = false; 185 (*fence)->signaled = false;
179 (*fence)->seq = 0; 186 (*fence)->seq = 0;
187 (*fence)->ring = ring;
180 INIT_LIST_HEAD(&(*fence)->list); 188 INIT_LIST_HEAD(&(*fence)->list);
181 189
182 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 190 write_lock_irqsave(&rdev->fence_lock, irq_flags);
183 list_add_tail(&(*fence)->list, &rdev->fence_drv.created); 191 list_add_tail(&(*fence)->list, &rdev->fence_drv[ring].created);
184 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 192 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
185 return 0; 193 return 0;
186} 194}
187 195
188
189bool radeon_fence_signaled(struct radeon_fence *fence) 196bool radeon_fence_signaled(struct radeon_fence *fence)
190{ 197{
191 unsigned long irq_flags; 198 unsigned long irq_flags;
@@ -197,7 +204,7 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
197 if (fence->rdev->gpu_lockup) 204 if (fence->rdev->gpu_lockup)
198 return true; 205 return true;
199 206
200 write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags); 207 write_lock_irqsave(&fence->rdev->fence_lock, irq_flags);
201 signaled = fence->signaled; 208 signaled = fence->signaled;
202 /* if we are shuting down report all fence as signaled */ 209 /* if we are shuting down report all fence as signaled */
203 if (fence->rdev->shutdown) { 210 if (fence->rdev->shutdown) {
@@ -208,10 +215,10 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
208 signaled = true; 215 signaled = true;
209 } 216 }
210 if (!signaled) { 217 if (!signaled) {
211 radeon_fence_poll_locked(fence->rdev); 218 radeon_fence_poll_locked(fence->rdev, fence->ring);
212 signaled = fence->signaled; 219 signaled = fence->signaled;
213 } 220 }
214 write_unlock_irqrestore(&fence->rdev->fence_drv.lock, irq_flags); 221 write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags);
215 return signaled; 222 return signaled;
216} 223}
217 224
@@ -230,14 +237,14 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
230 if (radeon_fence_signaled(fence)) { 237 if (radeon_fence_signaled(fence)) {
231 return 0; 238 return 0;
232 } 239 }
233 timeout = rdev->fence_drv.last_timeout; 240 timeout = rdev->fence_drv[fence->ring].last_timeout;
234retry: 241retry:
235 /* save current sequence used to check for GPU lockup */ 242 /* save current sequence used to check for GPU lockup */
236 seq = rdev->fence_drv.last_seq; 243 seq = rdev->fence_drv[fence->ring].last_seq;
237 trace_radeon_fence_wait_begin(rdev->ddev, seq); 244 trace_radeon_fence_wait_begin(rdev->ddev, seq);
238 if (intr) { 245 if (intr) {
239 radeon_irq_kms_sw_irq_get(rdev); 246 radeon_irq_kms_sw_irq_get(rdev);
240 r = wait_event_interruptible_timeout(rdev->fence_drv.queue, 247 r = wait_event_interruptible_timeout(rdev->fence_drv[fence->ring].queue,
241 radeon_fence_signaled(fence), timeout); 248 radeon_fence_signaled(fence), timeout);
242 radeon_irq_kms_sw_irq_put(rdev); 249 radeon_irq_kms_sw_irq_put(rdev);
243 if (unlikely(r < 0)) { 250 if (unlikely(r < 0)) {
@@ -245,7 +252,7 @@ retry:
245 } 252 }
246 } else { 253 } else {
247 radeon_irq_kms_sw_irq_get(rdev); 254 radeon_irq_kms_sw_irq_get(rdev);
248 r = wait_event_timeout(rdev->fence_drv.queue, 255 r = wait_event_timeout(rdev->fence_drv[fence->ring].queue,
249 radeon_fence_signaled(fence), timeout); 256 radeon_fence_signaled(fence), timeout);
250 radeon_irq_kms_sw_irq_put(rdev); 257 radeon_irq_kms_sw_irq_put(rdev);
251 } 258 }
@@ -258,10 +265,11 @@ retry:
258 timeout = r; 265 timeout = r;
259 goto retry; 266 goto retry;
260 } 267 }
261 /* don't protect read access to rdev->fence_drv.last_seq 268 /* don't protect read access to rdev->fence_drv[t].last_seq
262 * if we experiencing a lockup the value doesn't change 269 * if we experiencing a lockup the value doesn't change
263 */ 270 */
264 if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { 271 if (seq == rdev->fence_drv[fence->ring].last_seq &&
272 radeon_gpu_is_lockup(rdev)) {
265 /* good news we believe it's a lockup */ 273 /* good news we believe it's a lockup */
266 printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", 274 printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n",
267 fence->seq, seq); 275 fence->seq, seq);
@@ -272,20 +280,20 @@ retry:
272 r = radeon_gpu_reset(rdev); 280 r = radeon_gpu_reset(rdev);
273 if (r) 281 if (r)
274 return r; 282 return r;
275 radeon_fence_write(rdev, fence->seq); 283 radeon_fence_write(rdev, fence->seq, fence->ring);
276 rdev->gpu_lockup = false; 284 rdev->gpu_lockup = false;
277 } 285 }
278 timeout = RADEON_FENCE_JIFFIES_TIMEOUT; 286 timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
279 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 287 write_lock_irqsave(&rdev->fence_lock, irq_flags);
280 rdev->fence_drv.last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; 288 rdev->fence_drv[fence->ring].last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
281 rdev->fence_drv.last_jiffies = jiffies; 289 rdev->fence_drv[fence->ring].last_jiffies = jiffies;
282 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 290 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
283 goto retry; 291 goto retry;
284 } 292 }
285 return 0; 293 return 0;
286} 294}
287 295
288int radeon_fence_wait_next(struct radeon_device *rdev) 296int radeon_fence_wait_next(struct radeon_device *rdev, int ring)
289{ 297{
290 unsigned long irq_flags; 298 unsigned long irq_flags;
291 struct radeon_fence *fence; 299 struct radeon_fence *fence;
@@ -294,21 +302,21 @@ int radeon_fence_wait_next(struct radeon_device *rdev)
294 if (rdev->gpu_lockup) { 302 if (rdev->gpu_lockup) {
295 return 0; 303 return 0;
296 } 304 }
297 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 305 write_lock_irqsave(&rdev->fence_lock, irq_flags);
298 if (list_empty(&rdev->fence_drv.emitted)) { 306 if (list_empty(&rdev->fence_drv[ring].emitted)) {
299 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 307 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
300 return 0; 308 return 0;
301 } 309 }
302 fence = list_entry(rdev->fence_drv.emitted.next, 310 fence = list_entry(rdev->fence_drv[ring].emitted.next,
303 struct radeon_fence, list); 311 struct radeon_fence, list);
304 radeon_fence_ref(fence); 312 radeon_fence_ref(fence);
305 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 313 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
306 r = radeon_fence_wait(fence, false); 314 r = radeon_fence_wait(fence, false);
307 radeon_fence_unref(&fence); 315 radeon_fence_unref(&fence);
308 return r; 316 return r;
309} 317}
310 318
311int radeon_fence_wait_last(struct radeon_device *rdev) 319int radeon_fence_wait_last(struct radeon_device *rdev, int ring)
312{ 320{
313 unsigned long irq_flags; 321 unsigned long irq_flags;
314 struct radeon_fence *fence; 322 struct radeon_fence *fence;
@@ -317,15 +325,15 @@ int radeon_fence_wait_last(struct radeon_device *rdev)
317 if (rdev->gpu_lockup) { 325 if (rdev->gpu_lockup) {
318 return 0; 326 return 0;
319 } 327 }
320 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 328 write_lock_irqsave(&rdev->fence_lock, irq_flags);
321 if (list_empty(&rdev->fence_drv.emitted)) { 329 if (list_empty(&rdev->fence_drv[ring].emitted)) {
322 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 330 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
323 return 0; 331 return 0;
324 } 332 }
325 fence = list_entry(rdev->fence_drv.emitted.prev, 333 fence = list_entry(rdev->fence_drv[ring].emitted.prev,
326 struct radeon_fence, list); 334 struct radeon_fence, list);
327 radeon_fence_ref(fence); 335 radeon_fence_ref(fence);
328 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 336 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
329 r = radeon_fence_wait(fence, false); 337 r = radeon_fence_wait(fence, false);
330 radeon_fence_unref(&fence); 338 radeon_fence_unref(&fence);
331 return r; 339 return r;
@@ -347,39 +355,49 @@ void radeon_fence_unref(struct radeon_fence **fence)
347 } 355 }
348} 356}
349 357
350void radeon_fence_process(struct radeon_device *rdev) 358void radeon_fence_process(struct radeon_device *rdev, int ring)
351{ 359{
352 unsigned long irq_flags; 360 unsigned long irq_flags;
353 bool wake; 361 bool wake;
354 362
355 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 363 write_lock_irqsave(&rdev->fence_lock, irq_flags);
356 wake = radeon_fence_poll_locked(rdev); 364 wake = radeon_fence_poll_locked(rdev, ring);
357 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 365 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
358 if (wake) { 366 if (wake) {
359 wake_up_all(&rdev->fence_drv.queue); 367 wake_up_all(&rdev->fence_drv[ring].queue);
360 } 368 }
361} 369}
362 370
363int radeon_fence_driver_init(struct radeon_device *rdev) 371int radeon_fence_driver_init(struct radeon_device *rdev, int num_rings)
364{ 372{
365 unsigned long irq_flags; 373 unsigned long irq_flags;
366 int r; 374 int r, ring;
367 375
368 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 376 for (ring = 0; ring < num_rings; ring++) {
369 r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg); 377 write_lock_irqsave(&rdev->fence_lock, irq_flags);
370 if (r) { 378 r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg);
371 dev_err(rdev->dev, "fence failed to get scratch register\n"); 379 if (r) {
372 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 380 dev_err(rdev->dev, "fence failed to get scratch register\n");
373 return r; 381 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
382 return r;
383 }
384 radeon_fence_write(rdev, 0, ring);
385 atomic_set(&rdev->fence_drv[ring].seq, 0);
386 INIT_LIST_HEAD(&rdev->fence_drv[ring].created);
387 INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted);
388 INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled);
389 init_waitqueue_head(&rdev->fence_drv[ring].queue);
390 rdev->fence_drv[ring].initialized = true;
391 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
392 }
393 for (ring = num_rings; ring < RADEON_NUM_RINGS; ring++) {
394 write_lock_irqsave(&rdev->fence_lock, irq_flags);
395 INIT_LIST_HEAD(&rdev->fence_drv[ring].created);
396 INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted);
397 INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled);
398 rdev->fence_drv[ring].initialized = false;
399 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
374 } 400 }
375 radeon_fence_write(rdev, 0);
376 atomic_set(&rdev->fence_drv.seq, 0);
377 INIT_LIST_HEAD(&rdev->fence_drv.created);
378 INIT_LIST_HEAD(&rdev->fence_drv.emitted);
379 INIT_LIST_HEAD(&rdev->fence_drv.signaled);
380 init_waitqueue_head(&rdev->fence_drv.queue);
381 rdev->fence_drv.initialized = true;
382 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
383 if (radeon_debugfs_fence_init(rdev)) { 401 if (radeon_debugfs_fence_init(rdev)) {
384 dev_err(rdev->dev, "fence debugfs file creation failed\n"); 402 dev_err(rdev->dev, "fence debugfs file creation failed\n");
385 } 403 }
@@ -389,14 +407,17 @@ int radeon_fence_driver_init(struct radeon_device *rdev)
389void radeon_fence_driver_fini(struct radeon_device *rdev) 407void radeon_fence_driver_fini(struct radeon_device *rdev)
390{ 408{
391 unsigned long irq_flags; 409 unsigned long irq_flags;
392 410 int ring;
393 if (!rdev->fence_drv.initialized) 411
394 return; 412 for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
395 wake_up_all(&rdev->fence_drv.queue); 413 if (!rdev->fence_drv[ring].initialized)
396 write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 414 continue;
397 radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg); 415 wake_up_all(&rdev->fence_drv[ring].queue);
398 write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 416 write_lock_irqsave(&rdev->fence_lock, irq_flags);
399 rdev->fence_drv.initialized = false; 417 radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
418 write_unlock_irqrestore(&rdev->fence_lock, irq_flags);
419 rdev->fence_drv[ring].initialized = false;
420 }
400} 421}
401 422
402 423
@@ -410,14 +431,21 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data)
410 struct drm_device *dev = node->minor->dev; 431 struct drm_device *dev = node->minor->dev;
411 struct radeon_device *rdev = dev->dev_private; 432 struct radeon_device *rdev = dev->dev_private;
412 struct radeon_fence *fence; 433 struct radeon_fence *fence;
413 434 int i;
414 seq_printf(m, "Last signaled fence 0x%08X\n", 435
415 radeon_fence_read(rdev)); 436 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
416 if (!list_empty(&rdev->fence_drv.emitted)) { 437 if (!rdev->fence_drv[i].initialized)
417 fence = list_entry(rdev->fence_drv.emitted.prev, 438 continue;
418 struct radeon_fence, list); 439
419 seq_printf(m, "Last emitted fence %p with 0x%08X\n", 440 seq_printf(m, "--- ring %d ---\n", i);
420 fence, fence->seq); 441 seq_printf(m, "Last signaled fence 0x%08X\n",
442 radeon_fence_read(rdev, i));
443 if (!list_empty(&rdev->fence_drv[i].emitted)) {
444 fence = list_entry(rdev->fence_drv[i].emitted.prev,
445 struct radeon_fence, list);
446 seq_printf(m, "Last emitted fence %p with 0x%08X\n",
447 fence, fence->seq);
448 }
421 } 449 }
422 return 0; 450 return 0;
423} 451}
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 1fb84676afe3..19ed2c6c424a 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -271,7 +271,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
271 if (rdev->cp.ready) { 271 if (rdev->cp.ready) {
272 struct radeon_fence *fence; 272 struct radeon_fence *fence;
273 radeon_ring_alloc(rdev, 64); 273 radeon_ring_alloc(rdev, 64);
274 radeon_fence_create(rdev, &fence); 274 radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
275 radeon_fence_emit(rdev, fence); 275 radeon_fence_emit(rdev, fence);
276 radeon_ring_commit(rdev); 276 radeon_ring_commit(rdev);
277 radeon_fence_wait(fence, false); 277 radeon_fence_wait(fence, false);
@@ -797,17 +797,25 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work)
797 if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) { 797 if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) {
798 unsigned long irq_flags; 798 unsigned long irq_flags;
799 int not_processed = 0; 799 int not_processed = 0;
800 800 int i;
801 read_lock_irqsave(&rdev->fence_drv.lock, irq_flags); 801
802 if (!list_empty(&rdev->fence_drv.emitted)) { 802 read_lock_irqsave(&rdev->fence_lock, irq_flags);
803 struct list_head *ptr; 803 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
804 list_for_each(ptr, &rdev->fence_drv.emitted) { 804 if (!rdev->fence_drv[i].initialized)
805 /* count up to 3, that's enought info */ 805 continue;
806 if (++not_processed >= 3) 806
807 break; 807 if (!list_empty(&rdev->fence_drv[i].emitted)) {
808 struct list_head *ptr;
809 list_for_each(ptr, &rdev->fence_drv[i].emitted) {
810 /* count up to 3, that's enought info */
811 if (++not_processed >= 3)
812 break;
813 }
808 } 814 }
815 if (not_processed >= 3)
816 break;
809 } 817 }
810 read_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); 818 read_unlock_irqrestore(&rdev->fence_lock, irq_flags);
811 819
812 if (not_processed >= 3) { /* should upclock */ 820 if (not_processed >= 3) { /* should upclock */
813 if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_DOWNCLOCK) { 821 if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_DOWNCLOCK) {
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index f3d7d224eebf..c232317b1dd2 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -113,7 +113,7 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
113 int r = 0, i, c; 113 int r = 0, i, c;
114 114
115 *ib = NULL; 115 *ib = NULL;
116 r = radeon_fence_create(rdev, &fence); 116 r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
117 if (r) { 117 if (r) {
118 dev_err(rdev->dev, "failed to create fence for new IB\n"); 118 dev_err(rdev->dev, "failed to create fence for new IB\n");
119 return r; 119 return r;
@@ -314,7 +314,7 @@ int radeon_ring_alloc(struct radeon_device *rdev, unsigned ndw)
314 if (ndw < rdev->cp.ring_free_dw) { 314 if (ndw < rdev->cp.ring_free_dw) {
315 break; 315 break;
316 } 316 }
317 r = radeon_fence_wait_next(rdev); 317 r = radeon_fence_wait_next(rdev, RADEON_RING_TYPE_GFX_INDEX);
318 if (r) 318 if (r)
319 return r; 319 return r;
320 } 320 }
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 602fa3541c45..37f7acb6d5f7 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -104,7 +104,7 @@ void radeon_test_moves(struct radeon_device *rdev)
104 104
105 radeon_bo_kunmap(gtt_obj[i]); 105 radeon_bo_kunmap(gtt_obj[i]);
106 106
107 r = radeon_fence_create(rdev, &fence); 107 r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
108 if (r) { 108 if (r) {
109 DRM_ERROR("Failed to create GTT->VRAM fence %d\n", i); 109 DRM_ERROR("Failed to create GTT->VRAM fence %d\n", i);
110 goto out_cleanup; 110 goto out_cleanup;
@@ -153,7 +153,7 @@ void radeon_test_moves(struct radeon_device *rdev)
153 153
154 radeon_bo_kunmap(vram_obj); 154 radeon_bo_kunmap(vram_obj);
155 155
156 r = radeon_fence_create(rdev, &fence); 156 r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
157 if (r) { 157 if (r) {
158 DRM_ERROR("Failed to create VRAM->GTT fence %d\n", i); 158 DRM_ERROR("Failed to create VRAM->GTT fence %d\n", i);
159 goto out_cleanup; 159 goto out_cleanup;
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index e111a3812434..112ecaa6362b 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -226,7 +226,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
226 int r; 226 int r;
227 227
228 rdev = radeon_get_rdev(bo->bdev); 228 rdev = radeon_get_rdev(bo->bdev);
229 r = radeon_fence_create(rdev, &fence); 229 r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX);
230 if (unlikely(r)) { 230 if (unlikely(r)) {
231 return r; 231 return r;
232 } 232 }
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index 06b90c87f8f3..c71fa16106ca 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -516,7 +516,7 @@ int rs400_init(struct radeon_device *rdev)
516 /* initialize memory controller */ 516 /* initialize memory controller */
517 rs400_mc_init(rdev); 517 rs400_mc_init(rdev);
518 /* Fence driver */ 518 /* Fence driver */
519 r = radeon_fence_driver_init(rdev); 519 r = radeon_fence_driver_init(rdev, 1);
520 if (r) 520 if (r)
521 return r; 521 return r;
522 r = radeon_irq_kms_init(rdev); 522 r = radeon_irq_kms_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index b1053d640423..1c9ab9409531 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -642,7 +642,7 @@ int rs600_irq_process(struct radeon_device *rdev)
642 while (status || rdev->irq.stat_regs.r500.disp_int) { 642 while (status || rdev->irq.stat_regs.r500.disp_int) {
643 /* SW interrupt */ 643 /* SW interrupt */
644 if (G_000044_SW_INT(status)) { 644 if (G_000044_SW_INT(status)) {
645 radeon_fence_process(rdev); 645 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
646 } 646 }
647 /* GUI idle */ 647 /* GUI idle */
648 if (G_000040_GUI_IDLE(status)) { 648 if (G_000040_GUI_IDLE(status)) {
@@ -962,7 +962,7 @@ int rs600_init(struct radeon_device *rdev)
962 rs600_mc_init(rdev); 962 rs600_mc_init(rdev);
963 rs600_debugfs(rdev); 963 rs600_debugfs(rdev);
964 /* Fence driver */ 964 /* Fence driver */
965 r = radeon_fence_driver_init(rdev); 965 r = radeon_fence_driver_init(rdev, 1);
966 if (r) 966 if (r)
967 return r; 967 return r;
968 r = radeon_irq_kms_init(rdev); 968 r = radeon_irq_kms_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index a9049ed1a519..8aa5e7ef2efc 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -735,7 +735,7 @@ int rs690_init(struct radeon_device *rdev)
735 rs690_mc_init(rdev); 735 rs690_mc_init(rdev);
736 rv515_debugfs(rdev); 736 rv515_debugfs(rdev);
737 /* Fence driver */ 737 /* Fence driver */
738 r = radeon_fence_driver_init(rdev); 738 r = radeon_fence_driver_init(rdev, 1);
739 if (r) 739 if (r)
740 return r; 740 return r;
741 r = radeon_irq_kms_init(rdev); 741 r = radeon_irq_kms_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 6613ee9ecca3..fd8da02e1ca5 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -510,7 +510,7 @@ int rv515_init(struct radeon_device *rdev)
510 rv515_mc_init(rdev); 510 rv515_mc_init(rdev);
511 rv515_debugfs(rdev); 511 rv515_debugfs(rdev);
512 /* Fence driver */ 512 /* Fence driver */
513 r = radeon_fence_driver_init(rdev); 513 r = radeon_fence_driver_init(rdev, 1);
514 if (r) 514 if (r)
515 return r; 515 return r;
516 r = radeon_irq_kms_init(rdev); 516 r = radeon_irq_kms_init(rdev);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 23ae1c60ab3d..8637fd84e499 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1194,7 +1194,7 @@ int rv770_init(struct radeon_device *rdev)
1194 /* Initialize clocks */ 1194 /* Initialize clocks */
1195 radeon_get_clock_info(rdev->ddev); 1195 radeon_get_clock_info(rdev->ddev);
1196 /* Fence driver */ 1196 /* Fence driver */
1197 r = radeon_fence_driver_init(rdev); 1197 r = radeon_fence_driver_init(rdev, 1);
1198 if (r) 1198 if (r)
1199 return r; 1199 return r;
1200 /* initialize AGP */ 1200 /* initialize AGP */