]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/usb/host/xhci-uniphier.c
usb: ohci: enable cache support
[karo-tx-uboot.git] / drivers / usb / host / xhci-uniphier.c
1 /*
2  * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <linux/err.h>
9 #include <linux/io.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_SOCIONEXT_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 }