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