* [PATCH v6 1/4] drm/bridge: split HDMI Audio from DRM_BRIDGE_OP_HDMI
2025-03-14 9:36 [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges Dmitry Baryshkov
@ 2025-03-14 9:36 ` Dmitry Baryshkov
2025-03-14 17:53 ` Maxime Ripard
2025-03-14 9:36 ` [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation Dmitry Baryshkov
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Dmitry Baryshkov @ 2025-03-14 9:36 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
Abhinav Kumar, Sean Paul, Marijn Suijten, Hermes Wu,
Dmitry Baryshkov
Cc: dri-devel, linux-kernel, linux-arm-msm, freedreno,
Dmitry Baryshkov
From: Dmitry Baryshkov <lumag@kernel.org>
As pointed out by Laurent, OP bits are supposed to describe operations.
Split DRM_BRIDGE_OP_HDMI_AUDIO from DRM_BRIDGE_OP_HDMI instead of
overloading DRM_BRIDGE_OP_HDMI.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/bridge/lontium-lt9611.c | 2 +-
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 1 +
drivers/gpu/drm/display/drm_bridge_connector.c | 59 +++++++++++++++++---------
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 1 +
include/drm/drm_bridge.h | 46 ++++++++++++++------
5 files changed, 76 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 026803034231f78c17f619dc04119bdd9b2b6679..3b93c17e25c18ae0d13e9bb74553cf21dcc39f9d 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -1130,7 +1130,7 @@ static int lt9611_probe(struct i2c_client *client)
lt9611->bridge.of_node = client->dev.of_node;
lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES |
- DRM_BRIDGE_OP_HDMI;
+ DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO;
lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
lt9611->bridge.vendor = "Lontium";
lt9611->bridge.product = "LT9611";
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 6166f197e37b552cb8a52b7b0d23ffc632f54557..5e5f8c2f95be1f5c4633f1093b17a00f9425bb37 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -1077,6 +1077,7 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT |
DRM_BRIDGE_OP_EDID |
DRM_BRIDGE_OP_HDMI |
+ DRM_BRIDGE_OP_HDMI_AUDIO |
DRM_BRIDGE_OP_HPD;
hdmi->bridge.of_node = pdev->dev.of_node;
hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 30c736fc0067e31a97db242e5b16ea8a5b4cf359..030f98d454608a63154827c65d4822d378df3b4c 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -98,6 +98,13 @@ struct drm_bridge_connector {
* HDMI connector infrastructure, if any (see &DRM_BRIDGE_OP_HDMI).
*/
struct drm_bridge *bridge_hdmi;
+ /**
+ * @bridge_hdmi_audio:
+ *
+ * The bridge in the chain that implements necessary support for the
+ * HDMI Audio infrastructure, if any (see &DRM_BRIDGE_OP_HDMI_AUDIO).
+ */
+ struct drm_bridge *bridge_hdmi_audio;
};
#define to_drm_bridge_connector(x) \
@@ -433,7 +440,7 @@ static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi;
+ bridge = bridge_connector->bridge_hdmi_audio;
if (!bridge)
return -EINVAL;
@@ -451,7 +458,7 @@ static int drm_bridge_connector_audio_prepare(struct drm_connector *connector,
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi;
+ bridge = bridge_connector->bridge_hdmi_audio;
if (!bridge)
return -EINVAL;
@@ -464,7 +471,7 @@ static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector)
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi;
+ bridge = bridge_connector->bridge_hdmi_audio;
if (!bridge)
return;
@@ -478,7 +485,7 @@ static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connecto
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi;
+ bridge = bridge_connector->bridge_hdmi_audio;
if (!bridge)
return -EINVAL;
@@ -576,6 +583,21 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
max_bpc = bridge->max_bpc;
}
+ if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) {
+ if (bridge_connector->bridge_hdmi_audio)
+ return ERR_PTR(-EBUSY);
+
+ if (!bridge->hdmi_audio_max_i2s_playback_channels &&
+ !bridge->hdmi_audio_spdif_playback)
+ return ERR_PTR(-EINVAL);
+
+ if (!bridge->funcs->hdmi_audio_prepare ||
+ !bridge->funcs->hdmi_audio_shutdown)
+ return ERR_PTR(-EINVAL);
+
+ bridge_connector->bridge_hdmi_audio = bridge;
+ }
+
if (!drm_bridge_get_next_bridge(bridge))
connector_type = bridge->type;
@@ -611,22 +633,6 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
max_bpc);
if (ret)
return ERR_PTR(ret);
-
- if (bridge->hdmi_audio_max_i2s_playback_channels ||
- bridge->hdmi_audio_spdif_playback) {
- if (!bridge->funcs->hdmi_audio_prepare ||
- !bridge->funcs->hdmi_audio_shutdown)
- return ERR_PTR(-EINVAL);
-
- ret = drm_connector_hdmi_audio_init(connector,
- bridge->hdmi_audio_dev,
- &drm_bridge_connector_hdmi_audio_funcs,
- bridge->hdmi_audio_max_i2s_playback_channels,
- bridge->hdmi_audio_spdif_playback,
- bridge->hdmi_audio_dai_port);
- if (ret)
- return ERR_PTR(ret);
- }
} else {
ret = drmm_connector_init(drm, connector,
&drm_bridge_connector_funcs,
@@ -635,6 +641,19 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
return ERR_PTR(ret);
}
+ if (bridge_connector->bridge_hdmi_audio) {
+ bridge = bridge_connector->bridge_hdmi_audio;
+
+ ret = drm_connector_hdmi_audio_init(connector,
+ bridge->hdmi_audio_dev,
+ &drm_bridge_connector_hdmi_audio_funcs,
+ bridge->hdmi_audio_max_i2s_playback_channels,
+ bridge->hdmi_audio_spdif_playback,
+ bridge->hdmi_audio_dai_port);
+ if (ret)
+ return ERR_PTR(ret);
+ }
+
drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
if (bridge_connector->bridge_hpd)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 1456354c8af4bc7f655e8a47e958e9e0b99b7d29..ab6c8bc4a30b681f7de8ca7031f833795d1f7d94 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -515,6 +515,7 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi)
bridge->ops = DRM_BRIDGE_OP_HPD |
DRM_BRIDGE_OP_DETECT |
DRM_BRIDGE_OP_HDMI |
+ DRM_BRIDGE_OP_HDMI_AUDIO |
DRM_BRIDGE_OP_EDID;
bridge->hdmi_audio_max_i2s_playback_channels = 8;
bridge->hdmi_audio_dev = &hdmi->pdev->dev;
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index d4c75d59fa12be1bd7375ce3ea56415235781b28..c6b66f733fffa77afc875e52f9d1500fcb66400f 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -681,8 +681,10 @@ struct drm_bridge_funcs {
/**
* @hdmi_audio_startup:
*
- * Called when ASoC starts an audio stream setup. The
- * @hdmi_audio_startup() is optional.
+ * Called when ASoC starts an audio stream setup.
+ *
+ * This callback is optional, it can be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops.
*
* Returns:
* 0 on success, a negative error code otherwise
@@ -693,8 +695,10 @@ struct drm_bridge_funcs {
/**
* @hdmi_audio_prepare:
* Configures HDMI-encoder for audio stream. Can be called multiple
- * times for each setup. Mandatory if HDMI audio is enabled in the
- * bridge's configuration.
+ * times for each setup.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops.
*
* Returns:
* 0 on success, a negative error code otherwise
@@ -707,8 +711,10 @@ struct drm_bridge_funcs {
/**
* @hdmi_audio_shutdown:
*
- * Shut down the audio stream. Mandatory if HDMI audio is enabled in
- * the bridge's configuration.
+ * Shut down the audio stream.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops.
*
* Returns:
* 0 on success, a negative error code otherwise
@@ -719,8 +725,10 @@ struct drm_bridge_funcs {
/**
* @hdmi_audio_mute_stream:
*
- * Mute/unmute HDMI audio stream. The @hdmi_audio_mute_stream callback
- * is optional.
+ * Mute/unmute HDMI audio stream.
+ *
+ * This callback is optional, it can be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops.
*
* Returns:
* 0 on success, a negative error code otherwise
@@ -814,6 +822,17 @@ enum drm_bridge_ops {
* drivers.
*/
DRM_BRIDGE_OP_HDMI = BIT(4),
+ /**
+ * @DRM_BRIDGE_OP_HDMI_AUDIO: The bridge provides HDMI audio operations.
+ * Bridges that set this flag must implement the
+ * &drm_bridge_funcs->hdmi_audio_prepare and
+ * &drm_bridge_funcs->hdmi_audio_shutdown callbacks.
+ *
+ * Note: currently there can be at most one bridge in a chain that sets
+ * this bit. This is to simplify corresponding glue code in connector
+ * drivers.
+ */
+ DRM_BRIDGE_OP_HDMI_AUDIO = BIT(5),
};
/**
@@ -914,23 +933,26 @@ struct drm_bridge {
unsigned int max_bpc;
/**
- * @hdmi_audio_dev: device to be used as a parent for the HDMI Codec
+ * @hdmi_audio_dev: device to be used as a parent for the HDMI Codec if
+ * @DRM_BRIDGE_OP_HDMI_AUDIO is set.
*/
struct device *hdmi_audio_dev;
/**
* @hdmi_audio_max_i2s_playback_channels: maximum number of playback
- * I2S channels for the HDMI codec
+ * I2S channels for the bridge that sets @DRM_BRIDGE_OP_HDMI_AUDIO.
*/
int hdmi_audio_max_i2s_playback_channels;
/**
- * @hdmi_audio_spdif_playback: set if HDMI codec has S/PDIF playback port
+ * @hdmi_audio_spdif_playback: set if this bridge has S/PDIF playback
+ * port for @DRM_BRIDGE_OP_HDMI_AUDIO
*/
unsigned int hdmi_audio_spdif_playback : 1;
/**
- * @hdmi_audio_dai_port: sound DAI port, -1 if it is not enabled
+ * @hdmi_audio_dai_port: sound DAI port for @DRM_BRIDGE_OP_HDMI_AUDIO,
+ * -1 if it is not used.
*/
int hdmi_audio_dai_port;
};
--
2.39.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v6 1/4] drm/bridge: split HDMI Audio from DRM_BRIDGE_OP_HDMI
2025-03-14 9:36 ` [PATCH v6 1/4] drm/bridge: split HDMI Audio from DRM_BRIDGE_OP_HDMI Dmitry Baryshkov
@ 2025-03-14 17:53 ` Maxime Ripard
0 siblings, 0 replies; 13+ messages in thread
From: Maxime Ripard @ 2025-03-14 17:53 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: dri-devel, freedreno, linux-arm-msm, linux-kernel, Abhinav Kumar,
Andrzej Hajda, David Airlie, Dmitry Baryshkov, Hermes Wu,
Jernej Skrabec, Jonas Karlman, Laurent Pinchart,
Maarten Lankhorst, Marijn Suijten, Maxime Ripard, Neil Armstrong,
Rob Clark, Robert Foss, Sean Paul, Simona Vetter,
Thomas Zimmermann
On Fri, 14 Mar 2025 11:36:48 +0200, Dmitry Baryshkov wrote:
> From: Dmitry Baryshkov <lumag@kernel.org>
>
> As pointed out by Laurent, OP bits are supposed to describe operations.
> Split DRM_BRIDGE_OP_HDMI_AUDIO from DRM_BRIDGE_OP_HDMI instead of
> overloading DRM_BRIDGE_OP_HDMI.
>
> [ ... ]
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation
2025-03-14 9:36 [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges Dmitry Baryshkov
2025-03-14 9:36 ` [PATCH v6 1/4] drm/bridge: split HDMI Audio from DRM_BRIDGE_OP_HDMI Dmitry Baryshkov
@ 2025-03-14 9:36 ` Dmitry Baryshkov
2025-03-14 17:53 ` Maxime Ripard
2025-03-14 17:54 ` Maxime Ripard
2025-03-14 9:36 ` [PATCH v6 3/4] drm/bridge-connector: hook DisplayPort audio support Dmitry Baryshkov
` (2 subsequent siblings)
4 siblings, 2 replies; 13+ messages in thread
From: Dmitry Baryshkov @ 2025-03-14 9:36 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
Abhinav Kumar, Sean Paul, Marijn Suijten, Hermes Wu,
Dmitry Baryshkov
Cc: dri-devel, linux-kernel, linux-arm-msm, freedreno
It is common for the DisplayPort bridges to implement audio support. In
preparation to providing a generic framework for DP audio, add
corresponding interface to struct drm_bridge. As suggested by Maxime
for now this is mostly c&p of the corresponding HDMI audio API.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
include/drm/drm_bridge.h | 88 ++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 82 insertions(+), 6 deletions(-)
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index c6b66f733fffa77afc875e52f9d1500fcb66400f..e8d0e56bcc91c1f4c689e4e6fbd2aceaf4fc5cf1 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -737,6 +737,65 @@ struct drm_bridge_funcs {
struct drm_bridge *bridge,
bool enable, int direction);
+ /**
+ * @dp_audio_startup:
+ *
+ * Called when ASoC starts a DisplayPort audio stream setup.
+ *
+ * This callback is optional, it can be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_DP_AUDIO flag in their &drm_bridge->ops.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ int (*dp_audio_startup)(struct drm_connector *connector,
+ struct drm_bridge *bridge);
+
+ /**
+ * @dp_audio_prepare:
+ * Configures DisplayPort audio stream. Can be called multiple
+ * times for each setup.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_DP_AUDIO flag in their &drm_bridge->ops.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ int (*dp_audio_prepare)(struct drm_connector *connector,
+ struct drm_bridge *bridge,
+ struct hdmi_codec_daifmt *fmt,
+ struct hdmi_codec_params *hparms);
+
+ /**
+ * @dp_audio_shutdown:
+ *
+ * Shut down the DisplayPort audio stream.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_DP_AUDIO flag in their &drm_bridge->ops.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ void (*dp_audio_shutdown)(struct drm_connector *connector,
+ struct drm_bridge *bridge);
+
+ /**
+ * @dp_audio_mute_stream:
+ *
+ * Mute/unmute DisplayPort audio stream.
+ *
+ * This callback is optional, it can be implemented by bridges that
+ * set the @DRM_BRIDGE_OP_DP_AUDIO flag in their &drm_bridge->ops.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ int (*dp_audio_mute_stream)(struct drm_connector *connector,
+ struct drm_bridge *bridge,
+ bool enable, int direction);
+
/**
* @debugfs_init:
*
@@ -830,9 +889,24 @@ enum drm_bridge_ops {
*
* Note: currently there can be at most one bridge in a chain that sets
* this bit. This is to simplify corresponding glue code in connector
- * drivers.
+ * drivers. Also it is not possible to have a bridge in the chain that
+ * sets @DRM_BRIDGE_OP_DP_AUDIO if there is a bridge that sets this
+ * flag.
*/
DRM_BRIDGE_OP_HDMI_AUDIO = BIT(5),
+ /**
+ * @DRM_BRIDGE_OP_DP_AUDIO: The bridge provides DisplayPort audio operations.
+ * Bridges that set this flag must implement the
+ * &drm_bridge_funcs->dp_audio_prepare and
+ * &drm_bridge_funcs->dp_audio_shutdown callbacks.
+ *
+ * Note: currently there can be at most one bridge in a chain that sets
+ * this bit. This is to simplify corresponding glue code in connector
+ * drivers. Also it is not possible to have a bridge in the chain that
+ * sets @DRM_BRIDGE_OP_HDMI_AUDIO if there is a bridge that sets this
+ * flag.
+ */
+ DRM_BRIDGE_OP_DP_AUDIO = BIT(6),
};
/**
@@ -934,25 +1008,27 @@ struct drm_bridge {
/**
* @hdmi_audio_dev: device to be used as a parent for the HDMI Codec if
- * @DRM_BRIDGE_OP_HDMI_AUDIO is set.
+ * either of @DRM_BRIDGE_OP_HDMI_AUDIO or @DRM_BRIDGE_OP_DP_AUDIO is set.
*/
struct device *hdmi_audio_dev;
/**
* @hdmi_audio_max_i2s_playback_channels: maximum number of playback
- * I2S channels for the bridge that sets @DRM_BRIDGE_OP_HDMI_AUDIO.
+ * I2S channels for the @DRM_BRIDGE_OP_HDMI_AUDIO or
+ * @DRM_BRIDGE_OP_DP_AUDIO.
*/
int hdmi_audio_max_i2s_playback_channels;
/**
* @hdmi_audio_spdif_playback: set if this bridge has S/PDIF playback
- * port for @DRM_BRIDGE_OP_HDMI_AUDIO
+ * port for @DRM_BRIDGE_OP_HDMI_AUDIO or @DRM_BRIDGE_OP_DP_AUDIO.
*/
unsigned int hdmi_audio_spdif_playback : 1;
/**
- * @hdmi_audio_dai_port: sound DAI port for @DRM_BRIDGE_OP_HDMI_AUDIO,
- * -1 if it is not used.
+ * @hdmi_audio_dai_port: sound DAI port for either of
+ * @DRM_BRIDGE_OP_HDMI_AUDIO and @DRM_BRIDGE_OP_DP_AUDIO, -1 if it is
+ * not used.
*/
int hdmi_audio_dai_port;
};
--
2.39.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation
2025-03-14 9:36 ` [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation Dmitry Baryshkov
@ 2025-03-14 17:53 ` Maxime Ripard
2025-03-14 17:54 ` Maxime Ripard
1 sibling, 0 replies; 13+ messages in thread
From: Maxime Ripard @ 2025-03-14 17:53 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: dri-devel, freedreno, linux-arm-msm, linux-kernel, Abhinav Kumar,
Andrzej Hajda, David Airlie, Dmitry Baryshkov, Hermes Wu,
Jernej Skrabec, Jonas Karlman, Laurent Pinchart,
Maarten Lankhorst, Marijn Suijten, Maxime Ripard, Neil Armstrong,
Rob Clark, Robert Foss, Sean Paul, Simona Vetter,
Thomas Zimmermann
On Fri, 14 Mar 2025 11:36:49 +0200, Dmitry Baryshkov wrote:
> It is common for the DisplayPort bridges to implement audio support. In
> preparation to providing a generic framework for DP audio, add
> corresponding interface to struct drm_bridge. As suggested by Maxime
> for now this is mostly c&p of the corresponding HDMI audio API.
>
>
> [ ... ]
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation
2025-03-14 9:36 ` [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation Dmitry Baryshkov
2025-03-14 17:53 ` Maxime Ripard
@ 2025-03-14 17:54 ` Maxime Ripard
2025-03-14 18:55 ` Dmitry Baryshkov
1 sibling, 1 reply; 13+ messages in thread
From: Maxime Ripard @ 2025-03-14 17:54 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: dri-devel, freedreno, linux-arm-msm, linux-kernel, Abhinav Kumar,
Andrzej Hajda, David Airlie, Dmitry Baryshkov, Hermes Wu,
Jernej Skrabec, Jonas Karlman, Laurent Pinchart,
Maarten Lankhorst, Marijn Suijten, Maxime Ripard, Neil Armstrong,
Rob Clark, Robert Foss, Sean Paul, Simona Vetter,
Thomas Zimmermann
On Fri, 14 Mar 2025 11:36:49 +0200, Dmitry Baryshkov wrote:
> It is common for the DisplayPort bridges to implement audio support. In
> preparation to providing a generic framework for DP audio, add
> corresponding interface to struct drm_bridge. As suggested by Maxime
> for now this is mostly c&p of the corresponding HDMI audio API.
>
>
> [ ... ]
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation
2025-03-14 17:54 ` Maxime Ripard
@ 2025-03-14 18:55 ` Dmitry Baryshkov
2025-03-17 9:45 ` Maxime Ripard
0 siblings, 1 reply; 13+ messages in thread
From: Dmitry Baryshkov @ 2025-03-14 18:55 UTC (permalink / raw)
To: Maxime Ripard
Cc: dri-devel, freedreno, linux-arm-msm, linux-kernel, Abhinav Kumar,
Andrzej Hajda, David Airlie, Dmitry Baryshkov, Hermes Wu,
Jernej Skrabec, Jonas Karlman, Laurent Pinchart,
Maarten Lankhorst, Marijn Suijten, Neil Armstrong, Rob Clark,
Robert Foss, Sean Paul, Simona Vetter, Thomas Zimmermann
On Fri, Mar 14, 2025 at 05:54:14PM +0000, Maxime Ripard wrote:
> On Fri, 14 Mar 2025 11:36:49 +0200, Dmitry Baryshkov wrote:
> > It is common for the DisplayPort bridges to implement audio support. In
> > preparation to providing a generic framework for DP audio, add
> > corresponding interface to struct drm_bridge. As suggested by Maxime
> > for now this is mostly c&p of the corresponding HDMI audio API.
> >
> >
> > [ ... ]
>
> Reviewed-by: Maxime Ripard <mripard@kernel.org>
You've sent two r-b's for patch 2. Is there a chance that one of those
was for patch 3?
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation
2025-03-14 18:55 ` Dmitry Baryshkov
@ 2025-03-17 9:45 ` Maxime Ripard
2025-03-17 11:17 ` Dmitry Baryshkov
0 siblings, 1 reply; 13+ messages in thread
From: Maxime Ripard @ 2025-03-17 9:45 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: dri-devel, freedreno, linux-arm-msm, linux-kernel, Abhinav Kumar,
Andrzej Hajda, David Airlie, Dmitry Baryshkov, Hermes Wu,
Jernej Skrabec, Jonas Karlman, Laurent Pinchart,
Maarten Lankhorst, Marijn Suijten, Neil Armstrong, Rob Clark,
Robert Foss, Sean Paul, Simona Vetter, Thomas Zimmermann
[-- Attachment #1: Type: text/plain, Size: 741 bytes --]
On Fri, Mar 14, 2025 at 08:55:05PM +0200, Dmitry Baryshkov wrote:
> On Fri, Mar 14, 2025 at 05:54:14PM +0000, Maxime Ripard wrote:
> > On Fri, 14 Mar 2025 11:36:49 +0200, Dmitry Baryshkov wrote:
> > > It is common for the DisplayPort bridges to implement audio support. In
> > > preparation to providing a generic framework for DP audio, add
> > > corresponding interface to struct drm_bridge. As suggested by Maxime
> > > for now this is mostly c&p of the corresponding HDMI audio API.
> > >
> > >
> > > [ ... ]
> >
> > Reviewed-by: Maxime Ripard <mripard@kernel.org>
>
> You've sent two r-b's for patch 2. Is there a chance that one of those
> was for patch 3?
Did I? Sorry, it was indeed meant for patch 3
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation
2025-03-17 9:45 ` Maxime Ripard
@ 2025-03-17 11:17 ` Dmitry Baryshkov
0 siblings, 0 replies; 13+ messages in thread
From: Dmitry Baryshkov @ 2025-03-17 11:17 UTC (permalink / raw)
To: Maxime Ripard
Cc: dri-devel, freedreno, linux-arm-msm, linux-kernel, Abhinav Kumar,
Andrzej Hajda, David Airlie, Dmitry Baryshkov, Hermes Wu,
Jernej Skrabec, Jonas Karlman, Laurent Pinchart,
Maarten Lankhorst, Marijn Suijten, Neil Armstrong, Rob Clark,
Robert Foss, Sean Paul, Simona Vetter, Thomas Zimmermann
On Mon, Mar 17, 2025 at 10:45:16AM +0100, Maxime Ripard wrote:
> On Fri, Mar 14, 2025 at 08:55:05PM +0200, Dmitry Baryshkov wrote:
> > On Fri, Mar 14, 2025 at 05:54:14PM +0000, Maxime Ripard wrote:
> > > On Fri, 14 Mar 2025 11:36:49 +0200, Dmitry Baryshkov wrote:
> > > > It is common for the DisplayPort bridges to implement audio support. In
> > > > preparation to providing a generic framework for DP audio, add
> > > > corresponding interface to struct drm_bridge. As suggested by Maxime
> > > > for now this is mostly c&p of the corresponding HDMI audio API.
> > > >
> > > >
> > > > [ ... ]
> > >
> > > Reviewed-by: Maxime Ripard <mripard@kernel.org>
> >
> > You've sent two r-b's for patch 2. Is there a chance that one of those
> > was for patch 3?
>
> Did I? Sorry, it was indeed meant for patch 3
Yes, at least mutt and lore show both under patch 2. If/when you have
time, could you please fix that so that the r-b is recorded for future
generations?
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 3/4] drm/bridge-connector: hook DisplayPort audio support
2025-03-14 9:36 [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges Dmitry Baryshkov
2025-03-14 9:36 ` [PATCH v6 1/4] drm/bridge: split HDMI Audio from DRM_BRIDGE_OP_HDMI Dmitry Baryshkov
2025-03-14 9:36 ` [PATCH v6 2/4] drm/bridge: add function interface for DisplayPort audio implementation Dmitry Baryshkov
@ 2025-03-14 9:36 ` Dmitry Baryshkov
2025-03-19 15:52 ` Maxime Ripard
2025-03-14 9:36 ` [PATCH v6 4/4] drm/msm/dp: reuse generic HDMI codec implementation Dmitry Baryshkov
2025-04-07 13:09 ` (subset) [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges Dmitry Baryshkov
4 siblings, 1 reply; 13+ messages in thread
From: Dmitry Baryshkov @ 2025-03-14 9:36 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
Abhinav Kumar, Sean Paul, Marijn Suijten, Hermes Wu,
Dmitry Baryshkov
Cc: dri-devel, linux-kernel, linux-arm-msm, freedreno
Reuse existing code plumbing HDMI audio support and the existing HDMI
audio helpers that register HDMI codec device and plumb in the
DisplayPort audio interfaces to be handled by the drm_bridge_connector.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/display/drm_bridge_connector.c | 117 ++++++++++++++++++++-----
1 file changed, 93 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 030f98d454608a63154827c65d4822d378df3b4c..7d2e499ea5dec2f710c1c67323bf9e6b177d3c9e 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -105,6 +105,14 @@ struct drm_bridge_connector {
* HDMI Audio infrastructure, if any (see &DRM_BRIDGE_OP_HDMI_AUDIO).
*/
struct drm_bridge *bridge_hdmi_audio;
+ /**
+ * @bridge_dp_audio:
+ *
+ * The bridge in the chain that implements necessary support for the
+ * DisplayPort Audio infrastructure, if any (see
+ * &DRM_BRIDGE_OP_DP_AUDIO).
+ */
+ struct drm_bridge *bridge_dp_audio;
};
#define to_drm_bridge_connector(x) \
@@ -440,14 +448,25 @@ static int drm_bridge_connector_audio_startup(struct drm_connector *connector)
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi_audio;
- if (!bridge)
- return -EINVAL;
+ if (bridge_connector->bridge_hdmi_audio) {
+ bridge = bridge_connector->bridge_hdmi_audio;
- if (!bridge->funcs->hdmi_audio_startup)
- return 0;
+ if (!bridge->funcs->hdmi_audio_startup)
+ return 0;
- return bridge->funcs->hdmi_audio_startup(connector, bridge);
+ return bridge->funcs->hdmi_audio_startup(connector, bridge);
+ }
+
+ if (bridge_connector->bridge_dp_audio) {
+ bridge = bridge_connector->bridge_dp_audio;
+
+ if (!bridge->funcs->dp_audio_startup)
+ return 0;
+
+ return bridge->funcs->dp_audio_startup(connector, bridge);
+ }
+
+ return -EINVAL;
}
static int drm_bridge_connector_audio_prepare(struct drm_connector *connector,
@@ -458,11 +477,19 @@ static int drm_bridge_connector_audio_prepare(struct drm_connector *connector,
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi_audio;
- if (!bridge)
- return -EINVAL;
+ if (bridge_connector->bridge_hdmi_audio) {
+ bridge = bridge_connector->bridge_hdmi_audio;
+
+ return bridge->funcs->hdmi_audio_prepare(connector, bridge, fmt, hparms);
+ }
+
+ if (bridge_connector->bridge_dp_audio) {
+ bridge = bridge_connector->bridge_dp_audio;
+
+ return bridge->funcs->dp_audio_prepare(connector, bridge, fmt, hparms);
+ }
- return bridge->funcs->hdmi_audio_prepare(connector, bridge, fmt, hparms);
+ return -EINVAL;
}
static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector)
@@ -471,11 +498,15 @@ static void drm_bridge_connector_audio_shutdown(struct drm_connector *connector)
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi_audio;
- if (!bridge)
- return;
+ if (bridge_connector->bridge_hdmi_audio) {
+ bridge = bridge_connector->bridge_hdmi_audio;
+ bridge->funcs->hdmi_audio_shutdown(connector, bridge);
+ }
- bridge->funcs->hdmi_audio_shutdown(connector, bridge);
+ if (bridge_connector->bridge_dp_audio) {
+ bridge = bridge_connector->bridge_dp_audio;
+ bridge->funcs->dp_audio_shutdown(connector, bridge);
+ }
}
static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connector,
@@ -485,15 +516,27 @@ static int drm_bridge_connector_audio_mute_stream(struct drm_connector *connecto
to_drm_bridge_connector(connector);
struct drm_bridge *bridge;
- bridge = bridge_connector->bridge_hdmi_audio;
- if (!bridge)
- return -EINVAL;
+ if (bridge_connector->bridge_hdmi_audio) {
+ bridge = bridge_connector->bridge_hdmi_audio;
+
+ if (!bridge->funcs->hdmi_audio_mute_stream)
+ return -ENOTSUPP;
- if (bridge->funcs->hdmi_audio_mute_stream)
return bridge->funcs->hdmi_audio_mute_stream(connector, bridge,
enable, direction);
- else
- return -ENOTSUPP;
+ }
+
+ if (bridge_connector->bridge_dp_audio) {
+ bridge = bridge_connector->bridge_dp_audio;
+
+ if (!bridge->funcs->dp_audio_mute_stream)
+ return -ENOTSUPP;
+
+ return bridge->funcs->dp_audio_mute_stream(connector, bridge,
+ enable, direction);
+ }
+
+ return -EINVAL;
}
static const struct drm_connector_hdmi_audio_funcs drm_bridge_connector_hdmi_audio_funcs = {
@@ -587,6 +630,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
if (bridge_connector->bridge_hdmi_audio)
return ERR_PTR(-EBUSY);
+ if (bridge_connector->bridge_dp_audio)
+ return ERR_PTR(-EBUSY);
+
if (!bridge->hdmi_audio_max_i2s_playback_channels &&
!bridge->hdmi_audio_spdif_playback)
return ERR_PTR(-EINVAL);
@@ -598,6 +644,24 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
bridge_connector->bridge_hdmi_audio = bridge;
}
+ if (bridge->ops & DRM_BRIDGE_OP_DP_AUDIO) {
+ if (bridge_connector->bridge_dp_audio)
+ return ERR_PTR(-EBUSY);
+
+ if (bridge_connector->bridge_hdmi_audio)
+ return ERR_PTR(-EBUSY);
+
+ if (!bridge->hdmi_audio_max_i2s_playback_channels &&
+ !bridge->hdmi_audio_spdif_playback)
+ return ERR_PTR(-EINVAL);
+
+ if (!bridge->funcs->dp_audio_prepare ||
+ !bridge->funcs->dp_audio_shutdown)
+ return ERR_PTR(-EINVAL);
+
+ bridge_connector->bridge_dp_audio = bridge;
+ }
+
if (!drm_bridge_get_next_bridge(bridge))
connector_type = bridge->type;
@@ -641,11 +705,16 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
return ERR_PTR(ret);
}
- if (bridge_connector->bridge_hdmi_audio) {
- bridge = bridge_connector->bridge_hdmi_audio;
+ if (bridge_connector->bridge_hdmi_audio ||
+ bridge_connector->bridge_dp_audio) {
+ struct device *dev;
+
+ if (bridge_connector->bridge_hdmi_audio)
+ dev = bridge_connector->bridge_hdmi_audio->hdmi_audio_dev;
+ else
+ dev = bridge_connector->bridge_dp_audio->hdmi_audio_dev;
- ret = drm_connector_hdmi_audio_init(connector,
- bridge->hdmi_audio_dev,
+ ret = drm_connector_hdmi_audio_init(connector, dev,
&drm_bridge_connector_hdmi_audio_funcs,
bridge->hdmi_audio_max_i2s_playback_channels,
bridge->hdmi_audio_spdif_playback,
--
2.39.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v6 3/4] drm/bridge-connector: hook DisplayPort audio support
2025-03-14 9:36 ` [PATCH v6 3/4] drm/bridge-connector: hook DisplayPort audio support Dmitry Baryshkov
@ 2025-03-19 15:52 ` Maxime Ripard
0 siblings, 0 replies; 13+ messages in thread
From: Maxime Ripard @ 2025-03-19 15:52 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: dri-devel, freedreno, linux-arm-msm, linux-kernel, Abhinav Kumar,
Andrzej Hajda, David Airlie, Dmitry Baryshkov, Hermes Wu,
Jernej Skrabec, Jonas Karlman, Laurent Pinchart,
Maarten Lankhorst, Marijn Suijten, Maxime Ripard, Neil Armstrong,
Rob Clark, Robert Foss, Sean Paul, Simona Vetter,
Thomas Zimmermann
On Fri, 14 Mar 2025 11:36:50 +0200, Dmitry Baryshkov wrote:
> Reuse existing code plumbing HDMI audio support and the existing HDMI
> audio helpers that register HDMI codec device and plumb in the
> DisplayPort audio interfaces to be handled by the drm_bridge_connector.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
>
> [ ... ]
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 4/4] drm/msm/dp: reuse generic HDMI codec implementation
2025-03-14 9:36 [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges Dmitry Baryshkov
` (2 preceding siblings ...)
2025-03-14 9:36 ` [PATCH v6 3/4] drm/bridge-connector: hook DisplayPort audio support Dmitry Baryshkov
@ 2025-03-14 9:36 ` Dmitry Baryshkov
2025-04-07 13:09 ` (subset) [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges Dmitry Baryshkov
4 siblings, 0 replies; 13+ messages in thread
From: Dmitry Baryshkov @ 2025-03-14 9:36 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
Abhinav Kumar, Sean Paul, Marijn Suijten, Hermes Wu,
Dmitry Baryshkov
Cc: dri-devel, linux-kernel, linux-arm-msm, freedreno,
Dmitry Baryshkov
From: Dmitry Baryshkov <lumag@kernel.org>
The MSM DisplayPort driver implements several HDMI codec functions
in the driver, e.g. it manually manages HDMI codec device registration,
returning ELD and plugged_cb support. In order to reduce code
duplication reuse drm_hdmi_audio_* helpers and drm_bridge_connector
integration.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/Kconfig | 1 +
drivers/gpu/drm/msm/dp/dp_audio.c | 131 ++++--------------------------------
drivers/gpu/drm/msm/dp/dp_audio.h | 27 ++------
drivers/gpu/drm/msm/dp/dp_display.c | 28 ++------
drivers/gpu/drm/msm/dp/dp_display.h | 6 --
drivers/gpu/drm/msm/dp/dp_drm.c | 8 +++
6 files changed, 31 insertions(+), 170 deletions(-)
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 974bc7c0ea761147d3326bdce9039d6f26f290d0..7f127e2ae44292f8f5c7ff6a9251c3d7ec8c9f58 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -104,6 +104,7 @@ config DRM_MSM_DPU
config DRM_MSM_DP
bool "Enable DisplayPort support in MSM DRM driver"
depends on DRM_MSM
+ select DRM_DISPLAY_HDMI_AUDIO_HELPER
select RATIONAL
default y
help
diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
index 70fdc9fe228a7149546accd8479a9e4397f3d5dd..f8bfb908f9b4bf93ad5480f0785e3aed23dde160 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -13,13 +13,13 @@
#include "dp_catalog.h"
#include "dp_audio.h"
+#include "dp_drm.h"
#include "dp_panel.h"
#include "dp_reg.h"
#include "dp_display.h"
#include "dp_utils.h"
struct msm_dp_audio_private {
- struct platform_device *audio_pdev;
struct platform_device *pdev;
struct drm_device *drm_dev;
struct msm_dp_catalog *catalog;
@@ -160,24 +160,11 @@ static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable)
msm_dp_catalog_audio_enable(catalog, enable);
}
-static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev)
+static struct msm_dp_audio_private *msm_dp_audio_get_data(struct msm_dp *msm_dp_display)
{
struct msm_dp_audio *msm_dp_audio;
- struct msm_dp *msm_dp_display;
-
- if (!pdev) {
- DRM_ERROR("invalid input\n");
- return ERR_PTR(-ENODEV);
- }
-
- msm_dp_display = platform_get_drvdata(pdev);
- if (!msm_dp_display) {
- DRM_ERROR("invalid input\n");
- return ERR_PTR(-ENODEV);
- }
msm_dp_audio = msm_dp_display->msm_dp_audio;
-
if (!msm_dp_audio) {
DRM_ERROR("invalid msm_dp_audio data\n");
return ERR_PTR(-EINVAL);
@@ -186,68 +173,16 @@ static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device
return container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
}
-static int msm_dp_audio_hook_plugged_cb(struct device *dev, void *data,
- hdmi_codec_plugged_cb fn,
- struct device *codec_dev)
-{
-
- struct platform_device *pdev;
- struct msm_dp *msm_dp_display;
-
- pdev = to_platform_device(dev);
- if (!pdev) {
- pr_err("invalid input\n");
- return -ENODEV;
- }
-
- msm_dp_display = platform_get_drvdata(pdev);
- if (!msm_dp_display) {
- pr_err("invalid input\n");
- return -ENODEV;
- }
-
- return msm_dp_display_set_plugged_cb(msm_dp_display, fn, codec_dev);
-}
-
-static int msm_dp_audio_get_eld(struct device *dev,
- void *data, uint8_t *buf, size_t len)
-{
- struct platform_device *pdev;
- struct msm_dp *msm_dp_display;
-
- pdev = to_platform_device(dev);
-
- if (!pdev) {
- DRM_ERROR("invalid input\n");
- return -ENODEV;
- }
-
- msm_dp_display = platform_get_drvdata(pdev);
- if (!msm_dp_display) {
- DRM_ERROR("invalid input\n");
- return -ENODEV;
- }
-
- mutex_lock(&msm_dp_display->connector->eld_mutex);
- memcpy(buf, msm_dp_display->connector->eld,
- min(sizeof(msm_dp_display->connector->eld), len));
- mutex_unlock(&msm_dp_display->connector->eld_mutex);
-
- return 0;
-}
-
-int msm_dp_audio_hw_params(struct device *dev,
- void *data,
- struct hdmi_codec_daifmt *daifmt,
- struct hdmi_codec_params *params)
+int msm_dp_audio_prepare(struct drm_connector *connector,
+ struct drm_bridge *bridge,
+ struct hdmi_codec_daifmt *daifmt,
+ struct hdmi_codec_params *params)
{
int rc = 0;
struct msm_dp_audio_private *audio;
- struct platform_device *pdev;
struct msm_dp *msm_dp_display;
- pdev = to_platform_device(dev);
- msm_dp_display = platform_get_drvdata(pdev);
+ msm_dp_display = to_dp_bridge(bridge)->msm_dp_display;
/*
* there could be cases where sound card can be opened even
@@ -262,7 +197,7 @@ int msm_dp_audio_hw_params(struct device *dev,
goto end;
}
- audio = msm_dp_audio_get_data(pdev);
+ audio = msm_dp_audio_get_data(msm_dp_display);
if (IS_ERR(audio)) {
rc = PTR_ERR(audio);
goto end;
@@ -281,15 +216,14 @@ int msm_dp_audio_hw_params(struct device *dev,
return rc;
}
-static void msm_dp_audio_shutdown(struct device *dev, void *data)
+void msm_dp_audio_shutdown(struct drm_connector *connector,
+ struct drm_bridge *bridge)
{
struct msm_dp_audio_private *audio;
- struct platform_device *pdev;
struct msm_dp *msm_dp_display;
- pdev = to_platform_device(dev);
- msm_dp_display = platform_get_drvdata(pdev);
- audio = msm_dp_audio_get_data(pdev);
+ msm_dp_display = to_dp_bridge(bridge)->msm_dp_display;
+ audio = msm_dp_audio_get_data(msm_dp_display);
if (IS_ERR(audio)) {
DRM_ERROR("failed to get audio data\n");
return;
@@ -311,47 +245,6 @@ static void msm_dp_audio_shutdown(struct device *dev, void *data)
msm_dp_display_signal_audio_complete(msm_dp_display);
}
-static const struct hdmi_codec_ops msm_dp_audio_codec_ops = {
- .hw_params = msm_dp_audio_hw_params,
- .audio_shutdown = msm_dp_audio_shutdown,
- .get_eld = msm_dp_audio_get_eld,
- .hook_plugged_cb = msm_dp_audio_hook_plugged_cb,
-};
-
-static struct hdmi_codec_pdata codec_data = {
- .ops = &msm_dp_audio_codec_ops,
- .max_i2s_channels = 8,
- .i2s = 1,
-};
-
-void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio)
-{
- struct msm_dp_audio_private *audio_priv;
-
- audio_priv = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
-
- if (audio_priv->audio_pdev) {
- platform_device_unregister(audio_priv->audio_pdev);
- audio_priv->audio_pdev = NULL;
- }
-}
-
-int msm_dp_register_audio_driver(struct device *dev,
- struct msm_dp_audio *msm_dp_audio)
-{
- struct msm_dp_audio_private *audio_priv;
-
- audio_priv = container_of(msm_dp_audio,
- struct msm_dp_audio_private, msm_dp_audio);
-
- audio_priv->audio_pdev = platform_device_register_data(dev,
- HDMI_CODEC_DRV_NAME,
- PLATFORM_DEVID_AUTO,
- &codec_data,
- sizeof(codec_data));
- return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
-}
-
struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
struct msm_dp_catalog *catalog)
{
diff --git a/drivers/gpu/drm/msm/dp/dp_audio.h b/drivers/gpu/drm/msm/dp/dp_audio.h
index beea34cbab77f31b33873297dc454a9cee446240..58fc14693e48bff2b57ef7278983e5f21ee80ac7 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.h
+++ b/drivers/gpu/drm/msm/dp/dp_audio.h
@@ -35,23 +35,6 @@ struct msm_dp_audio {
struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
struct msm_dp_catalog *catalog);
-/**
- * msm_dp_register_audio_driver()
- *
- * Registers DP device with hdmi_codec interface.
- *
- * @dev: DP device instance.
- * @msm_dp_audio: an instance of msm_dp_audio module.
- *
- *
- * Returns the error code in case of failure, otherwise
- * zero on success.
- */
-int msm_dp_register_audio_driver(struct device *dev,
- struct msm_dp_audio *msm_dp_audio);
-
-void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio);
-
/**
* msm_dp_audio_put()
*
@@ -61,10 +44,12 @@ void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm
*/
void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio);
-int msm_dp_audio_hw_params(struct device *dev,
- void *data,
- struct hdmi_codec_daifmt *daifmt,
- struct hdmi_codec_params *params);
+int msm_dp_audio_prepare(struct drm_connector *connector,
+ struct drm_bridge *bridge,
+ struct hdmi_codec_daifmt *daifmt,
+ struct hdmi_codec_params *params);
+void msm_dp_audio_shutdown(struct drm_connector *connector,
+ struct drm_bridge *bridge);
#endif /* _DP_AUDIO_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index bbc47d86ae9e67245c87a8365df366cce0dc529e..ece184d20c0f8bffa3c2a48216015185d6cbc99e 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -13,6 +13,7 @@
#include <linux/delay.h>
#include <linux/string_choices.h>
#include <drm/display/drm_dp_aux_bus.h>
+#include <drm/display/drm_hdmi_audio_helper.h>
#include <drm/drm_edid.h>
#include "msm_drv.h"
@@ -288,13 +289,6 @@ static int msm_dp_display_bind(struct device *dev, struct device *master,
goto end;
}
-
- rc = msm_dp_register_audio_driver(dev, dp->audio);
- if (rc) {
- DRM_ERROR("Audio registration Dp failed\n");
- goto end;
- }
-
rc = msm_dp_hpd_event_thread_start(dp);
if (rc) {
DRM_ERROR("Event thread create failed\n");
@@ -316,7 +310,6 @@ static void msm_dp_display_unbind(struct device *dev, struct device *master,
of_dp_aux_depopulate_bus(dp->aux);
- msm_dp_unregister_audio_driver(dev, dp->audio);
msm_dp_aux_unregister(dp->aux);
dp->drm_dev = NULL;
dp->aux->drm_dev = NULL;
@@ -626,9 +619,9 @@ static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
struct msm_dp_display_private, msm_dp_display);
/* notify audio subsystem only if sink supports audio */
- if (msm_dp_display->plugged_cb && msm_dp_display->codec_dev &&
- dp->audio_supported)
- msm_dp_display->plugged_cb(msm_dp_display->codec_dev, plugged);
+ if (dp->audio_supported)
+ drm_connector_hdmi_audio_plugged_notify(msm_dp_display->connector,
+ plugged);
}
static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
@@ -907,19 +900,6 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp)
return 0;
}
-int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
- hdmi_codec_plugged_cb fn, struct device *codec_dev)
-{
- bool plugged;
-
- msm_dp_display->plugged_cb = fn;
- msm_dp_display->codec_dev = codec_dev;
- plugged = msm_dp_display->link_ready;
- msm_dp_display_handle_plugged_change(msm_dp_display, plugged);
-
- return 0;
-}
-
/**
* msm_dp_bridge_mode_valid - callback to determine if specified mode is valid
* @bridge: Pointer to drm bridge structure
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index ecbc2d92f546a346ee53adcf1b060933e4f54317..cc6e2cab36e9c0b1527ff292e547cbb4d69fd95c 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -7,7 +7,6 @@
#define _DP_DISPLAY_H_
#include "dp_panel.h"
-#include <sound/hdmi-codec.h>
#include "disp/msm_disp_snapshot.h"
#define DP_MAX_PIXEL_CLK_KHZ 675000
@@ -15,7 +14,6 @@
struct msm_dp {
struct drm_device *drm_dev;
struct platform_device *pdev;
- struct device *codec_dev;
struct drm_connector *connector;
struct drm_bridge *next_bridge;
bool link_ready;
@@ -25,14 +23,10 @@ struct msm_dp {
bool is_edp;
bool internal_hpd;
- hdmi_codec_plugged_cb plugged_cb;
-
struct msm_dp_audio *msm_dp_audio;
bool psr_supported;
};
-int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
- hdmi_codec_plugged_cb fn, struct device *codec_dev);
int msm_dp_display_get_modes(struct msm_dp *msm_dp_display);
bool msm_dp_display_check_video_test(struct msm_dp *msm_dp_display);
int msm_dp_display_get_test_bpp(struct msm_dp *msm_dp_display);
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index cca57e56c906255a315e759e85a5af5982c80e9c..838bc7d052c5cfa31572f7e23a6b1d09c4c63b5f 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -12,6 +12,7 @@
#include "msm_drv.h"
#include "msm_kms.h"
+#include "dp_audio.h"
#include "dp_drm.h"
/**
@@ -114,6 +115,9 @@ static const struct drm_bridge_funcs msm_dp_bridge_ops = {
.hpd_disable = msm_dp_bridge_hpd_disable,
.hpd_notify = msm_dp_bridge_hpd_notify,
.debugfs_init = msm_dp_bridge_debugfs_init,
+
+ .dp_audio_prepare = msm_dp_audio_prepare,
+ .dp_audio_shutdown = msm_dp_audio_shutdown,
};
static int msm_edp_bridge_atomic_check(struct drm_bridge *drm_bridge,
@@ -320,9 +324,13 @@ int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
*/
if (!msm_dp_display->is_edp) {
bridge->ops =
+ DRM_BRIDGE_OP_DP_AUDIO |
DRM_BRIDGE_OP_DETECT |
DRM_BRIDGE_OP_HPD |
DRM_BRIDGE_OP_MODES;
+ bridge->hdmi_audio_dev = &msm_dp_display->pdev->dev;
+ bridge->hdmi_audio_max_i2s_playback_channels = 8;
+ bridge->hdmi_audio_dai_port = -1;
}
rc = devm_drm_bridge_add(dev->dev, bridge);
--
2.39.5
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: (subset) [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges
2025-03-14 9:36 [PATCH v6 0/4] drm/bridge: reuse DRM HDMI Audio helpers for DisplayPort bridges Dmitry Baryshkov
` (3 preceding siblings ...)
2025-03-14 9:36 ` [PATCH v6 4/4] drm/msm/dp: reuse generic HDMI codec implementation Dmitry Baryshkov
@ 2025-04-07 13:09 ` Dmitry Baryshkov
4 siblings, 0 replies; 13+ messages in thread
From: Dmitry Baryshkov @ 2025-04-07 13:09 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
Abhinav Kumar, Sean Paul, Marijn Suijten, Hermes Wu,
Dmitry Baryshkov, Dmitry Baryshkov
Cc: dri-devel, linux-kernel, linux-arm-msm, freedreno,
Dmitry Baryshkov
On Fri, 14 Mar 2025 11:36:47 +0200, Dmitry Baryshkov wrote:
> A lot of DisplayPort bridges use HDMI Codec in order to provide audio
> support. Present DRM HDMI Audio support has been written with the HDMI
> and in particular DRM HDMI Connector framework support, however those
> audio helpers can be easily reused for DisplayPort drivers too.
>
> Patches by Hermes Wu that targeted implementing HDMI Audio support in
> the iTE IT6506 driver pointed out the necessity of allowing one to use
> generic audio helpers for DisplayPort drivers, as otherwise each driver
> has to manually (and correctly) implement the get_eld() and plugged_cb
> support.
>
> [...]
Applied to drm-misc-next, thanks!
[1/4] drm/bridge: split HDMI Audio from DRM_BRIDGE_OP_HDMI
commit: 5d04b41889596adab613b0e2f27f76f6414cda66
[2/4] drm/bridge: add function interface for DisplayPort audio implementation
commit: d87ecc232706ace682a900a45018d843f148da56
[3/4] drm/bridge-connector: hook DisplayPort audio support
commit: 231adeda9f674ece664b09b75b68a4c023180fb4
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 13+ messages in thread