2 * TUSB6010 USB 2.0 OTG Dual Role controller
4 * Copyright (C) 2006 Nokia Corporation
5 * Jarkko Nikula <jarkko.nikula@nokia.com>
6 * Tony Lindgren <tony@atomide.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 * - Driver assumes that interface to external host (main CPU) is
14 * configured for NOR FLASH interface instead of VLYNQ serial
18 #include <linux/config.h>
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/init.h>
23 #include <linux/usb.h>
24 #include <linux/irq.h>
25 #include <linux/platform_device.h>
31 * TUSB 6010 may use a parallel bus that doesn't support byte ops;
32 * so both loading and unloading FIFOs need explicit byte counts.
35 void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf)
37 void __iomem *ep_conf = hw_ep->conf;
38 void __iomem *fifo = hw_ep->fifo;
39 u8 epnum = hw_ep->bLocalEnd;
46 DBG(3, "%cX ep%d count %d bufp %p\n", 'T', epnum, len, bufp);
49 musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
50 TUSB_EP_CONFIG_XFR_SIZE(len));
52 musb_writel(ep_conf, 0, TUSB_EP0_CONFIG_DIR_TX |
53 TUSB_EP0_CONFIG_XFR_SIZE(len));
55 /* Write 32-bit blocks from buffer to FIFO
56 * REVISIT: Optimize for burst ... writesl/writesw
59 if (((unsigned long)bufp & 0x3) == 0) {
60 for (i = 0; i < (len / 4); i++ ) {
63 musb_writel(fifo, 0, val);
65 } else if (((unsigned long)bufp & 0x2) == 0x2) {
66 for (i = 0; i < (len / 4); i++ ) {
67 val = (u32)(*(u16 *)bufp);
69 val |= (*(u16 *)bufp) << 16;
71 musb_writel(fifo, 0, val);
74 for (i = 0; i < (len / 4); i++ ) {
75 memcpy(&val, bufp, 4);
77 musb_writel(fifo, 0, val);
80 remain = len - (i * 4);
85 /* Write rest of 1-3 bytes from buffer into FIFO */
86 memcpy(&val, bufp, remain);
87 musb_writel(fifo, 0, val);
91 void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf)
93 void __iomem *ep_conf = hw_ep->conf;
94 void __iomem *fifo = hw_ep->fifo;
95 u8 epnum = hw_ep->bLocalEnd;
100 DBG(3, "%cX ep%d count %d buf %p\n", 'R', epnum, len, bufp);
103 musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
104 TUSB_EP_CONFIG_XFR_SIZE(len));
106 musb_writel(ep_conf, 0, TUSB_EP0_CONFIG_XFR_SIZE(len));
108 /* Read 32-bit blocks from FIFO to buffer
109 * REVISIT: Optimize for burst ... writesl/writesw
112 if (((unsigned long)bufp & 0x3) == 0) {
113 for (i = 0; i < (len / 4); i++) {
114 val = musb_readl(fifo, 0);
118 } else if (((unsigned long)bufp & 0x2) == 0x2) {
119 for (i = 0; i < (len / 4); i++) {
120 val = musb_readl(fifo, 0);
121 *(u16 *)bufp = (u16)(val & 0xffff);
123 *(u16 *)bufp = (u16)(val >> 16);
127 for (i = 0; i < (len / 4); i++) {
128 val = musb_readl(fifo, 0);
129 memcpy(bufp, &val, 4);
133 remain = len - (i * 4);
138 /* Read rest of 1-3 bytes from FIFO */
139 val = musb_readl(fifo, 0);
140 memcpy(bufp, &val, remain);
145 * Enables TUSB6010 to use VBUS as power source in peripheral mode.
147 static inline void tusb_enable_vbus_charge(struct musb *musb)
149 void __iomem *base = musb->ctrl_base;
152 musb_writel(base, TUSB_PRCM_WAKEUP_MASK, 0xffff);
153 reg = musb_readl(base, TUSB_PRCM_MNGMT);
154 reg &= ~TUSB_PRCM_MNGMT_SUSPEND_MASK;
155 reg |= TUSB_PRCM_MNGMT_CPEN_MASK;
156 musb_writel(base, TUSB_PRCM_MNGMT, reg);
160 * Idles TUSB6010 until next wake-up event interrupt. Use all wake-up
161 * events for now. Note that TUSB will not respond if NOR chip select
162 * wake-up event is masked. Also note that any access to TUSB will wake
165 static inline void tusb_allow_idle(struct musb *musb, int wakeup_mask)
167 void __iomem *base = musb->ctrl_base;
170 musb_writel(base, TUSB_PRCM_WAKEUP_MASK, wakeup_mask);
171 reg = musb_readl(base, TUSB_PRCM_MNGMT);
172 reg &= ~TUSB_PRCM_MNGMT_CPEN_MASK;
173 reg |= TUSB_PRCM_MNGMT_SUSPEND_MASK;
174 musb_writel(base, TUSB_PRCM_MNGMT, reg);
178 * Updates cable VBUS status. Caller must take care of locking.
180 int musb_platform_get_vbus_status(struct musb *musb)
182 void __iomem *base = musb->ctrl_base;
183 u32 otg_stat, prcm_mngmt;
186 otg_stat = musb_readl(base, TUSB_DEV_OTG_STAT);
187 prcm_mngmt = musb_readl(base, TUSB_PRCM_MNGMT);
189 /* Temporarily enable VBUS detection if it was disabled for
190 * suspend mode. Unless it's enabled otg_stat and devctl will
191 * not show correct VBUS state.
193 if (!(prcm_mngmt & TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN)) {
194 u32 tmp = prcm_mngmt;
195 tmp |= TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN;
196 musb_writel(base, TUSB_PRCM_MNGMT, tmp);
197 otg_stat = musb_readl(base, TUSB_DEV_OTG_STAT);
198 musb_writel(base, TUSB_PRCM_MNGMT, prcm_mngmt);
201 if (otg_stat & TUSB_DEV_OTG_STAT_VBUS_SENSE)
208 * Sets the TUSB6010 idles mode in peripheral mode depending on the
209 * gadget driver state and cable VBUS status. Needs to be called as
210 * the last function everywhere where there is register access to
211 * TUSB6010 because of the NOR flash wake-up capability.
212 * Caller must take care of locking.
214 void musb_platform_try_idle(struct musb *musb)
218 /* Suspend with only NOR flash wake-up event enabled if no
219 * gadget driver is active.
221 if (musb->xceiv.state == OTG_STATE_UNDEFINED) {
222 wakeup_mask = 0xffff & ~TUSB_PRCM_WNORCS;
223 tusb_allow_idle(musb, wakeup_mask);
227 /* Use VBUS as power source if available, otherwise suspend
228 * with all wake-up events enabled.
230 * FIXME only B-device state machine ever _consumes_ VBUS.
232 if (musb_platform_get_vbus_status(musb))
233 tusb_enable_vbus_charge(musb);
235 wakeup_mask = TUSB_PRCM_WLD;
236 tusb_allow_idle(musb, wakeup_mask);
240 irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r)
242 struct musb *musb = __hci;
243 void __iomem *base = musb->ctrl_base;
245 u32 dma_src, int_src, otg_stat, musb_src = 0;
247 spin_lock_irqsave(&musb->Lock, flags);
249 dma_src = musb_readl(base, TUSB_DMA_INT_SRC);
250 int_src = musb_readl(base, TUSB_INT_SRC) & ~TUSB_INT_SRC_RESERVED_BITS;
251 otg_stat = musb_readl(base, TUSB_DEV_OTG_STAT);
253 DBG(3, "TUSB interrupt dma: %08x int: %08x otg: %08x\n",
254 dma_src, int_src, otg_stat);
261 if (otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS) {
262 /* ID pin is up. Either A-plug was removed or TUSB6010
263 * is in peripheral mode */
265 /* Still in pheripheral mode? */
266 if ((int_src & TUSB_INT_SRC_ID_STATUS_CHNG)) {
267 DBG(3, "tusb: Status change\n");
272 /* Peripheral suspend. Cable may be disconnected, try to idle */
273 if (int_src & TUSB_INT_SRC_USB_IP_SUSPEND) {
274 musb->status |= MUSB_VBUS_STATUS_CHG;
275 schedule_work(&musb->irq_work);
278 /* Connect and disconnect for host mode */
279 if (int_src & TUSB_INT_SRC_USB_IP_CONN) {
280 DBG(3, "tusb: Connected\n");
282 else if (int_src & TUSB_INT_SRC_USB_IP_DISCON) {
283 DBG(3, "tusb: Disconnected\n");
286 /* VBUS state change */
287 if ((int_src & TUSB_INT_SRC_VBUS_SENSE_CHNG) ||
288 (int_src & TUSB_INT_SRC_USB_IP_VBUS_ERR))
290 musb->status |= MUSB_VBUS_STATUS_CHG;
291 schedule_work(&musb->irq_work);
294 DBG(3, "tusb: VBUS changed. VBUS state %d\n",
295 (otg_stat & TUSB_DEV_OTG_STAT_VBUS_SENSE) ? 1 : 0);
296 if (!(otg_stat & TUSB_DEV_OTG_STAT_VBUS_SENSE) &&
297 !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) {
298 /* VBUS went off and ID pin is down */
299 DBG(3, "tusb: No VBUS, starting session\n");
300 /* Start session again, VBUS will be enabled */
301 musb_writeb(musb_base, MGC_O_HDRC_DEVCTL,
302 MGC_M_DEVCTL_SESSION);
308 if (int_src & TUSB_INT_SRC_ID_STATUS_CHNG) {
309 DBG(3, "tusb: ID pin changed. State is %d\n",
310 (musb_readl(base, TUSB_DEV_OTG_STAT) &
311 TUSB_DEV_OTG_STAT_ID_STATUS) ? 1 : 0);
314 /* OTG timer expiration */
315 if (int_src & TUSB_INT_SRC_OTG_TIMEOUT) {
316 DBG(3, "tusb: OTG timer expired\n");
317 musb_writel(base, TUSB_DEV_OTG_TIMER,
318 musb_readl(base, TUSB_DEV_OTG_TIMER) |
319 TUSB_DEV_OTG_TIMER_ENABLE);
322 /* TX dma callback must be handled here, RX dma callback is
323 * handled in tusb_omap_dma_cb.
325 if ((int_src & TUSB_INT_SRC_TXRX_DMA_DONE) && dma_src) {
326 u32 real_dma_src = musb_readl(base, TUSB_DMA_INT_MASK);
327 real_dma_src = ~real_dma_src & dma_src;
328 if (tusb_dma_omap()) {
329 int tx_source = (real_dma_src & 0xffff);
332 for (i = 1; i <= 15; i++) {
333 if (tx_source & (1 << i)) {
334 DBG(1, "completing ep%i %s\n", i, "tx");
335 musb_dma_completion(musb, i, 1);
339 musb_writel(base, TUSB_DMA_INT_CLEAR, dma_src);
342 /* EP interrupts. In OCP mode tusb6010 mirrors the MUSB * interrupts */
343 if (int_src & (TUSB_INT_SRC_USB_IP_TX | TUSB_INT_SRC_USB_IP_RX)) {
344 musb_src = musb_readl(base, TUSB_USBIP_INT_SRC);
345 musb_writel(base, TUSB_USBIP_INT_CLEAR, musb_src);
346 musb->int_rx = (((musb_src >> 16) & 0xffff) << 1);
347 musb->int_tx = (musb_src & 0xffff);
349 musb->int_usb = (int_src & 0xff);
350 if (musb->int_usb || musb->int_rx || musb->int_tx)
351 musb_interrupt(musb);
353 /* Acknowledge wake-up source interrupts */
354 if (int_src & TUSB_INT_SRC_DEV_WAKEUP) {
355 u32 reg = musb_readl(base, TUSB_PRCM_WAKEUP_SOURCE);
356 musb_writel(base, TUSB_PRCM_WAKEUP_CLEAR, reg);
357 schedule_work(&musb->irq_work);
360 /* Acknowledge TUSB interrupts. Clear only non-reserved bits */
362 musb_writel(base, TUSB_INT_SRC_CLEAR,
363 int_src & ~TUSB_INT_MASK_RESERVED_BITS);
365 spin_unlock_irqrestore(&musb->Lock, flags);
373 * Enables TUSB6010. Caller must take care of locking.
375 * - Check what is unnecessary in MGC_HdrcStart()
376 * - Interrupt should really be IRQT_FALLING level sensitive
378 void musb_platform_enable(struct musb * musb)
380 void __iomem *base = musb->ctrl_base;
382 /* Setup TUSB6010 main interrupt mask. Enable all interrupts except SOF.
383 * REVISIT: Enable and deal with TUSB_INT_SRC_USB_IP_SOF */
384 musb_writel(base, TUSB_INT_MASK, TUSB_INT_SRC_USB_IP_SOF);
386 /* Setup TUSB interrupt, disable DMA and GPIO interrupts */
387 musb_writel(base, TUSB_USBIP_INT_MASK, 0);
388 musb_writel(base, TUSB_DMA_INT_MASK, 0x7fffffff);
389 musb_writel(base, TUSB_GPIO_INT_MASK, 0x1ff);
391 /* Clear all subsystem interrups */
392 musb_writel(base, TUSB_USBIP_INT_CLEAR, 0x7fffffff);
393 musb_writel(base, TUSB_DMA_INT_CLEAR, 0x7fffffff);
394 musb_writel(base, TUSB_GPIO_INT_CLEAR, 0x1ff);
396 /* Acknowledge pending interrupt(s) */
397 musb_writel(base, TUSB_INT_SRC_CLEAR,
398 ~TUSB_INT_MASK_RESERVED_BITS);
401 /* Set OTG timer for about one second */
402 musb_writel(base, TUSB_DEV_OTG_TIMER,
403 TUSB_DEV_OTG_TIMER_ENABLE |
404 TUSB_DEV_OTG_TIMER_VAL(0x3c00000));
407 /* Only 0 clock cycles for minimum interrupt de-assertion time and
408 * interrupt polarity active low seems to work reliably here */
409 musb_writel(base, TUSB_INT_CTRL_CONF,
410 TUSB_INT_CTRL_CONF_INT_RELCYC(0));
412 set_irq_type(musb->nIrq, IRQ_TYPE_LEVEL_LOW);
414 if (is_dma_capable() && dma_off)
415 printk(KERN_WARNING "%s %s: dma not reactivated\n",
416 __FILE__, __FUNCTION__);
422 * Disables TUSB6010. Caller must take care of locking.
424 void musb_platform_disable(struct musb *musb)
426 if (is_dma_capable()) {
427 printk(KERN_WARNING "%s %s: dma still active\n",
428 __FILE__, __FUNCTION__);
434 * Sets up TUSB6010 CPU interface specific signals and registers
435 * Note: Settings optimized for OMAP24xx
437 static void tusb_setup_cpu_interface(struct musb *musb)
439 void __iomem *base = musb->ctrl_base;
441 /* Disable GPIO[7:0] pullups (used as output DMA requests) */
442 musb_writel(base, TUSB_PULLUP_1_CTRL, 0x000000FF);
443 /* Disable all pullups on NOR IF, DMAREQ0 and DMAREQ1 */
444 musb_writel(base, TUSB_PULLUP_2_CTRL, 0x01FFFFFF);
446 /* Turn GPIO[5:0] to DMAREQ[5:0] signals */
447 musb_writel(base, TUSB_GPIO_CONF, TUSB_GPIO_CONF_DMAREQ(0x3f));
449 /* Burst size 16x16 bits, all six DMA requests enabled, DMA request
450 * de-assertion time 2 system clocks p 62 */
451 musb_writel(base, TUSB_DMA_REQ_CONF,
452 TUSB_DMA_REQ_CONF_BURST_SIZE(2) |
453 TUSB_DMA_REQ_CONF_DMA_REQ_EN(0x3f) |
454 TUSB_DMA_REQ_CONF_DMA_REQ_ASSER(2));
456 /* Set 0 wait count for synchronous burst access */
457 musb_writel(base, TUSB_WAIT_COUNT, 1);
460 #define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf)
461 #define TUSB_REV_MINOR(reg_val) (reg_val & 0xf)
463 static int tusb_print_revision(struct musb *musb)
465 void __iomem *base = musb->ctrl_base;
467 pr_info("tusb: Revisions: %s%i.%i %s%i.%i %s%i.%i %s%i.%i\n",
469 TUSB_REV_MAJOR(musb_readl(base, TUSB_PRCM_REV)),
470 TUSB_REV_MINOR(musb_readl(base, TUSB_PRCM_REV)),
472 TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV)),
473 TUSB_REV_MINOR(musb_readl(base, TUSB_INT_CTRL_REV)),
475 TUSB_REV_MAJOR(musb_readl(base, TUSB_GPIO_REV)),
476 TUSB_REV_MINOR(musb_readl(base, TUSB_GPIO_REV)),
478 TUSB_REV_MAJOR(musb_readl(base, TUSB_DMA_CTRL_REV)),
479 TUSB_REV_MINOR(musb_readl(base, TUSB_DMA_CTRL_REV)));
481 return TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV));
484 static int tusb_start(struct musb *musb)
486 void __iomem *base = musb->ctrl_base;
490 if (musb->board_set_power)
491 ret = musb->board_set_power(1);
493 printk(KERN_ERR "tusb: Cannot enable TUSB6010\n");
497 spin_lock_irqsave(&musb->Lock, flags);
499 if (musb_readl(base, TUSB_PROD_TEST_RESET) !=
500 TUSB_PROD_TEST_RESET_VAL) {
501 printk(KERN_ERR "tusb: Unable to detect TUSB6010\n");
505 ret = tusb_print_revision(musb);
507 printk(KERN_ERR "tusb: Unsupported TUSB6010 revision %i\n",
512 /* The uint bit for "USB non-PDR interrupt enable" has to be 1 when
513 * NOR FLASH interface is used */
514 musb_writel(base, TUSB_VLYNQ_CTRL, 8);
516 /* Select PHY free running 60MHz as a system clock */
517 musb_writel(base, TUSB_PRCM_CONF, //FIXME: CPEN should not be needed!
518 TUSB_PRCM_CONF_SFW_CPEN | TUSB_PRCM_CONF_SYS_CLKSEL(1));
520 /* VBus valid timer 1us, disable DFT/Debug and VLYNQ clocks for
521 * power saving, enable VBus detect and session end comparators,
522 * enable IDpullup, enable VBus charging */
523 musb_writel(base, TUSB_PRCM_MNGMT,
524 TUSB_PRCM_MNGMT_VBUS_VALID_TIMER(0xa) |
525 TUSB_PRCM_MNGMT_VBUS_VALID_FLT_EN |
526 TUSB_PRCM_MNGMT_DFT_CLK_DIS |
527 TUSB_PRCM_MNGMT_VLYNQ_CLK_DIS |
528 TUSB_PRCM_MNGMT_OTG_SESS_END_EN |
529 TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN |
530 TUSB_PRCM_MNGMT_OTG_ID_PULLUP);
532 musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE,
533 musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE) |
534 TUSB_PHY_OTG_CTRL_WRPROTECT |
535 TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP |
536 TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN |
537 TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN);
538 musb_writel(base, TUSB_PHY_OTG_CTRL,
539 musb_readl(base, TUSB_PHY_OTG_CTRL) |
540 TUSB_PHY_OTG_CTRL_WRPROTECT |
541 TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP |
542 TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN |
543 TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN);
545 tusb_setup_cpu_interface(musb);
547 spin_unlock_irqrestore(&musb->Lock, flags);
552 if (musb->board_set_power)
553 musb->board_set_power(0);
558 int __devinit musb_platform_init(struct musb *musb)
560 struct platform_device *pdev;
561 struct resource *mem;
564 pdev = to_platform_device(musb->controller);
566 /* dma address for async dma */
567 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
568 musb->async = mem->start;
570 /* dma address for sync dma */
571 mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
573 pr_debug("no sync dma resource?\n");
576 musb->sync = mem->start;
578 /* Offsets from base: VLYNQ at 0x000, MUSB regs at 0x400,
579 * FIFOs at 0x600, TUSB at 0x800
581 musb->pRegs += TUSB_BASE_OFFSET;
583 ret = tusb_start(musb);
585 printk(KERN_ERR "Could not start tusb6010 (%d)\n",
589 musb->isr = tusb_interrupt;
591 musb_platform_try_idle(musb);
596 int musb_platform_exit(struct musb *musb)
598 if (musb->board_set_power)
599 musb->board_set_power(0);