xref: /rk3399_rockchip-uboot/arch/arm/mach-tegra/tegra210/xusb-padctl.c (revision 90aa625c9a9e1fb7a2f001fd8e50099bacaf92b8)
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>
11be789092SSimon Glass #include <dm/of_access.h>
12be789092SSimon Glass #include <dm/ofnode.h>
136c43f6c8STom Warren 
147a908c7eSStephen Warren #include "../xusb-padctl-common.h"
156c43f6c8STom Warren 
166c43f6c8STom Warren #include <asm/arch/clock.h>
176c43f6c8STom Warren 
186c43f6c8STom Warren #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
196c43f6c8STom Warren 
20be789092SSimon Glass DECLARE_GLOBAL_DATA_PTR;
21be789092SSimon Glass 
224e4b5574SStephen Warren enum tegra210_function {
234e4b5574SStephen Warren 	TEGRA210_FUNC_SNPS,
244e4b5574SStephen Warren 	TEGRA210_FUNC_XUSB,
254e4b5574SStephen Warren 	TEGRA210_FUNC_UART,
264e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X1,
274e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X4,
284e4b5574SStephen Warren 	TEGRA210_FUNC_USB3,
294e4b5574SStephen Warren 	TEGRA210_FUNC_SATA,
304e4b5574SStephen Warren 	TEGRA210_FUNC_RSVD,
314e4b5574SStephen Warren };
324e4b5574SStephen Warren 
334e4b5574SStephen Warren static const char *const tegra210_functions[] = {
344e4b5574SStephen Warren 	"snps",
354e4b5574SStephen Warren 	"xusb",
364e4b5574SStephen Warren 	"uart",
374e4b5574SStephen Warren 	"pcie-x1",
384e4b5574SStephen Warren 	"pcie-x4",
394e4b5574SStephen Warren 	"usb3",
404e4b5574SStephen Warren 	"sata",
414e4b5574SStephen Warren 	"rsvd",
424e4b5574SStephen Warren };
434e4b5574SStephen Warren 
444e4b5574SStephen Warren static const unsigned int tegra210_otg_functions[] = {
454e4b5574SStephen Warren 	TEGRA210_FUNC_SNPS,
464e4b5574SStephen Warren 	TEGRA210_FUNC_XUSB,
474e4b5574SStephen Warren 	TEGRA210_FUNC_UART,
484e4b5574SStephen Warren 	TEGRA210_FUNC_RSVD,
494e4b5574SStephen Warren };
504e4b5574SStephen Warren 
514e4b5574SStephen Warren static const unsigned int tegra210_usb_functions[] = {
524e4b5574SStephen Warren 	TEGRA210_FUNC_SNPS,
534e4b5574SStephen Warren 	TEGRA210_FUNC_XUSB,
544e4b5574SStephen Warren };
554e4b5574SStephen Warren 
564e4b5574SStephen Warren static const unsigned int tegra210_pci_functions[] = {
574e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X1,
584e4b5574SStephen Warren 	TEGRA210_FUNC_USB3,
594e4b5574SStephen Warren 	TEGRA210_FUNC_SATA,
604e4b5574SStephen Warren 	TEGRA210_FUNC_PCIE_X4,
614e4b5574SStephen Warren };
624e4b5574SStephen Warren 
634e4b5574SStephen Warren #define TEGRA210_LANE(_name, _offset, _shift, _mask, _iddq, _funcs)	\
644e4b5574SStephen Warren 	{								\
654e4b5574SStephen Warren 		.name = _name,						\
664e4b5574SStephen Warren 		.offset = _offset,					\
674e4b5574SStephen Warren 		.shift = _shift,					\
684e4b5574SStephen Warren 		.mask = _mask,						\
694e4b5574SStephen Warren 		.iddq = _iddq,						\
704e4b5574SStephen Warren 		.num_funcs = ARRAY_SIZE(tegra210_##_funcs##_functions),	\
714e4b5574SStephen Warren 		.funcs = tegra210_##_funcs##_functions,			\
724e4b5574SStephen Warren 	}
734e4b5574SStephen Warren 
744e4b5574SStephen Warren static const struct tegra_xusb_padctl_lane tegra210_lanes[] = {
754e4b5574SStephen Warren 	TEGRA210_LANE("otg-0",     0x004,  0, 0x3, 0, otg),
764e4b5574SStephen Warren 	TEGRA210_LANE("otg-1",     0x004,  2, 0x3, 0, otg),
774e4b5574SStephen Warren 	TEGRA210_LANE("otg-2",     0x004,  4, 0x3, 0, otg),
784e4b5574SStephen Warren 	TEGRA210_LANE("otg-3",     0x004,  6, 0x3, 0, otg),
794e4b5574SStephen Warren 	TEGRA210_LANE("usb2-bias", 0x004, 18, 0x3, 0, otg),
804e4b5574SStephen Warren 	TEGRA210_LANE("hsic-0",    0x004, 14, 0x1, 0, usb),
814e4b5574SStephen Warren 	TEGRA210_LANE("hsic-1",    0x004, 15, 0x1, 0, usb),
824e4b5574SStephen Warren 	TEGRA210_LANE("pcie-0",    0x028, 12, 0x3, 1, pci),
834e4b5574SStephen Warren 	TEGRA210_LANE("pcie-1",    0x028, 14, 0x3, 2, pci),
844e4b5574SStephen Warren 	TEGRA210_LANE("pcie-2",    0x028, 16, 0x3, 3, pci),
854e4b5574SStephen Warren 	TEGRA210_LANE("pcie-3",    0x028, 18, 0x3, 4, pci),
864e4b5574SStephen Warren 	TEGRA210_LANE("pcie-4",    0x028, 20, 0x3, 5, pci),
874e4b5574SStephen Warren 	TEGRA210_LANE("pcie-5",    0x028, 22, 0x3, 6, pci),
884e4b5574SStephen Warren 	TEGRA210_LANE("pcie-6",    0x028, 24, 0x3, 7, pci),
894e4b5574SStephen Warren 	TEGRA210_LANE("sata-0",    0x028, 30, 0x3, 8, pci),
904e4b5574SStephen Warren };
914e4b5574SStephen Warren 
926c43f6c8STom Warren #define XUSB_PADCTL_ELPG_PROGRAM 0x024
936c43f6c8STom Warren #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 31)
946c43f6c8STom Warren #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 30)
956c43f6c8STom Warren #define  XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 29)
966c43f6c8STom Warren 
tegra_xusb_padctl_enable(struct tegra_xusb_padctl * padctl)976c43f6c8STom Warren static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
986c43f6c8STom Warren {
996c43f6c8STom Warren 	u32 value;
1006c43f6c8STom Warren 
1016c43f6c8STom Warren 	if (padctl->enable++ > 0)
1026c43f6c8STom Warren 		return 0;
1036c43f6c8STom Warren 
1046c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1056c43f6c8STom Warren 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
1066c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1076c43f6c8STom Warren 
1086c43f6c8STom Warren 	udelay(100);
1096c43f6c8STom Warren 
1106c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1116c43f6c8STom Warren 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
1126c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1136c43f6c8STom Warren 
1146c43f6c8STom Warren 	udelay(100);
1156c43f6c8STom Warren 
1166c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1176c43f6c8STom Warren 	value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
1186c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1196c43f6c8STom Warren 
1206c43f6c8STom Warren 	return 0;
1216c43f6c8STom Warren }
1226c43f6c8STom Warren 
tegra_xusb_padctl_disable(struct tegra_xusb_padctl * padctl)1236c43f6c8STom Warren static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
1246c43f6c8STom Warren {
1256c43f6c8STom Warren 	u32 value;
1266c43f6c8STom Warren 
1276c43f6c8STom Warren 	if (padctl->enable == 0) {
128*90aa625cSMasahiro Yamada 		pr_err("unbalanced enable/disable");
1296c43f6c8STom Warren 		return 0;
1306c43f6c8STom Warren 	}
1316c43f6c8STom Warren 
1326c43f6c8STom Warren 	if (--padctl->enable > 0)
1336c43f6c8STom Warren 		return 0;
1346c43f6c8STom Warren 
1356c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1366c43f6c8STom Warren 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
1376c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1386c43f6c8STom Warren 
1396c43f6c8STom Warren 	udelay(100);
1406c43f6c8STom Warren 
1416c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1426c43f6c8STom Warren 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
1436c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1446c43f6c8STom Warren 
1456c43f6c8STom Warren 	udelay(100);
1466c43f6c8STom Warren 
1476c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
1486c43f6c8STom Warren 	value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
1496c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
1506c43f6c8STom Warren 
1516c43f6c8STom Warren 	return 0;
1526c43f6c8STom Warren }
1536c43f6c8STom Warren 
phy_prepare(struct tegra_xusb_phy * phy)1546c43f6c8STom Warren static int phy_prepare(struct tegra_xusb_phy *phy)
1556c43f6c8STom Warren {
1566c43f6c8STom Warren 	int err;
1576c43f6c8STom Warren 
1586c43f6c8STom Warren 	err = tegra_xusb_padctl_enable(phy->padctl);
1596c43f6c8STom Warren 	if (err < 0)
1606c43f6c8STom Warren 		return err;
1616c43f6c8STom Warren 
1626c43f6c8STom Warren 	reset_set_enable(PERIPH_ID_PEX_USB_UPHY, 0);
1636c43f6c8STom Warren 
1646c43f6c8STom Warren 	return 0;
1656c43f6c8STom Warren }
1666c43f6c8STom Warren 
phy_unprepare(struct tegra_xusb_phy * phy)1676c43f6c8STom Warren static int phy_unprepare(struct tegra_xusb_phy *phy)
1686c43f6c8STom Warren {
1696c43f6c8STom Warren 	reset_set_enable(PERIPH_ID_PEX_USB_UPHY, 1);
1706c43f6c8STom Warren 
1716c43f6c8STom Warren 	return tegra_xusb_padctl_disable(phy->padctl);
1726c43f6c8STom Warren }
1736c43f6c8STom Warren 
1746c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL1 0x360
1756c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV_MASK (0xff << 20)
1766c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV(x) (((x) & 0xff) << 20)
1776c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_MDIV_MASK (0x3 << 16)
1786c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS (1 << 15)
1796c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD (1 << 4)
1806c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_ENABLE (1 << 3)
1816c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP_MASK (0x3 << 1)
1826c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP(x) (((x) & 0x3) << 1)
1836c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL1_IDDQ (1 << 0)
1846c43f6c8STom Warren 
1856c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL2 0x364
1866c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL_MASK (0xffffff << 4)
1876c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL(x) (((x) & 0xffffff) << 4)
1886c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD (1 << 2)
1896c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE (1 << 1)
1906c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN (1 << 0)
1916c43f6c8STom Warren 
1926c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL4 0x36c
1936c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_EN (1 << 15)
1946c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL_MASK (0x3 << 12)
1956c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL(x) (((x) & 0x3) << 12)
1966c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLKBUF_EN (1 << 8)
1976c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLK_SEL_MASK (0xf << 4)
1986c43f6c8STom Warren 
1996c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL5 0x370
2006c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL_MASK (0xff << 16)
2016c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL(x) (((x) & 0xff) << 16)
2026c43f6c8STom Warren 
2036c43f6c8STom Warren #define XUSB_PADCTL_UPHY_PLL_P0_CTL8 0x37c
2046c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE (1 << 31)
2056c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD (1 << 15)
2066c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN (1 << 13)
2076c43f6c8STom Warren #define  XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN (1 << 12)
2086c43f6c8STom Warren 
2096c43f6c8STom Warren #define CLK_RST_XUSBIO_PLL_CFG0 0x51c
2106c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_SEQ_ENABLE (1 << 24)
2116c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ (1 << 13)
2126c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET (1 << 6)
2136c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL (1 << 2)
2146c43f6c8STom Warren #define  CLK_RST_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL (1 << 0)
2156c43f6c8STom Warren 
pcie_phy_enable(struct tegra_xusb_phy * phy)2166c43f6c8STom Warren static int pcie_phy_enable(struct tegra_xusb_phy *phy)
2176c43f6c8STom Warren {
2186c43f6c8STom Warren 	struct tegra_xusb_padctl *padctl = phy->padctl;
2196c43f6c8STom Warren 	unsigned long start;
2206c43f6c8STom Warren 	u32 value;
2216c43f6c8STom Warren 
2226c43f6c8STom Warren 	debug("> %s(phy=%p)\n", __func__, phy);
2236c43f6c8STom Warren 
2246c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2256c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL_MASK;
2266c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL(0x136);
2276c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2286c43f6c8STom Warren 
2296c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
2306c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL_MASK;
2316c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL(0x2a);
2326c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
2336c43f6c8STom Warren 
2346c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2356c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD;
2366c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2376c43f6c8STom Warren 
2386c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2396c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD;
2406c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2416c43f6c8STom Warren 
2426c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
2436c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD;
2446c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
2456c43f6c8STom Warren 
2466c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2476c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL_MASK;
2486c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLK_SEL_MASK;
2496c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL(2);
2506c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_EN;
2516c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2526c43f6c8STom Warren 
2536c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2546c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_MDIV_MASK;
2556c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV_MASK;
2566c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV(25);
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_IDDQ;
2616c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2626c43f6c8STom Warren 
2636c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2646c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP_MASK;
2656c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
2666c43f6c8STom Warren 
2676c43f6c8STom Warren 	udelay(1);
2686c43f6c8STom Warren 
2696c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2706c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLKBUF_EN;
2716c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
2726c43f6c8STom Warren 
2736c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2746c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN;
2756c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2766c43f6c8STom Warren 
2776c43f6c8STom Warren 	debug("  waiting for calibration\n");
2786c43f6c8STom Warren 
2796c43f6c8STom Warren 	start = get_timer(0);
2806c43f6c8STom Warren 
2816c43f6c8STom Warren 	while (get_timer(start) < 250) {
2826c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2836c43f6c8STom Warren 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)
2846c43f6c8STom Warren 			break;
2856c43f6c8STom Warren 	}
286f35cb125SStephen Warren 	if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)) {
287f35cb125SStephen Warren 		debug("  timeout\n");
288f35cb125SStephen Warren 		return -ETIMEDOUT;
289f35cb125SStephen Warren 	}
2906c43f6c8STom Warren 	debug("  done\n");
2916c43f6c8STom Warren 
2926c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2936c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN;
2946c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
2956c43f6c8STom Warren 
2966c43f6c8STom Warren 	debug("  waiting for calibration to stop\n");
2976c43f6c8STom Warren 
2986c43f6c8STom Warren 	start = get_timer(0);
2996c43f6c8STom Warren 
3006c43f6c8STom Warren 	while (get_timer(start) < 250) {
3016c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
3026c43f6c8STom Warren 		if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) == 0)
3036c43f6c8STom Warren 			break;
3046c43f6c8STom Warren 	}
305f35cb125SStephen Warren 	if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) {
306f35cb125SStephen Warren 		debug("  timeout\n");
307f35cb125SStephen Warren 		return -ETIMEDOUT;
308f35cb125SStephen Warren 	}
3096c43f6c8STom Warren 	debug("  done\n");
3106c43f6c8STom Warren 
3116c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3126c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_ENABLE;
3136c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3146c43f6c8STom Warren 
3156c43f6c8STom Warren 	debug("  waiting for PLL to lock...\n");
3166c43f6c8STom Warren 	start = get_timer(0);
3176c43f6c8STom Warren 
3186c43f6c8STom Warren 	while (get_timer(start) < 250) {
3196c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3206c43f6c8STom Warren 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)
3216c43f6c8STom Warren 			break;
3226c43f6c8STom Warren 	}
323f35cb125SStephen Warren 	if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)) {
324f35cb125SStephen Warren 		debug("  timeout\n");
325f35cb125SStephen Warren 		return -ETIMEDOUT;
326f35cb125SStephen Warren 	}
3276c43f6c8STom Warren 	debug("  done\n");
3286c43f6c8STom Warren 
3296c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3306c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN;
3316c43f6c8STom Warren 	value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN;
3326c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3336c43f6c8STom Warren 
3346c43f6c8STom Warren 	debug("  waiting for register calibration...\n");
3356c43f6c8STom Warren 	start = get_timer(0);
3366c43f6c8STom Warren 
3376c43f6c8STom Warren 	while (get_timer(start) < 250) {
3386c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3396c43f6c8STom Warren 		if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)
3406c43f6c8STom Warren 			break;
3416c43f6c8STom Warren 	}
342f35cb125SStephen Warren 	if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)) {
343f35cb125SStephen Warren 		debug("  timeout\n");
344f35cb125SStephen Warren 		return -ETIMEDOUT;
345f35cb125SStephen Warren 	}
3466c43f6c8STom Warren 	debug("  done\n");
3476c43f6c8STom Warren 
3486c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3496c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN;
3506c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3516c43f6c8STom Warren 
3526c43f6c8STom Warren 	debug("  waiting for register calibration to stop...\n");
3536c43f6c8STom Warren 	start = get_timer(0);
3546c43f6c8STom Warren 
3556c43f6c8STom Warren 	while (get_timer(start) < 250) {
3566c43f6c8STom Warren 		value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3576c43f6c8STom Warren 		if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) == 0)
3586c43f6c8STom Warren 			break;
3596c43f6c8STom Warren 	}
360f35cb125SStephen Warren 	if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) {
361f35cb125SStephen Warren 		debug("  timeout\n");
362f35cb125SStephen Warren 		return -ETIMEDOUT;
363f35cb125SStephen Warren 	}
3646c43f6c8STom Warren 	debug("  done\n");
3656c43f6c8STom Warren 
3666c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3676c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN;
3686c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3696c43f6c8STom Warren 
3706c43f6c8STom Warren 	value = readl(NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3716c43f6c8STom Warren 	value &= ~CLK_RST_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL;
3726c43f6c8STom Warren 	value &= ~CLK_RST_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL;
3736c43f6c8STom Warren 	value |= CLK_RST_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET;
3746c43f6c8STom Warren 	value |= CLK_RST_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ;
3756c43f6c8STom Warren 	writel(value, NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3766c43f6c8STom Warren 
3776c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3786c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD;
3796c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
3806c43f6c8STom Warren 
3816c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
3826c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD;
3836c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
3846c43f6c8STom Warren 
3856c43f6c8STom Warren 	value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3866c43f6c8STom Warren 	value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD;
3876c43f6c8STom Warren 	padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
3886c43f6c8STom Warren 
3896c43f6c8STom Warren 	udelay(1);
3906c43f6c8STom Warren 
3916c43f6c8STom Warren 	value = readl(NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3926c43f6c8STom Warren 	value |= CLK_RST_XUSBIO_PLL_CFG0_SEQ_ENABLE;
3936c43f6c8STom Warren 	writel(value, NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
3946c43f6c8STom Warren 
3956c43f6c8STom Warren 	debug("< %s()\n", __func__);
3966c43f6c8STom Warren 	return 0;
3976c43f6c8STom Warren }
3986c43f6c8STom Warren 
pcie_phy_disable(struct tegra_xusb_phy * phy)3996c43f6c8STom Warren static int pcie_phy_disable(struct tegra_xusb_phy *phy)
4006c43f6c8STom Warren {
4016c43f6c8STom Warren 	return 0;
4026c43f6c8STom Warren }
4036c43f6c8STom Warren 
4046c43f6c8STom Warren static const struct tegra_xusb_phy_ops pcie_phy_ops = {
4056c43f6c8STom Warren 	.prepare = phy_prepare,
4066c43f6c8STom Warren 	.enable = pcie_phy_enable,
4076c43f6c8STom Warren 	.disable = pcie_phy_disable,
4086c43f6c8STom Warren 	.unprepare = phy_unprepare,
4096c43f6c8STom Warren };
4106c43f6c8STom Warren 
4117a908c7eSStephen Warren static struct tegra_xusb_phy tegra210_phys[] = {
4127a908c7eSStephen Warren 	{
4137a908c7eSStephen Warren 		.type = TEGRA_XUSB_PADCTL_PCIE,
4146c43f6c8STom Warren 		.ops = &pcie_phy_ops,
4157a908c7eSStephen Warren 		.padctl = &padctl,
4166c43f6c8STom Warren 	},
4176c43f6c8STom Warren };
4186c43f6c8STom Warren 
4197a908c7eSStephen Warren static const struct tegra_xusb_padctl_soc tegra210_socdata = {
4204e4b5574SStephen Warren 	.lanes = tegra210_lanes,
4214e4b5574SStephen Warren 	.num_lanes = ARRAY_SIZE(tegra210_lanes),
4224e4b5574SStephen Warren 	.functions = tegra210_functions,
4234e4b5574SStephen Warren 	.num_functions = ARRAY_SIZE(tegra210_functions),
4247a908c7eSStephen Warren 	.phys = tegra210_phys,
4257a908c7eSStephen Warren 	.num_phys = ARRAY_SIZE(tegra210_phys),
4267a908c7eSStephen Warren };
4276c43f6c8STom Warren 
tegra_xusb_padctl_init(void)428be789092SSimon Glass void tegra_xusb_padctl_init(void)
4296c43f6c8STom Warren {
430be789092SSimon Glass 	ofnode nodes[1];
431be789092SSimon Glass 	int count = 0;
432be789092SSimon Glass 	int ret;
4336c43f6c8STom Warren 
434be789092SSimon Glass 	debug("%s: start\n", __func__);
435be789092SSimon Glass 	if (of_live_active()) {
436be789092SSimon Glass 		struct device_node *np = of_find_compatible_node(NULL, NULL,
437be789092SSimon Glass 						"nvidia,tegra210-xusb-padctl");
4386c43f6c8STom Warren 
439be789092SSimon Glass 		debug("np=%p\n", np);
440be789092SSimon Glass 		if (np) {
441be789092SSimon Glass 			nodes[0] = np_to_ofnode(np);
442be789092SSimon Glass 			count = 1;
443be789092SSimon Glass 		}
444be789092SSimon Glass 	} else {
445be789092SSimon Glass 		int node_offsets[1];
446be789092SSimon Glass 		int i;
447be789092SSimon Glass 
448be789092SSimon Glass 		count = fdtdec_find_aliases_for_id(gd->fdt_blob, "padctl",
4496c43f6c8STom Warren 				COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
450be789092SSimon Glass 				node_offsets, ARRAY_SIZE(node_offsets));
451be789092SSimon Glass 		for (i = 0; i < count; i++)
452be789092SSimon Glass 			nodes[i] = offset_to_ofnode(node_offsets[i]);
453be789092SSimon Glass 	}
4546c43f6c8STom Warren 
455be789092SSimon Glass 	ret = tegra_xusb_process_nodes(nodes, count, &tegra210_socdata);
456be789092SSimon Glass 	debug("%s: done, ret=%d\n", __func__, ret);
4576c43f6c8STom Warren }
458