summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>2026-01-07 21:15:06 +0300
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>2026-01-19 14:11:47 +0300
commitae219fdc952c315182b471f5aa71b379584b70ca (patch)
treef6dd6d94907adcf204987fbef7a8ed8ab4909a75
parent4fc30c2c5c61db88e3d6644bd3dd2032ec4bee06 (diff)
downloadlinux-ae219fdc952c315182b471f5aa71b379584b70ca.tar.xz
drm/display: bridge_connector: dynamically generate HDMI callbacks
The rest of the DRM framework uses presence of the callbacks to check if the particular infoframe is supported. Register HDMI callbacks dynamically, basing on the corresponding drm_bridge ops. Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patch.msgid.link/20260107-limit-infoframes-2-v4-9-213d0d3bd490@oss.qualcomm.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
-rw-r--r--drivers/gpu/drm/display/drm_bridge_connector.c94
1 files changed, 45 insertions, 49 deletions
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index ca6a72a4cf80..ba8ff113cff1 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -123,6 +123,14 @@ struct drm_bridge_connector {
* DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER).
*/
struct drm_bridge *bridge_hdmi_cec;
+
+ /**
+ * @hdmi_funcs:
+ *
+ * The particular &drm_connector_hdmi_funcs implementation for this
+ * bridge connector.
+ */
+ struct drm_connector_hdmi_funcs hdmi_funcs;
};
#define to_drm_bridge_connector(x) \
@@ -465,12 +473,7 @@ static int drm_bridge_connector_clear_audio_infoframe(struct drm_connector *conn
if (!bridge)
return -EINVAL;
- if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO)
- return bridge->funcs->hdmi_clear_audio_infoframe(bridge);
-
- drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n");
-
- return 0;
+ return bridge->funcs->hdmi_clear_audio_infoframe(bridge);
}
static int drm_bridge_connector_write_audio_infoframe(struct drm_connector *connector,
@@ -484,12 +487,7 @@ static int drm_bridge_connector_write_audio_infoframe(struct drm_connector *conn
if (!bridge)
return -EINVAL;
- if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO)
- return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len);
-
- drm_dbg_driver(connector->dev, "Unsupported HDMI Audio InfoFrame\n");
-
- return 0;
+ return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len);
}
static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector *connector)
@@ -502,12 +500,7 @@ static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector *co
if (!bridge)
return -EINVAL;
- if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME)
- return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge);
-
- drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n");
-
- return 0;
+ return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge);
}
static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector *connector,
@@ -521,12 +514,7 @@ static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector *co
if (!bridge)
return -EINVAL;
- if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME)
- return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len);
-
- drm_dbg_driver(connector->dev, "Unsupported HDMI HDR DRM InfoFrame\n");
-
- return 0;
+ return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len);
}
static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector *connector)
@@ -539,12 +527,7 @@ static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector *connec
if (!bridge)
return -EINVAL;
- if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME)
- return bridge->funcs->hdmi_clear_spd_infoframe(bridge);
-
- drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n");
-
- return 0;
+ return bridge->funcs->hdmi_clear_spd_infoframe(bridge);
}
static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connector,
@@ -558,12 +541,7 @@ static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connec
if (!bridge)
return -EINVAL;
- if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME)
- return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len);
-
- drm_dbg_driver(connector->dev, "Unsupported HDMI SPD InfoFrame\n");
-
- return 0;
+ return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len);
}
static const struct drm_edid *
@@ -591,18 +569,22 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
.clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe,
.write_infoframe = drm_bridge_connector_write_hdmi_infoframe,
},
- .audio = {
- .clear_infoframe = drm_bridge_connector_clear_audio_infoframe,
- .write_infoframe = drm_bridge_connector_write_audio_infoframe,
- },
- .hdr_drm = {
- .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe,
- .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe,
- },
- .spd = {
- .clear_infoframe = drm_bridge_connector_clear_spd_infoframe,
- .write_infoframe = drm_bridge_connector_write_spd_infoframe,
- },
+ /* audio, hdr_drm and spd are set dynamically during init */
+};
+
+static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_audio_infoframe = {
+ .clear_infoframe = drm_bridge_connector_clear_audio_infoframe,
+ .write_infoframe = drm_bridge_connector_write_audio_infoframe,
+};
+
+static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_hdr_drm_infoframe = {
+ .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe,
+ .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe,
+};
+
+static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_spd_infoframe = {
+ .clear_infoframe = drm_bridge_connector_clear_spd_infoframe,
+ .write_infoframe = drm_bridge_connector_write_spd_infoframe,
};
static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
@@ -971,11 +953,25 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
if (!connector->ycbcr_420_allowed)
supported_formats &= ~BIT(HDMI_COLORSPACE_YUV420);
+ bridge_connector->hdmi_funcs = drm_bridge_connector_hdmi_funcs;
+
+ if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_AUDIO)
+ bridge_connector->hdmi_funcs.audio =
+ drm_bridge_connector_hdmi_audio_infoframe;
+
+ if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME)
+ bridge_connector->hdmi_funcs.hdr_drm =
+ drm_bridge_connector_hdmi_hdr_drm_infoframe;
+
+ if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME)
+ bridge_connector->hdmi_funcs.spd =
+ drm_bridge_connector_hdmi_spd_infoframe;
+
ret = drmm_connector_hdmi_init(drm, connector,
bridge_connector->bridge_hdmi->vendor,
bridge_connector->bridge_hdmi->product,
&drm_bridge_connector_funcs,
- &drm_bridge_connector_hdmi_funcs,
+ &bridge_connector->hdmi_funcs,
connector_type, ddc,
supported_formats,
max_bpc);