Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109125723
D5841.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
30 KB
Referenced Files
None
Subscribers
None
D5841.diff
View Options
Index: head/sys/mips/mediatek/mtk_dotg.c
===================================================================
--- head/sys/mips/mediatek/mtk_dotg.c
+++ head/sys/mips/mediatek/mtk_dotg.c
@@ -0,0 +1,220 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 2015-2016 Stanislav Galabov. All rights reserved.
+ * Copyright (c) 2010,2011 Aleksandr Rybalko. All rights reserved.
+ * Copyright (c) 2007-2008 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+#include <sys/rman.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+
+#include <dev/usb/controller/dwc_otg.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#define MEM_RID 0
+
+static device_probe_t dotg_fdt_probe;
+static device_attach_t dotg_fdt_attach;
+static device_detach_t dotg_fdt_detach;
+
+static int
+dotg_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_is_compatible(dev, "ralink,rt3050-otg"))
+ return (ENXIO);
+
+ device_set_desc(dev, "MTK DWC-OTG USB Controller");
+ return (0);
+}
+
+static int
+dotg_fdt_attach(device_t dev)
+{
+ struct dwc_otg_softc *sc = device_get_softc(dev);
+ int err, rid;
+
+ /* setup controller interface softc */
+
+ /* initialise some bus fields */
+ sc->sc_mode = DWC_MODE_HOST;
+ sc->sc_bus.parent = dev;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = DWC_OTG_MAX_DEVICES;
+ sc->sc_bus.dma_bits = 32;
+
+ /* get all DMA memory */
+ if (usb_bus_mem_alloc_all(&sc->sc_bus,
+ USB_GET_DMA_TAG(dev), NULL)) {
+ printf("No mem\n");
+ return (ENOMEM);
+ }
+ rid = 0;
+ sc->sc_io_res =
+ bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ if (!(sc->sc_io_res)) {
+ printf("Can`t alloc MEM\n");
+ goto error;
+ }
+ sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+ sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+ sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+ rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &rid, RF_ACTIVE);
+ if (!(sc->sc_irq_res)) {
+ printf("Can`t alloc IRQ\n");
+ goto error;
+ }
+
+ sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+ if (!(sc->sc_bus.bdev)) {
+ printf("Can`t add usbus\n");
+ goto error;
+ }
+ device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+ err = bus_setup_intr(dev, sc->sc_irq_res,
+ INTR_TYPE_TTY | INTR_MPSAFE, dwc_otg_filter_interrupt,
+ dwc_otg_interrupt, sc, &sc->sc_intr_hdl);
+ if (err) {
+ sc->sc_intr_hdl = NULL;
+ printf("Can`t set IRQ handle\n");
+ goto error;
+ }
+
+ err = dwc_otg_init(sc);
+ if (err) printf("dotg_init fail\n");
+ if (!err) {
+ err = device_probe_and_attach(sc->sc_bus.bdev);
+ if (err) printf("device_probe_and_attach fail %d\n", err);
+ }
+ if (err) {
+ goto error;
+ }
+ return (0);
+
+error:
+ dotg_fdt_detach(dev);
+ return (ENXIO);
+}
+
+static int
+dotg_fdt_detach(device_t dev)
+{
+ struct dwc_otg_softc *sc = device_get_softc(dev);
+ device_t bdev;
+ int err;
+
+ if (sc->sc_bus.bdev) {
+ bdev = sc->sc_bus.bdev;
+ device_detach(bdev);
+ device_delete_child(dev, bdev);
+ }
+ /* during module unload there are lots of children leftover */
+ device_delete_children(dev);
+
+ if (sc->sc_irq_res && sc->sc_intr_hdl) {
+ /*
+ * only call dotg_fdt_uninit() after dotg_fdt_init()
+ */
+ dwc_otg_uninit(sc);
+
+ err = bus_teardown_intr(dev, sc->sc_irq_res,
+ sc->sc_intr_hdl);
+ sc->sc_intr_hdl = NULL;
+ }
+ if (sc->sc_irq_res) {
+ bus_release_resource(dev, SYS_RES_IRQ, 0,
+ sc->sc_irq_res);
+ sc->sc_irq_res = NULL;
+ }
+ if (sc->sc_io_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY, 0,
+ sc->sc_io_res);
+ sc->sc_io_res = NULL;
+ }
+ usb_bus_mem_free_all(&sc->sc_bus, NULL);
+
+ return (0);
+}
+
+static device_method_t dotg_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, dotg_fdt_probe),
+ DEVMETHOD(device_attach, dotg_fdt_attach),
+ DEVMETHOD(device_detach, dotg_fdt_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ DEVMETHOD_END
+};
+
+static driver_t dotg_fdt_driver = {
+ .name = "dwcotg",
+ .methods = dotg_fdt_methods,
+ .size = sizeof(struct dwc_otg_softc),
+};
+
+static devclass_t dotg_fdt_devclass;
+
+DRIVER_MODULE(dotg, simplebus, dotg_fdt_driver, dotg_fdt_devclass, 0, 0);
Index: head/sys/mips/mediatek/mtk_ehci.c
===================================================================
--- head/sys/mips/mediatek/mtk_ehci.c
+++ head/sys/mips/mediatek/mtk_ehci.c
@@ -0,0 +1,223 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 2015 Stanislav Galabov. All rights reserved.
+ * Copyright (c) 2010,2011 Aleksandr Rybalko. All rights reserved.
+ * Copyright (c) 2007-2008 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+#include <sys/rman.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+
+#include <dev/usb/controller/ehci.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#define EHCI_HC_DEVSTR "MTK USB 2.0 Controller"
+
+static device_probe_t ehci_fdt_probe;
+static device_attach_t ehci_fdt_attach;
+static device_detach_t ehci_fdt_detach;
+
+static int
+ehci_fdt_probe(device_t self)
+{
+
+ if (!ofw_bus_status_okay(self))
+ return (ENXIO);
+
+ if (!ofw_bus_is_compatible(self, "ralink,rt3xxx-ehci"))
+ return (ENXIO);
+
+ device_set_desc(self, EHCI_HC_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ehci_fdt_attach(device_t self)
+{
+ ehci_softc_t *sc = device_get_softc(self);
+ int err;
+ int rid;
+
+ /* initialise some bus fields */
+ sc->sc_bus.parent = self;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+ sc->sc_bus.dma_bits = 32;
+
+ /* get all DMA memory */
+ if (usb_bus_mem_alloc_all(&sc->sc_bus,
+ USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
+ printf("No mem\n");
+ return (ENOMEM);
+ }
+
+ rid = 0;
+ sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (!sc->sc_io_res) {
+ device_printf(self, "Could not map memory\n");
+ goto error;
+ }
+ sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+ sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+ sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+ rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (sc->sc_irq_res == NULL) {
+ device_printf(self, "Could not allocate irq\n");
+ goto error;
+ }
+
+ sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
+ if (!(sc->sc_bus.bdev)) {
+ device_printf(self, "Could not add USB device\n");
+ goto error;
+ }
+ device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+ device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
+
+ sprintf(sc->sc_vendor, "MediaTek");
+
+ err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+ NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
+ if (err) {
+ device_printf(self, "Could not setup irq, %d\n", err);
+ sc->sc_intr_hdl = NULL;
+ goto error;
+ }
+
+ err = ehci_init(sc);
+ if (!err) {
+ err = device_probe_and_attach(sc->sc_bus.bdev);
+ }
+ if (err) {
+ device_printf(self, "USB init failed err=%d\n", err);
+ goto error;
+ }
+ return (0);
+
+error:
+ ehci_fdt_detach(self);
+ return (ENXIO);
+}
+
+static int
+ehci_fdt_detach(device_t self)
+{
+ ehci_softc_t *sc = device_get_softc(self);
+ device_t bdev;
+ int err;
+
+ if (sc->sc_bus.bdev) {
+ bdev = sc->sc_bus.bdev;
+ device_detach(bdev);
+ device_delete_child(self, bdev);
+ }
+ /* during module unload there are lots of children leftover */
+ device_delete_children(self);
+
+ if (sc->sc_irq_res && sc->sc_intr_hdl) {
+ /*
+ * only call ehci_detach() after ehci_init()
+ */
+ ehci_detach(sc);
+
+ err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
+ if (err)
+ device_printf(self, "Could not tear down irq, %d\n",
+ err);
+ sc->sc_intr_hdl = NULL;
+ }
+ if (sc->sc_irq_res) {
+ bus_release_resource(self, SYS_RES_IRQ, 0,
+ sc->sc_irq_res);
+ sc->sc_irq_res = NULL;
+ }
+ if (sc->sc_io_res) {
+ bus_release_resource(self, SYS_RES_MEMORY, 0,
+ sc->sc_io_res);
+ sc->sc_io_res = NULL;
+ }
+ usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
+
+ return (0);
+}
+
+static device_method_t ehci_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ehci_fdt_probe),
+ DEVMETHOD(device_attach, ehci_fdt_attach),
+ DEVMETHOD(device_detach, ehci_fdt_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ DEVMETHOD_END
+};
+
+static driver_t ehci_fdt_driver = {
+ .name = "ehci",
+ .methods = ehci_fdt_methods,
+ .size = sizeof(ehci_softc_t),
+};
+
+static devclass_t ehci_fdt_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_fdt_driver, ehci_fdt_devclass, 0, 0);
Index: head/sys/mips/mediatek/mtk_ohci.c
===================================================================
--- head/sys/mips/mediatek/mtk_ohci.c
+++ head/sys/mips/mediatek/mtk_ohci.c
@@ -0,0 +1,223 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*-
+ * Copyright (c) 2015 Stanislav Galabov. All rights reserved.
+ * Copyright (c) 2010,2011 Aleksandr Rybalko. All rights reserved.
+ * Copyright (c) 2007-2008 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+#include <sys/rman.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+
+#include <dev/usb/controller/ohci.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#define OHCI_HC_DEVSTR "MTK USB Controller"
+
+static device_probe_t ohci_fdt_probe;
+static device_attach_t ohci_fdt_attach;
+static device_detach_t ohci_fdt_detach;
+
+static int
+ohci_fdt_probe(device_t self)
+{
+
+ if (!ofw_bus_status_okay(self))
+ return (ENXIO);
+
+ if (!ofw_bus_is_compatible(self, "ralink,rt3xxx-ohci"))
+ return (ENXIO);
+
+ device_set_desc(self, OHCI_HC_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ohci_fdt_attach(device_t self)
+{
+ ohci_softc_t *sc = device_get_softc(self);
+ int err;
+ int rid;
+
+ /* initialise some bus fields */
+ sc->sc_bus.parent = self;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = OHCI_MAX_DEVICES;
+ sc->sc_bus.dma_bits = 32;
+
+ /* get all DMA memory */
+ if (usb_bus_mem_alloc_all(&sc->sc_bus,
+ USB_GET_DMA_TAG(self), &ohci_iterate_hw_softc)) {
+ printf("No mem\n");
+ return (ENOMEM);
+ }
+
+ rid = 0;
+ sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (!sc->sc_io_res) {
+ device_printf(self, "Could not map memory\n");
+ goto error;
+ }
+ sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+ sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+ sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+ rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (sc->sc_irq_res == NULL) {
+ device_printf(self, "Could not allocate irq\n");
+ goto error;
+ }
+
+ sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
+ if (!(sc->sc_bus.bdev)) {
+ device_printf(self, "Could not add USB device\n");
+ goto error;
+ }
+ device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+ device_set_desc(sc->sc_bus.bdev, OHCI_HC_DEVSTR);
+
+ sprintf(sc->sc_vendor, "MediaTek");
+
+ err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+ NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_intr_hdl);
+ if (err) {
+ device_printf(self, "Could not setup irq, %d\n", err);
+ sc->sc_intr_hdl = NULL;
+ goto error;
+ }
+
+ err = ohci_init(sc);
+ if (!err) {
+ err = device_probe_and_attach(sc->sc_bus.bdev);
+ }
+ if (err) {
+ device_printf(self, "USB init failed err=%d\n", err);
+ goto error;
+ }
+ return (0);
+
+error:
+ ohci_fdt_detach(self);
+ return (ENXIO);
+}
+
+static int
+ohci_fdt_detach(device_t self)
+{
+ ohci_softc_t *sc = device_get_softc(self);
+ device_t bdev;
+ int err;
+
+ if (sc->sc_bus.bdev) {
+ bdev = sc->sc_bus.bdev;
+ device_detach(bdev);
+ device_delete_child(self, bdev);
+ }
+ /* during module unload there are lots of children leftover */
+ device_delete_children(self);
+
+ if (sc->sc_irq_res && sc->sc_intr_hdl) {
+ /*
+ * only call ohci_detach() after ohci_init()
+ */
+ ohci_detach(sc);
+
+ err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
+ if (err)
+ device_printf(self, "Could not tear down irq, %d\n",
+ err);
+ sc->sc_intr_hdl = NULL;
+ }
+ if (sc->sc_irq_res) {
+ bus_release_resource(self, SYS_RES_IRQ, 0,
+ sc->sc_irq_res);
+ sc->sc_irq_res = NULL;
+ }
+ if (sc->sc_io_res) {
+ bus_release_resource(self, SYS_RES_MEMORY, 0,
+ sc->sc_io_res);
+ sc->sc_io_res = NULL;
+ }
+ usb_bus_mem_free_all(&sc->sc_bus, &ohci_iterate_hw_softc);
+
+ return (0);
+}
+
+static device_method_t ohci_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ohci_fdt_probe),
+ DEVMETHOD(device_attach, ohci_fdt_attach),
+ DEVMETHOD(device_detach, ohci_fdt_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ DEVMETHOD_END
+};
+
+static driver_t ohci_fdt_driver = {
+ .name = "ohci",
+ .methods = ohci_fdt_methods,
+ .size = sizeof(ohci_softc_t),
+};
+
+static devclass_t ohci_fdt_devclass;
+
+DRIVER_MODULE(ohci, simplebus, ohci_fdt_driver, ohci_fdt_devclass, 0, 0);
Index: head/sys/mips/mediatek/mtk_usb_phy.h
===================================================================
--- head/sys/mips/mediatek/mtk_usb_phy.h
+++ head/sys/mips/mediatek/mtk_usb_phy.h
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2016 Stanislav Galabov.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _MTK_USB_PHY_H_
+#define _MTK_USB_PHY_H_
+
+#define MT7621_FM_FEG_BASE 0x0100
+#define MT7621_U2_BASE 0x0800
+#define MT7621_U2_BASE_P1 0x1000
+#define MT7621_SR_COEF 28
+
+#define MT7628_FM_FEG_BASE 0x0f00
+#define MT7628_U2_BASE 0x0800
+#define MT7628_SR_COEF 32
+
+#define U2_PHY_AC0 0x00
+#define U2_PHY_AC1 0x04
+#define U2_PHY_AC2 0x08
+#define U2_PHY_ACR0 0x10
+#define SRCAL_EN (1<<23)
+#define SRCTRL_MSK 0x7
+#define SRCTRL_OFF 16
+#define SRCTRL (SRCTRL_MSK<<SRCTRL_OFF)
+#define U2_PHY_ACR1 0x14
+#define U2_PHY_ACR2 0x18
+#define U2_PHY_ACR3 0x1C
+
+#define U2_PHY_DCR0 0x60
+#define U2_PHY_DCR1 0x64
+#define U2_PHY_DTM0 0x68
+#define U2_PHY_DTM1 0x6C
+
+#define U2_PHY_FMCR0 0x00
+#define CYCLECNT (0xffffff)
+#define FDET_EN (1<<24)
+#define U2_PHY_FMCR1 0x04
+#define FRCK_EN (1<<8)
+#define U2_PHY_FMCR2 0x08
+#define U2_PHY_FMMONR0 0x0C
+#define U2_PHY_FMMONR1 0x10
+
+#endif /* _MTK_USB_PHY_H_ */
Index: head/sys/mips/mediatek/mtk_usb_phy.c
===================================================================
--- head/sys/mips/mediatek/mtk_usb_phy.c
+++ head/sys/mips/mediatek/mtk_usb_phy.c
@@ -0,0 +1,314 @@
+/*-
+ * Copyright (c) 2016 Stanislav Galabov.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/fdt/fdt_clock.h>
+#include <mips/mediatek/fdt_reset.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <mips/mediatek/mtk_sysctl.h>
+#include <mips/mediatek/mtk_soc.h>
+#include <mips/mediatek/mtk_usb_phy.h>
+
+#define RESET_ASSERT_DELAY 1000
+#define RESET_DEASSERT_DELAY 10000
+
+struct mtk_usb_phy_softc {
+ device_t dev;
+ struct resource * res;
+ uint32_t fm_base;
+ uint32_t u2_base;
+ uint32_t sr_coef;
+ uint32_t socid;
+};
+
+#define USB_PHY_READ(_sc, _off) bus_read_4((_sc)->res, (_off))
+#define USB_PHY_WRITE(_sc, _off, _val) bus_write_4((_sc)->res, (_off), (_val))
+#define USB_PHY_CLR_SET(_sc, _off, _clr, _set) \
+ USB_PHY_WRITE(_sc, _off, ((USB_PHY_READ(_sc, _off) & ~(_clr)) | (_set)))
+
+#define USB_PHY_READ_U2(_sc, _off) \
+ USB_PHY_READ((_sc), ((_sc)->u2_base + (_off)))
+#define USB_PHY_WRITE_U2(_sc, _off, _val) \
+ USB_PHY_WRITE((_sc), ((_sc)->u2_base + (_off)), (_val))
+#define USB_PHY_CLR_SET_U2(_sc, _off, _clr, _set) \
+ USB_PHY_WRITE_U2((_sc), (_off), ((USB_PHY_READ_U2((_sc), (_off)) & \
+ ~(_clr)) | (_set)))
+#define USB_PHY_BARRIER(_sc) bus_barrier((_sc)->res, 0, 0, \
+ BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ)
+
+#define USB_PHY_READ_FM(_sc, _off) \
+ USB_PHY_READ((_sc), ((_sc)->fm_base + (_off)))
+#define USB_PHY_WRITE_FM(_sc, _off) \
+ USB_PHY_WRITE((_sc), ((_sc)->fm_base + (_off)), (_val))
+#define USB_PHY_CLR_SET_FM(_sc, _off, _clr, _set) \
+ USB_PHY_WRITE_U2((_sc), (_off), ((USB_PHY_READ_U2((_sc), (_off)) & \
+ ~(_clr)) | (_set)))
+
+static void mtk_usb_phy_mt7621_init(device_t);
+static void mtk_usb_phy_mt7628_init(device_t);
+
+static struct ofw_compat_data compat_data[] = {
+ { "ralink,mt7620a-usbphy", MTK_SOC_MT7620A },
+ { "ralink,mt7628an-usbphy", MTK_SOC_MT7628 },
+ { "ralink,rt3xxx-usbphy", MTK_SOC_RT3352 },
+ { NULL, MTK_SOC_UNKNOWN }
+};
+
+static int
+mtk_usb_phy_probe(device_t dev)
+{
+ struct mtk_usb_phy_softc *sc = device_get_softc(dev);
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+ if ((sc->socid =
+ ofw_bus_search_compatible(dev, compat_data)->ocd_data) ==
+ MTK_SOC_UNKNOWN)
+ return (ENXIO);
+
+ device_set_desc(dev, "MTK USB PHY");
+
+ return (0);
+}
+
+static int
+mtk_usb_phy_attach(device_t dev)
+{
+ struct mtk_usb_phy_softc * sc = device_get_softc(dev);
+ phandle_t node;
+ uint32_t val;
+ int rid;
+
+ sc->dev = dev;
+
+ /* Get our FDT node and SoC id */
+ node = ofw_bus_get_node(dev);
+
+ /* Now let's see about setting USB to host or device mode */
+ /* XXX: is it the same for all SoCs? */
+ val = mtk_sysctl_get(SYSCTL_SYSCFG1);
+ if (OF_hasprop(node, "mtk,usb-device"))
+ val &= ~SYSCFG1_USB_HOST_MODE;
+ else
+ val |= SYSCFG1_USB_HOST_MODE;
+ mtk_sysctl_set(SYSCTL_SYSCFG1, val);
+
+ /* If we have clocks defined - enable them */
+ if (OF_hasprop(node, "clocks"))
+ fdt_clock_enable_all(dev);
+
+ /* If we have resets defined - perform a reset sequence */
+ if (OF_hasprop(node, "resets")) {
+ fdt_reset_assert_all(dev);
+ DELAY(RESET_ASSERT_DELAY);
+ fdt_reset_deassert_all(dev);
+ DELAY(RESET_DEASSERT_DELAY);
+ }
+
+ /* Careful, some devices actually require resources */
+ if (OF_hasprop(node, "reg")) {
+ rid = 0;
+ sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (sc->res == NULL) {
+ device_printf(dev, "could not map memory\n");
+ return (ENXIO);
+ }
+ } else {
+ sc->res = NULL;
+ }
+
+ /* Some SoCs require specific USB PHY init... handle these */
+ switch (sc->socid) {
+ case MTK_SOC_MT7628: /* Fallthrough */
+ case MTK_SOC_MT7688:
+ if (sc->res == NULL)
+ return (ENXIO);
+ sc->fm_base = MT7628_FM_FEG_BASE;
+ sc->u2_base = MT7628_U2_BASE;
+ sc->sr_coef = MT7628_SR_COEF;
+ mtk_usb_phy_mt7628_init(dev);
+ break;
+ case MTK_SOC_MT7621:
+ if (sc->res == NULL)
+ return (ENXIO);
+ sc->fm_base = MT7621_FM_FEG_BASE;
+ sc->u2_base = MT7621_U2_BASE;
+ sc->sr_coef = MT7621_SR_COEF;
+ mtk_usb_phy_mt7621_init(dev);
+ break;
+ }
+
+ /* We no longer need the resources, release them */
+ if (sc->res != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res);
+
+ return (0);
+}
+
+static int
+mtk_usb_phy_detach(device_t dev)
+{
+ struct mtk_usb_phy_softc *sc = device_get_softc(dev);
+ phandle_t node;
+
+ /* Get our FDT node */
+ node = ofw_bus_get_node(dev);
+
+ /* If we have resets defined - assert them */
+ if (OF_hasprop(node, "resets"))
+ fdt_reset_assert_all(dev);
+
+ /* If we have clocks defined - disable them */
+ if (OF_hasprop(node, "clocks"))
+ fdt_clock_disable_all(dev);
+
+ /* Finally, release resources, if any were allocated */
+ if (sc->res != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res);
+
+ return (0);
+}
+
+static void
+mtk_usb_phy_slew_rate_calibration(struct mtk_usb_phy_softc *sc)
+{
+ uint32_t val;
+ int i;
+
+ USB_PHY_CLR_SET_U2(sc, U2_PHY_ACR0, 0, SRCAL_EN);
+ USB_PHY_BARRIER(sc);
+ DELAY(1000);
+
+ USB_PHY_CLR_SET_FM(sc, U2_PHY_FMMONR1, 0, FRCK_EN);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_CLR_SET_FM(sc, U2_PHY_FMCR0, CYCLECNT, 0x400);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_CLR_SET_FM(sc, U2_PHY_FMCR0, 0, FDET_EN);
+ USB_PHY_BARRIER(sc);
+
+ for (i = 0; i < 1000; i++) {
+ if ((val = USB_PHY_READ_FM(sc, U2_PHY_FMMONR0)) != 0) {
+ device_printf(sc->dev, "DONE with FDET\n");
+ break;
+ }
+ DELAY(10000);
+ }
+ device_printf(sc->dev, "After FDET\n");
+
+ USB_PHY_CLR_SET_FM(sc, U2_PHY_FMCR0, FDET_EN, 0);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_CLR_SET_FM(sc, U2_PHY_FMMONR1, FRCK_EN, 0);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_CLR_SET_U2(sc, U2_PHY_ACR0, SRCAL_EN, 0);
+ USB_PHY_BARRIER(sc);
+ DELAY(1000);
+
+ if (val == 0) {
+ USB_PHY_CLR_SET_U2(sc, U2_PHY_ACR0, SRCTRL, 0x4 << SRCTRL_OFF);
+ USB_PHY_BARRIER(sc);
+ } else {
+ val = ((((1024 * 25 * sc->sr_coef) / val) + 500) / 1000) &
+ SRCTRL_MSK;
+ USB_PHY_CLR_SET_U2(sc, U2_PHY_ACR0, SRCTRL, val << SRCTRL_OFF);
+ USB_PHY_BARRIER(sc);
+ }
+}
+
+static void
+mtk_usb_phy_mt7621_init(device_t dev)
+{
+ struct mtk_usb_phy_softc *sc = device_get_softc(dev);
+
+ /* Slew rate calibration only, but for 2 ports */
+ mtk_usb_phy_slew_rate_calibration(sc);
+
+ sc->u2_base = MT7621_U2_BASE_P1;
+ mtk_usb_phy_slew_rate_calibration(sc);
+}
+
+static void
+mtk_usb_phy_mt7628_init(device_t dev)
+{
+ struct mtk_usb_phy_softc *sc = device_get_softc(dev);
+
+ /* XXX: possibly add barriers between the next writes? */
+ USB_PHY_WRITE_U2(sc, U2_PHY_DCR0, 0x00ffff02);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_WRITE_U2(sc, U2_PHY_DCR0, 0x00555502);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_WRITE_U2(sc, U2_PHY_DCR0, 0x00aaaa02);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_WRITE_U2(sc, U2_PHY_DCR0, 0x00000402);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_WRITE_U2(sc, U2_PHY_AC0, 0x0048086a);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_WRITE_U2(sc, U2_PHY_AC1, 0x4400001c);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_WRITE_U2(sc, U2_PHY_ACR3, 0xc0200000);
+ USB_PHY_BARRIER(sc);
+ USB_PHY_WRITE_U2(sc, U2_PHY_DTM0, 0x02000000);
+ USB_PHY_BARRIER(sc);
+
+ /* Slew rate calibration */
+ //mtk_usb_phy_slew_rate_calibration(sc);
+}
+
+static device_method_t mtk_usb_phy_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, mtk_usb_phy_probe),
+ DEVMETHOD(device_attach, mtk_usb_phy_attach),
+ DEVMETHOD(device_detach, mtk_usb_phy_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ DEVMETHOD_END
+};
+
+static driver_t mtk_usb_phy_driver = {
+ .name = "usbphy",
+ .methods = mtk_usb_phy_methods,
+ .size = sizeof(struct mtk_usb_phy_softc),
+};
+
+static devclass_t mtk_usb_phy_devclass;
+
+DRIVER_MODULE(usbphy, simplebus, mtk_usb_phy_driver, mtk_usb_phy_devclass, 0,
+ 0);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 2, 3:32 AM (18 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16394976
Default Alt Text
D5841.diff (30 KB)
Attached To
Mode
D5841: Initial import of Ralink/Mediatek MIPS SoC support #5
Attached
Detach File
Event Timeline
Log In to Comment