ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/sys/arm/allwinner/a10_ehci.c
(Generate patch)

Comparing trunk/sys/arm/allwinner/a10_ehci.c (file contents):
Revision 12401 by laffer1, Sat Jun 2 15:44:28 2018 UTC vs.
Revision 12402 by laffer1, Sun Mar 8 17:23:22 2020 UTC

# Line 30 | Line 30
30   */
31  
32   #include <sys/cdefs.h>
33 < __FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_ehci.c 308402 2016-11-07 09:19:04Z hselasky $");
33 > __FBSDID("$FreeBSD: stable/11/sys/arm/allwinner/a10_ehci.c 346524 2019-04-22 04:56:41Z ian $");
34  
35   #include "opt_bus.h"
36  
# Line 41 | Line 41 | __FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_eh
41   #include <sys/condvar.h>
42   #include <sys/kernel.h>
43   #include <sys/module.h>
44 #include <sys/gpio.h>
44  
45   #include <machine/bus.h>
46 < #include <dev/ofw/ofw_bus.h>
46 > #include <dev/ofw/ofw_bus.h>
47   #include <dev/ofw/ofw_bus_subr.h>
48  
49 < #include <dev/usb/usb.h>
49 > #include <dev/usb/usb.h>
50   #include <dev/usb/usbdi.h>
51  
52   #include <dev/usb/usb_core.h>
# Line 60 | Line 59 | __FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_eh
59   #include <dev/usb/controller/ehci.h>
60   #include <dev/usb/controller/ehcireg.h>
61  
62 < #include "gpio_if.h"
62 > #include <arm/allwinner/aw_machdep.h>
63 > #include <dev/extres/clk/clk.h>
64 > #include <dev/extres/hwreset/hwreset.h>
65 > #include <dev/extres/phy/phy.h>
66  
65 #include "a10_clk.h"
66
67   #define EHCI_HC_DEVSTR                  "Allwinner Integrated USB 2.0 controller"
68  
69   #define SW_USB_PMU_IRQ_ENABLE           0x800
# Line 76 | Line 76 | __FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_eh
76   #define SW_AHB_INCRX_ALIGN              (1 << 8)
77   #define SW_AHB_INCR4                    (1 << 9)
78   #define SW_AHB_INCR8                    (1 << 10)
79 #define GPIO_USB1_PWR                   230
80 #define GPIO_USB2_PWR                   227
79  
80 + #define USB_CONF(d)                     \
81 +        (void *)ofw_bus_search_compatible((d), compat_data)->ocd_data
82 +
83   #define A10_READ_4(sc, reg)             \
84          bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
85  
# Line 88 | Line 89 | __FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_eh
89   static device_attach_t a10_ehci_attach;
90   static device_detach_t a10_ehci_detach;
91  
92 < bs_r_1_proto(reversed);
93 < bs_w_1_proto(reversed);
92 > struct aw_ehci_softc {
93 >        ehci_softc_t    sc;
94 >        clk_t           clk;
95 >        hwreset_t       rst;
96 >        phy_t           phy;
97 > };
98  
99 + struct aw_ehci_conf {
100 +        bool            sdram_init;
101 + };
102 +
103 + static const struct aw_ehci_conf a10_ehci_conf = {
104 +        .sdram_init = true,
105 + };
106 +
107 + static const struct aw_ehci_conf a31_ehci_conf = {
108 +        .sdram_init = false,
109 + };
110 +
111 + static struct ofw_compat_data compat_data[] = {
112 +        { "allwinner,sun4i-a10-ehci",   (uintptr_t)&a10_ehci_conf },
113 +        { "allwinner,sun5i-a13-ehci",   (uintptr_t)&a10_ehci_conf },
114 +        { "allwinner,sun6i-a31-ehci",   (uintptr_t)&a31_ehci_conf },
115 +        { "allwinner,sun7i-a20-ehci",   (uintptr_t)&a10_ehci_conf },
116 +        { "allwinner,sun8i-a83t-ehci",  (uintptr_t)&a31_ehci_conf },
117 +        { "allwinner,sun8i-h3-ehci",    (uintptr_t)&a31_ehci_conf },
118 +        { NULL,                         (uintptr_t)NULL }
119 + };
120 +
121   static int
122   a10_ehci_probe(device_t self)
123   {
# Line 98 | Line 125 | a10_ehci_probe(device_t self)
125          if (!ofw_bus_status_okay(self))
126                  return (ENXIO);
127  
128 <        if (!ofw_bus_is_compatible(self, "allwinner,usb-ehci"))
128 >        if (ofw_bus_search_compatible(self, compat_data)->ocd_data == 0)
129                  return (ENXIO);
130  
131          device_set_desc(self, EHCI_HC_DEVSTR);
# Line 109 | Line 136 | a10_ehci_probe(device_t self)
136   static int
137   a10_ehci_attach(device_t self)
138   {
139 <        ehci_softc_t *sc = device_get_softc(self);
139 >        struct aw_ehci_softc *aw_sc = device_get_softc(self);
140 >        ehci_softc_t *sc = &aw_sc->sc;
141 >        const struct aw_ehci_conf *conf;
142          bus_space_handle_t bsh;
114        device_t sc_gpio_dev;
143          int err;
144          int rid;
145          uint32_t reg_value = 0;
146  
147 +        conf = USB_CONF(self);
148 +
149          /* initialise some bus fields */
150          sc->sc_bus.parent = self;
151          sc->sc_bus.devices = sc->sc_devices;
# Line 165 | Line 195 | a10_ehci_attach(device_t self)
195  
196          sprintf(sc->sc_vendor, "Allwinner");
197  
168        /* Get the GPIO device, we need this to give power to USB */
169        sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
170        if (sc_gpio_dev == NULL) {
171                device_printf(self, "Error: failed to get the GPIO device\n");
172                goto error;
173        }
174
198          err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
199              NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
200          if (err) {
# Line 182 | Line 205 | a10_ehci_attach(device_t self)
205  
206          sc->sc_flags |= EHCI_SCFLG_DONTRESET;
207  
208 +        /* De-assert reset */
209 +        if (hwreset_get_by_ofw_idx(self, 0, 0, &aw_sc->rst) == 0) {
210 +                err = hwreset_deassert(aw_sc->rst);
211 +                if (err != 0) {
212 +                        device_printf(self, "Could not de-assert reset\n");
213 +                        goto error;
214 +                }
215 +        }
216 +
217          /* Enable clock for USB */
218 <        a10_clk_usb_activate();
218 >        err = clk_get_by_ofw_index(self, 0, 0, &aw_sc->clk);
219 >        if (err != 0) {
220 >                device_printf(self, "Could not get clock\n");
221 >                goto error;
222 >        }
223 >        err = clk_enable(aw_sc->clk);
224 >        if (err != 0) {
225 >                device_printf(self, "Could not enable clock\n");
226 >                goto error;
227 >        }
228  
229 <        /* Give power to USB */
230 <        GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB2_PWR, GPIO_PIN_OUTPUT);
231 <        GPIO_PIN_SET(sc_gpio_dev, GPIO_USB2_PWR, GPIO_PIN_HIGH);
229 >        /* Enable USB PHY */
230 >        err = phy_get_by_ofw_name(self, 0, "usb", &aw_sc->phy);
231 >        if (err != 0) {
232 >                device_printf(self, "Could not get phy\n");
233 >                goto error;
234 >        }
235 >        err = phy_enable(aw_sc->phy);
236 >        if (err != 0) {
237 >                device_printf(self, "Could not enable phy\n");
238 >                goto error;
239 >        }
240  
192        /* Give power to USB */
193        GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB1_PWR, GPIO_PIN_OUTPUT);
194        GPIO_PIN_SET(sc_gpio_dev, GPIO_USB1_PWR, GPIO_PIN_HIGH);
195
241          /* Enable passby */
242          reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
243          reg_value |= SW_AHB_INCR8; /* AHB INCR8 enable */
# Line 202 | Line 247 | a10_ehci_attach(device_t self)
247          A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
248  
249          /* Configure port */
250 <        reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
251 <        reg_value |= SW_SDRAM_BP_HPCR_ACCESS;
252 <        A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
250 >        if (conf->sdram_init) {
251 >                reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
252 >                reg_value |= SW_SDRAM_BP_HPCR_ACCESS;
253 >                A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
254 >        }
255  
256          err = ehci_init(sc);
257          if (!err) {
# Line 217 | Line 264 | a10_ehci_attach(device_t self)
264          return (0);
265  
266   error:
267 +        if (aw_sc->clk != NULL) {
268 +                clk_disable(aw_sc->clk);
269 +                clk_release(aw_sc->clk);
270 +        }
271          a10_ehci_detach(self);
272          return (ENXIO);
273   }
# Line 224 | Line 275 | error:
275   static int
276   a10_ehci_detach(device_t self)
277   {
278 <        ehci_softc_t *sc = device_get_softc(self);
278 >        struct aw_ehci_softc *aw_sc = device_get_softc(self);
279 >        ehci_softc_t *sc = &aw_sc->sc;
280 >        const struct aw_ehci_conf *conf;
281          int err;
282          uint32_t reg_value = 0;
283  
284 +        conf = USB_CONF(self);
285 +
286          /* during module unload there are lots of children leftover */
287          device_delete_children(self);
288  
# Line 258 | Line 313 | a10_ehci_detach(device_t self)
313          usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
314  
315          /* Disable configure port */
316 <        reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
317 <        reg_value &= ~SW_SDRAM_BP_HPCR_ACCESS;
318 <        A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
316 >        if (conf->sdram_init) {
317 >                reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
318 >                reg_value &= ~SW_SDRAM_BP_HPCR_ACCESS;
319 >                A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
320 >        }
321  
322          /* Disable passby */
323          reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
# Line 271 | Line 328 | a10_ehci_detach(device_t self)
328          A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
329  
330          /* Disable clock for USB */
331 <        a10_clk_usb_deactivate();
331 >        if (aw_sc->clk != NULL) {
332 >                clk_disable(aw_sc->clk);
333 >                clk_release(aw_sc->clk);
334 >        }
335  
336 +        /* Assert reset */
337 +        if (aw_sc->rst != NULL) {
338 +                hwreset_assert(aw_sc->rst);
339 +                hwreset_release(aw_sc->rst);
340 +        }
341 +
342          return (0);
343   }
344  
# Line 291 | Line 357 | static device_method_t ehci_methods[] = {
357   static driver_t ehci_driver = {
358          .name = "ehci",
359          .methods = ehci_methods,
360 <        .size = sizeof(ehci_softc_t),
360 >        .size = sizeof(struct aw_ehci_softc),
361   };
362  
363   static devclass_t ehci_devclass;
364  
365 < DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
366 < MODULE_DEPEND(ehci, usb, 1, 1, 1);
365 > DRIVER_MODULE(a10_ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
366 > MODULE_DEPEND(a10_ehci, usb, 1, 1, 1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines