[PATCH 050/165] drm/radeon: use callbacks for ring pointer handling
Christian König
deathsimple at vodafone.de
Wed Jun 26 08:31:54 PDT 2013
Am 26.06.2013 15:22, schrieb alexdeucher at gmail.com:
> From: Alex Deucher <alexander.deucher at 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.deucher at amd.com>
I'm ok with the general idea but let's put those callback into the
radeon_asic.ring structure where they belong.
With this we should be able to remove most of the UVD and
ptr_reg_shift/ptr_reg_mask special case handling.
Christian.
> ---
> 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,
More information about the dri-devel
mailing list