1/* $NetBSD: tegra210_xusbpad.c,v 1.16 2021/08/07 16:18:44 thorpej 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.16 2021/08/07 16:18:44 thorpej 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(n)	__BIT(8 + (n))
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_MODE		__BITS(9,8)
102#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_BYPASS_ENABLE	__BIT(7)
103#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREERUN_ENABLE	__BIT(6)
104#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD		__BIT(4)
105#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE		__BIT(3)
106#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP		__BITS(2,1)
107#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ		__BIT(0)
108#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG		0x364
109#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL		__BITS(27,4)
110#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_RESET	__BIT(3)
111#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD		__BIT(2)
112#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE		__BIT(1)
113#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN		__BIT(0)
114#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_3_REG		0x368
115#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_3_LOCKDET_CTRL	__BITS(27,4)
116#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_3_LOCKDET_RESET	__BIT(0)
117#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG		0x36c
118#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TCLKOUT_EN	__BIT(28)
119#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_CLKDIST_CTRL	__BITS(23,20)
120#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN	__BIT(15)
121#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL	__BITS(13,12)
122#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN	__BIT(8)
123#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL	__BITS(7,4)
124#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG		0x370
125#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL		__BITS(23,16)
126#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_6_REG		0x374
127#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_7_REG		0x378
128#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG		0x37c
129#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE	__BIT(31)
130#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD	__BIT(15)
131#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN	__BIT(13)
132#define	 XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN		__BIT(12)
133#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_9_REG		0x380
134#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_10_REG		0x384
135#define	XUSB_PADCTL_UPHY_PLL_P0_CTL_11_REG		0x388
136
137#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG		0x860
138#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_PSDIV	__BITS(29,28)
139#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_NDIV	__BITS(27,20)
140#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_MDIV	__BITS(17,16)
141#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_LOCKDET_STATUS	__BIT(15)
142#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_MODE		__BITS(9,8)
143#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_BYPASS_ENABLE	__BIT(7)
144#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREERUN_ENABLE	__BIT(6)
145#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_PWR_OVRD		__BIT(4)
146#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_ENABLE		__BIT(3)
147#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_SLEEP		__BITS(2,1)
148#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_1_IDDQ		__BIT(0)
149#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG		0x864
150#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_CTRL		__BITS(27,4)
151#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_RESET	__BIT(3)
152#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_OVRD		__BIT(2)
153#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_DONE		__BIT(1)
154#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_EN		__BIT(0)
155#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_3_REG		0x868
156#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_3_LOCKDET_CTRL	__BITS(27,4)
157#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_3_LOCKDET_RESET	__BIT(0)
158#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG		0x86c
159#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TCLKOUT_EN	__BIT(28)
160#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_4_CLKDIST_CTRL	__BITS(23,20)
161#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_EN	__BIT(15)
162#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_SEL	__BITS(13,12)
163#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLKBUF_EN	__BIT(8)
164#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLK_SEL	__BITS(7,4)
165#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_5_REG		0x870
166#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_5_DCO_CTRL		__BITS(23,16)
167#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_6_REG		0x874
168#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_7_REG		0x878
169#define	XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG		0x87c
170#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_DONE	__BIT(31)
171#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_OVRD	__BIT(15)
172#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_CLK_EN	__BIT(13)
173#define	 XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_EN		__BIT(12)
174
175#define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(n)	(0xa60 + (n) * 0x40)
176#define	 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL		__BITS(19,18)
177
178#define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_REG(n)	(0xa64 + (n) * 0x40)
179#define	 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE		__BITS(15,0)
180
181#define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_3_REG(n)	(0xa68 + (n) * 0x40)
182
183#define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_REG(n)	(0xa6c + (n) * 0x40)
184#define	 XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL		__BITS(31,16)
185
186#define	XUSB_PADCTL_UPHY_USB3_PADn_ECTL_6_REG(n)	(0xa74 + (n) * 0x40)
187
188#define	FUSE_SKUCALIB_REG				0xf0
189#define	 FUSE_SKUCALIB_HS_CURR_LEVEL(n)			\
190	 ((n) == 0 ? __BITS(6,0) : __BITS(((n) - 1) * 6 + 17, ((n) - 1) * 6 + 11))
191#define	 FUSE_SKUCALIB_HS_TERM_RANGE_ADJ			__BITS(10,7)
192
193#define	FUSE_USBCALIB_REG				0x250
194#define	 FUSE_USBCALIB_EXT_RPD_CTRL			__BITS(4,0)
195
196struct tegra210_xusbpad_softc {
197	device_t		sc_dev;
198	int			sc_phandle;
199	bus_space_tag_t		sc_bst;
200	bus_space_handle_t	sc_bsh;
201
202	struct fdtbus_reset	*sc_rst;
203
204	bool			sc_enabled;
205};
206
207struct tegra210_xusbpad_phy_softc {
208	device_t		sc_dev;
209	int			sc_phandle;
210	struct tegra210_xusbpad_softc *sc_xusbpad;
211};
212
213struct tegra210_xusbpad_phy_attach_args {
214	struct tegra210_xusbpad_softc	*paa_xusbpad;
215	int			paa_phandle;
216};
217
218#define	RD4(sc, reg)					\
219	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
220#define	WR4(sc, reg, val)				\
221	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
222#define	SETCLR4(sc, reg, set, clr)			\
223	tegra_reg_set_clear((sc)->sc_bst, (sc)->sc_bsh, (reg), (set), (clr))
224
225static const char * tegra210_xusbpad_usb2_func[] = { "snps", "xusb", "uart" };
226static const char * tegra210_xusbpad_hsic_func[] = { "snps", "xusb" };
227static const char * tegra210_xusbpad_pcie_func[] = { "pcie-x1", "usb3-ss", "sata", "pcie-x4" };
228
229static void
230tegra210_xusbpad_uphy_enable_pcie(struct tegra210_xusbpad_softc *sc)
231{
232	uint32_t val;
233	int retry;
234
235	/* UPHY PLLs */
236	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
237	    __SHIFTIN(0x136, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL),
238	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_CTRL);
239	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_REG,
240	    __SHIFTIN(0x2a, XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL),
241	    XUSB_PADCTL_UPHY_PLL_P0_CTL_5_DCO_CTRL);
242	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
243	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD, 0);
244	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
245	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD, 0);
246	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
247	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD, 0);
248
249	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
250	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL),
251	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLK_SEL);
252	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
253	    __SHIFTIN(2, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL),
254	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_SEL);
255	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
256	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_TXCLKREF_EN, 0);
257
258	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
259	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV),
260	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_MDIV);
261	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
262	    __SHIFTIN(0x19, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV),
263	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_NDIV);
264	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
265	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV),
266	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_FREQ_PSDIV);
267	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
268	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_IDDQ);
269	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
270	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_SLEEP);
271
272	delay(20);
273
274	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REG,
275	    XUSB_PADCTL_UPHY_PLL_P0_CTL_4_REFCLKBUF_EN, 0);
276
277	/* Calibration */
278	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
279	    XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN, 0);
280	for (retry = 10000; retry > 0; retry--) {
281		delay(2);
282		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG);
283		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) != 0)
284			break;
285	}
286	if (retry == 0) {
287		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (1)\n");
288		return;
289	}
290
291	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
292	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_EN);
293	for (retry = 10000; retry > 0; retry--) {
294		delay(2);
295		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG);
296		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_DONE) == 0)
297			break;
298	}
299	if (retry == 0) {
300		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (2)\n");
301		return;
302	}
303
304	/* Enable the PLL */
305	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
306	    XUSB_PADCTL_UPHY_PLL_P0_CTL_1_ENABLE, 0);
307	for (retry = 10000; retry > 0; retry--) {
308		delay(2);
309		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG);
310		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_1_LOCKDET_STATUS) != 0)
311			break;
312	}
313	if (retry == 0) {
314		aprint_error_dev(sc->sc_dev, "timeout enabling UPHY PLL\n");
315		return;
316	}
317
318	/* RCAL */
319	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
320	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN, 0);
321	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
322	    XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN, 0);
323	for (retry = 10000; retry > 0; retry--) {
324		delay(2);
325		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG);
326		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) != 0)
327			break;
328	}
329	if (retry == 0) {
330		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (3)\n");
331		return;
332	}
333
334	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
335	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_EN);
336	for (retry = 10000; retry > 0; retry--) {
337		delay(2);
338		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG);
339		if ((val & XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_DONE) == 0)
340			break;
341	}
342	if (retry == 0) {
343		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (4)\n");
344		return;
345	}
346
347	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
348	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_CLK_EN);
349
350	tegra210_car_xusbio_enable_hw_control();
351
352	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_REG,
353	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_1_PWR_OVRD);
354	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_REG,
355	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_2_CAL_OVRD);
356	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_REG,
357	    0, XUSB_PADCTL_UPHY_PLL_P0_CTL_8_RCAL_OVRD);
358
359	delay(1);
360
361	tegra210_car_xusbio_enable_hw_seq();
362}
363
364static void
365tegra210_xusbpad_lane_enable_pcie(struct tegra210_xusbpad_softc *sc, int index)
366{
367	tegra210_xusbpad_uphy_enable_pcie(sc);
368
369	SETCLR4(sc, XUSB_PADCTL_USB3_PAD_MUX_REG,
370	    XUSB_PADCTL_USB3_PAD_MUX_FORCE_PCIE_PAD_IDDQ_DISABLE(index), 0);
371}
372
373static void
374tegra210_xusbpad_lane_enable_usb2(struct tegra210_xusbpad_softc *sc, int index)
375{
376	uint32_t skucalib, usbcalib;
377
378	skucalib = tegra_fuse_read(FUSE_SKUCALIB_REG);
379	const u_int hs_curr_level = __SHIFTOUT(skucalib, FUSE_SKUCALIB_HS_CURR_LEVEL((u_int)index));
380	const u_int hs_term_range_adj = __SHIFTOUT(skucalib, FUSE_SKUCALIB_HS_TERM_RANGE_ADJ);
381
382	usbcalib = tegra_fuse_read(FUSE_USBCALIB_REG);
383	const u_int ext_rpd_ctrl = __SHIFTOUT(usbcalib, FUSE_USBCALIB_EXT_RPD_CTRL);
384
385	SETCLR4(sc, XUSB_PADCTL_USB2_PAD_MUX_REG,
386	    __SHIFTIN(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB,
387		      XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD),
388	    XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD);
389
390	SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_REG,
391	    __SHIFTIN(0x7, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_DISCON_LEVEL) |
392	    __SHIFTIN(0x0, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_SQUELCH_LEVEL),
393	    XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_DISCON_LEVEL |
394	    XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_HS_SQUELCH_LEVEL);
395	SETCLR4(sc, XUSB_PADCTL_USB2_OTG_PADn_CTL_0_REG(index),
396	    __SHIFTIN(hs_curr_level, XUSB_PADCTL_USB2_OTG_PADn_CTL_0_HS_CURR_LEVEL),
397	    XUSB_PADCTL_USB2_OTG_PADn_CTL_0_HS_CURR_LEVEL |
398	    XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD |
399	    XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD2 |
400	    XUSB_PADCTL_USB2_OTG_PADn_CTL_0_PD_ZI);
401	SETCLR4(sc, XUSB_PADCTL_USB2_OTG_PADn_CTL_1_REG(index),
402	    __SHIFTIN(hs_term_range_adj, XUSB_PADCTL_USB2_OTG_PADn_CTL_1_TERM_RANGE_ADJ) |
403	    __SHIFTIN(ext_rpd_ctrl, XUSB_PADCTL_USB2_OTG_PADn_CTL_1_RPD_CTRL),
404	    XUSB_PADCTL_USB2_OTG_PADn_CTL_1_TERM_RANGE_ADJ |
405	    XUSB_PADCTL_USB2_OTG_PADn_CTL_1_RPD_CTRL |
406	    XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_DR |
407	    XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_CHRP_OVRD |
408	    XUSB_PADCTL_USB2_OTG_PADn_CTL_1_PD_DISC_OVRD);
409	SETCLR4(sc, XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_REG(index),
410	    XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_VREG_FIX18,
411	    XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADn_CTL_1_VREG_LEV);
412
413	SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_REG,
414	    __SHIFTIN(0x1e, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_START_TIMER) |
415	    __SHIFTIN(0xa, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_DONE_RESET_TIMER),
416	    XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_START_TIMER |
417	    XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_TRK_DONE_RESET_TIMER);
418	SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_REG,
419	    0, XUSB_PADCTL_USB2_BIAS_PAD_CTL_0_PD);
420	delay(1);
421	SETCLR4(sc, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_REG,
422	    0, XUSB_PADCTL_USB2_BIAS_PAD_CTL_1_PD_TRK);
423	delay(50);
424}
425
426
427static void
428tegra210_xusbpad_uphy_enable_sata(struct tegra210_xusbpad_softc *sc)
429{
430	uint32_t val;
431	int retry;
432
433	/* UPHY PLLs */
434	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG,
435	    __SHIFTIN(0x136, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_CTRL),
436	    XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_CTRL);
437	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_5_REG,
438	    __SHIFTIN(0x2a, XUSB_PADCTL_UPHY_PLL_S0_CTL_5_DCO_CTRL),
439	    XUSB_PADCTL_UPHY_PLL_S0_CTL_5_DCO_CTRL);
440	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
441	    XUSB_PADCTL_UPHY_PLL_S0_CTL_1_PWR_OVRD, 0);
442	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG,
443	    XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_OVRD, 0);
444	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG,
445	    XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_OVRD, 0);
446
447	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG,
448	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLK_SEL),
449	    XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLK_SEL);
450	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG,
451	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_SEL),
452	    XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_SEL);
453	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG,
454	    XUSB_PADCTL_UPHY_PLL_S0_CTL_4_TXCLKREF_EN, 0);
455
456	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
457	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_MDIV),
458	    XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_MDIV);
459	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
460	    __SHIFTIN(0x1e, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_NDIV),
461	    XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_NDIV);
462	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
463	    __SHIFTIN(0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_PSDIV),
464	    XUSB_PADCTL_UPHY_PLL_S0_CTL_1_FREQ_PSDIV);
465	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
466	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_IDDQ);
467	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
468	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_SLEEP);
469
470	delay(20);
471
472	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REG,
473	    XUSB_PADCTL_UPHY_PLL_S0_CTL_4_REFCLKBUF_EN, 0);
474
475	/* Calibration */
476	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG,
477	    XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_EN, 0);
478	for (retry = 10000; retry > 0; retry--) {
479		delay(2);
480		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG);
481		if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_DONE) != 0)
482			break;
483	}
484	if (retry == 0) {
485		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (1)\n");
486		return;
487	}
488
489	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG,
490	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_EN);
491	for (retry = 10000; retry > 0; retry--) {
492		delay(2);
493		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG);
494		if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_DONE) == 0)
495			break;
496	}
497	if (retry == 0) {
498		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (2)\n");
499		return;
500	}
501
502	/* Enable the PLL */
503	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
504	    XUSB_PADCTL_UPHY_PLL_S0_CTL_1_ENABLE, 0);
505	for (retry = 10000; retry > 0; retry--) {
506		delay(2);
507		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG);
508		if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_1_LOCKDET_STATUS) != 0)
509			break;
510	}
511	if (retry == 0) {
512		aprint_error_dev(sc->sc_dev, "timeout enabling UPHY PLL\n");
513		return;
514	}
515
516	/* RCAL */
517	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG,
518	    XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_EN, 0);
519	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG,
520	    XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_CLK_EN, 0);
521	for (retry = 10000; retry > 0; retry--) {
522		delay(2);
523		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG);
524		if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_DONE) != 0)
525			break;
526	}
527	if (retry == 0) {
528		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (3)\n");
529		return;
530	}
531
532	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG,
533	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_EN);
534	for (retry = 10000; retry > 0; retry--) {
535		delay(2);
536		val = RD4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG);
537		if ((val & XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_DONE) == 0)
538			break;
539	}
540	if (retry == 0) {
541		aprint_error_dev(sc->sc_dev, "timeout calibrating UPHY PLL (4)\n");
542		return;
543	}
544
545	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG,
546	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_CLK_EN);
547
548	tegra210_car_sata_enable_hw_control();
549
550	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_REG,
551	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_1_PWR_OVRD);
552	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_REG,
553	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_2_CAL_OVRD);
554	SETCLR4(sc, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_REG,
555	    0, XUSB_PADCTL_UPHY_PLL_S0_CTL_8_RCAL_OVRD);
556
557	delay(1);
558
559	tegra210_car_sata_enable_hw_seq();
560}
561
562static void
563tegra210_xusbpad_lane_enable_sata(struct tegra210_xusbpad_softc *sc, int index)
564{
565	tegra210_xusbpad_uphy_enable_sata(sc);
566
567	KASSERT(index == 0);
568	SETCLR4(sc, XUSB_PADCTL_USB3_PAD_MUX_REG,
569	    XUSB_PADCTL_USB3_PAD_MUX_FORCE_SATA_PAD_IDDQ_DISABLE(index), 0);
570}
571
572
573#define	XUSBPAD_LANE(n, i, r, m, f, ef)		\
574	{					\
575		.name = (n),			\
576		.index = (i),			\
577		.reg = (r),			\
578		.mask = (m),			\
579		.funcs = (f),			\
580		.nfuncs = __arraycount(f),	\
581		.enable = (ef)			\
582	}
583
584static const struct tegra210_xusbpad_lane {
585	const char		*name;
586	int			index;
587	bus_size_t		reg;
588	uint32_t		mask;
589	const char		**funcs;
590	int			nfuncs;
591	void			(*enable)(struct tegra210_xusbpad_softc *, int);
592} tegra210_xusbpad_lanes[] = {
593	XUSBPAD_LANE("usb2-0", 0, 0x04, __BITS(1,0), tegra210_xusbpad_usb2_func,
594		     tegra210_xusbpad_lane_enable_usb2),
595	XUSBPAD_LANE("usb2-1", 1, 0x04, __BITS(3,2), tegra210_xusbpad_usb2_func,
596		     tegra210_xusbpad_lane_enable_usb2),
597	XUSBPAD_LANE("usb2-2", 2, 0x04, __BITS(5,4), tegra210_xusbpad_usb2_func,
598		     tegra210_xusbpad_lane_enable_usb2),
599	XUSBPAD_LANE("usb2-3", 3, 0x04, __BITS(7,6), tegra210_xusbpad_usb2_func,
600		     tegra210_xusbpad_lane_enable_usb2),
601
602	XUSBPAD_LANE("hsic-0", 0, 0x04, __BIT(14), tegra210_xusbpad_hsic_func,
603		     NULL),
604	XUSBPAD_LANE("hsic-1", 1, 0x04, __BIT(15), tegra210_xusbpad_hsic_func,
605		     NULL),
606
607	XUSBPAD_LANE("pcie-0", 0, 0x28, __BITS(13,12), tegra210_xusbpad_pcie_func,
608		     tegra210_xusbpad_lane_enable_pcie),
609	XUSBPAD_LANE("pcie-1", 1, 0x28, __BITS(15,14), tegra210_xusbpad_pcie_func,
610		     tegra210_xusbpad_lane_enable_pcie),
611	XUSBPAD_LANE("pcie-2", 2, 0x28, __BITS(17,16), tegra210_xusbpad_pcie_func,
612		     tegra210_xusbpad_lane_enable_pcie),
613	XUSBPAD_LANE("pcie-3", 3, 0x28, __BITS(19,18), tegra210_xusbpad_pcie_func,
614		     tegra210_xusbpad_lane_enable_pcie),
615	XUSBPAD_LANE("pcie-4", 4, 0x28, __BITS(21,20), tegra210_xusbpad_pcie_func,
616		     tegra210_xusbpad_lane_enable_pcie),
617	XUSBPAD_LANE("pcie-5", 5, 0x28, __BITS(23,22), tegra210_xusbpad_pcie_func,
618		     tegra210_xusbpad_lane_enable_pcie),
619	XUSBPAD_LANE("pcie-6", 6, 0x28, __BITS(25,24), tegra210_xusbpad_pcie_func,
620		     tegra210_xusbpad_lane_enable_pcie),
621
622	XUSBPAD_LANE("sata-0", 0, XUSB_PADCTL_USB3_PAD_MUX_REG, __BITS(31,30),
623	    tegra210_xusbpad_pcie_func, tegra210_xusbpad_lane_enable_sata),
624};
625
626#define	XUSBPAD_PORT(n, i, r, m, im)		\
627	{					\
628		.name = (n),			\
629		.index = (i),			\
630		.reg = (r),			\
631		.mask = (m),			\
632		.internal_mask = (im)		\
633	}
634
635struct tegra210_xusbpad_port {
636	const char		*name;
637	int			index;
638	bus_size_t		reg;
639	uint32_t		mask;
640	uint32_t		internal_mask;
641};
642
643static const struct tegra210_xusbpad_port tegra210_xusbpad_usb2_ports[] = {
644	XUSBPAD_PORT("usb2-0", 0, 0x08, __BITS(1,0), __BIT(2)),
645	XUSBPAD_PORT("usb2-1", 1, 0x08, __BITS(5,4), __BIT(6)),
646	XUSBPAD_PORT("usb2-2", 2, 0x08, __BITS(9,8), __BIT(10)),
647	XUSBPAD_PORT("usb2-3", 3, 0x08, __BITS(13,12), __BIT(14)),
648};
649
650static const struct tegra210_xusbpad_port tegra210_xusbpad_usb3_ports[] = {
651	XUSBPAD_PORT("usb3-0", 0, 0x14, __BITS(3,0), __BIT(4)),
652	XUSBPAD_PORT("usb3-1", 1, 0x14, __BITS(8,5), __BIT(9)),
653	XUSBPAD_PORT("usb3-2", 2, 0x14, __BITS(13,10), __BIT(14)),
654	XUSBPAD_PORT("usb3-3", 3, 0x14, __BITS(18,15), __BIT(19)),
655};
656
657static const struct tegra210_xusbpad_port tegra210_xusbpad_hsic_ports[] = {
658	XUSBPAD_PORT("hsic-0", 0, 0, 0, 0),
659	XUSBPAD_PORT("hsic-1", 1, 0, 0, 0),
660};
661
662static int
663tegra210_xusbpad_find_func(const struct tegra210_xusbpad_lane *lane,
664    const char *func)
665{
666	for (int n = 0; n < lane->nfuncs; n++)
667		if (strcmp(lane->funcs[n], func) == 0)
668			return n;
669	return -1;
670}
671
672static const struct tegra210_xusbpad_lane *
673tegra210_xusbpad_find_lane(const char *name)
674{
675	for (int n = 0; n < __arraycount(tegra210_xusbpad_lanes); n++)
676		if (strcmp(tegra210_xusbpad_lanes[n].name, name) == 0)
677			return &tegra210_xusbpad_lanes[n];
678	return NULL;
679}
680
681static void
682tegra210_xusbpad_configure_lane(struct tegra210_xusbpad_softc *sc,
683    int phandle)
684{
685	const struct tegra210_xusbpad_lane *lane;
686	const char *name, *function;
687	int func;
688
689	name = fdtbus_get_string(phandle, "name");
690	if (name == NULL) {
691		aprint_error_dev(sc->sc_dev, "no 'name' property\n");
692		return;
693	}
694	function = fdtbus_get_string(phandle, "nvidia,function");
695	if (function == NULL) {
696		aprint_error_dev(sc->sc_dev, "no 'nvidia,function' property\n");
697		return;
698	}
699
700	lane = tegra210_xusbpad_find_lane(name);
701	if (lane == NULL) {
702		aprint_error_dev(sc->sc_dev, "unsupported lane '%s'\n", name);
703		return;
704	}
705	func = tegra210_xusbpad_find_func(lane, function);
706	if (func == -1) {
707		aprint_error_dev(sc->sc_dev, "unsupported function '%s'\n", function);
708		return;
709	}
710
711	aprint_normal_dev(sc->sc_dev, "lane %s: set func %s\n", name, function);
712	SETCLR4(sc, lane->reg, __SHIFTIN(func, lane->mask), lane->mask);
713
714	if (lane->enable)
715		lane->enable(sc, lane->index);
716}
717
718static void
719tegra210_xusbpad_configure_pads(struct tegra210_xusbpad_softc *sc,
720    const char *name)
721{
722	struct fdtbus_reset *rst;
723	struct clk *clk;
724	int phandle, child;
725
726	/* Search for the pad's node */
727	phandle = of_find_firstchild_byname(sc->sc_phandle, "pads");
728	if (phandle == -1) {
729		aprint_error_dev(sc->sc_dev, "no 'pads' node\n");
730		return;
731	}
732	phandle = of_find_firstchild_byname(phandle, name);
733	if (phandle == -1) {
734		aprint_error_dev(sc->sc_dev, "no 'pads/%s' node\n", name);
735		return;
736	}
737
738	if (!fdtbus_status_okay(phandle))
739		return;		/* pad is disabled */
740
741	/* Enable the pad's resources */
742	if (of_hasprop(phandle, "clocks")) {
743		clk = fdtbus_clock_get_index(phandle, 0);
744		if (clk == NULL || clk_enable(clk) != 0) {
745			aprint_error_dev(sc->sc_dev, "couldn't enable %s's clock\n", name);
746			return;
747		}
748	}
749	if (of_hasprop(phandle, "resets")) {
750		rst = fdtbus_reset_get_index(phandle, 0);
751		if (rst == NULL || fdtbus_reset_deassert(rst) != 0) {
752			aprint_error_dev(sc->sc_dev, "couldn't de-assert %s's reset\n", name);
753			return;
754		}
755	}
756
757	/* Attach PHYs */
758	phandle = of_find_firstchild_byname(phandle, "lanes");
759	if (phandle == -1) {
760		aprint_error_dev(sc->sc_dev, "no 'pads/%s/lanes' node\n", name);
761		return;
762	}
763	for (child = OF_child(phandle); child; child = OF_peer(child)) {
764		struct tegra210_xusbpad_phy_attach_args paa = {
765			.paa_xusbpad = sc,
766			.paa_phandle = child
767		};
768		config_found(sc->sc_dev, &paa, NULL, CFARGS_NONE);
769	}
770}
771
772static const struct tegra210_xusbpad_port *
773tegra210_xusbpad_find_port(const char *name, const struct tegra210_xusbpad_port *ports,
774    int nports)
775{
776	for (int n = 0; n < nports; n++)
777		if (strcmp(name, ports[n].name) == 0)
778			return &ports[n];
779	return NULL;
780}
781
782static const struct tegra210_xusbpad_port *
783tegra210_xusbpad_find_usb2_port(const char *name)
784{
785	return tegra210_xusbpad_find_port(name, tegra210_xusbpad_usb2_ports,
786	    __arraycount(tegra210_xusbpad_usb2_ports));
787}
788
789static const struct tegra210_xusbpad_port *
790tegra210_xusbpad_find_usb3_port(const char *name)
791{
792	return tegra210_xusbpad_find_port(name, tegra210_xusbpad_usb3_ports,
793	    __arraycount(tegra210_xusbpad_usb3_ports));
794}
795
796static const struct tegra210_xusbpad_port *
797tegra210_xusbpad_find_hsic_port(const char *name)
798{
799	return tegra210_xusbpad_find_port(name, tegra210_xusbpad_hsic_ports,
800	    __arraycount(tegra210_xusbpad_hsic_ports));
801}
802
803static void
804tegra210_xusbpad_enable_vbus(struct tegra210_xusbpad_softc *sc,
805    const struct tegra210_xusbpad_port *port, int phandle)
806{
807	struct fdtbus_regulator *vbus_reg;
808
809	if (!of_hasprop(phandle, "vbus-supply"))
810		return;
811
812	vbus_reg = fdtbus_regulator_acquire(phandle, "vbus-supply");
813	if (vbus_reg == NULL || fdtbus_regulator_enable(vbus_reg) != 0) {
814		aprint_error_dev(sc->sc_dev,
815		    "couldn't enable vbus regulator for port %s\n",
816		    port->name);
817	}
818}
819
820static void
821tegra210_xusbpad_configure_usb2_port(struct tegra210_xusbpad_softc *sc,
822    int phandle, const struct tegra210_xusbpad_port *port)
823{
824	u_int modeval, internal;
825	const char *mode;
826
827	mode = fdtbus_get_string(phandle, "mode");
828	if (mode == NULL) {
829		aprint_error_dev(sc->sc_dev, "no 'mode' property on port %s\n", port->name);
830		return;
831	}
832	if (strcmp(mode, "host") == 0)
833		modeval = 1;
834	else if (strcmp(mode, "device") == 0)
835		modeval = 2;
836	else if (strcmp(mode, "otg") == 0)
837		modeval = 3;
838	else {
839		aprint_error_dev(sc->sc_dev, "unsupported mode '%s' on port %s\n", mode, port->name);
840		return;
841	}
842
843	internal = of_hasprop(phandle, "nvidia,internal");
844
845	tegra210_xusbpad_enable_vbus(sc, port, phandle);
846
847	aprint_normal_dev(sc->sc_dev, "port %s: set mode %s, %s\n", port->name, mode,
848	    internal ? "internal" : "external");
849	SETCLR4(sc, port->reg, __SHIFTIN(internal, port->internal_mask), port->internal_mask);
850	SETCLR4(sc, port->reg, __SHIFTIN(modeval, port->mask), port->mask);
851}
852
853static void
854tegra210_xusbpad_configure_usb3_port(struct tegra210_xusbpad_softc *sc,
855    int phandle, const struct tegra210_xusbpad_port *port)
856{
857	u_int companion, internal;
858
859	if (of_getprop_uint32(phandle, "nvidia,usb2-companion", &companion)) {
860		aprint_error_dev(sc->sc_dev, "no 'nvidia,usb2-companion' property on port %s\n", port->name);
861		return;
862	}
863	internal = of_hasprop(phandle, "nvidia,internal");
864
865	tegra210_xusbpad_enable_vbus(sc, port, phandle);
866
867	aprint_normal_dev(sc->sc_dev, "port %s: set companion usb2-%d, %s\n", port->name,
868	    companion, internal ? "internal" : "external");
869	SETCLR4(sc, port->reg, __SHIFTIN(internal, port->internal_mask), port->internal_mask);
870	SETCLR4(sc, port->reg, __SHIFTIN(companion, port->mask), port->mask);
871
872	SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_1_REG(port->index),
873	    __SHIFTIN(2, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL),
874	    XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_TX_TERM_CTRL);
875	SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_REG(port->index),
876	    __SHIFTIN(0xfc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE),
877	    XUSB_PADCTL_UPHY_USB3_PADn_ECTL_2_RX_CTLE);
878	WR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_3_REG(port->index), 0xc0077f1f);
879	SETCLR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_REG(port->index),
880	    __SHIFTIN(0x01c7, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL),
881	    XUSB_PADCTL_UPHY_USB3_PADn_ECTL_4_RX_CDR_CTRL);
882	WR4(sc, XUSB_PADCTL_UPHY_USB3_PADn_ECTL_6_REG(port->index), 0xfcf01368);
883
884	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG,
885	    0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN(port->index));
886	delay(200);
887	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG,
888	    0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_CLAMP_EN_EARLY(port->index));
889	delay(200);
890	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG,
891	    0, XUSB_PADCTL_ELPG_PROGRAM_1_SSPn_ELPG_VCORE_DOWN(port->index));
892
893	SETCLR4(sc, XUSB_PADCTL_VBUS_OC_MAP_REG,
894	    XUSB_PADCTL_VBUS_OC_MAP_VBUS_ENABLE(port->index), 0);
895}
896
897static void
898tegra210_xusbpad_configure_hsic_port(struct tegra210_xusbpad_softc *sc,
899    int phandle, const struct tegra210_xusbpad_port *port)
900{
901	tegra210_xusbpad_enable_vbus(sc, port, phandle);
902}
903
904static void
905tegra210_xusbpad_configure_ports(struct tegra210_xusbpad_softc *sc)
906{
907	const struct tegra210_xusbpad_port *port;
908	const char *port_name;
909	int phandle, child;
910
911	/* Search for the ports node */
912	phandle = of_find_firstchild_byname(sc->sc_phandle, "ports");
913
914	/* Configure ports */
915	for (child = OF_child(phandle); child; child = OF_peer(child)) {
916		if (!fdtbus_status_okay(child))
917			continue;
918		port_name = fdtbus_get_string(child, "name");
919
920		if ((port = tegra210_xusbpad_find_usb2_port(port_name)) != NULL)
921			tegra210_xusbpad_configure_usb2_port(sc, child, port);
922		else if ((port = tegra210_xusbpad_find_usb3_port(port_name)) != NULL)
923			tegra210_xusbpad_configure_usb3_port(sc, child, port);
924		else if ((port = tegra210_xusbpad_find_hsic_port(port_name)) != NULL)
925			tegra210_xusbpad_configure_hsic_port(sc, child, port);
926		else
927			aprint_error_dev(sc->sc_dev, "unsupported port '%s'\n", port_name);
928	}
929}
930
931static void
932tegra210_xusbpad_enable(struct tegra210_xusbpad_softc *sc)
933{
934	if (sc->sc_enabled)
935		return;
936
937	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN);
938	delay(200);
939	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_CLAMP_EN_EARLY);
940	delay(200);
941	SETCLR4(sc, XUSB_PADCTL_ELPG_PROGRAM_1_REG, 0, XUSB_PADCTL_ELPG_PROGRAM_1_AUX_MUX_LP0_VCORE_DOWN);
942
943	sc->sc_enabled = true;
944}
945
946static void
947tegra210_xusbpad_sata_enable(device_t dev)
948{
949	struct tegra210_xusbpad_softc * const sc = device_private(dev);
950
951	tegra210_xusbpad_enable(sc);
952}
953
954static void
955tegra210_xusbpad_xhci_enable(device_t dev)
956{
957	struct tegra210_xusbpad_softc * const sc = device_private(dev);
958
959	tegra210_xusbpad_enable(sc);
960}
961
962static const struct tegra_xusbpad_ops tegra210_xusbpad_ops = {
963	.sata_enable = tegra210_xusbpad_sata_enable,
964	.xhci_enable = tegra210_xusbpad_xhci_enable,
965};
966
967static const struct device_compatible_entry compat_data[] = {
968	{ .compat = "nvidia,tegra210-xusb-padctl" },
969	DEVICE_COMPAT_EOL
970};
971
972static int
973tegra210_xusbpad_match(device_t parent, cfdata_t cf, void *aux)
974{
975	struct fdt_attach_args * const faa = aux;
976
977	return of_compatible_match(faa->faa_phandle, compat_data);
978}
979
980static void
981tegra210_xusbpad_attach(device_t parent, device_t self, void *aux)
982{
983	struct tegra210_xusbpad_softc * const sc = device_private(self);
984	struct fdt_attach_args * const faa = aux;
985	bus_addr_t addr;
986	bus_size_t size;
987	int error;
988
989	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
990		aprint_error(": couldn't get registers\n");
991		return;
992	}
993	sc->sc_rst = fdtbus_reset_get(faa->faa_phandle, "padctl");
994	if (sc->sc_rst == NULL) {
995		aprint_error(": couldn't get reset padctl\n");
996		return;
997	}
998
999	sc->sc_dev = self;
1000	sc->sc_phandle = faa->faa_phandle;
1001	sc->sc_bst = faa->faa_bst;
1002	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
1003	if (error) {
1004		aprint_error(": couldn't map %#" PRIxBUSADDR ": %d", addr, error);
1005		return;
1006	}
1007
1008	aprint_naive("\n");
1009	aprint_normal(": XUSB PADCTL\n");
1010
1011	fdtbus_reset_deassert(sc->sc_rst);
1012
1013	tegra_xusbpad_register(self, &tegra210_xusbpad_ops);
1014
1015	tegra210_xusbpad_configure_pads(sc, "usb2");
1016	tegra210_xusbpad_configure_pads(sc, "hsic");
1017	tegra210_xusbpad_configure_pads(sc, "pcie");
1018	tegra210_xusbpad_configure_pads(sc, "sata");
1019
1020	tegra210_xusbpad_configure_ports(sc);
1021}
1022
1023static void *
1024tegra210_xusbpad_phy_acquire(device_t dev, const void *data, size_t len)
1025{
1026	struct tegra210_xusbpad_phy_softc * const sc = device_private(dev);
1027
1028	if (len != 0)
1029		return NULL;
1030
1031	return sc;
1032}
1033
1034static void
1035tegra210_xusbpad_phy_release(device_t dev, void *priv)
1036{
1037};
1038
1039static int
1040tegra210_xusbpad_phy_enable(device_t dev, void *priv, bool enable)
1041{
1042	struct tegra210_xusbpad_phy_softc * const sc = device_private(dev);
1043
1044	if (enable == false)
1045		return ENXIO;	/* not implemented */
1046
1047	tegra210_xusbpad_configure_lane(sc->sc_xusbpad, sc->sc_phandle);
1048
1049	return 0;
1050}
1051
1052static const struct fdtbus_phy_controller_func tegra210_xusbpad_phy_funcs = {
1053	.acquire = tegra210_xusbpad_phy_acquire,
1054	.release = tegra210_xusbpad_phy_release,
1055	.enable = tegra210_xusbpad_phy_enable,
1056};
1057
1058CFATTACH_DECL_NEW(tegra210_xusbpad, sizeof(struct tegra210_xusbpad_softc),
1059	tegra210_xusbpad_match, tegra210_xusbpad_attach, NULL, NULL);
1060
1061static int
1062tegra210_xusbpad_phy_match(device_t parent, cfdata_t cf, void *aux)
1063{
1064	struct tegra210_xusbpad_phy_attach_args * const paa = aux;
1065
1066	if (!fdtbus_status_okay(paa->paa_phandle))
1067		return 0;
1068
1069	return 1;
1070}
1071
1072static void
1073tegra210_xusbpad_phy_attach(device_t parent, device_t self, void *aux)
1074{
1075	struct tegra210_xusbpad_phy_softc * const sc = device_private(self);
1076	struct tegra210_xusbpad_phy_attach_args * const paa = aux;
1077
1078	sc->sc_dev = self;
1079	sc->sc_phandle = paa->paa_phandle;
1080	sc->sc_xusbpad = paa->paa_xusbpad;
1081
1082	aprint_naive("\n");
1083	aprint_normal(": %s\n", fdtbus_get_string(sc->sc_phandle, "name"));
1084
1085	fdtbus_register_phy_controller(self, sc->sc_phandle, &tegra210_xusbpad_phy_funcs);
1086}
1087
1088CFATTACH_DECL_NEW(tegra210xphy, sizeof(struct tegra210_xusbpad_phy_softc),
1089	tegra210_xusbpad_phy_match, tegra210_xusbpad_phy_attach, NULL, NULL);
1090