Skip to content

Commit c25b644

Browse files
dianderswuliangfeng
authored andcommitted
FROMLIST: phy: rockchip-typec: Try to turn the PHY on several times
Bind / unbind stress testing of the USB controller on rk3399 found that we'd often end up with lots of failures that looked like this: phy phy-ff800000.phy.9: phy poweron failed --> -110 dwc3 fe900000.dwc3: failed to initialize core dwc3: probe of fe900000.dwc3 failed with error -110 Those errors were sometimes seen at bootup too, in which case USB peripherals wouldn't work until unplugged and re-plugged in. I spent some time trying to figure out why the PHY was failing to power on but I wasn't able to. Possibly this has to do with the fact that the PHY docs say that the USB controller "needs to be held in reset to hold pipe power state in P2 before initializing the Type C PHY" but that doesn't appear to be easy to do with the dwc3 driver today. Messing around with the ordering of the reset vs. the PHY initialization in the dwc3 driver didn't seem to fix things. I did, however, find that if I simply retry the power on it seems to have a good chance of working. So let's add some retries. I ran a pretty tight bind/unbind loop overnight. When I did so, I found that I need to retry between 1% and 2% of the time. Overnight I found only a small handful of times where I needed 2 retries. I never found a case where I needed 3 retries. I'm completely aware of the fact that this is quite an ugly hack and I wish I didn't have to resort to it, but I have no other real idea how to make this hardware reliable. If Rockchip in the future can come up with a solution we can always revert this hack. Until then, let's at least have something that works. This patch is tested atop Enric's latest dwc3 patch series ending at: https://patchwork.kernel.org/patch/10095527/ ...but it could be applied independently of that series without any bad effects. For some more details on this bug, you can refer to: https://bugs.chromium.org/p/chromium/issues/detail?id=783464 Change-Id: I7909731247739694f56bf89ab3064889f2b34d3c Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: William Wu <william.wu@rock-chips.com> (am from https://patchwork.kernel.org/patch/10105833/)
1 parent c7719f8 commit c25b644

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

drivers/phy/rockchip/phy-rockchip-typec.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@
349349
#define MODE_DFP_USB BIT(1)
350350
#define MODE_DFP_DP BIT(2)
351351

352+
#define POWER_ON_TRIES 5
353+
352354
struct usb3phy_reg {
353355
u32 offset;
354356
u32 enable_bit;
@@ -840,9 +842,8 @@ static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
840842
return 0;
841843
}
842844

843-
static int rockchip_usb3_phy_power_on(struct phy *phy)
845+
static int _rockchip_usb3_phy_power_on(struct rockchip_typec_phy *tcphy)
844846
{
845-
struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
846847
struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs;
847848
const struct usb3phy_reg *reg = &cfg->pipe_status;
848849
int timeout, new_mode, ret = 0;
@@ -891,6 +892,24 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
891892
return ret;
892893
}
893894

895+
static int rockchip_usb3_phy_power_on(struct phy *phy)
896+
{
897+
struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
898+
int ret;
899+
int tries;
900+
901+
for (tries = 0; tries < POWER_ON_TRIES; tries++) {
902+
ret = _rockchip_usb3_phy_power_on(tcphy);
903+
if (!ret)
904+
break;
905+
}
906+
907+
if (tries && !ret)
908+
dev_info(tcphy->dev, "Needed %d loops to turn on\n", tries);
909+
910+
return ret;
911+
}
912+
894913
static int rockchip_usb3_phy_power_off(struct phy *phy)
895914
{
896915
struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);

0 commit comments

Comments
 (0)