Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 776ad806 authored by Jesse Barnes's avatar Jesse Barnes Committed by Chris Wilson
Browse files

drm/i915: detect & report PCH display error interrupts



FDI and the transcoders can fail for various reasons, so detect those
conditions and report on them.

Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent d5bb081b
Loading
Loading
Loading
Loading
+52 −2
Original line number Diff line number Diff line
@@ -398,6 +398,50 @@ static void gen6_pm_irq_handler(struct drm_device *dev)
	I915_WRITE(GEN6_PMIIR, pm_iir);
}

static void pch_irq_handler(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	u32 pch_iir;

	pch_iir = I915_READ(SDEIIR);

	if (pch_iir & SDE_AUDIO_POWER_MASK)
		DRM_DEBUG_DRIVER("PCH audio power change on port %d\n",
				 (pch_iir & SDE_AUDIO_POWER_MASK) >>
				 SDE_AUDIO_POWER_SHIFT);

	if (pch_iir & SDE_GMBUS)
		DRM_DEBUG_DRIVER("PCH GMBUS interrupt\n");

	if (pch_iir & SDE_AUDIO_HDCP_MASK)
		DRM_DEBUG_DRIVER("PCH HDCP audio interrupt\n");

	if (pch_iir & SDE_AUDIO_TRANS_MASK)
		DRM_DEBUG_DRIVER("PCH transcoder audio interrupt\n");

	if (pch_iir & SDE_POISON)
		DRM_ERROR("PCH poison interrupt\n");

	if (pch_iir & SDE_FDI_MASK) {
		u32 fdia, fdib;

		fdia = I915_READ(FDI_RXA_IIR);
		fdib = I915_READ(FDI_RXB_IIR);
		DRM_DEBUG_DRIVER("PCH FDI RX interrupt; FDI RXA IIR: 0x%08x, FDI RXB IIR: 0x%08x\n", fdia, fdib);
	}

	if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE))
		DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n");

	if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR))
		DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n");

	if (pch_iir & SDE_TRANSB_FIFO_UNDER)
		DRM_DEBUG_DRIVER("PCH transcoder B underrun interrupt\n");
	if (pch_iir & SDE_TRANSA_FIFO_UNDER)
		DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
}

static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -465,8 +509,11 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
		drm_handle_vblank(dev, 1);

	/* check event from PCH */
	if ((de_iir & DE_PCH_EVENT) && (pch_iir & hotplug_mask))
	if (de_iir & DE_PCH_EVENT) {
		if (pch_iir & hotplug_mask)
			queue_work(dev_priv->wq, &dev_priv->hotplug_work);
		pch_irq_handler(dev);
	}

	if (de_iir & DE_PCU_EVENT) {
		I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS));
@@ -1656,6 +1703,9 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
	} else {
		hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
			       SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
		hotplug_mask |= SDE_AUX_MASK | SDE_FDI_MASK | SDE_TRANS_MASK;
		I915_WRITE(FDI_RXA_IMR, 0);
		I915_WRITE(FDI_RXB_IMR, 0);
	}

	dev_priv->pch_irq_mask = ~hotplug_mask;
+29 −0
Original line number Diff line number Diff line
@@ -2778,12 +2778,41 @@
/* PCH */

/* south display engine interrupt */
#define SDE_AUDIO_POWER_D	(1 << 27)
#define SDE_AUDIO_POWER_C	(1 << 26)
#define SDE_AUDIO_POWER_B	(1 << 25)
#define SDE_AUDIO_POWER_SHIFT	(25)
#define SDE_AUDIO_POWER_MASK	(7 << SDE_AUDIO_POWER_SHIFT)
#define SDE_GMBUS		(1 << 24)
#define SDE_AUDIO_HDCP_TRANSB	(1 << 23)
#define SDE_AUDIO_HDCP_TRANSA	(1 << 22)
#define SDE_AUDIO_HDCP_MASK	(3 << 22)
#define SDE_AUDIO_TRANSB	(1 << 21)
#define SDE_AUDIO_TRANSA	(1 << 20)
#define SDE_AUDIO_TRANS_MASK	(3 << 20)
#define SDE_POISON		(1 << 19)
/* 18 reserved */
#define SDE_FDI_RXB		(1 << 17)
#define SDE_FDI_RXA		(1 << 16)
#define SDE_FDI_MASK		(3 << 16)
#define SDE_AUXD		(1 << 15)
#define SDE_AUXC		(1 << 14)
#define SDE_AUXB		(1 << 13)
#define SDE_AUX_MASK		(7 << 13)
/* 12 reserved */
#define SDE_CRT_HOTPLUG         (1 << 11)
#define SDE_PORTD_HOTPLUG       (1 << 10)
#define SDE_PORTC_HOTPLUG       (1 << 9)
#define SDE_PORTB_HOTPLUG       (1 << 8)
#define SDE_SDVOB_HOTPLUG       (1 << 6)
#define SDE_HOTPLUG_MASK	(0xf << 8)
#define SDE_TRANSB_CRC_DONE	(1 << 5)
#define SDE_TRANSB_CRC_ERR	(1 << 4)
#define SDE_TRANSB_FIFO_UNDER	(1 << 3)
#define SDE_TRANSA_CRC_DONE	(1 << 2)
#define SDE_TRANSA_CRC_ERR	(1 << 1)
#define SDE_TRANSA_FIFO_UNDER	(1 << 0)
#define SDE_TRANS_MASK		(0x3f)
/* CPT */
#define SDE_CRT_HOTPLUG_CPT	(1 << 19)
#define SDE_PORTD_HOTPLUG_CPT	(1 << 23)