[Intel-gfx] [PATCH 09/10] drm/i915: print IVB/HSW display error interrupts
Jani Nikula
jani.nikula at linux.intel.com
Thu Jan 24 14:06:45 CET 2013
On Fri, 18 Jan 2013, Ben Widawsky <ben at bwidawsk.net> wrote:
> On Fri, Jan 18, 2013 at 06:29:11PM -0200, Paulo Zanoni wrote:
>> From: Paulo Zanoni <paulo.r.zanoni at intel.com>
>>
>> If we get one of these messages it means we did something wrong, and
>> the first step to fix wrong things is to detect them and recognize
>> they exist.
>>
>> For now, leave these messages as DRM_DEBUG_KMS. After we conclude that
>> a certain message should not be print since our code is correct, then
>> we can promote that specific message to DRM_ERROR.
>>
>> Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
>
> A couple of recommendations below, but either way it is
> Reviewed-by: Ben Widawsky <ben at bwidawsk.net>
>
>> ---
>> drivers/gpu/drm/i915/i915_irq.c | 56 ++++++++++++++++++++++++++++++++++++++-
>> drivers/gpu/drm/i915/i915_reg.h | 23 ++++++++++++++--
>> 2 files changed, 76 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
>> index cc49a6d..2f17b54 100644
>> --- a/drivers/gpu/drm/i915/i915_irq.c
>> +++ b/drivers/gpu/drm/i915/i915_irq.c
>> @@ -697,6 +697,54 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
>> I915_READ(FDI_RX_IIR(pipe)));
>> }
>>
>> +static void ivb_err_int_handler(struct drm_device *dev)
>> +{
>> + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>> + u32 err_int = I915_READ(GEN7_ERR_INT);
>> +
>> + if (err_int & ERR_INT_POISON)
>> + DRM_DEBUG_KMS("Poison interrupt\n");
>> + if (err_int & ERR_INT_INVALID_GTT_PTE)
>> + DRM_DEBUG_KMS("Invalid GTT PTE\n");
>> + if (err_int & ERR_INT_INVALID_PTE_DATA)
>> + DRM_DEBUG_KMS("Invalid GTT PTE data\n");
>> + if (err_int & ERR_INT_SPRITE_GTT_FAULT_C)
>> + DRM_DEBUG_KMS("Sprite C GTT fault\n");
>> + if (err_int & ERR_INT_PRIMARY_GTT_FAULT_C)
>> + DRM_DEBUG_KMS("Primary place C GTT fault\n");
>> + if (err_int & ERR_INT_CURSOR_GTT_FAULT_C)
>> + DRM_DEBUG_KMS("Cursor C GTT fault\n");
>> + if (err_int & ERR_INT_SPRITE_GTT_FAULT_B)
>> + DRM_DEBUG_KMS("Sprite B GTT fault\n");
>> + if (err_int & ERR_INT_PRIMARY_GTT_FAULT_B)
>> + DRM_DEBUG_KMS("Primary place B GTT fault\n");
>> + if (err_int & ERR_INT_CURSOR_GTT_FAULT_B)
>> + DRM_DEBUG_KMS("Cursor B GTT fault\n");
>> + if (err_int & ERR_INT_SPRITE_GTT_FAULT_A)
>> + DRM_DEBUG_KMS("Sprite A GTT fault\n");
>> + if (err_int & ERR_INT_PRIMARY_GTT_FAULT_A)
>> + DRM_DEBUG_KMS("Primary place A GTT fault\n");
>> + if (err_int & ERR_INT_CURSOR_GTT_FAULT_A)
>> + DRM_DEBUG_KMS("Cursor A GTT fault\n");
>> + if (err_int & ERR_INT_PIPE_CRR_ERROR_C)
>> + DRM_DEBUG_KMS("Pipe C CRC error\n");
>> + if (err_int & ERR_INT_PIPE_FIFO_UNDERRRUN_C)
>> + DRM_DEBUG_KMS("Pipe C FIFO underrun\n");
>> + if (err_int & ERR_INT_PIPE_CRR_ERROR_B)
>> + DRM_DEBUG_KMS("Pipe B CRC error\n");
>> + if (err_int & ERR_INT_PIPE_FIFO_UNDERRRUN_B)
>> + DRM_DEBUG_KMS("Pipe B FIFO underrun\n");
>> + if (err_int & ERR_INT_PIPE_CRR_ERROR_A)
>> + DRM_DEBUG_KMS("Pipe A CRC error\n");
>> + if (err_int & ERR_INT_PIPE_FIFO_UNDERRRUN_A)
>> + DRM_DEBUG_KMS("Pipe A FIFO underrun\n");
>> +
>> + if (IS_HASWELL(dev) && (err_int & ERR_INT_MMIO_UNCLAIMED))
>> + DRM_DEBUG_KMS("MMIO cycle not claimed\n");
>> +
>> + I915_WRITE(GEN7_ERR_INT, err_int);
>> +}
>> +
>
> We probably don't need the IS_HASWELL() check, but it shouldn't hurt
> either.
>
> I shutter to think of debugging what will happen if this handler itself
> generates ERR_INT_MMIO_UNCLAIMED. Hopefully the DRM_DEBUG_KMS will get a
> chance to get spewed out.
>
> Since the only thing you're doing is printing, you could do something
> like:
> u32 err_int = I915_READ(GEN7_ERR_INT);
> if (drm_debug & DRM_UT_KMS == 0) {
Review-of-review, that needs braces or it's always false.
BR,
Jani.
> I915_WRITE(GEN7_ERR_INT, err_int);
> return;
> }
>
>> static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
>> {
>> struct drm_device *dev = (struct drm_device *) arg;
>> @@ -720,6 +768,9 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
>>
>> de_iir = I915_READ(DEIIR);
>> if (de_iir) {
>> + if (de_iir & DE_ERR_INT_IVB)
>> + ivb_err_int_handler(dev);
>> +
>> if (de_iir & DE_AUX_CHANNEL_A_IVB)
>> dp_aux_irq_handler(dev);
>>
>> @@ -1964,7 +2015,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
>> DE_PLANEC_FLIP_DONE_IVB |
>> DE_PLANEB_FLIP_DONE_IVB |
>> DE_PLANEA_FLIP_DONE_IVB |
>> - DE_AUX_CHANNEL_A_IVB;
>> + DE_AUX_CHANNEL_A_IVB | DE_ERR_INT_IVB;
>> u32 render_irqs;
>> u32 hotplug_mask;
>> u32 pch_irq_mask;
>> @@ -1972,6 +2023,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
>> dev_priv->irq_mask = ~display_mask;
>>
>> /* should always can generate irq */
>> + I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
>> I915_WRITE(DEIIR, I915_READ(DEIIR));
>> I915_WRITE(DEIMR, dev_priv->irq_mask);
>> I915_WRITE(DEIER,
>> @@ -2135,6 +2187,8 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
>> I915_WRITE(DEIMR, 0xffffffff);
>> I915_WRITE(DEIER, 0x0);
>> I915_WRITE(DEIIR, I915_READ(DEIIR));
>> + if (IS_GEN7(dev))
>> + I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
>>
>> I915_WRITE(GTIMR, 0xffffffff);
>> I915_WRITE(GTIER, 0x0);
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index f054554..e8ecdc4 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -511,7 +511,26 @@
>>
>> #define ERROR_GEN6 0x040a0
>> #define GEN7_ERR_INT 0x44040
>> -#define ERR_INT_MMIO_UNCLAIMED (1<<13)
>> +#define ERR_INT_POISON (1<<31)
>> +#define ERR_INT_INVALID_GTT_PTE (1<<29)
>> +#define ERR_INT_INVALID_PTE_DATA (1<<28)
>> +#define ERR_INT_SPRITE_GTT_FAULT_C (1<<23)
>> +#define ERR_INT_PRIMARY_GTT_FAULT_C (1<<22)
>> +#define ERR_INT_CURSOR_GTT_FAULT_C (1<<21)
>> +#define ERR_INT_SPRITE_GTT_FAULT_B (1<<20)
>> +#define ERR_INT_PRIMARY_GTT_FAULT_B (1<<19)
>> +#define ERR_INT_CURSOR_GTT_FAULT_B (1<<18)
>> +#define ERR_INT_SPRITE_GTT_FAULT_A (1<<17)
>> +#define ERR_INT_PRIMARY_GTT_FAULT_A (1<<16)
>> +#define ERR_INT_CURSOR_GTT_FAULT_A (1<<15)
>> +#define ERR_INT_PIPE_CRR_ERROR_C (1<<7)
>> +#define ERR_INT_PIPE_FIFO_UNDERRRUN_C (1<<6)
>> +#define ERR_INT_PIPE_CRR_ERROR_B (1<<4)
>> +#define ERR_INT_PIPE_FIFO_UNDERRRUN_B (1<<3)
>> +#define ERR_INT_PIPE_CRR_ERROR_A (1<<1)
>> +#define ERR_INT_PIPE_FIFO_UNDERRRUN_A (1<<0)
>> +/* Haswell only: */
>> +#define ERR_INT_MMIO_UNCLAIMED (1<<13)
>>
>> /* GM45+ chicken bits -- debug workaround bits that may be required
>> * for various sorts of correct behavior. The top 16 bits of each are
>> @@ -3374,7 +3393,7 @@
>> #define DE_PIPEA_FIFO_UNDERRUN (1 << 0)
>>
>> /* More Ivybridge lolz */
>> -#define DE_ERR_DEBUG_IVB (1<<30)
>> +#define DE_ERR_INT_IVB (1<<30)
>> #define DE_GSE_IVB (1<<29)
>> #define DE_PCH_EVENT_IVB (1<<28)
>> #define DE_DP_A_HOTPLUG_IVB (1<<27)
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Ben Widawsky, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list