diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c index 63711f6066c8..500e8f20ee27 100644 --- a/drivers/phy/tegra/xusb-tegra210.c +++ b/drivers/phy/tegra/xusb-tegra210.c @@ -240,6 +240,12 @@ #define XUSB_PADCTL_UPHY_PLL_S0_CTL8 0x87c +#define XUSB_PADCTL_UPHY_PLL_S0_CTL10 0x384 +#define CFG_ADDR(x) (((x) & 0xff) << 16) +#define CFG_WDATA(x) (((x) & 0xffff) << 0) +#define CFG_RESET (1 << 27) +#define CFG_WS (1 << 24) + #define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1 0x960 #define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL2 0x964 @@ -407,6 +413,18 @@ #define UHSIC_STROBE_RPD_C BIT(16) #define UHSIC_STROBE_RPD_D BIT(24) +struct init_data { + u8 cfg_addr; + u16 cfg_wdata; +}; + +static struct init_data tegra210b01_usb3_pll_g1_init_data[] = { + {.cfg_addr = 0x2, .cfg_wdata = 0x0000}, + {.cfg_addr = 0x3, .cfg_wdata = 0x7051}, + {.cfg_addr = 0x25, .cfg_wdata = 0x0130}, + {.cfg_addr = 0x1E, .cfg_wdata = 0x0017}, +}; + struct tegra210_xusb_fuse_calibration { u32 hs_curr_level[4]; u32 hs_term_range_adj; @@ -508,6 +526,7 @@ static int tegra210_usb3_lane_map(struct tegra_xusb_lane *lane) static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl) { struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(padctl->pcie); + bool is_t210b01 = padctl->soc == &tegra210b01_xusb_padctl_soc; unsigned long timeout; u32 value; unsigned int i; @@ -533,6 +552,18 @@ static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl) if (err < 0) goto disable; + if (is_t210b01) { + for (i = 0; i < ARRAY_SIZE(tegra210b01_usb3_pll_g1_init_data); i++) { + value = 0; + value |= CFG_ADDR(tegra210b01_usb3_pll_g1_init_data[i].cfg_addr); + value |= CFG_WDATA(tegra210b01_usb3_pll_g1_init_data[i].cfg_wdata); + value |= CFG_RESET; + value |= CFG_WS; + padctl_writel(padctl, value, + XUSB_PADCTL_UPHY_PLL_S0_CTL10); + } + } + 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);