From: Alex Deucher <alexander.deuc...@amd.com>

Add callbacks to the radeon_ring struct to handle
rptr/wptr fetchs and wptr updates.
We currently use one version for all rings, but this
allows us to override with a ring specific versions.

Needed for compute rings on CIK.

Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
---
 drivers/gpu/drm/radeon/radeon.h      |    5 +++
 drivers/gpu/drm/radeon/radeon_ring.c |   55 +++++++++++++++++++++++++--------
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9af0fa6..ad4e68a 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -695,6 +695,11 @@ struct radeon_ring {
        u32                     idx;
        u64                     last_semaphore_signal_addr;
        u64                     last_semaphore_wait_addr;
+       struct {
+               u32                     (*get_rptr)(struct radeon_device *rdev, 
struct radeon_ring *ring);
+               u32                     (*get_wptr)(struct radeon_device *rdev, 
struct radeon_ring *ring);
+               void                    (*set_wptr)(struct radeon_device *rdev, 
struct radeon_ring *ring);
+       } funcs;
 };
 
 /*
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index e17faa7..53018e9 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -357,6 +357,38 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device 
*rdev,
        }
 }
 
+static u32 radeon_ring_get_rptr(struct radeon_device *rdev,
+                               struct radeon_ring *ring)
+{
+       u32 rptr;
+
+       if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
+               rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+       else
+               rptr = RREG32(ring->rptr_reg);
+       rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+       return rptr;
+}
+
+static u32 radeon_ring_get_wptr(struct radeon_device *rdev,
+                               struct radeon_ring *ring)
+{
+       u32 wptr;
+
+       wptr = RREG32(ring->wptr_reg);
+       wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+       return wptr;
+}
+
+static void radeon_ring_set_wptr(struct radeon_device *rdev,
+                                struct radeon_ring *ring)
+{
+       WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
ring->ptr_reg_mask);
+       (void)RREG32(ring->wptr_reg);
+}
+
 /**
  * radeon_ring_free_size - update the free size
  *
@@ -367,13 +399,7 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device 
*rdev,
  */
 void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring 
*ring)
 {
-       u32 rptr;
-
-       if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
-               rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
-       else
-               rptr = RREG32(ring->rptr_reg);
-       ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+       ring->rptr = ring->funcs.get_rptr(rdev, ring);
        /* This works because ring_size is a power of 2 */
        ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4));
        ring->ring_free_dw -= ring->wptr;
@@ -458,8 +484,7 @@ void radeon_ring_commit(struct radeon_device *rdev, struct 
radeon_ring *ring)
                radeon_ring_write(ring, ring->nop);
        }
        DRM_MEMORYBARRIER();
-       WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & 
ring->ptr_reg_mask);
-       (void)RREG32(ring->wptr_reg);
+       ring->funcs.set_wptr(rdev, ring);
 }
 
 /**
@@ -561,7 +586,6 @@ void radeon_ring_lockup_update(struct radeon_ring *ring)
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring 
*ring)
 {
        unsigned long cjiffies, elapsed;
-       uint32_t rptr;
 
        cjiffies = jiffies;
        if (!time_after(cjiffies, ring->last_activity)) {
@@ -569,8 +593,7 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, 
struct radeon_ring *rin
                radeon_ring_lockup_update(ring);
                return false;
        }
-       rptr = RREG32(ring->rptr_reg);
-       ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+       ring->rptr = ring->funcs.get_rptr(rdev, ring);
        if (ring->rptr != ring->last_rptr) {
                /* CP is still working no lockup */
                radeon_ring_lockup_update(ring);
@@ -708,6 +731,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct 
radeon_ring *ring, unsig
        ring->ptr_reg_shift = ptr_reg_shift;
        ring->ptr_reg_mask = ptr_reg_mask;
        ring->nop = nop;
+       /* set the ptr callbacks */
+       ring->funcs.get_rptr = &radeon_ring_get_rptr;
+       ring->funcs.get_wptr = &radeon_ring_get_wptr;
+       ring->funcs.set_wptr = &radeon_ring_set_wptr;
        /* Allocate ring buffer */
        if (ring->ring_obj == NULL) {
                r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true,
@@ -797,9 +824,9 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
 
        radeon_ring_free_size(rdev, ring);
        count = (ring->ring_size / 4) - ring->ring_free_dw;
-       tmp = RREG32(ring->wptr_reg) >> ring->ptr_reg_shift;
+       tmp = ring->funcs.get_wptr(rdev, ring);
        seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp);
-       tmp = RREG32(ring->rptr_reg) >> ring->ptr_reg_shift;
+       tmp = ring->funcs.get_rptr(rdev, ring);
        seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp);
        if (ring->rptr_save_reg) {
                seq_printf(m, "rptr next(0x%04x): 0x%08x\n", 
ring->rptr_save_reg,
-- 
1.7.7.5

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to