for (map = tegra210_usb3_map; map->type; map++) { if (map->index == lane->index &&
strcmp(map->type, lane->pad->soc->name) == 0) {
dev_dbg(lane->pad->padctl->dev, "lane = %s map to port = usb3-%d\n",
lane->pad->soc->lanes[lane->index].name, map->port); return map->port;
}
}
return -EINVAL;
}
/* must be called under padctl->lock */ staticint tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
{ struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(padctl->pcie); unsignedlong timeout;
u32 value; unsignedint i; int err;
if (pcie->enable) return 0;
err = clk_prepare_enable(pcie->pll); if (err < 0) return err;
if (tegra210_plle_hw_sequence_is_enabled()) goto skip_pll_init;
err = reset_control_deassert(pcie->rst); if (err < 0) goto disable;
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT);
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT);
value |= XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value |= XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
value &= ~((XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT) |
(XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_SHIFT));
value |= (XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_USB_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT) |
XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value &= ~((XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_SHIFT) |
(XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT));
value |= XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_USB_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_IDDQ;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_SHIFT);
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
value |= XUSB_PADCTL_UPHY_PLL_CTL4_REFCLKBUF_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); if (value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); if (!(value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE)) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value |= XUSB_PADCTL_UPHY_PLL_CTL1_ENABLE;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); if (value & XUSB_PADCTL_UPHY_PLL_CTL1_LOCKDET_STATUS) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN |
XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); if (value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); if (!(value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE)) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
tegra210_xusb_pll_hw_control_enable();
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
usleep_range(10, 20);
tegra210_xusb_pll_hw_sequence_start();
skip_pll_init:
pcie->enable = true;
for (i = 0; i < padctl->pcie->soc->num_lanes; i++) {
value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);
value |= XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(i);
padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);
}
for (i = 0; i < padctl->pcie->soc->num_lanes; i++) {
value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);
value &= ~XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(i);
padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);
}
clk_disable_unprepare(pcie->pll);
}
/* must be called under padctl->lock */ staticint tegra210_sata_uphy_enable(struct tegra_xusb_padctl *padctl)
{ struct tegra_xusb_sata_pad *sata = to_sata_pad(padctl->sata); struct tegra_xusb_lane *lane = tegra_xusb_find_lane(padctl, "sata", 0); unsignedlong timeout;
u32 value; unsignedint i; int err; bool usb;
if (sata->enable) return 0;
if (IS_ERR(lane)) return 0;
if (tegra210_plle_hw_sequence_is_enabled()) goto skip_pll_init;
usb = tegra_xusb_lane_check(lane, "usb3-ss");
err = clk_prepare_enable(sata->pll); if (err < 0) return err;
err = reset_control_deassert(sata->rst); if (err < 0) goto disable;
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT);
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL5);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT);
value |= XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL5);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value |= XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL4);
value &= ~((XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT) |
(XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_SHIFT));
value |= XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_EN;
if (usb)
value |= (XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_USB_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT); else
value |= (XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SATA_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL4_XDIGCLK_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL4);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value &= ~((XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_SHIFT) |
(XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT));
if (usb)
value |= XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_USB_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT; else
value |= XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SATA_VAL <<
XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT;
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_IDDQ;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_SHIFT);
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL4);
value |= XUSB_PADCTL_UPHY_PLL_CTL4_REFCLKBUF_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL4);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); if (value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); if (!(value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE)) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value |= XUSB_PADCTL_UPHY_PLL_CTL1_ENABLE;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); if (value & XUSB_PADCTL_UPHY_PLL_CTL1_LOCKDET_STATUS) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN |
XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); if (value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
timeout = jiffies + msecs_to_jiffies(100);
while (time_before(jiffies, timeout)) {
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); if (!(value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE)) break;
usleep_range(10, 20);
}
if (time_after_eq(jiffies, timeout)) {
err = -ETIMEDOUT; goto reset;
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
tegra210_sata_pll_hw_control_enable();
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2);
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD;
padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8);
usleep_range(10, 20);
tegra210_sata_pll_hw_sequence_start();
skip_pll_init:
sata->enable = true;
for (i = 0; i < padctl->sata->soc->num_lanes; i++) {
value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);
value |= XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(i);
padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);
}
for (i = 0; i < padctl->sata->soc->num_lanes; i++) {
value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX);
value &= ~XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(i);
padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX);
}
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
}
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value |= XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value |= XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value |= XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN;
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
}
staticint tegra210_uphy_init(struct tegra_xusb_padctl *padctl)
{ if (padctl->pcie)
tegra210_pex_uphy_enable(padctl);
if (padctl->sata)
tegra210_sata_uphy_enable(padctl);
if (!tegra210_plle_hw_sequence_is_enabled())
tegra210_plle_hw_sequence_start(); else
dev_dbg(padctl->dev, "PLLE is already in HW control\n");
if (port < 0) {
dev_err(dev, "invalid usb3 port number\n"); return -EINVAL;
}
mutex_lock(&padctl->lock);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
if (port < 0) {
dev_err(dev, "invalid usb3 port number\n"); return -EINVAL;
}
mutex_lock(&padctl->lock);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
if (port < 0) {
dev_err(dev, "invalid usb3 port number\n"); return -EINVAL;
}
mutex_lock(&padctl->lock);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= SS_PORT_WAKEUP_EVENT(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= SS_PORT_WAKE_INTERRUPT_ENABLE(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
if (port < 0) {
dev_err(dev, "invalid usb3 port number\n"); return -EINVAL;
}
mutex_lock(&padctl->lock);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value &= ~SS_PORT_WAKE_INTERRUPT_ENABLE(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= SS_PORT_WAKEUP_EVENT(port);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
mutex_unlock(&padctl->lock);
return 0;
}
staticbool tegra210_usb3_phy_remote_wake_detected(struct tegra_xusb_lane *lane)
{ struct tegra_xusb_padctl *padctl = lane->pad->padctl; int index = tegra210_usb3_lane_map(lane);
u32 value;
if (index < 0) returnfalse;
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0); if ((value & SS_PORT_WAKE_INTERRUPT_ENABLE(index)) && (value & SS_PORT_WAKEUP_EVENT(index))) returntrue;
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= USB2_PORT_WAKEUP_EVENT(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= USB2_PORT_WAKE_INTERRUPT_ENABLE(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value &= ~USB2_PORT_WAKE_INTERRUPT_ENABLE(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= USB2_PORT_WAKEUP_EVENT(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= USB2_HSIC_PORT_WAKEUP_EVENT(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= USB2_HSIC_PORT_WAKE_INTERRUPT_ENABLE(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value &= ~USB2_HSIC_PORT_WAKE_INTERRUPT_ENABLE(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
usleep_range(10, 20);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_0);
value &= ~ALL_WAKE_EVENTS;
value |= USB2_HSIC_PORT_WAKEUP_EVENT(index);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_0);
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
tctrl = TCTRL_VALUE(value);
pctrl = PCTRL_VALUE(value);
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(port));
rpd_ctrl = RPD_CTRL_VALUE(value);
/* ensure sleepwalk logic is disabled */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value &= ~UTMIP_MASTER_ENABLE(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
/* ensure sleepwalk logics are in low power mode */
value = padctl_pmc_readl(priv, PMC_UTMIP_MASTER_CONFIG);
value |= UTMIP_PWR(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_MASTER_CONFIG);
/* set debounce time */
value = padctl_pmc_readl(priv, PMC_USB_DEBOUNCE_DEL);
value &= ~UTMIP_LINE_DEB_CNT(~0);
value |= UTMIP_LINE_DEB_CNT(0x1);
padctl_pmc_writel(priv, value, PMC_USB_DEBOUNCE_DEL);
/* ensure fake events of sleepwalk logic are desiabled */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_FAKE(port));
value &= ~(UTMIP_FAKE_USBOP_VAL(port) | UTMIP_FAKE_USBON_VAL(port) |
UTMIP_FAKE_USBOP_EN(port) | UTMIP_FAKE_USBON_EN(port));
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_FAKE(port));
/* ensure wake events of sleepwalk logic are not latched */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_LINE_WAKEUP);
value &= ~UTMIP_LINE_WAKEUP_EN(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_LINE_WAKEUP);
/* disable wake event triggers of sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value &= ~UTMIP_WAKE_VAL(port, ~0);
value |= UTMIP_WAKE_VAL_NONE(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
/* power down the line state detectors of the pad */
value = padctl_pmc_readl(priv, PMC_USB_AO);
value |= (USBOP_VAL_PD(port) | USBON_VAL_PD(port));
padctl_pmc_writel(priv, value, PMC_USB_AO);
/* save state per speed */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SAVED_STATE(port));
value &= ~SPEED(port, ~0);
switch (speed) { case USB_SPEED_HIGH:
value |= UTMI_HS(port); break;
case USB_SPEED_FULL:
value |= UTMI_FS(port); break;
case USB_SPEED_LOW:
value |= UTMI_LS(port); break;
/* enable the trigger of the sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEPWALK_CFG(port));
value |= UTMIP_LINEVAL_WALK_EN(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEPWALK_CFG(port));
/* * Reset the walk pointer and clear the alarm of the sleepwalk logic, * as well as capture the configuration of the USB2.0 pad.
*/
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_TRIGGERS);
value |= UTMIP_CLR_WALK_PTR(port) | UTMIP_CLR_WAKE_ALARM(port) | UTMIP_CAP_CFG(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_TRIGGERS);
/* program electrical parameters read from XUSB PADCTL */
value = padctl_pmc_readl(priv, PMC_UTMIP_TERM_PAD_CFG);
value &= ~(TCTRL_VAL(~0) | PCTRL_VAL(~0));
value |= (TCTRL_VAL(tctrl) | PCTRL_VAL(pctrl));
padctl_pmc_writel(priv, value, PMC_UTMIP_TERM_PAD_CFG);
value = padctl_pmc_readl(priv, PMC_UTMIP_PAD_CFGX(port));
value &= ~RPD_CTRL_PX(~0);
value |= RPD_CTRL_PX(rpd_ctrl);
padctl_pmc_writel(priv, value, PMC_UTMIP_PAD_CFGX(port));
/* * Set up the pull-ups and pull-downs of the signals during the four * stages of sleepwalk. If a device is connected, program sleepwalk * logic to maintain a J and keep driving K upon seeing remote wake.
*/
value = padctl_pmc_readl(priv, PMC_UTMIP_SLEEPWALK_PX(port));
value = UTMIP_USBOP_RPD_A | UTMIP_USBOP_RPD_B | UTMIP_USBOP_RPD_C | UTMIP_USBOP_RPD_D;
value |= UTMIP_USBON_RPD_A | UTMIP_USBON_RPD_B | UTMIP_USBON_RPD_C | UTMIP_USBON_RPD_D;
switch (speed) { case USB_SPEED_HIGH: case USB_SPEED_FULL: /* J state: D+/D- = high/low, K state: D+/D- = low/high */
value |= UTMIP_HIGHZ_A;
value |= UTMIP_AP_A;
value |= UTMIP_AN_B | UTMIP_AN_C | UTMIP_AN_D; break;
case USB_SPEED_LOW: /* J state: D+/D- = low/high, K state: D+/D- = high/low */
value |= UTMIP_HIGHZ_A;
value |= UTMIP_AN_A;
value |= UTMIP_AP_B | UTMIP_AP_C | UTMIP_AP_D; break;
/* power up the line state detectors of the pad */
value = padctl_pmc_readl(priv, PMC_USB_AO);
value &= ~(USBOP_VAL_PD(port) | USBON_VAL_PD(port));
padctl_pmc_writel(priv, value, PMC_USB_AO);
usleep_range(50, 100);
/* switch the electric control of the USB2.0 pad to PMC */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value |= UTMIP_FSLS_USE_PMC(port) | UTMIP_PCTRL_USE_PMC(port) | UTMIP_TCTRL_USE_PMC(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG1);
value |= UTMIP_RPD_CTRL_USE_PMC_PX(port) | UTMIP_RPU_SWITC_LOW_USE_PMC_PX(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG1);
/* set the wake signaling trigger events */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value &= ~UTMIP_WAKE_VAL(port, ~0);
value |= UTMIP_WAKE_VAL_ANY(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
/* enable the wake detection */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value |= UTMIP_MASTER_ENABLE(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_LINE_WAKEUP);
value |= UTMIP_LINE_WAKEUP_EN(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_LINE_WAKEUP);
/* disable the wake detection */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value &= ~UTMIP_MASTER_ENABLE(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_LINE_WAKEUP);
value &= ~UTMIP_LINE_WAKEUP_EN(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_LINE_WAKEUP);
/* switch the electric control of the USB2.0 pad to XUSB or USB2 */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value &= ~(UTMIP_FSLS_USE_PMC(port) | UTMIP_PCTRL_USE_PMC(port) |
UTMIP_TCTRL_USE_PMC(port));
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG1);
value &= ~(UTMIP_RPD_CTRL_USE_PMC_PX(port) | UTMIP_RPU_SWITC_LOW_USE_PMC_PX(port));
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG1);
/* disable wake event triggers of sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
value &= ~UTMIP_WAKE_VAL(port, ~0);
value |= UTMIP_WAKE_VAL_NONE(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_SLEEP_CFG(port));
/* power down the line state detectors of the port */
value = padctl_pmc_readl(priv, PMC_USB_AO);
value |= (USBOP_VAL_PD(port) | USBON_VAL_PD(port));
padctl_pmc_writel(priv, value, PMC_USB_AO);
/* clear alarm of the sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_TRIGGERS);
value |= UTMIP_CLR_WAKE_ALARM(port);
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_TRIGGERS);
/* ensure sleepwalk logic is disabled */
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEP_CFG);
value &= ~UHSIC_MASTER_ENABLE;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEP_CFG);
/* ensure sleepwalk logics are in low power mode */
value = padctl_pmc_readl(priv, PMC_UTMIP_MASTER_CONFIG);
value |= UHSIC_PWR;
padctl_pmc_writel(priv, value, PMC_UTMIP_MASTER_CONFIG);
/* set debounce time */
value = padctl_pmc_readl(priv, PMC_USB_DEBOUNCE_DEL);
value &= ~UHSIC_LINE_DEB_CNT(~0);
value |= UHSIC_LINE_DEB_CNT(0x1);
padctl_pmc_writel(priv, value, PMC_USB_DEBOUNCE_DEL);
/* ensure fake events of sleepwalk logic are desiabled */
value = padctl_pmc_readl(priv, PMC_UHSIC_FAKE);
value &= ~(UHSIC_FAKE_STROBE_VAL | UHSIC_FAKE_DATA_VAL |
UHSIC_FAKE_STROBE_EN | UHSIC_FAKE_DATA_EN);
padctl_pmc_writel(priv, value, PMC_UHSIC_FAKE);
/* ensure wake events of sleepwalk logic are not latched */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_LINE_WAKEUP);
value &= ~UHSIC_LINE_WAKEUP_EN;
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_LINE_WAKEUP);
/* disable wake event triggers of sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEP_CFG);
value &= ~UHSIC_WAKE_VAL(~0);
value |= UHSIC_WAKE_VAL_NONE;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEP_CFG);
/* power down the line state detectors of the port */
value = padctl_pmc_readl(priv, PMC_USB_AO);
value |= STROBE_VAL_PD | DATA0_VAL_PD | DATA1_VAL_PD;
padctl_pmc_writel(priv, value, PMC_USB_AO);
/* save state, HSIC always comes up as HS */
value = padctl_pmc_readl(priv, PMC_UHSIC_SAVED_STATE);
value &= ~UHSIC_MODE(~0);
value |= UHSIC_HS;
padctl_pmc_writel(priv, value, PMC_UHSIC_SAVED_STATE);
/* enable the trigger of the sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEPWALK_CFG);
value |= UHSIC_WAKE_WALK_EN | UHSIC_LINEVAL_WALK_EN;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEPWALK_CFG);
/* * Reset the walk pointer and clear the alarm of the sleepwalk logic, * as well as capture the configuration of the USB2.0 port.
*/
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_TRIGGERS);
value |= UHSIC_CLR_WALK_PTR | UHSIC_CLR_WAKE_ALARM;
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_TRIGGERS);
/* * Set up the pull-ups and pull-downs of the signals during the four * stages of sleepwalk. Maintain a HSIC IDLE and keep driving HSIC * RESUME upon remote wake.
*/
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEPWALK_P0);
value = UHSIC_DATA0_RPD_A | UHSIC_DATA0_RPU_B | UHSIC_DATA0_RPU_C | UHSIC_DATA0_RPU_D |
UHSIC_STROBE_RPU_A | UHSIC_STROBE_RPD_B | UHSIC_STROBE_RPD_C | UHSIC_STROBE_RPD_D;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEPWALK_P0);
/* power up the line state detectors of the port */
value = padctl_pmc_readl(priv, PMC_USB_AO);
value &= ~(STROBE_VAL_PD | DATA0_VAL_PD | DATA1_VAL_PD);
padctl_pmc_writel(priv, value, PMC_USB_AO);
usleep_range(50, 100);
/* set the wake signaling trigger events */
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEP_CFG);
value &= ~UHSIC_WAKE_VAL(~0);
value |= UHSIC_WAKE_VAL_SD10;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEP_CFG);
/* enable the wake detection */
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEP_CFG);
value |= UHSIC_MASTER_ENABLE;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEP_CFG);
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_LINE_WAKEUP);
value |= UHSIC_LINE_WAKEUP_EN;
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_LINE_WAKEUP);
/* disable the wake detection */
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEP_CFG);
value &= ~UHSIC_MASTER_ENABLE;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEP_CFG);
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_LINE_WAKEUP);
value &= ~UHSIC_LINE_WAKEUP_EN;
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_LINE_WAKEUP);
/* disable wake event triggers of sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UHSIC_SLEEP_CFG);
value &= ~UHSIC_WAKE_VAL(~0);
value |= UHSIC_WAKE_VAL_NONE;
padctl_pmc_writel(priv, value, PMC_UHSIC_SLEEP_CFG);
/* power down the line state detectors of the port */
value = padctl_pmc_readl(priv, PMC_USB_AO);
value |= STROBE_VAL_PD | DATA0_VAL_PD | DATA1_VAL_PD;
padctl_pmc_writel(priv, value, PMC_USB_AO);
/* clear alarm of the sleepwalk logic */
value = padctl_pmc_readl(priv, PMC_UTMIP_UHSIC_TRIGGERS);
value |= UHSIC_CLR_WAKE_ALARM;
padctl_pmc_writel(priv, value, PMC_UTMIP_UHSIC_TRIGGERS);
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;
}
dev_dbg(padctl->dev, "%s vbus override\n", status ? "set" : "clear");
value = padctl_readl(padctl, XUSB_PADCTL_USB2_VBUS_ID);
if (status) {
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
value &= ~(XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_MASK <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT);
value |= XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_FLOATING <<
XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_SHIFT;
} else {
value &= ~XUSB_PADCTL_USB2_VBUS_ID_OVERRIDE_VBUS_ON;
}
if (mode == PHY_MODE_USB_OTG) { if (submode == USB_ROLE_HOST) {
tegra210_xusb_padctl_id_override(padctl, true);
err = regulator_enable(port->supply);
} elseif (submode == USB_ROLE_DEVICE) {
tegra210_xusb_padctl_vbus_override(padctl, true);
} elseif (submode == USB_ROLE_NONE) { /* * When port is peripheral only or role transitions to * USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not * be enabled.
*/ if (regulator_is_enabled(port->supply))
regulator_disable(port->supply);
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;
}
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(
port->usb3_port_fake);
value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(
port->usb3_port_fake, index);
padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_VCORE_DOWN(
port->usb3_port_fake);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY(
port->usb3_port_fake);
padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1);
usleep_range(100, 200);
value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1);
value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN(
port->usb3_port_fake);
--> --------------------
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.