From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=148.251.105.195 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794632461; b=qiFblpE9wYybC6NUt3rgAIhK+5A3JQC7wWdc7xHkRQn6Cbsns3wbzPmKqwRWieos5VSE 6Nuz4twlT3OS6HXWgdR6jguvZf/oQZZC4MSIUSj/PZqgKocu7wk5fjgSUQeVBr8XkIaRW koBSOrlEyIffp5JjZIebUkwbAbVz0W2xpBwQ6nKU53hIPbbx/rWrDSojnFt4SQ7nukvgB YFBWOoWOe/Z57JtiuXKIbPrxwC76aJWfidMSQQnRs1Ijt8709CttpjbhXBrf0bMIbfdKQ 5TbHYjtXkmG5XfEISUKC+pl2KtDMeCbL3R91PaR0oXTAm2p0mWn+T+h1yO7/0PE4bEg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794632461; h=DMARC-Filter:DKIM-Signature:Received:Received:From:Date:Subject: MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id: References:In-Reply-To:To:Cc:X-Mailer:X-Developer-Signature: X-Developer-Key; bh=SA6Amvy8hWb+j5390vVNpKnnYb7JEyN8Q5nmxQv9Hz4=; b=OZEfLecKss/OJ9cpwF4pyP8/B6x6ZmiQsgQxtA7irb7JLrx4NcOaBBf0cGQyQBV2jp1l E8m/GwpBkrn20nft9PW2Xt9xNKmcv81Ttbj74dGxuVxfGeJg+jC4KN7HeENsalhUp/Gzq GkFFsXsG6TEVuCk7j74RN+4YJJ1NeNusKp8EqoMJdzGiHwCz3BHnZeqHQ2/WEw2xZZKQh M7XRHwU0AuKdxaE+Dv2Ily+WuRoZWutj4aY5HWdCzwfCRizMkConBvXHNpZkMnUw8ZJ3I NrshRCVenxDE122GJ/Zk/GVEJG/fV9hg4dC5juKEAHqZ2Wi2pl2R142VYaqUqQ2aT7g== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass header.d=collabora.com header.i=@collabora.com header.a=rsa-sha256 header.s=mail header.b=Cfwg245a; arc=none smtp.remote-ip=148.251.105.195 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EAE4D606A8B8; Sat, 14 Nov 2026 05:01:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org EAE4D606A8B8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.a=rsa-sha256 header.s=mail header.b=Cfwg245a DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1794632457; bh=jW3pTq3R7bOpTIyh4wVZ51psj2/mar6tT6/Xkgyz95U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Cfwg245aIg22lpownZsOmrhQm3NyLBV9MH2XACwSCMNpmS/4kFtwZE6fXPLDsZME5 lLUKv+gdIQWhpX0gjcuGF4KaHdBCETymWyLfz4l9JWc+wSQ9mX4hsmHYBrzjLclmaS gHP3HBdB3e4EsPrWyp1qEWhpcz9e1W4b7CllMqDaFycjX0T6YEkYHl1clXGgKr+xZi SmIPOmicU8FDpzddBoKWMHEoNn5IRXRjjPG90MeW6SiTYBfj/P7kXhygIUgNX5EuWW 7DTx67dvcZow4EurZOrq5htyJUKsyw8nDpyE41VXs02di9WRYyIZNYhbqzTf75Nt/+ H5+TbPK8OefSw== Received: from jupiter.universe (unknown [100.64.1.62]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519) (No client certificate requested) (Authenticated sender: sre) by bali.collaboradmins.com (Postfix) with ESMTPSA id CEA2117E3BE8; Sat, 14 Nov 2026 06:00:56 +0100 (CET) Received: by jupiter.universe (Postfix, from userid 1000) id 1EF70480052; Sat, 14 Nov 2026 06:00:56 +0100 (CET) From: Sebastian Reichel Date: Sat, 14 Nov 2026 06:00:46 +0100 Subject: [PATCH v12 13/23] drm/rockchip: dw_dp: Implement out-of-band HPD handling X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261114-synopsys-dw-dp-improvements-v12-13-d42d3dc5bdd4@collabora.com> References: <20261114-synopsys-dw-dp-improvements-v12-0-d42d3dc5bdd4@collabora.com> In-Reply-To: <20261114-synopsys-dw-dp-improvements-v12-0-d42d3dc5bdd4@collabora.com> To: Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , 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 , David Airlie , Simona Vetter , Dmitry Baryshkov , Luca Ceresoli , Philipp Zabel Cc: Cristian Ciocaltea , Damon Ding , Dmitry Baryshkov , Alexey Charkov , 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 , Igor Paunovic X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6431; i=sebastian.reichel@collabora.com; h=from:subject:message-id; bh=jW3pTq3R7bOpTIyh4wVZ51psj2/mar6tT6/Xkgyz95U=; b=owJ4nAFtApL9kA0DAAoB2O7X88g7+poByyZiAGr36weIOLemRYG8AS8zuIkjV18ZzUojTLjK1 wMCLKX5BebR84kCMwQAAQoAHRYhBO9mDQdGP4tyanlUE9ju1/PIO/qaBQJq9+sHAAoJENju1/PI O/qagsQP+QE4IBi+H2jk02AviXZbcohR6OfA6KCLqERt71uAjHrLO2fZnrI1HX6iDIJggIi4UPd n12JjEOKW+gkyIeuPOQs+M7hNmaDgIx7K/EKXgi1BmIxYGTUZJg5g4aMRrGEJr7Ki6+KmXFd1An oVxy6a7H8YBQGQAgPmhvtyUdFFHIcrCHFqdT0Bs2tuCRr8lR9Jzw7kaEV+6imIgQE+65SyKsKI3 oksVF9S75ubd83fZrtuylo6zTpUMAZ8p4VCqEjEdA+QyrqFT/egfLygzb3THU5wd1495fcygxHb BgZ7OAIYrGrX4Bf8wMMOaAGDRBR2MVDjp3BWGTXs5O5jk0hxj7RzBJTMcFJKzvgX2/jBdiRvLRw 4C+lVYdRZZsxMI0jDrFXVOP0lEbauRw3XxJBaXMT/eXt/xBkLtMbspgYmYCMNYKSsYoWhY71J/e pctpm5MEdwSxLZK1B7ZxsnV/BsPSOl+t10I/c8DP1kHVedkRJi/fODjYZK7q2H2s7yc2S+H2Yvt t/qfctTrNI2+CgLh8FGX4ipEbSmbsuw2iXoqDKU6ZytJVb7R0Vo0z91Z5chbA4rF+EsDgbXjIKT O65pHg3FzjqBEJ6dWQK4EanGQPio8tPFRPq4NrpKYcL23dF9DRzZSY/SNDXE5sFvinm++crPTV7 w8O5jGD/95QyiA6anqN8oSA== X-Developer-Key: i=sebastian.reichel@collabora.com; a=openpgp; fpr=EF660D07463F8B726A795413D8EED7F3C83BFA9A 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. Thus this patch prevents massive SError problems once runtime PM is implemented (and enabled) in the DP driver. Apart from that it avoids 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. Tested-by: Igor Paunovic # Orange Pi 5+ Signed-off-by: Sebastian Reichel --- drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 116 ++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c index 38e8fe75718e..c5386653991d 100644 --- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c @@ -7,9 +7,12 @@ */ #include +#include #include +#include #include #include +#include #include #include @@ -23,12 +26,46 @@ #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; + u64 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; }; +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]; + + regmap_write(dp->vo_grf, hpd_reg, + FIELD_PREP_WM16(ROCKCHIP_VO_GRF_DP_SINK_HPD_SEL, force_hpd_from_sw)); +} + +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]; + + regmap_write(dp->vo_grf, hpd_reg, + FIELD_PREP_WM16(ROCKCHIP_VO_GRF_DP_SINK_HPD_CFG, hpd)); +} + static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -71,6 +108,35 @@ static const struct drm_encoder_helper_funcs dw_dp_encoder_helper_funcs = { .atomic_check = dw_dp_encoder_atomic_check, }; +static struct regmap *dw_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, potential future platforms + * reusing the driver should just add a VO GRF phandle in the DisplayPort + * controller 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) { struct rockchip_dw_dp *dp = dev_get_drvdata(dev); @@ -121,19 +187,53 @@ static const struct component_ops dw_dp_rockchip_component_ops = { static int dw_dp_rockchip_probe(struct platform_device *pdev) { - const struct dw_dp_plat_data *plat_data; + const struct rockchip_dw_dp_plat_data *plat_data_const; + struct dw_dp_plat_data *plat_data; struct device *dev = &pdev->dev; struct rockchip_dw_dp *dp; + struct resource *res; + int id; - 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; + plat_data = devm_kzalloc(dev, sizeof(*plat_data), GFP_KERNEL); + if (!plat_data) + return -ENOMEM; + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); if (!dp) return -ENOMEM; platform_set_drvdata(pdev, dp); dp->dev = dev; + dp->pdata = plat_data_const; + + res = platform_get_mem_or_io(pdev, 0); + if (!res) + return -ENODEV; + + /* 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 = dw_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; dp->base = dw_dp_probe(pdev, plat_data); if (IS_ERR(dp->base)) @@ -147,14 +247,20 @@ static void dw_dp_rockchip_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