drm/i915: collect more per ring error state
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 14 Dec 2011 12:57:02 +0000 (13:57 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sun, 29 Jan 2012 16:45:07 +0000 (17:45 +0100)
Based on a patch by Ben Widawsky, but with different colors
for the bikeshed.

In contrast to Ben's patch this one doesn't add the fault regs.
Afaics they're for the optional page fault support which
- we're not enabling
- and which seems to be unsupported by the hw team. Recent bspec
  lacks tons of information about this that the public docs released
  half a year back still contain.

Also dump ring HEAD/TAIL registers - I've recently seen a few
error_state where just guessing these is not good enough.

v2: Also dump INSTPM for every ring.

v3: Fix a few really silly goof-ups spotted by Chris Wilson.

Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h

index 4002846d56a2763049271bf7d93c0f2ab2ead2a5..5aa256861df060e450bb080b253c31d2714375c5 100644 (file)
@@ -744,17 +744,21 @@ static void i915_ring_error_state(struct seq_file *m,
                                  unsigned ring)
 {
        seq_printf(m, "%s command stream:\n", ring_str(ring));
+       seq_printf(m, "  HEAD: 0x%08x\n", error->head[ring]);
+       seq_printf(m, "  TAIL: 0x%08x\n", error->tail[ring]);
        seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd[ring]);
        seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir[ring]);
        seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr[ring]);
        seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone[ring]);
-       if (ring == RCS) {
-               if (INTEL_INFO(dev)->gen >= 4) {
-                       seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
-                       seq_printf(m, "  INSTPS: 0x%08x\n", error->instps);
-               }
-               seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
+       if (ring == RCS && INTEL_INFO(dev)->gen >= 4) {
+               seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
+               seq_printf(m, "  BBADDR: 0x%08llx\n", error->bbaddr);
        }
+       if (INTEL_INFO(dev)->gen >= 4)
+               seq_printf(m, "  INSTPS: 0x%08x\n", error->instps[ring]);
+       seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm[ring]);
+       if (INTEL_INFO(dev)->gen >= 6)
+               seq_printf(m, "  FADDR: 0x%08x\n", error->faddr[ring]);
        seq_printf(m, "  seqno: 0x%08x\n", error->seqno[ring]);
 }
 
index 766ef1c10ce59d54d46a227c473945fc6d05d0d6..733f5f57babfab219d4a3bfff2ab5975155917ad 100644 (file)
@@ -152,16 +152,19 @@ struct drm_i915_error_state {
        u32 eir;
        u32 pgtbl_er;
        u32 pipestat[I915_MAX_PIPES];
+       u32 tail[I915_NUM_RINGS];
+       u32 head[I915_NUM_RINGS];
        u32 ipeir[I915_NUM_RINGS];
        u32 ipehr[I915_NUM_RINGS];
        u32 instdone[I915_NUM_RINGS];
        u32 acthd[I915_NUM_RINGS];
        u32 error; /* gen6+ */
-       u32 instpm;
-       u32 instps;
+       u32 instpm[I915_NUM_RINGS];
+       u32 instps[I915_NUM_RINGS];
        u32 instdone1;
        u32 seqno[I915_NUM_RINGS];
        u64 bbaddr;
+       u32 faddr[I915_NUM_RINGS];
        u64 fence[I915_MAX_NUM_FENCES];
        struct timeval time;
        struct drm_i915_error_object {
index dffeef870b3bf6e5821bef05579856ae61ae6466..1e75c44af56a60ea807afe4f2765c2ae2877e945 100644 (file)
@@ -882,12 +882,15 @@ static void i915_record_ring_state(struct drm_device *dev,
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
+       if (INTEL_INFO(dev)->gen >= 6)
+               error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base));
+
        if (INTEL_INFO(dev)->gen >= 4) {
                error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base));
                error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base));
                error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base));
+               error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base));
                if (ring->id == RCS) {
-                       error->instps = I915_READ(INSTPS);
                        error->instdone1 = I915_READ(INSTDONE1);
                        error->bbaddr = I915_READ64(BB_ADDR);
                }
@@ -898,8 +901,11 @@ static void i915_record_ring_state(struct drm_device *dev,
                error->bbaddr = 0;
        }
 
+       error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base));
        error->seqno[ring->id] = ring->get_seqno(ring);
        error->acthd[ring->id] = intel_ring_get_active_head(ring);
+       error->head[ring->id] = I915_READ_HEAD(ring);
+       error->tail[ring->id] = I915_READ_TAIL(ring);
 }
 
 /**
@@ -939,7 +945,6 @@ static void i915_capture_error_state(struct drm_device *dev)
        error->pgtbl_er = I915_READ(PGTBL_ER);
        for_each_pipe(pipe)
                error->pipestat[pipe] = I915_READ(PIPESTAT(pipe));
-       error->instpm = I915_READ(INSTPM);
 
        if (INTEL_INFO(dev)->gen >= 6)
                error->error = I915_READ(ERROR_GEN6);
index 80febc55a0c6a422041ad19dbef2b42eb04e673c..d107a1d756a8977c7e7d53515c828280ed954fca 100644 (file)
 #define RING_IPEIR(base)       ((base)+0x64)
 #define RING_IPEHR(base)       ((base)+0x68)
 #define RING_INSTDONE(base)    ((base)+0x6c)
+#define RING_INSTPS(base)      ((base)+0x70)
+#define RING_DMA_FADD(base)    ((base)+0x78)
+#define RING_INSTPM(base)      ((base)+0xc0)
 #define INSTPS         0x02070 /* 965+ only */
 #define INSTDONE1      0x0207c /* 965+ only */
 #define ACTHD_I965     0x02074