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