diff options
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r-- | drivers/usb/dwc3/Kconfig | 7 | ||||
-rw-r--r-- | drivers/usb/dwc3/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-uniphier.c | 120 | ||||
-rw-r--r-- | drivers/usb/dwc3/linux-compat.h | 2 |
4 files changed, 128 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index a291ceb6ae..ae7fc1c630 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 2964bae0d8..51497768b2 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 0000000000..25b17a85d0 --- /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 <dm.h> +#include <linux/bitops.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, +}; diff --git a/drivers/usb/dwc3/linux-compat.h b/drivers/usb/dwc3/linux-compat.h index 9e944a31be..5cbe377e3c 100644 --- a/drivers/usb/dwc3/linux-compat.h +++ b/drivers/usb/dwc3/linux-compat.h @@ -12,10 +12,8 @@ #ifndef __DWC3_LINUX_COMPAT__ #define __DWC3_LINUX_COMPAT__ -#define pr_debug(format) debug(format) #define WARN(val, format, arg...) debug(format, ##arg) #define dev_WARN(dev, format, arg...) debug(format, ##arg) -#define WARN_ON_ONCE(val) debug("Error %d\n", val) static inline size_t strlcat(char *dest, const char *src, size_t n) { |