[Intel-gfx] [RFC 11/13] drm/i915: Added watchdog interrupt handling

Lister, Ian ian.lister at intel.com
Mon Dec 16 17:03:34 CET 2013


From 65c61c6e71f8d01840eef1e373e91bf8849b978d Mon Sep 17 00:00:00 2001
Message-Id: <65c61c6e71f8d01840eef1e373e91bf8849b978d.1387201899.git.ian.lister at intel.com>
In-Reply-To: <cover.1387201899.git.ian.lister at intel.com>
References: <cover.1387201899.git.ian.lister at intel.com>
From: ian-lister <ian.lister at intel.com>
Date: Tue, 10 Dec 2013 17:08:47 +0000
Subject: [RFC 11/13] drm/i915: Added watchdog interrupt handling

Added watchdog interrupt handling to snb_gt_irq_handler.
The watchdog interrupts have been permanently enabled.

Signed-off-by: ian-lister <ian.lister at intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c         | 28 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_reg.h         |  7 +++++++
 drivers/gpu/drm/i915/intel_ringbuffer.h |  1 +
 3 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index f550b1e..c26c3db 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1309,6 +1309,7 @@ static void snb_gt_irq_handler(struct drm_device *dev,
 			       struct drm_i915_private *dev_priv,
 			       u32 gt_iir)
 {
+	struct intel_ring_buffer *ring;
 
 	if (gt_iir &
 	    (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT))
@@ -1325,6 +1326,26 @@ static void snb_gt_irq_handler(struct drm_device *dev,
 		i915_handle_error(dev, 0);
 	}
 
+	if (gt_iir & GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED) {
+		DRM_DEBUG_TDR("Render timeout counter exceeded\n");
+
+		/* Stop the counter to prevent further interrupts */
+		ring = &dev_priv->ring[RCS];
+		I915_WRITE(RING_CNTR(ring->mmio_base), RCS_WATCHDOG_DISABLE);
+		ring->hangcheck.watchdog_count++;
+		i915_handle_error(dev, 0x1 << ring->id);
+	}
+		
+	if (gt_iir & GEN6_BSD_TIMEOUT_COUNTER_EXPIRED) {
+		DRM_DEBUG_TDR("Video timeout counter exceeded\n");
+
+		/* Stop the counter to prevent further interrupts */
+		ring = &dev_priv->ring[VCS];
+		I915_WRITE(RING_CNTR(ring->mmio_base), VCS_WATCHDOG_DISABLE);
+		ring->hangcheck.watchdog_count++;
+		i915_handle_error(dev, 0x1 << ring->id);
+	}
+
 	if (gt_iir & GT_PARITY_ERROR(dev))
 		ivybridge_parity_error_irq_handler(dev, gt_iir);
 }
@@ -3293,6 +3314,13 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
 		gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT;
 	}
 
+	/* Enable watchdog interrupts by default */
+	dev_priv->gt_irq_mask &= ~(GT_GEN6_BSD_WATCHDOG_INTERRUPT |
+		GT_GEN6_RENDER_WATCHDOG_INTERRUPT);
+
+	gt_irqs |= (GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED |
+		GEN6_BSD_TIMEOUT_COUNTER_EXPIRED);
+
 	I915_WRITE(GTIIR, I915_READ(GTIIR));
 	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 	I915_WRITE(GTIER, gt_irqs);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a0bbf82..b86b5dc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -910,6 +910,7 @@
 #define IER		0x020a0
 #define IIR		0x020a4
 #define IMR		0x020a8
+#define GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED (1 << 6)
 #define ISR		0x020ac
 #define VLV_GUNIT_CLOCK_GATE	(VLV_DISPLAY_BASE + 0x2060)
 #define   GCFG_DIS		(1<<8)
@@ -1061,8 +1062,10 @@
 #define GT_BLT_FLUSHDW_NOTIFY_INTERRUPT		(1 << 26)
 #define GT_BLT_CS_ERROR_INTERRUPT		(1 << 25)
 #define GT_BLT_USER_INTERRUPT			(1 << 22)
+#define GT_GEN6_BSD_WATCHDOG_INTERRUPT		(1 << 18)
 #define GT_BSD_CS_ERROR_INTERRUPT		(1 << 15)
 #define GT_BSD_USER_INTERRUPT			(1 << 12)
+#define GT_GEN6_RENDER_WATCHDOG_INTERRUPT	(1 << 6)
 #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1	(1 << 11) /* hsw+; rsvd on snb, ivb, vlv */
 #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT	(1 <<  5) /* !snb */
 #define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT	(1 <<  4)
@@ -1118,6 +1121,10 @@
 #define I915_ASLE_INTERRUPT				(1<<0)
 #define I915_BSD_USER_INTERRUPT				(1<<25)
 
+#define GEN6_BSD_IMR			0x120a8
+#define  GEN6_BSD_USER_INTERRUPT	(1 << 12)
+#define  GEN6_BSD_TIMEOUT_COUNTER_EXPIRED (1 << 18)
+
 #define GEN6_BSD_RNCID			0x12198
 
 #define GEN7_FF_THREAD_MODE		0x20a0
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 91c10b7..473cb94 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -73,6 +73,7 @@ struct intel_ring_hangcheck {
 	u32 last_head; /* Head value recorded at last hang */
 	u32 status_updated;
 	u32 watchdog_threshold;
+	u32 watchdog_count; /* Total watchdog resets for this ring */
 };
 
 struct  intel_ring_buffer {
-- 
1.8.5.1




More information about the Intel-gfx mailing list