From cf3aa34e6f0798544c26ad93a6c3c2231ab09738 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 15 Sep 2026 17:06:12 +0200 Subject: [PATCH] phy: rockchip: usbdp: Avoid xHCI SErrors The USBDP PHY provides the PIPE clock to the USB3 controller, which means the PHY must be fully running when anything tries to access the xHCI registers. When switching between USB3-only, USB3 + DP and DP-only mode, the PHY must be re-initialized resulting in a short period of the PHY being disabled. If the DWC3 driver decides to access the xHCI at this point the system will fail with an SError. This patch avoids the problems by disabling the USB3 port before re-initializing it. This does a couple of things: - forces phystatus to 0 from GRF (not from PHY) - switches PIPE clock source from PHY to UTMI (safe fallback clock) - num_u3_port=0 The last part will be ignored, as DWC3 already probed, but the clock re-routing will avoid the SError. There is a small delay afterwards to make sure the mux happened. The datasheet gives no hints how long it takes, so delay time is a guess. Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver") Tested-by: Igor Paunovic # Orange Pi 5 Plus Signed-off-by: Sebastian Reichel Reviewed-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20260915-rockchip-usbdp-cleanup-part2-v15-9-8d507cb1174f@collabora.com Signed-off-by: Vinod Koul --- drivers/phy/rockchip/phy-rockchip-usbdp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c index 23cfb9bbd334..4116b4b18882 100644 --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c @@ -999,12 +999,15 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode) rk_udphy_u3_port_disable(udphy, false); udphy->phy_needs_reinit = false; } else if (udphy->phy_needs_reinit) { - if (udphy->mode == UDPHY_MODE_DP) - rk_udphy_u3_port_disable(udphy, true); + rk_udphy_u3_port_disable(udphy, true); + udelay(10); ret = rk_udphy_init(udphy); if (ret) return ret; + + if (!udphy->hs && udphy->mode & UDPHY_MODE_USB) + rk_udphy_u3_port_disable(udphy, false); udphy->phy_needs_reinit = false; }