usb: dwc3-uniphier: replace <common.h> with <linux/bitops.h>
[platform/kernel/u-boot.git] / drivers / usb / dwc3 / dwc3-uniphier.c
1 /*
2  * UniPhier Specific Glue Layer for DWC3
3  *
4  * Copyright (C) 2016-2017 Socionext Inc.
5  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include <dm.h>
11 #include <linux/bitops.h>
12 #include <linux/errno.h>
13 #include <linux/io.h>
14 #include <linux/sizes.h>
15
16 #define UNIPHIER_PRO4_DWC3_RESET        0x40
17 #define   UNIPHIER_PRO4_DWC3_RESET_XIOMMU       BIT(5)
18 #define   UNIPHIER_PRO4_DWC3_RESET_XLINK        BIT(4)
19 #define   UNIPHIER_PRO4_DWC3_RESET_PHY_SS       BIT(2)
20
21 #define UNIPHIER_PRO5_DWC3_RESET        0x00
22 #define   UNIPHIER_PRO5_DWC3_RESET_PHY_S1       BIT(17)
23 #define   UNIPHIER_PRO5_DWC3_RESET_PHY_S0       BIT(16)
24 #define   UNIPHIER_PRO5_DWC3_RESET_XLINK        BIT(15)
25 #define   UNIPHIER_PRO5_DWC3_RESET_XIOMMU       BIT(14)
26
27 #define UNIPHIER_PXS2_DWC3_RESET        0x00
28 #define   UNIPHIER_PXS2_DWC3_RESET_XLINK        BIT(15)
29
30 static int uniphier_pro4_dwc3_init(void __iomem *regs)
31 {
32         u32 tmp;
33
34         tmp = readl(regs + UNIPHIER_PRO4_DWC3_RESET);
35         tmp &= ~UNIPHIER_PRO4_DWC3_RESET_PHY_SS;
36         tmp |= UNIPHIER_PRO4_DWC3_RESET_XIOMMU | UNIPHIER_PRO4_DWC3_RESET_XLINK;
37         writel(tmp, regs + UNIPHIER_PRO4_DWC3_RESET);
38
39         return 0;
40 }
41
42 static int uniphier_pro5_dwc3_init(void __iomem *regs)
43 {
44         u32 tmp;
45
46         tmp = readl(regs + UNIPHIER_PRO5_DWC3_RESET);
47         tmp &= ~(UNIPHIER_PRO5_DWC3_RESET_PHY_S1 |
48                  UNIPHIER_PRO5_DWC3_RESET_PHY_S0);
49         tmp |= UNIPHIER_PRO5_DWC3_RESET_XLINK | UNIPHIER_PRO5_DWC3_RESET_XIOMMU;
50         writel(tmp, regs + UNIPHIER_PRO5_DWC3_RESET);
51
52         return 0;
53 }
54
55 static int uniphier_pxs2_dwc3_init(void __iomem *regs)
56 {
57         u32 tmp;
58
59         tmp = readl(regs + UNIPHIER_PXS2_DWC3_RESET);
60         tmp |= UNIPHIER_PXS2_DWC3_RESET_XLINK;
61         writel(tmp, regs + UNIPHIER_PXS2_DWC3_RESET);
62
63         return 0;
64 }
65
66 static int uniphier_dwc3_probe(struct udevice *dev)
67 {
68         fdt_addr_t base;
69         void __iomem *regs;
70         int (*init)(void __iomem *regs);
71         int ret;
72
73         base = devfdt_get_addr(dev);
74         if (base == FDT_ADDR_T_NONE)
75                 return -EINVAL;
76
77         regs = ioremap(base, SZ_32K);
78         if (!regs)
79                 return -ENOMEM;
80
81         init = (typeof(init))dev_get_driver_data(dev);
82         ret = init(regs);
83         if (ret)
84                 dev_err(dev, "failed to init glue layer\n");
85
86         iounmap(regs);
87
88         return ret;
89 }
90
91 static const struct udevice_id uniphier_dwc3_match[] = {
92         {
93                 .compatible = "socionext,uniphier-pro4-dwc3",
94                 .data = (ulong)uniphier_pro4_dwc3_init,
95         },
96         {
97                 .compatible = "socionext,uniphier-pro5-dwc3",
98                 .data = (ulong)uniphier_pro5_dwc3_init,
99         },
100         {
101                 .compatible = "socionext,uniphier-pxs2-dwc3",
102                 .data = (ulong)uniphier_pxs2_dwc3_init,
103         },
104         {
105                 .compatible = "socionext,uniphier-ld20-dwc3",
106                 .data = (ulong)uniphier_pxs2_dwc3_init,
107         },
108         {
109                 .compatible = "socionext,uniphier-pxs3-dwc3",
110                 .data = (ulong)uniphier_pxs2_dwc3_init,
111         },
112         { /* sentinel */ }
113 };
114
115 U_BOOT_DRIVER(usb_xhci) = {
116         .name = "uniphier-dwc3",
117         .id = UCLASS_SIMPLE_BUS,
118         .of_match = uniphier_dwc3_match,
119         .probe = uniphier_dwc3_probe,
120 };