blob: 4449187529af9e0455fa3945fac802ef6aead81f [file] [log] [blame]
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001/**
2 * dwc3_otg.c - DesignWare USB3 DRD Controller OTG
3 *
4 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/usb.h>
17#include <linux/usb/hcd.h>
18#include <linux/platform_device.h>
19
20#include "core.h"
21#include "dwc3_otg.h"
22#include "io.h"
23#include "xhci.h"
24
25
26/**
27 * dwc3_otg_set_host_regs - reset dwc3 otg registers to host operation.
28 *
29 * This function sets the OTG registers to work in A-Device host mode.
30 * This function should be called just before entering to A-Device mode.
31 *
32 * @w: Pointer to the dwc3 otg workqueue.
33 */
34static void dwc3_otg_set_host_regs(struct dwc3_otg *dotg)
35{
36 u32 octl;
37
38 /* Set OCTL[6](PeriMode) to 0 (host) */
39 octl = dwc3_readl(dotg->regs, DWC3_OCTL);
40 octl &= ~DWC3_OTG_OCTL_PERIMODE;
41 dwc3_writel(dotg->regs, DWC3_OCTL, octl);
42
43 /*
44 * TODO: add more OTG registers writes for HOST mode here,
45 * see figure 12-10 A-device flow in dwc3 Synopsis spec
46 */
47}
48
49/**
50 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
51 *
52 * This function sets the OTG registers to work in B-Device peripheral mode.
53 * This function should be called just before entering to B-Device mode.
54 *
55 * @w: Pointer to the dwc3 otg workqueue.
56 */
57static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
58{
59 u32 octl;
60
61 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
62 octl = dwc3_readl(dotg->regs, DWC3_OCTL);
63 octl |= DWC3_OTG_OCTL_PERIMODE;
64 dwc3_writel(dotg->regs, DWC3_OCTL, octl);
65
66 /*
67 * TODO: add more OTG registers writes for PERIPHERAL mode here,
68 * see figure 12-19 B-device flow in dwc3 Synopsis spec
69 */
70}
71
72/**
73 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
74 *
75 * @otg: Pointer to the otg_transceiver structure.
76 * @on: start / stop the host controller driver.
77 *
78 * Returns 0 on success otherwise negative errno.
79 */
80static int dwc3_otg_start_host(struct usb_otg *otg, int on)
81{
82 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
83 struct usb_hcd *hcd;
84 struct xhci_hcd *xhci;
85 int ret = 0;
86
87 if (!otg->host)
88 return -EINVAL;
89
90 hcd = bus_to_hcd(otg->host);
91 xhci = hcd_to_xhci(hcd);
92 if (on) {
93 dev_dbg(otg->phy->dev, "%s: turn on host %s\n",
94 __func__, otg->host->bus_name);
95 dwc3_otg_set_host_regs(dotg);
96
97 /*
98 * This should be revisited for more testing post-silicon.
99 * In worst case we may need to disconnect the root hub
100 * before stopping the controller so that it does not
101 * interfere with runtime pm/system pm.
102 * We can also consider registering and unregistering xhci
103 * platform device. It is almost similar to add_hcd and
104 * remove_hcd, But we may not use standard set_host method
105 * anymore.
106 */
107 ret = hcd->driver->start(hcd);
108 if (ret) {
109 dev_err(otg->phy->dev,
110 "%s: failed to start primary hcd, ret=%d\n",
111 __func__, ret);
112 return ret;
113 }
114
115 ret = xhci->shared_hcd->driver->start(xhci->shared_hcd);
116 if (ret) {
117 dev_err(otg->phy->dev,
118 "%s: failed to start secondary hcd, ret=%d\n",
119 __func__, ret);
120 return ret;
121 }
122 } else {
123 dev_dbg(otg->phy->dev, "%s: turn off host %s\n",
124 __func__, otg->host->bus_name);
125 hcd->driver->stop(hcd);
126 }
127
128 return 0;
129}
130
131/**
132 * dwc3_otg_set_host - bind/unbind the host controller driver.
133 *
134 * @otg: Pointer to the otg_transceiver structure.
135 * @host: Pointer to the usb_bus structure.
136 *
137 * Returns 0 on success otherwise negative errno.
138 */
139static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
140{
141 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
142
143 if (host) {
144 dev_dbg(otg->phy->dev, "%s: set host %s\n",
145 __func__, host->bus_name);
146 otg->host = host;
147
148 /*
149 * Only after both peripheral and host are set then check
150 * OTG sm. This prevents unnecessary activation of the sm
151 * in case the ID is high.
152 */
153 if (otg->gadget)
154 schedule_work(&dotg->sm_work);
155 } else {
156 if (otg->phy->state == OTG_STATE_A_HOST) {
157 dwc3_otg_start_host(otg, 0);
158 otg->host = NULL;
159 otg->phy->state = OTG_STATE_UNDEFINED;
160 schedule_work(&dotg->sm_work);
161 } else {
162 otg->host = NULL;
163 }
164 }
165
166 return 0;
167}
168
169/**
170 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
171 *
172 * @otg: Pointer to the otg_transceiver structure.
173 * @gadget: pointer to the usb_gadget structure.
174 *
175 * Returns 0 on success otherwise negative errno.
176 */
177static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
178{
179 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
180
181 if (!otg->gadget)
182 return -EINVAL;
183
184 if (on) {
185 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
186 __func__, otg->gadget->name);
187 dwc3_otg_set_peripheral_regs(dotg);
188 usb_gadget_vbus_connect(otg->gadget);
189 } else {
190 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
191 __func__, otg->gadget->name);
192 usb_gadget_vbus_disconnect(otg->gadget);
193 }
194
195 return 0;
196}
197
198/**
199 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
200 *
201 * @otg: Pointer to the otg_transceiver structure.
202 * @gadget: pointer to the usb_gadget structure.
203 *
204 * Returns 0 on success otherwise negative errno.
205 */
206static int dwc3_otg_set_peripheral(struct usb_otg *otg,
207 struct usb_gadget *gadget)
208{
209 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
210
211 if (gadget) {
212 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
213 __func__, gadget->name);
214 otg->gadget = gadget;
215
216 /*
217 * Only after both peripheral and host are set then check
218 * OTG sm. This prevents unnecessary activation of the sm
219 * in case the ID is grounded.
220 */
221 if (otg->host)
222 schedule_work(&dotg->sm_work);
223 } else {
224 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
225 dwc3_otg_start_peripheral(otg, 0);
226 otg->gadget = NULL;
227 otg->phy->state = OTG_STATE_UNDEFINED;
228 schedule_work(&dotg->sm_work);
229 } else {
230 otg->gadget = NULL;
231 }
232 }
233
234 return 0;
235}
236
237/**
238 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
239 * @_dotg: Pointer to out controller context structure
240 *
241 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
242 */
243static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
244{
245 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
246 u32 oevt_reg;
247 int ret = IRQ_NONE;
248 int handled_irqs = 0;
249
250 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
251
252 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
253 /*
254 * ID sts has changed, read it and later, in the workqueue
255 * function, switch from A to B or from B to A.
256 */
257 dotg->osts = dwc3_readl(dotg->regs, DWC3_OSTS);
258 if ((dotg->otg.phy->state == OTG_STATE_B_IDLE) ||
259 (dotg->otg.phy->state == OTG_STATE_A_IDLE)) {
260
261 /*
262 * OTG state is ABOUT to change to A or B device, but
263 * since ID sts was chnaged, then we return the state
264 * machine to the start point.
265 */
266 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
267 }
268 schedule_work(&dotg->sm_work);
269
270 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
271 ret = IRQ_HANDLED;
272 }
273
274 /*
275 * Clear the interrupts we handled.
276 */
277 if (ret == IRQ_HANDLED)
278 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
279
280 return ret;
281}
282
283/**
284 * dwc3_otg_sm_work - workqueue function.
285 *
286 * @w: Pointer to the dwc3 otg workqueue
287 *
288 * NOTE: After any change in phy->state,
289 * we must reschdule the state machine.
290 */
291static void dwc3_otg_sm_work(struct work_struct *w)
292{
293 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work);
294 struct usb_phy *phy = dotg->otg.phy;
295
296 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
297
298 /* Check OTG state */
299 switch (phy->state) {
300 case OTG_STATE_UNDEFINED:
301 /* Switch to A or B-Device according to IDSTS */
302 if (dotg->osts & DWC3_OTG_OSTS_CONIDSTS)
303 phy->state = OTG_STATE_B_IDLE;
304 else
305 phy->state = OTG_STATE_A_IDLE;
306
307 schedule_work(&dotg->sm_work);
308 break;
309 case OTG_STATE_B_IDLE:
310 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
311 /*
312 * Probably set_peripheral was not called yet.
313 * We will re-try as soon as it will be called
314 */
315 dev_err(phy->dev,
316 "unable to start B-device\n");
317 phy->state = OTG_STATE_UNDEFINED;
318 } else
319 phy->state = OTG_STATE_B_PERIPHERAL;
320
321 schedule_work(&dotg->sm_work);
322 break;
323 case OTG_STATE_B_PERIPHERAL:
324 if (!(dotg->osts & DWC3_OTG_OSTS_CONIDSTS)) {
325 dwc3_otg_start_peripheral(&dotg->otg, 0);
326 phy->state = OTG_STATE_A_IDLE;
327 schedule_work(&dotg->sm_work);
328 }
329 break;
330 case OTG_STATE_A_IDLE:
331 /* Switch to A-Device*/
332 if (dwc3_otg_start_host(&dotg->otg, 1)) {
333 /*
334 * Probably set_host was not called yet.
335 * We will re-try as soon as it will be called
336 */
337 dev_err(phy->dev,
338 "unable to start A-device\n");
339 phy->state = OTG_STATE_UNDEFINED;
340 } else
341 phy->state = OTG_STATE_A_HOST;
342
343 schedule_work(&dotg->sm_work);
344 break;
345 case OTG_STATE_A_HOST:
346 if (dotg->osts & DWC3_OTG_OSTS_CONIDSTS) {
347 dwc3_otg_start_host(&dotg->otg, 0);
348 phy->state = OTG_STATE_B_IDLE;
349 schedule_work(&dotg->sm_work);
350 }
351 break;
352 default:
353 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
354
355 }
356}
357
358
359/**
360 * dwc3_otg_reset - reset dwc3 otg registers.
361 *
362 * @w: Pointer to the dwc3 otg workqueue
363 */
364static void dwc3_otg_reset(struct dwc3_otg *dotg)
365{
366 /*
367 * OCFG[2] - OTG-Version = 1
368 * OCFG[1] - HNPCap = 0
369 * OCFG[0] - SRPCap = 0
370 */
371 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
372
373 /*
374 * OCTL[6] - PeriMode = 1
375 * OCTL[5] - PrtPwrCtl = 0
376 * OCTL[4] - HNPReq = 0
377 * OCTL[3] - SesReq = 0
378 * OCTL[2] - TermSelDLPulse = 0
379 * OCTL[1] - DevSetHNPEn = 0
380 * OCTL[0] - HstSetHNPEn = 0
381 */
382 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
383
384 /* Clear all otg events (interrupts) indications */
385 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
386
387 /* Enable only the ConIDStsChngEn event*/
388 dwc3_writel(dotg->regs, DWC3_OEVTEN,
389 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT);
390
391 /* Read OSTS */
392 dotg->osts = dwc3_readl(dotg->regs, DWC3_OSTS);
393
394}
395
396/**
397 * dwc3_otg_init - Initializes otg related registers
398 * @dwc: Pointer to out controller context structure
399 *
400 * Returns 0 on success otherwise negative errno.
401 */
402int dwc3_otg_init(struct dwc3 *dwc)
403{
404 u32 reg;
405 int ret = 0;
406 struct dwc3_otg *dotg;
407
408 dev_dbg(dwc->dev, "dwc3_otg_init\n");
409
410 /*
411 * GHWPARAMS6[10] bit is SRPSupport.
412 * This bit also reflects DWC_USB3_EN_OTG
413 */
414 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
415 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
416 /*
417 * No OTG support in the HW core.
418 * We return 0 to indicate no error, since this is acceptable
419 * situation, just continue probe the dwc3 driver without otg.
420 */
421 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
422 return 0;
423 }
424
425 /* Allocate and init otg instance */
426 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
427 if (!dotg) {
428 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
429 return -ENOMEM;
430 }
431
432 dotg->irq = platform_get_irq(to_platform_device(dwc->dev), 0);
433 if (dotg->irq < 0) {
434 dev_err(dwc->dev, "%s: missing IRQ\n", __func__);
435 ret = -ENODEV;
436 goto err1;
437 }
438
439 dotg->regs = dwc->regs;
440
441 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
442 dotg->otg.set_host = dwc3_otg_set_host;
443
444 /* This reference is used by dwc3 modules for checking otg existance */
445 dwc->dotg = dotg;
446
447 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
448 if (!dotg->otg.phy) {
449 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
450 ret = -ENOMEM;
451 goto err1;
452 }
453
454 dotg->otg.phy->otg = &dotg->otg;
455 dotg->otg.phy->dev = dwc->dev;
456
457 ret = usb_set_transceiver(dotg->otg.phy);
458 if (ret) {
459 dev_err(dotg->otg.phy->dev,
460 "%s: failed to set transceiver, already exists\n",
461 __func__);
462 goto err2;
463 }
464
465 dwc3_otg_reset(dotg);
466
467 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
468
469 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
470
471 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
472 "dwc3_otg", dotg);
473 if (ret) {
474 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
475 dotg->irq, ret);
476 goto err3;
477 }
478
479 return 0;
480
481err3:
482 cancel_work_sync(&dotg->sm_work);
483 usb_set_transceiver(NULL);
484err2:
485 kfree(dotg->otg.phy);
486err1:
487 dwc->dotg = NULL;
488 kfree(dotg);
489
490 return ret;
491}
492
493/**
494 * dwc3_otg_exit
495 * @dwc: Pointer to out controller context structure
496 *
497 * Returns 0 on success otherwise negative errno.
498 */
499void dwc3_otg_exit(struct dwc3 *dwc)
500{
501 struct dwc3_otg *dotg = dwc->dotg;
502
503 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
504 if (dotg) {
505 cancel_work_sync(&dotg->sm_work);
506 usb_set_transceiver(NULL);
507 free_irq(dotg->irq, dotg);
508 kfree(dotg->otg.phy);
509 kfree(dotg);
510 dwc->dotg = NULL;
511 }
512}