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

Ankit Nautiyal ankit.k.nautiyal at intel.com
Mon Mar 7 05:39:03 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 4fc3f6c7e058..01751d7f8d37 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -1018,3 +1018,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 5524ac98da3d..671abf3b2e15 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2425,6 +2425,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 ab3f85a3cb0e..9e0621a6a8f5 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1469,6 +1469,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