public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms
@ 2026-03-26 17:31 Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 01/10] drm/bridge: synopsys: dw-dp: Simplify driver data setting Sebastian Reichel
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

This patch series updates the Synopsys Designware DisplayPort bridge
together with the only existing user: The Rockchip RK3576/RK3588:

 1. follow-up bridges (PHY, USB-C connector)
    this is needed to get USB-C DP AltMode working; I've followed the
    Qualcomm driver as reference

 2. runtime PM
    the initial driver has been upstreamed without RPM; add it to
    avoid wasting power when nothing is plugged

 3. audio
    the initial driver has been upstreamed without audio support;
    this adds all missing bits for audio with single stream transport

The series is based on drm-misc-next with Cristian's cleanup series
applied as I expect that to land first:

https://lore.kernel.org/linux-rockchip/20260310-drm-rk-fixes-v2-0-645ecfb43f49@collabora.com/

To properly make use of the bridge code the following USBDP PHY series
is also needed:

https://lore.kernel.org/linux-rockchip/20260313-rockchip-usbdp-cleanup-v3-0-3e8fe89a35b5@collabora.com/

There are two parts, which possibly need some discussion:

 1. I added a dedicated bridge callback for out-of-band hotplug events,
    which is separate from the hotplug_notify. I have a feeling, that
    there might be a better solution, but haven't found it.

 2. The DT binding for audio support - explicitly marked as RFC - works
    perfectly fine, but is not ready for MST. I don't intend to
    implement that right now, but the binding should obviously take it
    into consideration to avoid breaking it in the future. I've put
    some points for discussion into the relevant patch.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
Sebastian Reichel (10):
      drm/bridge: synopsys: dw-dp: Simplify driver data setting
      drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED
      drm/bridge: synopsys: dw-dp: Add follow-up bridge support
      drm/bridge: Add out-of-band HPD notify handler
      drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD
      drm/rockchip: dw_dp: Implement out-of-band HPD handling
      drm/bridge: synopsys: dw-dp: Add Runtime PM support
      drm/rockchip: dw_dp: Add runtime PM support
      [RFC] dt-bindings: display: rockchip: dw-dp: fix sound DAI cells
      drm/bridge: synopsys: dw-dp: Add audio support

 .../bindings/display/rockchip/rockchip,dw-dp.yaml  |   5 +-
 drivers/gpu/drm/bridge/synopsys/dw-dp.c            | 284 ++++++++++++++++++++-
 drivers/gpu/drm/display/drm_bridge_connector.c     |   6 +
 drivers/gpu/drm/rockchip/dw_dp-rockchip.c          | 167 +++++++++++-
 include/drm/bridge/dw_dp.h                         |   6 +
 include/drm/drm_bridge.h                           |  14 +
 6 files changed, 469 insertions(+), 13 deletions(-)
---
base-commit: 0660ee19141e5e90b422b7daa0d8518a8d0d898b
change-id: 20260325-synopsys-dw-dp-improvements-7da2e98df1dd

Best regards,
-- 
Sebastian Reichel <sebastian.reichel@collabora.com>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 01/10] drm/bridge: synopsys: dw-dp: Simplify driver data setting
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 02/10] drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED Sebastian Reichel
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

There is no need to get the platform device just for setting up
the driver data. Simplify the logic.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
index 22c0911f1896..dd8db923d6d7 100644
--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
@@ -74,7 +74,6 @@ static const struct drm_encoder_helper_funcs dw_dp_encoder_helper_funcs = {
 
 static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *data)
 {
-	struct platform_device *pdev = to_platform_device(dev);
 	const struct dw_dp_plat_data *plat_data;
 	struct drm_device *drm_dev = data;
 	struct rockchip_dw_dp *dp;
@@ -87,7 +86,7 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *
 		return -ENOMEM;
 
 	dp->dev = dev;
-	platform_set_drvdata(pdev, dp);
+	dev_set_drvdata(dev, dp);
 
 	plat_data = of_device_get_match_data(dev);
 	if (!plat_data)

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 02/10] drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 01/10] drm/bridge: synopsys: dw-dp: Simplify driver data setting Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 03/10] drm/bridge: synopsys: dw-dp: Add follow-up bridge support Sebastian Reichel
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

Add support for MEDIA_BUS_FMT_FIXED, which is e.g. requested for USB-C
DP chains as the last bridge in the chain (aux-hpd-bridge) does not
implement atomic_get_output_bus_fmts(), which results in the generic
drm_atomic_bridge_chain_select_bus_fmts() code using MEDIA_BUS_FMT_FIXED
instead.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index 8f2739fa189e..222862d962d9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -1528,6 +1528,7 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge,
 				     struct drm_connector_state *conn_state)
 {
 	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+	unsigned int out_bus_format = bridge_state->output_bus_cfg.format;
 	struct dw_dp *dp = bridge_to_dp(bridge);
 	struct dw_dp_bridge_state *state;
 	const struct dw_dp_output_format *fmt;
@@ -1538,7 +1539,10 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge,
 	state = to_dw_dp_bridge_state(bridge_state);
 	mode = &state->mode;
 
-	fmt = dw_dp_get_output_format(bridge_state->output_bus_cfg.format);
+	if (out_bus_format == MEDIA_BUS_FMT_FIXED)
+		out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+
+	fmt = dw_dp_get_output_format(out_bus_format);
 	if (!fmt)
 		return -EINVAL;
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 03/10] drm/bridge: synopsys: dw-dp: Add follow-up bridge support
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 01/10] drm/bridge: synopsys: dw-dp: Simplify driver data setting Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 02/10] drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 04/10] drm/bridge: Add out-of-band HPD notify handler Sebastian Reichel
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

Add support to use USB-C connectors with the DP altmode helper code on
devicetree based platforms. To get this working there must be a DRM
bridge chain from the DisplayPort controller to the USB-C connector.
E.g. on Rockchip RK3576:

root@rk3576 # cat /sys/kernel/debug/dri/0/encoder-0/bridges
bridge[0]: dw_dp_bridge_funcs
        refcount: 7
        type: [10] DP
        OF: /soc/dp@27e40000:rockchip,rk3576-dp
        ops: [0x47] detect edid hpd
bridge[1]: drm_aux_bridge_funcs
        refcount: 4
        type: [0] Unknown
        OF: /soc/phy@2b010000:rockchip,rk3576-usbdp-phy
        ops: [0x0]
bridge[2]: drm_aux_hpd_bridge_funcs
        refcount: 5
        type: [10] DP
        OF: /soc/i2c@2ac50000/typec-portc@22/connector:usb-c-connector
        ops: [0x4] hpd

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index 222862d962d9..c3a108f1faa9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -1978,7 +1978,7 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dw_dp *dp;
-	struct drm_bridge *bridge;
+	struct drm_bridge *bridge, *next_bridge;
 	void __iomem *res;
 	int ret;
 
@@ -2072,6 +2072,20 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 		goto unregister_aux;
 	}
 
+	next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(next_bridge)) {
+		ret = PTR_ERR(next_bridge);
+		dev_err_probe(dev, ret, "failed to get follow-up bridge.\n");
+		goto unregister_aux;
+	}
+
+	ret = drm_bridge_attach(encoder, next_bridge, bridge,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret) {
+		dev_err_probe(dev, ret, "Failed to attach next bridge\n");
+		goto unregister_aux;
+	}
+
 	dw_dp_init_hw(dp);
 
 	ret = phy_init(dp->phy);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 04/10] drm/bridge: Add out-of-band HPD notify handler
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (2 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH 03/10] drm/bridge: synopsys: dw-dp: Add follow-up bridge support Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 05/10] drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD Sebastian Reichel
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

For DP bridges, that can be used for DP AltMode, it might be necessary
to enforce HPD status. There is an existing ->oob_hotplug_event() on
the DRM connector, but it currently just calls into hpd_notify().

As DP bridge drivers usually also implement .detect and that also
generates calls into hpd_notify, this is a bad place to force the
HPD status as the follow-up detect call might force it off again
resulting in all follow-up calls to the detection routine also
failing.

Avoid this by having a dedicated function for OOB events.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/display/drm_bridge_connector.c |  6 ++++++
 include/drm/drm_bridge.h                       | 14 ++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 39cc18f78eda..4333cc66073e 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -180,6 +180,12 @@ static void drm_bridge_connector_oob_hotplug_event(struct drm_connector *connect
 	struct drm_bridge_connector *bridge_connector =
 		to_drm_bridge_connector(connector);
 
+	/* Notify all bridges in the pipeline of hotplug events. */
+	drm_for_each_bridge_in_chain_scoped(bridge_connector->encoder, bridge) {
+		if (bridge->funcs->oob_notify)
+			bridge->funcs->oob_notify(bridge, connector, status);
+	}
+
 	drm_bridge_connector_handle_hpd(bridge_connector, status);
 }
 
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index a8d67bd9ee50..1ad9ae50c829 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -646,6 +646,20 @@ struct drm_bridge_funcs {
 	 */
 	void (*hpd_disable)(struct drm_bridge *bridge);
 
+	/**
+	 * @oob_notify:
+	 *
+	 * Notify the bridge of out of band hot plug detection.
+	 *
+	 * This callback is optional, it may be implemented by bridges that
+	 * need to be notified of display connection or disconnection for
+	 * internal reasons. One use case is to force the DP controllers HPD
+	 * signal for USB-C DP AltMode.
+	 */
+	void (*oob_notify)(struct drm_bridge *bridge,
+			   struct drm_connector *connector,
+			   enum drm_connector_status status);
+
 	/**
 	 * @hdmi_tmds_char_rate_valid:
 	 *

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 05/10] drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (3 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH 04/10] drm/bridge: Add out-of-band HPD notify handler Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 06/10] drm/rockchip: dw_dp: Implement out-of-band HPD handling Sebastian Reichel
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

Add support for USB-C DP AltMode out-of-band hotplug handling. The
handling itself is implemented in the platform specific driver as the
registers to force HPD state are not part of the Designware DisplayPort
IP itself. Instead the platform integration might provide the necessary
functionality to mux the HPD signal.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c | 38 ++++++++++++++++++++++++++++++++-
 include/drm/bridge/dw_dp.h              |  3 +++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index c3a108f1faa9..df2d629287fd 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -1824,6 +1824,19 @@ static struct drm_bridge_state *dw_dp_bridge_atomic_duplicate_state(struct drm_b
 	return &state->base;
 }
 
+static void dw_dp_bridge_oob_notify(struct drm_bridge *bridge,
+				    struct drm_connector *connector,
+				    enum drm_connector_status status)
+{
+	bool hpd_high = status != connector_status_disconnected;
+	struct dw_dp *dp = bridge_to_dp(bridge);
+
+	if (dp->plat_data.hpd_sw_cfg)
+		dp->plat_data.hpd_sw_cfg(dp->plat_data.data, hpd_high);
+	else
+		dev_err_once(dp->dev, "Missing platform handler for OOB HPD handling\n");
+}
+
 static const struct drm_bridge_funcs dw_dp_bridge_funcs = {
 	.atomic_duplicate_state = dw_dp_bridge_atomic_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -1837,6 +1850,7 @@ static const struct drm_bridge_funcs dw_dp_bridge_funcs = {
 	.detect = dw_dp_bridge_detect,
 	.edid_read = dw_dp_bridge_edid_read,
 	.detach = dw_dp_bridge_detach,
+	.oob_notify = dw_dp_bridge_oob_notify,
 };
 
 static int dw_dp_link_retrain(struct dw_dp *dp)
@@ -1973,6 +1987,19 @@ static void dw_dp_phy_exit(void *data)
 	phy_exit(dp->phy);
 }
 
+static bool dw_dp_is_routed_to_usb_c(struct drm_encoder *encoder)
+{
+	struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;
+	struct fwnode_handle *fwnode;
+
+	last_bridge = drm_bridge_chain_get_last_bridge(encoder);
+	if (!last_bridge)
+		return false;
+
+	fwnode = of_fwnode_handle(last_bridge->of_node);
+	return fwnode_device_is_compatible(fwnode, "usb-c-connector");
+}
+
 struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 			 const struct dw_dp_plat_data *plat_data)
 {
@@ -1988,7 +2015,9 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 
 	dp->dev = dev;
 	dp->pixel_mode = plat_data->pixel_mode;
-
+	dp->plat_data.hpd_sw_sel = plat_data->hpd_sw_sel;
+	dp->plat_data.hpd_sw_cfg = plat_data->hpd_sw_cfg;
+	dp->plat_data.data = plat_data->data;
 	dp->plat_data.max_link_rate = plat_data->max_link_rate;
 	bridge = &dp->bridge;
 	mutex_init(&dp->irq_lock);
@@ -2086,6 +2115,13 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 		goto unregister_aux;
 	}
 
+	if (dw_dp_is_routed_to_usb_c(encoder)) {
+		dev_dbg(dev, "USB-C mode\n");
+
+		if (dp->plat_data.hpd_sw_sel)
+			dp->plat_data.hpd_sw_sel(dp->plat_data.data, 1);
+	}
+
 	dw_dp_init_hw(dp);
 
 	ret = phy_init(dp->phy);
diff --git a/include/drm/bridge/dw_dp.h b/include/drm/bridge/dw_dp.h
index 25363541e69d..4aacd0e56f50 100644
--- a/include/drm/bridge/dw_dp.h
+++ b/include/drm/bridge/dw_dp.h
@@ -20,6 +20,9 @@ enum {
 struct dw_dp_plat_data {
 	u32 max_link_rate;
 	u8 pixel_mode;
+	void *data;
+	void (*hpd_sw_sel)(void *data, bool hpd);
+	void (*hpd_sw_cfg)(void *data, bool hpd);
 };
 
 struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 06/10] drm/rockchip: dw_dp: Implement out-of-band HPD handling
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (4 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH 05/10] drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 07/10] drm/bridge: synopsys: dw-dp: Add Runtime PM support Sebastian Reichel
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

Implement out-of-band hotplug handling, which will be used to receive
external hotplug information from the USB-C state machine. This is
currently handled by the USBDP PHY, which brings quite some trouble
as the register being accessed requires the power-domain from the DP
controller and also requires custom TypeC HPD info parsing in the
USBDP PHY driver.

In contrast to the USBDP PHY this does not just enable the hotplug
signal when a DP AltMode capable adapter is plugged in, but instead
properly detects if a cable is plugged in for things like USB-C to
HDMI adapters.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 126 ++++++++++++++++++++++++++++--
 1 file changed, 120 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
index dd8db923d6d7..a9845161ced3 100644
--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
@@ -8,9 +8,12 @@
 
 #include <linux/component.h>
 #include <linux/media-bus-format.h>
+#include <linux/hw_bitfield.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
+#include <linux/regmap.h>
 
 #include <drm/bridge/dw_dp.h>
 #include <drm/drm_atomic_helper.h>
@@ -24,12 +27,54 @@
 
 #include "rockchip_drm_drv.h"
 
+#define ROCKCHIP_MAX_CTRLS 2
+
+#define ROCKCHIP_VO_GRF_DP_SINK_HPD_SEL BIT(10)
+#define ROCKCHIP_VO_GRF_DP_SINK_HPD_CFG BIT(11)
+
+struct rockchip_dw_dp_plat_data {
+	u8 num_ctrls;
+	u32 ctrl_ids[ROCKCHIP_MAX_CTRLS];
+	u32 max_link_rate;
+	u8 pixel_mode;
+	u32 hpd_reg[ROCKCHIP_MAX_CTRLS];
+};
+
 struct rockchip_dw_dp {
 	struct dw_dp *base;
 	struct device *dev;
+	const struct rockchip_dw_dp_plat_data *pdata;
+	struct regmap *vo_grf;
 	struct rockchip_encoder encoder;
+	int id;
+	bool hpd_sel;
+	bool hpd_cfg;
 };
 
+static void dw_dp_rockchip_hpd_sw_sel(void *data, bool force_hpd_from_sw)
+{
+	struct rockchip_dw_dp *dp = data;
+	u32 hpd_reg = dp->pdata->hpd_reg[dp->id];
+
+	dp->hpd_sel = force_hpd_from_sw;
+
+	regmap_write(dp->vo_grf, hpd_reg,
+		     FIELD_PREP_WM16_CONST(ROCKCHIP_VO_GRF_DP_SINK_HPD_SEL, dp->hpd_sel));
+}
+
+static void dw_dp_rockchip_hpd_sw_cfg(void *data, bool hpd)
+{
+	struct rockchip_dw_dp *dp = data;
+	u32 hpd_reg = dp->pdata->hpd_reg[dp->id];
+
+	dev_dbg(dp->dev, "Force HPD connected=%s\n", str_yes_no(hpd));
+
+	dp->hpd_cfg = hpd;
+
+	regmap_write(dp->vo_grf, hpd_reg,
+		     FIELD_PREP_WM16_CONST(ROCKCHIP_VO_GRF_DP_SINK_HPD_CFG, dp->hpd_cfg));
+}
+
 static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder,
 				      struct drm_crtc_state *crtc_state,
 				      struct drm_connector_state *conn_state)
@@ -72,14 +117,49 @@ static const struct drm_encoder_helper_funcs dw_dp_encoder_helper_funcs = {
 	.atomic_check		= dw_dp_encoder_atomic_check,
 };
 
+static struct regmap *dp_dp_rockchip_get_vo_grf(struct rockchip_dw_dp *dp)
+{
+	struct device_node *np = dev_of_node(dp->dev);
+	struct of_phandle_args args;
+	struct regmap *regmap;
+	int ret;
+
+	ret = of_parse_phandle_with_args(np, "phys", "#phy-cells", 0, &args);
+	if (ret)
+		return ERR_PTR(-ENODEV);
+
+	/*
+	 * Limit this workaround to RK3576 and RK3588, new platforms should
+	 * add a VO GRF phandle in the DisplayPort DT node.
+	 */
+	if (!of_device_is_compatible(args.np, "rockchip,rk3576-usbdp-phy") &&
+	    !of_device_is_compatible(args.np, "rockchip,rk3588-usbdp-phy")) {
+		regmap = ERR_PTR(-ENODEV);
+		goto out_put_node;
+	}
+
+	regmap = syscon_regmap_lookup_by_phandle(args.np, "rockchip,vo-grf");
+
+out_put_node:
+	of_node_put(args.np);
+	return regmap;
+}
+
 static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *data)
 {
-	const struct dw_dp_plat_data *plat_data;
+	const struct rockchip_dw_dp_plat_data *plat_data_const;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dp_plat_data *plat_data;
 	struct drm_device *drm_dev = data;
 	struct rockchip_dw_dp *dp;
 	struct drm_encoder *encoder;
 	struct drm_connector *connector;
-	int ret;
+	struct resource *res;
+	int ret, id;
+
+	plat_data = drmm_kzalloc(drm_dev, sizeof(*plat_data), GFP_KERNEL);
+	if (!plat_data)
+		return -ENOMEM;
 
 	dp = drmm_kzalloc(drm_dev, sizeof(*dp), GFP_KERNEL);
 	if (!dp)
@@ -88,10 +168,38 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *
 	dp->dev = dev;
 	dev_set_drvdata(dev, dp);
 
-	plat_data = of_device_get_match_data(dev);
-	if (!plat_data)
+	plat_data_const = device_get_match_data(dev);
+	if (!plat_data_const)
 		return -ENODEV;
 
+	dp->pdata = plat_data_const;
+
+	res = platform_get_mem_or_io(pdev, 0);
+	if (IS_ERR(res))
+		return PTR_ERR(res);
+
+	/* find the DisplayPort ID from the io address */
+	dp->id = -ENODEV;
+	for (id = 0; id < plat_data_const->num_ctrls; id++) {
+		if (res->start == plat_data_const->ctrl_ids[id]) {
+			dp->id = id;
+			break;
+		}
+	}
+
+	if (dp->id < 0)
+		return dp->id;
+
+	dp->vo_grf = dp_dp_rockchip_get_vo_grf(dp);
+	if (IS_ERR(dp->vo_grf))
+		return PTR_ERR(dp->vo_grf);
+
+	plat_data->max_link_rate = plat_data_const->max_link_rate;
+	plat_data->pixel_mode = plat_data_const->pixel_mode;
+	plat_data->hpd_sw_sel = dw_dp_rockchip_hpd_sw_sel;
+	plat_data->hpd_sw_cfg = dw_dp_rockchip_hpd_sw_cfg;
+	plat_data->data = dp;
+
 	encoder = &dp->encoder.encoder;
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, dev->of_node);
 	rockchip_drm_encoder_set_crtc_endpoint_id(&dp->encoder, dev->of_node, 0, 0);
@@ -127,14 +235,20 @@ static void dw_dp_remove(struct platform_device *pdev)
 	component_del(&pdev->dev, &dw_dp_rockchip_component_ops);
 }
 
-static const struct dw_dp_plat_data rk3588_dp_plat_data = {
+static const struct rockchip_dw_dp_plat_data rk3588_dp_plat_data = {
+	.num_ctrls = 2,
+	.ctrl_ids = {0xfde50000, 0xfde60000},
 	.max_link_rate = 810000,
 	.pixel_mode = DW_DP_MP_QUAD_PIXEL,
+	.hpd_reg = {0x0000, 0x0008},
 };
 
-static const struct dw_dp_plat_data rk3576_dp_plat_data = {
+static const struct rockchip_dw_dp_plat_data rk3576_dp_plat_data = {
+	.num_ctrls = 1,
+	.ctrl_ids = {0x27e40000},
 	.max_link_rate = 810000,
 	.pixel_mode = DW_DP_MP_DUAL_PIXEL,
+	.hpd_reg = {0x0000},
 };
 
 static const struct of_device_id dw_dp_of_match[] = {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 07/10] drm/bridge: synopsys: dw-dp: Add Runtime PM support
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (5 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH 06/10] drm/rockchip: dw_dp: Implement out-of-band HPD handling Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 08/10] drm/rockchip: dw_dp: Add runtime " Sebastian Reichel
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

Add runtime PM stubs to the Synopsys DesignWare DisplayPort bridge
driver. Support is not enabled automatically and must be hooked up
in the vendor specific glue code.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c | 27 +++++++++++++++++++++++++++
 include/drm/bridge/dw_dp.h              |  3 +++
 2 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index df2d629287fd..9ee9e3b9d912 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -1465,6 +1465,8 @@ static ssize_t dw_dp_aux_transfer(struct drm_dp_aux *aux,
 	if (WARN_ON(msg->size > 16))
 		return -E2BIG;
 
+	ACQUIRE(pm_runtime_active_auto, pm)(dp->dev);
+
 	switch (msg->request & ~DP_AUX_I2C_MOT) {
 	case DP_AUX_NATIVE_WRITE:
 	case DP_AUX_I2C_WRITE:
@@ -1655,6 +1657,8 @@ static void dw_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 	struct drm_connector_state *conn_state;
 	int ret;
 
+	pm_runtime_get_sync(dp->dev);
+
 	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
 	if (!connector) {
 		dev_err(dp->dev, "failed to get connector\n");
@@ -1709,6 +1713,7 @@ static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 	dw_dp_link_disable(dp);
 	bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
 	dw_dp_reset(dp);
+	pm_runtime_put_autosuspend(dp->dev);
 }
 
 static bool dw_dp_hpd_detect_link(struct dw_dp *dp, struct drm_connector *connector)
@@ -1729,6 +1734,8 @@ static enum drm_connector_status dw_dp_bridge_detect(struct drm_bridge *bridge,
 {
 	struct dw_dp *dp = bridge_to_dp(bridge);
 
+	ACQUIRE(pm_runtime_active_auto, pm)(dp->dev);
+
 	if (!dw_dp_hpd_detect(dp))
 		return connector_status_disconnected;
 
@@ -2155,6 +2162,26 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 }
 EXPORT_SYMBOL_GPL(dw_dp_bind);
 
+int dw_dp_runtime_suspend(struct dw_dp *dp)
+{
+	clk_disable_unprepare(dp->aux_clk);
+	clk_disable_unprepare(dp->apb_clk);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_dp_runtime_suspend);
+
+int dw_dp_runtime_resume(struct dw_dp *dp)
+{
+	clk_prepare_enable(dp->apb_clk);
+	clk_prepare_enable(dp->aux_clk);
+
+	dw_dp_init_hw(dp);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_dp_runtime_resume);
+
 MODULE_AUTHOR("Andy Yan <andyshrk@163.com>");
 MODULE_DESCRIPTION("DW DP Core Library");
 MODULE_LICENSE("GPL");
diff --git a/include/drm/bridge/dw_dp.h b/include/drm/bridge/dw_dp.h
index 4aacd0e56f50..8377f4be8e9e 100644
--- a/include/drm/bridge/dw_dp.h
+++ b/include/drm/bridge/dw_dp.h
@@ -27,4 +27,7 @@ struct dw_dp_plat_data {
 
 struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 			 const struct dw_dp_plat_data *plat_data);
+
+int dw_dp_runtime_suspend(struct dw_dp *dp);
+int dw_dp_runtime_resume(struct dw_dp *dp);
 #endif /* __DW_DP__ */

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 08/10] drm/rockchip: dw_dp: Add runtime PM support
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (6 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH 07/10] drm/bridge: synopsys: dw-dp: Add Runtime PM support Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH RFC 09/10] dt-bindings: display: rockchip: dw-dp: fix sound DAI cells Sebastian Reichel
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

Add support for runtime PM to the Rockchip RK3576/3588 Synopsys
DesignWare DisplayPort driver.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 40 +++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
index a9845161ced3..c371306f7073 100644
--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
@@ -12,6 +12,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/videodev2.h>
 #include <linux/regmap.h>
 
@@ -58,6 +59,8 @@ static void dw_dp_rockchip_hpd_sw_sel(void *data, bool force_hpd_from_sw)
 
 	dp->hpd_sel = force_hpd_from_sw;
 
+	ACQUIRE(pm_runtime_active_auto, pm)(dp->dev);
+
 	regmap_write(dp->vo_grf, hpd_reg,
 		     FIELD_PREP_WM16_CONST(ROCKCHIP_VO_GRF_DP_SINK_HPD_SEL, dp->hpd_sel));
 }
@@ -71,6 +74,8 @@ static void dw_dp_rockchip_hpd_sw_cfg(void *data, bool hpd)
 
 	dp->hpd_cfg = hpd;
 
+	ACQUIRE(pm_runtime_active_auto, pm)(dp->dev);
+
 	regmap_write(dp->vo_grf, hpd_reg,
 		     FIELD_PREP_WM16_CONST(ROCKCHIP_VO_GRF_DP_SINK_HPD_CFG, dp->hpd_cfg));
 }
@@ -213,6 +218,12 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *
 	if (IS_ERR(dp->base))
 		return PTR_ERR(dp->base);
 
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_set_autosuspend_delay(dev, 500);
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to enable runtime PM\n");
+
 	connector = drm_bridge_connector_init(drm_dev, encoder);
 	if (IS_ERR(connector))
 		return dev_err_probe(dev, PTR_ERR(connector),
@@ -235,6 +246,34 @@ static void dw_dp_remove(struct platform_device *pdev)
 	component_del(&pdev->dev, &dw_dp_rockchip_component_ops);
 }
 
+static int dw_dp_rockchip_runtime_suspend(struct device *dev)
+{
+	struct rockchip_dw_dp *dp = dev_get_drvdata(dev);
+
+	return dw_dp_runtime_suspend(dp->base);
+}
+
+static int dw_dp_rockchip_runtime_resume(struct device *dev)
+{
+	struct rockchip_dw_dp *dp = dev_get_drvdata(dev);
+	u32 hpd_reg = dp->pdata->hpd_reg[dp->id];
+	int ret;
+
+	ret = dw_dp_runtime_resume(dp->base);
+	if (ret)
+		return ret;
+
+	regmap_write(dp->vo_grf, hpd_reg,
+		     FIELD_PREP_WM16_CONST(ROCKCHIP_VO_GRF_DP_SINK_HPD_SEL, dp->hpd_sel) |
+		     FIELD_PREP_WM16_CONST(ROCKCHIP_VO_GRF_DP_SINK_HPD_CFG, dp->hpd_cfg));
+
+	return 0;
+}
+
+static const struct dev_pm_ops dw_dp_pm_ops = {
+	RUNTIME_PM_OPS(dw_dp_rockchip_runtime_suspend, dw_dp_rockchip_runtime_resume, NULL)
+};
+
 static const struct rockchip_dw_dp_plat_data rk3588_dp_plat_data = {
 	.num_ctrls = 2,
 	.ctrl_ids = {0xfde50000, 0xfde60000},
@@ -269,5 +308,6 @@ struct platform_driver dw_dp_driver = {
 	.driver = {
 		.name = "dw-dp",
 		.of_match_table = dw_dp_of_match,
+		.pm = pm_ptr(&dw_dp_pm_ops),
 	},
 };

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH RFC 09/10] dt-bindings: display: rockchip: dw-dp: fix sound DAI cells
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (7 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH 08/10] drm/rockchip: dw_dp: Add runtime " Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-26 17:31 ` [PATCH 10/10] drm/bridge: synopsys: dw-dp: Add audio support Sebastian Reichel
  2026-03-30  1:34 ` [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Chaoyi Chen
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

The RK3588 and RK3576 DesignWare DisplayPort controllers both have two
possible DAI interfaces: I2S and S/PDIF. Thus it is needed to have an
argument to select the right interface.

In case of RK3576 this is not enough though. The RK3576 has the same IP
as RK3588, but configured with Multi Stream Transport (MST) enabled for
up to 3 displays and thus has a total of 6 DAI interfaces (I2S and
S/PDIF for each possible stream. Meanwhile the RK3588 does not support
MST and thus has only 2 DAI interfaces.

The binding update right now only supports the simple single stream
transport (SST) setup. To avoid further DT ABI breakage (or complicated
bindings supporting different number of arguments), it's probably a good
idea to take MST into account now even though the upstream Linux driver
does not yet support it.

I see two options:

1. Adding yet another cell, so that we have the following:
   <&dp_ctrl [display_stream] [i2s_or_spdif]>; potentially append
   extra input ports for MST video data to existing ports node
   (e.g. port@2). I would only handle the sound DAI part in my
   patch and basically use '0' for the display stream and just
   leave the option of using '1' or '2' once MST support is added.

2. The vendor kernel creates a sub-node for each supported display
   stream and puts the ports mapping as well as the DAI reference
   into that. This bundles all information for one display stream
   together, which creates a clean look but the subnode does not
   really describe any real thing in the hardware.

As upstream MST support seems to be quite limited, I wish for some
feedback about the preferred way to handle this.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml         | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml
index 2b0d9e23e943..1303d0e2145a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml
@@ -83,7 +83,8 @@ properties:
     maxItems: 1
 
   "#sound-dai-cells":
-    const: 0
+    const: 1
+    description: 0 for I2S, 1 for SPDIF
 
 required:
   - compatible
@@ -144,7 +145,7 @@ examples:
         resets = <&cru SRST_DP0>;
         phys = <&usbdp_phy0 PHY_TYPE_DP>;
         power-domains = <&power RK3588_PD_VO0>;
-        #sound-dai-cells = <0>;
+        #sound-dai-cells = <1>;
 
         ports {
           #address-cells = <1>;

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 10/10] drm/bridge: synopsys: dw-dp: Add audio support
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (8 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH RFC 09/10] dt-bindings: display: rockchip: dw-dp: fix sound DAI cells Sebastian Reichel
@ 2026-03-26 17:31 ` Sebastian Reichel
  2026-03-30  1:34 ` [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Chaoyi Chen
  10 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-26 17:31 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel,
	Sebastian Reichel

Implement audio support for the Synopsys DesignWare DisplayPort
controller.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c | 197 +++++++++++++++++++++++++++++++-
 1 file changed, 196 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index 9ee9e3b9d912..add22acea719 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -23,17 +23,21 @@
 #include <drm/drm_bridge.h>
 #include <drm/drm_bridge_connector.h>
 #include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_hdmi_audio_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
 
+#include <sound/hdmi-codec.h>
+
 #define DW_DP_VERSION_NUMBER			0x0000
 #define DW_DP_VERSION_TYPE			0x0004
 #define DW_DP_ID				0x0008
 
 #define DW_DP_CONFIG_REG1			0x0100
+#define AUDIO_SELECT				GENMASK(2, 1)
 #define DW_DP_CONFIG_REG2			0x0104
 #define DW_DP_CONFIG_REG3			0x0108
 
@@ -110,6 +114,10 @@
 #define HBR_MODE_ENABLE				BIT(10)
 #define AUDIO_DATA_WIDTH			GENMASK(9, 5)
 #define AUDIO_DATA_IN_EN			GENMASK(4, 1)
+#define AUDIO_DATA_IN_EN_CHANNEL12		BIT(0)
+#define AUDIO_DATA_IN_EN_CHANNEL34		BIT(1)
+#define AUDIO_DATA_IN_EN_CHANNEL56		BIT(2)
+#define AUDIO_DATA_IN_EN_CHANNEL78		BIT(3)
 #define AUDIO_INF_SELECT			BIT(0)
 
 #define DW_DP_SDP_VERTICAL_CTRL			0x0500
@@ -253,6 +261,8 @@
 
 #define SDP_REG_BANK_SIZE			16
 
+#define DW_DP_SDP_VERSION			0x12
+
 struct dw_dp_link_caps {
 	bool enhanced_framing;
 	bool tps3_supported;
@@ -305,6 +315,19 @@ struct dw_dp_hotplug {
 	bool long_hpd;
 };
 
+enum dw_dp_audio_interface_support {
+	DW_DP_AUDIO_I2S_ONLY = 0,
+	DW_DP_AUDIO_SPDIF_ONLY = 1,
+	DW_DP_AUDIO_I2S_AND_SPDIF = 2,
+	DW_DP_AUDIO_NONE = 3,
+};
+
+enum dw_dp_audio_interface {
+	DW_DP_AUDIO_I2S = 0,
+	DW_DP_AUDIO_SPDIF = 1,
+	DW_DP_AUDIO_UNUSED,
+};
+
 struct dw_dp {
 	struct drm_bridge bridge;
 	struct device *dev;
@@ -320,6 +343,8 @@ struct dw_dp {
 	int irq;
 	struct work_struct hpd_work;
 	struct dw_dp_hotplug hotplug;
+	enum dw_dp_audio_interface audio_interface;
+	int audio_channels;
 	/* Serialize hpd status access */
 	struct mutex irq_lock;
 
@@ -1844,6 +1869,163 @@ static void dw_dp_bridge_oob_notify(struct drm_bridge *bridge,
 		dev_err_once(dp->dev, "Missing platform handler for OOB HPD handling\n");
 }
 
+static int dw_dp_audio_infoframe_send(struct dw_dp *dp)
+{
+	struct hdmi_audio_infoframe frame;
+	struct dw_dp_sdp sdp;
+	int ret;
+
+	ret = hdmi_audio_infoframe_init(&frame);
+	if (ret < 0)
+		return ret;
+
+	frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
+	frame.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
+	frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
+	frame.channels = dp->audio_channels;
+
+	ret = hdmi_audio_infoframe_pack_for_dp(&frame, &sdp.base, DW_DP_SDP_VERSION);
+	if (ret < 0)
+		return ret;
+
+	sdp.flags = DW_DP_SDP_VERTICAL_INTERVAL;
+
+	return dw_dp_send_sdp(dp, &sdp);
+}
+
+static int dw_dp_audio_prepare(struct drm_bridge *bridge,
+			       struct drm_connector *connector,
+			       struct hdmi_codec_daifmt *daifmt,
+			       struct hdmi_codec_params *params)
+{
+	struct dw_dp *dp = bridge_to_dp(bridge);
+	u8 audio_data_in_en, supported_audio_interfaces;
+	u32 cfg1;
+	int ret;
+
+	pm_runtime_get_sync(dp->dev);
+
+	dp->audio_channels = params->cea.channels;
+	switch (params->cea.channels) {
+	case 1:
+	case 2:
+		audio_data_in_en = AUDIO_DATA_IN_EN_CHANNEL12;
+		break;
+	case 8:
+		audio_data_in_en = AUDIO_DATA_IN_EN_CHANNEL12 |
+				   AUDIO_DATA_IN_EN_CHANNEL34 |
+				   AUDIO_DATA_IN_EN_CHANNEL56 |
+				   AUDIO_DATA_IN_EN_CHANNEL78;
+		break;
+	default:
+		dev_err(dp->dev, "invalid audio channels %d\n", dp->audio_channels);
+		return -EINVAL;
+	}
+
+	switch (daifmt->fmt) {
+	case HDMI_SPDIF:
+		dp->audio_interface = DW_DP_AUDIO_SPDIF;
+		break;
+	case HDMI_I2S:
+		/*
+		 * It is recommended to use SPDIF instead of I2S, since I2S mode requires
+		 * manually inserting PCUV control bits from userspace and this is done
+		 * automatically in hardware for SPDIF mode.
+		 */
+		dp->audio_interface = DW_DP_AUDIO_I2S;
+		break;
+	default:
+		dev_err(dp->dev, "invalid DAI format %d\n", daifmt->fmt);
+		return -EINVAL;
+	}
+
+	regmap_read(dp->regmap, DW_DP_CONFIG_REG1, &cfg1);
+	supported_audio_interfaces = FIELD_GET(AUDIO_SELECT, cfg1);
+
+	if (supported_audio_interfaces != DW_DP_AUDIO_I2S_AND_SPDIF &&
+	    supported_audio_interfaces != dp->audio_interface) {
+		dev_err(dp->dev, "unsupported DAI %d\n", daifmt->fmt);
+		return -EINVAL;
+	}
+
+	clk_prepare_enable(dp->spdif_clk);
+	clk_prepare_enable(dp->i2s_clk);
+
+	regmap_update_bits(dp->regmap, DW_DP_AUD_CONFIG1,
+			   AUDIO_DATA_IN_EN | NUM_CHANNELS | AUDIO_DATA_WIDTH |
+			   AUDIO_INF_SELECT | HBR_MODE_ENABLE,
+			   FIELD_PREP(AUDIO_DATA_IN_EN, audio_data_in_en) |
+			   FIELD_PREP(NUM_CHANNELS, dp->audio_channels - 1) |
+			   FIELD_PREP(AUDIO_DATA_WIDTH, params->sample_width) |
+			   FIELD_PREP(AUDIO_INF_SELECT, dp->audio_interface) |
+			   FIELD_PREP(HBR_MODE_ENABLE, 0));
+
+	/* Wait for inf switch */
+	usleep_range(20, 40);
+
+	if (dp->audio_interface == DW_DP_AUDIO_I2S)
+		clk_disable_unprepare(dp->spdif_clk);
+	else if (dp->audio_interface == DW_DP_AUDIO_SPDIF)
+		clk_disable_unprepare(dp->i2s_clk);
+
+	/*
+	 * Send audio stream during vertical and horizontal blanking periods.
+	 * Send out audio timestamp SDP once per video frame during the vertical
+	 * blanking period
+	 */
+	regmap_update_bits(dp->regmap, DW_DP_SDP_VERTICAL_CTRL,
+			   EN_AUDIO_STREAM_SDP | EN_AUDIO_TIMESTAMP_SDP,
+			   FIELD_PREP(EN_AUDIO_STREAM_SDP, 1) |
+			   FIELD_PREP(EN_AUDIO_TIMESTAMP_SDP, 1));
+	regmap_update_bits(dp->regmap, DW_DP_SDP_HORIZONTAL_CTRL,
+			   EN_AUDIO_STREAM_SDP,
+			   FIELD_PREP(EN_AUDIO_STREAM_SDP, 1));
+
+	ret = dw_dp_audio_infoframe_send(dp);
+	if (ret < 0)
+		dev_err(dp->dev, "failed to send audio infoframe\n");
+
+	dev_dbg(dp->dev, "audio start with %d channels using DAI=%d\n",
+		dp->audio_channels, dp->audio_interface);
+
+	return 0;
+}
+
+static void dw_dp_audio_shutdown(struct drm_bridge *bridge,
+				 struct drm_connector *connector)
+{
+	struct dw_dp *dp = bridge_to_dp(bridge);
+
+	dev_dbg(dp->dev, "audio shutdown\n");
+
+	/* Disable all audio streams */
+	regmap_update_bits(dp->regmap, DW_DP_AUD_CONFIG1, AUDIO_DATA_IN_EN,
+			   FIELD_PREP(AUDIO_DATA_IN_EN, 0));
+
+	if (dp->audio_interface == DW_DP_AUDIO_SPDIF)
+		clk_disable_unprepare(dp->spdif_clk);
+	else if (dp->audio_interface == DW_DP_AUDIO_I2S)
+		clk_disable_unprepare(dp->i2s_clk);
+
+	dp->audio_interface = DW_DP_AUDIO_UNUSED;
+
+	pm_runtime_put_autosuspend(dp->dev);
+}
+
+static int dw_dp_audio_mute_stream(struct drm_bridge *bridge,
+				   struct drm_connector *connector,
+				   bool enable, int direction)
+{
+	struct dw_dp *dp = bridge_to_dp(bridge);
+
+	dev_dbg(dp->dev, "audio %smute\n", enable ? "" : "un");
+
+	regmap_update_bits(dp->regmap, DW_DP_AUD_CONFIG1, AUDIO_MUTE,
+			   FIELD_PREP(AUDIO_MUTE, enable));
+
+	return 0;
+}
+
 static const struct drm_bridge_funcs dw_dp_bridge_funcs = {
 	.atomic_duplicate_state = dw_dp_bridge_atomic_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -1858,6 +2040,10 @@ static const struct drm_bridge_funcs dw_dp_bridge_funcs = {
 	.edid_read = dw_dp_bridge_edid_read,
 	.detach = dw_dp_bridge_detach,
 	.oob_notify = dw_dp_bridge_oob_notify,
+
+	.dp_audio_prepare = dw_dp_audio_prepare,
+	.dp_audio_shutdown = dw_dp_audio_shutdown,
+	.dp_audio_mute_stream = dw_dp_audio_mute_stream,
 };
 
 static int dw_dp_link_retrain(struct dw_dp *dp)
@@ -2084,10 +2270,19 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 	}
 
 	bridge->of_node = dev->of_node;
-	bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
+	bridge->ops = DRM_BRIDGE_OP_DP_AUDIO |
+		      DRM_BRIDGE_OP_DETECT |
+		      DRM_BRIDGE_OP_EDID |
+		      DRM_BRIDGE_OP_HPD;
 	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
 	bridge->ycbcr_420_allowed = true;
 
+	dp->audio_interface = DW_DP_AUDIO_UNUSED;
+	bridge->hdmi_audio_dev = dev;
+	bridge->hdmi_audio_max_i2s_playback_channels = 8;
+	bridge->hdmi_audio_dai_port = 1;
+	bridge->hdmi_audio_spdif_playback = true;
+
 	ret = devm_drm_bridge_add(dev, bridge);
 	if (ret)
 		return ERR_PTR(ret);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms
  2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
                   ` (9 preceding siblings ...)
  2026-03-26 17:31 ` [PATCH 10/10] drm/bridge: synopsys: dw-dp: Add audio support Sebastian Reichel
@ 2026-03-30  1:34 ` Chaoyi Chen
  2026-03-30 11:50   ` Sebastian Reichel
  10 siblings, 1 reply; 13+ messages in thread
From: Chaoyi Chen @ 2026-03-30  1:34 UTC (permalink / raw)
  To: Sebastian Reichel, Sandy Huang, Heiko Stübner, Andy Yan,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Damon Ding, Dmitry Baryshkov, Alexey Charkov, dri-devel,
	linux-rockchip, linux-kernel, devicetree, kernel

Hello Sebastian, 

On 3/27/2026 1:31 AM, Sebastian Reichel wrote:
> This patch series updates the Synopsys Designware DisplayPort bridge
> together with the only existing user: The Rockchip RK3576/RK3588:
> 
>  1. follow-up bridges (PHY, USB-C connector)
>     this is needed to get USB-C DP AltMode working; I've followed the
>     Qualcomm driver as reference
> 
>  2. runtime PM
>     the initial driver has been upstreamed without RPM; add it to
>     avoid wasting power when nothing is plugged
> 
>  3. audio
>     the initial driver has been upstreamed without audio support;
>     this adds all missing bits for audio with single stream transport
> 
> The series is based on drm-misc-next with Cristian's cleanup series
> applied as I expect that to land first:
> 
> https://lore.kernel.org/linux-rockchip/20260310-drm-rk-fixes-v2-0-645ecfb43f49@collabora.com/
> 
> To properly make use of the bridge code the following USBDP PHY series
> is also needed:
> 
> https://lore.kernel.org/linux-rockchip/20260313-rockchip-usbdp-cleanup-v3-0-3e8fe89a35b5@collabora.com/
> 
> There are two parts, which possibly need some discussion:
> 
>  1. I added a dedicated bridge callback for out-of-band hotplug events,
>     which is separate from the hotplug_notify. I have a feeling, that
>     there might be a better solution, but haven't found it.
> 

Could you explain what an out-of-band hotplug event is?

Can't the drivers/usb/typec/altmodes/displayport.c respond to these
hot-plug events? Thank you.


>  2. The DT binding for audio support - explicitly marked as RFC - works
>     perfectly fine, but is not ready for MST. I don't intend to
>     implement that right now, but the binding should obviously take it
>     into consideration to avoid breaking it in the future. I've put
>     some points for discussion into the relevant patch.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> Sebastian Reichel (10):
>       drm/bridge: synopsys: dw-dp: Simplify driver data setting
>       drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED
>       drm/bridge: synopsys: dw-dp: Add follow-up bridge support
>       drm/bridge: Add out-of-band HPD notify handler
>       drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD
>       drm/rockchip: dw_dp: Implement out-of-band HPD handling
>       drm/bridge: synopsys: dw-dp: Add Runtime PM support
>       drm/rockchip: dw_dp: Add runtime PM support
>       [RFC] dt-bindings: display: rockchip: dw-dp: fix sound DAI cells
>       drm/bridge: synopsys: dw-dp: Add audio support
> 
>  .../bindings/display/rockchip/rockchip,dw-dp.yaml  |   5 +-
>  drivers/gpu/drm/bridge/synopsys/dw-dp.c            | 284 ++++++++++++++++++++-
>  drivers/gpu/drm/display/drm_bridge_connector.c     |   6 +
>  drivers/gpu/drm/rockchip/dw_dp-rockchip.c          | 167 +++++++++++-
>  include/drm/bridge/dw_dp.h                         |   6 +
>  include/drm/drm_bridge.h                           |  14 +
>  6 files changed, 469 insertions(+), 13 deletions(-)
> ---
> base-commit: 0660ee19141e5e90b422b7daa0d8518a8d0d898b
> change-id: 20260325-synopsys-dw-dp-improvements-7da2e98df1dd
> 
> Best regards,

-- 
Best, 
Chaoyi


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms
  2026-03-30  1:34 ` [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Chaoyi Chen
@ 2026-03-30 11:50   ` Sebastian Reichel
  0 siblings, 0 replies; 13+ messages in thread
From: Sebastian Reichel @ 2026-03-30 11:50 UTC (permalink / raw)
  To: Chaoyi Chen
  Cc: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Damon Ding,
	Dmitry Baryshkov, Alexey Charkov, dri-devel, linux-rockchip,
	linux-kernel, devicetree, kernel

[-- Attachment #1: Type: text/plain, Size: 1070 bytes --]

Hello Chaoyi,

On Mon, Mar 30, 2026 at 09:34:15AM +0800, Chaoyi Chen wrote:
> > There are two parts, which possibly need some discussion:
> > 
> >  1. I added a dedicated bridge callback for out-of-band hotplug events,
> >     which is separate from the hotplug_notify. I have a feeling, that
> >     there might be a better solution, but haven't found it.
> 
> Could you explain what an out-of-band hotplug event is?
> 
> Can't the drivers/usb/typec/altmodes/displayport.c respond to these
> hot-plug events? Thank you.

That is what generates the out-of-band hotplug event in the first
place via drm_connector_oob_hotplug_event(). The oob in that call
means out of band.

If you look at that function it calls oob_hotplug_event() callback
on the DRM connector, which is then implemented by
drm_bridge_connector_oob_hotplug_event(). This function calls uses
the normal hpd handling (shared by in-band and out-of-band) and I'm
patching it, so that the bridges are aware of hpd explicitly being
provided out-of-band.

Greetings,

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-03-30 11:51 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-26 17:31 [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
2026-03-26 17:31 ` [PATCH 01/10] drm/bridge: synopsys: dw-dp: Simplify driver data setting Sebastian Reichel
2026-03-26 17:31 ` [PATCH 02/10] drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED Sebastian Reichel
2026-03-26 17:31 ` [PATCH 03/10] drm/bridge: synopsys: dw-dp: Add follow-up bridge support Sebastian Reichel
2026-03-26 17:31 ` [PATCH 04/10] drm/bridge: Add out-of-band HPD notify handler Sebastian Reichel
2026-03-26 17:31 ` [PATCH 05/10] drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD Sebastian Reichel
2026-03-26 17:31 ` [PATCH 06/10] drm/rockchip: dw_dp: Implement out-of-band HPD handling Sebastian Reichel
2026-03-26 17:31 ` [PATCH 07/10] drm/bridge: synopsys: dw-dp: Add Runtime PM support Sebastian Reichel
2026-03-26 17:31 ` [PATCH 08/10] drm/rockchip: dw_dp: Add runtime " Sebastian Reichel
2026-03-26 17:31 ` [PATCH RFC 09/10] dt-bindings: display: rockchip: dw-dp: fix sound DAI cells Sebastian Reichel
2026-03-26 17:31 ` [PATCH 10/10] drm/bridge: synopsys: dw-dp: Add audio support Sebastian Reichel
2026-03-30  1:34 ` [PATCH 00/10] Synopsys DisplayPort Controller improvements for Rockchip platforms Chaoyi Chen
2026-03-30 11:50   ` Sebastian Reichel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox