diff options
Diffstat (limited to 'drivers/phy/tegra/xusb-tegra186.c')
-rw-r--r-- | drivers/phy/tegra/xusb-tegra186.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c index c0d9b9a09bcb..a7564fed7353 100644 --- a/drivers/phy/tegra/xusb-tegra186.c +++ b/drivers/phy/tegra/xusb-tegra186.c @@ -63,6 +63,10 @@ #define SSPX_ELPG_CLAMP_EN(x) BIT(0 + (x) * 3) #define SSPX_ELPG_CLAMP_EN_EARLY(x) BIT(1 + (x) * 3) #define SSPX_ELPG_VCORE_DOWN(x) BIT(2 + (x) * 3) +#define XUSB_PADCTL_SS_PORT_CFG 0x2c +#define PORTX_SPEED_SUPPORT_SHIFT(x) ((x) * 4) +#define PORTX_SPEED_SUPPORT_MASK (0x3) +#define PORT_SPEED_SUPPORT_GEN1 (0x0) #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x88 + (x) * 0x40) #define HS_CURR_LEVEL(x) ((x) & 0x3f) @@ -714,6 +718,15 @@ static int tegra186_usb3_phy_power_on(struct phy *phy) padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_CAP); + if (padctl->soc->supports_gen2 && port->disable_gen2) { + value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_CFG); + value &= ~(PORTX_SPEED_SUPPORT_MASK << + PORTX_SPEED_SUPPORT_SHIFT(index)); + value |= (PORT_SPEED_SUPPORT_GEN1 << + PORTX_SPEED_SUPPORT_SHIFT(index)); + padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_CFG); + } + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM_1); value &= ~SSPX_ELPG_VCORE_DOWN(index); padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM_1); @@ -989,6 +1002,66 @@ const struct tegra_xusb_padctl_soc tegra186_xusb_padctl_soc = { EXPORT_SYMBOL_GPL(tegra186_xusb_padctl_soc); #endif +#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) +static const char * const tegra194_xusb_padctl_supply_names[] = { + "avdd-usb", + "vclamp-usb", +}; + +static const struct tegra_xusb_lane_soc tegra194_usb2_lanes[] = { + TEGRA186_LANE("usb2-0", 0, 0, 0, usb2), + TEGRA186_LANE("usb2-1", 0, 0, 0, usb2), + TEGRA186_LANE("usb2-2", 0, 0, 0, usb2), + TEGRA186_LANE("usb2-3", 0, 0, 0, usb2), +}; + +static const struct tegra_xusb_pad_soc tegra194_usb2_pad = { + .name = "usb2", + .num_lanes = ARRAY_SIZE(tegra194_usb2_lanes), + .lanes = tegra194_usb2_lanes, + .ops = &tegra186_usb2_pad_ops, +}; + +static const struct tegra_xusb_lane_soc tegra194_usb3_lanes[] = { + TEGRA186_LANE("usb3-0", 0, 0, 0, usb3), + TEGRA186_LANE("usb3-1", 0, 0, 0, usb3), + TEGRA186_LANE("usb3-2", 0, 0, 0, usb3), + TEGRA186_LANE("usb3-3", 0, 0, 0, usb3), +}; + +static const struct tegra_xusb_pad_soc tegra194_usb3_pad = { + .name = "usb3", + .num_lanes = ARRAY_SIZE(tegra194_usb3_lanes), + .lanes = tegra194_usb3_lanes, + .ops = &tegra186_usb3_pad_ops, +}; + +static const struct tegra_xusb_pad_soc * const tegra194_pads[] = { + &tegra194_usb2_pad, + &tegra194_usb3_pad, +}; + +const struct tegra_xusb_padctl_soc tegra194_xusb_padctl_soc = { + .num_pads = ARRAY_SIZE(tegra194_pads), + .pads = tegra194_pads, + .ports = { + .usb2 = { + .ops = &tegra186_usb2_port_ops, + .count = 4, + }, + .usb3 = { + .ops = &tegra186_usb3_port_ops, + .count = 4, + }, + }, + .ops = &tegra186_xusb_padctl_ops, + .supply_names = tegra194_xusb_padctl_supply_names, + .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names), + .supports_gen2 = true, +}; +EXPORT_SYMBOL_GPL(tegra194_xusb_padctl_soc); +#endif + MODULE_AUTHOR("JC Kuo <jckuo@nvidia.com>"); MODULE_DESCRIPTION("NVIDIA Tegra186 XUSB Pad Controller driver"); MODULE_LICENSE("GPL v2"); |