[PATCH v2 7/9] drm/i915/gmbus: Unmask GPIO pins for SCDC communication

Ankit Nautiyal ankit.k.nautiyal at intel.com
Mon Mar 7 09:03:17 UTC 2022


To enable SCDC communication, GPIO pin pair for the given port must be
reset. Hardware masks off SCDC when the pin pair is selected.

Set GMBUS0 Pin Pair Select to:
-Disabled or,
-Pin pair other than the one for this port.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
 drivers/gpu/drm/i915/display/intel_gmbus.c | 50 ++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_gmbus.h |  1 +
 drivers/gpu/drm/i915/display/intel_hdmi.c  |  1 +
 drivers/gpu/drm/i915/i915_reg.h            |  1 +
 4 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c
index 3f375d9906d0..3f1a375e7005 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -1030,3 +1030,53 @@ void intel_gmbus_set_scdc_port(struct i2c_adapter *adapter, enum scdc_pin port)
 
 	mutex_unlock(&dev_priv->gmbus_mutex);
 }
+
+void intel_gmbus_unmask_scdc_pins(struct i2c_adapter *adapter)
+{
+	struct intel_gmbus *bus = to_intel_gmbus(adapter);
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+	u32 val;
+	int pin_pair;
+
+	if (bus->scdc_port == SCDC_PORT_NONE)
+		return;
+
+	switch (bus->scdc_port) {
+	case SCDC_PORT_A :
+		pin_pair = GMBUS_PIN_1_BXT;
+		break;
+	case SCDC_PORT_B :
+		pin_pair = GMBUS_PIN_2_BXT;
+		break;
+	case SCDC_PORT_C :
+		pin_pair = GMBUS_PIN_3_BXT;
+		break;
+	case SCDC_PORT_TC1 :
+		pin_pair = GMBUS_PIN_9_TC1_ICP;
+		break;
+	case SCDC_PORT_TC2 :
+		pin_pair = GMBUS_PIN_10_TC2_ICP;
+		break;
+	case SCDC_PORT_TC3 :
+		pin_pair = GMBUS_PIN_11_TC3_ICP;
+		break;
+	case SCDC_PORT_TC4 :
+		pin_pair = GMBUS_PIN_12_TC4_ICP;
+		break;
+	case SCDC_PORT_TC5 :
+		pin_pair = GMBUS_PIN_13_TC5_TGP;
+		break;
+	case SCDC_PORT_TC6 :
+		pin_pair = GMBUS_PIN_14_TC6_TGP;
+		break;
+	default:
+		return;
+	}
+
+	val = intel_de_read_fw(dev_priv, GMBUS0);
+	if ((val & GMBUS_PIN_PAIR_SELECT_MASK) != pin_pair)
+		return;
+
+	val &= ~GMBUS_PIN_PAIR_SELECT_MASK;
+	intel_de_write_fw(dev_priv, GMBUS0, val);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.h b/drivers/gpu/drm/i915/display/intel_gmbus.h
index 40744c84ac7c..ff22d6dabe31 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.h
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.h
@@ -46,5 +46,6 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
 bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter);
 void intel_gmbus_reset(struct drm_i915_private *dev_priv);
 void intel_gmbus_set_scdc_port(struct i2c_adapter *adapter, enum scdc_pin port);
+void intel_gmbus_unmask_scdc_pins(struct i2c_adapter *adapter);
 
 #endif /* __INTEL_GMBUS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 5f73c8bff5c0..89ed0e6a2f91 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2426,6 +2426,7 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 		enum scdc_pin scdc = intel_hdmi_get_scdc_pin(encoder);
 
 		intel_gmbus_set_scdc_port(i2c, scdc);
+		intel_gmbus_unmask_scdc_pins(i2c);
 	}
 
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7c96efbdd629..0888642e6952 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1473,6 +1473,7 @@
 #define   GMBUS_RATE_1MHZ	(3 << 8) /* reserved on Pineview */
 #define   GMBUS_HOLD_EXT	(1 << 7) /* 300ns hold time, rsvd on Pineview */
 #define   GMBUS_BYTE_CNT_OVERRIDE (1 << 6)
+#define   GMBUS_PIN_PAIR_SELECT_MASK	0x1F
 
 #define GMBUS1			_MMIO(dev_priv->gpio_mmio_base + 0x5104) /* command/status */
 #define   GMBUS_SW_CLR_INT	(1 << 31)
-- 
2.25.1



More information about the Intel-gfx-trybot mailing list