aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c10
-rw-r--r--drivers/gpu/drm/radeon/r600.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon.h5
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c31
-rw-r--r--drivers/gpu/drm/radeon/si.c10
5 files changed, 67 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 4b8e5c5fcf84..870009ad5f56 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1364,17 +1364,25 @@ void evergreen_mc_program(struct radeon_device *rdev)
1364void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) 1364void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1365{ 1365{
1366 struct radeon_ring *ring = &rdev->ring[ib->ring]; 1366 struct radeon_ring *ring = &rdev->ring[ib->ring];
1367 u32 next_rptr;
1367 1368
1368 /* set to DX10/11 mode */ 1369 /* set to DX10/11 mode */
1369 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); 1370 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1370 radeon_ring_write(ring, 1); 1371 radeon_ring_write(ring, 1);
1371 1372
1372 if (ring->rptr_save_reg) { 1373 if (ring->rptr_save_reg) {
1373 uint32_t next_rptr = ring->wptr + 3 + 4; 1374 next_rptr = ring->wptr + 3 + 4;
1374 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 1375 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1375 radeon_ring_write(ring, ((ring->rptr_save_reg - 1376 radeon_ring_write(ring, ((ring->rptr_save_reg -
1376 PACKET3_SET_CONFIG_REG_START) >> 2)); 1377 PACKET3_SET_CONFIG_REG_START) >> 2));
1377 radeon_ring_write(ring, next_rptr); 1378 radeon_ring_write(ring, next_rptr);
1379 } else if (rdev->wb.enabled) {
1380 next_rptr = ring->wptr + 5 + 4;
1381 radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3));
1382 radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
1383 radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18));
1384 radeon_ring_write(ring, next_rptr);
1385 radeon_ring_write(ring, 0);
1378 } 1386 }
1379 1387
1380 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 1388 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 9f24a804f6ea..c5b2e9069362 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2163,10 +2163,12 @@ void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsign
2163 ring->ring_size = ring_size; 2163 ring->ring_size = ring_size;
2164 ring->align_mask = 16 - 1; 2164 ring->align_mask = 16 - 1;
2165 2165
2166 r = radeon_scratch_get(rdev, &ring->rptr_save_reg); 2166 if (radeon_ring_supports_scratch_reg(rdev, ring)) {
2167 if (r) { 2167 r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
2168 DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r); 2168 if (r) {
2169 ring->rptr_save_reg = 0; 2169 DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
2170 ring->rptr_save_reg = 0;
2171 }
2170 } 2172 }
2171} 2173}
2172 2174
@@ -2576,13 +2578,21 @@ void r600_fini(struct radeon_device *rdev)
2576void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) 2578void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
2577{ 2579{
2578 struct radeon_ring *ring = &rdev->ring[ib->ring]; 2580 struct radeon_ring *ring = &rdev->ring[ib->ring];
2581 u32 next_rptr;
2579 2582
2580 if (ring->rptr_save_reg) { 2583 if (ring->rptr_save_reg) {
2581 uint32_t next_rptr = ring->wptr + 3 + 4; 2584 next_rptr = ring->wptr + 3 + 4;
2582 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 2585 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
2583 radeon_ring_write(ring, ((ring->rptr_save_reg - 2586 radeon_ring_write(ring, ((ring->rptr_save_reg -
2584 PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); 2587 PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
2585 radeon_ring_write(ring, next_rptr); 2588 radeon_ring_write(ring, next_rptr);
2589 } else if (rdev->wb.enabled) {
2590 next_rptr = ring->wptr + 5 + 4;
2591 radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3));
2592 radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
2593 radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18));
2594 radeon_ring_write(ring, next_rptr);
2595 radeon_ring_write(ring, 0);
2586 } 2596 }
2587 2597
2588 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 2598 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index be454725c377..5431af292408 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -623,6 +623,8 @@ struct radeon_ring {
623 unsigned rptr_offs; 623 unsigned rptr_offs;
624 unsigned rptr_reg; 624 unsigned rptr_reg;
625 unsigned rptr_save_reg; 625 unsigned rptr_save_reg;
626 u64 next_rptr_gpu_addr;
627 volatile u32 *next_rptr_cpu_addr;
626 unsigned wptr; 628 unsigned wptr;
627 unsigned wptr_old; 629 unsigned wptr_old;
628 unsigned wptr_reg; 630 unsigned wptr_reg;
@@ -758,6 +760,8 @@ int radeon_ib_pool_init(struct radeon_device *rdev);
758void radeon_ib_pool_fini(struct radeon_device *rdev); 760void radeon_ib_pool_fini(struct radeon_device *rdev);
759int radeon_ib_ring_tests(struct radeon_device *rdev); 761int radeon_ib_ring_tests(struct radeon_device *rdev);
760/* Ring access between begin & end cannot sleep */ 762/* Ring access between begin & end cannot sleep */
763bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
764 struct radeon_ring *ring);
761void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); 765void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp);
762int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); 766int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw);
763int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); 767int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw);
@@ -871,6 +875,7 @@ struct radeon_wb {
871}; 875};
872 876
873#define RADEON_WB_SCRATCH_OFFSET 0 877#define RADEON_WB_SCRATCH_OFFSET 0
878#define RADEON_WB_RING0_NEXT_RPTR 256
874#define RADEON_WB_CP_RPTR_OFFSET 1024 879#define RADEON_WB_CP_RPTR_OFFSET 1024
875#define RADEON_WB_CP1_RPTR_OFFSET 1280 880#define RADEON_WB_CP1_RPTR_OFFSET 1280
876#define RADEON_WB_CP2_RPTR_OFFSET 1536 881#define RADEON_WB_CP2_RPTR_OFFSET 1536
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index c5828b909024..c1efde6d53d3 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -207,6 +207,19 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v)
207 ring->ring_free_dw--; 207 ring->ring_free_dw--;
208} 208}
209 209
210bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
211 struct radeon_ring *ring)
212{
213 switch (ring->idx) {
214 case RADEON_RING_TYPE_GFX_INDEX:
215 case CAYMAN_RING_TYPE_CP1_INDEX:
216 case CAYMAN_RING_TYPE_CP2_INDEX:
217 return true;
218 default:
219 return false;
220 }
221}
222
210void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) 223void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
211{ 224{
212 u32 rptr; 225 u32 rptr;
@@ -372,7 +385,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring
372 mutex_lock(&rdev->ring_lock); 385 mutex_lock(&rdev->ring_lock);
373 *data = NULL; 386 *data = NULL;
374 387
375 if (ring->ring_obj == NULL || !ring->rptr_save_reg) { 388 if (ring->ring_obj == NULL) {
376 mutex_unlock(&rdev->ring_lock); 389 mutex_unlock(&rdev->ring_lock);
377 return 0; 390 return 0;
378 } 391 }
@@ -384,7 +397,16 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring
384 } 397 }
385 398
386 /* calculate the number of dw on the ring */ 399 /* calculate the number of dw on the ring */
387 ptr = RREG32(ring->rptr_save_reg); 400 if (ring->rptr_save_reg)
401 ptr = RREG32(ring->rptr_save_reg);
402 else if (rdev->wb.enabled)
403 ptr = le32_to_cpu(*ring->next_rptr_cpu_addr);
404 else {
405 /* no way to read back the next rptr */
406 mutex_unlock(&rdev->ring_lock);
407 return 0;
408 }
409
388 size = ring->wptr + (ring->ring_size / 4); 410 size = ring->wptr + (ring->ring_size / 4);
389 size -= ptr; 411 size -= ptr;
390 size &= ring->ptr_mask; 412 size &= ring->ptr_mask;
@@ -478,6 +500,11 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
478 } 500 }
479 ring->ptr_mask = (ring->ring_size / 4) - 1; 501 ring->ptr_mask = (ring->ring_size / 4) - 1;
480 ring->ring_free_dw = ring->ring_size / 4; 502 ring->ring_free_dw = ring->ring_size / 4;
503 if (rdev->wb.enabled) {
504 u32 index = RADEON_WB_RING0_NEXT_RPTR + (ring->idx * 4);
505 ring->next_rptr_gpu_addr = rdev->wb.gpu_addr + index;
506 ring->next_rptr_cpu_addr = &rdev->wb.wb[index/4];
507 }
481 if (radeon_debugfs_ring_init(rdev, ring)) { 508 if (radeon_debugfs_ring_init(rdev, ring)) {
482 DRM_ERROR("Failed to register debugfs file for rings !\n"); 509 DRM_ERROR("Failed to register debugfs file for rings !\n");
483 } 510 }
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 2b12cae52b29..7c3e330c7b59 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -1772,12 +1772,20 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1772 1772
1773 header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2); 1773 header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
1774 } else { 1774 } else {
1775 u32 next_rptr;
1775 if (ring->rptr_save_reg) { 1776 if (ring->rptr_save_reg) {
1776 uint32_t next_rptr = ring->wptr + 3 + 4 + 8; 1777 next_rptr = ring->wptr + 3 + 4 + 8;
1777 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 1778 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1778 radeon_ring_write(ring, ((ring->rptr_save_reg - 1779 radeon_ring_write(ring, ((ring->rptr_save_reg -
1779 PACKET3_SET_CONFIG_REG_START) >> 2)); 1780 PACKET3_SET_CONFIG_REG_START) >> 2));
1780 radeon_ring_write(ring, next_rptr); 1781 radeon_ring_write(ring, next_rptr);
1782 } else if (rdev->wb.enabled) {
1783 next_rptr = ring->wptr + 5 + 4 + 8;
1784 radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
1785 radeon_ring_write(ring, (1 << 8));
1786 radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
1787 radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff);
1788 radeon_ring_write(ring, next_rptr);
1781 } 1789 }
1782 1790
1783 header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); 1791 header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);