[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