On Fri, Nov 4, 2016 at 6:44 PM, Jordan Crouse <jcrouse@xxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/freedreno -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html