diff options
author | Rob Clark <robdclark@gmail.com> | 2013-12-22 10:29:43 -0500 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2014-03-31 10:27:45 -0400 |
commit | 5b6ef08e4b4e1bcb6b3ac4172c054e4462e2c767 (patch) | |
tree | d62e3bc1dfa8d95e241a136e0702ad2c3f28f55b /drivers/gpu/drm/msm | |
parent | c0c0d9eeeb8df43964601a2c4666f0c49bedacb4 (diff) |
drm/msm: add hang_debug module param
msm.hang_debug=y will dump out current register values if the gpu locks
up, for easier debugging.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r-- | drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.h | 1 |
3 files changed, 52 insertions, 1 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 461df93e825e..8b6fb847789e 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c | |||
@@ -35,6 +35,12 @@ | |||
35 | A3XX_INT0_CP_AHB_ERROR_HALT | \ | 35 | A3XX_INT0_CP_AHB_ERROR_HALT | \ |
36 | A3XX_INT0_UCHE_OOB_ACCESS) | 36 | A3XX_INT0_UCHE_OOB_ACCESS) |
37 | 37 | ||
38 | |||
39 | static bool hang_debug = false; | ||
40 | MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)"); | ||
41 | module_param_named(hang_debug, hang_debug, bool, 0600); | ||
42 | static void a3xx_dump(struct msm_gpu *gpu); | ||
43 | |||
38 | static struct platform_device *a3xx_pdev; | 44 | static struct platform_device *a3xx_pdev; |
39 | 45 | ||
40 | static void a3xx_me_init(struct msm_gpu *gpu) | 46 | static void a3xx_me_init(struct msm_gpu *gpu) |
@@ -291,6 +297,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu) | |||
291 | 297 | ||
292 | static void a3xx_recover(struct msm_gpu *gpu) | 298 | static void a3xx_recover(struct msm_gpu *gpu) |
293 | { | 299 | { |
300 | /* dump registers before resetting gpu, if enabled: */ | ||
301 | if (hang_debug) | ||
302 | a3xx_dump(gpu); | ||
294 | gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 1); | 303 | gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 1); |
295 | gpu_read(gpu, REG_A3XX_RBBM_SW_RESET_CMD); | 304 | gpu_read(gpu, REG_A3XX_RBBM_SW_RESET_CMD); |
296 | gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 0); | 305 | gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 0); |
@@ -352,7 +361,6 @@ static irqreturn_t a3xx_irq(struct msm_gpu *gpu) | |||
352 | return IRQ_HANDLED; | 361 | return IRQ_HANDLED; |
353 | } | 362 | } |
354 | 363 | ||
355 | #ifdef CONFIG_DEBUG_FS | ||
356 | static const unsigned int a3xx_registers[] = { | 364 | static const unsigned int a3xx_registers[] = { |
357 | 0x0000, 0x0002, 0x0010, 0x0012, 0x0018, 0x0018, 0x0020, 0x0027, | 365 | 0x0000, 0x0002, 0x0010, 0x0012, 0x0018, 0x0018, 0x0020, 0x0027, |
358 | 0x0029, 0x002b, 0x002e, 0x0033, 0x0040, 0x0042, 0x0050, 0x005c, | 366 | 0x0029, 0x002b, 0x002e, 0x0033, 0x0040, 0x0042, 0x0050, 0x005c, |
@@ -392,6 +400,7 @@ static const unsigned int a3xx_registers[] = { | |||
392 | 0x303c, 0x303c, 0x305e, 0x305f, | 400 | 0x303c, 0x303c, 0x305e, 0x305f, |
393 | }; | 401 | }; |
394 | 402 | ||
403 | #ifdef CONFIG_DEBUG_FS | ||
395 | static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m) | 404 | static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m) |
396 | { | 405 | { |
397 | int i; | 406 | int i; |
@@ -415,6 +424,29 @@ static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m) | |||
415 | } | 424 | } |
416 | #endif | 425 | #endif |
417 | 426 | ||
427 | /* would be nice to not have to duplicate the _show() stuff with printk(): */ | ||
428 | static void a3xx_dump(struct msm_gpu *gpu) | ||
429 | { | ||
430 | int i; | ||
431 | |||
432 | adreno_dump(gpu); | ||
433 | printk("status: %08x\n", | ||
434 | gpu_read(gpu, REG_A3XX_RBBM_STATUS)); | ||
435 | |||
436 | /* dump these out in a form that can be parsed by demsm: */ | ||
437 | printk("IO:region %s 00000000 00020000\n", gpu->name); | ||
438 | for (i = 0; i < ARRAY_SIZE(a3xx_registers); i += 2) { | ||
439 | uint32_t start = a3xx_registers[i]; | ||
440 | uint32_t end = a3xx_registers[i+1]; | ||
441 | uint32_t addr; | ||
442 | |||
443 | for (addr = start; addr <= end; addr++) { | ||
444 | uint32_t val = gpu_read(gpu, addr); | ||
445 | printk("IO:R %08x %08x\n", addr<<2, val); | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
418 | static const struct adreno_gpu_funcs funcs = { | 450 | static const struct adreno_gpu_funcs funcs = { |
419 | .base = { | 451 | .base = { |
420 | .get_param = adreno_get_param, | 452 | .get_param = adreno_get_param, |
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index d321099abdd4..cf6eb976dda7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c | |||
@@ -260,6 +260,24 @@ void adreno_show(struct msm_gpu *gpu, struct seq_file *m) | |||
260 | } | 260 | } |
261 | #endif | 261 | #endif |
262 | 262 | ||
263 | /* would be nice to not have to duplicate the _show() stuff with printk(): */ | ||
264 | void adreno_dump(struct msm_gpu *gpu) | ||
265 | { | ||
266 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | ||
267 | |||
268 | printk("revision: %d (%d.%d.%d.%d)\n", | ||
269 | adreno_gpu->info->revn, adreno_gpu->rev.core, | ||
270 | adreno_gpu->rev.major, adreno_gpu->rev.minor, | ||
271 | adreno_gpu->rev.patchid); | ||
272 | |||
273 | printk("fence: %d/%d\n", adreno_gpu->memptrs->fence, | ||
274 | gpu->submitted_fence); | ||
275 | printk("rptr: %d\n", adreno_gpu->memptrs->rptr); | ||
276 | printk("wptr: %d\n", adreno_gpu->memptrs->wptr); | ||
277 | printk("rb wptr: %d\n", get_wptr(gpu->rb)); | ||
278 | |||
279 | } | ||
280 | |||
263 | void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords) | 281 | void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords) |
264 | { | 282 | { |
265 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | 283 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index ca11ea4da165..e16200ddc60b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h | |||
@@ -114,6 +114,7 @@ void adreno_idle(struct msm_gpu *gpu); | |||
114 | #ifdef CONFIG_DEBUG_FS | 114 | #ifdef CONFIG_DEBUG_FS |
115 | void adreno_show(struct msm_gpu *gpu, struct seq_file *m); | 115 | void adreno_show(struct msm_gpu *gpu, struct seq_file *m); |
116 | #endif | 116 | #endif |
117 | void adreno_dump(struct msm_gpu *gpu); | ||
117 | void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords); | 118 | void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords); |
118 | 119 | ||
119 | int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, | 120 | int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, |