1 /* $NetBSD: tegra210_xusbpad.c,v 1.9 2018/07/16 23:11:47 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: tegra210_xusbpad.c,v 1.9 2018/07/16 23:11:47 christos Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/device.h> 35 #include <sys/intr.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 39 #include <arm/nvidia/tegra_reg.h> 40 #include <arm/nvidia/tegra_var.h> 41 #include <arm/nvidia/tegra_xusbpad.h> 42 43 #include <dev/fdt/fdtvar.h> 44 45 #define XUSB_PADCTL_USB2_PAD_MUX_REG 0x04 46 #define XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD __BITS(19,18) 47 #define XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB 1 48 49 #define XUSB_PADCTL_VBUS_OC_MAP_REG 0x18 50 #define XUSB_PADCTL_VBUS_OC_MAP_VBUS_ENABLE(n) __BIT((n) * 5) 51 52 #define XUSB_PADCTL_OC_DET_REG 0x1c 53 #define XUSB_PADCTL_OC_DET_OC_DETECTED_VBUS_PAD(n) __BIT(12 + (n)) 54 #define XUSB_PADCTL_OC_DET_OC_DETECTED(n) __BIT(8 + (n)) 55 #define XUSB_PADCTL_OC_DET_SET_OC_DETECTED(n) __BIT(0 + (n)) 56 57 #define XUSB_PADCTL_ELPG_PROGRAM_1_REG 0x24 58 #define XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_VCORE_DOWN __BIT(31) 59 #define XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN_EARLY __BIT(30) 60 #define XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN __BIT(29) 61 #define XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_VCORE_DOWN(n) __BIT((n) * 3 + 2) 62 #define XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN_EARLY(n) __BIT((n) * 3 + 1) 63 #define XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN(n) __BIT((n) * 3 + 0) 64 65 #define XUSB_PADCTL_USB3_PAD_MUX_REG 0x28 66 #define XUSB_PADCTL_USB3_PAD_MUX_FORCE_SATA_PAD_IDDQ_DISABLE __BIT(8) 67 #define XUSB_PADCTL_USB3_PAD_MUX_FORCE_PCIE_PAD_IDDQ_DISABLE(n) __BIT(1 + (n)) 68 69 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_REG(n) (0x84 + (n) * 0x40) 70 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_VREG_LEV __BITS(8,7) 71 #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_VREG_FIX18 __BIT(6) 72 73 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_0_REG(n) (0x88 + (n) * 0x40) 74 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD_ZI __BIT(29) 75 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD2 __BIT(27) 76 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD __BIT(26) 77 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_0_HS_CURR_LEVEL __BITS(5,0) 78 79 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_1_REG(n) (0x8c + (n) * 0x40) 80 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_1_RPD_CTRL __BITS(30,26) 81 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_1_TERM_RANGE_ADJ __BITS(6,3) 82 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_DR __BIT(2) 83 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_DISC_OVRD __BIT(1) 84 #define XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_CHRP_OVRD __BIT(0) 85 86 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_REG 0x284 87 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_PD __BIT(11) 88 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_DISCON_LEVEL __BITS(5,3) 89 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_SQUELCH_LEVEL __BITS(2,0) 90 91 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_REG 0x288 92 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_PD_TRK __BIT(26) 93 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_DONE_RESET_TIMER __BITS(25,19) 94 #define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_START_TIMER __BITS(18,12) 95 96 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG 0x360 97 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV __BITS(29,28) 98 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV __BITS(27,20) 99 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV __BITS(17,16) 100 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS __BIT(15) 101 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD __BIT(4) 102 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE __BIT(3) 103 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP __BITS(2,1) 104 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ __BIT(0) 105 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG 0x364 106 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL __BITS(27,4) 107 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD __BIT(2) 108 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE __BIT(1) 109 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN __BIT(0) 110 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_3_REG 0x368 111 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG 0x36c 112 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN __BIT(15) 113 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL __BITS(13,12) 114 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN __BIT(8) 115 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL __BITS(7,4) 116 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG 0x370 117 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL __BITS(23,16) 118 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_6_REG 0x374 119 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_7_REG 0x378 120 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG 0x37c 121 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE __BIT(31) 122 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD __BIT(15) 123 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN __BIT(13) 124 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN __BIT(12) 125 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_9_REG 0x380 126 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_10_REG 0x384 127 #define XUSB_PADCTL_UPHY_PLL_P0_CTL_11_REG 0x388 128 129 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(n) (0xa60 + (n) * 0x40) 130 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL __BITS(19,18) 131 132 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_REG(n) (0xa64 + (n) * 0x40) 133 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE __BITS(15,0) 134 135 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_3_REG(n) (0xa68 + (n) * 0x40) 136 137 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_REG(n) (0xa6c + (n) * 0x40) 138 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL __BITS(31,16) 139 140 #define XUSB_PADCTL_UPHY_USB3_PADn_ECTL_6_REG(n) (0xa74 + (n) * 0x40) 141 142 #define FUSE_SKUCALIB_REG 0xf0 143 #define FUSE_SKUCALIB_HS_CURR_LEVEL(n) \ 144 ((n) == 0 ? __BITS(6,0) : __BITS(((n) - 1) * 6 + 17, ((n) - 1) * 6 + 11)) 145 #define FUSE_SKUCALIB_HS_TERM_RANGE_ADJ __BITS(10,7) 146 147 #define FUSE_USBCALIB_REG 0x250 148 #define FUSE_USBCALIB_EXT_RPD_CTRL __BITS(4,0) 149 150 struct tegra210_xusbpad_softc { 151 device_t sc_dev; 152 int sc_phandle; 153 bus_space_tag_t sc_bst; 154 bus_space_handle_t sc_bsh; 155 156 struct fdtbus_reset *sc_rst; 157 158 bool sc_enabled; 159 }; 160 161 struct tegra210_xusbpad_phy_softc { 162 device_t sc_dev; 163 int sc_phandle; 164 struct tegra210_xusbpad_softc *sc_xusbpad; 165 }; 166 167 struct tegra210_xusbpad_phy_attach_args { 168 struct tegra210_xusbpad_softc *paa_xusbpad; 169 int paa_phandle; 170 }; 171 172 #define RD4(sc, reg) \ 173 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 174 #define WR4(sc, reg, val) \ 175 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 176 #define SETCLR4(sc, reg, set, clr) \ 177 tegra_reg_set_clear((sc)->sc_bst, (sc)->sc_bsh, (reg), (set), (clr)) 178 179 static const char * tegra210_xusbpad_usb2_func[] = { "snps", "xusb", "uart" }; 180 static const char * tegra210_xusbpad_hsic_func[] = { "snps", "xusb" }; 181 static const char * tegra210_xusbpad_pcie_func[] = { "pcie-x1", "usb3-ss", "sata", "pcie-x4" }; 182 183 static void 184 tegra210_xusbpad_uphy_enable_pcie(struct tegra210_xusbpad_softc *sc) 185 { 186 uint32_t val; 187 int retry; 188 189 /* UPHY PLLs */ 190 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG, 191 __SHIFTIN(0x136, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL), 192 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL); 193 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG, 194 __SHIFTIN(0x2a, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL), 195 XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL); 196 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 197 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD, 0); 198 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG, 199 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD, 0); 200 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG, 201 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD, 0); 202 203 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG, 204 __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL), 205 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL); 206 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG, 207 __SHIFTIN(2, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL), 208 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL); 209 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG, 210 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN, 0); 211 212 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 213 __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV), 214 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV); 215 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 216 __SHIFTIN(0x19, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV), 217 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV); 218 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 219 __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV), 220 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV); 221 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 222 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ); 223 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 224 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP); 225 226 delay(20); 227 228 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG, 229 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN, 0); 230 231 /* Calibration */ 232 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG, 233 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN, 0); 234 for (retry = 10000; retry > 0; retry--) { 235 delay(2); 236 val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG); 237 if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) != 0) 238 break; 239 } 240 if (retry == 0) { 241 aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (1)\n"); 242 return; 243 } 244 245 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG, 246 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN); 247 for (retry = 10000; retry > 0; retry--) { 248 delay(2); 249 val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG); 250 if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) == 0) 251 break; 252 } 253 if (retry == 0) { 254 aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (2)\n"); 255 return; 256 } 257 258 /* Enable the PLL */ 259 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 260 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE, 0); 261 for (retry = 10000; retry > 0; retry--) { 262 delay(2); 263 val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG); 264 if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS) != 0) 265 break; 266 } 267 if (retry == 0) { 268 aprint_error_dev(sc->sc_dev, "timeout enabling UPHY PLL\n"); 269 return; 270 } 271 272 /* RCAL */ 273 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG, 274 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN, 0); 275 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG, 276 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN, 0); 277 for (retry = 10000; retry > 0; retry--) { 278 delay(2); 279 val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG); 280 if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) != 0) 281 break; 282 } 283 if (retry == 0) { 284 aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (3)\n"); 285 return; 286 } 287 288 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG, 289 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN); 290 for (retry = 10000; retry > 0; retry--) { 291 delay(2); 292 val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG); 293 if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) == 0) 294 break; 295 } 296 if (retry == 0) { 297 aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (4)\n"); 298 return; 299 } 300 301 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG, 302 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN); 303 304 tegra210_car_xusbio_enable_hw_control(); 305 306 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG, 307 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD); 308 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG, 309 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD); 310 SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG, 311 0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD); 312 313 delay(1); 314 315 tegra210_car_xusbio_enable_hw_seq(); 316 } 317 318 static void 319 tegra210_xusbpad_lane_enable_pcie(struct tegra210_xusbpad_softc *sc, int index) 320 { 321 tegra210_xusbpad_uphy_enable_pcie(sc); 322 323 SETCLR4(sc, XUSB_PADCTL_USB3_PAD_MUX_REG, 324 XUSB_PADCTL_USB3_PAD_MUX_FORCE_PCIE_PAD_IDDQ_DISABLE(index), 0); 325 } 326 327 static void 328 tegra210_xusbpad_lane_enable_usb2(struct tegra210_xusbpad_softc *sc, int index) 329 { 330 uint32_t skucalib, usbcalib; 331 332 skucalib = tegra_fuse_read(FUSE_SKUCALIB_REG); 333 const u_int hs_curr_level = __SHIFTOUT(skucalib, FUSE_SKUCALIB_HS_CURR_LEVEL((u_int)index)); 334 const u_int hs_term_range_adj = __SHIFTOUT(skucalib, FUSE_SKUCALIB_HS_TERM_RANGE_ADJ); 335 336 usbcalib = tegra_fuse_read(FUSE_USBCALIB_REG); 337 const u_int ext_rpd_ctrl = __SHIFTOUT(usbcalib, FUSE_USBCALIB_EXT_RPD_CTRL); 338 339 SETCLR4(sc, XUSB_PADCTL_USB2_PAD_MUX_REG, 340 __SHIFTIN(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB, 341 XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD), 342 XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD); 343 344 SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_REG, 345 __SHIFTIN(0x7, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_DISCON_LEVEL) | 346 __SHIFTIN(0x0, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_SQUELCH_LEVEL), 347 XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_DISCON_LEVEL | 348 XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_SQUELCH_LEVEL); 349 SETCLR4(sc, XUSB_PADCTL_USB2_OTG_PADn_CTL_0_REG(index), 350 __SHIFTIN(hs_curr_level, XUSB_PADCTL_USB2_OTG_PADn_CTL_0_HS_CURR_LEVEL), 351 XUSB_PADCTL_USB2_OTG_PADn_CTL_0_HS_CURR_LEVEL | 352 XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD | 353 XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD2 | 354 XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD_ZI); 355 SETCLR4(sc, XUSB_PADCTL_USB2_OTG_PADn_CTL_1_REG(index), 356 __SHIFTIN(hs_term_range_adj, XUSB_PADCTL_USB2_OTG_PADn_CTL_1_TERM_RANGE_ADJ) | 357 __SHIFTIN(ext_rpd_ctrl, XUSB_PADCTL_USB2_OTG_PADn_CTL_1_RPD_CTRL), 358 XUSB_PADCTL_USB2_OTG_PADn_CTL_1_TERM_RANGE_ADJ | 359 XUSB_PADCTL_USB2_OTG_PADn_CTL_1_RPD_CTRL | 360 XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_DR | 361 XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_CHRP_OVRD | 362 XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_DISC_OVRD); 363 SETCLR4(sc, XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_REG(index), 364 XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_VREG_FIX18, 365 XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_VREG_LEV); 366 367 SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_REG, 368 __SHIFTIN(0x1e, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_START_TIMER) | 369 __SHIFTIN(0xa, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_DONE_RESET_TIMER), 370 XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_START_TIMER | 371 XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_DONE_RESET_TIMER); 372 SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_REG, 373 0, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_PD); 374 delay(1); 375 SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_REG, 376 0, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_PD_TRK); 377 delay(50); 378 } 379 380 #define XUSBPAD_LANE(n, i, r, m, f, ef) \ 381 { \ 382 .name = (n), \ 383 .index = (i), \ 384 .reg = (r), \ 385 .mask = (m), \ 386 .funcs = (f), \ 387 .nfuncs = __arraycount(f), \ 388 .enable = (ef) \ 389 } 390 391 static const struct tegra210_xusbpad_lane { 392 const char *name; 393 int index; 394 bus_size_t reg; 395 uint32_t mask; 396 const char **funcs; 397 int nfuncs; 398 void (*enable)(struct tegra210_xusbpad_softc *, int); 399 } tegra210_xusbpad_lanes[] = { 400 XUSBPAD_LANE("usb2-0", 0, 0x04, __BITS(1,0), tegra210_xusbpad_usb2_func, 401 tegra210_xusbpad_lane_enable_usb2), 402 XUSBPAD_LANE("usb2-1", 1, 0x04, __BITS(3,2), tegra210_xusbpad_usb2_func, 403 tegra210_xusbpad_lane_enable_usb2), 404 XUSBPAD_LANE("usb2-2", 2, 0x04, __BITS(5,4), tegra210_xusbpad_usb2_func, 405 tegra210_xusbpad_lane_enable_usb2), 406 XUSBPAD_LANE("usb2-3", 3, 0x04, __BITS(7,6), tegra210_xusbpad_usb2_func, 407 tegra210_xusbpad_lane_enable_usb2), 408 409 XUSBPAD_LANE("hsic-0", 0, 0x04, __BIT(14), tegra210_xusbpad_hsic_func, 410 NULL), 411 XUSBPAD_LANE("hsic-1", 1, 0x04, __BIT(15), tegra210_xusbpad_hsic_func, 412 NULL), 413 414 XUSBPAD_LANE("pcie-0", 0, 0x28, __BITS(13,12), tegra210_xusbpad_pcie_func, 415 tegra210_xusbpad_lane_enable_pcie), 416 XUSBPAD_LANE("pcie-1", 1, 0x28, __BITS(15,14), tegra210_xusbpad_pcie_func, 417 tegra210_xusbpad_lane_enable_pcie), 418 XUSBPAD_LANE("pcie-2", 2, 0x28, __BITS(17,16), tegra210_xusbpad_pcie_func, 419 tegra210_xusbpad_lane_enable_pcie), 420 XUSBPAD_LANE("pcie-3", 3, 0x28, __BITS(19,18), tegra210_xusbpad_pcie_func, 421 tegra210_xusbpad_lane_enable_pcie), 422 XUSBPAD_LANE("pcie-4", 4, 0x28, __BITS(21,20), tegra210_xusbpad_pcie_func, 423 tegra210_xusbpad_lane_enable_pcie), 424 XUSBPAD_LANE("pcie-5", 5, 0x28, __BITS(23,22), tegra210_xusbpad_pcie_func, 425 tegra210_xusbpad_lane_enable_pcie), 426 XUSBPAD_LANE("pcie-6", 6, 0x28, __BITS(25,24), tegra210_xusbpad_pcie_func, 427 tegra210_xusbpad_lane_enable_pcie), 428 429 XUSBPAD_LANE("sata-0", 0, 0x28, __BITS(31,30), tegra210_xusbpad_pcie_func, 430 NULL), 431 }; 432 433 #define XUSBPAD_PORT(n, i, r, m, im) \ 434 { \ 435 .name = (n), \ 436 .index = (i), \ 437 .reg = (r), \ 438 .mask = (m), \ 439 .internal_mask = (im) \ 440 } 441 442 struct tegra210_xusbpad_port { 443 const char *name; 444 int index; 445 bus_size_t reg; 446 uint32_t mask; 447 uint32_t internal_mask; 448 }; 449 450 static const struct tegra210_xusbpad_port tegra210_xusbpad_usb2_ports[] = { 451 XUSBPAD_PORT("usb2-0", 0, 0x08, __BITS(1,0), __BIT(2)), 452 XUSBPAD_PORT("usb2-1", 1, 0x08, __BITS(5,4), __BIT(6)), 453 XUSBPAD_PORT("usb2-2", 2, 0x08, __BITS(9,8), __BIT(10)), 454 XUSBPAD_PORT("usb2-3", 3, 0x08, __BITS(13,12), __BIT(14)), 455 }; 456 457 static const struct tegra210_xusbpad_port tegra210_xusbpad_usb3_ports[] = { 458 XUSBPAD_PORT("usb3-0", 0, 0x14, __BITS(3,0), __BIT(4)), 459 XUSBPAD_PORT("usb3-1", 1, 0x14, __BITS(8,5), __BIT(9)), 460 XUSBPAD_PORT("usb3-2", 2, 0x14, __BITS(13,10), __BIT(14)), 461 XUSBPAD_PORT("usb3-3", 3, 0x14, __BITS(18,15), __BIT(19)), 462 }; 463 464 static const struct tegra210_xusbpad_port tegra210_xusbpad_hsic_ports[] = { 465 XUSBPAD_PORT("hsic-0", 0, 0, 0, 0), 466 XUSBPAD_PORT("hsic-1", 1, 0, 0, 0), 467 }; 468 469 static int 470 tegra210_xusbpad_find_func(const struct tegra210_xusbpad_lane *lane, 471 const char *func) 472 { 473 for (int n = 0; n < lane->nfuncs; n++) 474 if (strcmp(lane->funcs[n], func) == 0) 475 return n; 476 return -1; 477 } 478 479 static const struct tegra210_xusbpad_lane * 480 tegra210_xusbpad_find_lane(const char *name) 481 { 482 for (int n = 0; n < __arraycount(tegra210_xusbpad_lanes); n++) 483 if (strcmp(tegra210_xusbpad_lanes[n].name, name) == 0) 484 return &tegra210_xusbpad_lanes[n]; 485 return NULL; 486 } 487 488 static void 489 tegra210_xusbpad_configure_lane(struct tegra210_xusbpad_softc *sc, 490 int phandle) 491 { 492 const struct tegra210_xusbpad_lane *lane; 493 const char *name, *function; 494 int func; 495 496 name = fdtbus_get_string(phandle, "name"); 497 if (name == NULL) { 498 aprint_error_dev(sc->sc_dev, "no 'name' property\n"); 499 return; 500 } 501 function = fdtbus_get_string(phandle, "nvidia,function"); 502 if (function == NULL) { 503 aprint_error_dev(sc->sc_dev, "no 'nvidia,function' property\n"); 504 return; 505 } 506 507 lane = tegra210_xusbpad_find_lane(name); 508 if (lane == NULL) { 509 aprint_error_dev(sc->sc_dev, "unsupported lane '%s'\n", name); 510 return; 511 } 512 func = tegra210_xusbpad_find_func(lane, function); 513 if (func == -1) { 514 aprint_error_dev(sc->sc_dev, "unsupported function '%s'\n", function); 515 return; 516 } 517 518 aprint_normal_dev(sc->sc_dev, "lane %s: set func %s\n", name, function); 519 SETCLR4(sc, lane->reg, __SHIFTIN(func, lane->mask), lane->mask); 520 521 if (lane->enable) 522 lane->enable(sc, lane->index); 523 } 524 525 static void 526 tegra210_xusbpad_configure_pads(struct tegra210_xusbpad_softc *sc, 527 const char *name) 528 { 529 struct fdtbus_reset *rst; 530 struct clk *clk; 531 int phandle, child; 532 533 /* Search for the pad's node */ 534 phandle = of_find_firstchild_byname(sc->sc_phandle, "pads"); 535 if (phandle == -1) { 536 aprint_error_dev(sc->sc_dev, "no 'pads' node\n"); 537 return; 538 } 539 phandle = of_find_firstchild_byname(phandle, name); 540 if (phandle == -1) { 541 aprint_error_dev(sc->sc_dev, "no 'pads/%s' node\n", name); 542 return; 543 } 544 545 if (!fdtbus_status_okay(phandle)) 546 return; /* pad is disabled */ 547 548 /* Enable the pad's resources */ 549 if (of_hasprop(phandle, "clocks")) { 550 clk = fdtbus_clock_get_index(phandle, 0); 551 if (clk == NULL || clk_enable(clk) != 0) { 552 aprint_error_dev(sc->sc_dev, "couldn't enable %s's clock\n", name); 553 return; 554 } 555 } 556 if (of_hasprop(phandle, "resets")) { 557 rst = fdtbus_reset_get_index(phandle, 0); 558 if (rst == NULL || fdtbus_reset_deassert(rst) != 0) { 559 aprint_error_dev(sc->sc_dev, "couldn't de-assert %s's reset\n", name); 560 return; 561 } 562 } 563 564 /* Attach PHYs */ 565 phandle = of_find_firstchild_byname(phandle, "lanes"); 566 if (phandle == -1) { 567 aprint_error_dev(sc->sc_dev, "no 'pads/%s/lanes' node\n", name); 568 return; 569 } 570 for (child = OF_child(phandle); child; child = OF_peer(child)) { 571 struct tegra210_xusbpad_phy_attach_args paa = { 572 .paa_xusbpad = sc, 573 .paa_phandle = child 574 }; 575 config_found(sc->sc_dev, &paa, NULL); 576 } 577 } 578 579 static const struct tegra210_xusbpad_port * 580 tegra210_xusbpad_find_port(const char *name, const struct tegra210_xusbpad_port *ports, 581 int nports) 582 { 583 for (int n = 0; n < nports; n++) 584 if (strcmp(name, ports[n].name) == 0) 585 return &ports[n]; 586 return NULL; 587 } 588 589 static const struct tegra210_xusbpad_port * 590 tegra210_xusbpad_find_usb2_port(const char *name) 591 { 592 return tegra210_xusbpad_find_port(name, tegra210_xusbpad_usb2_ports, 593 __arraycount(tegra210_xusbpad_usb2_ports)); 594 } 595 596 static const struct tegra210_xusbpad_port * 597 tegra210_xusbpad_find_usb3_port(const char *name) 598 { 599 return tegra210_xusbpad_find_port(name, tegra210_xusbpad_usb3_ports, 600 __arraycount(tegra210_xusbpad_usb3_ports)); 601 } 602 603 static const struct tegra210_xusbpad_port * 604 tegra210_xusbpad_find_hsic_port(const char *name) 605 { 606 return tegra210_xusbpad_find_port(name, tegra210_xusbpad_hsic_ports, 607 __arraycount(tegra210_xusbpad_hsic_ports)); 608 } 609 610 static void 611 tegra210_xusbpad_enable_vbus(struct tegra210_xusbpad_softc *sc, 612 const struct tegra210_xusbpad_port *port, int phandle) 613 { 614 struct fdtbus_regulator *vbus_reg; 615 616 if (!of_hasprop(phandle, "vbus-supply")) 617 return; 618 619 vbus_reg = fdtbus_regulator_acquire(phandle, "vbus-supply"); 620 if (vbus_reg == NULL || fdtbus_regulator_enable(vbus_reg) != 0) { 621 aprint_error_dev(sc->sc_dev, 622 "couldn't enable vbus regulator for port %s\n", 623 port->name); 624 } 625 } 626 627 static void 628 tegra210_xusbpad_configure_usb2_port(struct tegra210_xusbpad_softc *sc, 629 int phandle, const struct tegra210_xusbpad_port *port) 630 { 631 u_int modeval, internal; 632 const char *mode; 633 634 mode = fdtbus_get_string(phandle, "mode"); 635 if (mode == NULL) { 636 aprint_error_dev(sc->sc_dev, "no 'mode' property on port %s\n", port->name); 637 return; 638 } 639 if (strcmp(mode, "host") == 0) 640 modeval = 1; 641 else if (strcmp(mode, "device") == 0) 642 modeval = 2; 643 else if (strcmp(mode, "otg") == 0) 644 modeval = 3; 645 else { 646 aprint_error_dev(sc->sc_dev, "unsupported mode '%s' on port %s\n", mode, port->name); 647 return; 648 } 649 650 internal = of_hasprop(phandle, "nvidia,internal"); 651 652 tegra210_xusbpad_enable_vbus(sc, port, phandle); 653 654 aprint_normal_dev(sc->sc_dev, "port %s: set mode %s, %s\n", port->name, mode, 655 internal ? "internal" : "external"); 656 SETCLR4(sc, port->reg, __SHIFTIN(internal, port->internal_mask), port->internal_mask); 657 SETCLR4(sc, port->reg, __SHIFTIN(modeval, port->mask), port->mask); 658 } 659 660 static void 661 tegra210_xusbpad_configure_usb3_port(struct tegra210_xusbpad_softc *sc, 662 int phandle, const struct tegra210_xusbpad_port *port) 663 { 664 u_int companion, internal; 665 666 if (of_getprop_uint32(phandle, "nvidia,usb2-companion", &companion)) { 667 aprint_error_dev(sc->sc_dev, "no 'nvidia,usb2-companion' property on port %s\n", port->name); 668 return; 669 } 670 internal = of_hasprop(phandle, "nvidia,internal"); 671 672 tegra210_xusbpad_enable_vbus(sc, port, phandle); 673 674 aprint_normal_dev(sc->sc_dev, "port %s: set companion usb2-%d, %s\n", port->name, 675 companion, internal ? "internal" : "external"); 676 SETCLR4(sc, port->reg, __SHIFTIN(internal, port->internal_mask), port->internal_mask); 677 SETCLR4(sc, port->reg, __SHIFTIN(companion, port->mask), port->mask); 678 679 SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(port->index), 680 __SHIFTIN(2, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL), 681 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL); 682 SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_REG(port->index), 683 __SHIFTIN(0xfc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE), 684 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE); 685 WR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_3_REG(port->index), 0xc0077f1f); 686 SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_REG(port->index), 687 __SHIFTIN(0x01c7, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL), 688 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL); 689 WR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_6_REG(port->index), 0xfcf01368); 690 691 SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 692 0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN(port->index)); 693 delay(200); 694 SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 695 0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN_EARLY(port->index)); 696 delay(200); 697 SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 698 0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_VCORE_DOWN(port->index)); 699 700 SETCLR4(sc, XUSB_PADCTL_VBUS_OC_MAP_REG, 701 XUSB_PADCTL_VBUS_OC_MAP_VBUS_ENABLE(port->index), 0); 702 } 703 704 static void 705 tegra210_xusbpad_configure_hsic_port(struct tegra210_xusbpad_softc *sc, 706 int phandle, const struct tegra210_xusbpad_port *port) 707 { 708 tegra210_xusbpad_enable_vbus(sc, port, phandle); 709 } 710 711 static void 712 tegra210_xusbpad_configure_ports(struct tegra210_xusbpad_softc *sc) 713 { 714 const struct tegra210_xusbpad_port *port; 715 const char *port_name; 716 int phandle, child; 717 718 /* Search for the ports node */ 719 phandle = of_find_firstchild_byname(sc->sc_phandle, "ports"); 720 721 /* Configure ports */ 722 for (child = OF_child(phandle); child; child = OF_peer(child)) { 723 if (!fdtbus_status_okay(child)) 724 continue; 725 port_name = fdtbus_get_string(child, "name"); 726 727 if ((port = tegra210_xusbpad_find_usb2_port(port_name)) != NULL) 728 tegra210_xusbpad_configure_usb2_port(sc, child, port); 729 else if ((port = tegra210_xusbpad_find_usb3_port(port_name)) != NULL) 730 tegra210_xusbpad_configure_usb3_port(sc, child, port); 731 else if ((port = tegra210_xusbpad_find_hsic_port(port_name)) != NULL) 732 tegra210_xusbpad_configure_hsic_port(sc, child, port); 733 else 734 aprint_error_dev(sc->sc_dev, "unsupported port '%s'\n", port_name); 735 } 736 } 737 738 static void 739 tegra210_xusbpad_enable(struct tegra210_xusbpad_softc *sc) 740 { 741 if (sc->sc_enabled) 742 return; 743 744 SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN); 745 delay(200); 746 SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN_EARLY); 747 delay(200); 748 SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_VCORE_DOWN); 749 750 sc->sc_enabled = true; 751 } 752 753 static void 754 tegra210_xusbpad_sata_enable(device_t dev) 755 { 756 struct tegra210_xusbpad_softc * const sc = device_private(dev); 757 758 tegra210_xusbpad_enable(sc); 759 } 760 761 static void 762 tegra210_xusbpad_xhci_enable(device_t dev) 763 { 764 struct tegra210_xusbpad_softc * const sc = device_private(dev); 765 766 tegra210_xusbpad_enable(sc); 767 } 768 769 static const struct tegra_xusbpad_ops tegra210_xusbpad_ops = { 770 .sata_enable = tegra210_xusbpad_sata_enable, 771 .xhci_enable = tegra210_xusbpad_xhci_enable, 772 }; 773 774 static int 775 tegra210_xusbpad_match(device_t parent, cfdata_t cf, void *aux) 776 { 777 const char * const compatible[] = { 778 "nvidia,tegra210-xusb-padctl", 779 NULL 780 }; 781 struct fdt_attach_args * const faa = aux; 782 783 return of_match_compatible(faa->faa_phandle, compatible); 784 } 785 786 static void 787 tegra210_xusbpad_attach(device_t parent, device_t self, void *aux) 788 { 789 struct tegra210_xusbpad_softc * const sc = device_private(self); 790 struct fdt_attach_args * const faa = aux; 791 bus_addr_t addr; 792 bus_size_t size; 793 int error; 794 795 if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { 796 aprint_error(": couldn't get registers\n"); 797 return; 798 } 799 sc->sc_rst = fdtbus_reset_get(faa->faa_phandle, "padctl"); 800 if (sc->sc_rst == NULL) { 801 aprint_error(": couldn't get reset padctl\n"); 802 return; 803 } 804 805 sc->sc_dev = self; 806 sc->sc_phandle = faa->faa_phandle; 807 sc->sc_bst = faa->faa_bst; 808 error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); 809 if (error) { 810 aprint_error(": couldn't map %#" PRIx64 ": %d", 811 (uint64_t)addr, error); 812 return; 813 } 814 815 aprint_naive("\n"); 816 aprint_normal(": XUSB PADCTL\n"); 817 818 fdtbus_reset_deassert(sc->sc_rst); 819 820 tegra_xusbpad_register(self, &tegra210_xusbpad_ops); 821 822 tegra210_xusbpad_configure_pads(sc, "usb2"); 823 tegra210_xusbpad_configure_pads(sc, "hsic"); 824 tegra210_xusbpad_configure_pads(sc, "pcie"); 825 tegra210_xusbpad_configure_pads(sc, "sata"); 826 827 tegra210_xusbpad_configure_ports(sc); 828 } 829 830 static void * 831 tegra210_xusbpad_phy_acquire(device_t dev, const void *data, size_t len) 832 { 833 struct tegra210_xusbpad_phy_softc * const sc = device_private(dev); 834 835 if (len != 0) 836 return NULL; 837 838 return sc; 839 } 840 841 static void 842 tegra210_xusbpad_phy_release(device_t dev, void *priv) 843 { 844 }; 845 846 static int 847 tegra210_xusbpad_phy_enable(device_t dev, void *priv, bool enable) 848 { 849 struct tegra210_xusbpad_phy_softc * const sc = device_private(dev); 850 851 if (enable == false) 852 return ENXIO; /* not implemented */ 853 854 tegra210_xusbpad_configure_lane(sc->sc_xusbpad, sc->sc_phandle); 855 856 return 0; 857 } 858 859 static const struct fdtbus_phy_controller_func tegra210_xusbpad_phy_funcs = { 860 .acquire = tegra210_xusbpad_phy_acquire, 861 .release = tegra210_xusbpad_phy_release, 862 .enable = tegra210_xusbpad_phy_enable, 863 }; 864 865 CFATTACH_DECL_NEW(tegra210_xusbpad, sizeof(struct tegra210_xusbpad_softc), 866 tegra210_xusbpad_match, tegra210_xusbpad_attach, NULL, NULL); 867 868 static int 869 tegra210_xusbpad_phy_match(device_t parent, cfdata_t cf, void *aux) 870 { 871 struct tegra210_xusbpad_phy_attach_args * const paa = aux; 872 873 if (!fdtbus_status_okay(paa->paa_phandle)) 874 return 0; 875 876 return 1; 877 } 878 879 static void 880 tegra210_xusbpad_phy_attach(device_t parent, device_t self, void *aux) 881 { 882 struct tegra210_xusbpad_phy_softc * const sc = device_private(self); 883 struct tegra210_xusbpad_phy_attach_args * const paa = aux; 884 885 sc->sc_dev = self; 886 sc->sc_phandle = paa->paa_phandle; 887 sc->sc_xusbpad = paa->paa_xusbpad; 888 889 aprint_naive("\n"); 890 aprint_normal(": %s\n", fdtbus_get_string(sc->sc_phandle, "name")); 891 892 fdtbus_register_phy_controller(self, sc->sc_phandle, &tegra210_xusbpad_phy_funcs); 893 } 894 895 CFATTACH_DECL_NEW(tegra210xphy, sizeof(struct tegra210_xusbpad_phy_softc), 896 tegra210_xusbpad_phy_match, tegra210_xusbpad_phy_attach, NULL, NULL); 897