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