lkml.org 
[lkml]   [2021]   [Jan]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 11/14] phy: tegra: xusb: Tegra210 host mode VBUS control
    Date
    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>
    ---
    v7:
    no change
    v6:
    no change
    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
    \
     
     \ /
      Last update: 2021-01-20 08:41    [W:4.167 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site