From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jean-Jacques Hiblot Date: Fri, 18 May 2018 15:26:27 +0200 Subject: [U-Boot] [PATCH v2 3/6] usb: dwc3: Add generic DWC3 glue logic driver In-Reply-To: References: Message-ID: <3e53ec44-b402-96f3-e672-dfa18488f249@ti.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit To: u-boot@lists.denx.de On 18/05/2018 15:24, Jean-Jacques Hiblot wrote: > > > On 18/05/2018 13:15, Michal Simek wrote: >> By enabling BLK by default this is the next driver which needs to get >> support for DM_USB. Adding generic DWC3 glue logic which only >> parse nodes and read device mode. Based on it probe proper >> host/peripheral DWC3 drivers for it. >> >> Signed-off-by: Michal Simek >> --- >> >> Changes in v2: >> - Change style to avoid correct but not nice indentation by using char >>    *driver variable (suggested by Marek) >> >>   drivers/usb/dwc3/Kconfig        |   6 ++ >>   drivers/usb/dwc3/Makefile       |   1 + >>   drivers/usb/dwc3/dwc3-generic.c | 157 ++++++++++++++++++++++++++++++++ >>   3 files changed, 164 insertions(+) >>   create mode 100644 drivers/usb/dwc3/dwc3-generic.c >> >> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig >> index ae7fc1c6304d..943b7630eba4 100644 >> --- a/drivers/usb/dwc3/Kconfig >> +++ b/drivers/usb/dwc3/Kconfig >> @@ -37,6 +37,12 @@ config USB_DWC3_OMAP >>           Say 'Y' here if you have one such device >>   +config USB_DWC3_GENERIC >> +    bool "Xilinx ZynqMP and similar Platforms" >> +    depends on DM_USB && USB_DWC3 >> +    help >> +      Some platforms can reuse this DWC3 generic implementation. >> + >>   config USB_DWC3_UNIPHIER >>       bool "DesignWare USB3 Host Support on UniPhier Platforms" >>       depends on ARCH_UNIPHIER && USB_XHCI_DWC3 >> diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile >> index cd18b8d9ec02..60b5515a67da 100644 >> --- a/drivers/usb/dwc3/Makefile >> +++ b/drivers/usb/dwc3/Makefile >> @@ -7,6 +7,7 @@ dwc3-y                    := core.o >>   obj-$(CONFIG_USB_DWC3_GADGET)        += gadget.o ep0.o >>     obj-$(CONFIG_USB_DWC3_OMAP)        += dwc3-omap.o >> +obj-$(CONFIG_USB_DWC3_GENERIC)        += dwc3-generic.o >>   obj-$(CONFIG_USB_DWC3_UNIPHIER)        += dwc3-uniphier.o >>   obj-$(CONFIG_USB_DWC3_PHY_OMAP)        += ti_usb_phy.o >>   obj-$(CONFIG_USB_DWC3_PHY_SAMSUNG)    += samsung_usb_phy.o >> diff --git a/drivers/usb/dwc3/dwc3-generic.c >> b/drivers/usb/dwc3/dwc3-generic.c >> new file mode 100644 >> index 000000000000..ca63eac3d98e >> --- /dev/null >> +++ b/drivers/usb/dwc3/dwc3-generic.c >> @@ -0,0 +1,157 @@ >> +// SPDX-License-Identifier:     GPL-2.0 >> +/* >> + * Generic DWC3 Glue layer >> + * >> + * Copyright (C) 2016 - 2018 Xilinx, Inc. >> + * >> + * Based on dwc3-omap.c. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include "core.h" >> +#include "gadget.h" >> +#include "linux-compat.h" >> + >> +DECLARE_GLOBAL_DATA_PTR; >> + >> +int usb_gadget_handle_interrupts(int index) >> +{ >> +    struct dwc3 *priv; >> +    struct udevice *dev; >> +    int ret; >> + >> +    ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &dev); >> +    if (!dev || ret) { >> +        pr_err("No USB device found\n"); >> +        return -ENODEV; >> +    } >> + >> +    priv = dev_get_priv(dev); >> + >> +    dwc3_gadget_uboot_handle_interrupt(priv); >> + >> +    return 0; >> +} >> + >> +static int dwc3_generic_peripheral_probe(struct udevice *dev) >> +{ >> +    struct dwc3 *priv = dev_get_priv(dev); >> + >> +    return dwc3_init(priv); >> +} >> + >> +static int dwc3_generic_peripheral_remove(struct udevice *dev) >> +{ >> +    struct dwc3 *priv = dev_get_priv(dev); >> + >> +    dwc3_remove(priv); >> + >> +    return 0; >> +} >> + >> +static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice >> *dev) >> +{ >> +    struct dwc3 *priv = dev_get_priv(dev); >> +    int node = dev_of_offset(dev); >> + >> +    priv->regs = (void *)devfdt_get_addr(dev); >> +    priv->regs += DWC3_GLOBALS_REGS_START; >> + >> +    priv->maximum_speed = usb_get_maximum_speed(node); >> +    if (priv->maximum_speed == USB_SPEED_UNKNOWN) { >> +        pr_err("Invalid usb maximum speed\n"); >> +        return -ENODEV; >> +    } >> + >> +    priv->dr_mode = usb_get_dr_mode(node); >> +    if (priv->dr_mode == USB_DR_MODE_UNKNOWN) { >> +        pr_err("Invalid usb mode setup\n"); >> +        return -ENODEV; >> +    } >> + >> +    return 0; >> +} >> + >> +static int dwc3_generic_peripheral_bind(struct udevice *dev) >> +{ >> +    return device_probe(dev); > This is wrong place to probe the device. > What must be done is to probe the device when it is first used. > I have a patch in progress for this. When it's cleaned up I'll share a > repo so that you can have look and maybe pick it up. Well the series is already applied. I'll send the patch to ML in this case. >> +} >> + >> +U_BOOT_DRIVER(dwc3_generic_peripheral) = { >> +    .name    = "dwc3-generic-peripheral", >> +    .id    = UCLASS_USB_DEV_GENERIC, >> +    .ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata, >> +    .probe = dwc3_generic_peripheral_probe, >> +    .remove = dwc3_generic_peripheral_remove, >> +    .bind = dwc3_generic_peripheral_bind, >> +    .platdata_auto_alloc_size = sizeof(struct usb_platdata), >> +    .priv_auto_alloc_size = sizeof(struct dwc3), >> +    .flags    = DM_FLAG_ALLOC_PRIV_DMA, >> +}; >> + >> +static int dwc3_generic_bind(struct udevice *parent) >> +{ >> +    const void *fdt = gd->fdt_blob; >> +    int node; >> +    int ret; >> + >> +    for (node = fdt_first_subnode(fdt, dev_of_offset(parent)); node >> > 0; >> +         node = fdt_next_subnode(fdt, node)) { >> +        const char *name = fdt_get_name(fdt, node, NULL); >> +        enum usb_dr_mode dr_mode; >> +        struct udevice *dev; >> +        const char *driver; >> + >> +        debug("%s: subnode name: %s\n", __func__, name); >> +        if (strncmp(name, "dwc3@", 4)) >> +            continue; >> + >> +        dr_mode = usb_get_dr_mode(node); >> + >> +        switch (dr_mode) { >> +        case USB_DR_MODE_PERIPHERAL: >> +        case USB_DR_MODE_OTG: >> +            debug("%s: dr_mode: OTG or Peripheral\n", __func__); >> +            driver = "dwc3-generic-peripheral"; >> +            break; >> +        case USB_DR_MODE_HOST: >> +            debug("%s: dr_mode: HOST\n", __func__); >> +            driver = "dwc3-generic-host"; >> +            break; >> +        default: >> +            debug("%s: unsupported dr_mode\n", __func__); >> +            return -ENODEV; >> +        }; >> + >> +        ret = device_bind_driver_to_node(parent, driver, name, >> +                         offset_to_ofnode(node), &dev); >> +        if (ret) { >> +            debug("%s: not able to bind usb device mode\n", >> +                  __func__); >> +            return ret; >> +        } >> +    } >> + >> +    return 0; >> +} >> + >> +static const struct udevice_id dwc3_generic_ids[] = { >> +    { .compatible = "xlnx,zynqmp-dwc3" }, >> +    { } >> +}; >> + >> +U_BOOT_DRIVER(dwc3_generic_wrapper) = { >> +    .name    = "dwc3-generic-wrapper", >> +    .id    = UCLASS_MISC, >> +    .of_match = dwc3_generic_ids, >> +    .bind = dwc3_generic_bind, >> +}; > > _______________________________________________ > U-Boot mailing list > U-Boot at lists.denx.de > https://lists.denx.de/listinfo/u-boot