* [PATCH 0/2] phy: rockchip: inno-usb2: fix gadget mode disconnection after 6 seconds
@ 2025-07-22 8:43 Luca Ceresoli
2025-07-22 8:43 ` [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in gadget mode Luca Ceresoli
2025-07-22 8:43 ` [PATCH 2/2] phy: rockchip: inno-usb2: fix communication disruption " Luca Ceresoli
0 siblings, 2 replies; 3+ messages in thread
From: Luca Ceresoli @ 2025-07-22 8:43 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Heiko Stuebner, William Wu
Cc: Kever Yang, Minas Harutyunyan, Alan Stern, Louis Chauvet,
Hervé Codina, Thomas Petazzoni, linux-phy, linux-rockchip,
linux-usb, linux-arm-kernel, linux-kernel, Luca Ceresoli
The USB OTG port of the RK3308 exibits a bug when:
- configured as peripheral, and
- used in gadget mode, and
- the USB cable is connected since before booting
The symptom is: about 6 seconds after configuring gadget mode the device is
disconnected and then re-enumerated. This happens only once per boot.
Investigation showed that in this configuration the charger detection code
turns off the PHY after 6 seconds. Patch 1 avoids this when a cable is
connected (VBUS present).
After patch 1 the connection is stable but communication stops after 6
seconds. this is addressed by patch 2.
The topic had been discussed in [0]. Thanks Alan and Minas for the
discussion and Louis for having found the 1st issue, leading to patch 1.
[0] https://lore.kernel.org/lkml/20250414185458.7767aabc@booty/
Luca
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Louis Chauvet (1):
phy: rockchip: inno-usb2: fix disconnection in gadget mode
Luca Ceresoli (1):
phy: rockchip: inno-usb2: fix communication disruption in gadget mode
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
---
base-commit: 15240745d6cd14183d112249a9fff87fb968b859
change-id: 20250718-rk3308-fix-usb-gadget-phy-disconnect-d7de71fb28b4
Best regards,
--
Luca Ceresoli <luca.ceresoli@bootlin.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in gadget mode
2025-07-22 8:43 [PATCH 0/2] phy: rockchip: inno-usb2: fix gadget mode disconnection after 6 seconds Luca Ceresoli
@ 2025-07-22 8:43 ` Luca Ceresoli
2025-07-22 8:43 ` [PATCH 2/2] phy: rockchip: inno-usb2: fix communication disruption " Luca Ceresoli
1 sibling, 0 replies; 3+ messages in thread
From: Luca Ceresoli @ 2025-07-22 8:43 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Heiko Stuebner, William Wu
Cc: Kever Yang, Minas Harutyunyan, Alan Stern, Louis Chauvet,
Hervé Codina, Thomas Petazzoni, linux-phy, linux-rockchip,
linux-usb, linux-arm-kernel, linux-kernel, Luca Ceresoli
From: Louis Chauvet <louis.chauvet@bootlin.com>
When the OTG USB port is used to power to SoC, configured as peripheral and
used in gadget mode, there is a disconnection about 6 seconds after the
gadget is configured and enumerated.
The problem was observed on a Radxa Rock Pi S board, which can only be
powered by the only USB-C connector. That connector is the only one usable
in gadget mode. This implies the USB cable is connected from before boot
and never disconnects while the kernel runs.
The problem happens because of the PHY driver code flow, summarized as:
* UDC start code (triggered via configfs at any time after boot)
-> phy_init
-> rockchip_usb2phy_init
-> schedule_delayed_work(otg_sm_work [A], 6 sec)
-> phy_power_on
-> rockchip_usb2phy_power_on
-> enable clock
-> rockchip_usb2phy_reset
* Now the gadget interface is up and running.
* 6 seconds later otg_sm_work starts [A]
-> rockchip_usb2phy_otg_sm_work():
if (B_IDLE state && VBUS present && ...):
schedule_delayed_work(&rport->chg_work [B], 0);
* immediately the chg_detect_work starts [B]
-> rockchip_chg_detect_work():
if chg_state is UNDEFINED:
if (!rport->suspended):
rockchip_usb2phy_power_off() <--- [X]
At [X], the PHY is powered off, causing a disconnection. This quickly
triggers a new connection and following re-enumeration, but any connection
that had been established during the 6 seconds is broken.
The code already checks for !rport->suspended, so add a guard for VBUS as
well to avoid a disconnection when a cable is connected.
Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399")
Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc@booty/
Co-developed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index b0f23690ec3002202c0f33a6988f5509622fa10e..0106d7b7ae24ead91d9c996daaa56671de02a39a 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -821,14 +821,16 @@ static void rockchip_chg_detect_work(struct work_struct *work)
container_of(work, struct rockchip_usb2phy_port, chg_work.work);
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
struct regmap *base = get_reg_base(rphy);
- bool is_dcd, tmout, vout;
+ bool is_dcd, tmout, vout, vbus_attach;
unsigned long delay;
+ vbus_attach = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
+
dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
rphy->chg_state);
switch (rphy->chg_state) {
case USB_CHG_STATE_UNDEFINED:
- if (!rport->suspended)
+ if (!rport->suspended && !vbus_attach)
rockchip_usb2phy_power_off(rport->phy);
/* put the controller in non-driving mode */
property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
--
2.50.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] phy: rockchip: inno-usb2: fix communication disruption in gadget mode
2025-07-22 8:43 [PATCH 0/2] phy: rockchip: inno-usb2: fix gadget mode disconnection after 6 seconds Luca Ceresoli
2025-07-22 8:43 ` [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in gadget mode Luca Ceresoli
@ 2025-07-22 8:43 ` Luca Ceresoli
1 sibling, 0 replies; 3+ messages in thread
From: Luca Ceresoli @ 2025-07-22 8:43 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Heiko Stuebner, William Wu
Cc: Kever Yang, Minas Harutyunyan, Alan Stern, Louis Chauvet,
Hervé Codina, Thomas Petazzoni, linux-phy, linux-rockchip,
linux-usb, linux-arm-kernel, linux-kernel, Luca Ceresoli
When the OTG USB port is used to power to SoC, configured as peripheral and
used in gadget mode, communication stops without notice about 6 seconds
after the gadget is configured and enumerated.
The problem was observed on a Radxa Rock Pi S board, which can only be
powered by the only USB-C connector. That connector is the only one usable
in gadget mode. This implies the USB cable is connected from before boot
and never disconnects while the kernel runs.
The related code flow in the PHY driver code can be summarized as:
* UDC start code (triggered via configfs at any time after boot)
-> phy_init
-> rockchip_usb2phy_init
-> schedule_delayed_work(otg_sm_work [A], 6 sec)
-> phy_power_on
-> rockchip_usb2phy_power_on
-> enable clock
-> rockchip_usb2phy_reset
* Now the gadget interface is up and running.
* 6 seconds later otg_sm_work starts [A]
-> rockchip_usb2phy_otg_sm_work():
if (B_IDLE state && VBUS present && ...):
schedule_delayed_work(&rport->chg_work [B], 0);
* immediately the chg_detect_work starts [B]
-> rockchip_chg_detect_work():
if chg_state is UNDEFINED:
property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); [Y]
* rockchip_chg_detect_work() changes state and re-triggers itself a few
times until it reached the DETECTED state:
-> rockchip_chg_detect_work():
if chg_state is DETECTED:
property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); [Z]
At [Y] there is no disconnection and the USB device appears still present
to userspace, but all existing communications stop. E.g. using a CDC serial
gadget, the /dev/tty* devices are still present on both host and device,
but no data is transferred anymore. The later call with a 'true' argument
at [Z] does not restore it.
Due to the lack of documentation, what chg_det.opmode does exactly is not
clear, however by code inspection it seems reasonable that is disables
something needed to keep the communication working, and testing proves that
disabling these lines lefs gadget mode keep working. So prevent changes to
chg_det.opmode when there is a cable connected (VBUS present).
Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399")
Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc@booty/
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 0106d7b7ae24ead91d9c996daaa56671de02a39a..e5efae7b013590f5b0bf65654008cdc167f52e3f 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -833,7 +833,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
if (!rport->suspended && !vbus_attach)
rockchip_usb2phy_power_off(rport->phy);
/* put the controller in non-driving mode */
- property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
+ if (!vbus_attach)
+ property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
/* Start DCD processing stage 1 */
rockchip_chg_enable_dcd(rphy, true);
rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
@@ -896,7 +897,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
fallthrough;
case USB_CHG_STATE_DETECTED:
/* put the controller in normal mode */
- property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
+ if (!vbus_attach)
+ property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
dev_dbg(&rport->phy->dev, "charger = %s\n",
chg_to_string(rphy->chg_type));
--
2.50.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-07-22 8:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-22 8:43 [PATCH 0/2] phy: rockchip: inno-usb2: fix gadget mode disconnection after 6 seconds Luca Ceresoli
2025-07-22 8:43 ` [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in gadget mode Luca Ceresoli
2025-07-22 8:43 ` [PATCH 2/2] phy: rockchip: inno-usb2: fix communication disruption " Luca Ceresoli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).