* [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3)
@ 2026-09-15 15:32 Sebastian Reichel
2026-09-15 15:32 ` [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support Sebastian Reichel
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-15 15:32 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam,
Heiko Stuebner, Zhang Yubing, Frank Wang
Cc: linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
kernel, Sebastian Reichel, Igor Paunovic
This series was split from the USBDP cleanup series and contains a bunch
of critical bug fixes for the Rockchip USBDP driver, but the fixes
depend on the cleanup and features added in the previous parts and
cannot be sensibly moved to the start of everything.
This part depends on the cleanup series part 1, part 2, as well as the
series adding the new DWC3 glue driver.
The most important change is the first patch adding PHY reset
notification support (i.e. the PHY notifies the consumer that the
PHY is about to reset).
Changes in v15:
- Link to v14: https://patch.msgid.link/20260813-rockchip-usbdp-cleanup-v14-0-b5ad9c68fa11@collabora.com
- Split the series, no patch changes in this part
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
Sebastian Reichel (6):
phy: rockchip: usbdp: Add phy reset notification support
phy: rockchip: usbdp: Drop -EPROBE_DEFER hack
phy: rockchip: usbdp: Rename mode to hw_mode
phy: rockchip: usbdp: Fix power state handling
phy: rockchip: usbdp: Re-init PHY on mux change
phy: rockchip: usbdp: Add USB-C state without DP enabled
drivers/phy/rockchip/phy-rockchip-usbdp.c | 237 ++++++++++++++++++------------
1 file changed, 144 insertions(+), 93 deletions(-)
---
base-commit: e5e04726cdd043e309677071ab1b65a4b18f422b
change-id: 20260914-b4-rockchip-usbdp-cleanup-part3-cca70383ebe3
prerequisite-message-id: 20260915-rockchip-usbdp-cleanup-v15-0-80e2c11d1ce8@collabora.com
prerequisite-patch-id: 27d601f203e30baebffc3486a1b787a2d280f5f7
prerequisite-patch-id: b42efbccabb13cd37252ea9bbc3873141bd5b8f8
prerequisite-patch-id: 8b416e19148a0b90c71778ff4fcc032b52ed49ce
prerequisite-patch-id: 04b986df824850902431339cdf43787d8036ac5c
prerequisite-patch-id: c0a6f7da1f986c76248c6271b0c04d8dab21e5cb
prerequisite-patch-id: 12bf844fd4a355c1860812522fdb16a1ff4232ea
prerequisite-patch-id: d71d6a6a232b59804f0775ba5c87d71bfdbbea61
prerequisite-patch-id: 301c705f92061ccb1a1923ec5d3bdc1fdceca24d
prerequisite-patch-id: 978560cb9620a16f57e14c424e8efa4ad7178747
prerequisite-patch-id: a6562299bf87dc57d4b14a8079d2b1e3fe407702
prerequisite-patch-id: 1b90e6acf41e9093636c3fe8791f46492b583520
prerequisite-patch-id: 60f32afe1f50ed33d48041b41e7ec8a5841d0ebd
prerequisite-patch-id: 8a9a01d462e581e6539bc9fd07b13e0f32933126
prerequisite-patch-id: fbcfbe4a42de5c488052e865bfd146260be738fb
prerequisite-patch-id: 7f3c3811dee1e11e0386ff2d8b4080f07bd68e88
prerequisite-patch-id: 831ca526a0099f3f7292f2060df9888bdf3055b4
prerequisite-message-id: 20260915-rockchip-usbdp-cleanup-part2-v15-0-8d507cb1174f@collabora.com
prerequisite-patch-id: aa7f5784cc227e8dd7e9fe376dad1997828aefbc
prerequisite-patch-id: 21ff208d83fc75ac5efa9f69d8aa36455d1ae94e
prerequisite-patch-id: 4f721e51f1f4d57284354cc0b99b6a092b4603da
prerequisite-patch-id: c5d9d7bf27e215f9f60ac98ce9cc2117b5041d38
prerequisite-patch-id: e1cefd986004360890e009dede50fc849ce927df
prerequisite-patch-id: e2788d7c6dad4f9b3352ed59c5b4bedd7c55529e
prerequisite-patch-id: 45c0c6cdd117dba967ae3616531d7229fa853075
prerequisite-patch-id: acca212cc347efc4748dbe8d74a192e0f58f0133
prerequisite-patch-id: dabae3467575f218da2042bd26aa7314f599169e
prerequisite-patch-id: 4208007b7e8ce5710399a7a1cd93a45b2da0007c
prerequisite-patch-id: d2362c993cd9289d8849af2144a05da1bb5d84c9
prerequisite-message-id: 20260915-b4-rockchip-dwc3-rockchip-glue-v1-0-763bb546824e@collabora.com
prerequisite-patch-id: 14c0d95ef04887c85fa5b00910f128416efcf17a
prerequisite-patch-id: 887cc9953b0df9e238ae0777ac3c8a263e537d9c
prerequisite-patch-id: dadeaf9e369e04d8b3329493a1a0756ddd6140f0
prerequisite-patch-id: be213d23cea80f1c646983de557fb1305d545f63
prerequisite-patch-id: 8cc3059384276b97b1905fb04ac5ba153e1bf2f5
Best regards,
--
Sebastian Reichel <sebastian.reichel@collabora.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support
2026-09-15 15:32 [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3) Sebastian Reichel
@ 2026-09-15 15:32 ` Sebastian Reichel
2026-09-26 7:54 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 2/6] phy: rockchip: usbdp: Drop -EPROBE_DEFER hack Sebastian Reichel
` (4 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-15 15:32 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam,
Heiko Stuebner, Zhang Yubing, Frank Wang
Cc: linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
kernel, Sebastian Reichel, Igor Paunovic
To resolve issues with running into permanent "cmn ana lcpll lock
timeout" errors after a few device replugs, add support for reset
notifications, which will be handled by the DWC3 driver to gracefully
handle the PHY being disabled. This avoids corrupting the controller's
internal state and the PIPE interface between the USB3 controller and
the PHY, thus fixing the issue.
Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index e748acdd2d31..0f39982c70b1 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1004,24 +1004,39 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
}
if (udphy->status == UDPHY_MODE_NONE) {
+ phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_PRE_RESET);
+
+ rk_udphy_u3_port_disable(udphy, true);
+ udelay(10);
+
ret = rk_udphy_setup(udphy);
- if (ret)
+ if (ret) {
+ phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
return ret;
+ }
if (!udphy->hs && udphy->mode & UDPHY_MODE_USB)
rk_udphy_u3_port_disable(udphy, false);
udphy->phy_needs_reinit = false;
+
+ phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
} else if (udphy->phy_needs_reinit) {
+ phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_PRE_RESET);
+
rk_udphy_u3_port_disable(udphy, true);
udelay(10);
ret = rk_udphy_init(udphy);
- if (ret)
+ if (ret) {
+ phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
return ret;
+ }
if (!udphy->hs && udphy->mode & UDPHY_MODE_USB)
rk_udphy_u3_port_disable(udphy, false);
udphy->phy_needs_reinit = false;
+
+ phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
}
udphy->status |= mode;
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v15 2/6] phy: rockchip: usbdp: Drop -EPROBE_DEFER hack
2026-09-15 15:32 [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3) Sebastian Reichel
2026-09-15 15:32 ` [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support Sebastian Reichel
@ 2026-09-15 15:32 ` Sebastian Reichel
2026-09-26 7:55 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 3/6] phy: rockchip: usbdp: Rename mode to hw_mode Sebastian Reichel
` (3 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-15 15:32 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam,
Heiko Stuebner, Zhang Yubing, Frank Wang
Cc: linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
kernel, Sebastian Reichel, Igor Paunovic
The hack to return -EPROBE_DEFER when the lcpll lock timeouts is no
longer needed. The driver now does a reset during its PHY init, which
avoids the problem.
Since rk_udphy_status_check() is called after the probe, it should not
return -EPROBE_DEFER.
Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 0f39982c70b1..144d83997a79 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -749,17 +749,7 @@ static int rk_udphy_status_check(struct rk_udphy *udphy)
(val & CMN_ANA_LCPLL_LOCK_DONE), 200, 100000);
if (ret) {
dev_err(udphy->dev, "cmn ana lcpll lock timeout\n");
- /*
- * If earlier software (U-Boot) enabled USB once already
- * the PLL may have problems locking on the first try.
- * It will be successful on the second try, so for the
- * time being a -EPROBE_DEFER will solve the issue.
- *
- * This requires further investigation to understand the
- * root cause, especially considering that the driver is
- * asserting all reset lines at probe time.
- */
- return -EPROBE_DEFER;
+ return ret;
}
if (!udphy->flip) {
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v15 3/6] phy: rockchip: usbdp: Rename mode to hw_mode
2026-09-15 15:32 [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3) Sebastian Reichel
2026-09-15 15:32 ` [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support Sebastian Reichel
2026-09-15 15:32 ` [PATCH v15 2/6] phy: rockchip: usbdp: Drop -EPROBE_DEFER hack Sebastian Reichel
@ 2026-09-15 15:32 ` Sebastian Reichel
2026-09-26 7:57 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 4/6] phy: rockchip: usbdp: Fix power state handling Sebastian Reichel
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-15 15:32 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam,
Heiko Stuebner, Zhang Yubing, Frank Wang
Cc: linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
kernel, Sebastian Reichel, Igor Paunovic
Rename mode field to hw_mode to make clear that this is the modes
currently supported by the hardware, but not necessarily requested
by software. I.e. it is only set by either the USB-C state machine
or device-tree if the PHY is used in a fixed routing setup.
Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 48 +++++++++++++++----------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 144d83997a79..b06d94db42ea 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -173,7 +173,7 @@ struct rk_udphy {
/* PHY status management */
bool flip;
bool phy_needs_reinit;
- u8 mode;
+ u8 hw_mode; /* modes currently supported by hardware */
u8 status;
/* utilized for USB */
@@ -578,18 +578,18 @@ static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
}
-static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 mode)
+static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 hw_mode)
{
- if (udphy->mode == mode)
+ if (udphy->hw_mode == hw_mode)
return;
udphy->phy_needs_reinit = true;
- udphy->mode = mode;
+ udphy->hw_mode = hw_mode;
}
static void rk_udphy_set_typec_state(struct rk_udphy *udphy, unsigned long state)
{
- u8 mode;
+ u8 hw_mode;
switch (state) {
case TYPEC_DP_STATE_C:
@@ -598,7 +598,7 @@ static void rk_udphy_set_typec_state(struct rk_udphy *udphy, unsigned long state
udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
- mode = UDPHY_MODE_DP;
+ hw_mode = UDPHY_MODE_DP;
udphy->dp_lanes = 4;
break;
@@ -615,12 +615,12 @@ static void rk_udphy_set_typec_state(struct rk_udphy *udphy, unsigned long state
udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
}
- mode = UDPHY_MODE_DP_USB;
+ hw_mode = UDPHY_MODE_DP_USB;
udphy->dp_lanes = 2;
break;
}
- rk_udphy_mode_set(udphy, mode);
+ rk_udphy_mode_set(udphy, hw_mode);
}
static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
@@ -743,7 +743,7 @@ static int rk_udphy_status_check(struct rk_udphy *udphy)
int ret;
/* LCPLL check */
- if (udphy->mode & UDPHY_MODE_USB) {
+ if (udphy->hw_mode & UDPHY_MODE_USB) {
ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_LCPLL_DONE_OFFSET,
val, (val & CMN_ANA_LCPLL_AFC_DONE) &&
(val & CMN_ANA_LCPLL_LOCK_DONE), 200, 100000);
@@ -778,15 +778,15 @@ static int rk_udphy_init(struct rk_udphy *udphy)
int ret;
dev_dbg(udphy->dev, "reinit PHY with USB3=%s and DP=%s (%u lanes) flipped=%s\n",
- str_on_off(udphy->mode & UDPHY_MODE_USB),
- str_on_off(udphy->mode & UDPHY_MODE_DP),
+ str_on_off(udphy->hw_mode & UDPHY_MODE_USB),
+ str_on_off(udphy->hw_mode & UDPHY_MODE_DP),
udphy->dp_lanes, str_yes_no(udphy->flip));
rk_udphy_reset_assert_all(udphy);
usleep_range(10000, 11000);
/* enable rx lfps for usb */
- if (udphy->mode & UDPHY_MODE_USB)
+ if (udphy->hw_mode & UDPHY_MODE_USB)
rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.rx_lfps, true);
/* Step 1: power on pma and deassert apb rstn */
@@ -823,13 +823,13 @@ static int rk_udphy_init(struct rk_udphy *udphy)
FIELD_PREP(CMN_DP_LANE_EN_ALL, 0));
/* Step 4: deassert init rstn and wait for 200ns from datasheet */
- if (udphy->mode & UDPHY_MODE_USB) {
+ if (udphy->hw_mode & UDPHY_MODE_USB) {
ret = rk_udphy_reset_deassert(udphy, "init");
if (ret)
goto assert_resets;
}
- if (udphy->mode & UDPHY_MODE_DP) {
+ if (udphy->hw_mode & UDPHY_MODE_DP) {
regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
CMN_DP_INIT_RSTN,
FIELD_PREP(CMN_DP_INIT_RSTN, 0x1));
@@ -838,7 +838,7 @@ static int rk_udphy_init(struct rk_udphy *udphy)
udelay(1);
/* Step 5: deassert cmn/lane rstn */
- if (udphy->mode & UDPHY_MODE_USB) {
+ if (udphy->hw_mode & UDPHY_MODE_USB) {
ret = rk_udphy_reset_deassert(udphy, "cmn");
if (ret)
goto assert_resets;
@@ -897,7 +897,7 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
num_lanes = device_property_count_u32(udphy->dev, "rockchip,dp-lane-mux");
if (num_lanes < 0) {
dev_dbg(udphy->dev, "no dp-lane-mux, following dp alt mode\n");
- udphy->mode = UDPHY_MODE_USB;
+ udphy->hw_mode = UDPHY_MODE_USB;
return 0;
}
@@ -926,10 +926,10 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
}
}
- udphy->mode = UDPHY_MODE_DP;
+ udphy->hw_mode = UDPHY_MODE_DP;
udphy->dp_lanes = num_lanes;
if (num_lanes == 1 || num_lanes == 2) {
- udphy->mode |= UDPHY_MODE_USB;
+ udphy->hw_mode |= UDPHY_MODE_USB;
udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP) ||
(udphy->lane_mux_sel[1] == PHY_LANE_MUX_DP);
}
@@ -988,7 +988,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
{
int ret;
- if (!(udphy->mode & mode)) {
+ if (!(udphy->hw_mode & mode)) {
dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
return 0;
}
@@ -1005,7 +1005,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
return ret;
}
- if (!udphy->hs && udphy->mode & UDPHY_MODE_USB)
+ if (!udphy->hs && udphy->hw_mode & UDPHY_MODE_USB)
rk_udphy_u3_port_disable(udphy, false);
udphy->phy_needs_reinit = false;
@@ -1022,7 +1022,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
return ret;
}
- if (!udphy->hs && udphy->mode & UDPHY_MODE_USB)
+ if (!udphy->hs && udphy->hw_mode & UDPHY_MODE_USB)
rk_udphy_u3_port_disable(udphy, false);
udphy->phy_needs_reinit = false;
@@ -1036,7 +1036,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
static void rk_udphy_power_off(struct rk_udphy *udphy, u8 mode)
{
- if (!(udphy->mode & mode)) {
+ if (!(udphy->hw_mode & mode)) {
dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
return;
}
@@ -1295,7 +1295,7 @@ static int rk_udphy_usb3_phy_init(struct phy *phy)
guard(mutex)(&udphy->mutex);
/* DP only or high-speed, disable U3 port */
- if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) {
+ if (!(udphy->hw_mode & UDPHY_MODE_USB) || udphy->hs) {
rk_udphy_u3_port_disable(udphy, true);
return 0;
}
@@ -1310,7 +1310,7 @@ static int rk_udphy_usb3_phy_exit(struct phy *phy)
guard(mutex)(&udphy->mutex);
/* DP only or high-speed */
- if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs)
+ if (!(udphy->hw_mode & UDPHY_MODE_USB) || udphy->hs)
return 0;
rk_udphy_power_off(udphy, UDPHY_MODE_USB);
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v15 4/6] phy: rockchip: usbdp: Fix power state handling
2026-09-15 15:32 [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3) Sebastian Reichel
` (2 preceding siblings ...)
2026-09-15 15:32 ` [PATCH v15 3/6] phy: rockchip: usbdp: Rename mode to hw_mode Sebastian Reichel
@ 2026-09-15 15:32 ` Sebastian Reichel
2026-09-26 7:59 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 5/6] phy: rockchip: usbdp: Re-init PHY on mux change Sebastian Reichel
2026-09-15 15:32 ` [PATCH v15 6/6] phy: rockchip: usbdp: Add USB-C state without DP enabled Sebastian Reichel
5 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-15 15:32 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam,
Heiko Stuebner, Zhang Yubing, Frank Wang
Cc: linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
kernel, Sebastian Reichel, Igor Paunovic
Restructure power state handling by introducing sw_mode in addition
to the hw_mode field, so that the PHY knows about the currently
supported modes from the hardware perspective, the current modes
requested by software and the actual hardware status.
Now anything updating either the hardware or software state can simply
update the status field and call rk_udphy_update_power_state().
This makes it a lot more obvious what is going on and also fixes a few
potential resource leaks identified by Sashiko as a side-effect. For
example if USB3 is requested by software while the USB-C is in DP-only
mode, things are decently handled after this.
Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 143 +++++++++++++++++++-----------
1 file changed, 90 insertions(+), 53 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index b06d94db42ea..867f356f394d 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -172,9 +172,10 @@ struct rk_udphy {
/* PHY status management */
bool flip;
- bool phy_needs_reinit;
+ bool phy_needs_reinit; /* lane mux changed */
u8 hw_mode; /* modes currently supported by hardware */
- u8 status;
+ u8 sw_mode; /* modes currently requested */
+ u8 status; /* current PHY power state */
/* utilized for USB */
bool hs; /* flag for high-speed */
@@ -984,70 +985,95 @@ static int rk_udphy_parse_dt(struct rk_udphy *udphy)
return rk_udphy_reset_init(udphy, dev);
}
-static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
+static int rk_udphy_update_power_state(struct rk_udphy *udphy)
{
+ bool usb3_port_enable;
+ u8 target_mode;
int ret;
- if (!(udphy->hw_mode & mode)) {
- dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
+ /*
+ * Initialize PHY mode according to the hardware setup (either described
+ * in DT or negotiated via the Type-C controller) instead of requesting
+ * only the needed PHY side, because that would break the USB/DP data
+ * streams when the other PHY is being requested. This is not an issue
+ * during the Type-C negotiation as that happens during the hotplug phase
+ * and not during normal operation. Also disable everything if the
+ * software has not requested anything, as there shouldn't be any active
+ * data streams in that case.
+ */
+ target_mode = udphy->hw_mode;
+ if (udphy->sw_mode == UDPHY_MODE_NONE)
+ target_mode = UDPHY_MODE_NONE;
+
+ usb3_port_enable = !udphy->hs && (target_mode & UDPHY_MODE_USB);
+
+ if (!udphy->phy_needs_reinit && udphy->status == target_mode) {
+ if (udphy->sw_mode & UDPHY_MODE_USB)
+ rk_udphy_u3_port_disable(udphy, !usb3_port_enable);
return 0;
}
- if (udphy->status == UDPHY_MODE_NONE) {
- phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_PRE_RESET);
+ /* Avoid to re-init disabled PHY */
+ if (udphy->status == target_mode && target_mode == UDPHY_MODE_NONE)
+ return 0;
+ /*
+ * Inform DWC3 driver, that we are about to reset the PHY, so that it can
+ * assert its PIPE reset lines and avoid DWC3 getting into a buggy state.
+ * This is intentionally done for a PHY disable, since that also changes
+ * the clocks routed to the PHY.
+ */
+ ret = phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_PRE_RESET);
+ if (ret)
+ return ret;
+
+ /*
+ * Disable USB3 port, which among other things re-routes a DWC3 clock to
+ * avoid SErrors when the DWC3 registers are accessed while the PHY is
+ * disabled. This is only done, when the DWC3 is running as the accessed
+ * GRF registers and in PD_USB.
+ */
+ if (udphy->sw_mode & UDPHY_MODE_USB) {
rk_udphy_u3_port_disable(udphy, true);
udelay(10);
+ }
+ if (udphy->status == UDPHY_MODE_NONE) {
+ /* Power up (incl. clocks) */
ret = rk_udphy_setup(udphy);
if (ret) {
phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
return ret;
}
-
- if (!udphy->hs && udphy->hw_mode & UDPHY_MODE_USB)
- rk_udphy_u3_port_disable(udphy, false);
- udphy->phy_needs_reinit = false;
-
- phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
- } else if (udphy->phy_needs_reinit) {
- phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_PRE_RESET);
-
- rk_udphy_u3_port_disable(udphy, true);
- udelay(10);
-
+ } else if (target_mode == UDPHY_MODE_NONE) {
+ /* Power down (incl. clocks) */
+ rk_udphy_disable(udphy);
+ } else {
+ /* Mode change => re-init */
ret = rk_udphy_init(udphy);
if (ret) {
phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
return ret;
}
-
- if (!udphy->hs && udphy->hw_mode & UDPHY_MODE_USB)
- rk_udphy_u3_port_disable(udphy, false);
- udphy->phy_needs_reinit = false;
-
- phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
}
- udphy->status |= mode;
-
- return 0;
-}
+ /* Ensure USB3 support is enabled when supported */
+ if (udphy->sw_mode & UDPHY_MODE_USB)
+ rk_udphy_u3_port_disable(udphy, !usb3_port_enable);
-static void rk_udphy_power_off(struct rk_udphy *udphy, u8 mode)
-{
- if (!(udphy->hw_mode & mode)) {
- dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
- return;
- }
-
- if (!udphy->status)
- return;
+ /*
+ * Inform DWC3, that we are done with the reset, so that it can deassert
+ * its PIPE reset line. This is sent in pair with a PRE_RESET allowing
+ * consumer driver to do paired resource requests (e.g. clocks) in their
+ * notification handlers. As we reroute the clocks, its also fine to
+ * send this after completely disabling the PHY.
+ */
+ phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_POST_RESET);
- udphy->status &= ~mode;
+ udphy->status = target_mode;
+ udphy->phy_needs_reinit = false;
- if (udphy->status == UDPHY_MODE_NONE)
- rk_udphy_disable(udphy);
+ return 0;
}
static int rk_udphy_dp_phy_power_on(struct phy *phy)
@@ -1056,11 +1082,15 @@ static int rk_udphy_dp_phy_power_on(struct phy *phy)
int ret;
scoped_guard(mutex, &udphy->mutex) {
+ udphy->sw_mode |= UDPHY_MODE_DP;
+
phy_set_bus_width(phy, udphy->dp_lanes);
- ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
- if (ret)
+ ret = rk_udphy_update_power_state(udphy);
+ if (ret) {
+ udphy->sw_mode &= ~UDPHY_MODE_DP;
return ret;
+ }
rk_udphy_dp_lane_enable(udphy, udphy->dp_lanes);
@@ -1083,10 +1113,10 @@ static int rk_udphy_dp_phy_power_off(struct phy *phy)
guard(mutex)(&udphy->mutex);
- rk_udphy_dp_lane_enable(udphy, 0);
- rk_udphy_power_off(udphy, UDPHY_MODE_DP);
+ udphy->sw_mode &= ~UDPHY_MODE_DP;
- return 0;
+ rk_udphy_dp_lane_enable(udphy, 0);
+ return rk_udphy_update_power_state(udphy);
}
/*
@@ -1291,16 +1321,24 @@ static const struct phy_ops rk_udphy_dp_phy_ops = {
static int rk_udphy_usb3_phy_init(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
+ int ret;
guard(mutex)(&udphy->mutex);
- /* DP only or high-speed, disable U3 port */
- if (!(udphy->hw_mode & UDPHY_MODE_USB) || udphy->hs) {
+ if (udphy->hs) {
rk_udphy_u3_port_disable(udphy, true);
return 0;
}
- return rk_udphy_power_on(udphy, UDPHY_MODE_USB);
+ udphy->sw_mode |= UDPHY_MODE_USB;
+
+ ret = rk_udphy_update_power_state(udphy);
+ if (ret) {
+ udphy->sw_mode &= ~UDPHY_MODE_USB;
+ return ret;
+ }
+
+ return 0;
}
static int rk_udphy_usb3_phy_exit(struct phy *phy)
@@ -1309,13 +1347,12 @@ static int rk_udphy_usb3_phy_exit(struct phy *phy)
guard(mutex)(&udphy->mutex);
- /* DP only or high-speed */
- if (!(udphy->hw_mode & UDPHY_MODE_USB) || udphy->hs)
+ if (udphy->hs)
return 0;
- rk_udphy_power_off(udphy, UDPHY_MODE_USB);
+ udphy->sw_mode &= ~UDPHY_MODE_USB;
- return 0;
+ return rk_udphy_update_power_state(udphy);
}
static const struct phy_ops rk_udphy_usb3_phy_ops = {
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v15 5/6] phy: rockchip: usbdp: Re-init PHY on mux change
2026-09-15 15:32 [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3) Sebastian Reichel
` (3 preceding siblings ...)
2026-09-15 15:32 ` [PATCH v15 4/6] phy: rockchip: usbdp: Fix power state handling Sebastian Reichel
@ 2026-09-15 15:32 ` Sebastian Reichel
2026-09-26 8:00 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 6/6] phy: rockchip: usbdp: Add USB-C state without DP enabled Sebastian Reichel
5 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-15 15:32 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam,
Heiko Stuebner, Zhang Yubing, Frank Wang
Cc: linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
kernel, Sebastian Reichel, Igor Paunovic
Ensure that the right part of the PHY are powered up when the
mode changes. This ensures the PHY is re-initialized in the
following two scenarios, which are currently broken:
- cable orientation changes without DP being involved
- switching from DP-only into a mode with USB support
Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 867f356f394d..ca01c1112c0f 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1391,7 +1391,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
rk_udphy_set_typec_state(udphy, state->mode);
- return 0;
+ return rk_udphy_update_power_state(udphy);
}
static void rk_udphy_typec_mux_unregister(void *data)
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v15 6/6] phy: rockchip: usbdp: Add USB-C state without DP enabled
2026-09-15 15:32 [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3) Sebastian Reichel
` (4 preceding siblings ...)
2026-09-15 15:32 ` [PATCH v15 5/6] phy: rockchip: usbdp: Re-init PHY on mux change Sebastian Reichel
@ 2026-09-15 15:32 ` Sebastian Reichel
2026-09-26 8:42 ` Manivannan Sadhasivam
5 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-15 15:32 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam,
Heiko Stuebner, Zhang Yubing, Frank Wang
Cc: linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel,
kernel, Sebastian Reichel, Igor Paunovic
The driver currently only differs between 4 lanes DP mode or combined DP
+ USB3 mode. This makes sense from a lane routing point of view, as the
hardware only has 2 lanes of USB3.
But adding a separate state for USB-only helps with power management,
since we always power up all PHY parts according to the current hardware
setup to avoid data stream interruptions. Even if some lanes are muxed
to the DP controller there is no need to keep the DP side enabled if
something without DP AltMode is plugged into USB-C.
This potentially triggers some more USB reconnections during the PD
AltMode negotiation when switching from USB-only to combined USB+DP
mode. This should be fine, as the cable is freshly plugged at this
point.
Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 57 ++++++++++++++++++-------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index ca01c1112c0f..f95c3216364f 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -579,32 +579,14 @@ static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
}
-static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 hw_mode)
+static void rk_udphy_set_lane_mux(struct rk_udphy *udphy)
{
- if (udphy->hw_mode == hw_mode)
- return;
-
- udphy->phy_needs_reinit = true;
- udphy->hw_mode = hw_mode;
-}
-
-static void rk_udphy_set_typec_state(struct rk_udphy *udphy, unsigned long state)
-{
- u8 hw_mode;
-
- switch (state) {
- case TYPEC_DP_STATE_C:
- case TYPEC_DP_STATE_E:
+ if (udphy->dp_lanes == 4) {
udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
- hw_mode = UDPHY_MODE_DP;
- udphy->dp_lanes = 4;
- break;
-
- case TYPEC_DP_STATE_D:
- default:
+ } else {
if (udphy->flip) {
udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
@@ -616,12 +598,39 @@ static void rk_udphy_set_typec_state(struct rk_udphy *udphy, unsigned long state
udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
}
- hw_mode = UDPHY_MODE_DP_USB;
- udphy->dp_lanes = 2;
+ }
+}
+
+static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 hw_mode, u8 dp_lanes)
+{
+ if (udphy->hw_mode == hw_mode && udphy->dp_lanes == dp_lanes)
+ return;
+
+ udphy->phy_needs_reinit = true;
+ udphy->hw_mode = hw_mode;
+ udphy->dp_lanes = dp_lanes;
+}
+
+static void rk_udphy_set_typec_state(struct rk_udphy *udphy, unsigned long state)
+{
+ switch (state) {
+ case TYPEC_DP_STATE_C:
+ case TYPEC_DP_STATE_E:
+ rk_udphy_mode_set(udphy, UDPHY_MODE_DP, 4);
+ break;
+
+ case TYPEC_DP_STATE_D:
+ rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB, 2);
+ break;
+
+ case TYPEC_STATE_SAFE:
+ case TYPEC_STATE_USB:
+ default:
+ rk_udphy_mode_set(udphy, UDPHY_MODE_USB, 0);
break;
}
- rk_udphy_mode_set(udphy, hw_mode);
+ rk_udphy_set_lane_mux(udphy);
}
static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support
2026-09-15 15:32 ` [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support Sebastian Reichel
@ 2026-09-26 7:54 ` Manivannan Sadhasivam
2026-09-28 16:18 ` Sebastian Reichel
0 siblings, 1 reply; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-26 7:54 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Zhang Yubing,
Frank Wang, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, Igor Paunovic
On Tue, Sep 15, 2026 at 05:32:48PM +0200, Sebastian Reichel wrote:
> To resolve issues with running into permanent "cmn ana lcpll lock
> timeout" errors after a few device replugs, add support for reset
> notifications, which will be handled by the DWC3 driver to gracefully
> handle the PHY being disabled. This avoids corrupting the controller's
> internal state and the PIPE interface between the USB3 controller and
> the PHY, thus fixing the issue.
>
> Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/phy/rockchip/phy-rockchip-usbdp.c | 19 +++++++++++++++++--
> 1 file changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> index e748acdd2d31..0f39982c70b1 100644
> --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> @@ -1004,24 +1004,39 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
> }
>
> if (udphy->status == UDPHY_MODE_NONE) {
> + phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_PRE_RESET);
> +
> + rk_udphy_u3_port_disable(udphy, true);
This change is not described in the commit message.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v15 2/6] phy: rockchip: usbdp: Drop -EPROBE_DEFER hack
2026-09-15 15:32 ` [PATCH v15 2/6] phy: rockchip: usbdp: Drop -EPROBE_DEFER hack Sebastian Reichel
@ 2026-09-26 7:55 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-26 7:55 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Zhang Yubing,
Frank Wang, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, Igor Paunovic
On Tue, Sep 15, 2026 at 05:32:49PM +0200, Sebastian Reichel wrote:
> The hack to return -EPROBE_DEFER when the lcpll lock timeouts is no
> longer needed. The driver now does a reset during its PHY init, which
> avoids the problem.
>
> Since rk_udphy_status_check() is called after the probe, it should not
> return -EPROBE_DEFER.
>
> Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v15 3/6] phy: rockchip: usbdp: Rename mode to hw_mode
2026-09-15 15:32 ` [PATCH v15 3/6] phy: rockchip: usbdp: Rename mode to hw_mode Sebastian Reichel
@ 2026-09-26 7:57 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-26 7:57 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Zhang Yubing,
Frank Wang, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, Igor Paunovic
On Tue, Sep 15, 2026 at 05:32:50PM +0200, Sebastian Reichel wrote:
> Rename mode field to hw_mode to make clear that this is the modes
> currently supported by the hardware, but not necessarily requested
> by software. I.e. it is only set by either the USB-C state machine
> or device-tree if the PHY is used in a fixed routing setup.
>
> Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v15 4/6] phy: rockchip: usbdp: Fix power state handling
2026-09-15 15:32 ` [PATCH v15 4/6] phy: rockchip: usbdp: Fix power state handling Sebastian Reichel
@ 2026-09-26 7:59 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-26 7:59 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Zhang Yubing,
Frank Wang, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, Igor Paunovic
On Tue, Sep 15, 2026 at 05:32:51PM +0200, Sebastian Reichel wrote:
> Restructure power state handling by introducing sw_mode in addition
> to the hw_mode field, so that the PHY knows about the currently
> supported modes from the hardware perspective, the current modes
> requested by software and the actual hardware status.
>
> Now anything updating either the hardware or software state can simply
> update the status field and call rk_udphy_update_power_state().
>
> This makes it a lot more obvious what is going on and also fixes a few
> potential resource leaks identified by Sashiko as a side-effect. For
> example if USB3 is requested by software while the USB-C is in DP-only
> mode, things are decently handled after this.
>
> Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v15 5/6] phy: rockchip: usbdp: Re-init PHY on mux change
2026-09-15 15:32 ` [PATCH v15 5/6] phy: rockchip: usbdp: Re-init PHY on mux change Sebastian Reichel
@ 2026-09-26 8:00 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-26 8:00 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Zhang Yubing,
Frank Wang, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, Igor Paunovic
On Tue, Sep 15, 2026 at 05:32:52PM +0200, Sebastian Reichel wrote:
> Ensure that the right part of the PHY are powered up when the
> mode changes. This ensures the PHY is re-initialized in the
> following two scenarios, which are currently broken:
>
> - cable orientation changes without DP being involved
> - switching from DP-only into a mode with USB support
>
> Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
> Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v15 6/6] phy: rockchip: usbdp: Add USB-C state without DP enabled
2026-09-15 15:32 ` [PATCH v15 6/6] phy: rockchip: usbdp: Add USB-C state without DP enabled Sebastian Reichel
@ 2026-09-26 8:42 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2026-09-26 8:42 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Zhang Yubing,
Frank Wang, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, Igor Paunovic
On Tue, Sep 15, 2026 at 05:32:53PM +0200, Sebastian Reichel wrote:
> The driver currently only differs between 4 lanes DP mode or combined DP
> + USB3 mode. This makes sense from a lane routing point of view, as the
> hardware only has 2 lanes of USB3.
>
> But adding a separate state for USB-only helps with power management,
> since we always power up all PHY parts according to the current hardware
> setup to avoid data stream interruptions. Even if some lanes are muxed
> to the DP controller there is no need to keep the DP side enabled if
> something without DP AltMode is plugged into USB-C.
>
> This potentially triggers some more USB reconnections during the PD
> AltMode negotiation when switching from USB-only to combined USB+DP
> mode. This should be fine, as the cable is freshly plugged at this
> point.
>
> Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support
2026-09-26 7:54 ` Manivannan Sadhasivam
@ 2026-09-28 16:18 ` Sebastian Reichel
0 siblings, 0 replies; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-28 16:18 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Vinod Koul, Neil Armstrong, Heiko Stuebner, Zhang Yubing,
Frank Wang, linux-phy, linux-arm-kernel, linux-rockchip,
linux-kernel, kernel, Igor Paunovic
[-- Attachment #1: Type: text/plain, Size: 1967 bytes --]
Hello Mani,
On Sat, Sep 26, 2026 at 09:54:56AM +0200, Manivannan Sadhasivam wrote:
> On Tue, Sep 15, 2026 at 05:32:48PM +0200, Sebastian Reichel wrote:
> > To resolve issues with running into permanent "cmn ana lcpll lock
> > timeout" errors after a few device replugs, add support for reset
> > notifications, which will be handled by the DWC3 driver to gracefully
> > handle the PHY being disabled. This avoids corrupting the controller's
> > internal state and the PIPE interface between the USB3 controller and
> > the PHY, thus fixing the issue.
> >
> > Tested-by: Igor Paunovic <royalnet026@gmail.com> # Orange Pi 5 Plus
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > ---
> > drivers/phy/rockchip/phy-rockchip-usbdp.c | 19 +++++++++++++++++--
> > 1 file changed, 17 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> > index e748acdd2d31..0f39982c70b1 100644
> > --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
> > +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
> > @@ -1004,24 +1004,39 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
> > }
> >
> > if (udphy->status == UDPHY_MODE_NONE) {
> > + phy_notify_reset(udphy->phy_u3, PHY_NOTIFY_PRE_RESET);
> > +
> > + rk_udphy_u3_port_disable(udphy, true);
>
> This change is not described in the commit message.
Good catch. I'm not sure when that sneaked in. I will split it into
its own follow-up patch.
FWIW these two things are a little bit interleaved:
resetting the PHY results in disabled clocks, results in SError when
dwc3 driver tries to access its registers during the PHY reset. This
is worked around by the u3 port disabling, which reroutes the clock.
But doing that increases the chance a lot, that the PHY does not
start up properly again, which requires the reset notifier bits.
Greetings,
-- Sebastian
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-09-28 16:18 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-15 15:32 [PATCH v15 0/6] phy: rockchip: usbdp: Clean up the mess (part 3) Sebastian Reichel
2026-09-15 15:32 ` [PATCH v15 1/6] phy: rockchip: usbdp: Add phy reset notification support Sebastian Reichel
2026-09-26 7:54 ` Manivannan Sadhasivam
2026-09-28 16:18 ` Sebastian Reichel
2026-09-15 15:32 ` [PATCH v15 2/6] phy: rockchip: usbdp: Drop -EPROBE_DEFER hack Sebastian Reichel
2026-09-26 7:55 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 3/6] phy: rockchip: usbdp: Rename mode to hw_mode Sebastian Reichel
2026-09-26 7:57 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 4/6] phy: rockchip: usbdp: Fix power state handling Sebastian Reichel
2026-09-26 7:59 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 5/6] phy: rockchip: usbdp: Re-init PHY on mux change Sebastian Reichel
2026-09-26 8:00 ` Manivannan Sadhasivam
2026-09-15 15:32 ` [PATCH v15 6/6] phy: rockchip: usbdp: Add USB-C state without DP enabled Sebastian Reichel
2026-09-26 8:42 ` Manivannan Sadhasivam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®