[Freedreno] [PATCH 05/16] drm/msm: gpu: Return error on hw_init failure
Rob Clark
robdclark at gmail.com
Mon Nov 7 18:54:36 UTC 2016
On Fri, Nov 4, 2016 at 6:44 PM, Jordan Crouse <jcrouse at codeaurora.org> wrote:
> When the GPU hardware init function fails (like say, ME_INIT timed
> out) return error instead of blindly continuing on. This gives us
> a small chance of saving the system before it goes boom.
seems like a good idea.. although I guess we should just make it an
int return (ie. 0 or -ETIMEDOUT)..
BR,
-R
> Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
> ---
> drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 21 ++++++++++++---------
> drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 20 +++++++++++---------
> drivers/gpu/drm/msm/adreno/adreno_gpu.c | 11 +++++------
> drivers/gpu/drm/msm/adreno/adreno_gpu.h | 2 +-
> drivers/gpu/drm/msm/msm_gpu.h | 2 +-
> 5 files changed, 30 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> index 5eda847..13989d9 100644
> --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
> @@ -41,7 +41,7 @@ extern bool hang_debug;
>
> static void a3xx_dump(struct msm_gpu *gpu);
>
> -static void a3xx_me_init(struct msm_gpu *gpu)
> +static bool a3xx_me_init(struct msm_gpu *gpu)
> {
> struct msm_ringbuffer *ring = gpu->rb;
>
> @@ -65,7 +65,7 @@ static void a3xx_me_init(struct msm_gpu *gpu)
> OUT_RING(ring, 0x00000000);
>
> gpu->funcs->flush(gpu);
> - gpu->funcs->idle(gpu);
> + return gpu->funcs->idle(gpu);
> }
>
> static int a3xx_hw_init(struct msm_gpu *gpu)
> @@ -294,9 +294,7 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
> /* clear ME_HALT to start micro engine */
> gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0);
>
> - a3xx_me_init(gpu);
> -
> - return 0;
> + return a3xx_me_init(gpu) ? 0 : -EINVAL;
> }
>
> static void a3xx_recover(struct msm_gpu *gpu)
> @@ -330,17 +328,22 @@ static void a3xx_destroy(struct msm_gpu *gpu)
> kfree(a3xx_gpu);
> }
>
> -static void a3xx_idle(struct msm_gpu *gpu)
> +static bool a3xx_idle(struct msm_gpu *gpu)
> {
> /* wait for ringbuffer to drain: */
> - adreno_idle(gpu);
> + if (!adreno_idle(gpu))
> + return false;
>
> /* then wait for GPU to finish: */
> if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) &
> - A3XX_RBBM_STATUS_GPU_BUSY)))
> + 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? */
> + /* TODO maybe we need to reset GPU here to recover from hang? */
> + return false;
> + }
> +
> + return true;
> }
>
> static irqreturn_t a3xx_irq(struct msm_gpu *gpu)
> diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> index 0354be2..ba16507 100644
> --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
> @@ -113,7 +113,7 @@ static void a4xx_enable_hwcg(struct msm_gpu *gpu)
> }
>
>
> -static void a4xx_me_init(struct msm_gpu *gpu)
> +static bool a4xx_me_init(struct msm_gpu *gpu)
> {
> struct msm_ringbuffer *ring = gpu->rb;
>
> @@ -137,7 +137,7 @@ static void a4xx_me_init(struct msm_gpu *gpu)
> OUT_RING(ring, 0x00000000);
>
> gpu->funcs->flush(gpu);
> - gpu->funcs->idle(gpu);
> + return gpu->funcs->idle(gpu);
> }
>
> static int a4xx_hw_init(struct msm_gpu *gpu)
> @@ -292,9 +292,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
> /* clear ME_HALT to start micro engine */
> gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0);
>
> - a4xx_me_init(gpu);
> -
> - return 0;
> + return a4xx_me_init(gpu) ? 0 : -EINVAL;
> }
>
> static void a4xx_recover(struct msm_gpu *gpu)
> @@ -328,17 +326,21 @@ static void a4xx_destroy(struct msm_gpu *gpu)
> kfree(a4xx_gpu);
> }
>
> -static void a4xx_idle(struct msm_gpu *gpu)
> +static bool a4xx_idle(struct msm_gpu *gpu)
> {
> /* wait for ringbuffer to drain: */
> - adreno_idle(gpu);
> + if (!adreno_idle(gpu))
> + return false;
>
> /* then wait for GPU to finish: */
> if (spin_until(!(gpu_read(gpu, REG_A4XX_RBBM_STATUS) &
> - A4XX_RBBM_STATUS_GPU_BUSY)))
> + A4XX_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? */
> + return false;
> + }
>
> - /* TODO maybe we need to reset GPU here to recover from hang? */
> + return true;
> }
>
> static irqreturn_t a4xx_irq(struct msm_gpu *gpu)
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index f386f46..8b2201c 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -218,19 +218,18 @@ void adreno_flush(struct msm_gpu *gpu)
> adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_WPTR, wptr);
> }
>
> -void adreno_idle(struct msm_gpu *gpu)
> +bool adreno_idle(struct msm_gpu *gpu)
> {
> struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> uint32_t wptr = get_wptr(gpu->rb);
> - int ret;
>
> /* wait for CP to drain ringbuffer: */
> - ret = spin_until(get_rptr(adreno_gpu) == wptr);
> -
> - if (ret)
> - DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
> + if (!spin_until(get_rptr(adreno_gpu) == wptr))
> + return true;
>
> /* TODO maybe we need to reset GPU here to recover from hang? */
> + DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
> + return false;
> }
>
> #ifdef CONFIG_DEBUG_FS
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> index fd976e8..30c2956 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> @@ -182,7 +182,7 @@ void adreno_recover(struct msm_gpu *gpu);
> void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
> struct msm_file_private *ctx);
> void adreno_flush(struct msm_gpu *gpu);
> -void adreno_idle(struct msm_gpu *gpu);
> +bool adreno_idle(struct msm_gpu *gpu);
> #ifdef CONFIG_DEBUG_FS
> void adreno_show(struct msm_gpu *gpu, struct seq_file *m);
> #endif
> diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
> index c902283..4ee95ca 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.h
> +++ b/drivers/gpu/drm/msm/msm_gpu.h
> @@ -50,7 +50,7 @@ struct msm_gpu_funcs {
> void (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit,
> struct msm_file_private *ctx);
> void (*flush)(struct msm_gpu *gpu);
> - void (*idle)(struct msm_gpu *gpu);
> + bool (*idle)(struct msm_gpu *gpu);
> irqreturn_t (*irq)(struct msm_gpu *irq);
> uint32_t (*last_fence)(struct msm_gpu *gpu);
> void (*recover)(struct msm_gpu *gpu);
> --
> 1.9.1
>
> _______________________________________________
> Freedreno mailing list
> Freedreno at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno
More information about the Freedreno
mailing list