usb: cdns3: Add Cadence USB3 DRD Driver
[linux-2.6-microblaze.git] / drivers / usb / cdns3 / drd.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Cadence USBSS DRD Driver.
4  *
5  * Copyright (C) 2018-2019 Cadence.
6  * Copyright (C) 2019 Texas Instruments
7  *
8  * Author: Pawel Laszczak <pawell@cadence.com>
9  *         Roger Quadros <rogerq@ti.com>
10  *
11  *
12  */
13 #include <linux/kernel.h>
14 #include <linux/interrupt.h>
15 #include <linux/delay.h>
16 #include <linux/iopoll.h>
17 #include <linux/usb/otg.h>
18
19 #include "gadget.h"
20 #include "drd.h"
21 #include "core.h"
22
23 /**
24  * cdns3_set_mode - change mode of OTG Core
25  * @cdns: pointer to context structure
26  * @mode: selected mode from cdns_role
27  *
28  * Returns 0 on success otherwise negative errno
29  */
30 int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode)
31 {
32         int ret = 0;
33         u32 reg;
34
35         switch (mode) {
36         case USB_DR_MODE_PERIPHERAL:
37                 break;
38         case USB_DR_MODE_HOST:
39                 break;
40         case USB_DR_MODE_OTG:
41                 dev_dbg(cdns->dev, "Set controller to OTG mode\n");
42                 if (cdns->version == CDNS3_CONTROLLER_V1) {
43                         reg = readl(&cdns->otg_v1_regs->override);
44                         reg |= OVERRIDE_IDPULLUP;
45                         writel(reg, &cdns->otg_v1_regs->override);
46                 } else {
47                         reg = readl(&cdns->otg_v0_regs->ctrl1);
48                         reg |= OVERRIDE_IDPULLUP_V0;
49                         writel(reg, &cdns->otg_v0_regs->ctrl1);
50                 }
51
52                 /*
53                  * Hardware specification says: "ID_VALUE must be valid within
54                  * 50ms after idpullup is set to '1" so driver must wait
55                  * 50ms before reading this pin.
56                  */
57                 usleep_range(50000, 60000);
58                 break;
59         default:
60                 dev_err(cdns->dev, "Unsupported mode of operation %d\n", mode);
61                 return -EINVAL;
62         }
63
64         return ret;
65 }
66
67 int cdns3_get_id(struct cdns3 *cdns)
68 {
69         int id;
70
71         id = readl(&cdns->otg_regs->sts) & OTGSTS_ID_VALUE;
72         dev_dbg(cdns->dev, "OTG ID: %d", id);
73
74         return id;
75 }
76
77 int cdns3_get_vbus(struct cdns3 *cdns)
78 {
79         int vbus;
80
81         vbus = !!(readl(&cdns->otg_regs->sts) & OTGSTS_VBUS_VALID);
82         dev_dbg(cdns->dev, "OTG VBUS: %d", vbus);
83
84         return vbus;
85 }
86
87 int cdns3_is_host(struct cdns3 *cdns)
88 {
89         if (cdns->dr_mode == USB_DR_MODE_HOST)
90                 return 1;
91         else if (!cdns3_get_id(cdns))
92                 return 1;
93
94         return 0;
95 }
96
97 int cdns3_is_device(struct cdns3 *cdns)
98 {
99         if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL)
100                 return 1;
101         else if (cdns->dr_mode == USB_DR_MODE_OTG)
102                 if (cdns3_get_id(cdns))
103                         return 1;
104
105         return 0;
106 }
107
108 /**
109  * cdns3_otg_disable_irq - Disable all OTG interrupts
110  * @cdns: Pointer to controller context structure
111  */
112 static void cdns3_otg_disable_irq(struct cdns3 *cdns)
113 {
114         writel(0, &cdns->otg_regs->ien);
115 }
116
117 /**
118  * cdns3_otg_enable_irq - enable id and sess_valid interrupts
119  * @cdns: Pointer to controller context structure
120  */
121 static void cdns3_otg_enable_irq(struct cdns3 *cdns)
122 {
123         writel(OTGIEN_ID_CHANGE_INT | OTGIEN_VBUSVALID_RISE_INT |
124                OTGIEN_VBUSVALID_FALL_INT, &cdns->otg_regs->ien);
125 }
126
127 /**
128  * cdns3_drd_switch_host - start/stop host
129  * @cdns: Pointer to controller context structure
130  * @on: 1 for start, 0 for stop
131  *
132  * Returns 0 on success otherwise negative errno
133  */
134 int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
135 {
136         int ret, val;
137         u32 reg = OTGCMD_OTG_DIS;
138
139         /* switch OTG core */
140         if (on) {
141                 writel(OTGCMD_HOST_BUS_REQ | reg, &cdns->otg_regs->cmd);
142
143                 dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
144                 ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
145                                                 val & OTGSTS_XHCI_READY,
146                                                 1, 100000);
147                 if (ret) {
148                         dev_err(cdns->dev, "timeout waiting for xhci_ready\n");
149                         return ret;
150                 }
151         } else {
152                 writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
153                        OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
154                        &cdns->otg_regs->cmd);
155                 /* Waiting till H_IDLE state.*/
156                 readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
157                                           !(val & OTGSTATE_HOST_STATE_MASK),
158                                           1, 2000000);
159         }
160
161         return 0;
162 }
163
164 /**
165  * cdns3_drd_switch_gadget - start/stop gadget
166  * @cdns: Pointer to controller context structure
167  * @on: 1 for start, 0 for stop
168  *
169  * Returns 0 on success otherwise negative errno
170  */
171 int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
172 {
173         int ret, val;
174         u32 reg = OTGCMD_OTG_DIS;
175
176         /* switch OTG core */
177         if (on) {
178                 writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);
179
180                 dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
181
182                 ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
183                                                 val & OTGSTS_DEV_READY,
184                                                 1, 100000);
185                 if (ret) {
186                         dev_err(cdns->dev, "timeout waiting for dev_ready\n");
187                         return ret;
188                 }
189         } else {
190                 /*
191                  * driver should wait at least 10us after disabling Device
192                  * before turning-off Device (DEV_BUS_DROP)
193                  */
194                 usleep_range(20, 30);
195                 writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
196                        OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
197                        &cdns->otg_regs->cmd);
198                 /* Waiting till DEV_IDLE state.*/
199                 readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
200                                           !(val & OTGSTATE_DEV_STATE_MASK),
201                                           1, 2000000);
202         }
203
204         return 0;
205 }
206
207 /**
208  * cdns3_init_otg_mode - initialize drd controller
209  * @cdns: Pointer to controller context structure
210  *
211  * Returns 0 on success otherwise negative errno
212  */
213 static int cdns3_init_otg_mode(struct cdns3 *cdns)
214 {
215         int ret = 0;
216
217         cdns3_otg_disable_irq(cdns);
218         /* clear all interrupts */
219         writel(~0, &cdns->otg_regs->ivect);
220
221         ret = cdns3_set_mode(cdns, USB_DR_MODE_OTG);
222         if (ret)
223                 return ret;
224
225         cdns3_otg_enable_irq(cdns);
226         return ret;
227 }
228
229 /**
230  * cdns3_drd_update_mode - initialize mode of operation
231  * @cdns: Pointer to controller context structure
232  *
233  * Returns 0 on success otherwise negative errno
234  */
235 int cdns3_drd_update_mode(struct cdns3 *cdns)
236 {
237         int ret = 0;
238
239         switch (cdns->dr_mode) {
240         case USB_DR_MODE_PERIPHERAL:
241                 ret = cdns3_set_mode(cdns, USB_DR_MODE_PERIPHERAL);
242                 break;
243         case USB_DR_MODE_HOST:
244                 ret = cdns3_set_mode(cdns, USB_DR_MODE_HOST);
245                 break;
246         case USB_DR_MODE_OTG:
247                 ret = cdns3_init_otg_mode(cdns);
248                 break;
249         default:
250                 dev_err(cdns->dev, "Unsupported mode of operation %d\n",
251                         cdns->dr_mode);
252                 return -EINVAL;
253         }
254
255         return ret;
256 }
257
258 static irqreturn_t cdns3_drd_thread_irq(int irq, void *data)
259 {
260         struct cdns3 *cdns = data;
261
262         cdns3_hw_role_switch(cdns);
263
264         return IRQ_HANDLED;
265 }
266
267 /**
268  * cdns3_drd_irq - interrupt handler for OTG events
269  *
270  * @irq: irq number for cdns3 core device
271  * @data: structure of cdns3
272  *
273  * Returns IRQ_HANDLED or IRQ_NONE
274  */
275 static irqreturn_t cdns3_drd_irq(int irq, void *data)
276 {
277         irqreturn_t ret = IRQ_NONE;
278         struct cdns3 *cdns = data;
279         u32 reg;
280
281         if (cdns->dr_mode != USB_DR_MODE_OTG)
282                 return ret;
283
284         reg = readl(&cdns->otg_regs->ivect);
285
286         if (!reg)
287                 return ret;
288
289         if (reg & OTGIEN_ID_CHANGE_INT) {
290                 dev_dbg(cdns->dev, "OTG IRQ: new ID: %d\n",
291                         cdns3_get_id(cdns));
292
293                 ret = IRQ_WAKE_THREAD;
294         }
295
296         if (reg & (OTGIEN_VBUSVALID_RISE_INT | OTGIEN_VBUSVALID_FALL_INT)) {
297                 dev_dbg(cdns->dev, "OTG IRQ: new VBUS: %d\n",
298                         cdns3_get_vbus(cdns));
299
300                 ret = IRQ_WAKE_THREAD;
301         }
302
303         writel(~0, &cdns->otg_regs->ivect);
304         return ret;
305 }
306
307 int cdns3_drd_init(struct cdns3 *cdns)
308 {
309         void __iomem *regs;
310         int ret = 0;
311         u32 state;
312
313         regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res);
314         if (IS_ERR(regs))
315                 return PTR_ERR(regs);
316
317         /* Detection of DRD version. Controller has been released
318          * in two versions. Both are similar, but they have same changes
319          * in register maps.
320          * The first register in old version is command register and it's read
321          * only, so driver should read 0 from it. On the other hand, in v1
322          * the first register contains device ID number which is not set to 0.
323          * Driver uses this fact to detect the proper version of
324          * controller.
325          */
326         cdns->otg_v0_regs = regs;
327         if (!readl(&cdns->otg_v0_regs->cmd)) {
328                 cdns->version  = CDNS3_CONTROLLER_V0;
329                 cdns->otg_v1_regs = NULL;
330                 cdns->otg_regs = regs;
331                 writel(1, &cdns->otg_v0_regs->simulate);
332                 dev_info(cdns->dev, "DRD version v0 (%08x)\n",
333                          readl(&cdns->otg_v0_regs->version));
334         } else {
335                 cdns->otg_v0_regs = NULL;
336                 cdns->otg_v1_regs = regs;
337                 cdns->otg_regs = (void *)&cdns->otg_v1_regs->cmd;
338                 cdns->version  = CDNS3_CONTROLLER_V1;
339                 writel(1, &cdns->otg_v1_regs->simulate);
340                 dev_info(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n",
341                          readl(&cdns->otg_v1_regs->did),
342                          readl(&cdns->otg_v1_regs->rid));
343         }
344
345         state = OTGSTS_STRAP(readl(&cdns->otg_regs->sts));
346
347         /* Update dr_mode according to STRAP configuration. */
348         cdns->dr_mode = USB_DR_MODE_OTG;
349         if (state == OTGSTS_STRAP_HOST) {
350                 dev_dbg(cdns->dev, "Controller strapped to HOST\n");
351                 cdns->dr_mode = USB_DR_MODE_HOST;
352         } else if (state == OTGSTS_STRAP_GADGET) {
353                 dev_dbg(cdns->dev, "Controller strapped to PERIPHERAL\n");
354                 cdns->dr_mode = USB_DR_MODE_PERIPHERAL;
355         }
356
357         ret = devm_request_threaded_irq(cdns->dev, cdns->otg_irq,
358                                         cdns3_drd_irq,
359                                         cdns3_drd_thread_irq,
360                                         IRQF_SHARED,
361                                         dev_name(cdns->dev), cdns);
362
363         if (ret) {
364                 dev_err(cdns->dev, "couldn't get otg_irq\n");
365                 return ret;
366         }
367
368         state = readl(&cdns->otg_regs->sts);
369         if (OTGSTS_OTG_NRDY(state) != 0) {
370                 dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n");
371                 return -ENODEV;
372         }
373
374         return ret;
375 }
376
377 int cdns3_drd_exit(struct cdns3 *cdns)
378 {
379         cdns3_otg_disable_irq(cdns);
380         return 0;
381 }