usb: musb: move clock handling to glue layer
[pandora-kernel.git] / drivers / usb / musb / 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  * The Inventra Controller Driver for Linux is free software; you
11  * can redistribute it and/or modify it under the terms of the GNU
12  * General Public License version 2 as published by the Free Software
13  * Foundation.
14  *
15  * The Inventra Controller Driver for Linux is distributed in
16  * the hope that it will be useful, but WITHOUT ANY WARRANTY;
17  * without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19  * License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with The Inventra Controller Driver for Linux ; if not,
23  * write to the Free Software Foundation, Inc., 59 Temple Place,
24  * Suite 330, Boston, MA  02111-1307  USA
25  *
26  */
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/init.h>
31 #include <linux/list.h>
32 #include <linux/clk.h>
33 #include <linux/io.h>
34 #include <linux/platform_device.h>
35 #include <linux/dma-mapping.h>
36
37 #include "musb_core.h"
38 #include "omap2430.h"
39
40 struct omap2430_glue {
41         struct device           *dev;
42         struct platform_device  *musb;
43         struct clk              *clk;
44 };
45
46 static struct timer_list musb_idle_timer;
47
48 static void musb_do_idle(unsigned long _musb)
49 {
50         struct musb     *musb = (void *)_musb;
51         unsigned long   flags;
52 #ifdef CONFIG_USB_MUSB_HDRC_HCD
53         u8      power;
54 #endif
55         u8      devctl;
56
57         spin_lock_irqsave(&musb->lock, flags);
58
59         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
60
61         switch (musb->xceiv->state) {
62         case OTG_STATE_A_WAIT_BCON:
63                 devctl &= ~MUSB_DEVCTL_SESSION;
64                 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
65
66                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
67                 if (devctl & MUSB_DEVCTL_BDEVICE) {
68                         musb->xceiv->state = OTG_STATE_B_IDLE;
69                         MUSB_DEV_MODE(musb);
70                 } else {
71                         musb->xceiv->state = OTG_STATE_A_IDLE;
72                         MUSB_HST_MODE(musb);
73                 }
74                 break;
75 #ifdef CONFIG_USB_MUSB_HDRC_HCD
76         case OTG_STATE_A_SUSPEND:
77                 /* finish RESUME signaling? */
78                 if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
79                         power = musb_readb(musb->mregs, MUSB_POWER);
80                         power &= ~MUSB_POWER_RESUME;
81                         DBG(1, "root port resume stopped, power %02x\n", power);
82                         musb_writeb(musb->mregs, MUSB_POWER, power);
83                         musb->is_active = 1;
84                         musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
85                                                 | MUSB_PORT_STAT_RESUME);
86                         musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
87                         usb_hcd_poll_rh_status(musb_to_hcd(musb));
88                         /* NOTE: it might really be A_WAIT_BCON ... */
89                         musb->xceiv->state = OTG_STATE_A_HOST;
90                 }
91                 break;
92 #endif
93 #ifdef CONFIG_USB_MUSB_HDRC_HCD
94         case OTG_STATE_A_HOST:
95                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
96                 if (devctl &  MUSB_DEVCTL_BDEVICE)
97                         musb->xceiv->state = OTG_STATE_B_IDLE;
98                 else
99                         musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
100 #endif
101         default:
102                 break;
103         }
104         spin_unlock_irqrestore(&musb->lock, flags);
105 }
106
107
108 static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
109 {
110         unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
111         static unsigned long    last_timer;
112
113         if (timeout == 0)
114                 timeout = default_timeout;
115
116         /* Never idle if active, or when VBUS timeout is not set as host */
117         if (musb->is_active || ((musb->a_wait_bcon == 0)
118                         && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
119                 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
120                 del_timer(&musb_idle_timer);
121                 last_timer = jiffies;
122                 return;
123         }
124
125         if (time_after(last_timer, timeout)) {
126                 if (!timer_pending(&musb_idle_timer))
127                         last_timer = timeout;
128                 else {
129                         DBG(4, "Longer idle timer already pending, ignoring\n");
130                         return;
131                 }
132         }
133         last_timer = timeout;
134
135         DBG(4, "%s inactive, for idle timer for %lu ms\n",
136                 otg_state_string(musb),
137                 (unsigned long)jiffies_to_msecs(timeout - jiffies));
138         mod_timer(&musb_idle_timer, timeout);
139 }
140
141 static void omap2430_musb_enable(struct musb *musb)
142 {
143 }
144
145 static void omap2430_musb_disable(struct musb *musb)
146 {
147 }
148
149 static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
150 {
151         u8              devctl;
152         /* HDRC controls CPEN, but beware current surges during device
153          * connect.  They can trigger transient overcurrent conditions
154          * that must be ignored.
155          */
156
157         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
158
159         if (is_on) {
160                 musb->is_active = 1;
161                 musb->xceiv->default_a = 1;
162                 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
163                 devctl |= MUSB_DEVCTL_SESSION;
164
165                 MUSB_HST_MODE(musb);
166         } else {
167                 musb->is_active = 0;
168
169                 /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
170                  * jumping right to B_IDLE...
171                  */
172
173                 musb->xceiv->default_a = 0;
174                 musb->xceiv->state = OTG_STATE_B_IDLE;
175                 devctl &= ~MUSB_DEVCTL_SESSION;
176
177                 MUSB_DEV_MODE(musb);
178         }
179         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
180
181         DBG(1, "VBUS %s, devctl %02x "
182                 /* otg %3x conf %08x prcm %08x */ "\n",
183                 otg_state_string(musb),
184                 musb_readb(musb->mregs, MUSB_DEVCTL));
185 }
186
187 static int omap2430_musb_resume(struct musb *musb);
188
189 static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
190 {
191         u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
192
193         devctl |= MUSB_DEVCTL_SESSION;
194         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
195
196         return 0;
197 }
198
199 static int omap2430_musb_init(struct musb *musb)
200 {
201         u32 l;
202         struct device *dev = musb->controller;
203         struct musb_hdrc_platform_data *plat = dev->platform_data;
204         struct omap_musb_board_data *data = plat->board_data;
205
206         /* We require some kind of external transceiver, hooked
207          * up through ULPI.  TWL4030-family PMICs include one,
208          * which needs a driver, drivers aren't always needed.
209          */
210         musb->xceiv = otg_get_transceiver();
211         if (!musb->xceiv) {
212                 pr_err("HS USB OTG: no transceiver configured\n");
213                 return -ENODEV;
214         }
215
216         omap2430_musb_resume(musb);
217
218         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
219         l &= ~ENABLEWAKEUP;     /* disable wakeup */
220         l &= ~NOSTDBY;          /* remove possible nostdby */
221         l |= SMARTSTDBY;        /* enable smart standby */
222         l &= ~AUTOIDLE;         /* disable auto idle */
223         l &= ~NOIDLE;           /* remove possible noidle */
224         l |= SMARTIDLE;         /* enable smart idle */
225         /*
226          * MUSB AUTOIDLE don't work in 3430.
227          * Workaround by Richard Woodruff/TI
228          */
229         if (!cpu_is_omap3430())
230                 l |= AUTOIDLE;          /* enable auto idle */
231         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
232
233         l = musb_readl(musb->mregs, OTG_INTERFSEL);
234
235         if (data->interface_type == MUSB_INTERFACE_UTMI) {
236                 /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
237                 l &= ~ULPI_12PIN;       /* Disable ULPI */
238                 l |= UTMI_8BIT;         /* Enable UTMI  */
239         } else {
240                 l |= ULPI_12PIN;
241         }
242
243         musb_writel(musb->mregs, OTG_INTERFSEL, l);
244
245         pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
246                         "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
247                         musb_readl(musb->mregs, OTG_REVISION),
248                         musb_readl(musb->mregs, OTG_SYSCONFIG),
249                         musb_readl(musb->mregs, OTG_SYSSTATUS),
250                         musb_readl(musb->mregs, OTG_INTERFSEL),
251                         musb_readl(musb->mregs, OTG_SIMENABLE));
252
253         if (is_host_enabled(musb))
254                 musb->board_set_vbus = omap2430_musb_set_vbus;
255
256         setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
257
258         return 0;
259 }
260
261 #ifdef CONFIG_PM
262 void musb_platform_save_context(struct musb *musb,
263                 struct musb_context_registers *musb_context)
264 {
265         musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
266         musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
267 }
268
269 void musb_platform_restore_context(struct musb *musb,
270                 struct musb_context_registers *musb_context)
271 {
272         musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig);
273         musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby);
274 }
275 #endif
276
277 static int omap2430_musb_suspend(struct musb *musb)
278 {
279         u32 l;
280
281         /* in any role */
282         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
283         l |= ENABLEFORCE;       /* enable MSTANDBY */
284         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
285
286         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
287         l |= ENABLEWAKEUP;      /* enable wakeup */
288         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
289
290         otg_set_suspend(musb->xceiv, 1);
291
292         return 0;
293 }
294
295 static int omap2430_musb_resume(struct musb *musb)
296 {
297         u32 l;
298
299         otg_set_suspend(musb->xceiv, 0);
300
301         l = musb_readl(musb->mregs, OTG_SYSCONFIG);
302         l &= ~ENABLEWAKEUP;     /* disable wakeup */
303         musb_writel(musb->mregs, OTG_SYSCONFIG, l);
304
305         l = musb_readl(musb->mregs, OTG_FORCESTDBY);
306         l &= ~ENABLEFORCE;      /* disable MSTANDBY */
307         musb_writel(musb->mregs, OTG_FORCESTDBY, l);
308
309         return 0;
310 }
311
312 static int omap2430_musb_exit(struct musb *musb)
313 {
314
315         omap2430_musb_suspend(musb);
316
317         otg_put_transceiver(musb->xceiv);
318         return 0;
319 }
320
321 static const struct musb_platform_ops omap2430_ops = {
322         .init           = omap2430_musb_init,
323         .exit           = omap2430_musb_exit,
324
325         .suspend        = omap2430_musb_suspend,
326         .resume         = omap2430_musb_resume,
327
328         .enable         = omap2430_musb_enable,
329         .disable        = omap2430_musb_disable,
330
331         .set_mode       = omap2430_musb_set_mode,
332         .try_idle       = omap2430_musb_try_idle,
333
334         .set_vbus       = omap2430_musb_set_vbus,
335 };
336
337 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
338
339 static int __init omap2430_probe(struct platform_device *pdev)
340 {
341         struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
342         struct platform_device          *musb;
343         struct omap2430_glue            *glue;
344         struct clk                      *clk;
345
346         int                             ret = -ENOMEM;
347
348         glue = kzalloc(sizeof(*glue), GFP_KERNEL);
349         if (!glue) {
350                 dev_err(&pdev->dev, "failed to allocate glue context\n");
351                 goto err0;
352         }
353
354         musb = platform_device_alloc("musb-hdrc", -1);
355         if (!musb) {
356                 dev_err(&pdev->dev, "failed to allocate musb device\n");
357                 goto err1;
358         }
359
360         clk = clk_get(&pdev->dev, "ick");
361         if (IS_ERR(clk)) {
362                 dev_err(&pdev->dev, "failed to get clock\n");
363                 ret = PTR_ERR(clk);
364                 goto err2;
365         }
366
367         ret = clk_enable(clk);
368         if (ret) {
369                 dev_err(&pdev->dev, "failed to enable clock\n");
370                 goto err3;
371         }
372
373         musb->dev.parent                = &pdev->dev;
374         musb->dev.dma_mask              = &omap2430_dmamask;
375         musb->dev.coherent_dma_mask     = omap2430_dmamask;
376
377         glue->dev                       = &pdev->dev;
378         glue->musb                      = musb;
379         glue->clk                       = clk;
380
381         pdata->platform_ops             = &omap2430_ops;
382
383         platform_set_drvdata(pdev, glue);
384
385         ret = platform_device_add_resources(musb, pdev->resource,
386                         pdev->num_resources);
387         if (ret) {
388                 dev_err(&pdev->dev, "failed to add resources\n");
389                 goto err4;
390         }
391
392         ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
393         if (ret) {
394                 dev_err(&pdev->dev, "failed to add platform_data\n");
395                 goto err4;
396         }
397
398         ret = platform_device_add(musb);
399         if (ret) {
400                 dev_err(&pdev->dev, "failed to register musb device\n");
401                 goto err4;
402         }
403
404         return 0;
405
406 err4:
407         clk_disable(clk);
408
409 err3:
410         clk_put(clk);
411
412 err2:
413         platform_device_put(musb);
414
415 err1:
416         kfree(glue);
417
418 err0:
419         return ret;
420 }
421
422 static int __exit omap2430_remove(struct platform_device *pdev)
423 {
424         struct omap2430_glue            *glue = platform_get_drvdata(pdev);
425
426         platform_device_del(glue->musb);
427         platform_device_put(glue->musb);
428         clk_disable(glue->clk);
429         clk_put(glue->clk);
430         kfree(glue);
431
432         return 0;
433 }
434
435 static struct platform_driver omap2430_driver = {
436         .remove         = __exit_p(omap2430_remove),
437         .driver         = {
438                 .name   = "musb-omap2430",
439         },
440 };
441
442 MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
443 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
444 MODULE_LICENSE("GPL v2");
445
446 static int __init omap2430_init(void)
447 {
448         return platform_driver_probe(&omap2430_driver, omap2430_probe);
449 }
450 subsys_initcall(omap2430_init);
451
452 static void __exit omap2430_exit(void)
453 {
454         platform_driver_unregister(&omap2430_driver);
455 }
456 module_exit(omap2430_exit);