[PATCH 6/9] drm/i915/gmbus: Set SCDC_RR interrupt during GPIO xfers

Ankit Nautiyal ankit.k.nautiyal at intel.com
Mon Mar 7 05:39:02 UTC 2022


Disable/Enable SCDC_RR pre and post GPIO xfer.

This patch:
-Adds new field in intel_gmbus structure to store SCDC port
-Initializes the new field, based on if SCDC_RR is supported.
-Sets the SCDC_RR pre/post GPIO xfers for the SCDC port.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
 drivers/gpu/drm/i915/display/intel_gmbus.c | 39 ++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_gmbus.h |  2 ++
 drivers/gpu/drm/i915/display/intel_hdmi.c  | 11 ++++++
 drivers/gpu/drm/i915/i915_drv.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 2fad03250661..4fc3f6c7e058 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -38,6 +38,8 @@
 #include "intel_display_types.h"
 #include "intel_gmbus.h"
 
+enum scdc_pin;
+
 struct gmbus_pin {
 	const char *name;
 	enum i915_gpio gpio;
@@ -291,6 +293,27 @@ static void set_data(void *data, int state_high)
 	intel_uncore_posting_read(uncore, bus->gpio_reg);
 }
 
+static void
+set_scdc(struct drm_i915_private *dev_priv, enum scdc_pin pin, bool enable)
+{
+	u32 scdc_bit;
+
+	if (pin == SCDC_PORT_NONE)
+		return;
+
+	if (DISPLAY_VER(dev_priv) < 11)
+		return;
+
+	scdc_bit = dev_priv->scdc_rr.scdc[pin];
+
+	spin_lock_irq(&dev_priv->irq_lock);
+	if (enable)
+		ibx_disable_display_interrupt(dev_priv, scdc_bit);
+	else
+		ibx_disable_display_interrupt(dev_priv, scdc_bit);
+	spin_unlock_irq(&dev_priv->irq_lock);
+}
+
 static int
 intel_gpio_pre_xfer(struct i2c_adapter *adapter)
 {
@@ -301,6 +324,8 @@ intel_gpio_pre_xfer(struct i2c_adapter *adapter)
 
 	intel_gmbus_reset(dev_priv);
 
+	set_scdc(dev_priv, bus->scdc_port, false);
+
 	if (IS_PINEVIEW(dev_priv))
 		pnv_gmbus_clock_gating(dev_priv, false);
 
@@ -321,6 +346,8 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter)
 	set_data(bus, 1);
 	set_clock(bus, 1);
 
+	set_scdc(dev_priv, bus->scdc_port, true);
+
 	if (IS_PINEVIEW(dev_priv))
 		pnv_gmbus_clock_gating(dev_priv, true);
 }
@@ -979,3 +1006,15 @@ void intel_gmbus_teardown(struct drm_i915_private *dev_priv)
 		i2c_del_adapter(&bus->adapter);
 	}
 }
+
+void intel_gmbus_set_scdc_port(struct i2c_adapter *adapter, enum scdc_pin port)
+{
+	struct intel_gmbus *bus = to_intel_gmbus(adapter);
+	struct drm_i915_private *dev_priv = bus->dev_priv;
+
+	mutex_lock(&dev_priv->gmbus_mutex);
+
+	bus->scdc_port = port;
+
+	mutex_unlock(&dev_priv->gmbus_mutex);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.h b/drivers/gpu/drm/i915/display/intel_gmbus.h
index 8edc2e99cf53..40744c84ac7c 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.h
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.h
@@ -10,6 +10,7 @@
 
 struct drm_i915_private;
 struct i2c_adapter;
+enum scdc_pin;
 
 #define GMBUS_PIN_DISABLED	0
 #define GMBUS_PIN_SSC		1
@@ -44,5 +45,6 @@ intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin);
 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);
 
 #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 bbbc2b63aa62..5524ac98da3d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2322,6 +2322,9 @@ static void
 intel_hdmi_unset_edid(struct drm_connector *connector)
 {
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct i2c_adapter *adapter =
+		intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
 
 	intel_hdmi->has_hdmi_sink = false;
 	intel_hdmi->has_audio = false;
@@ -2331,6 +2334,7 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 
 	kfree(to_intel_connector(connector)->detect_edid);
 	to_intel_connector(connector)->detect_edid = NULL;
+	intel_gmbus_set_scdc_port(adapter, SCDC_NUM_PINS);
 }
 
 static void
@@ -2416,6 +2420,13 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 
 	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
 
+	if (connector->display_info.hdmi.scdc.read_request) {
+		struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
+		enum scdc_pin scdc = intel_hdmi_get_scdc_pin(encoder);
+
+		intel_gmbus_set_scdc_port(i2c, scdc);
+	}
+
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
 
 	to_intel_connector(connector)->detect_edid = edid;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9772c26fcbf6..32257fa5858e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -268,6 +268,7 @@ struct intel_gmbus {
 #define GMBUS_FORCE_BIT_RETRY (1U << 31)
 	u32 force_bit;
 	u32 reg0;
+	enum scdc_pin scdc_port;
 	i915_reg_t gpio_reg;
 	struct i2c_algo_bit_data bit_algo;
 	struct drm_i915_private *dev_priv;
-- 
2.25.1



More information about the Intel-gfx-trybot mailing list