diff mbox

[050/165] drm/radeon: use callbacks for ring pointer handling

Message ID 1372253045-17042-51-git-send-email-alexdeucher@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alex Deucher June 26, 2013, 1:22 p.m. UTC
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>
---
 drivers/gpu/drm/radeon/radeon.h      |    5 +++
 drivers/gpu/drm/radeon/radeon_ring.c |   55 +++++++++++++++++++++++++--------
 2 files changed, 46 insertions(+), 14 deletions(-)

Comments

Christian König June 26, 2013, 3:31 p.m. UTC | #1
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 mbox

Patch

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,