aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-08-04 15:26:07 -0400
committerEric Anholt <eric@anholt.net>2010-08-09 14:24:31 -0400
commit6ef3d4278034982c13df87c4a51e0445f762d316 (patch)
treebb67e30d7898a1024d68b5bce4e526b40a2807fd
parentdbd7ac9661ba321fe9c1f1b7cb5f4471a6e59570 (diff)
drm/i915: Capture the overlay status upon a GPU hang.
v2: Add the interrupt status and address. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h10
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c3
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c96
4 files changed, 110 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 9214119c0154..92d5605a34d1 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -467,6 +467,9 @@ static int i915_error_state(struct seq_file *m, void *unused)
467 } 467 }
468 } 468 }
469 469
470 if (error->overlay)
471 intel_overlay_print_error_state(m, error->overlay);
472
470out: 473out:
471 spin_unlock_irqrestore(&dev_priv->error_lock, flags); 474 spin_unlock_irqrestore(&dev_priv->error_lock, flags);
472 475
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5cd593f826ef..151056501a5f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -113,6 +113,9 @@ struct intel_opregion {
113 int enabled; 113 int enabled;
114}; 114};
115 115
116struct intel_overlay;
117struct intel_overlay_error_state;
118
116struct drm_i915_master_private { 119struct drm_i915_master_private {
117 drm_local_map_t *sarea; 120 drm_local_map_t *sarea;
118 struct _drm_i915_sarea *sarea_priv; 121 struct _drm_i915_sarea *sarea_priv;
@@ -166,6 +169,7 @@ struct drm_i915_error_state {
166 u32 purgeable:1; 169 u32 purgeable:1;
167 } *active_bo; 170 } *active_bo;
168 u32 active_bo_count; 171 u32 active_bo_count;
172 struct intel_overlay_error_state *overlay;
169}; 173};
170 174
171struct drm_i915_display_funcs { 175struct drm_i915_display_funcs {
@@ -186,8 +190,6 @@ struct drm_i915_display_funcs {
186 /* clock gating init */ 190 /* clock gating init */
187}; 191};
188 192
189struct intel_overlay;
190
191struct intel_device_info { 193struct intel_device_info {
192 u8 is_mobile : 1; 194 u8 is_mobile : 1;
193 u8 is_i8xx : 1; 195 u8 is_i8xx : 1;
@@ -1069,6 +1071,10 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
1069extern void intel_detect_pch (struct drm_device *dev); 1071extern void intel_detect_pch (struct drm_device *dev);
1070extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); 1072extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
1071 1073
1074/* overlay */
1075extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
1076extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
1077
1072/** 1078/**
1073 * Lock test for when it's just for synchronization of ring access. 1079 * Lock test for when it's just for synchronization of ring access.
1074 * 1080 *
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 85785a8844ed..854ab1e92fd9 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -489,6 +489,7 @@ i915_error_state_free(struct drm_device *dev,
489 i915_error_object_free(error->batchbuffer[1]); 489 i915_error_object_free(error->batchbuffer[1]);
490 i915_error_object_free(error->ringbuffer); 490 i915_error_object_free(error->ringbuffer);
491 kfree(error->active_bo); 491 kfree(error->active_bo);
492 kfree(error->overlay);
492 kfree(error); 493 kfree(error);
493} 494}
494 495
@@ -667,6 +668,8 @@ static void i915_capture_error_state(struct drm_device *dev)
667 668
668 do_gettimeofday(&error->time); 669 do_gettimeofday(&error->time);
669 670
671 error->overlay = intel_overlay_capture_error_state(dev);
672
670 spin_lock_irqsave(&dev_priv->error_lock, flags); 673 spin_lock_irqsave(&dev_priv->error_lock, flags);
671 if (dev_priv->first_error == NULL) { 674 if (dev_priv->first_error == NULL) {
672 dev_priv->first_error = error; 675 dev_priv->first_error = error;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index d39aea24eabe..9ae61aa05a1f 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1416,3 +1416,99 @@ void intel_cleanup_overlay(struct drm_device *dev)
1416 kfree(dev_priv->overlay); 1416 kfree(dev_priv->overlay);
1417 } 1417 }
1418} 1418}
1419
1420struct intel_overlay_error_state {
1421 struct overlay_registers regs;
1422 unsigned long base;
1423 u32 dovsta;
1424 u32 isr;
1425};
1426
1427struct intel_overlay_error_state *
1428intel_overlay_capture_error_state(struct drm_device *dev)
1429{
1430 drm_i915_private_t *dev_priv = dev->dev_private;
1431 struct intel_overlay *overlay = dev_priv->overlay;
1432 struct intel_overlay_error_state *error;
1433 struct overlay_registers __iomem *regs;
1434
1435 if (!overlay || !overlay->active)
1436 return NULL;
1437
1438 error = kmalloc(sizeof(*error), GFP_ATOMIC);
1439 if (error == NULL)
1440 return NULL;
1441
1442 error->dovsta = I915_READ(DOVSTA);
1443 error->isr = I915_READ(ISR);
1444 if (OVERLAY_NONPHYSICAL(overlay->dev))
1445 error->base = (long) overlay->reg_bo->gtt_offset;
1446 else
1447 error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
1448
1449 regs = intel_overlay_map_regs_atomic(overlay);
1450 if (!regs)
1451 goto err;
1452
1453 memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1454 intel_overlay_unmap_regs_atomic(overlay);
1455
1456 return error;
1457
1458err:
1459 kfree(error);
1460 return NULL;
1461}
1462
1463void
1464intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
1465{
1466 seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1467 error->dovsta, error->isr);
1468 seq_printf(m, " Register file at 0x%08lx:\n",
1469 error->base);
1470
1471#define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x)
1472 P(OBUF_0Y);
1473 P(OBUF_1Y);
1474 P(OBUF_0U);
1475 P(OBUF_0V);
1476 P(OBUF_1U);
1477 P(OBUF_1V);
1478 P(OSTRIDE);
1479 P(YRGB_VPH);
1480 P(UV_VPH);
1481 P(HORZ_PH);
1482 P(INIT_PHS);
1483 P(DWINPOS);
1484 P(DWINSZ);
1485 P(SWIDTH);
1486 P(SWIDTHSW);
1487 P(SHEIGHT);
1488 P(YRGBSCALE);
1489 P(UVSCALE);
1490 P(OCLRC0);
1491 P(OCLRC1);
1492 P(DCLRKV);
1493 P(DCLRKM);
1494 P(SCLRKVH);
1495 P(SCLRKVL);
1496 P(SCLRKEN);
1497 P(OCONFIG);
1498 P(OCMD);
1499 P(OSTART_0Y);
1500 P(OSTART_1Y);
1501 P(OSTART_0U);
1502 P(OSTART_0V);
1503 P(OSTART_1U);
1504 P(OSTART_1V);
1505 P(OTILEOFF_0Y);
1506 P(OTILEOFF_1Y);
1507 P(OTILEOFF_0U);
1508 P(OTILEOFF_0V);
1509 P(OTILEOFF_1U);
1510 P(OTILEOFF_1V);
1511 P(FASTHSCALE);
1512 P(UVSCALEV);
1513#undef P
1514}