1 /* 2 * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #define pr_fmt(fmt) "tegra-xusb-padctl: " fmt 8 9 #include <common.h> 10 #include <errno.h> 11 12 #include "../xusb-padctl-common.h" 13 14 #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> 15 16 #define XUSB_PADCTL_ELPG_PROGRAM 0x01c 17 #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26) 18 #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25) 19 #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24) 20 21 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040 22 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19) 23 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12) 24 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1) 25 26 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044 27 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6) 28 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5) 29 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4) 30 31 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138 32 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27) 33 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24) 34 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3) 35 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1) 36 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0) 37 38 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148 39 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1) 40 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0) 41 42 enum tegra124_function { 43 TEGRA124_FUNC_SNPS, 44 TEGRA124_FUNC_XUSB, 45 TEGRA124_FUNC_UART, 46 TEGRA124_FUNC_PCIE, 47 TEGRA124_FUNC_USB3, 48 TEGRA124_FUNC_SATA, 49 TEGRA124_FUNC_RSVD, 50 }; 51 52 static const char *const tegra124_functions[] = { 53 "snps", 54 "xusb", 55 "uart", 56 "pcie", 57 "usb3", 58 "sata", 59 "rsvd", 60 }; 61 62 static const unsigned int tegra124_otg_functions[] = { 63 TEGRA124_FUNC_SNPS, 64 TEGRA124_FUNC_XUSB, 65 TEGRA124_FUNC_UART, 66 TEGRA124_FUNC_RSVD, 67 }; 68 69 static const unsigned int tegra124_usb_functions[] = { 70 TEGRA124_FUNC_SNPS, 71 TEGRA124_FUNC_XUSB, 72 }; 73 74 static const unsigned int tegra124_pci_functions[] = { 75 TEGRA124_FUNC_PCIE, 76 TEGRA124_FUNC_USB3, 77 TEGRA124_FUNC_SATA, 78 TEGRA124_FUNC_RSVD, 79 }; 80 81 #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ 82 { \ 83 .name = _name, \ 84 .offset = _offset, \ 85 .shift = _shift, \ 86 .mask = _mask, \ 87 .iddq = _iddq, \ 88 .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \ 89 .funcs = tegra124_##_funcs##_functions, \ 90 } 91 92 static const struct tegra_xusb_padctl_lane tegra124_lanes[] = { 93 TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg), 94 TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg), 95 TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg), 96 TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb), 97 TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb), 98 TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb), 99 TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci), 100 TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci), 101 TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci), 102 TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci), 103 TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci), 104 TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci), 105 }; 106 107 static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) 108 { 109 u32 value; 110 111 if (padctl->enable++ > 0) 112 return 0; 113 114 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 115 value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; 116 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 117 118 udelay(100); 119 120 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 121 value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; 122 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 123 124 udelay(100); 125 126 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 127 value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 128 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 129 130 return 0; 131 } 132 133 static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) 134 { 135 u32 value; 136 137 if (padctl->enable == 0) { 138 error("unbalanced enable/disable"); 139 return 0; 140 } 141 142 if (--padctl->enable > 0) 143 return 0; 144 145 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 146 value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; 147 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 148 149 udelay(100); 150 151 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 152 value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; 153 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 154 155 udelay(100); 156 157 value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); 158 value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; 159 padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); 160 161 return 0; 162 } 163 164 static int phy_prepare(struct tegra_xusb_phy *phy) 165 { 166 return tegra_xusb_padctl_enable(phy->padctl); 167 } 168 169 static int phy_unprepare(struct tegra_xusb_phy *phy) 170 { 171 return tegra_xusb_padctl_disable(phy->padctl); 172 } 173 174 static int pcie_phy_enable(struct tegra_xusb_phy *phy) 175 { 176 struct tegra_xusb_padctl *padctl = phy->padctl; 177 int err = -ETIMEDOUT; 178 unsigned long start; 179 u32 value; 180 181 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 182 value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; 183 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 184 185 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); 186 value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | 187 XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | 188 XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; 189 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); 190 191 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 192 value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; 193 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 194 195 start = get_timer(0); 196 197 while (get_timer(start) < 50) { 198 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 199 if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) { 200 err = 0; 201 break; 202 } 203 } 204 205 return err; 206 } 207 208 static int pcie_phy_disable(struct tegra_xusb_phy *phy) 209 { 210 struct tegra_xusb_padctl *padctl = phy->padctl; 211 u32 value; 212 213 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 214 value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; 215 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); 216 217 return 0; 218 } 219 220 static int sata_phy_enable(struct tegra_xusb_phy *phy) 221 { 222 struct tegra_xusb_padctl *padctl = phy->padctl; 223 int err = -ETIMEDOUT; 224 unsigned long start; 225 u32 value; 226 227 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 228 value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; 229 value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; 230 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 231 232 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 233 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; 234 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; 235 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 236 237 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 238 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; 239 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 240 241 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 242 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; 243 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 244 245 start = get_timer(0); 246 247 while (get_timer(start) < 50) { 248 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 249 if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) { 250 err = 0; 251 break; 252 } 253 } 254 255 return err; 256 } 257 258 static int sata_phy_disable(struct tegra_xusb_phy *phy) 259 { 260 struct tegra_xusb_padctl *padctl = phy->padctl; 261 u32 value; 262 263 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 264 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; 265 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 266 267 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 268 value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; 269 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 270 271 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 272 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; 273 value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; 274 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); 275 276 value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 277 value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; 278 value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; 279 padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); 280 281 return 0; 282 } 283 284 static const struct tegra_xusb_phy_ops pcie_phy_ops = { 285 .prepare = phy_prepare, 286 .enable = pcie_phy_enable, 287 .disable = pcie_phy_disable, 288 .unprepare = phy_unprepare, 289 }; 290 291 static const struct tegra_xusb_phy_ops sata_phy_ops = { 292 .prepare = phy_prepare, 293 .enable = sata_phy_enable, 294 .disable = sata_phy_disable, 295 .unprepare = phy_unprepare, 296 }; 297 298 static struct tegra_xusb_phy tegra124_phys[] = { 299 { 300 .type = TEGRA_XUSB_PADCTL_PCIE, 301 .ops = &pcie_phy_ops, 302 .padctl = &padctl, 303 }, 304 { 305 .type = TEGRA_XUSB_PADCTL_SATA, 306 .ops = &sata_phy_ops, 307 .padctl = &padctl, 308 }, 309 }; 310 311 static const struct tegra_xusb_padctl_soc tegra124_socdata = { 312 .lanes = tegra124_lanes, 313 .num_lanes = ARRAY_SIZE(tegra124_lanes), 314 .functions = tegra124_functions, 315 .num_functions = ARRAY_SIZE(tegra124_functions), 316 .phys = tegra124_phys, 317 .num_phys = ARRAY_SIZE(tegra124_phys), 318 }; 319 320 void tegra_xusb_padctl_init(const void *fdt) 321 { 322 int count, nodes[1]; 323 324 count = fdtdec_find_aliases_for_id(fdt, "padctl", 325 COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, 326 nodes, ARRAY_SIZE(nodes)); 327 if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra124_socdata)) 328 return; 329 } 330