Commit 1e7df7c4e4a1ad12b764c55369c313c1731dc4e8

Authored by Masahiro Yamada
1 parent de01a768f0

usb: UniPhier: add UniPhier on-chip xHCI host driver support

Support xHCI host driver used on Panasonic UniPhier platform.

Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
Acked-by: Marek Vasut <marex@denx.de>

Showing 6 changed files with 98 additions and 1 deletions Side-by-side Diff

... ... @@ -73,7 +73,8 @@
73 73  
74 74 - UART (on-chip)
75 75 - NAND
76   - - USB (2.0)
  76 + - USB 2.0 (EHCI)
  77 + - USB 3.0 (xHCI)
77 78 - LAN (on-board SMSC9118)
78 79 - I2C
79 80 - EEPROM (connected to the on-board I2C bus)
drivers/usb/host/Kconfig
... ... @@ -17,6 +17,14 @@
17 17  
18 18 if USB_XHCI_HCD
19 19  
  20 +config USB_XHCI_UNIPHIER
  21 + bool "Support for Panasonic UniPhier on-chip xHCI USB controller"
  22 + depends on ARCH_UNIPHIER
  23 + default y
  24 + ---help---
  25 + Enables support for the on-chip xHCI controller on Panasonic
  26 + UniPhier SoCs.
  27 +
20 28 endif
21 29  
22 30 config USB_EHCI_HCD
drivers/usb/host/Makefile
... ... @@ -48,6 +48,7 @@
48 48 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
49 49 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
50 50 obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
  51 +obj-$(CONFIG_USB_XHCI_UNIPHIER) += xhci-uniphier.o
51 52  
52 53 # designware
53 54 obj-$(CONFIG_USB_DWC2) += dwc2.o
drivers/usb/host/xhci-uniphier.c
  1 +/*
  2 + * Copyright (C) 2015 Panasonic Corporation
  3 + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
  4 + *
  5 + * SPDX-License-Identifier: GPL-2.0+
  6 + */
  7 +
  8 +#include <common.h>
  9 +#include <linux/err.h>
  10 +#include <usb.h>
  11 +#include <fdtdec.h>
  12 +#include "xhci.h"
  13 +
  14 +static int get_uniphier_xhci_base(int index, struct xhci_hccr **base)
  15 +{
  16 + DECLARE_GLOBAL_DATA_PTR;
  17 + int node_list[2];
  18 + fdt_addr_t addr;
  19 + int count;
  20 +
  21 + count = fdtdec_find_aliases_for_id(gd->fdt_blob, "usb",
  22 + COMPAT_PANASONIC_XHCI, node_list,
  23 + ARRAY_SIZE(node_list));
  24 +
  25 + if (index >= count)
  26 + return -ENODEV;
  27 +
  28 + addr = fdtdec_get_addr(gd->fdt_blob, node_list[index], "reg");
  29 + if (addr == FDT_ADDR_T_NONE)
  30 + return -ENODEV;
  31 +
  32 + *base = (struct xhci_hccr *)addr;
  33 +
  34 + return 0;
  35 +}
  36 +
  37 +#define USB3_RST_CTRL 0x00100040
  38 +#define IOMMU_RST_N (1 << 5)
  39 +#define LINK_RST_N (1 << 4)
  40 +
  41 +static void uniphier_xhci_reset(void __iomem *base, int on)
  42 +{
  43 + u32 tmp;
  44 +
  45 + tmp = readl(base + USB3_RST_CTRL);
  46 +
  47 + if (on)
  48 + tmp &= ~(IOMMU_RST_N | LINK_RST_N);
  49 + else
  50 + tmp |= IOMMU_RST_N | LINK_RST_N;
  51 +
  52 + writel(tmp, base + USB3_RST_CTRL);
  53 +}
  54 +
  55 +int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
  56 +{
  57 + int ret;
  58 + struct xhci_hccr *cr;
  59 + struct xhci_hcor *or;
  60 +
  61 + ret = get_uniphier_xhci_base(index, &cr);
  62 + if (ret < 0)
  63 + return ret;
  64 +
  65 + uniphier_xhci_reset(cr, 0);
  66 +
  67 + or = (void *)cr + HC_LENGTH(xhci_readl(&cr->cr_capbase));
  68 +
  69 + *hccr = cr;
  70 + *hcor = or;
  71 +
  72 + return 0;
  73 +}
  74 +
  75 +void xhci_hcd_stop(int index)
  76 +{
  77 + int ret;
  78 + struct xhci_hccr *cr;
  79 +
  80 + ret = get_uniphier_xhci_base(index, &cr);
  81 + if (ret < 0)
  82 + return;
  83 +
  84 + uniphier_xhci_reset(cr, 1);
  85 +}
... ... @@ -168,6 +168,7 @@
168 168 COMPAT_AMS_AS3722, /* AMS AS3722 PMIC */
169 169 COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */
170 170 COMPAT_INTEL_QRK_MRC, /* Intel Quark MRC */
  171 + COMPAT_PANASONIC_XHCI, /* Panasonic UniPhier xHCI */
171 172  
172 173 COMPAT_COUNT,
173 174 };
... ... @@ -76,6 +76,7 @@
76 76 COMPAT(AMS_AS3722, "ams,as3722"),
77 77 COMPAT(INTEL_ICH_SPI, "intel,ich-spi"),
78 78 COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
  79 + COMPAT(PANASONIC_XHCI, "panasonic,uniphier-xhci"),
79 80 };
80 81  
81 82 const char *fdtdec_get_compatible(enum fdt_compat_id id)