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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ben Widawsky <ben@xxxxxxxxxxxx>

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@xxxxxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Reported-by: Mark Janes <mark.a.janes@xxxxxxxxx>
Signed-off-by: Ben Widawsky <ben@xxxxxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]