From: JC Kuo <jckuo@nvidia.com>
To: <gregkh@linuxfoundation.org>, <thierry.reding@gmail.com>,
<robh@kernel.org>, <jonathanh@nvidia.com>, <kishon@ti.com>
Cc: <linux-tegra@vger.kernel.org>, <linux-usb@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
<nkristam@nvidia.com>, JC Kuo <jckuo@nvidia.com>,
Thierry Reding <treding@nvidia.com>
Subject: [PATCH v5 12/16] phy: tegra: xusb: Tegra210 host mode VBUS control
Date: Thu, 19 Nov 2020 16:54:01 +0800 [thread overview]
Message-ID: <20201119085405.556138-13-jckuo@nvidia.com> (raw)
In-Reply-To: <20201119085405.556138-1-jckuo@nvidia.com>
To support XUSB host controller ELPG, this commit moves VBUS control
.phy_power_on()/.phy_power_off() to .phy_init()/.phy_exit().
When XUSB host controller enters ELPG, host driver invokes
.phy_power_off(), VBUS should remain ON so that USB devices will not
disconnect. VBUS can be turned OFF when host driver invokes
.phy_exit() which indicates disabling a USB port.
Signed-off-by: JC Kuo <jckuo@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
---
v5:
no change
v4:
no change
v3:
new, was a part of "phy: tegra: xusb: Add wake/sleepwalk for Tegra210"
drivers/phy/tegra/xusb-tegra210.c | 52 ++++++++++++++++++++++++-------
1 file changed, 40 insertions(+), 12 deletions(-)
diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
index 8af73ba78ad7..9d39f812fb43 100644
--- a/drivers/phy/tegra/xusb-tegra210.c
+++ b/drivers/phy/tegra/xusb-tegra210.c
@@ -1819,8 +1819,25 @@ static int tegra210_usb2_phy_init(struct phy *phy)
{
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+ unsigned int index = lane->index;
+ struct tegra_xusb_usb2_port *port;
+ int err;
u32 value;
+ port = tegra_xusb_find_usb2_port(padctl, index);
+ if (!port) {
+ dev_err(&phy->dev, "no port found for USB2 lane %u\n", index);
+ return -ENODEV;
+ }
+
+ if (port->supply && port->mode == USB_DR_MODE_HOST) {
+ err = regulator_enable(port->supply);
+ if (err)
+ return err;
+ }
+
+ mutex_lock(&padctl->lock);
+
value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX);
value &= ~(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK <<
XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT);
@@ -1828,11 +1845,30 @@ static int tegra210_usb2_phy_init(struct phy *phy)
XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT;
padctl_writel(padctl, value, XUSB_PADCTL_USB2_PAD_MUX);
+ mutex_unlock(&padctl->lock);
+
return 0;
}
static int tegra210_usb2_phy_exit(struct phy *phy)
{
+ struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+ struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+ struct tegra_xusb_usb2_port *port;
+ int err;
+
+ port = tegra_xusb_find_usb2_port(padctl, lane->index);
+ if (!port) {
+ dev_err(&phy->dev, "no port found for USB2 lane %u\n", lane->index);
+ return -ENODEV;
+ }
+
+ if (port->supply && port->mode == USB_DR_MODE_HOST) {
+ err = regulator_disable(port->supply);
+ if (err)
+ return err;
+ }
+
return 0;
}
@@ -1953,6 +1989,8 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
priv = to_tegra210_xusb_padctl(padctl);
+ mutex_lock(&padctl->lock);
+
if (port->usb3_port_fake != -1) {
value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP);
value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(
@@ -2046,14 +2084,6 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
padctl_writel(padctl, value,
XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index));
- if (port->supply && port->mode == USB_DR_MODE_HOST) {
- err = regulator_enable(port->supply);
- if (err)
- return err;
- }
-
- mutex_lock(&padctl->lock);
-
if (pad->enable > 0) {
pad->enable++;
mutex_unlock(&padctl->lock);
@@ -2062,7 +2092,7 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
err = clk_prepare_enable(pad->clk);
if (err)
- goto disable_regulator;
+ goto out;
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK <<
@@ -2094,8 +2124,7 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
return 0;
-disable_regulator:
- regulator_disable(port->supply);
+out:
mutex_unlock(&padctl->lock);
return err;
}
@@ -2154,7 +2183,6 @@ static int tegra210_usb2_phy_power_off(struct phy *phy)
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
out:
- regulator_disable(port->supply);
mutex_unlock(&padctl->lock);
return 0;
}
--
2.25.1
next prev parent reply other threads:[~2020-11-19 8:54 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-19 8:53 [PATCH v5 00/16] Tegra XHCI controller ELPG support JC Kuo
2020-11-19 8:53 ` [PATCH v5 01/16] clk: tegra: Add PLLE HW power sequencer control JC Kuo
2020-11-19 8:53 ` [PATCH v5 02/16] clk: tegra: Don't enable PLLE HW sequencer at init JC Kuo
2020-11-19 8:53 ` [PATCH v5 03/16] phy: tegra: xusb: Move usb3 port init for Tegra210 JC Kuo
2020-11-19 8:53 ` [PATCH v5 04/16] phy: tegra: xusb: tegra210: Do not reset UPHY PLL JC Kuo
2020-11-19 8:53 ` [PATCH v5 05/16] phy: tegra: xusb: Rearrange UPHY init on Tegra210 JC Kuo
2020-11-19 8:53 ` [PATCH v5 06/16] phy: tegra: xusb: Add Tegra210 lane_iddq operation JC Kuo
2020-11-19 8:53 ` [PATCH v5 07/16] phy: tegra: xusb: Add sleepwalk and suspend/resume JC Kuo
2020-11-19 8:53 ` [PATCH v5 08/16] soc/tegra: pmc: Provide USB sleepwalk register map JC Kuo
2020-11-19 8:53 ` [PATCH v5 09/16] arm64: tegra210: XUSB PADCTL add "nvidia,pmc" prop JC Kuo
2020-11-19 8:53 ` [PATCH v5 10/16] dt-bindings: phy: tegra-xusb: Add nvidia,pmc prop JC Kuo
2020-11-30 22:03 ` Rob Herring
2020-11-19 8:54 ` [PATCH v5 11/16] phy: tegra: xusb: Add wake/sleepwalk for Tegra210 JC Kuo
2020-11-19 8:54 ` JC Kuo [this message]
2020-11-19 8:54 ` [PATCH v5 13/16] phy: tegra: xusb: Add wake/sleepwalk for Tegra186 JC Kuo
2020-11-19 8:54 ` [PATCH v5 14/16] arm64: tegra210/tegra186/tegra194: XUSB PADCTL irq JC Kuo
2020-11-19 8:54 ` [PATCH v5 15/16] usb: host: xhci-tegra: Unlink power domain devices JC Kuo
2020-11-19 8:54 ` [PATCH v5 16/16] xhci: tegra: Enable ELPG for runtime/system PM JC Kuo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201119085405.556138-13-jckuo@nvidia.com \
--to=jckuo@nvidia.com \
--cc=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=jonathanh@nvidia.com \
--cc=kishon@ti.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=nkristam@nvidia.com \
--cc=robh@kernel.org \
--cc=thierry.reding@gmail.com \
--cc=treding@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).