[PATCH RFC 05/25] drm/bridge: Add VTEM EMP support

Nicolas Frattaroli nicolas.frattaroli at collabora.com
Mon Sep 21 08:51:31 PDT 2026


From: Derek Foreman <derek.foreman at collabora.com>

Add setters and support bit for VTEM emp to the bridge.

Signed-off-by: Derek Foreman <derek.foreman at collabora.com>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 41 ++++++++++++++++++++++++++
 include/drm/drm_bridge.h                       | 29 ++++++++++++++++++
 include/drm/drm_connector.h                    |  8 +++++
 3 files changed, 78 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 707d7143e475..dc814dbb5120 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -610,6 +610,33 @@ static int drm_bridge_connector_scrambler_disable(struct drm_connector *connecto
 	return bridge->funcs->hdmi_scrambler_disable(bridge);
 }
 
+static int drm_bridge_connector_clear_vtem_emp(struct drm_connector *connector)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	return bridge->funcs->hdmi_clear_vtem_emp(bridge);
+}
+
+static int drm_bridge_connector_write_vtem_emp(struct drm_connector *connector,
+					       const u8 *buffer, size_t len)
+{
+	struct drm_bridge_connector *bridge_connector =
+		to_drm_bridge_connector(connector);
+	struct drm_bridge *bridge;
+
+	bridge = bridge_connector->bridge_hdmi;
+	if (!bridge)
+		return -EINVAL;
+
+	return bridge->funcs->hdmi_write_vtem_emp(bridge, buffer, len);
+}
+
 static const struct drm_edid *
 drm_bridge_connector_read_edid(struct drm_connector *connector)
 {
@@ -655,6 +682,11 @@ static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_spd_
 	.write_infoframe = drm_bridge_connector_write_spd_infoframe,
 };
 
+static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_vtem_emp = {
+	.clear_infoframe = drm_bridge_connector_clear_vtem_emp,
+	.write_infoframe = drm_bridge_connector_write_vtem_emp,
+};
+
 static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
 {
 	struct drm_bridge_connector *bridge_connector =
@@ -946,6 +978,11 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 			     !bridge->funcs->hdmi_scrambler_disable))
 				return ERR_PTR(-EINVAL);
 
+			if (bridge->ops & DRM_BRIDGE_OP_HDMI_VTEM_EMP &&
+			    (!bridge->funcs->hdmi_write_vtem_emp ||
+			     !bridge->funcs->hdmi_clear_vtem_emp))
+				return ERR_PTR(-EINVAL);
+
 			bridge_connector->bridge_hdmi = drm_bridge_get(bridge);
 		}
 
@@ -1072,6 +1109,10 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
 				drm_bridge_connector_scrambler_disable;
 		}
 
+		if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_VTEM_EMP)
+			bridge_connector->hdmi_funcs.vtem =
+				drm_bridge_connector_hdmi_vtem_emp;
+
 		ret = drmm_connector_hdmi_init(drm, connector,
 					       &drm_bridge_connector_funcs,
 					       &bridge_connector->hdmi_funcs,
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 77b3ffe69230..9dbd1bfa39af 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -684,6 +684,29 @@ struct drm_bridge_funcs {
 	int (*hdmi_write_spd_infoframe)(struct drm_bridge *bridge,
 					const u8 *buffer, size_t len);
 
+	/**
+	 * @hdmi_clear_vtem_emp:
+	 *
+	 * This callback clears the emp in the hardware during commit.
+	 *
+	 * This callback is optional but it must be implemented by bridges that
+	 * set the DRM_BRIDGE_OP_HDMI_VTEM_EMP flag in their
+	 * &drm_bridge->ops.
+	 */
+	int (*hdmi_clear_vtem_emp)(struct drm_bridge *bridge);
+
+	/**
+	 * @hdmi_write_spd_infoframe:
+	 *
+	 * Program the emp into the hardware.
+	 *
+	 * This callback is optional but it must be implemented by bridges that
+	 * set the DRM_BRIDGE_OP_HDMI_VTEM_EMP flag in their
+	 * &drm_bridge->ops.
+	 */
+	int (*hdmi_write_vtem_emp)(struct drm_bridge *bridge,
+				   const u8 *buffer, size_t len);
+
 	/**
 	 * @hdmi_clear_audio_infoframe:
 	 *
@@ -1021,6 +1044,12 @@ enum drm_bridge_ops {
 	 * &drm_bridge_funcs->hdmi_clear_spd_infoframe callbacks.
 	 */
 	DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME = BIT(10),
+	/**
+	 * @DRM_BRIDGE_OP_HDMI_VTEM_EMP: The bridge supports
+	 * &drm_bridge_funcs->hdmi_write_vtem_emp and
+	 * &drm_bridge_funcs->hdmi_clear_vtem_emp callbacks.
+	 */
+	DRM_BRIDGE_OP_HDMI_VTEM_EMP = BIT(11),
 };
 
 /**
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 593fbeaffa16..e561a444515f 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1633,6 +1633,14 @@ struct drm_connector_hdmi_funcs {
 	 * optional.
 	 */
 	struct drm_connector_infoframe_funcs spd;
+
+	/**
+	 * @vtem:
+	 *
+	 * Set of callbacks for handling the VTEM EMP. These callbacks are
+	 * optional.
+	 */
+	struct drm_connector_infoframe_funcs vtem;
 };
 
 /**

-- 
2.55.0




More information about the linux-arm-kernel mailing list