Home | History | Annotate | Line # | Download | only in nvidia
tegra210_xusbpad.c revision 1.5
      1 /* $NetBSD: tegra210_xusbpad.c,v 1.5 2017/09/23 23:21:35 jmcneill Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2017 Jared McNeill <jmcneill (at) 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.5 2017/09/23 23:21:35 jmcneill 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_UPHY_PLL_P0_CTL_1_REG		0x360
     66 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV	__BITS(29,28)
     67 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV	__BITS(27,20)
     68 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV	__BITS(17,16)
     69 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS	__BIT(15)
     70 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD		__BIT(4)
     71 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE		__BIT(3)
     72 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP		__BITS(2,1)
     73 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ		__BIT(0)
     74 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG		0x364
     75 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL		__BITS(27,4)
     76 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD		__BIT(2)
     77 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE		__BIT(1)
     78 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN		__BIT(0)
     79 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_3_REG		0x368
     80 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG		0x36c
     81 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN	__BIT(15)
     82 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL	__BITS(13,12)
     83 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN	__BIT(8)
     84 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL	__BITS(7,4)
     85 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG		0x370
     86 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL		__BITS(23,16)
     87 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_6_REG		0x374
     88 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_7_REG		0x378
     89 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG		0x37c
     90 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE	__BIT(31)
     91 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD	__BIT(15)
     92 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN	__BIT(13)
     93 #define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN		__BIT(12)
     94 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_9_REG		0x380
     95 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_10_REG		0x384
     96 #define	XUSB_PADCTL_UPHY_PLL_P0_CTL_11_REG		0x388
     97 
     98 #define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(n)	(0xa60 + (n) * 0x40)
     99 #define	 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL		__BITS(19,18)
    100 
    101 #define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_REG(n)	(0xa64 + (n) * 0x40)
    102 #define	 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE		__BITS(15,0)
    103 
    104 #define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_3_REG(n)	(0xa68 + (n) * 0x40)
    105 
    106 #define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_REG(n)	(0xa6c + (n) * 0x40)
    107 #define	 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL		__BITS(31,16)
    108 
    109 #define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_6_REG(n)	(0xa74 + (n) * 0x40)
    110 
    111 struct tegra210_xusbpad_softc {
    112 	device_t		sc_dev;
    113 	int			sc_phandle;
    114 	bus_space_tag_t		sc_bst;
    115 	bus_space_handle_t	sc_bsh;
    116 
    117 	struct fdtbus_reset	*sc_rst;
    118 
    119 	bool			sc_enabled;
    120 };
    121 
    122 #define	RD4(sc, reg)					\
    123 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
    124 #define	WR4(sc, reg, val)				\
    125 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
    126 #define	SETCLR4(sc, reg, set, clr)			\
    127 	tegra_reg_set_clear((sc)->sc_bst, (sc)->sc_bsh, (reg), (set), (clr))
    128 
    129 static const char * tegra210_xusbpad_usb2_func[] = { "snps", "xusb", "uart" };
    130 static const char * tegra210_xusbpad_hsic_func[] = { "snps", "xusb" };
    131 static const char * tegra210_xusbpad_pcie_func[] = { "pcie-x1", "usb3-ss", "sata", "pcie-x4" };
    132 
    133 #define	XUSBPAD_LANE(n, r, m, f)		\
    134 	{					\
    135 		.name = (n),			\
    136 		.reg = (r),			\
    137 		.mask = (m),			\
    138 		.funcs = (f),			\
    139 		.nfuncs = __arraycount(f)	\
    140 	}
    141 
    142 static const struct tegra210_xusbpad_lane {
    143 	const char		*name;
    144 	bus_size_t		reg;
    145 	uint32_t		mask;
    146 	const char		**funcs;
    147 	int			nfuncs;
    148 } tegra210_xusbpad_lanes[] = {
    149 	XUSBPAD_LANE("usb2-0", 0x04, __BITS(1,0), tegra210_xusbpad_usb2_func),
    150 	XUSBPAD_LANE("usb2-1", 0x04, __BITS(3,2), tegra210_xusbpad_usb2_func),
    151 	XUSBPAD_LANE("usb2-2", 0x04, __BITS(5,4), tegra210_xusbpad_usb2_func),
    152 	XUSBPAD_LANE("usb2-3", 0x04, __BITS(7,6), tegra210_xusbpad_usb2_func),
    153 
    154 	XUSBPAD_LANE("hsic-0", 0x04, __BIT(14), tegra210_xusbpad_hsic_func),
    155 	XUSBPAD_LANE("hsic-1", 0x04, __BIT(15), tegra210_xusbpad_hsic_func),
    156 
    157 	XUSBPAD_LANE("pcie-0", 0x28, __BITS(13,12), tegra210_xusbpad_pcie_func),
    158 	XUSBPAD_LANE("pcie-1", 0x28, __BITS(15,14), tegra210_xusbpad_pcie_func),
    159 	XUSBPAD_LANE("pcie-2", 0x28, __BITS(17,16), tegra210_xusbpad_pcie_func),
    160 	XUSBPAD_LANE("pcie-3", 0x28, __BITS(19,18), tegra210_xusbpad_pcie_func),
    161 	XUSBPAD_LANE("pcie-4", 0x28, __BITS(21,20), tegra210_xusbpad_pcie_func),
    162 	XUSBPAD_LANE("pcie-5", 0x28, __BITS(23,22), tegra210_xusbpad_pcie_func),
    163 	XUSBPAD_LANE("pcie-6", 0x28, __BITS(25,24), tegra210_xusbpad_pcie_func),
    164 
    165 	XUSBPAD_LANE("sata-0", 0x28, __BITS(31,30), tegra210_xusbpad_pcie_func),
    166 };
    167 
    168 #define	XUSBPAD_PORT(n, i, r, m, im)		\
    169 	{					\
    170 		.name = (n),			\
    171 		.index = (i),			\
    172 		.reg = (r),			\
    173 		.mask = (m),			\
    174 		.internal_mask = (im)		\
    175 	}
    176 
    177 struct tegra210_xusbpad_port {
    178 	const char		*name;
    179 	int			index;
    180 	bus_size_t		reg;
    181 	uint32_t		mask;
    182 	uint32_t		internal_mask;
    183 };
    184 
    185 static const struct tegra210_xusbpad_port tegra210_xusbpad_usb2_ports[] = {
    186 	XUSBPAD_PORT("usb2-0", 0, 0x08, __BITS(1,0), __BIT(2)),
    187 	XUSBPAD_PORT("usb2-1", 1, 0x08, __BITS(5,4), __BIT(6)),
    188 	XUSBPAD_PORT("usb2-2", 2, 0x08, __BITS(9,8), __BIT(10)),
    189 	XUSBPAD_PORT("usb2-3", 3, 0x08, __BITS(13,12), __BIT(14)),
    190 };
    191 
    192 static const struct tegra210_xusbpad_port tegra210_xusbpad_usb3_ports[] = {
    193 	XUSBPAD_PORT("usb3-0", 0, 0x14, __BITS(3,0), __BIT(4)),
    194 	XUSBPAD_PORT("usb3-1", 1, 0x14, __BITS(8,5), __BIT(9)),
    195 	XUSBPAD_PORT("usb3-2", 2, 0x14, __BITS(13,10), __BIT(14)),
    196 	XUSBPAD_PORT("usb3-3", 3, 0x14, __BITS(18,15), __BIT(19)),
    197 };
    198 
    199 static const struct tegra210_xusbpad_port tegra210_xusbpad_hsic_ports[] = {
    200 	XUSBPAD_PORT("hsic-0", 0, 0, 0, 0),
    201 	XUSBPAD_PORT("hsic-1", 1, 0, 0, 0),
    202 };
    203 
    204 static int
    205 tegra210_xusbpad_find_func(const struct tegra210_xusbpad_lane *lane,
    206     const char *func)
    207 {
    208 	for (int n = 0; n < lane->nfuncs; n++)
    209 		if (strcmp(lane->funcs[n], func) == 0)
    210 			return n;
    211 	return -1;
    212 }
    213 
    214 static const struct tegra210_xusbpad_lane *
    215 tegra210_xusbpad_find_lane(const char *name)
    216 {
    217 	for (int n = 0; n < __arraycount(tegra210_xusbpad_lanes); n++)
    218 		if (strcmp(tegra210_xusbpad_lanes[n].name, name) == 0)
    219 			return &tegra210_xusbpad_lanes[n];
    220 	return NULL;
    221 }
    222 
    223 static void
    224 tegra210_xusbpad_configure_lane(struct tegra210_xusbpad_softc *sc,
    225     int phandle)
    226 {
    227 	const struct tegra210_xusbpad_lane *lane;
    228 	const char *name, *function;
    229 	int func;
    230 
    231 	name = fdtbus_get_string(phandle, "name");
    232 	if (name == NULL) {
    233 		aprint_error_dev(sc->sc_dev, "no 'name' property\n");
    234 		return;
    235 	}
    236 	function = fdtbus_get_string(phandle, "nvidia,function");
    237 	if (function == NULL) {
    238 		aprint_error_dev(sc->sc_dev, "no 'nvidia,function' property\n");
    239 		return;
    240 	}
    241 
    242 	lane = tegra210_xusbpad_find_lane(name);
    243 	if (lane == NULL) {
    244 		aprint_error_dev(sc->sc_dev, "unsupported lane '%s'\n", name);
    245 		return;
    246 	}
    247 	func = tegra210_xusbpad_find_func(lane, function);
    248 	if (func == -1) {
    249 		aprint_error_dev(sc->sc_dev, "unsupported function '%s'\n", function);
    250 		return;
    251 	}
    252 
    253 	aprint_normal_dev(sc->sc_dev, "lane %s: set func %s\n", name, function);
    254 	SETCLR4(sc, lane->reg, __SHIFTIN(func, lane->mask), lane->mask);
    255 }
    256 
    257 static void
    258 tegra210_xusbpad_configure_pads(struct tegra210_xusbpad_softc *sc,
    259     const char *name)
    260 {
    261 	struct fdtbus_reset *rst;
    262 	struct clk *clk;
    263 	int phandle, child;
    264 
    265 	/* Search for the pad's node */
    266 	phandle = of_find_firstchild_byname(sc->sc_phandle, "pads");
    267 	if (phandle == -1) {
    268 		aprint_error_dev(sc->sc_dev, "no 'pads' node\n");
    269 		return;
    270 	}
    271 	phandle = of_find_firstchild_byname(phandle, name);
    272 	if (phandle == -1) {
    273 		aprint_error_dev(sc->sc_dev, "no 'pads/%s' node\n", name);
    274 		return;
    275 	}
    276 
    277 	if (!fdtbus_status_okay(phandle))
    278 		return;		/* pad is disabled */
    279 
    280 	/* Enable the pad's resources */
    281 	if (of_hasprop(phandle, "clocks")) {
    282 		clk = fdtbus_clock_get_index(phandle, 0);
    283 		if (clk == NULL || clk_enable(clk) != 0) {
    284 			aprint_error_dev(sc->sc_dev, "couldn't enable %s's clock\n", name);
    285 			return;
    286 		}
    287 	}
    288 	if (of_hasprop(phandle, "resets")) {
    289 		rst = fdtbus_reset_get_index(phandle, 0);
    290 		if (rst == NULL || fdtbus_reset_deassert(rst) != 0) {
    291 			aprint_error_dev(sc->sc_dev, "couldn't de-assert %s's reset\n", name);
    292 			return;
    293 		}
    294 	}
    295 
    296 	/* Configure lanes */
    297 	phandle = of_find_firstchild_byname(phandle, "lanes");
    298 	if (phandle == -1) {
    299 		aprint_error_dev(sc->sc_dev, "no 'pads/%s/lanes' node\n", name);
    300 		return;
    301 	}
    302 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
    303 		if (!fdtbus_status_okay(child))
    304 			continue;
    305 		tegra210_xusbpad_configure_lane(sc, child);
    306 	}
    307 }
    308 
    309 static const struct tegra210_xusbpad_port *
    310 tegra210_xusbpad_find_port(const char *name, const struct tegra210_xusbpad_port *ports,
    311     int nports)
    312 {
    313 	for (int n = 0; n < nports; n++)
    314 		if (strcmp(name, ports[n].name) == 0)
    315 			return &ports[n];
    316 	return NULL;
    317 }
    318 
    319 static const struct tegra210_xusbpad_port *
    320 tegra210_xusbpad_find_usb2_port(const char *name)
    321 {
    322 	return tegra210_xusbpad_find_port(name, tegra210_xusbpad_usb2_ports,
    323 	    __arraycount(tegra210_xusbpad_usb2_ports));
    324 }
    325 
    326 static const struct tegra210_xusbpad_port *
    327 tegra210_xusbpad_find_usb3_port(const char *name)
    328 {
    329 	return tegra210_xusbpad_find_port(name, tegra210_xusbpad_usb3_ports,
    330 	    __arraycount(tegra210_xusbpad_usb3_ports));
    331 }
    332 
    333 static const struct tegra210_xusbpad_port *
    334 tegra210_xusbpad_find_hsic_port(const char *name)
    335 {
    336 	return tegra210_xusbpad_find_port(name, tegra210_xusbpad_hsic_ports,
    337 	    __arraycount(tegra210_xusbpad_hsic_ports));
    338 }
    339 
    340 static void
    341 tegra210_xusbpad_configure_usb2_port(struct tegra210_xusbpad_softc *sc,
    342     int phandle, const struct tegra210_xusbpad_port *port)
    343 {
    344 	struct fdtbus_regulator *vbus_reg;
    345 	const char *mode;
    346 	u_int modeval, internal;
    347 
    348 	mode = fdtbus_get_string(phandle, "mode");
    349 	if (mode == NULL) {
    350 		aprint_error_dev(sc->sc_dev, "no 'mode' property on port %s\n", port->name);
    351 		return;
    352 	}
    353 	if (strcmp(mode, "host") == 0)
    354 		modeval = 1;
    355 	else if (strcmp(mode, "device") == 0)
    356 		modeval = 2;
    357 	else if (strcmp(mode, "otg") == 0)
    358 		modeval = 3;
    359 	else {
    360 		aprint_error_dev(sc->sc_dev, "unsupported mode '%s' on port %s\n", mode, port->name);
    361 		return;
    362 	}
    363 
    364 	internal = of_hasprop(phandle, "nvidia,internal");
    365 
    366 	vbus_reg = fdtbus_regulator_acquire(phandle, "vbus-supply");
    367 	if (vbus_reg && fdtbus_regulator_enable(vbus_reg) != 0) {
    368 		aprint_error_dev(sc->sc_dev,
    369 		    "couldn't enable vbus regulator for port %s\n",
    370 		    port->name);
    371 	}
    372 
    373 	aprint_normal_dev(sc->sc_dev, "port %s: set mode %s, %s\n", port->name, mode,
    374 	    internal ? "internal" : "external");
    375 	SETCLR4(sc, port->reg, __SHIFTIN(internal, port->internal_mask), port->internal_mask);
    376 	SETCLR4(sc, port->reg, __SHIFTIN(modeval, port->mask), port->mask);
    377 }
    378 
    379 static void
    380 tegra210_xusbpad_configure_usb3_port(struct tegra210_xusbpad_softc *sc,
    381     int phandle, const struct tegra210_xusbpad_port *port)
    382 {
    383 	struct fdtbus_regulator *vbus_reg;
    384 	u_int companion, internal;
    385 
    386 	if (of_getprop_uint32(phandle, "nvidia,usb2-companion", &companion)) {
    387 		aprint_error_dev(sc->sc_dev, "no 'nvidia,usb2-companion' property on port %s\n", port->name);
    388 		return;
    389 	}
    390 	internal = of_hasprop(phandle, "nvidia,internal");
    391 
    392 	vbus_reg = fdtbus_regulator_acquire(phandle, "vbus-supply");
    393 	if (vbus_reg && fdtbus_regulator_enable(vbus_reg) != 0) {
    394 		aprint_error_dev(sc->sc_dev,
    395 		    "couldn't enable vbus regulator for port %s\n",
    396 		    port->name);
    397 	}
    398 
    399 	aprint_normal_dev(sc->sc_dev, "port %s: set companion usb2-%d, %s\n", port->name,
    400 	    companion, internal ? "internal" : "external");
    401 	SETCLR4(sc, port->reg, __SHIFTIN(internal, port->internal_mask), port->internal_mask);
    402 	SETCLR4(sc, port->reg, __SHIFTIN(companion, port->mask), port->mask);
    403 
    404 	SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(port->index),
    405 	    __SHIFTIN(2, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL),
    406 	    XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL);
    407 	SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_REG(port->index),
    408 	    __SHIFTIN(0xfc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE),
    409 	    XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE);
    410 	WR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_3_REG(port->index), 0xc0077f1f);
    411 	SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_REG(port->index),
    412 	    __SHIFTIN(0x01c7, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL),
    413 	    XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL);
    414 	WR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_6_REG(port->index), 0xfcf01368);
    415 
    416 	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG,
    417 	    0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN(port->index));
    418 	delay(200);
    419 	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG,
    420 	    0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN_EARLY(port->index));
    421 	delay(200);
    422 	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG,
    423 	    0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_VCORE_DOWN(port->index));
    424 
    425 	SETCLR4(sc, XUSB_PADCTL_VBUS_OC_MAP_REG,
    426 	    XUSB_PADCTL_VBUS_OC_MAP_VBUS_ENABLE(port->index), 0);
    427 }
    428 
    429 static void
    430 tegra210_xusbpad_configure_hsic_port(struct tegra210_xusbpad_softc *sc,
    431     int phandle, const struct tegra210_xusbpad_port *port)
    432 {
    433 	struct fdtbus_regulator *vbus_reg;
    434 
    435 	vbus_reg = fdtbus_regulator_acquire(phandle, "vbus-supply");
    436 	if (vbus_reg && fdtbus_regulator_enable(vbus_reg) != 0) {
    437 		aprint_error_dev(sc->sc_dev,
    438 		    "couldn't enable vbus regulator for port %s\n",
    439 		    port->name);
    440 	}
    441 }
    442 
    443 static void
    444 tegra210_xusbpad_configure_ports(struct tegra210_xusbpad_softc *sc)
    445 {
    446 	const struct tegra210_xusbpad_port *port;
    447 	const char *port_name;
    448 	int phandle, child;
    449 
    450 	/* Search for the ports node */
    451 	phandle = of_find_firstchild_byname(sc->sc_phandle, "ports");
    452 
    453 	/* Configure ports */
    454 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
    455 		if (!fdtbus_status_okay(child))
    456 			continue;
    457 		port_name = fdtbus_get_string(child, "name");
    458 
    459 		if ((port = tegra210_xusbpad_find_usb2_port(port_name)) != NULL)
    460 			tegra210_xusbpad_configure_usb2_port(sc, child, port);
    461 		else if ((port = tegra210_xusbpad_find_usb3_port(port_name)) != NULL)
    462 			tegra210_xusbpad_configure_usb3_port(sc, child, port);
    463 		else if ((port = tegra210_xusbpad_find_hsic_port(port_name)) != NULL)
    464 			tegra210_xusbpad_configure_hsic_port(sc, child, port);
    465 		else
    466 			aprint_error_dev(sc->sc_dev, "unsupported port '%s'\n", port_name);
    467 	}
    468 }
    469 
    470 static void
    471 tegra210_xusbpad_enable(struct tegra210_xusbpad_softc *sc)
    472 {
    473 	if (sc->sc_enabled)
    474 		return;
    475 
    476 	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN);
    477 	delay(200);
    478 	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN_EARLY);
    479 	delay(200);
    480 	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_VCORE_DOWN);
    481 
    482 	sc->sc_enabled = true;
    483 }
    484 
    485 static void
    486 tegra210_xusbpad_sata_enable(device_t dev)
    487 {
    488 	struct tegra210_xusbpad_softc * const sc = device_private(dev);
    489 
    490 	tegra210_xusbpad_enable(sc);
    491 }
    492 
    493 static void
    494 tegra210_xusbpad_xhci_enable(device_t dev)
    495 {
    496 	struct tegra210_xusbpad_softc * const sc = device_private(dev);
    497 	uint32_t val;
    498 	int retry;
    499 
    500 	SETCLR4(sc, XUSB_PADCTL_USB2_PAD_MUX_REG,
    501 	    __SHIFTIN(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB,
    502 		      XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD),
    503 	    XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD);
    504 
    505 	tegra210_xusbpad_enable(sc);
    506 
    507 	/* UPHY PLLs */
    508 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
    509 	    __SHIFTIN(0x136, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL),
    510 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL);
    511 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG,
    512 	    __SHIFTIN(0x2a, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL),
    513 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL);
    514 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
    515 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD, 0);
    516 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
    517 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD, 0);
    518 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
    519 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD, 0);
    520 
    521 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
    522 	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL),
    523 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL);
    524 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
    525 	    __SHIFTIN(2, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL),
    526 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL);
    527 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
    528 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN, 0);
    529 
    530 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
    531 	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV),
    532 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV);
    533 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
    534 	    __SHIFTIN(0x19, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV),
    535 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV);
    536 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
    537 	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV),
    538 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV);
    539 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
    540 	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ);
    541 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
    542 	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP);
    543 
    544 	delay(20);
    545 
    546 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
    547 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN, 0);
    548 
    549 	/* Calibration */
    550 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
    551 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN, 0);
    552 	for (retry = 10000; retry > 0; retry--) {
    553 		delay(2);
    554 		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG);
    555 		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) != 0)
    556 			break;
    557 	}
    558 	if (retry == 0) {
    559 		aprint_error_dev(dev, "timeout calibrating UPHY PLL (1)\n");
    560 		return;
    561 	}
    562 
    563 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
    564 	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN);
    565 	for (retry = 10000; retry > 0; retry--) {
    566 		delay(2);
    567 		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG);
    568 		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) == 0)
    569 			break;
    570 	}
    571 	if (retry == 0) {
    572 		aprint_error_dev(dev, "timeout calibrating UPHY PLL (2)\n");
    573 		return;
    574 	}
    575 
    576 	/* Enable the PLL */
    577 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
    578 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE, 0);
    579 	for (retry = 10000; retry > 0; retry--) {
    580 		delay(2);
    581 		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG);
    582 		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS) != 0)
    583 			break;
    584 	}
    585 	if (retry == 0) {
    586 		aprint_error_dev(dev, "timeout enabling UPHY PLL\n");
    587 		return;
    588 	}
    589 
    590 	/* RCAL */
    591 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
    592 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN, 0);
    593 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
    594 	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN, 0);
    595 	for (retry = 10000; retry > 0; retry--) {
    596 		delay(2);
    597 		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG);
    598 		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) != 0)
    599 			break;
    600 	}
    601 	if (retry == 0) {
    602 		aprint_error_dev(dev, "timeout calibrating UPHY PLL (3)\n");
    603 		return;
    604 	}
    605 
    606 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
    607 	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN);
    608 	for (retry = 10000; retry > 0; retry--) {
    609 		delay(2);
    610 		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG);
    611 		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) == 0)
    612 			break;
    613 	}
    614 	if (retry == 0) {
    615 		aprint_error_dev(dev, "timeout calibrating UPHY PLL (4)\n");
    616 		return;
    617 	}
    618 
    619 	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
    620 	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN);
    621 }
    622 
    623 static const struct tegra_xusbpad_ops tegra210_xusbpad_ops = {
    624 	.sata_enable = tegra210_xusbpad_sata_enable,
    625 	.xhci_enable = tegra210_xusbpad_xhci_enable,
    626 };
    627 
    628 static int
    629 tegra210_xusbpad_match(device_t parent, cfdata_t cf, void *aux)
    630 {
    631 	const char * const compatible[] = {
    632 		"nvidia,tegra210-xusb-padctl",
    633 		NULL
    634 	};
    635 	struct fdt_attach_args * const faa = aux;
    636 
    637 	return of_match_compatible(faa->faa_phandle, compatible);
    638 }
    639 
    640 static void
    641 tegra210_xusbpad_attach(device_t parent, device_t self, void *aux)
    642 {
    643 	struct tegra210_xusbpad_softc * const sc = device_private(self);
    644 	struct fdt_attach_args * const faa = aux;
    645 	bus_addr_t addr;
    646 	bus_size_t size;
    647 	int error;
    648 
    649 	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
    650 		aprint_error(": couldn't get registers\n");
    651 		return;
    652 	}
    653 	sc->sc_rst = fdtbus_reset_get(faa->faa_phandle, "padctl");
    654 	if (sc->sc_rst == NULL) {
    655 		aprint_error(": couldn't get reset padctl\n");
    656 		return;
    657 	}
    658 
    659 	sc->sc_dev = self;
    660 	sc->sc_phandle = faa->faa_phandle;
    661 	sc->sc_bst = faa->faa_bst;
    662 	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
    663 	if (error) {
    664 		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
    665 		return;
    666 	}
    667 
    668 	aprint_naive("\n");
    669 	aprint_normal(": XUSB PADCTL\n");
    670 
    671 	fdtbus_reset_deassert(sc->sc_rst);
    672 
    673 	tegra_xusbpad_register(self, &tegra210_xusbpad_ops);
    674 
    675 	tegra210_xusbpad_configure_pads(sc, "usb2");
    676 	tegra210_xusbpad_configure_pads(sc, "hsic");
    677 	tegra210_xusbpad_configure_pads(sc, "pcie");
    678 	tegra210_xusbpad_configure_pads(sc, "sata");
    679 
    680 	tegra210_xusbpad_configure_ports(sc);
    681 }
    682 
    683 CFATTACH_DECL_NEW(tegra210_xusbpad, sizeof(struct tegra210_xusbpad_softc),
    684 	tegra210_xusbpad_match, tegra210_xusbpad_attach, NULL, NULL);
    685