aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600.c
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-07-06 10:22:55 -0400
committerChristian König <deathsimple@vodafone.de>2012-07-17 04:33:09 -0400
commit45df68035c4964d42ea3850980708ce8674f75b3 (patch)
treeb0d75e0068924399a798d4aa5bcc61b2cbc7e2a0 /drivers/gpu/drm/radeon/r600.c
parent04eb2206d8022dc4a1eadb5e9cc5122c84959881 (diff)
drm/radeon: record what is next valid wptr for each ring v4
Before emitting any indirect buffer, emit the offset of the next valid ring content if any. This allow code that want to resume ring to resume ring right after ib that caused GPU lockup. v2: use scratch registers instead of storing it into memory v3: skip over the surface sync for ni and si as well v4: use SET_CONFIG_REG instead of PACKET0 Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r--drivers/gpu/drm/radeon/r600.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c808fa976d2..3156d251b3c 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2155,18 +2155,27 @@ int r600_cp_resume(struct radeon_device *rdev)
2155void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) 2155void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size)
2156{ 2156{
2157 u32 rb_bufsz; 2157 u32 rb_bufsz;
2158 int r;
2158 2159
2159 /* Align ring size */ 2160 /* Align ring size */
2160 rb_bufsz = drm_order(ring_size / 8); 2161 rb_bufsz = drm_order(ring_size / 8);
2161 ring_size = (1 << (rb_bufsz + 1)) * 4; 2162 ring_size = (1 << (rb_bufsz + 1)) * 4;
2162 ring->ring_size = ring_size; 2163 ring->ring_size = ring_size;
2163 ring->align_mask = 16 - 1; 2164 ring->align_mask = 16 - 1;
2165
2166 r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
2167 if (r) {
2168 DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
2169 ring->rptr_save_reg = 0;
2170 }
2164} 2171}
2165 2172
2166void r600_cp_fini(struct radeon_device *rdev) 2173void r600_cp_fini(struct radeon_device *rdev)
2167{ 2174{
2175 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
2168 r600_cp_stop(rdev); 2176 r600_cp_stop(rdev);
2169 radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 2177 radeon_ring_fini(rdev, ring);
2178 radeon_scratch_free(rdev, ring->rptr_save_reg);
2170} 2179}
2171 2180
2172 2181
@@ -2568,7 +2577,14 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
2568{ 2577{
2569 struct radeon_ring *ring = &rdev->ring[ib->ring]; 2578 struct radeon_ring *ring = &rdev->ring[ib->ring];
2570 2579
2571 /* FIXME: implement */ 2580 if (ring->rptr_save_reg) {
2581 uint32_t next_rptr = ring->wptr + 3 + 4;
2582 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
2583 radeon_ring_write(ring, ((ring->rptr_save_reg -
2584 PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
2585 radeon_ring_write(ring, next_rptr);
2586 }
2587
2572 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 2588 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
2573 radeon_ring_write(ring, 2589 radeon_ring_write(ring,
2574#ifdef __BIG_ENDIAN 2590#ifdef __BIG_ENDIAN