Commit ae219fdc authored by Dmitry Baryshkov's avatar Dmitry Baryshkov
Browse files

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: default avatarMaxime Ripard <mripard@kernel.org>
Link: https://patch.msgid.link/20260107-limit-infoframes-2-v4-9-213d0d3bd490@oss.qualcomm.com


Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
parent 4fc30c2c
Loading
Loading
Loading
Loading
+45 −49
Original line number Diff line number Diff line
@@ -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;
}

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;
}

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;
}

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;
}

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;
}

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;
}

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 = {
	/* 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,
	},
	.hdr_drm = {
};

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,
	},
	.spd = {
};

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);