[U-Boot] [PATCH 11/14] usb: UniPhier: add UniPhier on-chip xHCI host driver support
Simon Glass
sjg at chromium.org
Wed Feb 18 06:01:53 CET 2015
Hi Masahiro,
On 17 February 2015 at 00:00, Masahiro Yamada <yamada.m at jp.panasonic.com> wrote:
> Support xHCI host driver used on Panasonic UniPhier platform.
>
> Signed-off-by: Masahiro Yamada <yamada.m at jp.panasonic.com>
> ---
> Hi Marek,
>
> I want apply this patch onto u-boot-uniphier/master
> to avoid conflicts.
>
> If you are OK with it, could you issue your Acked-by tag, please?
>
> Thanks,
> Masahiro
>
>
> doc/README.uniphier | 3 +-
> drivers/usb/host/Kconfig | 8 ++++
> drivers/usb/host/Makefile | 1 +
> drivers/usb/host/xhci-uniphier.c | 85 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 96 insertions(+), 1 deletion(-)
> create mode 100644 drivers/usb/host/xhci-uniphier.c
>
> diff --git a/doc/README.uniphier b/doc/README.uniphier
> index aaeb50c..4902533 100644
> --- a/doc/README.uniphier
> +++ b/doc/README.uniphier
> @@ -73,7 +73,8 @@ Supported devices
>
> - UART (on-chip)
> - NAND
> - - USB (2.0)
> + - USB 2.0 (EHCI)
> + - USB 3.0 (xHCI)
> - LAN (on-board SMSC9118)
> - I2C
> - EEPROM (connected to the on-board I2C bus)
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 0e005c2..24a595f 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -17,6 +17,14 @@ config USB_XHCI
>
> if USB_XHCI_HCD
>
> +config USB_XHCI_UNIPHIER
> + bool "Support for Panasonic UniPhier on-chip xHCI USB controller"
> + depends on ARCH_UNIPHIER
> + default y
> + ---help---
> + Enables support for the on-chip xHCI controller on Panasonic
> + UniPhier SoCs.
> +
> endif
>
> config USB_EHCI_HCD
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 66d6e9a..eb6f34b 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -48,6 +48,7 @@ obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
> obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
> obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
> obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
> +obj-$(CONFIG_USB_XHCI_UNIPHIER) += xhci-uniphier.o
>
> # designware
> obj-$(CONFIG_USB_DWC2) += dwc2.o
> diff --git a/drivers/usb/host/xhci-uniphier.c b/drivers/usb/host/xhci-uniphier.c
> new file mode 100644
> index 0000000..9bbd65f
> --- /dev/null
> +++ b/drivers/usb/host/xhci-uniphier.c
> @@ -0,0 +1,85 @@
> +/*
> + * Copyright (C) 2015 Panasonic Corporation
> + * Author: Masahiro Yamada <yamada.m at jp.panasonic.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <linux/err.h>
> +#include <usb.h>
> +#include <fdtdec.h>
> +#include "xhci.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define FDT gd->fdt_blob
Ick, please don't do this. Just use a local variable if you like.
> +#define COMPAT "panasonic,uniphier-xhci"
This too.
> +
> +static int get_uniphier_xhci_base(int index, struct xhci_hccr **base)
> +{
> + int offset;
> +
> + for (offset = fdt_node_offset_by_compatible(FDT, 0, COMPAT);
> + offset >= 0;
> + offset = fdt_node_offset_by_compatible(FDT, offset, COMPAT)) {
> + if (index == 0) {
> + *base = (struct xhci_hccr *)
> + fdtdec_get_addr(FDT, offset, "reg");
> + return 0;
> + }
> + index--;
> + }
How about this"
count = fdtdec_find_aliasses_for_id(gd->fdt_blob, "usb",
COMPAT_PANASONIC_XHCI, node_list, 4);
if (index >= count)
return -ENOENT;
offset = node_list[index];
then aliases will work. You need to ad the COMPAT to
include/fdtdec.h/c. See ehci-tegra.c for an example.
> +
> + return -ENODEV; /* not found */
> +}
> +
> +#define USB3_RST_CTRL 0x00100040
> +#define IOMMU_RST_N (1 << 5)
> +#define LINK_RST_N (1 << 4)
> +
> +static void uniphier_xhci_reset(void __iomem *base, int on)
> +{
> + u32 tmp;
> +
> + tmp = readl(base + USB3_RST_CTRL);
> +
> + if (on)
> + tmp &= ~(IOMMU_RST_N | LINK_RST_N);
> + else
> + tmp |= IOMMU_RST_N | LINK_RST_N;
> +
> + writel(tmp, base + USB3_RST_CTRL);
> +}
> +
> +int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
> +{
> + int ret;
> + struct xhci_hccr *cr;
> + struct xhci_hcor *or;
> +
> + ret = get_uniphier_xhci_base(index, &cr);
> + if (ret < 0)
> + return ret;
> +
> + uniphier_xhci_reset(cr, 0);
> +
> + or = (void *)cr + HC_LENGTH(xhci_readl(&cr->cr_capbase));
> +
> + *hccr = cr;
> + *hcor = or;
> +
> + return 0;
> +}
> +
> +void xhci_hcd_stop(int index)
> +{
> + int ret;
> + struct xhci_hccr *cr;
> +
> + ret = get_uniphier_xhci_base(index, &cr);
> + if (ret < 0)
> + return;
> +
> + uniphier_xhci_reset(cr, 1);
> +}
> --
> 1.9.1
>
Regards,
Simon
More information about the U-Boot
mailing list