Commit 1e7df7c4e4a1ad12b764c55369c313c1731dc4e8
1 parent
de01a768f0
Exists in
v2017.01-smarct4x
and in
37 other branches
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
doc/README.uniphier
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
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 | +} |
include/fdtdec.h
lib/fdtdec.c