xref: /freebsd/sys/dev/usb/controller/generic_xhci_fdt.c (revision ca48e43ba9ee73a07cdbad8365117793b01273bb)
1052073c3SEmmanuel Vadot /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3052073c3SEmmanuel Vadot  *
4052073c3SEmmanuel Vadot  * Copyright (c) 2015 Semihalf.
5052073c3SEmmanuel Vadot  * Copyright (c) 2015 Stormshield.
6052073c3SEmmanuel Vadot  * All rights reserved.
7052073c3SEmmanuel Vadot  *
8052073c3SEmmanuel Vadot  * Redistribution and use in source and binary forms, with or without
9052073c3SEmmanuel Vadot  * modification, are permitted provided that the following conditions
10052073c3SEmmanuel Vadot  * are met:
11052073c3SEmmanuel Vadot  * 1. Redistributions of source code must retain the above copyright
12052073c3SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer.
13052073c3SEmmanuel Vadot  * 2. Redistributions in binary form must reproduce the above copyright
14052073c3SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer in the
15052073c3SEmmanuel Vadot  *    documentation and/or other materials provided with the distribution.
16052073c3SEmmanuel Vadot  *
17052073c3SEmmanuel Vadot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18052073c3SEmmanuel Vadot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19052073c3SEmmanuel Vadot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20052073c3SEmmanuel Vadot  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21052073c3SEmmanuel Vadot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22052073c3SEmmanuel Vadot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23052073c3SEmmanuel Vadot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24052073c3SEmmanuel Vadot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25052073c3SEmmanuel Vadot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26052073c3SEmmanuel Vadot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27052073c3SEmmanuel Vadot  * SUCH DAMAGE.
28052073c3SEmmanuel Vadot  */
29052073c3SEmmanuel Vadot 
30052073c3SEmmanuel Vadot #include "opt_bus.h"
31052073c3SEmmanuel Vadot 
32052073c3SEmmanuel Vadot #include <sys/param.h>
33052073c3SEmmanuel Vadot #include <sys/systm.h>
34052073c3SEmmanuel Vadot #include <sys/bus.h>
35052073c3SEmmanuel Vadot #include <sys/condvar.h>
36052073c3SEmmanuel Vadot #include <sys/kernel.h>
37052073c3SEmmanuel Vadot #include <sys/module.h>
38052073c3SEmmanuel Vadot 
39052073c3SEmmanuel Vadot #include <dev/usb/usb.h>
40052073c3SEmmanuel Vadot #include <dev/usb/usbdi.h>
41052073c3SEmmanuel Vadot 
42052073c3SEmmanuel Vadot #include <dev/usb/usb_core.h>
43052073c3SEmmanuel Vadot #include <dev/usb/usb_busdma.h>
44052073c3SEmmanuel Vadot #include <dev/usb/usb_process.h>
45052073c3SEmmanuel Vadot 
46052073c3SEmmanuel Vadot #include <dev/usb/usb_controller.h>
47052073c3SEmmanuel Vadot #include <dev/usb/usb_bus.h>
48052073c3SEmmanuel Vadot #include <dev/usb/controller/xhci.h>
49052073c3SEmmanuel Vadot 
50052073c3SEmmanuel Vadot #include <dev/ofw/ofw_bus.h>
51052073c3SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h>
52052073c3SEmmanuel Vadot 
53*950a6087SEmmanuel Vadot #include <dev/phy/phy.h>
54052073c3SEmmanuel Vadot 
55052073c3SEmmanuel Vadot #include "generic_xhci.h"
56052073c3SEmmanuel Vadot 
57332af8c2SStephen J. Kiernan /* Flags for the OFW compat data table */
58332af8c2SStephen J. Kiernan #define	XHCI_FDT_MATCH		0x01
59332af8c2SStephen J. Kiernan #define	XHCI_FDT_32BIT_DMA	0x02	/* Controller needs 32-bit DMA */
60332af8c2SStephen J. Kiernan 
61052073c3SEmmanuel Vadot static struct ofw_compat_data compat_data[] = {
62332af8c2SStephen J. Kiernan 	{"marvell,armada-380-xhci",	XHCI_FDT_MATCH},
63332af8c2SStephen J. Kiernan 	{"marvell,armada3700-xhci",	XHCI_FDT_MATCH},
64332af8c2SStephen J. Kiernan 	{"marvell,armada-8k-xhci",	XHCI_FDT_MATCH},
65332af8c2SStephen J. Kiernan 	{"generic-xhci",		XHCI_FDT_MATCH},
66332af8c2SStephen J. Kiernan 	{NULL,				0}
67052073c3SEmmanuel Vadot };
68052073c3SEmmanuel Vadot 
69052073c3SEmmanuel Vadot static int
generic_xhci_fdt_probe(device_t dev)70052073c3SEmmanuel Vadot generic_xhci_fdt_probe(device_t dev)
71052073c3SEmmanuel Vadot {
72052073c3SEmmanuel Vadot 
73052073c3SEmmanuel Vadot 	if (!ofw_bus_status_okay(dev))
74052073c3SEmmanuel Vadot 		return (ENXIO);
75052073c3SEmmanuel Vadot 
76052073c3SEmmanuel Vadot 	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
77052073c3SEmmanuel Vadot 		return (ENXIO);
78052073c3SEmmanuel Vadot 
79052073c3SEmmanuel Vadot 	device_set_desc(dev, XHCI_HC_DEVSTR);
80052073c3SEmmanuel Vadot 
81052073c3SEmmanuel Vadot 	return (BUS_PROBE_DEFAULT);
82052073c3SEmmanuel Vadot }
83052073c3SEmmanuel Vadot 
84052073c3SEmmanuel Vadot static int
generic_xhci_fdt_attach(device_t dev)85052073c3SEmmanuel Vadot generic_xhci_fdt_attach(device_t dev)
86052073c3SEmmanuel Vadot {
87332af8c2SStephen J. Kiernan 	struct xhci_softc *sc = device_get_softc(dev);
88052073c3SEmmanuel Vadot 	phandle_t node;
89052073c3SEmmanuel Vadot 	phy_t phy;
90332af8c2SStephen J. Kiernan 	int flags;
91052073c3SEmmanuel Vadot 
92052073c3SEmmanuel Vadot 	node = ofw_bus_get_node(dev);
93052073c3SEmmanuel Vadot 	if (phy_get_by_ofw_property(dev, node, "usb-phy", &phy) == 0)
94052073c3SEmmanuel Vadot 		if (phy_enable(phy) != 0)
95052073c3SEmmanuel Vadot 			device_printf(dev, "Cannot enable phy\n");
96052073c3SEmmanuel Vadot 
97332af8c2SStephen J. Kiernan 	flags = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
98332af8c2SStephen J. Kiernan 	if ((flags & XHCI_FDT_32BIT_DMA) != 0)
99332af8c2SStephen J. Kiernan 		sc->sc_quirks |= XHCI_QUIRK_DMA_32B;
100332af8c2SStephen J. Kiernan 
101052073c3SEmmanuel Vadot 	return (generic_xhci_attach(dev));
102052073c3SEmmanuel Vadot }
103052073c3SEmmanuel Vadot 
104052073c3SEmmanuel Vadot static int
generic_xhci_fdt_detach(device_t dev)105052073c3SEmmanuel Vadot generic_xhci_fdt_detach(device_t dev)
106052073c3SEmmanuel Vadot {
107052073c3SEmmanuel Vadot 	phandle_t node;
108052073c3SEmmanuel Vadot 	phy_t phy;
109052073c3SEmmanuel Vadot 	int err;
110052073c3SEmmanuel Vadot 
111052073c3SEmmanuel Vadot 	err = generic_xhci_detach(dev);
112052073c3SEmmanuel Vadot 	if (err != 0)
113052073c3SEmmanuel Vadot 		return (err);
114052073c3SEmmanuel Vadot 
115052073c3SEmmanuel Vadot 	node = ofw_bus_get_node(dev);
116052073c3SEmmanuel Vadot 	if (phy_get_by_ofw_property(dev, node, "usb-phy", &phy) == 0)
117052073c3SEmmanuel Vadot 		phy_release(phy);
118052073c3SEmmanuel Vadot 
119052073c3SEmmanuel Vadot 	return (0);
120052073c3SEmmanuel Vadot }
121052073c3SEmmanuel Vadot 
122052073c3SEmmanuel Vadot static device_method_t xhci_fdt_methods[] = {
123052073c3SEmmanuel Vadot 	/* Device interface */
124052073c3SEmmanuel Vadot 	DEVMETHOD(device_probe, generic_xhci_fdt_probe),
125052073c3SEmmanuel Vadot 	DEVMETHOD(device_attach, generic_xhci_fdt_attach),
126052073c3SEmmanuel Vadot 	DEVMETHOD(device_detach, generic_xhci_fdt_detach),
127052073c3SEmmanuel Vadot 
128052073c3SEmmanuel Vadot 	DEVMETHOD_END
129052073c3SEmmanuel Vadot };
130052073c3SEmmanuel Vadot 
131052073c3SEmmanuel Vadot DEFINE_CLASS_1(xhci, xhci_fdt_driver, xhci_fdt_methods,
132052073c3SEmmanuel Vadot     sizeof(struct xhci_softc), generic_xhci_driver);
133052073c3SEmmanuel Vadot 
134bc9372d7SJohn Baldwin DRIVER_MODULE(xhci, simplebus, xhci_fdt_driver, 0, 0);
135052073c3SEmmanuel Vadot MODULE_DEPEND(xhci, usb, 1, 1, 1);
136