xref: /rk3399_rockchip-uboot/arch/arm/mach-tegra/tegra210/xusb-padctl.c (revision 4e4b5574fb2a0536f133a36f2fc96bd43ed92f14)
16c43f6c8STom Warren /*
26c43f6c8STom Warren  * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
36c43f6c8STom Warren  *
46c43f6c8STom Warren  * SPDX-License-Identifier: GPL-2.0
56c43f6c8STom Warren  */
66c43f6c8STom Warren 
76c43f6c8STom Warren #define pr_fmt(fmt) "tegra-xusb-padctl: " fmt
86c43f6c8STom Warren 
96c43f6c8STom Warren #include <common.h>
106c43f6c8STom Warren #include <errno.h>
116c43f6c8STom Warren 
127a908c7eSStephen Warren #include "../xusb-padctl-common.h"
136c43f6c8STom Warren 
146c43f6c8STom Warren #include <asm/arch/clock.h>
156c43f6c8STom Warren 
166c43f6c8STom Warren #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
176c43f6c8STom Warren 
18*4e4b5574SStephen Warren enum tegra210_function {
19*4e4b5574SStephen Warren 	TEGRA210_FUNC_SNPS,
20*4e4b5574SStephen Warren 	TEGRA210_FUNC_XUSB,
21*4e4b5574SStephen Warren 	TEGRA210_FUNC_UART,
22*4e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X1,
23*4e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X4,
24*4e4b5574SStephen Warren 	TEGRA210_FUNC_USB3,
25*4e4b5574SStephen Warren 	TEGRA210_FUNC_SATA,
26*4e4b5574SStephen Warren 	TEGRA210_FUNC_RSVD,
27*4e4b5574SStephen Warren };
28*4e4b5574SStephen Warren 
29*4e4b5574SStephen Warren static const char *const tegra210_functions[] = {
30*4e4b5574SStephen Warren 	"snps",
31*4e4b5574SStephen Warren 	"xusb",
32*4e4b5574SStephen Warren 	"uart",
33*4e4b5574SStephen Warren 	"pcie-x1",
34*4e4b5574SStephen Warren 	"pcie-x4",
35*4e4b5574SStephen Warren 	"usb3",
36*4e4b5574SStephen Warren 	"sata",
37*4e4b5574SStephen Warren 	"rsvd",
38*4e4b5574SStephen Warren };
39*4e4b5574SStephen Warren 
40*4e4b5574SStephen Warren static const unsigned int tegra210_otg_functions[] = {
41*4e4b5574SStephen Warren 	TEGRA210_FUNC_SNPS,
42*4e4b5574SStephen Warren 	TEGRA210_FUNC_XUSB,
43*4e4b5574SStephen Warren 	TEGRA210_FUNC_UART,
44*4e4b5574SStephen Warren 	TEGRA210_FUNC_RSVD,
45*4e4b5574SStephen Warren };
46*4e4b5574SStephen Warren 
47*4e4b5574SStephen Warren static const unsigned int tegra210_usb_functions[] = {
48*4e4b5574SStephen Warren 	TEGRA210_FUNC_SNPS,
49*4e4b5574SStephen Warren 	TEGRA210_FUNC_XUSB,
50*4e4b5574SStephen Warren };
51*4e4b5574SStephen Warren 
52*4e4b5574SStephen Warren static const unsigned int tegra210_pci_functions[] = {
53*4e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X1,
54*4e4b5574SStephen Warren 	TEGRA210_FUNC_USB3,
55*4e4b5574SStephen Warren 	TEGRA210_FUNC_SATA,
56*4e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X4,
57*4e4b5574SStephen Warren };
58*4e4b5574SStephen Warren 
59*4e4b5574SStephen Warren #define TEGRA210_LANE(_name, _offset, _shift, _mask, _iddq, _funcs)	\
60*4e4b5574SStephen Warren 	{								\
61*4e4b5574SStephen Warren 		.name = _name,						\
62*4e4b5574SStephen Warren 		.offset = _offset,					\
63*4e4b5574SStephen Warren 		.shift = _shift,					\
64*4e4b5574SStephen Warren 		.mask = _mask,						\
65*4e4b5574SStephen Warren 		.iddq = _iddq,						\
66*4e4b5574SStephen Warren 		.num_funcs = ARRAY_SIZE(tegra210_##_funcs##_functions),	\
67*4e4b5574SStephen Warren 		.funcs = tegra210_##_funcs##_functions,			\
68*4e4b5574SStephen Warren 	}
69*4e4b5574SStephen Warren 
70*4e4b5574SStephen Warren static const struct tegra_xusb_padctl_lane tegra210_lanes[] = {
71*4e4b5574SStephen Warren 	TEGRA210_LANE("otg-0",     0x004,  0, 0x3, 0, otg),
72*4e4b5574SStephen Warren 	TEGRA210_LANE("otg-1",     0x004,  2, 0x3, 0, otg),
73*4e4b5574SStephen Warren 	TEGRA210_LANE("otg-2",     0x004,  4, 0x3, 0, otg),
74*4e4b5574SStephen Warren 	TEGRA210_LANE("otg-3",     0x004,  6, 0x3, 0, otg),
75*4e4b5574SStephen Warren 	TEGRA210_LANE("usb2-bias", 0x004, 18, 0x3, 0, otg),
76*4e4b5574SStephen Warren 	TEGRA210_LANE("hsic-0",    0x004, 14, 0x1, 0, usb),
77*4e4b5574SStephen Warren 	TEGRA210_LANE("hsic-1",    0x004, 15, 0x1, 0, usb),
78*4e4b5574SStephen Warren 	TEGRA210_LANE("pcie-0",    0x028, 12, 0x3, 1, pci),
79*4e4b5574SStephen Warren 	TEGRA210_LANE("pcie-1",    0x028, 14, 0x3, 2, pci),
80*4e4b5574SStephen Warren 	TEGRA210_LANE("pcie-2",    0x028, 16, 0x3, 3, pci),
81*4e4b5574SStephen Warren 	TEGRA210_LANE("pcie-3",    0x028, 18, 0x3, 4, pci),
82*4e4b5574SStephen Warren 	TEGRA210_LANE("pcie-4",    0x028, 20, 0x3, 5, pci),
83*4e4b5574SStephen Warren 	TEGRA210_LANE("pcie-5",    0x028, 22, 0x3, 6, pci),
84*4e4b5574SStephen Warren 	TEGRA210_LANE("pcie-6",    0x028, 24, 0x3, 7, pci),
85*4e4b5574SStephen Warren 	TEGRA210_LANE("sata-0",    0x028, 30, 0x3, 8, pci),
86*4e4b5574SStephen Warren };
87*4e4b5574SStephen Warren 
886c43f6c8STom Warren #define XUSB_PADCTL_ELPG_PROGRAM 0x024
896c43f6c8STom Warren #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 31)
906c43f6c8STom Warren #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 30)
916c43f6c8STom Warren #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 29)
926c43f6c8STom Warren 
936c43f6c8STom Warren static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
946c43f6c8STom Warren {
956c43f6c8STom Warren 	u32 value;
966c43f6c8STom Warren 
976c43f6c8STom Warren 	if (padctl->enable++ > 0)
986c43f6c8STom Warren 		return 0;
996c43f6c8STom Warren 
1006c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1016c43f6c8STom Warren 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
1026c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1036c43f6c8STom Warren 
1046c43f6c8STom Warren 	udelay(100);
1056c43f6c8STom Warren 
1066c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1076c43f6c8STom Warren 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
1086c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1096c43f6c8STom Warren 
1106c43f6c8STom Warren 	udelay(100);
1116c43f6c8STom Warren 
1126c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1136c43f6c8STom Warren 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
1146c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1156c43f6c8STom Warren 
1166c43f6c8STom Warren 	return 0;
1176c43f6c8STom Warren }
1186c43f6c8STom Warren 
1196c43f6c8STom Warren static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
1206c43f6c8STom Warren {
1216c43f6c8STom Warren 	u32 value;
1226c43f6c8STom Warren 
1236c43f6c8STom Warren 	if (padctl->enable == 0) {
1246c43f6c8STom Warren 		error("unbalanced enable/disable");
1256c43f6c8STom Warren 		return 0;
1266c43f6c8STom Warren 	}
1276c43f6c8STom Warren 
1286c43f6c8STom Warren 	if (--padctl->enable > 0)
1296c43f6c8STom Warren 		return 0;
1306c43f6c8STom Warren 
1316c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1326c43f6c8STom Warren 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
1336c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1346c43f6c8STom Warren 
1356c43f6c8STom Warren 	udelay(100);
1366c43f6c8STom Warren 
1376c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1386c43f6c8STom Warren 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
1396c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1406c43f6c8STom Warren 
1416c43f6c8STom Warren 	udelay(100);
1426c43f6c8STom Warren 
1436c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1446c43f6c8STom Warren 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
1456c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1466c43f6c8STom Warren 
1476c43f6c8STom Warren 	return 0;
1486c43f6c8STom Warren }
1496c43f6c8STom Warren 
1506c43f6c8STom Warren static int phy_prepare(struct tegra_xusb_phy *phy)
1516c43f6c8STom Warren {
1526c43f6c8STom Warren 	int err;
1536c43f6c8STom Warren 
1546c43f6c8STom Warren 	err = tegra_xusb_padctl_enable(phy->padctl);
1556c43f6c8STom Warren 	if (err < 0)
1566c43f6c8STom Warren 		return err;
1576c43f6c8STom Warren 
1586c43f6c8STom Warren 	reset_set_enable(PERIPH_ID_PEX_USB_UPHY, 0);
1596c43f6c8STom Warren 
1606c43f6c8STom Warren 	return 0;
1616c43f6c8STom Warren }
1626c43f6c8STom Warren 
1636c43f6c8STom Warren static int phy_unprepare(struct tegra_xusb_phy *phy)
1646c43f6c8STom Warren {
1656c43f6c8STom Warren 	reset_set_enable(PERIPH_ID_PEX_USB_UPHY, 1);
1666c43f6c8STom Warren 
1676c43f6c8STom Warren 	return tegra_xusb_padctl_disable(phy->padctl);
1686c43f6c8STom Warren }
1696c43f6c8STom Warren 
1706c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL1 0x360
1716c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV_MASK (0xff << 20)
1726c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV(x) (((x) & 0xff) << 20)
1736c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_MDIV_MASK (0x3 << 16)
1746c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS (1 << 15)
1756c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD (1 << 4)
1766c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_ENABLE (1 << 3)
1776c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP_MASK (0x3 << 1)
1786c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP(x) (((x) & 0x3) << 1)
1796c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_IDDQ (1 << 0)
1806c43f6c8STom Warren 
1816c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL2 0x364
1826c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL_MASK (0xffffff << 4)
1836c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL(x) (((x) & 0xffffff) << 4)
1846c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD (1 << 2)
1856c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE (1 << 1)
1866c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN (1 << 0)
1876c43f6c8STom Warren 
1886c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL4 0x36c
1896c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_EN (1 << 15)
1906c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL_MASK (0x3 << 12)
1916c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL(x) (((x) & 0x3) << 12)
1926c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLKBUF_EN (1 << 8)
1936c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLK_SEL_MASK (0xf << 4)
1946c43f6c8STom Warren 
1956c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL5 0x370
1966c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL_MASK (0xff << 16)
1976c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL(x) (((x) & 0xff) << 16)
1986c43f6c8STom Warren 
1996c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL8 0x37c
2006c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE (1 << 31)
2016c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD (1 << 15)
2026c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN (1 << 13)
2036c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN (1 << 12)
2046c43f6c8STom Warren 
2056c43f6c8STom Warren #define CLK_RST_XUSBIO_PLL_CFG0 0x51c
2066c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_SEQ_ENABLE (1 << 24)
2076c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ (1 << 13)
2086c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET (1 << 6)
2096c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL (1 << 2)
2106c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL (1 << 0)
2116c43f6c8STom Warren 
2126c43f6c8STom Warren static int pcie_phy_enable(struct tegra_xusb_phy *phy)
2136c43f6c8STom Warren {
2146c43f6c8STom Warren 	struct tegra_xusb_padctl *padctl = phy->padctl;
2156c43f6c8STom Warren 	unsigned long start;
2166c43f6c8STom Warren 	u32 value;
2176c43f6c8STom Warren 
2186c43f6c8STom Warren 	debug("> %s(phy=%p)\n", __func__, phy);
2196c43f6c8STom Warren 
2206c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2216c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL_MASK;
2226c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL(0x136);
2236c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2246c43f6c8STom Warren 
2256c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
2266c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL_MASK;
2276c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL(0x2a);
2286c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
2296c43f6c8STom Warren 
2306c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2316c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD;
2326c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2336c43f6c8STom Warren 
2346c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2356c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD;
2366c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2376c43f6c8STom Warren 
2386c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
2396c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD;
2406c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
2416c43f6c8STom Warren 
2426c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2436c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL_MASK;
2446c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLK_SEL_MASK;
2456c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL(2);
2466c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_EN;
2476c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2486c43f6c8STom Warren 
2496c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2506c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_MDIV_MASK;
2516c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV_MASK;
2526c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV(25);
2536c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2546c43f6c8STom Warren 
2556c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2566c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_IDDQ;
2576c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2586c43f6c8STom Warren 
2596c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2606c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP_MASK;
2616c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2626c43f6c8STom Warren 
2636c43f6c8STom Warren 	udelay(1);
2646c43f6c8STom Warren 
2656c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2666c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLKBUF_EN;
2676c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2686c43f6c8STom Warren 
2696c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2706c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN;
2716c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2726c43f6c8STom Warren 
2736c43f6c8STom Warren 	debug("  waiting for calibration\n");
2746c43f6c8STom Warren 
2756c43f6c8STom Warren 	start = get_timer(0);
2766c43f6c8STom Warren 
2776c43f6c8STom Warren 	while (get_timer(start) < 250) {
2786c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2796c43f6c8STom Warren 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)
2806c43f6c8STom Warren 			break;
2816c43f6c8STom Warren 	}
2826c43f6c8STom Warren 
2836c43f6c8STom Warren 	debug("  done\n");
2846c43f6c8STom Warren 
2856c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2866c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN;
2876c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2886c43f6c8STom Warren 
2896c43f6c8STom Warren 	debug("  waiting for calibration to stop\n");
2906c43f6c8STom Warren 
2916c43f6c8STom Warren 	start = get_timer(0);
2926c43f6c8STom Warren 
2936c43f6c8STom Warren 	while (get_timer(start) < 250) {
2946c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2956c43f6c8STom Warren 		if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) == 0)
2966c43f6c8STom Warren 			break;
2976c43f6c8STom Warren 	}
2986c43f6c8STom Warren 
2996c43f6c8STom Warren 	debug("  done\n");
3006c43f6c8STom Warren 
3016c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3026c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_ENABLE;
3036c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3046c43f6c8STom Warren 
3056c43f6c8STom Warren 	debug("  waiting for PLL to lock...\n");
3066c43f6c8STom Warren 	start = get_timer(0);
3076c43f6c8STom Warren 
3086c43f6c8STom Warren 	while (get_timer(start) < 250) {
3096c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3106c43f6c8STom Warren 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)
3116c43f6c8STom Warren 			break;
3126c43f6c8STom Warren 	}
3136c43f6c8STom Warren 
3146c43f6c8STom Warren 	debug("  done\n");
3156c43f6c8STom Warren 
3166c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3176c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN;
3186c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN;
3196c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3206c43f6c8STom Warren 
3216c43f6c8STom Warren 	debug("  waiting for register calibration...\n");
3226c43f6c8STom Warren 	start = get_timer(0);
3236c43f6c8STom Warren 
3246c43f6c8STom Warren 	while (get_timer(start) < 250) {
3256c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3266c43f6c8STom Warren 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)
3276c43f6c8STom Warren 			break;
3286c43f6c8STom Warren 	}
3296c43f6c8STom Warren 
3306c43f6c8STom Warren 	debug("  done\n");
3316c43f6c8STom Warren 
3326c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3336c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN;
3346c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3356c43f6c8STom Warren 
3366c43f6c8STom Warren 	debug("  waiting for register calibration to stop...\n");
3376c43f6c8STom Warren 	start = get_timer(0);
3386c43f6c8STom Warren 
3396c43f6c8STom Warren 	while (get_timer(start) < 250) {
3406c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3416c43f6c8STom Warren 		if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) == 0)
3426c43f6c8STom Warren 			break;
3436c43f6c8STom Warren 	}
3446c43f6c8STom Warren 
3456c43f6c8STom Warren 	debug("  done\n");
3466c43f6c8STom Warren 
3476c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3486c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN;
3496c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3506c43f6c8STom Warren 
3516c43f6c8STom Warren 	value = readl(NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3526c43f6c8STom Warren 	value &= ~CLK_RST_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL;
3536c43f6c8STom Warren 	value &= ~CLK_RST_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL;
3546c43f6c8STom Warren 	value |= CLK_RST_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET;
3556c43f6c8STom Warren 	value |= CLK_RST_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ;
3566c43f6c8STom Warren 	writel(value, NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3576c43f6c8STom Warren 
3586c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3596c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD;
3606c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3616c43f6c8STom Warren 
3626c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
3636c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD;
3646c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
3656c43f6c8STom Warren 
3666c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3676c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD;
3686c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3696c43f6c8STom Warren 
3706c43f6c8STom Warren 	udelay(1);
3716c43f6c8STom Warren 
3726c43f6c8STom Warren 	value = readl(NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3736c43f6c8STom Warren 	value |= CLK_RST_XUSBIO_PLL_CFG0_SEQ_ENABLE;
3746c43f6c8STom Warren 	writel(value, NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3756c43f6c8STom Warren 
3766c43f6c8STom Warren 	debug("< %s()\n", __func__);
3776c43f6c8STom Warren 	return 0;
3786c43f6c8STom Warren }
3796c43f6c8STom Warren 
3806c43f6c8STom Warren static int pcie_phy_disable(struct tegra_xusb_phy *phy)
3816c43f6c8STom Warren {
3826c43f6c8STom Warren 	return 0;
3836c43f6c8STom Warren }
3846c43f6c8STom Warren 
3856c43f6c8STom Warren static const struct tegra_xusb_phy_ops pcie_phy_ops = {
3866c43f6c8STom Warren 	.prepare = phy_prepare,
3876c43f6c8STom Warren 	.enable = pcie_phy_enable,
3886c43f6c8STom Warren 	.disable = pcie_phy_disable,
3896c43f6c8STom Warren 	.unprepare = phy_unprepare,
3906c43f6c8STom Warren };
3916c43f6c8STom Warren 
3927a908c7eSStephen Warren static struct tegra_xusb_phy tegra210_phys[] = {
3937a908c7eSStephen Warren 	{
3947a908c7eSStephen Warren 		.type = TEGRA_XUSB_PADCTL_PCIE,
3956c43f6c8STom Warren 		.ops = &pcie_phy_ops,
3967a908c7eSStephen Warren 		.padctl = &padctl,
3976c43f6c8STom Warren 	},
3986c43f6c8STom Warren };
3996c43f6c8STom Warren 
4007a908c7eSStephen Warren static const struct tegra_xusb_padctl_soc tegra210_socdata = {
401*4e4b5574SStephen Warren 	.lanes = tegra210_lanes,
402*4e4b5574SStephen Warren 	.num_lanes = ARRAY_SIZE(tegra210_lanes),
403*4e4b5574SStephen Warren 	.functions = tegra210_functions,
404*4e4b5574SStephen Warren 	.num_functions = ARRAY_SIZE(tegra210_functions),
4057a908c7eSStephen Warren 	.phys = tegra210_phys,
4067a908c7eSStephen Warren 	.num_phys = ARRAY_SIZE(tegra210_phys),
4077a908c7eSStephen Warren };
4086c43f6c8STom Warren 
4096c43f6c8STom Warren void tegra_xusb_padctl_init(const void *fdt)
4106c43f6c8STom Warren {
4116c43f6c8STom Warren 	int count, nodes[1];
4126c43f6c8STom Warren 
4136c43f6c8STom Warren 	debug("> %s(fdt=%p)\n", __func__, fdt);
4146c43f6c8STom Warren 
4156c43f6c8STom Warren 	count = fdtdec_find_aliases_for_id(fdt, "padctl",
4166c43f6c8STom Warren 					   COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
4176c43f6c8STom Warren 					   nodes, ARRAY_SIZE(nodes));
4187a908c7eSStephen Warren 	if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra210_socdata))
4196c43f6c8STom Warren 		return;
4206c43f6c8STom Warren 
4216c43f6c8STom Warren 	debug("< %s()\n", __func__);
4226c43f6c8STom Warren }
423