[Intel-gfx] [PATCH] i915: dump error state when error interrupt is raised

Jesse Barnes jbarnes at virtuousgeek.org
Sat Apr 18 01:45:45 CEST 2009


On Fri, 17 Apr 2009 16:18:10 -0700
Jesse Barnes <jbarnes at virtuousgeek.org> wrote:

> On Fri, 17 Apr 2009 15:10:59 -0700
> Jesse Barnes <jbarnes at virtuousgeek.org> wrote:
> 
> > This is long overdue.  I'm still in the process of testing it
> > though, and it probably needs work on pre-965.  Would be good to
> > get it working for 945 and 8xx though, since we seem to have a lot
> > of problems with those chips these days, and it would be good to get
> > data on the hangs people see there.
> > 
> > The patch is simple, it just enables the error interrupt and unmasks
> > all error types, then dumps info from the interrupt handler if an
> > error is detected.
> > 
> > My s-o-b is here in the unlikely event that the patch is ok on 8xx
> > and 9xx.
> > 
> > Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
> 
> Here's an updated version (actually tested too; seems to spit out
> error messages alright).
> 
> I'm not sure how much sense the output makes yet:
> 
> render error detected, EIR: 0x00000001
> instruction error: 0x00000001
> IPHR: 0x01000000
> INSTDONE: 0xffe5fafe
> INSTDONE1: 0x000fffff
> 
> In this case, instruction error has a "reserved" ring number.  Not
> sure about the IPHR though, and INSTDONE does indicate that some
> parts of the chip aren't "done" yet.

Yet another one (still testing this one).  Fixed the offset of IPEIR
and added a few more regs.

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 98bb4c8..336b584 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -41,8 +41,9 @@
  * we leave them always unmasked in IMR and then control enabling them through
  * PIPESTAT alone.
  */
-#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
-				   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |  \
+#define I915_INTERRUPT_ENABLE_FIX (I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT |\
+				   I915_ASLE_INTERRUPT |		\
+				   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
 				   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
 
 /** Interrupts that we mask and unmask at runtime. */
@@ -267,6 +268,37 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 			I915_READ(PORT_HOTPLUG_STAT);
 		}
 
+		if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) {
+			u32 eir = I915_READ(EIR);
+			printk(KERN_ERR "render error detected, EIR: 0x%08x\n",
+			       eir);
+			I915_WRITE(EIR, eir);
+			(void)I915_READ(EIR);
+			if (eir & I915_ERROR_PAGE_TABLE) {
+				printk(KERN_ERR "page table error\n");
+				printk(KERN_ERR "  PGTBL_ER: 0x%08x\n",
+				       I915_READ(PGTBL_ER));
+			}
+			if (eir & I915_ERROR_MEMORY_REFRESH) {
+				printk(KERN_ERR "memory refresh error\n");
+			}
+			if (eir & I915_ERROR_INSTRUCTION) {
+				printk(KERN_ERR "instruction error\n");
+				printk(KERN_ERR "  IPEIR: 0x%08x\n",
+				       I915_READ(IPEIR));
+				printk(KERN_ERR "  IPEHR: 0x%08x\n",
+				       I915_READ(IPEHR));
+				printk(KERN_ERR "  INSTDONE: 0x%08x\n",
+				       I915_READ(INSTDONE));
+				printk(KERN_ERR "  INSTPS: 0x%08x\n",
+				       I915_READ(INSTPS));
+				printk(KERN_ERR "  INSTDONE1: 0x%08x\n",
+				       I915_READ(INSTDONE1));
+				printk(KERN_ERR "  ACTHD: 0x%08x\n",
+				       I915_READ(ACTHD_I965));
+			}
+		}
+
 		I915_WRITE(IIR, iir);
 		new_iir = I915_READ(IIR); /* Flush posted writes */
 
@@ -569,6 +601,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
+	u32 error_mask;
 
 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
@@ -602,6 +635,13 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
 		i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT);
 	}
 
+	/* Enable some error detection */
+	error_mask = ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH |
+		       I915_ERROR_INSTRUCTION);
+	I915_WRITE(EMR, error_mask);
+	enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
+	i915_enable_irq(dev_priv, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
+
 	/* Disable pipe interrupt enables, clear pending pipe status */
 	I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
 	I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5211947..42a3f2c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -205,6 +205,7 @@
 /*
  * Instruction and interrupt control regs
  */
+#define PGTBL_ER	0x02024
 #define PRB0_TAIL	0x02030
 #define PRB0_HEAD	0x02034
 #define PRB0_START	0x02038
@@ -225,11 +226,15 @@
 #define PRB1_HEAD	0x02044 /* 915+ only */
 #define PRB1_START	0x02048 /* 915+ only */
 #define PRB1_CTL	0x0204c /* 915+ only */
+#define IPEIR		0x02064
+#define IPEHR		0x02068
+#define INSTDONE	0x0206c
+#define INSTPS		0x02070
+#define INSTDONE1	0x0207c
 #define ACTHD_I965	0x02074
 #define HWS_PGA		0x02080
 #define HWS_ADDRESS_MASK	0xfffff000
 #define HWS_START_ADDRESS_SHIFT	4
-#define IPEIR		0x02088
 #define NOPID		0x02094
 #define HWSTAM		0x02098
 #define SCPD0		0x0209c /* 915+ only */
@@ -257,6 +262,9 @@
 #define EIR		0x020b0
 #define EMR		0x020b4
 #define ESR		0x020b8
+#define   I915_ERROR_PAGE_TABLE				(1<<4)
+#define   I915_ERROR_MEMORY_REFRESH			(1<<1)
+#define   I915_ERROR_INSTRUCTION			(1<<0)
 #define INSTPM	        0x020c0
 #define ACTHD	        0x020c8
 #define FW_BLC		0x020d8



More information about the Intel-gfx mailing list