This is needed for SDP downloads of eg. fitimages
in SPL stage.

Signed-off-by: Manuel Traut <ma...@mecka.net>
---
 common/spl/Kconfig          |  10 +++
 common/usb_hub.c            |   4 +
 drivers/usb/gadget/Makefile |  18 ++--
 drivers/usb/gadget/ci_udc.c | 159 +++++++++++++++++-------------------
 drivers/usb/gadget/ci_udc.h |   2 +-
 drivers/usb/host/Makefile   |   2 +-
 6 files changed, 98 insertions(+), 97 deletions(-)

diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index dc319adeac..f5545d2cb2 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1181,6 +1181,16 @@ config SPL_USB_GADGET

 if SPL_USB_GADGET

+config SPL_CI_UDC
+       bool "Support USB CI UDC controller in SPL"
+       help
+         Enables CI UDC driver to be available in SPL
+
+config SPL_USB_EHCI_HCD
+       bool "Support USB EHCI Host in SPL"
+       help
+         Enables EHCI host driver in SPL.
+
 config SPL_USB_ETHER
        bool "Support USB Ethernet drivers"
        depends on SPL_NET
diff --git a/common/usb_hub.c b/common/usb_hub.c
index ba11a188ca..d572d7dd17 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -166,7 +166,9 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
        int i;
        struct usb_device *dev;
        unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2;
+#ifndef CONFIG_SPL_BUILD
        const char *env;
+#endif

        dev = hub->pusb_dev;

@@ -185,6 +187,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
                return;
 #endif

+#ifndef CONFIG_SPL_BUILD
        /*
         * Wait for power to become stable,
         * plus spec-defined max time for device to connect
@@ -196,6 +199,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
                pgood_delay = max(pgood_delay,
                                  (unsigned)simple_strtol(env, NULL, 0));
        debug("pgood_delay=%dms\n", pgood_delay);
+#endif

        /*
         * Do a minimum delay of the larger value of 100ms or pgood_delay
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index d5d891b205..df88ae2f30 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -21,16 +21,16 @@ obj-$(CONFIG_USB_GADGET_DWC2_OTG) += dwc2_udc_otg.o
 obj-$(CONFIG_USB_GADGET_DWC2_OTG_PHY) += dwc2_udc_otg_phy.o
 obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 obj-$(CONFIG_USB_GADGET_MAX3420) += max3420_udc.o
-obj-$(CONFIG_CI_UDC)   += ci_udc.o
+obj-$(CONFIG_$(SPL_)CI_UDC)    += ci_udc.o
 ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o
-obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o
-obj-$(CONFIG_DFU_OVER_USB) += f_dfu.o
-obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o
-obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o
-obj-$(CONFIG_USB_FUNCTION_SDP) += f_sdp.o
-obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o
-obj-$(CONFIG_USB_FUNCTION_ACM) += f_acm.o
+obj-$(CONFIG_$(SPL_)USB_GADGET_DOWNLOAD) += g_dnl.o
+obj-$(CONFIG_$(SPL_)USB_FUNCTION_THOR) += f_thor.o
+obj-$(CONFIG_$(SPL_)DFU_OVER_USB) += f_dfu.o
+obj-$(CONFIG_$(SPL_)USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o
+obj-$(CONFIG_$(SPL_)USB_FUNCTION_FASTBOOT) += f_fastboot.o
+obj-$(CONFIG_$(SPL_)USB_FUNCTION_SDP) += f_sdp.o
+obj-$(CONFIG_$(SPL_)USB_FUNCTION_ROCKUSB) += f_rockusb.o
+obj-$(CONFIG_$(SPL_)USB_FUNCTION_ACM)  += f_acm.o
 endif
 endif
 ifdef CONFIG_USB_ETHER
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 542684c1c3..2e274331fe 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -25,6 +25,7 @@
 #include <usb/ci_udc.h>
 #include "../host/ehci.h"
 #include "ci_udc.h"
+#include <dm.h>

 /*
  * Check if the system has too long cachelines. If the cachelines are
@@ -94,10 +95,42 @@ static struct usb_request *
 ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags);
static void ci_ep_free_request(struct usb_ep *ep, struct usb_request *_req);

+static int ci_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *d);
+static int ci_gadget_stop(struct usb_gadget *g);
+
 static struct usb_gadget_ops ci_udc_ops = {
-       .pullup = ci_pullup,
+       .pullup    = ci_pullup,
+       .udc_start = ci_gadget_start,
+       .udc_stop  = ci_gadget_stop,
+};
+
+static struct ci_drv controller = {
+       .gadget = {
+               .name   = "ci_udc",
+               .ops    = &ci_udc_ops,
+               .is_dualspeed = 1,
+               .is_otg = 0,
+               .is_a_peripheral = 0,
+               .b_hnp_enable = 0,
+               .a_hnp_support = 0,
+               .a_alt_hnp_support = 0,
+       },
 };

+static int ci_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *d)
+{
+       controller.driver = d;
+       printf("Registered gadget driver %s\n", controller.gadget.name);
+       return 0;
+}
+
+static int ci_gadget_stop(struct usb_gadget *g)
+{
+       printf("Unregistered gadget driver %s\n", controller.gadget.name);
+       controller.driver = 0;
+       return 0;
+}
+
 static struct usb_ep_ops ci_ep_ops = {
        .enable         = ci_ep_enable,
        .disable        = ci_ep_disable,
@@ -107,10 +140,6 @@ static struct usb_ep_ops ci_ep_ops = {
        .free_request   = ci_ep_free_request,
 };

-__weak void ci_init_after_reset(struct ehci_ctrl *ctrl)
-{
-}
-
 /* Init values for USB endpoints. */
 static const struct usb_ep ci_ep_init[5] = {
        [0] = { /* EP 0 */
@@ -140,15 +169,6 @@ static const struct usb_ep ci_ep_init[5] = {
        },
 };

-static struct ci_drv controller = {
-       .gadget = {
-               .name   = "ci_udc",
-               .ops    = &ci_udc_ops,
-               .is_dualspeed = 1,
-               .max_speed = USB_SPEED_HIGH,
-       },
-};
-
 /**
  * ci_get_qh() - return queue head for endpoint
  * @ep_num:    Endpoint number
@@ -310,7 +330,7 @@ static void ci_ep_free_request(struct usb_ep *ep, struct usb_request *req)

 static void ep_enable(int num, int in, int maxpacket)
 {
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+       struct ci_udc *udc = controller.udc;
        unsigned n;

        n = readl(&udc->epctrl[num]);
@@ -432,7 +452,7 @@ static void ci_debounce(struct ci_req *ci_req, int in)

 static void ci_ep_submit_next_request(struct ci_ep *ci_ep)
 {
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+       struct ci_udc *udc = controller.udc;
        struct ept_queue_item *item;
        struct ept_queue_head *head;
        int bit, num, len, in;
@@ -673,7 +693,7 @@ static void handle_setup(void)
        struct ci_ep *ci_ep = &controller.ep[0];
        struct ci_req *ci_req;
        struct usb_request *req;
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+       struct ci_udc *udc = controller.udc;
        struct ept_queue_head *head;
        struct usb_ctrlrequest r;
        int status = 0;
@@ -776,7 +796,7 @@ static void stop_activity(void)
 {
        int i, num, in;
        struct ept_queue_head *head;
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+       struct ci_udc *udc = controller.udc;
        writel(readl(&udc->epcomp), &udc->epcomp);
 #ifdef CONFIG_CI_UDC_HAS_HOSTPC
        writel(readl(&udc->epsetupstat), &udc->epsetupstat);
@@ -800,16 +820,18 @@ static void stop_activity(void)
        }
 }

-void udc_irq(void)
+static int udc_irq(void)
 {
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
-       unsigned n = readl(&udc->usbsts);
-       writel(n, &udc->usbsts);
+       struct ci_udc *udc = controller.udc;
+       unsigned n;
        int bit, i, num, in;

+       n = readl(&udc->usbsts);
+       writel(n, &udc->usbsts);
+
        n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI);
        if (n == 0)
-               return;
+               return IRQ_NONE;

        if (n & STS_URI) {
                DBG("-- reset --\n");
@@ -867,23 +889,17 @@ void udc_irq(void)
                        }
                }
        }
+       return IRQ_HANDLED;
 }

-int usb_gadget_handle_interrupts(int index)
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
 {
-       u32 value;
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
-
-       value = readl(&udc->usbsts);
-       if (value)
-               udc_irq();
-
-       return value;
+       return udc_irq();
 }

 void udc_disconnect(void)
 {
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+       struct ci_udc *udc = controller.udc;
        /* disable pullup */
        stop_activity();
        writel(USBCMD_FS2, &udc->usbcmd);
@@ -894,14 +910,12 @@ void udc_disconnect(void)

 static int ci_pullup(struct usb_gadget *gadget, int is_on)
 {
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+       struct ci_udc *udc = controller.udc;
        if (is_on) {
                /* RESET */
                writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RST, &udc->usbcmd);
                udelay(200);

-               ci_init_after_reset(controller.ctrl);
-
                writel((unsigned long)controller.epts, &udc->epinitaddr);

                /* select DEVICE mode */
@@ -924,7 +938,7 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on)
        return 0;
 }

-static int ci_udc_probe(void)
+static int ci_udc_probe(struct udevice *dev)
 {
        struct ept_queue_head *head;
        int i;
@@ -936,6 +950,9 @@ static int ci_udc_probe(void)
        const int eplist_raw_sz = num * sizeof(struct ept_queue_head);
        const int eplist_sz = roundup(eplist_raw_sz, ARCH_DMA_MINALIGN);

+       controller.driver = 0;
+       controller.udc = (struct ci_udc *) 0x32e40140; // TODO read from DTB
+
        /* The QH list must be aligned to 4096 bytes. */
        controller.epts = memalign(eplist_align, eplist_sz);
        if (!controller.epts)
@@ -1010,66 +1027,36 @@ static int ci_udc_probe(void)
                return -ENOMEM;
        }

-       return 0;
+       return usb_add_gadget_udc((struct device *)dev, &controller.gadget);
 }

-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+static int ci_udc_remove(struct udevice *dev)
 {
-       int ret;
-
-       if (!driver)
-               return -EINVAL;
-       if (!driver->bind || !driver->setup || !driver->disconnect)
-               return -EINVAL;
-
-#if CONFIG_IS_ENABLED(DM_USB)
-       ret = usb_setup_ehci_gadget(&controller.ctrl);
-#else
- ret = usb_lowlevel_init(0, USB_INIT_DEVICE, (void **)&controller.ctrl);
-#endif
-       if (ret)
-               return ret;
-
-       ret = ci_udc_probe();
-       if (ret) {
-               DBG("udc probe failed, returned %d\n", ret);
-               return ret;
-       }
-
-       ret = driver->bind(&controller.gadget);
-       if (ret) {
-               DBG("driver->bind() returned %d\n", ret);
-               return ret;
-       }
-       controller.driver = driver;
-
-       return 0;
-}
-
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
-{
-       udc_disconnect();
-
-       driver->unbind(&controller.gadget);
-       controller.driver = NULL;
-
+       usb_del_gadget_udc(&controller.gadget);
        ci_ep_free_request(&controller.ep[0].ep, &controller.ep0_req->req);
        free(controller.items_mem);
        free(controller.epts);

-#if CONFIG_IS_ENABLED(DM_USB)
-       usb_remove_ehci_gadget(&controller.ctrl);
-#else
-       usb_lowlevel_stop(0);
-       controller.ctrl = NULL;
-#endif
-
-       return 0;
+       return dm_scan_fdt_dev(dev);
 }

+static const struct udevice_id ci_udc_ids[] = {
+       { .compatible = "fsl,imx27-usb-gadget" },
+       {},
+};
+
+U_BOOT_DRIVER(ci_udc_usb) = {
+       .name       = "ci-udc",
+       .id         = UCLASS_USB_GADGET_GENERIC,
+       .of_match   = ci_udc_ids,
+       .probe      = ci_udc_probe,
+       .remove     = ci_udc_remove,
+       .priv_auto  = sizeof(struct ci_udc),
+};
+
 bool dfu_usb_get_reset(void)
 {
-       struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+       struct ci_udc *udc = controller.udc;

        return !!(readl(&udc->usbsts) & STS_URI);
 }
diff --git a/drivers/usb/gadget/ci_udc.h b/drivers/usb/gadget/ci_udc.h
index 95cc07992b..c087ac533d 100644
--- a/drivers/usb/gadget/ci_udc.h
+++ b/drivers/usb/gadget/ci_udc.h
@@ -101,7 +101,7 @@ struct ci_drv {
        struct ci_req                   *ep0_req;
        bool                            ep0_data_phase;
        struct usb_gadget_driver        *driver;
-       struct ehci_ctrl                *ctrl;
+       struct ci_udc           *udc;
        struct ept_queue_head           *epts;
        uint8_t                         *items_mem;
        struct ci_ep                    ep[NUM_ENDPOINTS];
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index eb6fe9f6b3..08474daaf2 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -20,7 +20,7 @@ obj-$(CONFIG_USB_OHCI_PCI) += ohci-pci.o
 obj-$(CONFIG_USB_OHCI_GENERIC) += ohci-generic.o

 # echi
-obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
+obj-$(CONFIG_$(SPL_)USB_EHCI_HCD) += ehci-hcd.o
 obj-$(CONFIG_USB_EHCI_ARMADA100) += ehci-armada100.o utmi-armada100.o
 obj-$(CONFIG_USB_EHCI_ATMEL) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
--
2.30.2

Reply via email to