[PATCH 1/9] drm/drm_scdc_helper: Add SCDC helper funcs for reading SCDC_RR updates

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


Add scdc helper functions to read SCDC Update flags and SCDC Status
flags. These flags can be used to get notification about Link status
changes or character errors detected via SCDC READ Request mechanism,
if supported.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
 drivers/gpu/drm/drm_scdc_helper.c | 129 ++++++++++++++++++++++++++++++
 include/drm/drm_scdc_helper.h     |   5 ++
 2 files changed, 134 insertions(+)

diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c
index 48a382464d54..b7529b2718ab 100644
--- a/drivers/gpu/drm/drm_scdc_helper.c
+++ b/drivers/gpu/drm/drm_scdc_helper.c
@@ -247,3 +247,132 @@ bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set)
 	return true;
 }
 EXPORT_SYMBOL(drm_scdc_set_high_tmds_clock_ratio);
+
+/**
+ * drm_scdc_read_update_flags - read the SCDC update flags
+ * @adapter: I2C adapter for DDC channel
+ *
+ * Returns:
+ * 8bit SCDC update
+ */
+u8 drm_scdc_read_update_flags(struct i2c_adapter *adapter)
+{
+	u8 update = 0;
+	int ret;
+
+	ret = drm_scdc_readb(adapter, SCDC_UPDATE_0, &update);
+	if (ret < 0)
+		DRM_DEBUG_KMS("Failed to read scdc update: %d\n", ret);
+
+	return update;
+}
+EXPORT_SYMBOL(drm_scdc_read_update_flags);
+
+/**
+ * drm_scdc_clear_update_flags - Clears the given update flag bits
+ * @adapter: I2C adapter for DDC channel
+ * @status: update flag bits to be cleared
+ *
+ * Returns:
+ * 0 on success, negative error code otherwise.
+ */
+int drm_scdc_clear_update_flags(struct i2c_adapter *adapter, u8 update_flags)
+{
+	u8 buf;
+	int ret;
+
+	/* Not all flags can be cleared by source */
+	if (update_flags & ~(SCDC_STATUS_UPDATE | SCDC_CED_UPDATE)) {
+		DRM_DEBUG_KMS("SCDC Update flag/s %u cannot be cleared\n",
+			      update_flags);
+		return false;
+	}
+
+	ret = drm_scdc_readb(adapter, SCDC_UPDATE_0, &buf);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("Failed to read SCDC_UPDATE_0\n");
+		return ret;
+	}
+
+	buf = buf | update_flags;
+
+	ret = drm_scdc_writeb(adapter, SCDC_UPDATE_0, buf);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("Failed to clear SCDC Update flag/s\n");
+		return ret;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_scdc_clear_update_flags);
+
+/**
+ * drm_scdc_read_status_flags - Read the status flags from offset 0x40
+ * @adapter: I2C adapter for DDC channel
+ *
+ * Returns:
+ * 8 bit value read from the 0ffset 0x40
+ */
+u8 drm_scdc_read_status_flags(struct i2c_adapter *adapter)
+{
+	u8 update = 0;
+	int ret;
+
+	ret = drm_scdc_readb(adapter, SCDC_STATUS_FLAGS_0, &update);
+	if (ret < 0)
+		DRM_DEBUG_KMS("Failed to read scdc status flag: %d\n", ret);
+
+	return update;
+}
+EXPORT_SYMBOL(drm_scdc_read_status_flags);
+
+/**
+ * drm_scdc_get_char_error_count - get the charater error count detected by
+ * sink in 10 msec
+ * @adapter: I2C adapter for DDC channel
+ * @lane_num: lane# for which the errors are checked
+ *
+ * Returns:
+ * No. of errors detected by sink in 10 msec time period.
+ * Negative error code otherwise.
+ */
+int drm_scdc_get_char_error_count(struct i2c_adapter *adapter,
+				  u8 lane_num)
+{
+	u8 offset;
+	u8 count_l, count_h;
+	int count;
+	int ret;
+
+	if (lane_num > 2) {
+		DRM_DEBUG_KMS("Invalid Lane:%d\n", lane_num);
+		return -EINVAL;
+	}
+
+	offset = SCDC_ERR_DET_0_H + lane_num * 2;
+
+	ret = drm_scdc_readb(adapter, offset, &count_h);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("Failed to read CED for Lane%d: %d\n", lane_num,
+			      ret);
+		return ret;
+	}
+
+	if (!(count_h & SCDC_CHANNEL_VALID))
+		return 0;
+
+	offset = SCDC_ERR_DET_0_L + lane_num * 2;
+
+	ret = drm_scdc_readb(adapter, offset, &count_l);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("Failed to read CED for Lane%d: %d\n",
+				lane_num, ret);
+		return ret;
+	}
+
+	count = count_h & ~SCDC_CHANNEL_VALID;
+	count = count << 8;
+	count |= count_l;
+
+	return count;
+}
+EXPORT_SYMBOL(drm_scdc_get_char_error_count);
diff --git a/include/drm/drm_scdc_helper.h b/include/drm/drm_scdc_helper.h
index 6a483533aae4..50062fd6d6a7 100644
--- a/include/drm/drm_scdc_helper.h
+++ b/include/drm/drm_scdc_helper.h
@@ -133,4 +133,9 @@ bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter);
 
 bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable);
 bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set);
+u8 drm_scdc_read_update_flags(struct i2c_adapter *adapter);
+int drm_scdc_clear_update_flags(struct i2c_adapter *adapter, u8 update_flags);
+u8 drm_scdc_read_status_flags(struct i2c_adapter *adapter);
+int drm_scdc_get_char_error_count(struct i2c_adapter *adapter,
+				  u8 lane_num);
 #endif
-- 
2.25.1



More information about the Intel-gfx-trybot mailing list