From: Sebastian Reichel <sebastian.reichel@collabora.com>
To: "Sandy Huang" <hjc@rock-chips.com>,
"Heiko Stübner" <heiko@sntech.de>,
"Andy Yan" <andy.yan@rock-chips.com>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Andrzej Hajda" <andrzej.hajda@intel.com>,
"Neil Armstrong" <neil.armstrong@linaro.org>,
"Robert Foss" <rfoss@kernel.org>,
"Laurent Pinchart" <Laurent.pinchart@ideasonboard.com>,
"Jonas Karlman" <jonas@kwiboo.se>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>,
"Luca Ceresoli" <luca.ceresoli@bootlin.com>
Cc: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>,
Damon Ding <damon.ding@rock-chips.com>,
Dmitry Baryshkov <lumag@kernel.org>,
Alexey Charkov <alchark@gmail.com>,
dri-devel@lists.freedesktop.org,
linux-rockchip@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
kernel@collabora.com, linux-arm-kernel@lists.infradead.org,
Sebastian Reichel <sebastian.reichel@collabora.com>
Subject: [PATCH v2 07/12] drm/rockchip: dw_dp: Implement out-of-band HPD handling
Date: Fri, 01 May 2026 00:20:34 +0200 [thread overview]
Message-ID: <20260501-synopsys-dw-dp-improvements-v2-7-d7e7f6bac77f@collabora.com> (raw)
In-Reply-To: <20260501-synopsys-dw-dp-improvements-v2-0-d7e7f6bac77f@collabora.com>
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 52e956bffb12..5750cf887981 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);
@@ -138,14 +246,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
next prev parent reply other threads:[~2026-04-30 22:21 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-30 22:20 [PATCH v2 00/12] Synopsys DisplayPort Controller improvements for Rockchip platforms Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 01/12] drm/bridge: synopsys: dw-dp: Support unregistering the AUX channel Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 02/12] drm/rockchip: dw_dp: Release core resources Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 03/12] drm/bridge: synopsys: dw-dp: Simplify driver data setting Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 04/12] drm/bridge: synopsys: dw-dp: Support MEDIA_BUS_FMT_FIXED Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 05/12] drm/bridge: synopsys: dw-dp: Add follow-up bridge support Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 06/12] drm/bridge: Add out-of-band HPD notify handler Sebastian Reichel
2026-04-30 22:20 ` Sebastian Reichel [this message]
2026-04-30 22:20 ` [PATCH v2 08/12] drm/bridge: synopsys: dw-dp: Support software triggered OOB HPD Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 09/12] drm/bridge: synopsys: dw-dp: Add Runtime PM support Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 10/12] drm/rockchip: dw_dp: Add runtime " Sebastian Reichel
2026-04-30 22:20 ` [PATCH RFC v2 11/12] dt-bindings: display: rockchip: dw-dp: fix sound DAI cells Sebastian Reichel
2026-04-30 22:20 ` [PATCH v2 12/12] drm/bridge: synopsys: dw-dp: Add audio support Sebastian Reichel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260501-synopsys-dw-dp-improvements-v2-7-d7e7f6bac77f@collabora.com \
--to=sebastian.reichel@collabora.com \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=alchark@gmail.com \
--cc=andrzej.hajda@intel.com \
--cc=andy.yan@rock-chips.com \
--cc=conor+dt@kernel.org \
--cc=cristian.ciocaltea@collabora.com \
--cc=damon.ding@rock-chips.com \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=heiko@sntech.de \
--cc=hjc@rock-chips.com \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=kernel@collabora.com \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=luca.ceresoli@bootlin.com \
--cc=lumag@kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=rfoss@kernel.org \
--cc=robh@kernel.org \
--cc=simona@ffwll.ch \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox