diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 10 |
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) | |||
1364 | void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 1364 | void 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) | |||
2576 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 2578 | void 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); | |||
758 | void radeon_ib_pool_fini(struct radeon_device *rdev); | 760 | void radeon_ib_pool_fini(struct radeon_device *rdev); |
759 | int radeon_ib_ring_tests(struct radeon_device *rdev); | 761 | int radeon_ib_ring_tests(struct radeon_device *rdev); |
760 | /* Ring access between begin & end cannot sleep */ | 762 | /* Ring access between begin & end cannot sleep */ |
763 | bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev, | ||
764 | struct radeon_ring *ring); | ||
761 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); | 765 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); |
762 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); | 766 | int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); |
763 | int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); | 767 | int 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 | ||
210 | bool 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 | |||
210 | void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) | 223 | void 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); |