diff mbox series

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

Message ID 1506603660-10408-1-git-send-email-yamada.masahiro@socionext.com
State Accepted
Commit dc04b35ef2c8c04cb362758ec467777348ef3f15
Delegated to: Marek Vasut
Headers show
Series [U-Boot] usb: dwc3: add UniPhier specific glue layer | expand

Commit Message

Masahiro Yamada Sept. 28, 2017, 1:01 p.m. UTC
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

Comments

Marek Vasut Sept. 28, 2017, 3:26 p.m. UTC | #1
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,
> +};
>
Masahiro Yamada Sept. 29, 2017, 1:31 a.m. UTC | #2
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.
Marek Vasut Sept. 29, 2017, 2:31 a.m. UTC | #3
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.
Tom Rini Sept. 29, 2017, 2:45 p.m. UTC | #4
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.
diff mbox series

Patch

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,
+};