Revert "patch to latest usbhost patch"
[kernel-power] / usbhost / 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  * Jarkko Nikula <jarkko.nikula@nokia.com>
7  * Tony Lindgren <tony@atomide.com>
8  *
9  * This file is part of the Inventra Controller Driver for Linux.
10  *
11  * The Inventra Controller Driver for Linux is free software; you
12  * can redistribute it and/or modify it under the terms of the GNU
13  * General Public License version 2 as published by the Free Software
14  * Foundation.
15  *
16  * The Inventra Controller Driver for Linux is distributed in
17  * the hope that it will be useful, but WITHOUT ANY WARRANTY;
18  * without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20  * License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with The Inventra Controller Driver for Linux ; if not,
24  * write to the Free Software Foundation, Inc., 59 Temple Place,
25  * Suite 330, Boston, MA  02111-1307  USA
26  *
27  */
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h>
32 #include <linux/init.h>
33 #include <linux/list.h>
34 #include <linux/clk.h>
35 #include <linux/io.h>
36
37 #include <asm/mach-types.h>
38 #include <mach/hardware.h>
39 #include <mach/mux.h>
40
41 #include <linux/i2c/twl4030.h>
42
43 #include "musb_core.h"
44 #include "omap2430.h"
45
46 #ifdef CONFIG_ARCH_OMAP3430
47 #define get_cpu_rev()   2
48 #endif
49
50 #define MUSB_TIMEOUT_A_WAIT_BCON        1100
51
52 static struct timer_list musb_idle_timer;
53
54 static void musb_vbus_work(struct work_struct *data)
55 {
56         struct musb *musb = container_of(data, struct musb, vbus_work);
57         u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
58
59         /* clear/set requirements for musb to work with DPS on omap3 */
60         if (musb->board && musb->board->set_pm_limits && !musb->is_charger)
61                 musb->board->set_pm_limits(musb->controller,
62                                         (devctl & MUSB_DEVCTL_VBUS));
63 }
64
65 static void musb_do_idle(unsigned long _musb)
66 {
67         struct musb     *musb = (void *)_musb;
68         unsigned long   flags;
69 #ifdef CONFIG_USB_MUSB_HDRC_HCD
70         u8      power;
71 #endif
72         u8      devctl;
73
74         spin_lock_irqsave(&musb->lock, flags);
75
76         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
77
78         switch (musb->xceiv->state) {
79         case OTG_STATE_A_WAIT_BCON:
80                 devctl &= ~MUSB_DEVCTL_SESSION;
81                 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
82
83                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
84                 if (devctl & MUSB_DEVCTL_BDEVICE) {
85                         musb->xceiv->state = OTG_STATE_B_IDLE;
86                         MUSB_DEV_MODE(musb);
87                 } else {
88                         musb->xceiv->state = OTG_STATE_A_IDLE;
89                         MUSB_HST_MODE(musb);
90                 }
91                 break;
92 #ifdef CONFIG_USB_MUSB_HDRC_HCD
93         case OTG_STATE_A_SUSPEND:
94                 /* finish RESUME signaling? */
95                 if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
96                         power = musb_readb(musb->mregs, MUSB_POWER);
97                         power &= ~MUSB_POWER_RESUME;
98                         DBG(1, "root port resume stopped, power %02x\n", power);
99                         musb_writeb(musb->mregs, MUSB_POWER, power);
100                         musb->is_active = 1;
101                         musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
102                                                 | MUSB_PORT_STAT_RESUME);
103                         musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
104                         usb_hcd_poll_rh_status(musb_to_hcd(musb));
105                         /* NOTE: it might really be A_WAIT_BCON ... */
106                         musb->xceiv->state = OTG_STATE_A_HOST;
107                 }
108                 break;
109 #endif
110 #ifdef CONFIG_USB_MUSB_HDRC_HCD
111         case OTG_STATE_A_HOST:
112                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
113                 if (devctl &  MUSB_DEVCTL_BDEVICE)
114                         musb->xceiv->state = OTG_STATE_B_IDLE;
115                 else
116                         musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
117 #endif
118         default:
119                 break;
120         }
121         spin_unlock_irqrestore(&musb->lock, flags);
122 }
123
124
125 void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
126 {
127         unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
128         static unsigned long    last_timer;
129
130         if (timeout == 0)
131                 timeout = default_timeout;
132
133         /* Never idle if active, or when VBUS timeout is not set as host */
134         if (musb->is_active || ((musb->a_wait_bcon == 0)
135                         && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
136                 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
137                 del_timer(&musb_idle_timer);
138                 last_timer = jiffies;
139                 return;
140         }
141
142         if (time_after(last_timer, timeout)) {
143                 if (!timer_pending(&musb_idle_timer))
144                         last_timer = timeout;
145                 else {
146                         DBG(4, "Longer idle timer already pending, ignoring\n");
147                         return;
148                 }
149         }
150         last_timer = timeout;
151
152         DBG(4, "%s inactive, for idle timer for %lu ms\n",
153                 otg_state_string(musb),
154                 (unsigned long)jiffies_to_msecs(timeout - jiffies));
155         mod_timer(&musb_idle_timer, timeout);
156 }
157
158 void musb_platform_enable(struct musb *musb)
159 {
160         twl4030_upd_usb_suspended(0);
161 }
162 void musb_platform_disable(struct musb *musb)
163 {
164         twl4030_upd_usb_suspended(musb->is_suspended);
165 }
166 static void omap_vbus_power(struct musb *musb, int is_on, int sleeping)
167 {
168 }
169
170 static void omap_set_vbus(struct musb *musb, int is_on)
171 {
172         u8              devctl;
173         /* HDRC controls CPEN, but beware current surges during device
174          * connect.  They can trigger transient overcurrent conditions
175          * that must be ignored.
176          */
177
178         devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
179
180         if (is_on) {
181                 musb->is_active = 1;
182                 musb->xceiv->default_a = 1;
183                 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
184                 devctl |= MUSB_DEVCTL_SESSION;
185
186                 MUSB_HST_MODE(musb);
187         } else {
188                 musb->is_active = 0;
189
190                 /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
191                  * jumping right to B_IDLE...
192                  */
193
194                 musb->xceiv->default_a = 0;
195                 musb->xceiv->state = OTG_STATE_B_IDLE;
196                 devctl &= ~MUSB_DEVCTL_SESSION;
197
198                 MUSB_DEV_MODE(musb);
199         }
200         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
201
202         DBG(1, "VBUS %s, devctl %02x "
203                 /* otg %3x conf %08x prcm %08x */ "\n",
204                 otg_state_string(musb),
205                 musb_readb(musb->mregs, MUSB_DEVCTL));
206 }
207 static int omap_set_power(struct otg_transceiver *x, unsigned mA)
208 {
209         return 0;
210 }
211
212 static int musb_platform_resume(struct musb *musb);
213
214 int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
215 {
216         struct usb_hcd  *hcd;
217         struct usb_bus  *host;
218         u8              devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
219
220         devctl |= MUSB_DEVCTL_SESSION;
221         musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
222
223         switch (musb_mode) {
224 #ifdef CONFIG_USB_MUSB_HDRC_HCD
225         case MUSB_HOST:
226                 hcd = musb_to_hcd(musb);
227                 host = hcd_to_bus(hcd);
228
229                 otg_set_host(musb->xceiv, host);
230                 break;
231 #endif
232 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
233         case MUSB_PERIPHERAL:
234                 otg_set_peripheral(musb->xceiv, &musb->g);
235                 break;
236 #endif
237 #ifdef CONFIG_USB_MUSB_OTG
238         case MUSB_OTG:
239                 break;
240 #endif
241         default:
242                 return -EINVAL;
243         }
244         return 0;
245 }
246
247 int __init musb_platform_init(struct musb *musb)
248 {
249         struct otg_transceiver *x = otg_get_transceiver();
250         u32 l;
251
252 #if defined(CONFIG_ARCH_OMAP2430)
253         omap_cfg_reg(AE5_2430_USB0HS_STP);
254 #endif
255
256         musb->suspendm = true;
257         musb->xceiv = x;
258         musb_platform_resume(musb);
259
260         l = omap_readl(OTG_SYSCONFIG);
261         l &= ~ENABLEWAKEUP;     /* disable wakeup */
262         l &= ~NOSTDBY;          /* remove possible nostdby */
263         l |= SMARTSTDBY;        /* enable smart standby */
264         l &= ~AUTOIDLE;         /* disable auto idle */
265         l &= ~NOIDLE;           /* remove possible noidle */
266         l |= SMARTIDLE;         /* enable smart idle */
267         /*
268          * MUSB AUTOIDLE don't work in 3430.
269          * Workaround by Richard Woodruff/TI
270          */
271         if (!cpu_is_omap3430())
272                 l |= AUTOIDLE;  /* enable auto idle */
273         omap_writel(l, OTG_SYSCONFIG);
274
275         l = omap_readl(OTG_INTERFSEL);
276         l |= ULPI_12PIN;
277         omap_writel(l, OTG_INTERFSEL);
278
279         pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
280                         "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
281                         omap_readl(OTG_REVISION), omap_readl(OTG_SYSCONFIG),
282                         omap_readl(OTG_SYSSTATUS), omap_readl(OTG_INTERFSEL),
283                         omap_readl(OTG_SIMENABLE));
284
285         omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
286
287         if (is_host_enabled(musb))
288                 musb->board_set_vbus = omap_set_vbus;
289         if (is_peripheral_enabled(musb))
290                 musb->xceiv->set_power = omap_set_power;
291         musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON;
292
293         setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
294         INIT_WORK(&musb->vbus_work, musb_vbus_work);
295
296         return 0;
297 }
298
299 int musb_platform_suspend(struct musb *musb)
300 {
301         u32 l;
302
303         if (!musb->clock)
304                 return 0;
305
306         /* in any role */
307         l = omap_readl(OTG_FORCESTDBY);
308         l |= ENABLEFORCE;       /* enable MSTANDBY */
309         omap_writel(l, OTG_FORCESTDBY);
310
311         l = omap_readl(OTG_SYSCONFIG);
312         l |= ENABLEWAKEUP;      /* enable wakeup */
313         omap_writel(l, OTG_SYSCONFIG);
314
315         if (musb->xceiv->set_suspend)
316                 musb->xceiv->set_suspend(musb->xceiv, 1);
317
318         if (musb->set_clock)
319                 musb->set_clock(musb->clock, 0);
320         else
321                 clk_disable(musb->clock);
322
323         return 0;
324 }
325
326 static int musb_platform_resume(struct musb *musb)
327 {
328         u32 l;
329
330         if (!musb->clock)
331                 return 0;
332
333         if (musb->xceiv->set_suspend)
334                 musb->xceiv->set_suspend(musb->xceiv, 0);
335
336         if (musb->set_clock)
337                 musb->set_clock(musb->clock, 1);
338         else
339                 clk_enable(musb->clock);
340
341         l = omap_readl(OTG_SYSCONFIG);
342         l &= ~ENABLEWAKEUP;     /* disable wakeup */
343         omap_writel(l, OTG_SYSCONFIG);
344
345         l = omap_readl(OTG_FORCESTDBY);
346         l &= ~ENABLEFORCE;      /* disable MSTANDBY */
347         omap_writel(l, OTG_FORCESTDBY);
348
349         return 0;
350 }
351
352
353 int musb_platform_exit(struct musb *musb)
354 {
355
356         omap_vbus_power(musb, 0 /*off*/, 1);
357
358         musb_platform_suspend(musb);
359
360         clk_put(musb->clock);
361         musb->clock = 0;
362
363         return 0;
364 }
365
366 #ifdef CONFIG_PM
367
368 void musb_save_ctx_and_suspend(struct usb_gadget *gadget, int overwrite)
369 {
370         struct musb *musb = gadget_to_musb(gadget);
371         u32 l;
372         unsigned long   flags;
373         unsigned long   tmo;
374
375         spin_lock_irqsave(&musb->lock, flags);
376         if (overwrite)
377                 /* Save register context */
378                 musb_save_ctx(musb);
379         spin_unlock_irqrestore(&musb->lock, flags);
380
381         DBG(3, "allow sleep\n");
382         /* Do soft reset. This needs to be done with broken AUTOIDLE */
383         tmo = jiffies + msecs_to_jiffies(300);
384         omap_writel(SOFTRST, OTG_SYSCONFIG);
385         while (!omap_readl(OTG_SYSSTATUS)) {
386                 if (time_after(jiffies, tmo)) {
387                         WARN(1, "musb failed to recover from reset!");
388                         break;
389                 }
390         }
391
392         l = omap_readl(OTG_FORCESTDBY);
393         l |= ENABLEFORCE;       /* enable MSTANDBY */
394         omap_writel(l, OTG_FORCESTDBY);
395
396         l = ENABLEWAKEUP;       /* enable wakeup */
397         omap_writel(l, OTG_SYSCONFIG);
398         /* Use AUTOIDLE here or the device may fail to hit sleep */
399         l |= AUTOIDLE;
400         omap_writel(l, OTG_SYSCONFIG);
401
402         if (musb->board && musb->board->xceiv_power)
403                 musb->board->xceiv_power(0);
404         /* Now it's safe to get rid of the buggy AUTOIDLE */
405         l &= ~AUTOIDLE;
406         omap_writel(l, OTG_SYSCONFIG);
407
408         musb->is_charger = 0;
409
410         /* clear constraints */
411         if (musb->board && musb->board->set_pm_limits)
412                 musb->board->set_pm_limits(musb->controller, 0);
413 }
414 EXPORT_SYMBOL_GPL(musb_save_ctx_and_suspend);
415
416 void musb_restore_ctx_and_resume(struct usb_gadget *gadget)
417 {
418         struct musb *musb = gadget_to_musb(gadget);
419         u32 l;
420         u8 r;
421         unsigned long   flags;
422
423         DBG(3, "restoring register context\n");
424
425         if (musb->board && musb->board->xceiv_power)
426                 musb->board->xceiv_power(1);
427
428         spin_lock_irqsave(&musb->lock, flags);
429         if (musb->set_clock)
430                 musb->set_clock(musb->clock, 1);
431         else
432                 clk_enable(musb->clock);
433
434         /* Recover OTG control */
435         r = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL);
436         r |= ISP1704_OTG_CTRL_IDPULLUP | ISP1704_OTG_CTRL_DP_PULLDOWN;
437         musb_ulpi_writeb(musb->mregs, ISP1704_OTG_CTRL, r);
438
439         /* Recover FUNC control */
440         r = ISP1704_FUNC_CTRL_FULL_SPEED;
441         r |= ISP1704_FUNC_CTRL_SUSPENDM | ISP1704_FUNC_CTRL_RESET;
442         musb_ulpi_writeb(musb->mregs, ISP1704_FUNC_CTRL, r);
443
444         l = omap_readl(OTG_SYSCONFIG);
445         l &= ~ENABLEWAKEUP;     /* disable wakeup */
446         omap_writel(l, OTG_SYSCONFIG);
447
448         l = omap_readl(OTG_FORCESTDBY);
449         l &= ~ENABLEFORCE;      /* disable MSTANDBY */
450         omap_writel(l, OTG_FORCESTDBY);
451
452         l = omap_readl(OTG_SYSCONFIG);
453         l &= ~ENABLEWAKEUP;     /* disable wakeup */
454         l &= ~NOSTDBY;          /* remove possible nostdby */
455         l |= SMARTSTDBY;        /* enable smart standby */
456         l &= ~AUTOIDLE;         /* disable auto idle */
457         l &= ~NOIDLE;           /* remove possible noidle */
458         l |= SMARTIDLE;         /* enable smart idle */
459         omap_writel(l, OTG_SYSCONFIG);
460
461         l = omap_readl(OTG_INTERFSEL);
462         l |= ULPI_12PIN;
463         omap_writel(l, OTG_INTERFSEL);
464
465         /* Restore register context */
466         musb_restore_ctx(musb);
467
468         /* set constraints */
469         schedule_work(&musb->vbus_work);
470         spin_unlock_irqrestore(&musb->lock, flags);
471 }
472 EXPORT_SYMBOL_GPL(musb_restore_ctx_and_resume);
473 #endif