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

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


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.

-- 
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 ee7ce7b..07875a2 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,31 @@ 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, 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: 0x%08x\n",
+					  I915_READ(IPEIR));
+				printk(KERN_ERR "IPHR: 0x%08x\n",
+				       I915_READ(IPEHR));
+				printk(KERN_ERR "INSTDONE: 0x%08x\n",
+					  I915_READ(INSTDONE));
+				printk(KERN_ERR "INSTDONE1: 0x%08x\n",
+					  I915_READ(INSTDONE1));
+			}
+		}
+
 		I915_WRITE(IIR, iir);
 		new_iir = I915_READ(IIR); /* Flush posted writes */
 
@@ -569,6 +595,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 +629,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..5588997 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,10 +226,13 @@
 #define PRB1_HEAD	0x02044 /* 915+ only */
 #define PRB1_START	0x02048 /* 915+ only */
 #define PRB1_CTL	0x0204c /* 915+ only */
+#define INSTDONE	0x0206c
+#define INSTDONE1	0x0207c
 #define ACTHD_I965	0x02074
 #define HWS_PGA		0x02080
 #define HWS_ADDRESS_MASK	0xfffff000
 #define HWS_START_ADDRESS_SHIFT	4
+#define IPEHR		0x02068
 #define IPEIR		0x02088
 #define NOPID		0x02094
 #define HWSTAM		0x02098
@@ -257,6 +261,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