aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/musb/Kconfig5
-rw-r--r--drivers/usb/musb/Makefile4
-rw-r--r--drivers/usb/musb/da8xx.c469
-rw-r--r--drivers/usb/musb/musb_core.h1
4 files changed, 478 insertions, 1 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index cfd38edfcf9e..1dd21c2315e4 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -45,6 +45,9 @@ config USB_MUSB_SOC
45comment "DaVinci 35x and 644x USB support" 45comment "DaVinci 35x and 644x USB support"
46 depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx 46 depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx
47 47
48comment "DA8xx/OMAP-L1x USB support"
49 depends on USB_MUSB_HDRC && ARCH_DAVINCI_DA8XX
50
48comment "OMAP 243x high speed USB support" 51comment "OMAP 243x high speed USB support"
49 depends on USB_MUSB_HDRC && ARCH_OMAP2430 52 depends on USB_MUSB_HDRC && ARCH_OMAP2430
50 53
@@ -144,7 +147,7 @@ config USB_MUSB_HDRC_HCD
144config MUSB_PIO_ONLY 147config MUSB_PIO_ONLY
145 bool 'Disable DMA (always use PIO)' 148 bool 'Disable DMA (always use PIO)'
146 depends on USB_MUSB_HDRC 149 depends on USB_MUSB_HDRC
147 default y if USB_TUSB6010 150 default USB_TUSB6010 || ARCH_DAVINCI_DA8XX
148 help 151 help
149 All data is copied between memory and FIFO by the CPU. 152 All data is copied between memory and FIFO by the CPU.
150 DMA controllers are ignored. 153 DMA controllers are ignored.
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 9705f716386e..f664ecfa21c4 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -10,6 +10,10 @@ ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
10 musb_hdrc-objs += davinci.o 10 musb_hdrc-objs += davinci.o
11endif 11endif
12 12
13ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y)
14 musb_hdrc-objs += da8xx.o
15endif
16
13ifeq ($(CONFIG_USB_TUSB6010),y) 17ifeq ($(CONFIG_USB_TUSB6010),y)
14 musb_hdrc-objs += tusb6010.o 18 musb_hdrc-objs += tusb6010.o
15endif 19endif
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
new file mode 100644
index 000000000000..84427bebbf62
--- /dev/null
+++ b/drivers/usb/musb/da8xx.c
@@ -0,0 +1,469 @@
1/*
2 * Texas Instruments DA8xx/OMAP-L1x "glue layer"
3 *
4 * Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
5 *
6 * Based on the DaVinci "glue layer" code.
7 * Copyright (C) 2005-2006 by Texas Instruments
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
29#include <linux/init.h>
30#include <linux/clk.h>
31#include <linux/io.h>
32
33#include <mach/da8xx.h>
34#include <mach/usb.h>
35
36#include "musb_core.h"
37
38/*
39 * DA8XX specific definitions
40 */
41
42/* USB 2.0 OTG module registers */
43#define DA8XX_USB_REVISION_REG 0x00
44#define DA8XX_USB_CTRL_REG 0x04
45#define DA8XX_USB_STAT_REG 0x08
46#define DA8XX_USB_EMULATION_REG 0x0c
47#define DA8XX_USB_MODE_REG 0x10 /* Transparent, CDC, [Generic] RNDIS */
48#define DA8XX_USB_AUTOREQ_REG 0x14
49#define DA8XX_USB_SRP_FIX_TIME_REG 0x18
50#define DA8XX_USB_TEARDOWN_REG 0x1c
51#define DA8XX_USB_INTR_SRC_REG 0x20
52#define DA8XX_USB_INTR_SRC_SET_REG 0x24
53#define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28
54#define DA8XX_USB_INTR_MASK_REG 0x2c
55#define DA8XX_USB_INTR_MASK_SET_REG 0x30
56#define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34
57#define DA8XX_USB_INTR_SRC_MASKED_REG 0x38
58#define DA8XX_USB_END_OF_INTR_REG 0x3c
59#define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2))
60
61/* Control register bits */
62#define DA8XX_SOFT_RESET_MASK 1
63
64#define DA8XX_USB_TX_EP_MASK 0x1f /* EP0 + 4 Tx EPs */
65#define DA8XX_USB_RX_EP_MASK 0x1e /* 4 Rx EPs */
66
67/* USB interrupt register bits */
68#define DA8XX_INTR_USB_SHIFT 16
69#define DA8XX_INTR_USB_MASK (0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */
70 /* interrupts and DRVVBUS interrupt */
71#define DA8XX_INTR_DRVVBUS 0x100
72#define DA8XX_INTR_RX_SHIFT 8
73#define DA8XX_INTR_RX_MASK (DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT)
74#define DA8XX_INTR_TX_SHIFT 0
75#define DA8XX_INTR_TX_MASK (DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT)
76
77#define DA8XX_MENTOR_CORE_OFFSET 0x400
78
79#define CFGCHIP2 IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG)
80
81/*
82 * REVISIT (PM): we should be able to keep the PHY in low power mode most
83 * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0
84 * and, when in host mode, autosuspending idle root ports... PHY_PLLON
85 * (overriding SUSPENDM?) then likely needs to stay off.
86 */
87
88static inline void phy_on(void)
89{
90 u32 cfgchip2 = __raw_readl(CFGCHIP2);
91
92 /*
93 * Start the on-chip PHY and its PLL.
94 */
95 cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN);
96 cfgchip2 |= CFGCHIP2_PHY_PLLON;
97 __raw_writel(cfgchip2, CFGCHIP2);
98
99 pr_info("Waiting for USB PHY clock good...\n");
100 while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD))
101 cpu_relax();
102}
103
104static inline void phy_off(void)
105{
106 u32 cfgchip2 = __raw_readl(CFGCHIP2);
107
108 /*
109 * Ensure that USB 1.1 reference clock is not being sourced from
110 * USB 2.0 PHY. Otherwise do not power down the PHY.
111 */
112 if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX) &&
113 (cfgchip2 & CFGCHIP2_USB1SUSPENDM)) {
114 pr_warning("USB 1.1 clocked from USB 2.0 PHY -- "
115 "can't power it down\n");
116 return;
117 }
118
119 /*
120 * Power down the on-chip PHY.
121 */
122 cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN;
123 __raw_writel(cfgchip2, CFGCHIP2);
124}
125
126/*
127 * Because we don't set CTRL.UINT, it's "important" to:
128 * - not read/write INTRUSB/INTRUSBE (except during
129 * initial setup, as a workaround);
130 * - use INTSET/INTCLR instead.
131 */
132
133/**
134 * musb_platform_enable - enable interrupts
135 */
136void musb_platform_enable(struct musb *musb)
137{
138 void __iomem *reg_base = musb->ctrl_base;
139 u32 mask;
140
141 /* Workaround: setup IRQs through both register sets. */
142 mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) |
143 ((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) |
144 DA8XX_INTR_USB_MASK;
145 musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask);
146
147 /* Force the DRVVBUS IRQ so we can start polling for ID change. */
148 if (is_otg_enabled(musb))
149 musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG,
150 DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT);
151}
152
153/**
154 * musb_platform_disable - disable HDRC and flush interrupts
155 */
156void musb_platform_disable(struct musb *musb)
157{
158 void __iomem *reg_base = musb->ctrl_base;
159
160 musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG,
161 DA8XX_INTR_USB_MASK |
162 DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK);
163 musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
164 musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
165}
166
167#ifdef CONFIG_USB_MUSB_HDRC_HCD
168#define portstate(stmt) stmt
169#else
170#define portstate(stmt)
171#endif
172
173static void da8xx_set_vbus(struct musb *musb, int is_on)
174{
175 WARN_ON(is_on && is_peripheral_active(musb));
176}
177
178#define POLL_SECONDS 2
179
180static struct timer_list otg_workaround;
181
182static void otg_timer(unsigned long _musb)
183{
184 struct musb *musb = (void *)_musb;
185 void __iomem *mregs = musb->mregs;
186 u8 devctl;
187 unsigned long flags;
188
189 /*
190 * We poll because DaVinci's won't expose several OTG-critical
191 * status change events (from the transceiver) otherwise.
192 */
193 devctl = musb_readb(mregs, MUSB_DEVCTL);
194 DBG(7, "Poll devctl %02x (%s)\n", devctl, otg_state_string(musb));
195
196 spin_lock_irqsave(&musb->lock, flags);
197 switch (musb->xceiv->state) {
198 case OTG_STATE_A_WAIT_BCON:
199 devctl &= ~MUSB_DEVCTL_SESSION;
200 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
201
202 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
203 if (devctl & MUSB_DEVCTL_BDEVICE) {
204 musb->xceiv->state = OTG_STATE_B_IDLE;
205 MUSB_DEV_MODE(musb);
206 } else {
207 musb->xceiv->state = OTG_STATE_A_IDLE;
208 MUSB_HST_MODE(musb);
209 }
210 break;
211 case OTG_STATE_A_WAIT_VFALL:
212 /*
213 * Wait till VBUS falls below SessionEnd (~0.2 V); the 1.3
214 * RTL seems to mis-handle session "start" otherwise (or in
215 * our case "recover"), in routine "VBUS was valid by the time
216 * VBUSERR got reported during enumeration" cases.
217 */
218 if (devctl & MUSB_DEVCTL_VBUS) {
219 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
220 break;
221 }
222 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
223 musb_writel(musb->ctrl_base, DA8XX_USB_INTR_SRC_SET_REG,
224 MUSB_INTR_VBUSERROR << DA8XX_INTR_USB_SHIFT);
225 break;
226 case OTG_STATE_B_IDLE:
227 if (!is_peripheral_enabled(musb))
228 break;
229
230 /*
231 * There's no ID-changed IRQ, so we have no good way to tell
232 * when to switch to the A-Default state machine (by setting
233 * the DEVCTL.Session bit).
234 *
235 * Workaround: whenever we're in B_IDLE, try setting the
236 * session flag every few seconds. If it works, ID was
237 * grounded and we're now in the A-Default state machine.
238 *
239 * NOTE: setting the session flag is _supposed_ to trigger
240 * SRP but clearly it doesn't.
241 */
242 musb_writeb(mregs, MUSB_DEVCTL, devctl | MUSB_DEVCTL_SESSION);
243 devctl = musb_readb(mregs, MUSB_DEVCTL);
244 if (devctl & MUSB_DEVCTL_BDEVICE)
245 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
246 else
247 musb->xceiv->state = OTG_STATE_A_IDLE;
248 break;
249 default:
250 break;
251 }
252 spin_unlock_irqrestore(&musb->lock, flags);
253}
254
255void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
256{
257 static unsigned long last_timer;
258
259 if (!is_otg_enabled(musb))
260 return;
261
262 if (timeout == 0)
263 timeout = jiffies + msecs_to_jiffies(3);
264
265 /* Never idle if active, or when VBUS timeout is not set as host */
266 if (musb->is_active || (musb->a_wait_bcon == 0 &&
267 musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
268 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
269 del_timer(&otg_workaround);
270 last_timer = jiffies;
271 return;
272 }
273
274 if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) {
275 DBG(4, "Longer idle timer already pending, ignoring...\n");
276 return;
277 }
278 last_timer = timeout;
279
280 DBG(4, "%s inactive, starting idle timer for %u ms\n",
281 otg_state_string(musb), jiffies_to_msecs(timeout - jiffies));
282 mod_timer(&otg_workaround, timeout);
283}
284
285static irqreturn_t da8xx_interrupt(int irq, void *hci)
286{
287 struct musb *musb = hci;
288 void __iomem *reg_base = musb->ctrl_base;
289 unsigned long flags;
290 irqreturn_t ret = IRQ_NONE;
291 u32 status;
292
293 spin_lock_irqsave(&musb->lock, flags);
294
295 /*
296 * NOTE: DA8XX shadows the Mentor IRQs. Don't manage them through
297 * the Mentor registers (except for setup), use the TI ones and EOI.
298 */
299
300 /* Acknowledge and handle non-CPPI interrupts */
301 status = musb_readl(reg_base, DA8XX_USB_INTR_SRC_MASKED_REG);
302 if (!status)
303 goto eoi;
304
305 musb_writel(reg_base, DA8XX_USB_INTR_SRC_CLEAR_REG, status);
306 DBG(4, "USB IRQ %08x\n", status);
307
308 musb->int_rx = (status & DA8XX_INTR_RX_MASK) >> DA8XX_INTR_RX_SHIFT;
309 musb->int_tx = (status & DA8XX_INTR_TX_MASK) >> DA8XX_INTR_TX_SHIFT;
310 musb->int_usb = (status & DA8XX_INTR_USB_MASK) >> DA8XX_INTR_USB_SHIFT;
311
312 /*
313 * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
314 * DA8xx's missing ID change IRQ. We need an ID change IRQ to
315 * switch appropriately between halves of the OTG state machine.
316 * Managing DEVCTL.Session per Mentor docs requires that we know its
317 * value but DEVCTL.BDevice is invalid without DEVCTL.Session set.
318 * Also, DRVVBUS pulses for SRP (but not at 5 V)...
319 */
320 if (status & (DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT)) {
321 int drvvbus = musb_readl(reg_base, DA8XX_USB_STAT_REG);
322 void __iomem *mregs = musb->mregs;
323 u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
324 int err;
325
326 err = is_host_enabled(musb) && (musb->int_usb &
327 MUSB_INTR_VBUSERROR);
328 if (err) {
329 /*
330 * The Mentor core doesn't debounce VBUS as needed
331 * to cope with device connect current spikes. This
332 * means it's not uncommon for bus-powered devices
333 * to get VBUS errors during enumeration.
334 *
335 * This is a workaround, but newer RTL from Mentor
336 * seems to allow a better one: "re"-starting sessions
337 * without waiting for VBUS to stop registering in
338 * devctl.
339 */
340 musb->int_usb &= ~MUSB_INTR_VBUSERROR;
341 musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
342 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
343 WARNING("VBUS error workaround (delay coming)\n");
344 } else if (is_host_enabled(musb) && drvvbus) {
345 MUSB_HST_MODE(musb);
346 musb->xceiv->default_a = 1;
347 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
348 portstate(musb->port1_status |= USB_PORT_STAT_POWER);
349 del_timer(&otg_workaround);
350 } else {
351 musb->is_active = 0;
352 MUSB_DEV_MODE(musb);
353 musb->xceiv->default_a = 0;
354 musb->xceiv->state = OTG_STATE_B_IDLE;
355 portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
356 }
357
358 DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
359 drvvbus ? "on" : "off",
360 otg_state_string(musb),
361 err ? " ERROR" : "",
362 devctl);
363 ret = IRQ_HANDLED;
364 }
365
366 if (musb->int_tx || musb->int_rx || musb->int_usb)
367 ret |= musb_interrupt(musb);
368
369 eoi:
370 /* EOI needs to be written for the IRQ to be re-asserted. */
371 if (ret == IRQ_HANDLED || status)
372 musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
373
374 /* Poll for ID change */
375 if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
376 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
377
378 spin_unlock_irqrestore(&musb->lock, flags);
379
380 return ret;
381}
382
383int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
384{
385 u32 cfgchip2 = __raw_readl(CFGCHIP2);
386
387 cfgchip2 &= ~CFGCHIP2_OTGMODE;
388 switch (musb_mode) {
389#ifdef CONFIG_USB_MUSB_HDRC_HCD
390 case MUSB_HOST: /* Force VBUS valid, ID = 0 */
391 cfgchip2 |= CFGCHIP2_FORCE_HOST;
392 break;
393#endif
394#ifdef CONFIG_USB_GADGET_MUSB_HDRC
395 case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
396 cfgchip2 |= CFGCHIP2_FORCE_DEVICE;
397 break;
398#endif
399#ifdef CONFIG_USB_MUSB_OTG
400 case MUSB_OTG: /* Don't override the VBUS/ID comparators */
401 cfgchip2 |= CFGCHIP2_NO_OVERRIDE;
402 break;
403#endif
404 default:
405 DBG(2, "Trying to set unsupported mode %u\n", musb_mode);
406 }
407
408 __raw_writel(cfgchip2, CFGCHIP2);
409 return 0;
410}
411
412int __init musb_platform_init(struct musb *musb, void *board_data)
413{
414 void __iomem *reg_base = musb->ctrl_base;
415 u32 rev;
416
417 musb->mregs += DA8XX_MENTOR_CORE_OFFSET;
418
419 clk_enable(musb->clock);
420
421 /* Returns zero if e.g. not clocked */
422 rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG);
423 if (!rev)
424 goto fail;
425
426 usb_nop_xceiv_register();
427 musb->xceiv = otg_get_transceiver();
428 if (!musb->xceiv)
429 goto fail;
430
431 if (is_host_enabled(musb))
432 setup_timer(&otg_workaround, otg_timer, (unsigned long)musb);
433
434 musb->board_set_vbus = da8xx_set_vbus;
435
436 /* Reset the controller */
437 musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK);
438
439 /* Start the on-chip PHY and its PLL. */
440 phy_on();
441
442 msleep(5);
443
444 /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */
445 pr_debug("DA8xx OTG revision %08x, PHY %03x, control %02x\n",
446 rev, __raw_readl(CFGCHIP2),
447 musb_readb(reg_base, DA8XX_USB_CTRL_REG));
448
449 musb->isr = da8xx_interrupt;
450 return 0;
451fail:
452 clk_disable(musb->clock);
453 return -ENODEV;
454}
455
456int musb_platform_exit(struct musb *musb)
457{
458 if (is_host_enabled(musb))
459 del_timer_sync(&otg_workaround);
460
461 phy_off();
462
463 otg_put_transceiver(musb->xceiv);
464 usb_nop_xceiv_unregister();
465
466 clk_disable(musb->clock);
467
468 return 0;
469}
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 91d67794e350..2a8236216dc7 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -599,6 +599,7 @@ extern void musb_hnp_stop(struct musb *musb);
599extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); 599extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
600 600
601#if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ 601#if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
602 defined(CONFIG_ARCH_DAVINCI_DA8XX) || \
602 defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ 603 defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
603 defined(CONFIG_ARCH_OMAP4) 604 defined(CONFIG_ARCH_OMAP4)
604extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); 605extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);