Merge branch 'master' of git://git.denx.de/u-boot-i2c; branch 'master' of git://git...
[oweals/u-boot.git] / drivers / usb / musb-new / omap2430.c
1 /*
2  * Copyright (C) 2005-2007 by Texas Instruments
3  * Some code has been taken from tusb6010.c
4  * Copyrights for that are attributable to:
5  * Copyright (C) 2006 Nokia Corporation
6  * Tony Lindgren <tony@atomide.com>
7  *
8  * This file is part of the Inventra Controller Driver for Linux.
9  *
10  * SPDX-License-Identifier:     GPL-2.0
11  */
12 #ifndef __UBOOT__
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/init.h>
17 #include <linux/list.h>
18 #include <linux/io.h>
19 #include <linux/platform_device.h>
20 #include <linux/dma-mapping.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/err.h>
23 #include <linux/usb/musb-omap.h>
24 #else
25 #include <common.h>
26 #include <asm/omap_musb.h>
27 #include <twl4030.h>
28 #include "linux-compat.h"
29 #endif
30
31 #include "musb_core.h"
32 #include "omap2430.h"
33
34 #ifndef __UBOOT__
35 struct omap2430_glue {
36         struct device           *dev;
37         struct platform_device  *musb;
38         enum omap_musb_vbus_id_status status;
39         struct work_struct      omap_musb_mailbox_work;
40 };
41 #define glue_to_musb(g)         platform_get_drvdata(g->musb)
42
43 struct omap2430_glue            *_glue;
44
45 static struct timer_list musb_idle_timer;
46
47 static void musb_do_idle(unsigned long _musb)
48 {
49         struct musb     *musb = (void *)_musb;
50         unsigned long   flags;
51         u8      power;
52         u8      devctl;
53
54         spin_lock_irqsave(&musb->lock, flags);
55
56         switch (musb->xceiv->state) {
57         case OTG_STATE_A_WAIT_BCON:
58
59                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
60                 if (devctl & MUSB_DEVCTL_BDEVICE) {
61                         musb->xceiv->state = OTG_STATE_B_IDLE;
62                         MUSB_DEV_MODE(musb);
63                 } else {
64                         musb->xceiv->state = OTG_STATE_A_IDLE;
65                         MUSB_HST_MODE(musb);
66                 }
67                 break;
68         case OTG_STATE_A_SUSPEND:
69                 /* finish RESUME signaling? */
70                 if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
71                         power = musb_readb(musb->mregs, MUSB_POWER);
72                         power &= ~MUSB_POWER_RESUME;
73                         dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
74                         musb_writeb(musb->mregs, MUSB_POWER, power);
75                         musb->is_active = 1;
76                         musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
77                                                 | MUSB_PORT_STAT_RESUME);
78                         musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
79                         usb_hcd_poll_rh_status(musb_to_hcd(musb));
80                         /* NOTE: it might really be A_WAIT_BCON ... */
81                         musb->xceiv->state = OTG_STATE_A_HOST;
82                 }
83                 break;
84         case OTG_STATE_A_HOST:
85                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
86                 if (devctl &  MUSB_DEVCTL_BDEVICE)
87                         musb->xceiv->state = OTG_STATE_B_IDLE;
88                 else
89                         musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
90         default:
91                 break;
92         }
93         spin_unlock_irqrestore(&musb->lock, flags);
94 }
95
96
97 static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
98 {
99         unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
100         static unsigned long    last_timer;
101
102         if (timeout == 0)
103                 timeout = default_timeout;
104
105         /* Never idle if active, or when VBUS timeout is not set as host */
106         if (musb->is_active || ((musb->a_wait_bcon == 0)
107                         && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
108                 dev_dbg(musb->controller, "%s active, deleting timer\n",
109                         otg_state_string(musb->xceiv->state));
110                 del_timer(&musb_idle_timer);
111                 last_timer = jiffies;
112                 return;
113         }
114
115         if (time_after(last_timer, timeout)) {
116                 if (!timer_pending(&musb_idle_timer))
117                         last_timer = timeout;
118                 else {
119                         dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
120                         return;
121                 }
122         }
123         last_timer = timeout;
124
125         dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
126                 otg_state_string(musb->xceiv->state),
127                 (unsigned long)jiffies_to_msecs(timeout - jiffies));
128         mod_timer(&musb_idle_timer, timeout);
129 }
130
131 static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
132 {
133         struct usb_otg  *otg = musb->xceiv->otg;
134         u8              devctl;
135         unsigned long timeout = jiffies + msecs_to_jiffies(1000);
136         int ret = 1;
137         /* HDRC controls CPEN, but beware current surges during device
138          * connect.  They can trigger transient overcurrent conditions
139          * that must be ignored.
140          */
141
142         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
143
144         if (is_on) {
145                 if (musb->xceiv->state == OTG_STATE_A_IDLE) {
146                         /* start the session */
147                         devctl |= MUSB_DEVCTL_SESSION;
148                         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
149                         /*
150                          * Wait for the musb to set as A device to enable the
151                          * VBUS
152                          */
153                         while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
154
155                                 cpu_relax();
156
157                                 if (time_after(jiffies, timeout)) {
158                                         dev_err(musb->controller,
159                                         "configured as A device timeout");
160                                         ret = -EINVAL;
161                                         break;
162                                 }
163                         }
164
165                         if (ret && otg->set_vbus)
166                                 otg_set_vbus(otg, 1);
167                 } else {
168                         musb->is_active = 1;
169                         otg->default_a = 1;
170                         musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
171                         devctl |= MUSB_DEVCTL_SESSION;
172                         MUSB_HST_MODE(musb);
173                 }
174         } else {
175                 musb->is_active = 0;
176
177                 /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
178                  * jumping right to B_IDLE...
179                  */
180
181                 otg->default_a = 0;
182                 musb->xceiv->state = OTG_STATE_B_IDLE;
183                 devctl &= ~MUSB_DEVCTL_SESSION;
184
185                 MUSB_DEV_MODE(musb);
186         }
187         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
188
189         dev_dbg(musb->controller, "VBUS %s, devctl %02x "
190                 /* otg %3x conf %08x prcm %08x */ "\n",
191                 otg_state_string(musb->xceiv->state),
192                 musb_readb(musb->mregs, MUSB_DEVCTL));
193 }
194
195 static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
196 {
197         u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
198
199         devctl |= MUSB_DEVCTL_SESSION;
200         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
201
202         return 0;
203 }
204 #endif
205
206 static inline void omap2430_low_level_exit(struct musb *musb)
207 {
208         u32 l;
209
210         /* in any role */
211         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
212         l |= ENABLEFORCE;       /* enable MSTANDBY */
213         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
214 }
215
216 static inline void omap2430_low_level_init(struct musb *musb)
217 {
218         u32 l;
219
220         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
221         l &= ~ENABLEFORCE;      /* disable MSTANDBY */
222         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
223 }
224
225 #ifndef __UBOOT__
226 void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
227 {
228         struct omap2430_glue    *glue = _glue;
229         struct musb             *musb = glue_to_musb(glue);
230
231         glue->status = status;
232         if (!musb) {
233                 dev_err(glue->dev, "musb core is not yet ready\n");
234                 return;
235         }
236
237         schedule_work(&glue->omap_musb_mailbox_work);
238 }
239 EXPORT_SYMBOL_GPL(omap_musb_mailbox);
240
241 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
242 {
243         struct musb *musb = glue_to_musb(glue);
244         struct device *dev = musb->controller;
245         struct musb_hdrc_platform_data *pdata = dev->platform_data;
246         struct omap_musb_board_data *data = pdata->board_data;
247         struct usb_otg *otg = musb->xceiv->otg;
248
249         switch (glue->status) {
250         case OMAP_MUSB_ID_GROUND:
251                 dev_dbg(dev, "ID GND\n");
252
253                 otg->default_a = true;
254                 musb->xceiv->state = OTG_STATE_A_IDLE;
255                 musb->xceiv->last_event = USB_EVENT_ID;
256                 if (!is_otg_enabled(musb) || musb->gadget_driver) {
257                         pm_runtime_get_sync(dev);
258                         usb_phy_init(musb->xceiv);
259                         omap2430_musb_set_vbus(musb, 1);
260                 }
261                 break;
262
263         case OMAP_MUSB_VBUS_VALID:
264                 dev_dbg(dev, "VBUS Connect\n");
265
266                 otg->default_a = false;
267                 musb->xceiv->state = OTG_STATE_B_IDLE;
268                 musb->xceiv->last_event = USB_EVENT_VBUS;
269                 if (musb->gadget_driver)
270                         pm_runtime_get_sync(dev);
271                 usb_phy_init(musb->xceiv);
272                 break;
273
274         case OMAP_MUSB_ID_FLOAT:
275         case OMAP_MUSB_VBUS_OFF:
276                 dev_dbg(dev, "VBUS Disconnect\n");
277
278                 musb->xceiv->last_event = USB_EVENT_NONE;
279                 if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
280                         if (musb->gadget_driver) {
281                                 pm_runtime_mark_last_busy(dev);
282                                 pm_runtime_put_autosuspend(dev);
283                         }
284
285                 if (data->interface_type == MUSB_INTERFACE_UTMI) {
286                         if (musb->xceiv->otg->set_vbus)
287                                 otg_set_vbus(musb->xceiv->otg, 0);
288                 }
289                 usb_phy_shutdown(musb->xceiv);
290                 break;
291         default:
292                 dev_dbg(dev, "ID float\n");
293         }
294 }
295
296
297 static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
298 {
299         struct omap2430_glue *glue = container_of(mailbox_work,
300                                 struct omap2430_glue, omap_musb_mailbox_work);
301         omap_musb_set_mailbox(glue);
302 }
303 #endif
304
305 static int omap2430_musb_init(struct musb *musb)
306 {
307         u32 l;
308         int status = 0;
309         unsigned long int start;
310 #ifndef __UBOOT__
311         struct device *dev = musb->controller;
312         struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
313         struct musb_hdrc_platform_data *plat = dev->platform_data;
314         struct omap_musb_board_data *data = plat->board_data;
315 #else
316         struct omap_musb_board_data *data =
317                 (struct omap_musb_board_data *)musb->controller;
318 #endif
319
320         /* Reset the controller */
321         musb_writel(musb->mregs, OTG_SYSCONFIG, SOFTRST);
322
323         start = get_timer(0);
324
325         while (1) {
326                 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
327                 if ((l & SOFTRST) == 0)
328                         break;
329
330                 if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
331                         dev_err(musb->controller, "MUSB reset is taking too long\n");
332                         return -ENODEV;
333                 }
334         }
335
336 #ifndef __UBOOT__
337         /* We require some kind of external transceiver, hooked
338          * up through ULPI.  TWL4030-family PMICs include one,
339          * which needs a driver, drivers aren't always needed.
340          */
341         musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
342         if (IS_ERR_OR_NULL(musb->xceiv)) {
343                 pr_err("HS USB OTG: no transceiver configured\n");
344                 return -ENODEV;
345         }
346
347         status = pm_runtime_get_sync(dev);
348         if (status < 0) {
349                 dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
350                 goto err1;
351         }
352 #endif
353
354         l = musb_readl(musb->mregs, OTG_INTERFSEL);
355
356         if (data->interface_type == MUSB_INTERFACE_UTMI) {
357                 /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
358                 l &= ~ULPI_12PIN;       /* Disable ULPI */
359                 l |= UTMI_8BIT;         /* Enable UTMI  */
360         } else {
361                 l |= ULPI_12PIN;
362         }
363
364         musb_writel(musb->mregs, OTG_INTERFSEL, l);
365
366         pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
367                         "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
368                         musb_readl(musb->mregs, OTG_REVISION),
369                         musb_readl(musb->mregs, OTG_SYSCONFIG),
370                         musb_readl(musb->mregs, OTG_SYSSTATUS),
371                         musb_readl(musb->mregs, OTG_INTERFSEL),
372                         musb_readl(musb->mregs, OTG_SIMENABLE));
373
374 #ifndef __UBOOT__
375         setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
376
377         if (glue->status != OMAP_MUSB_UNKNOWN)
378                 omap_musb_set_mailbox(glue);
379
380         pm_runtime_put_noidle(musb->controller);
381 #endif
382         return 0;
383
384 err1:
385         return status;
386 }
387
388 #ifndef __UBOOT__
389 static void omap2430_musb_enable(struct musb *musb)
390 #else
391 static int omap2430_musb_enable(struct musb *musb)
392 #endif
393 {
394 #ifndef __UBOOT__
395         u8              devctl;
396         unsigned long timeout = jiffies + msecs_to_jiffies(1000);
397         struct device *dev = musb->controller;
398         struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
399         struct musb_hdrc_platform_data *pdata = dev->platform_data;
400         struct omap_musb_board_data *data = pdata->board_data;
401
402         switch (glue->status) {
403
404         case OMAP_MUSB_ID_GROUND:
405                 usb_phy_init(musb->xceiv);
406                 if (data->interface_type != MUSB_INTERFACE_UTMI)
407                         break;
408                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
409                 /* start the session */
410                 devctl |= MUSB_DEVCTL_SESSION;
411                 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
412                 while (musb_readb(musb->mregs, MUSB_DEVCTL) &
413                                 MUSB_DEVCTL_BDEVICE) {
414                         cpu_relax();
415
416                         if (time_after(jiffies, timeout)) {
417                                 dev_err(dev, "configured as A device timeout");
418                                 break;
419                         }
420                 }
421                 break;
422
423         case OMAP_MUSB_VBUS_VALID:
424                 usb_phy_init(musb->xceiv);
425                 break;
426
427         default:
428                 break;
429         }
430 #else
431 #ifdef CONFIG_TWL4030_USB
432         if (twl4030_usb_ulpi_init()) {
433                 serial_printf("ERROR: %s Could not initialize PHY\n",
434                                 __PRETTY_FUNCTION__);
435         }
436 #endif
437         return 0;
438 #endif
439 }
440
441 static void omap2430_musb_disable(struct musb *musb)
442 {
443 #ifndef __UBOOT__
444         struct device *dev = musb->controller;
445         struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
446
447         if (glue->status != OMAP_MUSB_UNKNOWN)
448                 usb_phy_shutdown(musb->xceiv);
449 #endif
450 }
451
452 static int omap2430_musb_exit(struct musb *musb)
453 {
454         del_timer_sync(&musb_idle_timer);
455
456         omap2430_low_level_exit(musb);
457
458         return 0;
459 }
460
461 #ifndef __UBOOT__
462 static const struct musb_platform_ops omap2430_ops = {
463 #else
464 const struct musb_platform_ops omap2430_ops = {
465 #endif
466         .init           = omap2430_musb_init,
467         .exit           = omap2430_musb_exit,
468
469 #ifndef __UBOOT__
470         .set_mode       = omap2430_musb_set_mode,
471         .try_idle       = omap2430_musb_try_idle,
472
473         .set_vbus       = omap2430_musb_set_vbus,
474 #endif
475
476         .enable         = omap2430_musb_enable,
477         .disable        = omap2430_musb_disable,
478 };
479
480 #ifndef __UBOOT__
481 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
482
483 static int __devinit omap2430_probe(struct platform_device *pdev)
484 {
485         struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
486         struct platform_device          *musb;
487         struct omap2430_glue            *glue;
488         int                             ret = -ENOMEM;
489
490         glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
491         if (!glue) {
492                 dev_err(&pdev->dev, "failed to allocate glue context\n");
493                 goto err0;
494         }
495
496         musb = platform_device_alloc("musb-hdrc", -1);
497         if (!musb) {
498                 dev_err(&pdev->dev, "failed to allocate musb device\n");
499                 goto err0;
500         }
501
502         musb->dev.parent                = &pdev->dev;
503         musb->dev.dma_mask              = &omap2430_dmamask;
504         musb->dev.coherent_dma_mask     = omap2430_dmamask;
505
506         glue->dev                       = &pdev->dev;
507         glue->musb                      = musb;
508         glue->status                    = OMAP_MUSB_UNKNOWN;
509
510         pdata->platform_ops             = &omap2430_ops;
511
512         platform_set_drvdata(pdev, glue);
513
514         /*
515          * REVISIT if we ever have two instances of the wrapper, we will be
516          * in big trouble
517          */
518         _glue   = glue;
519
520         INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
521
522         ret = platform_device_add_resources(musb, pdev->resource,
523                         pdev->num_resources);
524         if (ret) {
525                 dev_err(&pdev->dev, "failed to add resources\n");
526                 goto err1;
527         }
528
529         ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
530         if (ret) {
531                 dev_err(&pdev->dev, "failed to add platform_data\n");
532                 goto err1;
533         }
534
535         pm_runtime_enable(&pdev->dev);
536
537         ret = platform_device_add(musb);
538         if (ret) {
539                 dev_err(&pdev->dev, "failed to register musb device\n");
540                 goto err1;
541         }
542
543         return 0;
544
545 err1:
546         platform_device_put(musb);
547
548 err0:
549         return ret;
550 }
551
552 static int __devexit omap2430_remove(struct platform_device *pdev)
553 {
554         struct omap2430_glue            *glue = platform_get_drvdata(pdev);
555
556         cancel_work_sync(&glue->omap_musb_mailbox_work);
557         platform_device_del(glue->musb);
558         platform_device_put(glue->musb);
559
560         return 0;
561 }
562
563 #ifdef CONFIG_PM
564
565 static int omap2430_runtime_suspend(struct device *dev)
566 {
567         struct omap2430_glue            *glue = dev_get_drvdata(dev);
568         struct musb                     *musb = glue_to_musb(glue);
569
570         if (musb) {
571                 musb->context.otg_interfsel = musb_readl(musb->mregs,
572                                 OTG_INTERFSEL);
573
574                 omap2430_low_level_exit(musb);
575                 usb_phy_set_suspend(musb->xceiv, 1);
576         }
577
578         return 0;
579 }
580
581 static int omap2430_runtime_resume(struct device *dev)
582 {
583         struct omap2430_glue            *glue = dev_get_drvdata(dev);
584         struct musb                     *musb = glue_to_musb(glue);
585
586         if (musb) {
587                 omap2430_low_level_init(musb);
588                 musb_writel(musb->mregs, OTG_INTERFSEL,
589                                 musb->context.otg_interfsel);
590
591                 usb_phy_set_suspend(musb->xceiv, 0);
592         }
593
594         return 0;
595 }
596
597 static struct dev_pm_ops omap2430_pm_ops = {
598         .runtime_suspend = omap2430_runtime_suspend,
599         .runtime_resume = omap2430_runtime_resume,
600 };
601
602 #define DEV_PM_OPS      (&omap2430_pm_ops)
603 #else
604 #define DEV_PM_OPS      NULL
605 #endif
606
607 static struct platform_driver omap2430_driver = {
608         .probe          = omap2430_probe,
609         .remove         = __devexit_p(omap2430_remove),
610         .driver         = {
611                 .name   = "musb-omap2430",
612                 .pm     = DEV_PM_OPS,
613         },
614 };
615
616 MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
617 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
618 MODULE_LICENSE("GPL v2");
619
620 static int __init omap2430_init(void)
621 {
622         return platform_driver_register(&omap2430_driver);
623 }
624 subsys_initcall(omap2430_init);
625
626 static void __exit omap2430_exit(void)
627 {
628         platform_driver_unregister(&omap2430_driver);
629 }
630 module_exit(omap2430_exit);
631 #endif