[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