phy: tegra: xusb: Add T210B01 support

- Add T210b01 soc data for xusb_padctl driver
- Add uphy_management clock support
- Add PLL defaults programming

Bug 200340262

Change-Id: Ie5a685a49542221142a0a8e31e5a9ebb729a3035
Signed-off-by: Rohith Seelaboyina <rseelaboyina@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1584421
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Rakesh Babu Bodla <rbodla@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
This commit is contained in:
Rohith Seelaboyina
2017-10-24 12:27:46 +05:30
committed by Thomas Makin
parent b33310ac0b
commit 6c5e31fc75

View File

@@ -230,6 +230,12 @@
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_VAL GENMASK(13, 12) #define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_VAL GENMASK(13, 12)
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_PWR_OVRD BIT(25) #define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_PWR_OVRD BIT(25)
#define XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL8(x) (0x460 + (x) * (0x1c))
#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_PLL_S0_CTL1 0x860 #define XUSB_PADCTL_UPHY_PLL_S0_CTL1 0x860
#define XUSB_PADCTL_UPHY_PLL_S0_CTL2 0x864 #define XUSB_PADCTL_UPHY_PLL_S0_CTL2 0x864
@@ -240,6 +246,8 @@
#define XUSB_PADCTL_UPHY_PLL_S0_CTL8 0x87c #define XUSB_PADCTL_UPHY_PLL_S0_CTL8 0x87c
#define XUSB_PADCTL_UPHY_PLL_S0_CTL10 0x384
#define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1 0x960 #define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1 0x960
#define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL2 0x964 #define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL2 0x964
@@ -407,6 +415,18 @@
#define UHSIC_STROBE_RPD_C BIT(16) #define UHSIC_STROBE_RPD_C BIT(16)
#define UHSIC_STROBE_RPD_D BIT(24) #define UHSIC_STROBE_RPD_D BIT(24)
struct init_data {
u8 cfg_addr;
u16 cfg_wdata;
};
static struct init_data 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 { struct tegra210_xusb_fuse_calibration {
u32 hs_curr_level[4]; u32 hs_curr_level[4];
u32 hs_term_range_adj; u32 hs_term_range_adj;
@@ -444,11 +464,38 @@ static const struct tegra_xusb_lane_map tegra210_usb3_map[] = {
{ 0, NULL, 0 } { 0, NULL, 0 }
}; };
static const struct tegra_xusb_lane_map tegra210b01_usb3_map[] = {
{ 0, "pcie", 5 },
{ 1, "pcie", 4 },
{ 2, "pcie", 1 },
{ 0, NULL, 0 }
};
static int t210b01_compatible(struct tegra_xusb_padctl *padctl)
{
struct device_node *np;
const char *compatible;
np = padctl->dev->of_node;
compatible = of_get_property(np, "compatible", NULL);
if (!compatible) {
dev_err(padctl->dev, "Failed to get compatible property\n");
return -ENODEV;
}
if (strstr(compatible, "tegra210b01") != NULL)
return 1;
return 0;
}
static int tegra210_usb3_lane_map(struct tegra_xusb_lane *lane) static int tegra210_usb3_lane_map(struct tegra_xusb_lane *lane)
{ {
const struct tegra_xusb_lane_map *map; const struct tegra_xusb_lane_map *map;
for (map = tegra210_usb3_map; map->type; map++) { for (map = t210b01_compatible(lane->pad->padctl) ?
tegra210b01_usb3_map : tegra210_usb3_map;
map->type; map++) {
if (map->index == lane->index && if (map->index == lane->index &&
strcmp(map->type, lane->pad->soc->name) == 0) { strcmp(map->type, lane->pad->soc->name) == 0) {
dev_dbg(lane->pad->padctl->dev, "lane = %s map to port = usb3-%d\n", dev_dbg(lane->pad->padctl->dev, "lane = %s map to port = usb3-%d\n",
@@ -476,6 +523,12 @@ static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
if (err < 0) if (err < 0)
return err; return err;
if (t210b01_compatible(padctl) == 1) {
err = clk_prepare_enable(pcie->uphy_mgmt_clk);
if (err < 0)
return err;
}
if (tegra210_plle_hw_sequence_is_enabled()) if (tegra210_plle_hw_sequence_is_enabled())
goto skip_pll_init; goto skip_pll_init;
@@ -483,6 +536,18 @@ static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
if (err < 0) if (err < 0)
goto disable; goto disable;
if (t210b01_compatible(padctl) == 1) {
for (i = 0; i < ARRAY_SIZE(usb3_pll_g1_init_data); i++) {
value = 0;
value |= CFG_ADDR(usb3_pll_g1_init_data[i].cfg_addr);
value |= CFG_WDATA(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 = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK << value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT); XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT);
@@ -676,6 +741,8 @@ reset:
reset_control_assert(pcie->rst); reset_control_assert(pcie->rst);
disable: disable:
clk_disable_unprepare(pcie->pll); clk_disable_unprepare(pcie->pll);
if (t210b01_compatible(padctl) == 1)
clk_disable_unprepare(pcie->uphy_mgmt_clk);
return err; return err;
} }
@@ -697,6 +764,8 @@ static void tegra210_pex_uphy_disable(struct tegra_xusb_padctl *padctl)
} }
clk_disable_unprepare(pcie->pll); clk_disable_unprepare(pcie->pll);
if (t210b01_compatible(padctl) == 1)
clk_disable_unprepare(pcie->uphy_mgmt_clk);
} }
/* must be called under padctl->lock */ /* must be called under padctl->lock */
@@ -2560,12 +2629,12 @@ static const struct tegra_xusb_lane_soc tegra210_pcie_lanes[] = {
}; };
static const struct tegra_xusb_lane_soc tegra210b01_pcie_lanes[] = { static const struct tegra_xusb_lane_soc tegra210b01_pcie_lanes[] = {
TEGRA210_UPHY_LANE("pcie-0", 0x028, 12, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)), TEGRA210_UPHY_LANE("pcie-0", 0x28, 12, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-1", 0x028, 14, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(1)), TEGRA210_UPHY_LANE("pcie-1", 0x28, 14, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-2", 0x028, 16, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(2)), TEGRA210_UPHY_LANE("pcie-2", 0x28, 16, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-3", 0x028, 18, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(3)), TEGRA210_UPHY_LANE("pcie-3", 0x28, 18, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-4", 0x028, 20, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(4)), TEGRA210_UPHY_LANE("pcie-4", 0x28, 20, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-5", 0x028, 22, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(5)), TEGRA210_UPHY_LANE("pcie-5", 0x28, 22, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
}; };
static struct tegra_xusb_usb3_port * static struct tegra_xusb_usb3_port *
@@ -2816,6 +2885,15 @@ tegra210_pcie_pad_probe(struct tegra_xusb_padctl *padctl,
goto unregister; goto unregister;
} }
if (t210b01_compatible(padctl) == 1) {
pcie->uphy_mgmt_clk = devm_clk_get(&pad->dev, "uphy_mgmt");
if (IS_ERR(pcie->uphy_mgmt_clk)) {
err = PTR_ERR(pcie->uphy_mgmt_clk);
dev_err(&pad->dev,
"failed to get uphy_mgmt_clk clock: %d\n", err);
}
}
pcie->rst = devm_reset_control_get(&pad->dev, "phy"); pcie->rst = devm_reset_control_get(&pad->dev, "phy");
if (IS_ERR(pcie->rst)) { if (IS_ERR(pcie->rst)) {
err = PTR_ERR(pcie->rst); err = PTR_ERR(pcie->rst);
@@ -3094,7 +3172,16 @@ static void tegra210_usb3_port_disable(struct tegra_xusb_port *port)
static struct tegra_xusb_lane * static struct tegra_xusb_lane *
tegra210_usb3_port_map(struct tegra_xusb_port *port) tegra210_usb3_port_map(struct tegra_xusb_port *port)
{ {
return tegra_xusb_port_find_lane(port, tegra210_usb3_map, "usb3-ss"); int err = t210b01_compatible(port->padctl);
if (err == 1)
return tegra_xusb_port_find_lane(port,
tegra210b01_usb3_map, "usb3-ss");
else if (err == 0)
return tegra_xusb_port_find_lane(port,
tegra210_usb3_map, "usb3-ss");
else
return NULL;
} }
static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = { static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = {
@@ -3287,6 +3374,14 @@ static const char * const tegra210_xusb_padctl_supply_names[] = {
"hvdd-pex-pll-e", "hvdd-pex-pll-e",
}; };
static const char * const tegra210b01_supply_names[] = {
"avdd_pll_uerefe",
"hvdd_pex_pll_e",
"dvdd_pex_pll",
"hvddio_pex",
"dvddio_pex",
};
const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc = { const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc = {
.num_pads = ARRAY_SIZE(tegra210_pads), .num_pads = ARRAY_SIZE(tegra210_pads),
.pads = tegra210_pads, .pads = tegra210_pads,
@@ -3325,8 +3420,8 @@ const struct tegra_xusb_padctl_soc tegra210b01_xusb_padctl_soc = {
}, },
}, },
.ops = &tegra210_xusb_padctl_ops, .ops = &tegra210_xusb_padctl_ops,
.supply_names = tegra210_xusb_padctl_supply_names, .supply_names = tegra210b01_supply_names,
.num_supplies = ARRAY_SIZE(tegra210_xusb_padctl_supply_names), .num_supplies = ARRAY_SIZE(tegra210b01_supply_names),
.need_fake_usb3_port = true, .need_fake_usb3_port = true,
}; };
EXPORT_SYMBOL_GPL(tegra210b01_xusb_padctl_soc); EXPORT_SYMBOL_GPL(tegra210b01_xusb_padctl_soc);