diff options
author | Masahiro Yamada <yamada.m@jp.panasonic.com> | 2015-02-27 02:27:00 +0900 |
---|---|---|
committer | Masahiro Yamada <yamada.m@jp.panasonic.com> | 2015-03-01 00:03:00 +0900 |
commit | 1e7df7c4e4a1ad12b764c55369c313c1731dc4e8 (patch) | |
tree | e9459d0595006ff828854ca3e8bd1ec91809fcfb /drivers/usb/host/xhci-uniphier.c | |
parent | de01a768f079ddfdf3c0fa6372658972081e916c (diff) | |
download | u-boot-imx-1e7df7c4e4a1ad12b764c55369c313c1731dc4e8.zip u-boot-imx-1e7df7c4e4a1ad12b764c55369c313c1731dc4e8.tar.gz u-boot-imx-1e7df7c4e4a1ad12b764c55369c313c1731dc4e8.tar.bz2 |
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>
Diffstat (limited to 'drivers/usb/host/xhci-uniphier.c')
-rw-r--r-- | drivers/usb/host/xhci-uniphier.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-uniphier.c b/drivers/usb/host/xhci-uniphier.c new file mode 100644 index 0000000..08b15e0 --- /dev/null +++ b/drivers/usb/host/xhci-uniphier.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@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" + +static int get_uniphier_xhci_base(int index, struct xhci_hccr **base) +{ + DECLARE_GLOBAL_DATA_PTR; + int node_list[2]; + fdt_addr_t addr; + int count; + + count = fdtdec_find_aliases_for_id(gd->fdt_blob, "usb", + COMPAT_PANASONIC_XHCI, node_list, + ARRAY_SIZE(node_list)); + + if (index >= count) + return -ENODEV; + + addr = fdtdec_get_addr(gd->fdt_blob, node_list[index], "reg"); + if (addr == FDT_ADDR_T_NONE) + return -ENODEV; + + *base = (struct xhci_hccr *)addr; + + return 0; +} + +#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); +} |