[PATCH 10/11] drm/i915: Add helper funcs to read SCDC updates

Ankit Nautiyal ankit.k.nautiyal at intel.com
Wed Mar 9 06:47:41 UTC 2022


Add helper function to read SCDC updates, on receiving an SCDC_RR
interrupt.

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

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 966cbf63aa38..22c38d07d8b5 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2992,6 +2992,17 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
 					   &conn_info);
 	if (!intel_hdmi->cec_notifier)
 		drm_dbg_kms(&dev_priv->drm, "CEC notifier get failed\n");
+
+	if (DISPLAY_VER(dev_priv) >= 11 &&
+	    connector->display_info.hdmi.scdc.read_request) {
+		int ret;
+
+		ret = drm_scdc_writeb(ddc, SCDC_CONFIG_0, SCDC_READ_REQUEST_ENABLE);
+		if (ret < 0) {
+			drm_dbg_kms(&dev_priv->drm, "Failed to write scdc config register\n");
+			return;
+		}
+	}
 }
 
 /*
@@ -3254,3 +3265,40 @@ enum scdc_pin intel_hdmi_get_scdc_pin(struct intel_encoder *encoder)
 
 	return SCDC_PORT_NONE;
 }
+
+void intel_hdmi_handle_scdc_rr(struct drm_i915_private *dev_priv,
+			       struct intel_encoder *encoder)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct i2c_adapter *adapter =
+		intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
+	u8 update, status_flags;
+
+	update = drm_scdc_read_update_flags(adapter);
+	if (update & SCDC_STATUS_UPDATE) {
+		drm_scdc_clear_update_flags(adapter, SCDC_STATUS_UPDATE);
+		status_flags = drm_scdc_read_status_flags(adapter);
+		if (!(status_flags & SCDC_CLOCK_DETECT))
+			drm_dbg_kms(&dev_priv->drm, "SCDC Update: TMDS CLOCK LOST\n");
+		if (!(status_flags & SCDC_CH_LOCK_MASK))
+			drm_dbg_kms(&dev_priv->drm, "SCDC Update: Channels not locked. Mask=0x%x\n",
+				    status_flags & SCDC_CH_LOCK_MASK);
+		/*
+		 * #TODO send uevent to userspace for lost signal
+		 */
+	}
+
+	if (update & SCDC_CED_UPDATE) {
+		int lane, char_errs;
+
+		for (lane = 0; lane < 3; lane++) {
+			char_errs = drm_scdc_get_char_error_count(adapter, lane);
+
+			if (char_errs <= 0)
+				continue;
+
+			drm_dbg_kms(&dev_priv->drm, "Lane#%d: Char errors detected %d\n",
+				    lane, char_errs);
+		}
+	}
+}
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index 49da11b30632..8ea41395abab 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -55,5 +55,7 @@ int intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
 				  int hdmi_max_slices, int hdmi_throughput);
 int intel_hdmi_dsc_get_slice_height(int vactive);
 enum scdc_pin intel_hdmi_get_scdc_pin(struct intel_encoder *encoder);
+void intel_hdmi_handle_scdc_rr(struct drm_i915_private *dev_priv,
+			       struct intel_encoder *encoder);
 
 #endif /* __INTEL_HDMI_H__ */
-- 
2.25.1



More information about the Intel-gfx-trybot mailing list