blob: 54b52dcd66a9f004ca862ca549012796288fc1e2 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Masahiro Yamadaa50bab32017-09-28 22:01:00 +09002/*
3 * UniPhier Specific Glue Layer for DWC3
4 *
5 * Copyright (C) 2016-2017 Socionext Inc.
6 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
Masahiro Yamadaa50bab32017-09-28 22:01:00 +09007 */
8
Masahiro Yamadaa50bab32017-09-28 22:01:00 +09009#include <dm.h>
Simon Glass9bc15642020-02-03 07:36:16 -070010#include <dm/device_compat.h>
Masahiro Yamada0da3db92017-10-13 19:21:56 +090011#include <linux/bitops.h>
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090012#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
30static 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
42static 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
55static 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
66static 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
Masahiro Yamadaa89b4de2020-07-17 14:36:48 +090073 base = dev_read_addr(dev);
Masahiro Yamadaa50bab32017-09-28 22:01:00 +090074 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
91static 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
115U_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};