aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2016-11-28 14:28:27 -0500
committerRob Clark <robdclark@gmail.com>2016-11-28 15:14:11 -0500
commitc4a8d4756061f72cba52af1e3035c07769cee679 (patch)
treea48c7d5dd2bc366eb96db6ee44494105a660a9f5
parentbcc188b77d3e7d77fc7efd5feab148707e095b77 (diff)
drm/msm: gpu: Return error on hw_init failure
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. Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c21
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.c20
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c11
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h2
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h2
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 a224fdbcb5f0..ff6489444423 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;
41 41
42static void a3xx_dump(struct msm_gpu *gpu); 42static void a3xx_dump(struct msm_gpu *gpu);
43 43
44static void a3xx_me_init(struct msm_gpu *gpu) 44static bool a3xx_me_init(struct msm_gpu *gpu)
45{ 45{
46 struct msm_ringbuffer *ring = gpu->rb; 46 struct msm_ringbuffer *ring = gpu->rb;
47 47
@@ -65,7 +65,7 @@ static void a3xx_me_init(struct msm_gpu *gpu)
65 OUT_RING(ring, 0x00000000); 65 OUT_RING(ring, 0x00000000);
66 66
67 gpu->funcs->flush(gpu); 67 gpu->funcs->flush(gpu);
68 gpu->funcs->idle(gpu); 68 return gpu->funcs->idle(gpu);
69} 69}
70 70
71static int a3xx_hw_init(struct msm_gpu *gpu) 71static int a3xx_hw_init(struct msm_gpu *gpu)
@@ -294,9 +294,7 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
294 /* clear ME_HALT to start micro engine */ 294 /* clear ME_HALT to start micro engine */
295 gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0); 295 gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0);
296 296
297 a3xx_me_init(gpu); 297 return a3xx_me_init(gpu) ? 0 : -EINVAL;
298
299 return 0;
300} 298}
301 299
302static void a3xx_recover(struct msm_gpu *gpu) 300static void a3xx_recover(struct msm_gpu *gpu)
@@ -337,17 +335,22 @@ static void a3xx_destroy(struct msm_gpu *gpu)
337 kfree(a3xx_gpu); 335 kfree(a3xx_gpu);
338} 336}
339 337
340static void a3xx_idle(struct msm_gpu *gpu) 338static bool a3xx_idle(struct msm_gpu *gpu)
341{ 339{
342 /* wait for ringbuffer to drain: */ 340 /* wait for ringbuffer to drain: */
343 adreno_idle(gpu); 341 if (!adreno_idle(gpu))
342 return false;
344 343
345 /* then wait for GPU to finish: */ 344 /* then wait for GPU to finish: */
346 if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) & 345 if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) &
347 A3XX_RBBM_STATUS_GPU_BUSY))) 346 A3XX_RBBM_STATUS_GPU_BUSY))) {
348 DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name); 347 DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
349 348
350 /* TODO maybe we need to reset GPU here to recover from hang? */ 349 /* TODO maybe we need to reset GPU here to recover from hang? */
350 return false;
351 }
352
353 return true;
351} 354}
352 355
353static irqreturn_t a3xx_irq(struct msm_gpu *gpu) 356static 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 5745cc81eeda..2abf2627f822 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)
113} 113}
114 114
115 115
116static void a4xx_me_init(struct msm_gpu *gpu) 116static bool a4xx_me_init(struct msm_gpu *gpu)
117{ 117{
118 struct msm_ringbuffer *ring = gpu->rb; 118 struct msm_ringbuffer *ring = gpu->rb;
119 119
@@ -137,7 +137,7 @@ static void a4xx_me_init(struct msm_gpu *gpu)
137 OUT_RING(ring, 0x00000000); 137 OUT_RING(ring, 0x00000000);
138 138
139 gpu->funcs->flush(gpu); 139 gpu->funcs->flush(gpu);
140 gpu->funcs->idle(gpu); 140 return gpu->funcs->idle(gpu);
141} 141}
142 142
143static int a4xx_hw_init(struct msm_gpu *gpu) 143static int a4xx_hw_init(struct msm_gpu *gpu)
@@ -292,9 +292,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
292 /* clear ME_HALT to start micro engine */ 292 /* clear ME_HALT to start micro engine */
293 gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0); 293 gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0);
294 294
295 a4xx_me_init(gpu); 295 return a4xx_me_init(gpu) ? 0 : -EINVAL;
296
297 return 0;
298} 296}
299 297
300static void a4xx_recover(struct msm_gpu *gpu) 298static void a4xx_recover(struct msm_gpu *gpu)
@@ -335,17 +333,21 @@ static void a4xx_destroy(struct msm_gpu *gpu)
335 kfree(a4xx_gpu); 333 kfree(a4xx_gpu);
336} 334}
337 335
338static void a4xx_idle(struct msm_gpu *gpu) 336static bool a4xx_idle(struct msm_gpu *gpu)
339{ 337{
340 /* wait for ringbuffer to drain: */ 338 /* wait for ringbuffer to drain: */
341 adreno_idle(gpu); 339 if (!adreno_idle(gpu))
340 return false;
342 341
343 /* then wait for GPU to finish: */ 342 /* then wait for GPU to finish: */
344 if (spin_until(!(gpu_read(gpu, REG_A4XX_RBBM_STATUS) & 343 if (spin_until(!(gpu_read(gpu, REG_A4XX_RBBM_STATUS) &
345 A4XX_RBBM_STATUS_GPU_BUSY))) 344 A4XX_RBBM_STATUS_GPU_BUSY))) {
346 DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name); 345 DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
346 /* TODO maybe we need to reset GPU here to recover from hang? */
347 return false;
348 }
347 349
348 /* TODO maybe we need to reset GPU here to recover from hang? */ 350 return true;
349} 351}
350 352
351static irqreturn_t a4xx_irq(struct msm_gpu *gpu) 353static 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 3d4eb08d8c28..04080f9b7e09 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)
218 adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_WPTR, wptr); 218 adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_WPTR, wptr);
219} 219}
220 220
221void adreno_idle(struct msm_gpu *gpu) 221bool adreno_idle(struct msm_gpu *gpu)
222{ 222{
223 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 223 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
224 uint32_t wptr = get_wptr(gpu->rb); 224 uint32_t wptr = get_wptr(gpu->rb);
225 int ret;
226 225
227 /* wait for CP to drain ringbuffer: */ 226 /* wait for CP to drain ringbuffer: */
228 ret = spin_until(get_rptr(adreno_gpu) == wptr); 227 if (!spin_until(get_rptr(adreno_gpu) == wptr))
229 228 return true;
230 if (ret)
231 DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
232 229
233 /* TODO maybe we need to reset GPU here to recover from hang? */ 230 /* TODO maybe we need to reset GPU here to recover from hang? */
231 DRM_ERROR("%s: timeout waiting to drain ringbuffer!\n", gpu->name);
232 return false;
234} 233}
235 234
236#ifdef CONFIG_DEBUG_FS 235#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 cccc1a508295..d0f9e1e3acd6 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);
182void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, 182void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
183 struct msm_file_private *ctx); 183 struct msm_file_private *ctx);
184void adreno_flush(struct msm_gpu *gpu); 184void adreno_flush(struct msm_gpu *gpu);
185void adreno_idle(struct msm_gpu *gpu); 185bool adreno_idle(struct msm_gpu *gpu);
186#ifdef CONFIG_DEBUG_FS 186#ifdef CONFIG_DEBUG_FS
187void adreno_show(struct msm_gpu *gpu, struct seq_file *m); 187void adreno_show(struct msm_gpu *gpu, struct seq_file *m);
188#endif 188#endif
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 6a7e78b317f2..10954135130d 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 {
50 void (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit, 50 void (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit,
51 struct msm_file_private *ctx); 51 struct msm_file_private *ctx);
52 void (*flush)(struct msm_gpu *gpu); 52 void (*flush)(struct msm_gpu *gpu);
53 void (*idle)(struct msm_gpu *gpu); 53 bool (*idle)(struct msm_gpu *gpu);
54 irqreturn_t (*irq)(struct msm_gpu *irq); 54 irqreturn_t (*irq)(struct msm_gpu *irq);
55 uint32_t (*last_fence)(struct msm_gpu *gpu); 55 uint32_t (*last_fence)(struct msm_gpu *gpu);
56 void (*recover)(struct msm_gpu *gpu); 56 void (*recover)(struct msm_gpu *gpu);