[Intel-gfx] [PATCH] drm/i915/hsw: Implement Selective Write workaround

Ben Widawsky benjamin.widawsky at intel.com
Thu Dec 18 18:20:18 PST 2014


From: Ben Widawsky <ben at bwidawsk.net>

The docs specify this needs to be set on HSW GT1 parts. I've implemented it as
such since it should only be needed when using RC6, but it can probably go
anywhere.

This patch fixes extremely reproducible hangs on our Jenkins setup.

The interesting failure signature is:
  IPEHR: 0x780c0000 (3DSTATE_VF)
  INSTDONE_0: 0xffdfbffa (SVG + VS)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87138 (more?)
Cc: Kenneth Graunke <kenneth at whitecape.org>
Cc: stable at vger.kernel.org
Reported-by: Mark Janes <mark.a.janes at intel.com>
Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 drivers/gpu/drm/i915/i915_reg.h | 7 +++++++
 drivers/gpu/drm/i915/intel_pm.c | 9 +++++++++
 3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 921e4c5..f69984d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2282,6 +2282,8 @@ struct drm_i915_cmd_table {
 				 (INTEL_DEVID(dev) & 0xf) == 0xe))
 #define IS_BDW_GT3(dev)		(IS_BROADWELL(dev) && \
 				 (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
+#define IS_HSW_GT1(dev)		(IS_HASWELL(dev) && \
+				 (INTEL_DEVID(dev) & 0x00F0) == 0x0)
 #define IS_HSW_ULT(dev)		(IS_HASWELL(dev) && \
 				 (INTEL_DEVID(dev) & 0xFF00) == 0x0A00)
 #define IS_HSW_GT3(dev)		(IS_HASWELL(dev) && \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 40ca873..f9ff662 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1218,6 +1218,13 @@ enum punit_power_well {
 #define RING_DMA_FADD_UDW(base)	((base)+0x60) /* gen8+ */
 #define RING_INSTPM(base)	((base)+0xc0)
 #define RING_MI_MODE(base)	((base)+0x9c)
+#define RING_WAIT_FOR_RC6_EXIT(base)	((base)+0xcc)
+#define   RING_RC6_SEL_WRITE_ADDR_MASK		(0x7 << 4)
+#define   RING_RC6_SEL_WRITE_ADDR_MULTICAST	(0x0 << 4)
+#define   RING_RC6_SEL_WRITE_ADDR_UPPER_LEFT	(0x4 << 4)
+#define   RING_RC6_SEL_WRITE_ADDR_UPPER_RIGHT	(0x5 << 4)
+#define   RING_RC6_SEL_WRITE_ADDR_LOWER_LEFT	(0x6 << 4)
+#define   RING_RC6_SEL_WRITE_ADDR_LOWER_RIGHT	(0x7 << 4)
 #define INSTPS		0x02070 /* 965+ only */
 #define INSTDONE1	0x0207c /* 965+ only */
 #define ACTHD_I965	0x02074
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a3ebaa8..a27003c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4259,6 +4259,15 @@ static void gen6_enable_rps(struct drm_device *dev)
 			DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
 	}
 
+	/* HSW GT1: "This field must be always [be] programmed to “100” , this
+	 * is required to address know [sic] HW issue." */
+	if (IS_HSW_GT1(dev)) {
+		for_each_ring(ring, dev_priv, i) {
+			I915_WRITE(RING_WAIT_FOR_RC6_EXIT(ring->mmio_base),
+				   _MASKED_FIELD(RING_RC6_SEL_WRITE_ADDR_MASK,
+						 RING_RC6_SEL_WRITE_ADDR_UPPER_LEFT));
+		}
+	}
 	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
-- 
2.2.0



More information about the Intel-gfx mailing list