blob: f3f181dae0101645b54a4d61648faa4ef8e2769e [file] [log] [blame]
Chunfeng Yun74102832020-05-02 11:35:18 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2019 MediaTek, Inc.
4 * Authors: Chunfeng Yun <chunfeng.yun@mediatek.com>
5 */
6
7#include <clk.h>
8#include <common.h>
9#include <dm.h>
10#include <dm/devres.h>
11#include <generic-phy.h>
12#include <malloc.h>
13#include <usb.h>
14#include <linux/errno.h>
15#include <linux/compat.h>
16#include <power/regulator.h>
17#include <linux/iopoll.h>
18#include <usb/xhci.h>
19
20/* IPPC (IP Port Control) registers */
21#define IPPC_IP_PW_CTRL0 0x00
22#define CTRL0_IP_SW_RST BIT(0)
23
24#define IPPC_IP_PW_CTRL1 0x04
25#define CTRL1_IP_HOST_PDN BIT(0)
26
27#define IPPC_IP_PW_STS1 0x10
28#define STS1_IP_SLEEP_STS BIT(30)
29#define STS1_U3_MAC_RST BIT(16)
30#define STS1_XHCI_RST BIT(11)
31#define STS1_SYS125_RST BIT(10)
32#define STS1_REF_RST BIT(8)
33#define STS1_SYSPLL_STABLE BIT(0)
34
35#define IPPC_IP_XHCI_CAP 0x24
36#define CAP_U3_PORT_NUM(p) ((p) & 0xff)
37#define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff)
38
39#define IPPC_U3_CTRL_0P 0x30
40#define CTRL_U3_PORT_HOST_SEL BIT(2)
41#define CTRL_U3_PORT_PDN BIT(1)
42#define CTRL_U3_PORT_DIS BIT(0)
43
44#define IPPC_U2_CTRL_0P 0x50
45#define CTRL_U2_PORT_HOST_SEL BIT(2)
46#define CTRL_U2_PORT_PDN BIT(1)
47#define CTRL_U2_PORT_DIS BIT(0)
48
49#define IPPC_U3_CTRL(p) (IPPC_U3_CTRL_0P + ((p) * 0x08))
50#define IPPC_U2_CTRL(p) (IPPC_U2_CTRL_0P + ((p) * 0x08))
51
52struct mtk_xhci {
53 struct xhci_ctrl ctrl; /* Needs to come first in this struct! */
54 struct xhci_hccr *hcd;
55 void __iomem *ippc;
56 struct udevice *dev;
57 struct udevice *vusb33_supply;
58 struct udevice *vbus_supply;
59 struct clk_bulk clks;
60 struct phy_bulk phys;
61 int num_u2ports;
62 int num_u3ports;
63};
64
65static int xhci_mtk_host_enable(struct mtk_xhci *mtk)
66{
67 u32 value;
68 u32 check_val;
69 int ret;
70 int i;
71
72 /* power on host ip */
73 clrbits_le32(mtk->ippc + IPPC_IP_PW_CTRL1, CTRL1_IP_HOST_PDN);
74
75 /* power on and enable all u3 ports */
76 for (i = 0; i < mtk->num_u3ports; i++) {
77 clrsetbits_le32(mtk->ippc + IPPC_U3_CTRL(i),
78 CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS,
79 CTRL_U3_PORT_HOST_SEL);
80 }
81
82 /* power on and enable all u2 ports */
83 for (i = 0; i < mtk->num_u2ports; i++) {
84 clrsetbits_le32(mtk->ippc + IPPC_U2_CTRL(i),
85 CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS,
86 CTRL_U2_PORT_HOST_SEL);
87 }
88
89 /*
90 * wait for clocks to be stable, and clock domains reset to
91 * be inactive after power on and enable ports
92 */
93 check_val = STS1_SYSPLL_STABLE | STS1_REF_RST |
94 STS1_SYS125_RST | STS1_XHCI_RST;
95
96 if (mtk->num_u3ports)
97 check_val |= STS1_U3_MAC_RST;
98
99 ret = readl_poll_timeout(mtk->ippc + IPPC_IP_PW_STS1, value,
100 (check_val == (value & check_val)), 20000);
101 if (ret)
102 dev_err(mtk->dev, "clocks are not stable 0x%x!\n", value);
103
104 return ret;
105}
106
107static int xhci_mtk_host_disable(struct mtk_xhci *mtk)
108{
109 int i;
110
111 /* power down all u3 ports */
112 for (i = 0; i < mtk->num_u3ports; i++)
113 setbits_le32(mtk->ippc + IPPC_U3_CTRL(i), CTRL_U3_PORT_PDN);
114
115 /* power down all u2 ports */
116 for (i = 0; i < mtk->num_u2ports; i++)
117 setbits_le32(mtk->ippc + IPPC_U2_CTRL(i), CTRL_U2_PORT_PDN);
118
119 /* power down host ip */
120 setbits_le32(mtk->ippc + IPPC_IP_PW_CTRL1, CTRL1_IP_HOST_PDN);
121
122 return 0;
123}
124
125static int xhci_mtk_ssusb_init(struct mtk_xhci *mtk)
126{
127 u32 value;
128
129 /* reset whole ip */
130 setbits_le32(mtk->ippc + IPPC_IP_PW_CTRL0, CTRL0_IP_SW_RST);
131 udelay(1);
132 clrbits_le32(mtk->ippc + IPPC_IP_PW_CTRL0, CTRL0_IP_SW_RST);
133
134 value = readl(mtk->ippc + IPPC_IP_XHCI_CAP);
135 mtk->num_u3ports = CAP_U3_PORT_NUM(value);
136 mtk->num_u2ports = CAP_U2_PORT_NUM(value);
137 dev_info(mtk->dev, "u2p:%d, u3p:%d\n",
138 mtk->num_u2ports, mtk->num_u3ports);
139
140 return xhci_mtk_host_enable(mtk);
141}
142
143static int xhci_mtk_ofdata_get(struct mtk_xhci *mtk)
144{
145 struct udevice *dev = mtk->dev;
146 int ret = 0;
147
148 mtk->hcd = devfdt_remap_addr_name(dev, "mac");
149 if (!mtk->hcd) {
150 dev_err(dev, "failed to get xHCI base address\n");
151 return -ENXIO;
152 }
153
154 mtk->ippc = devfdt_remap_addr_name(dev, "ippc");
155 if (!mtk->ippc) {
156 dev_err(dev, "failed to get IPPC base address\n");
157 return -ENXIO;
158 }
159
160 dev_info(dev, "hcd: 0x%p, ippc: 0x%p\n", mtk->hcd, mtk->ippc);
161
162 ret = clk_get_bulk(dev, &mtk->clks);
163 if (ret) {
164 dev_err(dev, "failed to get clocks %d!\n", ret);
165 return ret;
166 }
167
168 ret = device_get_supply_regulator(dev, "vusb33-supply",
169 &mtk->vusb33_supply);
170 if (ret)
171 debug("can't get vusb33 regulator %d!\n", ret);
172
173 ret = device_get_supply_regulator(dev, "vbus-supply",
174 &mtk->vbus_supply);
175 if (ret)
176 debug("can't get vbus regulator %d!\n", ret);
177
178 return 0;
179}
180
181static int xhci_mtk_ldos_enable(struct mtk_xhci *mtk)
182{
183 int ret;
184
185 ret = regulator_set_enable(mtk->vusb33_supply, true);
186 if (ret < 0 && ret != -ENOSYS) {
187 dev_err(mtk->dev, "failed to enable vusb33 %d!\n", ret);
188 return ret;
189 }
190
191 ret = regulator_set_enable(mtk->vbus_supply, true);
192 if (ret < 0 && ret != -ENOSYS) {
193 dev_err(mtk->dev, "failed to enable vbus %d!\n", ret);
194 regulator_set_enable(mtk->vusb33_supply, false);
195 return ret;
196 }
197
198 return 0;
199}
200
201static void xhci_mtk_ldos_disable(struct mtk_xhci *mtk)
202{
203 regulator_set_enable(mtk->vbus_supply, false);
204 regulator_set_enable(mtk->vusb33_supply, false);
205}
206
207static int xhci_mtk_phy_setup(struct mtk_xhci *mtk)
208{
209 struct udevice *dev = mtk->dev;
210 struct phy_bulk *phys = &mtk->phys;
211 int ret;
212
213 ret = generic_phy_get_bulk(dev, phys);
214 if (ret)
215 return ret;
216
217 ret = generic_phy_init_bulk(phys);
218 if (ret)
219 return ret;
220
221 ret = generic_phy_power_on_bulk(phys);
222 if (ret)
223 generic_phy_exit_bulk(phys);
224
225 return ret;
226}
227
228static void xhci_mtk_phy_shutdown(struct mtk_xhci *mtk)
229{
230 generic_phy_power_off_bulk(&mtk->phys);
231 generic_phy_exit_bulk(&mtk->phys);
232}
233
234static int xhci_mtk_probe(struct udevice *dev)
235{
236 struct mtk_xhci *mtk = dev_get_priv(dev);
237 struct xhci_hcor *hcor;
238 int ret;
239
240 mtk->dev = dev;
241 ret = xhci_mtk_ofdata_get(mtk);
242 if (ret)
243 return ret;
244
245 ret = xhci_mtk_ldos_enable(mtk);
246 if (ret)
247 goto ldos_err;
248
249 ret = clk_enable_bulk(&mtk->clks);
250 if (ret)
251 goto clks_err;
252
253 ret = xhci_mtk_phy_setup(mtk);
254 if (ret)
255 goto phys_err;
256
257 ret = xhci_mtk_ssusb_init(mtk);
258 if (ret)
259 goto ssusb_init_err;
260
Chunfeng Yun74082052020-09-08 18:59:57 +0200261 mtk->ctrl.quirks = XHCI_MTK_HOST;
Chunfeng Yun74102832020-05-02 11:35:18 +0200262 hcor = (struct xhci_hcor *)((uintptr_t)mtk->hcd +
263 HC_LENGTH(xhci_readl(&mtk->hcd->cr_capbase)));
264
265 return xhci_register(dev, mtk->hcd, hcor);
266
267ssusb_init_err:
268 xhci_mtk_phy_shutdown(mtk);
269phys_err:
270 clk_disable_bulk(&mtk->clks);
271clks_err:
272 xhci_mtk_ldos_disable(mtk);
273ldos_err:
274 return ret;
275}
276
277static int xhci_mtk_remove(struct udevice *dev)
278{
279 struct mtk_xhci *mtk = dev_get_priv(dev);
280
281 xhci_deregister(dev);
282 xhci_mtk_host_disable(mtk);
283 xhci_mtk_ldos_disable(mtk);
284 clk_disable_bulk(&mtk->clks);
285
286 return 0;
287}
288
289static const struct udevice_id xhci_mtk_ids[] = {
290 { .compatible = "mediatek,mtk-xhci" },
291 { }
292};
293
294U_BOOT_DRIVER(usb_xhci) = {
295 .name = "xhci-mtk",
296 .id = UCLASS_USB,
297 .of_match = xhci_mtk_ids,
298 .probe = xhci_mtk_probe,
299 .remove = xhci_mtk_remove,
300 .ops = &xhci_usb_ops,
301 .bind = dm_scan_fdt_dev,
302 .priv_auto_alloc_size = sizeof(struct mtk_xhci),
303 .flags = DM_FLAG_ALLOC_PRIV_DMA,
304};