summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2011-09-25 10:59:21 +0200
committerChristian König <deathsimple@vodafone.de>2012-01-06 13:28:01 +0100
commit02c26c31906984bb482dcba37da5b5fe447cc499 (patch)
treeb00bfdc48e482fd1a626329348d6c2e1ce6b792b
parent51bf0090813a6c552881a2e36e9d14f1d0fa69f8 (diff)
WIP: drm/radeon: Enable additional compute rings on caymanmulti-ring-testing
Compute rings on cayman aren't reliable because of hardware bugs. So we actually need to disable them for a production environment, but right now they are good enough for testing. Signed-off-by: Christian König <deathsimple@vodafone.de>
-rw-r--r--drivers/gpu/drm/radeon/ni.c63
-rw-r--r--drivers/gpu/drm/radeon/nid.h2
2 files changed, 57 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 321137295400..18576cbfaaa6 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1188,7 +1188,16 @@ static int cayman_cp_start(struct radeon_device *rdev)
radeon_ring_unlock_commit(rdev, ring);
- /* XXX init other rings */
+ for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) {
+ ring = &rdev->ring[i];
+ r = radeon_ring_lock(rdev, ring, 2);
+
+ /* clear the compute context state */
+ radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0));
+ radeon_ring_write(ring, 0);
+
+ radeon_ring_unlock_commit(rdev, ring);
+ }
return 0;
}
@@ -1224,6 +1233,7 @@ int cayman_cp_resume(struct radeon_device *rdev)
WREG32(CP_RB_WPTR_DELAY, 0);
WREG32(CP_DEBUG, (1 << 27));
+ WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
/* ring 0 - compute and gfx */
/* Set ring buffer size */
@@ -1243,7 +1253,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
/* set the wb address wether it's enabled or not */
WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
- WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
if (rdev->wb.enabled)
WREG32(SCRATCH_UMSK, 0xff);
@@ -1314,17 +1323,23 @@ int cayman_cp_resume(struct radeon_device *rdev)
/* start the rings */
cayman_cp_start(rdev);
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
- rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
- rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
/* this only test cp0 */
r = radeon_ring_test(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
if (r) {
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
- rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
- rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
return r;
}
+ rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true;
+ r = radeon_ring_test(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
+ if (r)
+ rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
+
+ rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true;
+ r = radeon_ring_test(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
+ if (r)
+ rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
+
return 0;
}
@@ -1433,7 +1448,7 @@ int cayman_asic_reset(struct radeon_device *rdev)
static int cayman_startup(struct radeon_device *rdev)
{
- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ struct radeon_ring *ring;
int r;
/* enable pcie gen2 link */
@@ -1501,11 +1516,27 @@ static int cayman_startup(struct radeon_device *rdev)
}
evergreen_irq_set(rdev);
+ ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
CP_RB0_RPTR, CP_RB0_WPTR,
0, 0xfffff, RADEON_CP_PACKET2);
if (r)
return r;
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
+ CP_RB1_RPTR, CP_RB1_WPTR,
+ 0, 0xfffff, RADEON_CP_PACKET2);
+ if (r)
+ return r;
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
+ CP_RB2_RPTR, CP_RB2_WPTR,
+ 0, 0xfffff, RADEON_CP_PACKET2);
+ if (r)
+ return r;
+
r = cayman_cp_load_microcode(rdev);
if (r)
return r;
@@ -1523,6 +1554,13 @@ static int cayman_startup(struct radeon_device *rdev)
rdev->accel_working = false;
return r;
}
+ r = r600_ib_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
+ if (r)
+ DRM_ERROR("radeon: failled testing IB (%d) on ring 1.\n", r);
+
+ r = r600_ib_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
+ if (r)
+ DRM_ERROR("radeon: failled testing IB (%d) on ring 2.\n", r);
r = radeon_vm_manager_start(rdev);
if (r)
@@ -1573,7 +1611,7 @@ int cayman_suspend(struct radeon_device *rdev)
*/
int cayman_init(struct radeon_device *rdev)
{
- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ struct radeon_ring *ring;
int r;
/* This don't do much */
@@ -1626,6 +1664,15 @@ int cayman_init(struct radeon_device *rdev)
if (r)
return r;
+ ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 1024 * 1024);
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 1024 * 1024);
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
ring->ring_obj = NULL;
r600_ring_init(rdev, ring, 1024 * 1024);
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index f9df2a645e79..2a63236c49a0 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -450,6 +450,8 @@
(((op) & 0xFF) << 8) | \
((n) & 0x3FFF) << 16)
+#define PACKET3_COMPUTE(op, n) (PACKET3(op, n) | 1 << 1)
+
/* Packet 3 types */
#define PACKET3_NOP 0x10
#define PACKET3_SET_BASE 0x11