[Intel-gfx] [PATCH 2/2] drm/i915: Try GPIO NAK discovery before GMBUS

Chris Wilson chris at chris-wilson.co.uk
Fri Aug 19 16:45:03 UTC 2016


Some GMBUS devices fail to report NAKs (even recent Skylakes), resulting
in us hitting the 50ms timeout every time we try to read an EDID on a
disconnected device. Try a quick GPIO discovery first by setting the
clock line and seeing if the device responds.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: David Weinehall <david.weinehall at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 6841c41281a3..72945a7c5547 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -461,6 +461,22 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
 	return ret;
 }
 
+static bool gpio_is_alive(struct intel_gmbus *bus)
+{
+	bool result = true;
+
+	intel_i2c_quirk_set(bus->dev_priv, true);
+	set_clock(bus, 1);
+
+	if (wait_for_us(get_clock(bus), 10) && wait_for(get_clock(bus), 2))
+		result = false;
+
+	set_clock(bus, 0);
+	intel_i2c_quirk_set(bus->dev_priv, false);
+
+	return result;
+}
+
 static int
 do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 {
@@ -474,6 +490,13 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 	int i = 0, inc, try = 0;
 	int ret = 0;
 
+	/* Some GMBUS devices fail to report NAKs and so we hit the 50ms
+	 * timeout, every time. Try a quick GPIO discovery first by seeing
+	 * if the device responds to setting the clock line high.
+	 */
+	if (!gpio_is_alive(bus))
+		return -ENXIO;
+
 	intel_uncore_forcewake_get(dev_priv, fw);
 retry:
 	I915_WRITE_FW(GMBUS0, bus->reg0);
-- 
2.9.3



More information about the Intel-gfx mailing list