Message ID | 1372253045-17042-51-git-send-email-alexdeucher@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Am 26.06.2013 15:22, schrieb alexdeucher@gmail.com: > From: Alex Deucher <alexander.deucher@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@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,
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,