xref: /freebsd/sys/dev/usb/controller/generic_xhci_fdt.c (revision 950a6087ec18cd22464b3297573f54a6d9223c99)
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 <sys/cdefs.h>
31052073c3SEmmanuel Vadot #include "opt_bus.h"
32052073c3SEmmanuel Vadot 
33052073c3SEmmanuel Vadot #include <sys/param.h>
34052073c3SEmmanuel Vadot #include <sys/systm.h>
35052073c3SEmmanuel Vadot #include <sys/bus.h>
36052073c3SEmmanuel Vadot #include <sys/condvar.h>
37052073c3SEmmanuel Vadot #include <sys/kernel.h>
38052073c3SEmmanuel Vadot #include <sys/module.h>
39052073c3SEmmanuel Vadot 
40052073c3SEmmanuel Vadot #include <dev/usb/usb.h>
41052073c3SEmmanuel Vadot #include <dev/usb/usbdi.h>
42052073c3SEmmanuel Vadot 
43052073c3SEmmanuel Vadot #include <dev/usb/usb_core.h>
44052073c3SEmmanuel Vadot #include <dev/usb/usb_busdma.h>
45052073c3SEmmanuel Vadot #include <dev/usb/usb_process.h>
46052073c3SEmmanuel Vadot 
47052073c3SEmmanuel Vadot #include <dev/usb/usb_controller.h>
48052073c3SEmmanuel Vadot #include <dev/usb/usb_bus.h>
49052073c3SEmmanuel Vadot #include <dev/usb/controller/xhci.h>
50052073c3SEmmanuel Vadot 
51052073c3SEmmanuel Vadot #include <dev/ofw/ofw_bus.h>
52052073c3SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h>
53052073c3SEmmanuel Vadot 
54*950a6087SEmmanuel Vadot #include <dev/phy/phy.h>
55052073c3SEmmanuel Vadot 
56052073c3SEmmanuel Vadot #include "generic_xhci.h"
57052073c3SEmmanuel Vadot 
58332af8c2SStephen J. Kiernan /* Flags for the OFW compat data table */
59332af8c2SStephen J. Kiernan #define	XHCI_FDT_MATCH		0x01
60332af8c2SStephen J. Kiernan #define	XHCI_FDT_32BIT_DMA	0x02	/* Controller needs 32-bit DMA */
61332af8c2SStephen J. Kiernan 
62052073c3SEmmanuel Vadot static struct ofw_compat_data compat_data[] = {
63332af8c2SStephen J. Kiernan 	{"marvell,armada-380-xhci",	XHCI_FDT_MATCH},
64332af8c2SStephen J. Kiernan 	{"marvell,armada3700-xhci",	XHCI_FDT_MATCH},
65332af8c2SStephen J. Kiernan 	{"marvell,armada-8k-xhci",	XHCI_FDT_MATCH},
66332af8c2SStephen J. Kiernan 	{"generic-xhci",		XHCI_FDT_MATCH},
67332af8c2SStephen J. Kiernan 	{NULL,				0}
68052073c3SEmmanuel Vadot };
69052073c3SEmmanuel Vadot 
70052073c3SEmmanuel Vadot static int
generic_xhci_fdt_probe(device_t dev)71052073c3SEmmanuel Vadot generic_xhci_fdt_probe(device_t dev)
72052073c3SEmmanuel Vadot {
73052073c3SEmmanuel Vadot 
74052073c3SEmmanuel Vadot 	if (!ofw_bus_status_okay(dev))
75052073c3SEmmanuel Vadot 		return (ENXIO);
76052073c3SEmmanuel Vadot 
77052073c3SEmmanuel Vadot 	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
78052073c3SEmmanuel Vadot 		return (ENXIO);
79052073c3SEmmanuel Vadot 
80052073c3SEmmanuel Vadot 	device_set_desc(dev, XHCI_HC_DEVSTR);
81052073c3SEmmanuel Vadot 
82052073c3SEmmanuel Vadot 	return (BUS_PROBE_DEFAULT);
83052073c3SEmmanuel Vadot }
84052073c3SEmmanuel Vadot 
85052073c3SEmmanuel Vadot static int
generic_xhci_fdt_attach(device_t dev)86052073c3SEmmanuel Vadot generic_xhci_fdt_attach(device_t dev)
87052073c3SEmmanuel Vadot {
88332af8c2SStephen J. Kiernan 	struct xhci_softc *sc = device_get_softc(dev);
89052073c3SEmmanuel Vadot 	phandle_t node;
90052073c3SEmmanuel Vadot 	phy_t phy;
91332af8c2SStephen J. Kiernan 	int flags;
92052073c3SEmmanuel Vadot 
93052073c3SEmmanuel Vadot 	node = ofw_bus_get_node(dev);
94052073c3SEmmanuel Vadot 	if (phy_get_by_ofw_property(dev, node, "usb-phy", &phy) == 0)
95052073c3SEmmanuel Vadot 		if (phy_enable(phy) != 0)
96052073c3SEmmanuel Vadot 			device_printf(dev, "Cannot enable phy\n");
97052073c3SEmmanuel Vadot 
98332af8c2SStephen J. Kiernan 	flags = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
99332af8c2SStephen J. Kiernan 	if ((flags & XHCI_FDT_32BIT_DMA) != 0)
100332af8c2SStephen J. Kiernan 		sc->sc_quirks |= XHCI_QUIRK_DMA_32B;
101332af8c2SStephen J. Kiernan 
102052073c3SEmmanuel Vadot 	return (generic_xhci_attach(dev));
103052073c3SEmmanuel Vadot }
104052073c3SEmmanuel Vadot 
105052073c3SEmmanuel Vadot static int
generic_xhci_fdt_detach(device_t dev)106052073c3SEmmanuel Vadot generic_xhci_fdt_detach(device_t dev)
107052073c3SEmmanuel Vadot {
108052073c3SEmmanuel Vadot 	phandle_t node;
109052073c3SEmmanuel Vadot 	phy_t phy;
110052073c3SEmmanuel Vadot 	int err;
111052073c3SEmmanuel Vadot 
112052073c3SEmmanuel Vadot 	err = generic_xhci_detach(dev);
113052073c3SEmmanuel Vadot 	if (err != 0)
114052073c3SEmmanuel Vadot 		return (err);
115052073c3SEmmanuel Vadot 
116052073c3SEmmanuel Vadot 	node = ofw_bus_get_node(dev);
117052073c3SEmmanuel Vadot 	if (phy_get_by_ofw_property(dev, node, "usb-phy", &phy) == 0)
118052073c3SEmmanuel Vadot 		phy_release(phy);
119052073c3SEmmanuel Vadot 
120052073c3SEmmanuel Vadot 	return (0);
121052073c3SEmmanuel Vadot }
122052073c3SEmmanuel Vadot 
123052073c3SEmmanuel Vadot static device_method_t xhci_fdt_methods[] = {
124052073c3SEmmanuel Vadot 	/* Device interface */
125052073c3SEmmanuel Vadot 	DEVMETHOD(device_probe, generic_xhci_fdt_probe),
126052073c3SEmmanuel Vadot 	DEVMETHOD(device_attach, generic_xhci_fdt_attach),
127052073c3SEmmanuel Vadot 	DEVMETHOD(device_detach, generic_xhci_fdt_detach),
128052073c3SEmmanuel Vadot 
129052073c3SEmmanuel Vadot 	DEVMETHOD_END
130052073c3SEmmanuel Vadot };
131052073c3SEmmanuel Vadot 
132052073c3SEmmanuel Vadot DEFINE_CLASS_1(xhci, xhci_fdt_driver, xhci_fdt_methods,
133052073c3SEmmanuel Vadot     sizeof(struct xhci_softc), generic_xhci_driver);
134052073c3SEmmanuel Vadot 
135bc9372d7SJohn Baldwin DRIVER_MODULE(xhci, simplebus, xhci_fdt_driver, 0, 0);
136052073c3SEmmanuel Vadot MODULE_DEPEND(xhci, usb, 1, 1, 1);
137