aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c10
-rw-r--r--drivers/gpu/drm/radeon/ni.c13
-rw-r--r--drivers/gpu/drm/radeon/r600.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c4
-rw-r--r--drivers/gpu/drm/radeon/rv770.c4
-rw-r--r--drivers/gpu/drm/radeon/si.c24
7 files changed, 68 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index f39b900d46f..4b8e5c5fcf8 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1368,7 +1368,15 @@ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1368 /* set to DX10/11 mode */ 1368 /* set to DX10/11 mode */
1369 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); 1369 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1370 radeon_ring_write(ring, 1); 1370 radeon_ring_write(ring, 1);
1371 /* FIXME: implement */ 1371
1372 if (ring->rptr_save_reg) {
1373 uint32_t next_rptr = ring->wptr + 3 + 4;
1374 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1375 radeon_ring_write(ring, ((ring->rptr_save_reg -
1376 PACKET3_SET_CONFIG_REG_START) >> 2));
1377 radeon_ring_write(ring, next_rptr);
1378 }
1379
1372 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 1380 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1373 radeon_ring_write(ring, 1381 radeon_ring_write(ring,
1374#ifdef __BIG_ENDIAN 1382#ifdef __BIG_ENDIAN
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index f2afefb44b7..ddfef8cdd83 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -855,6 +855,15 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
855 /* set to DX10/11 mode */ 855 /* set to DX10/11 mode */
856 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); 856 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
857 radeon_ring_write(ring, 1); 857 radeon_ring_write(ring, 1);
858
859 if (ring->rptr_save_reg) {
860 uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
861 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
862 radeon_ring_write(ring, ((ring->rptr_save_reg -
863 PACKET3_SET_CONFIG_REG_START) >> 2));
864 radeon_ring_write(ring, next_rptr);
865 }
866
858 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 867 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
859 radeon_ring_write(ring, 868 radeon_ring_write(ring,
860#ifdef __BIG_ENDIAN 869#ifdef __BIG_ENDIAN
@@ -981,8 +990,10 @@ static int cayman_cp_start(struct radeon_device *rdev)
981 990
982static void cayman_cp_fini(struct radeon_device *rdev) 991static void cayman_cp_fini(struct radeon_device *rdev)
983{ 992{
993 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
984 cayman_cp_enable(rdev, false); 994 cayman_cp_enable(rdev, false);
985 radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 995 radeon_ring_fini(rdev, ring);
996 radeon_scratch_free(rdev, ring->rptr_save_reg);
986} 997}
987 998
988int cayman_cp_resume(struct radeon_device *rdev) 999int cayman_cp_resume(struct radeon_device *rdev)
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
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 872270c9a0d..64d39adaad9 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -622,6 +622,7 @@ struct radeon_ring {
622 unsigned rptr; 622 unsigned rptr;
623 unsigned rptr_offs; 623 unsigned rptr_offs;
624 unsigned rptr_reg; 624 unsigned rptr_reg;
625 unsigned rptr_save_reg;
625 unsigned wptr; 626 unsigned wptr;
626 unsigned wptr_old; 627 unsigned wptr_old;
627 unsigned wptr_reg; 628 unsigned wptr_reg;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 087383408a8..ce8eb9d5af5 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -451,6 +451,10 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
451 count = (ring->ring_size / 4) - ring->ring_free_dw; 451 count = (ring->ring_size / 4) - ring->ring_free_dw;
452 seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg)); 452 seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg));
453 seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg)); 453 seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg));
454 if (ring->rptr_save_reg) {
455 seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg,
456 RREG32(ring->rptr_save_reg));
457 }
454 seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr); 458 seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr);
455 seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); 459 seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr);
456 seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); 460 seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index b4b1256fb15..eb4704e72bd 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -358,8 +358,10 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev)
358 358
359void r700_cp_fini(struct radeon_device *rdev) 359void r700_cp_fini(struct radeon_device *rdev)
360{ 360{
361 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
361 r700_cp_stop(rdev); 362 r700_cp_stop(rdev);
362 radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 363 radeon_ring_fini(rdev, ring);
364 radeon_scratch_free(rdev, ring->rptr_save_reg);
363} 365}
364 366
365/* 367/*
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index f61b550f9ef..53e313b0575 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -1765,6 +1765,14 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1765 struct radeon_ring *ring = &rdev->ring[ib->ring]; 1765 struct radeon_ring *ring = &rdev->ring[ib->ring];
1766 u32 header; 1766 u32 header;
1767 1767
1768 if (ring->rptr_save_reg) {
1769 uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
1770 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1771 radeon_ring_write(ring, ((ring->rptr_save_reg -
1772 PACKET3_SET_CONFIG_REG_START) >> 2));
1773 radeon_ring_write(ring, next_rptr);
1774 }
1775
1768 if (ib->is_const_ib) 1776 if (ib->is_const_ib)
1769 header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2); 1777 header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
1770 else 1778 else
@@ -1917,10 +1925,20 @@ static int si_cp_start(struct radeon_device *rdev)
1917 1925
1918static void si_cp_fini(struct radeon_device *rdev) 1926static void si_cp_fini(struct radeon_device *rdev)
1919{ 1927{
1928 struct radeon_ring *ring;
1920 si_cp_enable(rdev, false); 1929 si_cp_enable(rdev, false);
1921 radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 1930
1922 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); 1931 ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1923 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); 1932 radeon_ring_fini(rdev, ring);
1933 radeon_scratch_free(rdev, ring->rptr_save_reg);
1934
1935 ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
1936 radeon_ring_fini(rdev, ring);
1937 radeon_scratch_free(rdev, ring->rptr_save_reg);
1938
1939 ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
1940 radeon_ring_fini(rdev, ring);
1941 radeon_scratch_free(rdev, ring->rptr_save_reg);
1924} 1942}
1925 1943
1926static int si_cp_resume(struct radeon_device *rdev) 1944static int si_cp_resume(struct radeon_device *rdev)