Skip to contentSkip to conversation

usb: phy: tegra: Wait for VBUS wakeup status deassertion on suspend

PATCH In review Dmitry Osipenko 2 participants 6 messages Jun 13, 2021 – Jun 16, 2021

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 usb: phy: tegra: Wait for VBUS wakeup status deassertion on suspend

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")
---
 drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/usb/phy/phy-tegra-usb.c +10 -0
index fc5c6cab58ba..ff482c694200 100644
@@ -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 */
Signature · 1 line
2.30.2
#1 lore raw

PATCH 2/2 usb: phy: tegra: Correct definition of B_SESS_VLD_WAKEUP_EN bit

The B_SESS_VLD_WAKEUP_EN bit 6 was added by a mistake in a previous commit. This bit corresponds to B_SESS_END_WAKEUP_EN, which we don't use. The B_VBUS_VLD_WAKEUP_EN doesn't exist at all and B_SESS_VLD_WAKEUP_EN needs to be in place of it. We don't utilize B-sensors in the driver, so it never was a problem, nevertheless let's correct the definition of the bits.

Fixes 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode")
---
 drivers/usb/phy/phy-tegra-usb.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/usb/phy/phy-tegra-usb.c +2 -3
index ff482c694200..cd425b937750 100644
@@ -58,8 +58,7 @@
 #define   USB_WAKEUP_DEBOUNCE_COUNT(x)		(((x) & 0x7) << 16)
 
 #define USB_PHY_VBUS_SENSORS			0x404
-#define   B_SESS_VLD_WAKEUP_EN			BIT(6)
-#define   B_VBUS_VLD_WAKEUP_EN			BIT(14)
+#define   B_SESS_VLD_WAKEUP_EN			BIT(14)
 #define   A_SESS_VLD_WAKEUP_EN			BIT(22)
 #define   A_VBUS_VLD_WAKEUP_EN			BIT(30)
 
@@ -548,7 +547,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
 
 		val = readl_relaxed(base + USB_PHY_VBUS_SENSORS);
 		val &= ~(A_VBUS_VLD_WAKEUP_EN | A_SESS_VLD_WAKEUP_EN);
-		val &= ~(B_VBUS_VLD_WAKEUP_EN | B_SESS_VLD_WAKEUP_EN);
+		val &= ~(B_SESS_VLD_WAKEUP_EN);
 		writel_relaxed(val, base + USB_PHY_VBUS_SENSORS);
 
 		val = readl_relaxed(base + UTMIP_BAT_CHRG_CFG0);
Signature · 1 line
2.30.2
Reviewed-by on v1 1/2
#2 lore raw
In reply to Dmitry Osipenko
Quoted 8 lines · Dmitry Osipenko

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.

Quoted 4 lines
Fixes 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode")
Quoted 35 lines
---
 drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/usb/phy/phy-tegra-usb.c +10 -0
index fc5c6cab58ba..ff482c694200 100644
@@ -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 */
Signature · 1 line
2.30.2
Signature · 2 lines
Thanks,
Peter Chen
#3 lore raw
In reply to Dmitry Osipenko
Quoted 31 lines · Dmitry Osipenko

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")
---
 drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/usb/phy/phy-tegra-usb.c +1 -0
index fc5c6cab58ba..ff482c694200 100644
@@ -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;

drivers/usb/phy/phy-tegra-usb.c static int utmi_phy_power_off(struct tegra_usb_phy *phy) · line 657

Quoted 10 lines
drivers/usb/phy/phy-tegra-usb.c +9 -0
 
+	/*
+	 * 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?

Signature · 2 lines
Thanks,
Peter Chen
#4 lore raw

15.06.2021 04:05, Peter Chen пишет:

Quoted 33 lines · Dmitry Osipenko
Quoted 32 lines

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")
---
 drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/usb/phy/phy-tegra-usb.c +1 -0
index fc5c6cab58ba..ff482c694200 100644
@@ -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;
 
Quoted 12 lines

drivers/usb/phy/phy-tegra-usb.c static int utmi_phy_power_off(struct tegra_usb_phy *phy) · line 657

Quoted 9 lines
drivers/usb/phy/phy-tegra-usb.c +9 -0
+	/*
+	 * 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.

Reviewed-by on v1 1/2
#5 lore raw
In reply to Dmitry Osipenko
Quoted 31 lines · Dmitry Osipenko

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")
---
 drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/usb/phy/phy-tegra-usb.c +1 -0
index fc5c6cab58ba..ff482c694200 100644
@@ -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;

drivers/usb/phy/phy-tegra-usb.c static int utmi_phy_power_off(struct tegra_usb_phy *phy) · line 657

Quoted 10 lines
drivers/usb/phy/phy-tegra-usb.c +9 -0
 
+	/*
+	 * 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);
+
Quoted 6 lines
drivers/usb/phy/phy-tegra-usb.c +0 -0
 	utmi_phy_clk_disable(phy);
 
 	/* PHY won't resume if reset is asserted */
Signature · 1 line
2.30.2
Signature · 2 lines
Thanks,
Peter Chen