[U-Boot] [PATCH] usb: dwc3: add UniPhier specific glue layer

Add UniPhier platform specific glue layer to support USB3 Host mode on Synopsys DWC3 IP.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Reviewed-by: Marek Vasut marex@denx.de ---
I sent amost the same one last year, and applied in u-boot-usb: http://patchwork.ozlabs.org/patch/622564/
I retracted it for some reasons, but now U-Boot has similar code as I was trying to push one year ago.
I am resending the driver.
drivers/usb/dwc3/Kconfig | 7 +++ drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-uniphier.c | 120 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 drivers/usb/dwc3/dwc3-uniphier.c
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index a291ceb..ae7fc1c 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -37,6 +37,13 @@ config USB_DWC3_OMAP
Say 'Y' here if you have one such device
+config USB_DWC3_UNIPHIER + bool "DesignWare USB3 Host Support on UniPhier Platforms" + depends on ARCH_UNIPHIER && USB_XHCI_DWC3 + help + Support of USB2/3 functionality in Socionext UniPhier platforms. + Say 'Y' here if you have one such device. + menu "PHY Subsystem"
config USB_DWC3_PHY_OMAP diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 2964bae..5149776 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -9,5 +9,6 @@ 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_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-uniphier.c b/drivers/usb/dwc3/dwc3-uniphier.c new file mode 100644 index 0000000..0d13770 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-uniphier.c @@ -0,0 +1,120 @@ +/* + * UniPhier Specific Glue Layer for DWC3 + * + * Copyright (C) 2016-2017 Socionext Inc. + * Author: Masahiro Yamada yamada.masahiro@socionext.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <linux/errno.h> +#include <linux/io.h> +#include <linux/sizes.h> + +#define UNIPHIER_PRO4_DWC3_RESET 0x40 +#define UNIPHIER_PRO4_DWC3_RESET_XIOMMU BIT(5) +#define UNIPHIER_PRO4_DWC3_RESET_XLINK BIT(4) +#define UNIPHIER_PRO4_DWC3_RESET_PHY_SS BIT(2) + +#define UNIPHIER_PRO5_DWC3_RESET 0x00 +#define UNIPHIER_PRO5_DWC3_RESET_PHY_S1 BIT(17) +#define UNIPHIER_PRO5_DWC3_RESET_PHY_S0 BIT(16) +#define UNIPHIER_PRO5_DWC3_RESET_XLINK BIT(15) +#define UNIPHIER_PRO5_DWC3_RESET_XIOMMU BIT(14) + +#define UNIPHIER_PXS2_DWC3_RESET 0x00 +#define UNIPHIER_PXS2_DWC3_RESET_XLINK BIT(15) + +static int uniphier_pro4_dwc3_init(void __iomem *regs) +{ + u32 tmp; + + tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET); + tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS; + tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK; + writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET); + + return 0; +} + +static int uniphier_pro5_dwc3_init(void __iomem *regs) +{ + u32 tmp; + + tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET); + tmp &= ~(UNIPHIER_PRO5_DWC3_RESET_PHY_S1 | + UNIPHIER_PRO5_DWC3_RESET_PHY_S0); + tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU; + writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET); + + return 0; +} + +static int uniphier_pxs2_dwc3_init(void __iomem *regs) +{ + u32 tmp; + + tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET); + tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK; + writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET); + + return 0; +} + +static int uniphier_dwc3_probe(struct udevice *dev) +{ + fdt_addr_t base; + void __iomem *regs; + int (*init)(void __iomem *regs); + int ret; + + base = devfdt_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + regs = ioremap(base, SZ_32K); + if (!regs) + return -ENOMEM; + + init = (typeof(init))dev_get_driver_data(dev); + ret = init(regs); + if (ret) + dev_err(dev, "failed to init glue layer\n"); + + iounmap(regs); + + return ret; +} + +static const struct udevice_id uniphier_dwc3_match[] = { + { + .compatible = "socionext,uniphier-pro4-dwc3", + .data = (ulong)uniphier_pro4_dwc3_init, + }, + { + .compatible = "socionext,uniphier-pro5-dwc3", + .data = (ulong)uniphier_pro5_dwc3_init, + }, + { + .compatible = "socionext,uniphier-pxs2-dwc3", + .data = (ulong)uniphier_pxs2_dwc3_init, + }, + { + .compatible = "socionext,uniphier-ld20-dwc3", + .data = (ulong)uniphier_pxs2_dwc3_init, + }, + { + .compatible = "socionext,uniphier-pxs3-dwc3", + .data = (ulong)uniphier_pxs2_dwc3_init, + }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(usb_xhci) = { + .name = "uniphier-dwc3", + .id = UCLASS_SIMPLE_BUS, + .of_match = uniphier_dwc3_match, + .probe = uniphier_dwc3_probe, +};

On 09/28/2017 03:01 PM, Masahiro Yamada wrote:
Add UniPhier platform specific glue layer to support USB3 Host mode on Synopsys DWC3 IP.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Reviewed-by: Marek Vasut marex@denx.de
[...]
+static int uniphier_pro4_dwc3_init(void __iomem *regs) +{
- u32 tmp;
- tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
- tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS;
- tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
- writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
Do I even want to nag you about clrsetbits_le32() or not ? What do you think?
- return 0;
+}
+static int uniphier_pro5_dwc3_init(void __iomem *regs) +{
- u32 tmp;
- tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
- tmp &= ~(UNIPHIER_PRO5_DWC3_RESET_PHY_S1 |
UNIPHIER_PRO5_DWC3_RESET_PHY_S0);
- tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
- writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
- return 0;
+}
+static int uniphier_pxs2_dwc3_init(void __iomem *regs) +{
- u32 tmp;
- tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
- tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
- writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
- return 0;
+}
+static int uniphier_dwc3_probe(struct udevice *dev) +{
- fdt_addr_t base;
- void __iomem *regs;
- int (*init)(void __iomem *regs);
- int ret;
- base = devfdt_get_addr(dev);
- if (base == FDT_ADDR_T_NONE)
return -EINVAL;
- regs = ioremap(base, SZ_32K);
- if (!regs)
return -ENOMEM;
- init = (typeof(init))dev_get_driver_data(dev);
- ret = init(regs);
- if (ret)
dev_err(dev, "failed to init glue layer\n");
- iounmap(regs);
- return ret;
+}
+static const struct udevice_id uniphier_dwc3_match[] = {
- {
.compatible = "socionext,uniphier-pro4-dwc3",
.data = (ulong)uniphier_pro4_dwc3_init,
- },
- {
.compatible = "socionext,uniphier-pro5-dwc3",
.data = (ulong)uniphier_pro5_dwc3_init,
- },
- {
.compatible = "socionext,uniphier-pxs2-dwc3",
.data = (ulong)uniphier_pxs2_dwc3_init,
- },
- {
.compatible = "socionext,uniphier-ld20-dwc3",
.data = (ulong)uniphier_pxs2_dwc3_init,
- },
- {
.compatible = "socionext,uniphier-pxs3-dwc3",
.data = (ulong)uniphier_pxs2_dwc3_init,
- },
- { /* sentinel */ }
+};
+U_BOOT_DRIVER(usb_xhci) = {
- .name = "uniphier-dwc3",
- .id = UCLASS_SIMPLE_BUS,
- .of_match = uniphier_dwc3_match,
- .probe = uniphier_dwc3_probe,
+};

Hi Marek,
2017-09-29 0:26 GMT+09:00 Marek Vasut marex@denx.de:
On 09/28/2017 03:01 PM, Masahiro Yamada wrote:
Add UniPhier platform specific glue layer to support USB3 Host mode on Synopsys DWC3 IP.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Reviewed-by: Marek Vasut marex@denx.de
[...]
+static int uniphier_pro4_dwc3_init(void __iomem *regs) +{
u32 tmp;
tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS;
tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
Do I even want to nag you about clrsetbits_le32() or not ? What do you think?
I did not know this macro.
This seems to come from PPC Linux (defined in arch/powerpc/include/asm/io.h) probably in order to abstract the endianness.
Of course, it makes drivers ppc-specific, disabling COMPILE_TEST coverage.
In U-Boot, more architectures support this macro, ARM as well. (probably people wanted to write the code shorter?)
I am reluctant with it because I do not want to diverge from Linux.

On 09/29/2017 03:31 AM, Masahiro Yamada wrote:
Hi Marek,
2017-09-29 0:26 GMT+09:00 Marek Vasut marex@denx.de:
On 09/28/2017 03:01 PM, Masahiro Yamada wrote:
Add UniPhier platform specific glue layer to support USB3 Host mode on Synopsys DWC3 IP.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Reviewed-by: Marek Vasut marex@denx.de
[...]
+static int uniphier_pro4_dwc3_init(void __iomem *regs) +{
u32 tmp;
tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS;
tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
Do I even want to nag you about clrsetbits_le32() or not ? What do you think?
I did not know this macro.
This seems to come from PPC Linux (defined in arch/powerpc/include/asm/io.h) probably in order to abstract the endianness.
Of course, it makes drivers ppc-specific, disabling COMPILE_TEST coverage.
In U-Boot, more architectures support this macro, ARM as well. (probably people wanted to write the code shorter?)
I am reluctant with it because I do not want to diverge from Linux.
OK, then applied.

On Fri, Sep 29, 2017 at 10:31:53AM +0900, Masahiro Yamada wrote:
Hi Marek,
2017-09-29 0:26 GMT+09:00 Marek Vasut marex@denx.de:
On 09/28/2017 03:01 PM, Masahiro Yamada wrote:
Add UniPhier platform specific glue layer to support USB3 Host mode on Synopsys DWC3 IP.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Reviewed-by: Marek Vasut marex@denx.de
[...]
+static int uniphier_pro4_dwc3_init(void __iomem *regs) +{
u32 tmp;
tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS;
tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
Do I even want to nag you about clrsetbits_le32() or not ? What do you think?
I did not know this macro.
This seems to come from PPC Linux (defined in arch/powerpc/include/asm/io.h) probably in order to abstract the endianness.
Of course, it makes drivers ppc-specific, disabling COMPILE_TEST coverage.
In U-Boot, more architectures support this macro, ARM as well. (probably people wanted to write the code shorter?)
I am reluctant with it because I do not want to diverge from Linux.
This is one of those funny cases where perhaps some generic shuffling of code in Linux might help? Having whacked things for sandbox this morning in https://patchwork.ozlabs.org/patch/819919/ and looking at drivers/crypto/caam/regs.h in the kernel now, it's either a helpful thing that should be more widely available / used (drop it into say include/asm-generic/io.h) or time has moved on, and there's a better convention to use now. Just a thought.
participants (3)
-
Marek Vasut
-
Masahiro Yamada
-
Tom Rini