diff mbox

[3/7] drm/msm: spin helper

Message ID 1394470062-27442-4-git-send-email-robdclark@gmail.com (mailing list archive)
State Deferred
Headers show

Commit Message

Rob Clark March 10, 2014, 4:47 p.m. UTC
Helper macro to simplify places where we need to poll with timeout
waiting for gpu.

Signed-off-by: Rob Clark <robdclark@gmail.com>
---
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c   | 14 +++--------
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 41 ++++++++++++---------------------
 drivers/gpu/drm/msm/adreno/adreno_gpu.h | 15 +++++++++++-
 3 files changed, 32 insertions(+), 38 deletions(-)

Comments

Jordan Crouse March 10, 2014, 8:27 p.m. UTC | #1
On 03/10/2014 10:47 AM, Rob Clark wrote:
> Helper macro to simplify places where we need to poll with timeout
> waiting for gpu.
>
> Signed-off-by: Rob Clark <robdclark@gmail.com>

Acked-by: Jordan Crouse <jcrouse@codeaurora.org>
> ---
>   drivers/gpu/drm/msm/adreno/a3xx_gpu.c   | 14 +++--------
>   drivers/gpu/drm/msm/adreno/adreno_gpu.c | 41 ++++++++++++---------------------
>   drivers/gpu/drm/msm/adreno/adreno_gpu.h | 15 +++++++++++-
>   3 files changed, 32 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> index 8b6fb84..59ed762 100644
> --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> @@ -326,21 +326,13 @@ static void a3xx_destroy(struct msm_gpu *gpu)
>
>   static void a3xx_idle(struct msm_gpu *gpu)
>   {
> -	unsigned long t;
> -
>   	/* wait for ringbuffer to drain: */
>   	adreno_idle(gpu);
>
> -	t = jiffies + ADRENO_IDLE_TIMEOUT;
> -
>   	/* then wait for GPU to finish: */
> -	do {
> -		uint32_t rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS);
> -		if (!(rbbm_status & A3XX_RBBM_STATUS_GPU_BUSY))
> -			return;
> -	} while(time_before(jiffies, t));
> -
> -	DRM_ERROR("timeout waiting for %s to idle!\n", gpu->name);
> +	if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) &
> +			A3XX_RBBM_STATUS_GPU_BUSY)))
> +		DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
>
>   	/* TODO maybe we need to reset GPU here to recover from hang? */
>   }
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index cf6eb97..7a11563 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -225,19 +225,11 @@ void adreno_flush(struct msm_gpu *gpu)
>   void adreno_idle(struct msm_gpu *gpu)
>   {
>   	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> -	uint32_t rptr, wptr = get_wptr(gpu->rb);
> -	unsigned long t;
> -
> -	t = jiffies + ADRENO_IDLE_TIMEOUT;
> -
> -	/* then wait for CP to drain ringbuffer: */
> -	do {
> -		rptr = adreno_gpu->memptrs->rptr;
> -		if (rptr == wptr)
> -			return;
> -	} while(time_before(jiffies, t));
> +	uint32_t wptr = get_wptr(gpu->rb);
>
> -	DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
> +	/* wait for CP to drain ringbuffer: */
> +	if (spin_until(adreno_gpu->memptrs->rptr == wptr))
> +		DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
>
>   	/* TODO maybe we need to reset GPU here to recover from hang? */
>   }
> @@ -278,22 +270,19 @@ void adreno_dump(struct msm_gpu *gpu)
>
>   }
>
> -void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
> +static uint32_t ring_freewords(struct msm_gpu *gpu)
>   {
>   	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> -	uint32_t freedwords;
> -	unsigned long t = jiffies + ADRENO_IDLE_TIMEOUT;
> -	do {
> -		uint32_t size = gpu->rb->size / 4;
> -		uint32_t wptr = get_wptr(gpu->rb);
> -		uint32_t rptr = adreno_gpu->memptrs->rptr;
> -		freedwords = (rptr + (size - 1) - wptr) % size;
> -
> -		if (time_after(jiffies, t)) {
> -			DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
> -			break;
> -		}
> -	} while(freedwords < ndwords);
> +	uint32_t size = gpu->rb->size / 4;
> +	uint32_t wptr = get_wptr(gpu->rb);
> +	uint32_t rptr = adreno_gpu->memptrs->rptr;
> +	return (rptr + (size - 1) - wptr) % size;
> +}
> +
> +void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
> +{
> +	if (spin_until(ring_freewords(gpu) >= ndwords))
> +		DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
>   }
>
>   static const char *iommu_ports[] = {
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> index e16200d..63c36ce 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> @@ -76,7 +76,20 @@ struct adreno_platform_config {
>   #endif
>   };
>
> -#define ADRENO_IDLE_TIMEOUT (20 * 1000)
> +#define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
> +
> +#define spin_until(X) ({                                   \
> +	int __ret = -ETIMEDOUT;                            \
> +	unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \
> +	do {                                               \
> +		if (X) {                                   \
> +			__ret = 0;                         \
> +			break;                             \
> +		}                                          \
> +	} while (time_before(jiffies, __t));               \
> +	__ret;                                             \
> +})
> +
>
>   static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
>   {
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 8b6fb84..59ed762 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -326,21 +326,13 @@  static void a3xx_destroy(struct msm_gpu *gpu)
 
 static void a3xx_idle(struct msm_gpu *gpu)
 {
-	unsigned long t;
-
 	/* wait for ringbuffer to drain: */
 	adreno_idle(gpu);
 
-	t = jiffies + ADRENO_IDLE_TIMEOUT;
-
 	/* then wait for GPU to finish: */
-	do {
-		uint32_t rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS);
-		if (!(rbbm_status & A3XX_RBBM_STATUS_GPU_BUSY))
-			return;
-	} while(time_before(jiffies, t));
-
-	DRM_ERROR("timeout waiting for %s to idle!\n", gpu->name);
+	if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) &
+			A3XX_RBBM_STATUS_GPU_BUSY)))
+		DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
 
 	/* TODO maybe we need to reset GPU here to recover from hang? */
 }
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index cf6eb97..7a11563 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -225,19 +225,11 @@  void adreno_flush(struct msm_gpu *gpu)
 void adreno_idle(struct msm_gpu *gpu)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
-	uint32_t rptr, wptr = get_wptr(gpu->rb);
-	unsigned long t;
-
-	t = jiffies + ADRENO_IDLE_TIMEOUT;
-
-	/* then wait for CP to drain ringbuffer: */
-	do {
-		rptr = adreno_gpu->memptrs->rptr;
-		if (rptr == wptr)
-			return;
-	} while(time_before(jiffies, t));
+	uint32_t wptr = get_wptr(gpu->rb);
 
-	DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
+	/* wait for CP to drain ringbuffer: */
+	if (spin_until(adreno_gpu->memptrs->rptr == wptr))
+		DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
 
 	/* TODO maybe we need to reset GPU here to recover from hang? */
 }
@@ -278,22 +270,19 @@  void adreno_dump(struct msm_gpu *gpu)
 
 }
 
-void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
+static uint32_t ring_freewords(struct msm_gpu *gpu)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
-	uint32_t freedwords;
-	unsigned long t = jiffies + ADRENO_IDLE_TIMEOUT;
-	do {
-		uint32_t size = gpu->rb->size / 4;
-		uint32_t wptr = get_wptr(gpu->rb);
-		uint32_t rptr = adreno_gpu->memptrs->rptr;
-		freedwords = (rptr + (size - 1) - wptr) % size;
-
-		if (time_after(jiffies, t)) {
-			DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
-			break;
-		}
-	} while(freedwords < ndwords);
+	uint32_t size = gpu->rb->size / 4;
+	uint32_t wptr = get_wptr(gpu->rb);
+	uint32_t rptr = adreno_gpu->memptrs->rptr;
+	return (rptr + (size - 1) - wptr) % size;
+}
+
+void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
+{
+	if (spin_until(ring_freewords(gpu) >= ndwords))
+		DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
 }
 
 static const char *iommu_ports[] = {
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index e16200d..63c36ce 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -76,7 +76,20 @@  struct adreno_platform_config {
 #endif
 };
 
-#define ADRENO_IDLE_TIMEOUT (20 * 1000)
+#define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
+
+#define spin_until(X) ({                                   \
+	int __ret = -ETIMEDOUT;                            \
+	unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \
+	do {                                               \
+		if (X) {                                   \
+			__ret = 0;                         \
+			break;                             \
+		}                                          \
+	} while (time_before(jiffies, __t));               \
+	__ret;                                             \
+})
+
 
 static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
 {