2 * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
30 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/malloc.h>
37 #include <machine/bus.h>
38 #include <machine/fdt.h>
40 #include <dev/extres/hwreset/hwreset.h>
41 #include <dev/extres/phy/phy.h>
42 #include <dev/fdt/fdt_common.h>
43 #include <dev/fdt/fdt_pinctrl.h>
44 #include <dev/ofw/openfirm.h>
45 #include <dev/ofw/ofw_bus.h>
46 #include <dev/ofw/ofw_bus_subr.h>
48 #include <gnu/dts/include/dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
52 #define XUSB_PADCTL_USB2_PAD_MUX 0x004
54 #define XUSB_PADCTL_ELPG_PROGRAM 0x01C
55 #define ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)
56 #define ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)
57 #define ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)
59 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040
60 #define IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)
61 #define IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf<< 12)
62 #define IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)
64 #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044
65 #define IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)
66 #define IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)
67 #define IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)
70 #define XUSB_PADCTL_USB3_PAD_MUX 0x134
72 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138
73 #define IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)
74 #define IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)
75 #define IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)
76 #define IOPHY_PLL_S0_CTL1_PLL_RST_L (1 << 1)
77 #define IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)
79 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2 0x13C
80 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL3 0x140
81 #define XUSB_PADCTL_IOPHY_PLL_S0_CTL4 0x144
83 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148
84 #define IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)
85 #define IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)
87 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL2 0x14C
88 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL3 0x150
89 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL4 0x154
90 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL5 0x158
91 #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL6 0x15C
99 struct xusbpadctl_softc {
101 struct resource *mem_res;
106 static struct ofw_compat_data compat_data[] = {
107 {"nvidia,tegra124-xusb-padctl", 1},
121 static char *otg_mux[] = {"snps", "xusb", "uart", "rsvd"};
122 static char *usb_mux[] = {"snps", "xusb"};
123 static char *pci_mux[] = {"pcie", "usb3", "sata", "rsvd"};
125 #define LANE(n, r, s, m, i, mx) \
133 .nmux = nitems(mx), \
136 static const struct padctl_lane lanes_tbl[] = {
137 LANE("otg-0", XUSB_PADCTL_USB2_PAD_MUX, 0, 0x3, -1, otg_mux),
138 LANE("otg-1", XUSB_PADCTL_USB2_PAD_MUX, 2, 0x3, -1, otg_mux),
139 LANE("otg-2", XUSB_PADCTL_USB2_PAD_MUX, 4, 0x3, -1, otg_mux),
140 LANE("ulpi-0", XUSB_PADCTL_USB2_PAD_MUX, 12, 0x1, -1, usb_mux),
141 LANE("hsic-0", XUSB_PADCTL_USB2_PAD_MUX, 14, 0x1, -1, usb_mux),
142 LANE("hsic-1", XUSB_PADCTL_USB2_PAD_MUX, 15, 0x1, -1, usb_mux),
143 LANE("pcie-0", XUSB_PADCTL_USB3_PAD_MUX, 16, 0x3, 1, pci_mux),
144 LANE("pcie-1", XUSB_PADCTL_USB3_PAD_MUX, 18, 0x3, 2, pci_mux),
145 LANE("pcie-2", XUSB_PADCTL_USB3_PAD_MUX, 20, 0x3, 3, pci_mux),
146 LANE("pcie-3", XUSB_PADCTL_USB3_PAD_MUX, 22, 0x3, 4, pci_mux),
147 LANE("pcie-4", XUSB_PADCTL_USB3_PAD_MUX, 24, 0x3, 5, pci_mux),
148 LANE("sata-0", XUSB_PADCTL_USB3_PAD_MUX, 26, 0x3, 6, pci_mux),
152 xusbpadctl_mux_function(const struct padctl_lane *lane, char *fnc_name)
156 for (i = 0; i < lane->nmux; i++) {
157 if (strcmp(fnc_name, lane->mux[i]) == 0)
165 xusbpadctl_config_lane(struct xusbpadctl_softc *sc, char *lane_name,
166 const struct padctl_lane *lane, struct lane_cfg *cfg)
172 reg = bus_read_4(sc->mem_res, lane->reg);
173 if (cfg->function != NULL) {
174 tmp = xusbpadctl_mux_function(lane, cfg->function);
176 device_printf(sc->dev,
177 "Unknown function %s for lane %s\n", cfg->function,
181 reg &= ~(lane->mask << lane->shift);
182 reg |= (tmp & lane->mask) << lane->shift;
184 if (cfg->iddq != -1) {
185 if (lane->iddq == -1) {
186 device_printf(sc->dev, "Invalid IDDQ for lane %s\n",
191 reg &= ~(1 << lane->iddq);
193 reg |= 1 << lane->iddq;
196 bus_write_4(sc->mem_res, lane->reg, reg);
200 static const struct padctl_lane *
201 xusbpadctl_search_lane(char *lane_name)
205 for (i = 0; i < nitems(lanes_tbl); i++) {
206 if (strcmp(lane_name, lanes_tbl[i].name) == 0)
207 return (&lanes_tbl[i]);
214 xusbpadctl_config_node(struct xusbpadctl_softc *sc, char *lane_name,
215 struct lane_cfg *cfg)
217 const struct padctl_lane *lane;
220 lane = xusbpadctl_search_lane(lane_name);
222 device_printf(sc->dev, "Unknown lane: %s\n", lane_name);
225 rv = xusbpadctl_config_lane(sc, lane_name, lane, cfg);
230 xusbpadctl_read_node(struct xusbpadctl_softc *sc, phandle_t node,
231 struct lane_cfg *cfg, char **lanes, int *llanes)
235 *llanes = OF_getprop_alloc(node, "nvidia,lanes", 1, (void **)lanes);
239 /* Read function (mux) settings. */
240 rv = OF_getprop_alloc(node, "nvidia,function", 1,
241 (void **)&cfg->function);
243 cfg->function = NULL;
244 /* Read numeric properties. */
245 rv = OF_getencprop(node, "nvidia,iddq", &cfg->iddq,
253 xusbpadctl_process_node(struct xusbpadctl_softc *sc, phandle_t node)
257 int i, len, llanes, rv;
259 rv = xusbpadctl_read_node(sc, node, &cfg, &lanes, &llanes);
266 i = strlen(lname) + 1;
267 rv = xusbpadctl_config_node(sc, lname, &cfg);
269 device_printf(sc->dev,
270 "Cannot configure lane: %s: %d\n", lname, rv);
274 } while (len < llanes);
278 if (cfg.function != NULL)
279 OF_prop_free(cfg.function);
285 xusbpadctl_pinctrl_cfg(device_t dev, phandle_t cfgxref)
287 struct xusbpadctl_softc *sc;
288 phandle_t node, cfgnode;
291 sc = device_get_softc(dev);
292 cfgnode = OF_node_from_xref(cfgxref);
295 for (node = OF_child(cfgnode); node != 0; node = OF_peer(node)) {
296 if (!fdt_is_enabled(node))
298 rv = xusbpadctl_process_node(sc, node);
307 xusbpadctl_phy_pcie_powerup(struct xusbpadctl_softc *sc)
312 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
313 reg &= ~IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK;
314 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL1, reg);
317 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
318 reg |= IOPHY_PLL_P0_CTL2_REFCLKBUF_EN;
319 reg |= IOPHY_PLL_P0_CTL2_TXCLKREF_EN;
320 reg |= IOPHY_PLL_P0_CTL2_TXCLKREF_SEL;
321 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL2, reg);
324 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
325 reg |= IOPHY_PLL_P0_CTL1_PLL_RST;
326 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL1, reg);
329 for (i = 0; i < 100; i++) {
330 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
331 if (reg & IOPHY_PLL_P0_CTL1_PLL0_LOCKDET)
341 xusbpadctl_phy_pcie_powerdown(struct xusbpadctl_softc *sc)
345 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
346 reg &= ~IOPHY_PLL_P0_CTL1_PLL_RST;
347 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_P0_CTL1, reg);
354 xusbpadctl_phy_sata_powerup(struct xusbpadctl_softc *sc)
359 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
360 reg &= ~IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
361 reg &= ~IOPHY_MISC_PAD_S0_CTL1_IDDQ;
362 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1, reg);
364 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
365 reg &= ~IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
366 reg &= ~IOPHY_PLL_S0_CTL1_PLL_IDDQ;
367 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1, reg);
369 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
370 reg |= IOPHY_PLL_S0_CTL1_PLL1_MODE;
371 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1, reg);
373 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
374 reg |= IOPHY_PLL_S0_CTL1_PLL_RST_L;
375 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1, reg);
377 for (i = 100; i >= 0; i--) {
378 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
379 if (reg & IOPHY_PLL_S0_CTL1_PLL1_LOCKDET)
384 device_printf(sc->dev, "Failed to power up SATA phy\n");
392 xusbpadctl_phy_sata_powerdown(struct xusbpadctl_softc *sc)
396 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
397 reg &= ~IOPHY_PLL_S0_CTL1_PLL_RST_L;
398 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1, reg);
401 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
402 reg &= ~IOPHY_PLL_S0_CTL1_PLL1_MODE;
403 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1, reg);
406 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
407 reg |= IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
408 reg |= IOPHY_PLL_S0_CTL1_PLL_IDDQ;
409 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_PLL_S0_CTL1, reg);
412 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
413 reg |= IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
414 reg |= IOPHY_MISC_PAD_S0_CTL1_IDDQ;
415 bus_write_4(sc->mem_res, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1, reg);
422 xusbpadctl_phy_powerup(struct xusbpadctl_softc *sc)
426 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM);
427 reg &= ~ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
428 bus_write_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM, reg);
431 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM);
432 reg &= ~ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
433 bus_write_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM, reg);
436 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM);
437 reg &= ~ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
438 bus_write_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM, reg);
445 xusbpadctl_phy_powerdown(struct xusbpadctl_softc *sc)
449 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM);
450 reg |= ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
451 bus_write_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM, reg);
454 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM);
455 reg |= ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
456 bus_write_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM, reg);
459 reg = bus_read_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM);
460 reg |= ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
461 bus_write_4(sc->mem_res, XUSB_PADCTL_ELPG_PROGRAM, reg);
468 xusbpadctl_phy_enable(device_t dev, intptr_t id, bool enable)
470 struct xusbpadctl_softc *sc;
473 sc = device_get_softc(dev);
475 if ((id != TEGRA_XUSB_PADCTL_PCIE) &&
476 (id != TEGRA_XUSB_PADCTL_SATA)) {
477 device_printf(dev, "Unknown phy: %d\n", id);
483 if (sc->phy_ena_cnt == 0) {
484 rv = xusbpadctl_phy_powerup(sc);
491 if (id == TEGRA_XUSB_PADCTL_PCIE) {
493 rv = xusbpadctl_phy_pcie_powerup(sc);
495 rv = xusbpadctl_phy_pcie_powerdown(sc);
498 } else if (id == TEGRA_XUSB_PADCTL_SATA) {
500 rv = xusbpadctl_phy_sata_powerup(sc);
502 rv = xusbpadctl_phy_sata_powerdown(sc);
507 if (sc->phy_ena_cnt == 1) {
508 rv = xusbpadctl_phy_powerdown(sc);
519 xusbpadctl_probe(device_t dev)
522 if (!ofw_bus_status_okay(dev))
525 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
528 device_set_desc(dev, "Tegra XUSB phy");
529 return (BUS_PROBE_DEFAULT);
533 xusbpadctl_detach(device_t dev)
536 /* This device is always present. */
541 xusbpadctl_attach(device_t dev)
543 struct xusbpadctl_softc * sc;
547 sc = device_get_softc(dev);
551 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
553 if (sc->mem_res == NULL) {
554 device_printf(dev, "Cannot allocate memory resources\n");
558 node = ofw_bus_get_node(dev);
559 rv = hwreset_get_by_ofw_name(dev, "padctl", &sc->rst);
561 device_printf(dev, "Cannot get 'padctl' reset: %d\n", rv);
564 rv = hwreset_deassert(sc->rst);
566 device_printf(dev, "Cannot unreset 'padctl' reset: %d\n", rv);
570 /* Register as a pinctrl device and use default configuration */
571 fdt_pinctrl_register(dev, NULL);
572 fdt_pinctrl_configure_by_name(dev, "default");
573 phy_register_provider(dev);
579 static device_method_t tegra_xusbpadctl_methods[] = {
580 /* Device interface */
581 DEVMETHOD(device_probe, xusbpadctl_probe),
582 DEVMETHOD(device_attach, xusbpadctl_attach),
583 DEVMETHOD(device_detach, xusbpadctl_detach),
585 /* fdt_pinctrl interface */
586 DEVMETHOD(fdt_pinctrl_configure, xusbpadctl_pinctrl_cfg),
589 DEVMETHOD(phy_enable, xusbpadctl_phy_enable),
594 static driver_t tegra_xusbpadctl_driver = {
596 tegra_xusbpadctl_methods,
597 sizeof(struct xusbpadctl_softc),
600 static devclass_t tegra_xusbpadctl_devclass;
602 EARLY_DRIVER_MODULE(tegra_xusbpadctl, simplebus, tegra_xusbpadctl_driver,
603 tegra_xusbpadctl_devclass, 0, 0, 73);