Message ID | 20210613145936.9902-1-digetx@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 6f8d39a8ef55efde414b6e574384acbce70c3119 |
Headers | show |
Series | [v1,1/2] usb: phy: tegra: Wait for VBUS wakeup status deassertion on suspend | expand |
On 21-06-13 17:59:35, Dmitry Osipenko wrote: > Some devices need an extra delay after losing VBUS, otherwise VBUS may > be detected as active at suspend time, preventing the PHY's suspension > by the VBUS detection sensor. This problem was found on Asus Transformer > TF700T (Tegra30) tablet device, where the USB PHY wakes up immediately > from suspend because VBUS sensor continues to detect VBUS as active after > disconnection. We need to poll the PHY's VBUS wakeup status until it's > deasserted before suspending PHY in order to fix this minor trouble. > > Fixes: 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode") > Reported-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T > Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > --- > drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c > index fc5c6cab58ba..ff482c694200 100644 > --- a/drivers/usb/phy/phy-tegra-usb.c > +++ b/drivers/usb/phy/phy-tegra-usb.c > @@ -64,6 +64,7 @@ > #define A_VBUS_VLD_WAKEUP_EN BIT(30) > > #define USB_PHY_VBUS_WAKEUP_ID 0x408 > +#define VBUS_WAKEUP_STS BIT(10) > #define VBUS_WAKEUP_WAKEUP_EN BIT(30) > > #define USB1_LEGACY_CTRL 0x410 > @@ -645,6 +646,15 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) > void __iomem *base = phy->regs; > u32 val; > > + /* > + * Give hardware time to settle down after VBUS disconnection, > + * otherwise PHY will immediately wake up from suspend. > + */ > + if (phy->wakeup_enabled && phy->mode != USB_DR_MODE_HOST) > + readl_relaxed_poll_timeout(base + USB_PHY_VBUS_WAKEUP_ID, > + val, !(val & VBUS_WAKEUP_STS), > + 5000, 100000); > + Where will clear VBUS_WAKEUP_STS? Or it will be cleared by HW after VBUS lower than B Session Valid?
On 21-06-13 17:59:35, Dmitry Osipenko wrote: > Some devices need an extra delay after losing VBUS, otherwise VBUS may > be detected as active at suspend time, preventing the PHY's suspension > by the VBUS detection sensor. This problem was found on Asus Transformer > TF700T (Tegra30) tablet device, where the USB PHY wakes up immediately > from suspend because VBUS sensor continues to detect VBUS as active after > disconnection. We need to poll the PHY's VBUS wakeup status until it's > deasserted before suspending PHY in order to fix this minor trouble. > > Fixes: 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode") > Reported-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T > Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Reviewed-by: Peter Chen <peter.chen@kernel.org> > --- > drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c > index fc5c6cab58ba..ff482c694200 100644 > --- a/drivers/usb/phy/phy-tegra-usb.c > +++ b/drivers/usb/phy/phy-tegra-usb.c > @@ -64,6 +64,7 @@ > #define A_VBUS_VLD_WAKEUP_EN BIT(30) > > #define USB_PHY_VBUS_WAKEUP_ID 0x408 > +#define VBUS_WAKEUP_STS BIT(10) > #define VBUS_WAKEUP_WAKEUP_EN BIT(30) > > #define USB1_LEGACY_CTRL 0x410 > @@ -645,6 +646,15 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) > void __iomem *base = phy->regs; > u32 val; > > + /* > + * Give hardware time to settle down after VBUS disconnection, > + * otherwise PHY will immediately wake up from suspend. > + */ > + if (phy->wakeup_enabled && phy->mode != USB_DR_MODE_HOST) > + readl_relaxed_poll_timeout(base + USB_PHY_VBUS_WAKEUP_ID, > + val, !(val & VBUS_WAKEUP_STS), > + 5000, 100000); > + > utmi_phy_clk_disable(phy); > > /* PHY won't resume if reset is asserted */ > -- > 2.30.2 >
15.06.2021 04:05, Peter Chen пишет: > On 21-06-13 17:59:35, Dmitry Osipenko wrote: >> Some devices need an extra delay after losing VBUS, otherwise VBUS may >> be detected as active at suspend time, preventing the PHY's suspension >> by the VBUS detection sensor. This problem was found on Asus Transformer >> TF700T (Tegra30) tablet device, where the USB PHY wakes up immediately >> from suspend because VBUS sensor continues to detect VBUS as active after >> disconnection. We need to poll the PHY's VBUS wakeup status until it's >> deasserted before suspending PHY in order to fix this minor trouble. >> >> Fixes: 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode") >> Reported-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T >> Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> >> --- >> drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++ >> 1 file changed, 10 insertions(+) >> >> diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c >> index fc5c6cab58ba..ff482c694200 100644 >> --- a/drivers/usb/phy/phy-tegra-usb.c >> +++ b/drivers/usb/phy/phy-tegra-usb.c >> @@ -64,6 +64,7 @@ >> #define A_VBUS_VLD_WAKEUP_EN BIT(30) >> >> #define USB_PHY_VBUS_WAKEUP_ID 0x408 >> +#define VBUS_WAKEUP_STS BIT(10) >> #define VBUS_WAKEUP_WAKEUP_EN BIT(30) >> >> #define USB1_LEGACY_CTRL 0x410 >> @@ -645,6 +646,15 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) >> void __iomem *base = phy->regs; >> u32 val; >> >> + /* >> + * Give hardware time to settle down after VBUS disconnection, >> + * otherwise PHY will immediately wake up from suspend. >> + */ >> + if (phy->wakeup_enabled && phy->mode != USB_DR_MODE_HOST) >> + readl_relaxed_poll_timeout(base + USB_PHY_VBUS_WAKEUP_ID, >> + val, !(val & VBUS_WAKEUP_STS), >> + 5000, 100000); >> + > > Where will clear VBUS_WAKEUP_STS? Or it will be cleared by HW after VBUS lower than > B Session Valid? It's cleared by hardware. Tegra documentation doesn't explicitly saying what voltage level is used by the VBUS_WAKEUP sensor, but it implies the session-valid level. There are two sensors that could be used for detection of cable-insertion into B-device USB port of Tegra: VBUS_WAKEUP and A_SESS_VLD (from perspective of Tegra as a B-device). The VBUS_WAKEUP sensor may not work in some hardware configurations, always outputting 0. Seems it depends on whether port is OTG-capable (VBUS_WAKEUP works) or fixed to a device mode. IIUC, only VBUS_WAKEUP sensor can generate wake event that can resume system for a deepest suspend state.
On 21-06-13 17:59:35, Dmitry Osipenko wrote: > Some devices need an extra delay after losing VBUS, otherwise VBUS may > be detected as active at suspend time, preventing the PHY's suspension > by the VBUS detection sensor. This problem was found on Asus Transformer > TF700T (Tegra30) tablet device, where the USB PHY wakes up immediately > from suspend because VBUS sensor continues to detect VBUS as active after > disconnection. We need to poll the PHY's VBUS wakeup status until it's > deasserted before suspending PHY in order to fix this minor trouble. > > Fixes: 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode") > Reported-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T > Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > --- > drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c > index fc5c6cab58ba..ff482c694200 100644 > --- a/drivers/usb/phy/phy-tegra-usb.c > +++ b/drivers/usb/phy/phy-tegra-usb.c > @@ -64,6 +64,7 @@ > #define A_VBUS_VLD_WAKEUP_EN BIT(30) > > #define USB_PHY_VBUS_WAKEUP_ID 0x408 > +#define VBUS_WAKEUP_STS BIT(10) > #define VBUS_WAKEUP_WAKEUP_EN BIT(30) > > #define USB1_LEGACY_CTRL 0x410 > @@ -645,6 +646,15 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) > void __iomem *base = phy->regs; > u32 val; > > + /* > + * Give hardware time to settle down after VBUS disconnection, > + * otherwise PHY will immediately wake up from suspend. > + */ > + if (phy->wakeup_enabled && phy->mode != USB_DR_MODE_HOST) > + readl_relaxed_poll_timeout(base + USB_PHY_VBUS_WAKEUP_ID, > + val, !(val & VBUS_WAKEUP_STS), > + 5000, 100000); > + Reviewed-by: Peter Chen <peter.chen@kernel.org> > utmi_phy_clk_disable(phy); > > /* PHY won't resume if reset is asserted */ > -- > 2.30.2 >
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index fc5c6cab58ba..ff482c694200 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -64,6 +64,7 @@ #define A_VBUS_VLD_WAKEUP_EN BIT(30) #define USB_PHY_VBUS_WAKEUP_ID 0x408 +#define VBUS_WAKEUP_STS BIT(10) #define VBUS_WAKEUP_WAKEUP_EN BIT(30) #define USB1_LEGACY_CTRL 0x410 @@ -645,6 +646,15 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy) void __iomem *base = phy->regs; u32 val; + /* + * Give hardware time to settle down after VBUS disconnection, + * otherwise PHY will immediately wake up from suspend. + */ + if (phy->wakeup_enabled && phy->mode != USB_DR_MODE_HOST) + readl_relaxed_poll_timeout(base + USB_PHY_VBUS_WAKEUP_ID, + val, !(val & VBUS_WAKEUP_STS), + 5000, 100000); + utmi_phy_clk_disable(phy); /* PHY won't resume if reset is asserted */