45#include <sys/kernel.h>
46#include <sys/condvar.h>
47#include <sys/module.h>
48#include <machine/bus.h>
50#include <dev/ofw/ofw_bus.h>
51#include <dev/ofw/ofw_bus_subr.h>
65#include <dev/extres/clk/clk.h>
66#include <dev/extres/hwreset/hwreset.h>
67#include <dev/extres/phy/phy.h>
68#include <dev/extres/phy/phy_usb.h>
71#include <arm/allwinner/aw_machdep.h>
72#include <arm/allwinner/a10_sramc.h>
76#define DRD_EP_MAX_H3 4
78#define MUSB2_REG_AWIN_VEND0 0x0043
79#define VEND0_PIO_MODE 0
82#define bs_parent_space(bs) ((bs)->bs_parent)
83typedef bus_space_tag_t awusb_bs_tag;
84#elif defined(__aarch64__)
85#define bs_parent_space(bs) (bs)
86typedef void * awusb_bs_tag;
89#define AWUSB_OKAY 0x01
90#define AWUSB_NO_CONFDATA 0x02
102 .ep_fifosz_shift = 9,
113 .ep_fifosz_shift = 9,
132 { SYS_RES_MEMORY, 0, RF_ACTIVE },
133 { SYS_RES_IRQ, 0, RF_ACTIVE },
137#define REMAPFLAG 0x8000
138#define REGDECL(a, b) [(a)] = ((b) | REMAPFLAG)
220 (
"%s: Invalid register %#lx", __func__, o));
226 KASSERT((v &
REMAPFLAG) != 0, (
"%s: reg %#lx not in regmap",
248 const struct bus_space *bs = t;
255 return (bus_space_read_1(bs_parent_space(bs), h,
awusbdrd_reg(o)));
276 const struct bus_space *bs = t;
280 return bus_space_read_2(bs_parent_space(bs), h,
awusbdrd_reg(o));
287 const struct bus_space *bs = t;
292 bus_space_write_1(bs_parent_space(bs), h,
awusbdrd_reg(o), v);
299 const struct bus_space *bs = t;
304 bus_space_write_2(bs_parent_space(bs), h,
awusbdrd_reg(o), v);
309 uint8_t *d, bus_size_t c)
311 const struct bus_space *bs = t;
313 bus_space_read_multi_1(bs_parent_space(bs), h,
awusbdrd_reg(o), d, c);
318 uint32_t *d, bus_size_t c)
320 const struct bus_space *bs = t;
322 bus_space_read_multi_4(bs_parent_space(bs), h,
awusbdrd_reg(o), d, c);
327 const uint8_t *d, bus_size_t c)
329 const struct bus_space *bs = t;
334 bus_space_write_multi_1(bs_parent_space(bs), h,
awusbdrd_reg(o), d, c);
339 const uint32_t *d, bus_size_t c)
341 const struct bus_space *bs = t;
346 bus_space_write_multi_4(bs_parent_space(bs), h,
awusbdrd_reg(o), d, c);
354 uint16_t inttx, intrx;
359 if (intusb == 0 && inttx == 0 && intrx == 0)
375 if (!ofw_bus_status_okay(
dev))
381 device_set_desc(
dev,
"Allwinner USB DRD");
382 return (BUS_PROBE_DEFAULT);
394 sc = device_get_softc(
dev);
402 phy_mode = PHY_USB_MODE_HOST;
403 if (OF_getprop(ofw_bus_get_node(
dev),
"dr_mode",
404 &usb_mode,
sizeof(usb_mode)) > 0) {
405 usb_mode[
sizeof(usb_mode) - 1] = 0;
406 if (strcasecmp(usb_mode,
"host") == 0) {
408 phy_mode = PHY_USB_MODE_HOST;
409 }
else if (strcasecmp(usb_mode,
"peripheral") == 0) {
411 phy_mode = PHY_USB_MODE_DEVICE;
412 }
else if (strcasecmp(usb_mode,
"otg") == 0) {
419 phy_mode = PHY_USB_MODE_DEVICE;
421 device_printf(
dev,
"Invalid FDT dr_mode: %s\n",
427 error = clk_get_by_ofw_index(
dev, 0, 0, &
sc->clk);
432 (void)hwreset_get_by_ofw_idx(
dev, 0, 0, &
sc->reset);
437 device_printf(
dev,
"failed to enable clock: %d\n",
error);
440 if (
sc->reset != NULL) {
441 error = hwreset_deassert(
sc->reset);
443 device_printf(
dev,
"failed to de-assert reset: %d\n",
450 (void)phy_get_by_ofw_name(
dev, 0,
"usb", &
sc->phy);
451 if (
sc->phy != NULL) {
452 device_printf(
dev,
"setting phy mode %d\n", phy_mode);
456 device_printf(
dev,
"Could not enable phy\n");
460 error = phy_usb_set_mode(
sc->phy, phy_mode);
462 device_printf(
dev,
"Could not set phy mode\n");
480 sc->bs.bs_parent = rman_get_bustag(
sc->res[0]);
481#elif defined(__aarch64__)
482 sc->bs.bs_cookie = rman_get_bustag(
sc->res[0]);
510 if (ofw_bus_is_compatible(
dev,
"allwinner,sun8i-h3-musb")) {
518 error = bus_setup_intr(
dev,
sc->res[1], INTR_MPSAFE | INTR_TYPE_BIO,
528 switch (allwinner_soc_family()) {
529 case ALLWINNERSOC_SUN4I:
530 case ALLWINNERSOC_SUN7I:
549 if (
sc->phy != NULL) {
551 (void)phy_disable(
sc->phy);
552 phy_release(
sc->phy);
554 if (
sc->reset != NULL) {
555 hwreset_assert(
sc->reset);
556 hwreset_release(
sc->reset);
559 clk_release(
sc->clk);
571 sc = device_get_softc(
dev);
576 device_delete_child(
dev, bdev);
586 if (
sc->phy != NULL) {
588 phy_disable(
sc->phy);
589 phy_release(
sc->phy);
591 if (
sc->reset != NULL) {
592 if (hwreset_assert(
sc->reset) != 0)
593 device_printf(
dev,
"failed to assert reset\n");
594 hwreset_release(
sc->reset);
597 clk_release(
sc->clk);
601 device_delete_children(
dev);
611 DEVMETHOD(device_suspend, bus_generic_suspend),
612 DEVMETHOD(device_resume, bus_generic_resume),
613 DEVMETHOD(device_shutdown, bus_generic_shutdown),
void musbotg_uninit(struct musbotg_softc *sc)
void musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on)
void musbotg_interrupt(struct musbotg_softc *sc, uint16_t rxstat, uint16_t txstat, uint8_t stat)
usb_error_t musbotg_init(struct musbotg_softc *sc)
#define MUSB2_REG_RXDBDIS
#define MUSB2_READ_1(sc, reg)
#define MUSB2_REG_RXNAKLIMIT
#define MUSB2_DEVICE_MODE
#define MUSB2_REG_RXHUBPORT(n)
#define MUSB2_REG_RXFIFOADD
#define MUSB2_REG_RXFIFOSZ
#define MUSB2_REG_TXNAKLIMIT
#define MUSB2_REG_TXFIFOADD
#define MUSB2_MAX_DEVICES
#define MUSB2_REG_TESTMODE
#define MUSB2_REG_RXCOUNT
#define MUSB2_WRITE_1(sc, reg, data)
#define MUSB2_WRITE_2(sc, reg, data)
#define MUSB2_REG_RXFADDR(n)
#define MUSB2_REG_TXDBDIS
#define MUSB2_REG_TXFIFOSZ
#define MUSB2_REG_EPFIFO(n)
#define MUSB2_REG_INTUSBE
#define MUSB2_VAL_FIFOSZ_512
#define MUSB2_REG_CONFDATA
#define MUSB2_REG_TXFADDR(n)
#define MUSB2_REG_RXHADDR(n)
#define MUSB2_REG_TXHUBPORT(n)
#define MUSB2_READ_2(sc, reg)
#define MUSB2_REG_EPINDEX
#define MUSB2_REG_TXHADDR(n)
static void awusbdrd_bs_w_1(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o, uint8_t v)
static int awusbdrd_probe(device_t dev)
static driver_t awusbdrd_driver
static device_method_t awusbdrd_methods[]
static struct resource_spec awusbdrd_spec[]
static devclass_t awusbdrd_devclass
static bus_size_t awusbdrd_reg(bus_size_t o)
static uint8_t awusbdrd_bs_r_1_noconf(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o)
static const uint16_t awusbdrd_regmap[]
#define MUSB2_REG_AWIN_VEND0
static void awusbdrd_intr(void *arg)
static const struct musb_otg_ep_cfg musbotg_ep_allwinner_h3[]
static uint8_t awusbdrd_bs_r_1(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o)
DRIVER_MODULE(musbotg, simplebus, awusbdrd_driver, awusbdrd_devclass, 0, 0)
static void awusbdrd_bs_rm_1(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o, uint8_t *d, bus_size_t c)
#define AWUSB_NO_CONFDATA
static void awusbdrd_bs_wm_4(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o, const uint32_t *d, bus_size_t c)
static int awusbdrd_detach(device_t dev)
static int awusbdrd_attach(device_t dev)
static void awusbdrd_bs_w_2(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o, uint16_t v)
static void awusbdrd_bs_wm_1(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o, const uint8_t *d, bus_size_t c)
static uint16_t awusbdrd_bs_r_2(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o)
static const struct musb_otg_ep_cfg musbotg_ep_allwinner[]
static struct ofw_compat_data compat_data[]
static void awusbdrd_bs_rm_4(awusb_bs_tag t, bus_space_handle_t h, bus_size_t o, uint32_t *d, bus_size_t c)
MODULE_DEPEND(musbotg, usb, 1, 1, 1)
static int awusbdrd_filt(bus_size_t o)
struct usb_device * sc_devices[MUSB2_MAX_DEVICES]
bus_space_tag_t sc_io_tag
bus_space_handle_t sc_io_hdl
const struct musb_otg_ep_cfg * sc_ep_cfg
struct usb_device ** devices
#define USB_GET_DMA_TAG(dev)
void usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
uint8_t usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, usb_bus_mem_cb_t *cb)