diff options
author | Christian König <deathsimple@vodafone.de> | 2011-09-25 10:59:21 +0200 |
---|---|---|
committer | Christian König <deathsimple@vodafone.de> | 2012-01-06 13:28:01 +0100 |
commit | 02c26c31906984bb482dcba37da5b5fe447cc499 (patch) | |
tree | b00bfdc48e482fd1a626329348d6c2e1ce6b792b | |
parent | 51bf0090813a6c552881a2e36e9d14f1d0fa69f8 (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.c | 63 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/nid.h | 2 |
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 |