109f455dcSMasahiro Yamada /* 2*1680d7b6SStephen Warren * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. 309f455dcSMasahiro Yamada * 409f455dcSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0 509f455dcSMasahiro Yamada */ 609f455dcSMasahiro Yamada 709f455dcSMasahiro Yamada #define pr_fmt(fmt) "tegra-xusb-padctl: " fmt 809f455dcSMasahiro Yamada 909f455dcSMasahiro Yamada #include <common.h> 1009f455dcSMasahiro Yamada #include <errno.h> 1109f455dcSMasahiro Yamada #include <fdtdec.h> 1209f455dcSMasahiro Yamada #include <malloc.h> 1309f455dcSMasahiro Yamada 14*1680d7b6SStephen Warren #include "../xusb-padctl-common.h" 15*1680d7b6SStephen Warren 1609f455dcSMasahiro Yamada #include <asm/io.h> 1709f455dcSMasahiro Yamada 1809f455dcSMasahiro Yamada #include <asm/arch/clock.h> 1909f455dcSMasahiro Yamada #include <asm/arch-tegra/xusb-padctl.h> 2009f455dcSMasahiro Yamada 2109f455dcSMasahiro Yamada #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> 2209f455dcSMasahiro Yamada 2309f455dcSMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM 0x01c 2409f455dcSMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26) 2509f455dcSMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25) 2609f455dcSMasahiro Yamada #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24) 2709f455dcSMasahiro Yamada 2809f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040 2909f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19) 3009f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12) 3109f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1) 3209f455dcSMasahiro Yamada 3309f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044 3409f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6) 3509f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5) 3609f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4) 3709f455dcSMasahiro Yamada 3809f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138 3909f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27) 4009f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24) 4109f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3) 4209f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1) 4309f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0) 4409f455dcSMasahiro Yamada 4509f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148 4609f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1) 4709f455dcSMasahiro Yamada #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0) 4809f455dcSMasahiro Yamada 4909f455dcSMasahiro Yamada enum tegra124_function { 5009f455dcSMasahiro Yamada TEGRA124_FUNC_SNPS, 5109f455dcSMasahiro Yamada TEGRA124_FUNC_XUSB, 5209f455dcSMasahiro Yamada TEGRA124_FUNC_UART, 5309f455dcSMasahiro Yamada TEGRA124_FUNC_PCIE, 5409f455dcSMasahiro Yamada TEGRA124_FUNC_USB3, 5509f455dcSMasahiro Yamada TEGRA124_FUNC_SATA, 5609f455dcSMasahiro Yamada TEGRA124_FUNC_RSVD, 5709f455dcSMasahiro Yamada }; 5809f455dcSMasahiro Yamada 5909f455dcSMasahiro Yamada static const char *const tegra124_functions[] = { 6009f455dcSMasahiro Yamada "snps", 6109f455dcSMasahiro Yamada "xusb", 6209f455dcSMasahiro Yamada "uart", 6309f455dcSMasahiro Yamada "pcie", 6409f455dcSMasahiro Yamada "usb3", 6509f455dcSMasahiro Yamada "sata", 6609f455dcSMasahiro Yamada "rsvd", 6709f455dcSMasahiro Yamada }; 6809f455dcSMasahiro Yamada 6909f455dcSMasahiro Yamada static const unsigned int tegra124_otg_functions[] = { 7009f455dcSMasahiro Yamada TEGRA124_FUNC_SNPS, 7109f455dcSMasahiro Yamada TEGRA124_FUNC_XUSB, 7209f455dcSMasahiro Yamada TEGRA124_FUNC_UART, 7309f455dcSMasahiro Yamada TEGRA124_FUNC_RSVD, 7409f455dcSMasahiro Yamada }; 7509f455dcSMasahiro Yamada 7609f455dcSMasahiro Yamada static const unsigned int tegra124_usb_functions[] = { 7709f455dcSMasahiro Yamada TEGRA124_FUNC_SNPS, 7809f455dcSMasahiro Yamada TEGRA124_FUNC_XUSB, 7909f455dcSMasahiro Yamada }; 8009f455dcSMasahiro Yamada 8109f455dcSMasahiro Yamada static const unsigned int tegra124_pci_functions[] = { 8209f455dcSMasahiro Yamada TEGRA124_FUNC_PCIE, 8309f455dcSMasahiro Yamada TEGRA124_FUNC_USB3, 8409f455dcSMasahiro Yamada TEGRA124_FUNC_SATA, 8509f455dcSMasahiro Yamada TEGRA124_FUNC_RSVD, 8609f455dcSMasahiro Yamada }; 8709f455dcSMasahiro Yamada 8809f455dcSMasahiro Yamada #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ 8909f455dcSMasahiro Yamada { \ 9009f455dcSMasahiro Yamada .name = _name, \ 9109f455dcSMasahiro Yamada .offset = _offset, \ 9209f455dcSMasahiro Yamada .shift = _shift, \ 9309f455dcSMasahiro Yamada .mask = _mask, \ 9409f455dcSMasahiro Yamada .iddq = _iddq, \ 9509f455dcSMasahiro Yamada .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \ 9609f455dcSMasahiro Yamada .funcs = tegra124_##_funcs##_functions, \ 9709f455dcSMasahiro Yamada } 9809f455dcSMasahiro Yamada 9909f455dcSMasahiro Yamada static const struct tegra_xusb_padctl_lane tegra124_lanes[] = { 10009f455dcSMasahiro Yamada TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg), 10109f455dcSMasahiro Yamada TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg), 10209f455dcSMasahiro Yamada TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg), 10309f455dcSMasahiro Yamada TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb), 10409f455dcSMasahiro Yamada TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb), 10509f455dcSMasahiro Yamada TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb), 10609f455dcSMasahiro Yamada TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci), 10709f455dcSMasahiro Yamada TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci), 10809f455dcSMasahiro Yamada TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci), 10909f455dcSMasahiro Yamada TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci), 11009f455dcSMasahiro Yamada TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci), 11109f455dcSMasahiro Yamada TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci), 11209f455dcSMasahiro Yamada }; 11309f455dcSMasahiro Yamada 11409f455dcSMasahiro Yamada static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) 11509f455dcSMasahiro Yamada { 11609f455dcSMasahiro Yamada u32 value; 11709f455dcSMasahiro Yamada 11809f455dcSMasahiro Yamada if (padctl->enable++ > 0) 11909f455dcSMasahiro Yamada return 0; 12009f455dcSMasahiro Yamada 12109f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 12209f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; 12309f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 12409f455dcSMasahiro Yamada 12509f455dcSMasahiro Yamada udelay(100); 12609f455dcSMasahiro Yamada 12709f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 12809f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; 12909f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 13009f455dcSMasahiro Yamada 13109f455dcSMasahiro Yamada udelay(100); 13209f455dcSMasahiro Yamada 13309f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 13409f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 13509f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 13609f455dcSMasahiro Yamada 13709f455dcSMasahiro Yamada return 0; 13809f455dcSMasahiro Yamada } 13909f455dcSMasahiro Yamada 14009f455dcSMasahiro Yamada static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) 14109f455dcSMasahiro Yamada { 14209f455dcSMasahiro Yamada u32 value; 14309f455dcSMasahiro Yamada 14409f455dcSMasahiro Yamada if (padctl->enable == 0) { 145057fd32fSStephen Warren error("unbalanced enable/disable"); 14609f455dcSMasahiro Yamada return 0; 14709f455dcSMasahiro Yamada } 14809f455dcSMasahiro Yamada 14909f455dcSMasahiro Yamada if (--padctl->enable > 0) 15009f455dcSMasahiro Yamada return 0; 15109f455dcSMasahiro Yamada 15209f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 15309f455dcSMasahiro Yamada value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 15409f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 15509f455dcSMasahiro Yamada 15609f455dcSMasahiro Yamada udelay(100); 15709f455dcSMasahiro Yamada 15809f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 15909f455dcSMasahiro Yamada value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; 16009f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 16109f455dcSMasahiro Yamada 16209f455dcSMasahiro Yamada udelay(100); 16309f455dcSMasahiro Yamada 16409f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 16509f455dcSMasahiro Yamada value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; 16609f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 16709f455dcSMasahiro Yamada 16809f455dcSMasahiro Yamada return 0; 16909f455dcSMasahiro Yamada } 17009f455dcSMasahiro Yamada 17109f455dcSMasahiro Yamada static int phy_prepare(struct tegra_xusb_phy *phy) 17209f455dcSMasahiro Yamada { 17309f455dcSMasahiro Yamada return tegra_xusb_padctl_enable(phy->padctl); 17409f455dcSMasahiro Yamada } 17509f455dcSMasahiro Yamada 17609f455dcSMasahiro Yamada static int phy_unprepare(struct tegra_xusb_phy *phy) 17709f455dcSMasahiro Yamada { 17809f455dcSMasahiro Yamada return tegra_xusb_padctl_disable(phy->padctl); 17909f455dcSMasahiro Yamada } 18009f455dcSMasahiro Yamada 18109f455dcSMasahiro Yamada static int pcie_phy_enable(struct tegra_xusb_phy *phy) 18209f455dcSMasahiro Yamada { 18309f455dcSMasahiro Yamada struct tegra_xusb_padctl *padctl = phy->padctl; 18409f455dcSMasahiro Yamada int err = -ETIMEDOUT; 18509f455dcSMasahiro Yamada unsigned long start; 18609f455dcSMasahiro Yamada u32 value; 18709f455dcSMasahiro Yamada 18809f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 18909f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; 19009f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 19109f455dcSMasahiro Yamada 19209f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); 19309f455dcSMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | 19409f455dcSMasahiro Yamada XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | 19509f455dcSMasahiro Yamada XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; 19609f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); 19709f455dcSMasahiro Yamada 19809f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 19909f455dcSMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; 20009f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 20109f455dcSMasahiro Yamada 20209f455dcSMasahiro Yamada start = get_timer(0); 20309f455dcSMasahiro Yamada 20409f455dcSMasahiro Yamada while (get_timer(start) < 50) { 20509f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 20609f455dcSMasahiro Yamada if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) { 20709f455dcSMasahiro Yamada err = 0; 20809f455dcSMasahiro Yamada break; 20909f455dcSMasahiro Yamada } 21009f455dcSMasahiro Yamada } 21109f455dcSMasahiro Yamada 21209f455dcSMasahiro Yamada return err; 21309f455dcSMasahiro Yamada } 21409f455dcSMasahiro Yamada 21509f455dcSMasahiro Yamada static int pcie_phy_disable(struct tegra_xusb_phy *phy) 21609f455dcSMasahiro Yamada { 21709f455dcSMasahiro Yamada struct tegra_xusb_padctl *padctl = phy->padctl; 21809f455dcSMasahiro Yamada u32 value; 21909f455dcSMasahiro Yamada 22009f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 22109f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; 22209f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 22309f455dcSMasahiro Yamada 22409f455dcSMasahiro Yamada return 0; 22509f455dcSMasahiro Yamada } 22609f455dcSMasahiro Yamada 22709f455dcSMasahiro Yamada static int sata_phy_enable(struct tegra_xusb_phy *phy) 22809f455dcSMasahiro Yamada { 22909f455dcSMasahiro Yamada struct tegra_xusb_padctl *padctl = phy->padctl; 23009f455dcSMasahiro Yamada int err = -ETIMEDOUT; 23109f455dcSMasahiro Yamada unsigned long start; 23209f455dcSMasahiro Yamada u32 value; 23309f455dcSMasahiro Yamada 23409f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 23509f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; 23609f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; 23709f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 23809f455dcSMasahiro Yamada 23909f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 24009f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; 24109f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; 24209f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 24309f455dcSMasahiro Yamada 24409f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 24509f455dcSMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; 24609f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 24709f455dcSMasahiro Yamada 24809f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 24909f455dcSMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; 25009f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 25109f455dcSMasahiro Yamada 25209f455dcSMasahiro Yamada start = get_timer(0); 25309f455dcSMasahiro Yamada 25409f455dcSMasahiro Yamada while (get_timer(start) < 50) { 25509f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 25609f455dcSMasahiro Yamada if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) { 25709f455dcSMasahiro Yamada err = 0; 25809f455dcSMasahiro Yamada break; 25909f455dcSMasahiro Yamada } 26009f455dcSMasahiro Yamada } 26109f455dcSMasahiro Yamada 26209f455dcSMasahiro Yamada return err; 26309f455dcSMasahiro Yamada } 26409f455dcSMasahiro Yamada 26509f455dcSMasahiro Yamada static int sata_phy_disable(struct tegra_xusb_phy *phy) 26609f455dcSMasahiro Yamada { 26709f455dcSMasahiro Yamada struct tegra_xusb_padctl *padctl = phy->padctl; 26809f455dcSMasahiro Yamada u32 value; 26909f455dcSMasahiro Yamada 27009f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 27109f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; 27209f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 27309f455dcSMasahiro Yamada 27409f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 27509f455dcSMasahiro Yamada value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; 27609f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 27709f455dcSMasahiro Yamada 27809f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 27909f455dcSMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; 28009f455dcSMasahiro Yamada value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; 28109f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 28209f455dcSMasahiro Yamada 28309f455dcSMasahiro Yamada value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 28409f455dcSMasahiro Yamada value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; 28509f455dcSMasahiro Yamada value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; 28609f455dcSMasahiro Yamada padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 28709f455dcSMasahiro Yamada 28809f455dcSMasahiro Yamada return 0; 28909f455dcSMasahiro Yamada } 29009f455dcSMasahiro Yamada 29109f455dcSMasahiro Yamada static const struct tegra_xusb_phy_ops pcie_phy_ops = { 29209f455dcSMasahiro Yamada .prepare = phy_prepare, 29309f455dcSMasahiro Yamada .enable = pcie_phy_enable, 29409f455dcSMasahiro Yamada .disable = pcie_phy_disable, 29509f455dcSMasahiro Yamada .unprepare = phy_unprepare, 29609f455dcSMasahiro Yamada }; 29709f455dcSMasahiro Yamada 29809f455dcSMasahiro Yamada static const struct tegra_xusb_phy_ops sata_phy_ops = { 29909f455dcSMasahiro Yamada .prepare = phy_prepare, 30009f455dcSMasahiro Yamada .enable = sata_phy_enable, 30109f455dcSMasahiro Yamada .disable = sata_phy_disable, 30209f455dcSMasahiro Yamada .unprepare = phy_unprepare, 30309f455dcSMasahiro Yamada }; 30409f455dcSMasahiro Yamada 305*1680d7b6SStephen Warren struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) { 30609f455dcSMasahiro Yamada .phys = { 30709f455dcSMasahiro Yamada [0] = { 30809f455dcSMasahiro Yamada .ops = &pcie_phy_ops, 30909f455dcSMasahiro Yamada }, 31009f455dcSMasahiro Yamada [1] = { 31109f455dcSMasahiro Yamada .ops = &sata_phy_ops, 31209f455dcSMasahiro Yamada }, 31309f455dcSMasahiro Yamada }, 31409f455dcSMasahiro Yamada }; 31509f455dcSMasahiro Yamada 316*1680d7b6SStephen Warren int process_nodes(const void *fdt, int nodes[], unsigned int count) 31709f455dcSMasahiro Yamada { 31809f455dcSMasahiro Yamada unsigned int i; 31909f455dcSMasahiro Yamada 32009f455dcSMasahiro Yamada for (i = 0; i < count; i++) { 32109f455dcSMasahiro Yamada enum fdt_compat_id id; 32209f455dcSMasahiro Yamada int err; 32309f455dcSMasahiro Yamada 32409f455dcSMasahiro Yamada if (!fdtdec_get_is_enabled(fdt, nodes[i])) 32509f455dcSMasahiro Yamada continue; 32609f455dcSMasahiro Yamada 32709f455dcSMasahiro Yamada id = fdtdec_lookup(fdt, nodes[i]); 32809f455dcSMasahiro Yamada switch (id) { 32909f455dcSMasahiro Yamada case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL: 33009f455dcSMasahiro Yamada break; 33109f455dcSMasahiro Yamada 33209f455dcSMasahiro Yamada default: 333057fd32fSStephen Warren error("unsupported compatible: %s", 33409f455dcSMasahiro Yamada fdtdec_get_compatible(id)); 33509f455dcSMasahiro Yamada continue; 33609f455dcSMasahiro Yamada } 33709f455dcSMasahiro Yamada 33809f455dcSMasahiro Yamada padctl->num_lanes = ARRAY_SIZE(tegra124_lanes); 33909f455dcSMasahiro Yamada padctl->lanes = tegra124_lanes; 34009f455dcSMasahiro Yamada 34109f455dcSMasahiro Yamada padctl->num_functions = ARRAY_SIZE(tegra124_functions); 34209f455dcSMasahiro Yamada padctl->functions = tegra124_functions; 34309f455dcSMasahiro Yamada 34409f455dcSMasahiro Yamada err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]); 34509f455dcSMasahiro Yamada if (err < 0) { 346057fd32fSStephen Warren error("failed to parse DT: %d", err); 34709f455dcSMasahiro Yamada continue; 34809f455dcSMasahiro Yamada } 34909f455dcSMasahiro Yamada 35009f455dcSMasahiro Yamada /* deassert XUSB padctl reset */ 35109f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); 35209f455dcSMasahiro Yamada 35309f455dcSMasahiro Yamada err = tegra_xusb_padctl_config_apply(padctl, &padctl->config); 35409f455dcSMasahiro Yamada if (err < 0) { 355057fd32fSStephen Warren error("failed to apply pinmux: %d", err); 35609f455dcSMasahiro Yamada continue; 35709f455dcSMasahiro Yamada } 35809f455dcSMasahiro Yamada 35909f455dcSMasahiro Yamada /* only a single instance is supported */ 36009f455dcSMasahiro Yamada break; 36109f455dcSMasahiro Yamada } 36209f455dcSMasahiro Yamada 36309f455dcSMasahiro Yamada return 0; 36409f455dcSMasahiro Yamada } 36509f455dcSMasahiro Yamada 36609f455dcSMasahiro Yamada void tegra_xusb_padctl_init(const void *fdt) 36709f455dcSMasahiro Yamada { 36809f455dcSMasahiro Yamada int count, nodes[1]; 36909f455dcSMasahiro Yamada 37009f455dcSMasahiro Yamada count = fdtdec_find_aliases_for_id(fdt, "padctl", 37109f455dcSMasahiro Yamada COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, 37209f455dcSMasahiro Yamada nodes, ARRAY_SIZE(nodes)); 37309f455dcSMasahiro Yamada if (process_nodes(fdt, nodes, count)) 37409f455dcSMasahiro Yamada return; 37509f455dcSMasahiro Yamada } 376