xref: /netbsd-src/sys/arch/arm/nvidia/tegra210_xusbpad.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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