diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-07-17 14:02:31 -0400 |
---|---|---|
committer | Christian König <deathsimple@vodafone.de> | 2012-07-18 07:53:17 -0400 |
commit | 89d35807fb0fe53b84e88e759cc39107a6195e5f (patch) | |
tree | afb2e2cb9439239e6f83ad339ad624f42d012adc /drivers/gpu/drm/radeon/radeon_ring.c | |
parent | 8b25ed3482885e5f1dc65ace796e90f879d76c52 (diff) |
drm/radeon: update rptr saving logic for memory buffers
Add support for using memory buffers rather than
scratch registers. Some rings may not be able to
write to scratch registers.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_ring.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 31 |
1 files changed, 29 insertions, 2 deletions
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 | } |