]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'musb'
authorTony Lindgren <tony@atomide.com>
Thu, 18 Dec 2008 12:37:02 +0000 (14:37 +0200)
committerTony Lindgren <tony@atomide.com>
Thu, 18 Dec 2008 12:37:02 +0000 (14:37 +0200)
19 files changed:
MAINTAINERS
drivers/usb/gadget/Kconfig
drivers/usb/musb/Kconfig
drivers/usb/musb/Makefile
drivers/usb/musb/blackfin.c [new file with mode: 0644]
drivers/usb/musb/blackfin.h [new file with mode: 0644]
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_dma.h
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_io.h
drivers/usb/musb/musb_regs.h
drivers/usb/musb/musbhsdma.c
drivers/usb/musb/musbhsdma.h [new file with mode: 0644]
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
include/linux/usb/musb.h

index 24741de12a39b8d680974f385770842e0b376bf0..f79a60e79c516d4fa531a4ad09236eddeba8c6dd 100644 (file)
@@ -2979,6 +2979,7 @@ MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
 P:     Felipe Balbi
 M:     felipe.balbi@nokia.com
 L:     linux-usb@vger.kernel.org
+T:     git gitorious.org:/musb/mainline.git
 S:     Maintained
 
 MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
index dd4cd5a5137087a31827f11a5932781b6ba8637b..9aecb422c39ffdc269db23aff6a40039f9fa024d 100644 (file)
@@ -297,13 +297,13 @@ config USB_S3C2410_DEBUG
 
 # musb builds in ../musb along with host support
 config USB_GADGET_MUSB_HDRC
-       boolean "Inventra HDRC USB Peripheral (TI, ...)"
+       boolean "Inventra HDRC USB Peripheral (TI, ADI, ...)"
        depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
        select USB_GADGET_DUALSPEED
        select USB_GADGET_SELECTED
        help
          This OTG-capable silicon IP is used in dual designs including
-         the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
+         the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin
 
 config USB_GADGET_M66592
        boolean "Renesas M66592 USB Peripheral Controller"
index 4b9542bbb35cee8b3231999bd436491a967e79b8..5af7379cd9a3a73157b0d4214c796c521fdd20ca 100644 (file)
@@ -11,7 +11,7 @@ config USB_MUSB_HDRC
        depends on (USB || USB_GADGET) && HAVE_CLK
        depends on !SUPERH
        select TWL4030_USB if MACH_OMAP_3430SDP
-       tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
+       tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
        help
          Say Y here if your system has a dual role high speed USB
          controller based on the Mentor Graphics silicon IP.  Then
@@ -22,6 +22,9 @@ config USB_MUSB_HDRC
          Texas Instruments parts using this IP include DaVinci 644x,
          OMAP 243x, OMAP 343x, and TUSB 6010.
 
+         Analog Devices parts using this IP include Blackfin BF54x,
+         BF525 and BF527.
+
          If you do not know what this is, please say N.
 
          To compile this driver as a module, choose M here; the
@@ -33,6 +36,8 @@ config USB_MUSB_SOC
        default y if ARCH_DAVINCI
        default y if ARCH_OMAP2430
        default y if ARCH_OMAP34XX
+       default y if (BF54x && !BF544)
+       default y if (BF52x && !BF522 && !BF523)
 
 comment "DaVinci 644x USB support"
        depends on USB_MUSB_HDRC && ARCH_DAVINCI
@@ -43,6 +48,9 @@ comment "OMAP 243x high speed USB support"
 comment "OMAP 343x high speed USB support"
        depends on USB_MUSB_HDRC && ARCH_OMAP34XX
 
+comment "Blackfin high speed USB Support"
+       depends on USB_MUSB_HDRC && (BF54x && !BF544) || (BF52x && !BF522 && !BF523)
+
 config USB_TUSB6010
        boolean "TUSB 6010 support"
        depends on USB_MUSB_HDRC && !USB_MUSB_SOC
@@ -142,7 +150,7 @@ config MUSB_PIO_ONLY
 config USB_INVENTRA_DMA
        bool
        depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
-       default ARCH_OMAP2430 || ARCH_OMAP34XX
+       default ARCH_OMAP2430 || ARCH_OMAP34XX || BLACKFIN
        help
          Enable DMA transfers using Mentor's engine.
 
index b6af0d687a73657b27fc87fd8c57153fc7f2021d..85710ccc188754ad5bc52678fe9d2071b67ee188 100644 (file)
@@ -22,6 +22,14 @@ ifeq ($(CONFIG_ARCH_OMAP3430),y)
        musb_hdrc-objs  += omap2430.o
 endif
 
+ifeq ($(CONFIG_BF54x),y)
+       musb_hdrc-objs  += blackfin.o
+endif
+
+ifeq ($(CONFIG_BF52x),y)
+       musb_hdrc-objs  += blackfin.o
+endif
+
 ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
        musb_hdrc-objs          += musb_gadget_ep0.o musb_gadget.o
 endif
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
new file mode 100644 (file)
index 0000000..7861348
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * MUSB OTG controller driver for Blackfin Processors
+ *
+ * Copyright 2006-2008 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include "musb_core.h"
+#include "blackfin.h"
+
+/*
+ * Load an endpoint's FIFO
+ */
+void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
+{
+       void __iomem *fifo = hw_ep->fifo;
+       void __iomem *epio = hw_ep->regs;
+
+       prefetch((u8 *)src);
+
+       musb_writew(epio, MUSB_TXCOUNT, len);
+
+       DBG(4, "TX ep%d fifo %p count %d buf %p, epio %p\n",
+                       hw_ep->epnum, fifo, len, src, epio);
+
+       dump_fifo_data(src, len);
+
+       if (unlikely((unsigned long)src & 0x01))
+               outsw_8((unsigned long)fifo, src,
+                       len & 0x01 ? (len >> 1) + 1 : len >> 1);
+       else
+               outsw((unsigned long)fifo, src,
+                       len & 0x01 ? (len >> 1) + 1 : len >> 1);
+}
+
+/*
+ * Unload an endpoint's FIFO
+ */
+void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
+{
+       void __iomem *fifo = hw_ep->fifo;
+       u8 epnum = hw_ep->epnum;
+       u16 dma_reg = 0;
+
+       DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
+                       'R', hw_ep->epnum, fifo, len, dst);
+
+#ifdef CONFIG_BF52x
+       invalidate_dcache_range((unsigned int)dst,
+               (unsigned int)(dst + len));
+
+       /* Setup DMA address register */
+       dma_reg = (u16) ((u32) dst & 0xFFFF);
+       bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
+       SSYNC();
+
+       dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF);
+       bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
+       SSYNC();
+
+       /* Setup DMA count register */
+       bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
+       bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
+       SSYNC();
+
+       /* Enable the DMA */
+       dma_reg = (epnum << 4) | DMA_ENA | INT_ENA;
+       bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
+       SSYNC();
+
+       /* Wait for compelete */
+       while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
+               cpu_relax();
+
+       /* acknowledge dma interrupt */
+       bfin_write_USB_DMA_INTERRUPT(1 << epnum);
+       SSYNC();
+
+       /* Reset DMA */
+       bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
+       SSYNC();
+#else
+       if (unlikely((unsigned long)dst & 0x01))
+               insw_8((unsigned long)fifo, dst,
+                       len & 0x01 ? (len >> 1) + 1 : len >> 1);
+       else
+               insw((unsigned long)fifo, dst,
+                       len & 0x01 ? (len >> 1) + 1 : len >> 1);
+#endif
+
+       dump_fifo_data(dst, len);
+}
+
+static irqreturn_t blackfin_interrupt(int irq, void *__hci)
+{
+       unsigned long   flags;
+       irqreturn_t     retval = IRQ_NONE;
+       struct musb     *musb = __hci;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
+       musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
+       musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
+
+       if (musb->int_usb || musb->int_tx || musb->int_rx) {
+               musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb);
+               musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx);
+               musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx);
+               retval = musb_interrupt(musb);
+       }
+
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       /* REVISIT we sometimes get spurious IRQs on g_ep0
+        * not clear why... fall in BF54x too.
+        */
+       if (retval != IRQ_HANDLED)
+               DBG(5, "spurious?\n");
+
+       return IRQ_HANDLED;
+}
+
+static void musb_conn_timer_handler(unsigned long _musb)
+{
+       struct musb *musb = (void *)_musb;
+       unsigned long flags;
+       u16 val;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       switch (musb->xceiv.state) {
+       case OTG_STATE_A_IDLE:
+       case OTG_STATE_A_WAIT_BCON:
+               /* Start a new session */
+               val = musb_readw(musb->mregs, MUSB_DEVCTL);
+               val |= MUSB_DEVCTL_SESSION;
+               musb_writew(musb->mregs, MUSB_DEVCTL, val);
+
+               val = musb_readw(musb->mregs, MUSB_DEVCTL);
+               if (!(val & MUSB_DEVCTL_BDEVICE)) {
+                       gpio_set_value(musb->config->gpio_vrsel, 1);
+                       musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
+               } else {
+                       gpio_set_value(musb->config->gpio_vrsel, 0);
+
+                       /* Ignore VBUSERROR and SUSPEND IRQ */
+                       val = musb_readb(musb->mregs, MUSB_INTRUSBE);
+                       val &= ~MUSB_INTR_VBUSERROR;
+                       musb_writeb(musb->mregs, MUSB_INTRUSBE, val);
+
+                       val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR;
+                       musb_writeb(musb->mregs, MUSB_INTRUSB, val);
+
+                       val = MUSB_POWER_HSENAB;
+                       musb_writeb(musb->mregs, MUSB_POWER, val);
+               }
+               mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
+               break;
+
+       default:
+               DBG(1, "%s state not handled\n", otg_state_string(musb));
+               break;
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       DBG(4, "state is %s\n", otg_state_string(musb));
+}
+
+void musb_platform_enable(struct musb *musb)
+{
+       if (is_host_enabled(musb)) {
+               mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
+               musb->a_wait_bcon = TIMER_DELAY;
+       }
+}
+
+void musb_platform_disable(struct musb *musb)
+{
+}
+
+static void bfin_vbus_power(struct musb *musb, int is_on, int sleeping)
+{
+}
+
+static void bfin_set_vbus(struct musb *musb, int is_on)
+{
+       if (is_on)
+               gpio_set_value(musb->config->gpio_vrsel, 1);
+       else
+               gpio_set_value(musb->config->gpio_vrsel, 0);
+
+       DBG(1, "VBUS %s, devctl %02x "
+               /* otg %3x conf %08x prcm %08x */ "\n",
+               otg_state_string(musb),
+               musb_readb(musb->mregs, MUSB_DEVCTL));
+}
+
+static int bfin_set_power(struct otg_transceiver *x, unsigned mA)
+{
+       return 0;
+}
+
+void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
+{
+       if (is_host_enabled(musb))
+               mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
+}
+
+int musb_platform_get_vbus_status(struct musb *musb)
+{
+       return 0;
+}
+
+void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
+{
+}
+
+int __init musb_platform_init(struct musb *musb)
+{
+
+       /*
+        * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
+        * and OTG HOST modes, while rev 1.1 and greater require PE7 to
+        * be low for DEVICE mode and high for HOST mode. We set it high
+        * here because we are in host mode
+        */
+
+       if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
+               printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n",
+                       musb->config->gpio_vrsel);
+               return -ENODEV;
+       }
+       gpio_direction_output(musb->config->gpio_vrsel, 0);
+
+       if (ANOMALY_05000346) {
+               bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
+               SSYNC();
+       }
+
+       if (ANOMALY_05000347) {
+               bfin_write_USB_APHY_CNTRL(0x0);
+               SSYNC();
+       }
+
+       /* TODO
+        * Set SIC-IVG register
+        */
+
+       /* Configure PLL oscillator register */
+       bfin_write_USB_PLLOSC_CTRL(0x30a8);
+       SSYNC();
+
+       bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
+       SSYNC();
+
+       bfin_write_USB_EP_NI0_RXMAXP(64);
+       SSYNC();
+
+       bfin_write_USB_EP_NI0_TXMAXP(64);
+       SSYNC();
+
+       /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
+       bfin_write_USB_GLOBINTR(0x7);
+       SSYNC();
+
+       bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
+                               EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
+                               EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
+                               EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
+                               EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
+       SSYNC();
+
+       if (is_host_enabled(musb)) {
+               musb->board_set_vbus = bfin_set_vbus;
+               setup_timer(&musb_conn_timer,
+                       musb_conn_timer_handler, (unsigned long) musb);
+       }
+       if (is_peripheral_enabled(musb))
+               musb->xceiv.set_power = bfin_set_power;
+
+       musb->isr = blackfin_interrupt;
+
+       return 0;
+}
+
+int musb_platform_suspend(struct musb *musb)
+{
+       return 0;
+}
+
+int musb_platform_resume(struct musb *musb)
+{
+       return 0;
+}
+
+
+int musb_platform_exit(struct musb *musb)
+{
+
+       bfin_vbus_power(musb, 0 /*off*/, 1);
+       gpio_free(musb->config->gpio_vrsel);
+       musb_platform_suspend(musb);
+
+       return 0;
+}
diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h
new file mode 100644 (file)
index 0000000..a240c1e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007 by Analog Devices, Inc.
+ *
+ * The Inventra Controller Driver for Linux is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU
+ * General Public License version 2 as published by the Free Software
+ * Foundation.
+ */
+
+#ifndef __MUSB_BLACKFIN_H__
+#define __MUSB_BLACKFIN_H__
+
+/*
+ * Blackfin specific definitions
+ */
+
+#undef DUMP_FIFO_DATA
+#ifdef DUMP_FIFO_DATA
+static void dump_fifo_data(u8 *buf, u16 len)
+{
+       u8 *tmp = buf;
+       int i;
+
+       for (i = 0; i < len; i++) {
+               if (!(i % 16) && i)
+                       pr_debug("\n");
+               pr_debug("%02x ", *tmp++);
+       }
+       pr_debug("\n");
+}
+#else
+#define dump_fifo_data(buf, len)       do {} while (0)
+#endif
+
+#ifdef CONFIG_BF52x
+
+#define USB_DMA_BASE           USB_DMA_INTERRUPT
+#define USB_DMAx_CTRL          0x04
+#define USB_DMAx_ADDR_LOW      0x08
+#define USB_DMAx_ADDR_HIGH     0x0C
+#define USB_DMAx_COUNT_LOW     0x10
+#define USB_DMAx_COUNT_HIGH    0x14
+
+#define USB_DMA_REG(ep, reg)   (USB_DMA_BASE + 0x20 * ep + reg)
+#endif
+
+/* Almost 1 second */
+#define TIMER_DELAY    (1 * HZ)
+
+static struct timer_list musb_conn_timer;
+
+#endif /* __MUSB_BLACKFIN_H__ */
index dfb3bcbe00fceae11ed12b91c4fe03e9d0123be2..628ea8b423efc059b2fceb0be82ac6c4a823072a 100644 (file)
@@ -32,9 +32,9 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 
-#include <asm/arch/hardware.h>
-#include <asm/arch/memory.h>
-#include <asm/arch/gpio.h>
+#include <mach/arch/hardware.h>
+#include <mach/arch/memory.h>
+#include <mach/arch/gpio.h>
 #include <asm/mach-types.h>
 
 #include "musb_core.h"
@@ -265,7 +265,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
        /* CPPI interrupts share the same IRQ line, but have their own
         * mask, state, "vector", and EOI registers.
         */
-       if (is_cppi_enabled()) {
+       if (cppi_ti_dma()) {
                u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
                u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);
 
@@ -364,6 +364,18 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
        return IRQ_HANDLED;
 }
 
+int musb_platform_set_mode(struct musb *musb, u8 mode)
+{
+       /* EVM can't do this (right?) */
+       return -EIO;
+}
+
+int musb_platform_set_mode(struct musb *musb, u8 mode)
+{
+       /* EVM can't do this (right?) */
+       return -EIO;
+}
+
 int __init musb_platform_init(struct musb *musb)
 {
        void __iomem    *tibase = musb->ctrl_base;
index 5280dba9b1fb7e0a94f6dc1b379b28fc5c7d831b..251c6d314f6600d60f426832188868e6d2dacaf7 100644 (file)
@@ -148,7 +148,8 @@ static inline struct musb *dev_to_musb(struct device *dev)
 
 /*-------------------------------------------------------------------------*/
 
-#ifndef CONFIG_USB_TUSB6010
+#if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN)
+
 /*
  * Load an endpoint's FIFO
  */
@@ -1124,25 +1125,25 @@ fifo_setup(struct musb *musb, struct musb_hw_ep  *hw_ep,
 #endif
        switch (cfg->style) {
        case FIFO_TX:
-               musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_TXFIFOADD, c_off);
+               musb_write_txfifosz(mbase, c_size);
+               musb_write_txfifoadd(mbase, c_off);
                hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
                hw_ep->max_packet_sz_tx = maxpacket;
                break;
        case FIFO_RX:
-               musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_RXFIFOADD, c_off);
+               musb_write_rxfifosz(mbase, c_size);
+               musb_write_rxfifoadd(mbase, c_off);
                hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
                hw_ep->max_packet_sz_rx = maxpacket;
                break;
        case FIFO_RXTX:
-               musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_TXFIFOADD, c_off);
+               musb_write_txfifosz(mbase, c_size);
+               musb_write_txfifoadd(mbase, c_off);
                hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
                hw_ep->max_packet_sz_rx = maxpacket;
 
-               musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
-               musb_writew(mbase, MUSB_RXFIFOADD, c_off);
+               musb_write_rxfifosz(mbase, c_size);
+               musb_write_rxfifoadd(mbase, c_off);
                hw_ep->tx_double_buffered = hw_ep->rx_double_buffered;
                hw_ep->max_packet_sz_tx = maxpacket;
 
@@ -1212,7 +1213,7 @@ static int __init ep_config_from_table(struct musb *musb)
                if (epn >= musb->config->num_eps) {
                        pr_debug("%s: invalid ep %d\n",
                                        musb_driver_name, epn);
-                       continue;
+                       return -EINVAL;
                }
                offset = fifo_setup(musb, hw_ep + epn, cfg++, offset);
                if (offset < 0) {
@@ -1246,9 +1247,10 @@ static int __init ep_config_from_table(struct musb *musb)
  */
 static int __init ep_config_from_hw(struct musb *musb)
 {
-       u8 epnum = 0, reg;
+       u8 epnum = 0;
        struct musb_hw_ep *hw_ep;
        void *mbase = musb->mregs;
+       int ret = 0;
 
        DBG(2, "<== static silicon ep config\n");
 
@@ -1258,26 +1260,9 @@ static int __init ep_config_from_hw(struct musb *musb)
                musb_ep_select(mbase, epnum);
                hw_ep = musb->endpoints + epnum;
 
-               /* read from core using indexed model */
-               reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
-               if (!reg) {
-                       /* 0's returned when no more endpoints */
+               ret = musb_read_fifosize(musb, hw_ep, epnum);
+               if (ret < 0)
                        break;
-               }
-               musb->nr_endpoints++;
-               musb->epmask |= (1 << epnum);
-
-               hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
-
-               /* shared TX/RX FIFO? */
-               if ((reg & 0xf0) == 0xf0) {
-                       hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
-                       hw_ep->is_shared_fifo = true;
-                       continue;
-               } else {
-                       hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
-                       hw_ep->is_shared_fifo = false;
-               }
 
                /* FIXME set up hw_ep->{rx,tx}_double_buffered */
 
@@ -1326,7 +1311,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 
        /* log core options (read using indexed model) */
        musb_ep_select(mbase, 0);
-       reg = musb_readb(mbase, 0x10 + MUSB_CONFIGDATA);
+       reg = musb_read_configdata(mbase);
 
        strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
        if (reg & MUSB_CONFIGDATA_DYNFIFO)
@@ -1391,7 +1376,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
        }
 
        /* log release info */
-       hwvers = musb_readw(mbase, MUSB_HWVERS);
+       hwvers = musb_read_hwvers(mbase);
        rev_major = (hwvers >> 10) & 0x1f;
        rev_minor = hwvers & 0x3ff;
        snprintf(aRevision, 32, "%d.%d%s", rev_major,
@@ -1400,8 +1385,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
                        musb_driver_name, type, aRevision, aDate);
 
        /* configure ep0 */
-       musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
-       musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+       musb_configure_ep0(musb);
 
        /* discover endpoint configuration */
        musb->nr_endpoints = 1;
@@ -1445,7 +1429,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 
                hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase;
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
-               hw_ep->target_regs = MUSB_BUSCTL_OFFSET(i, 0) + mbase;
+               hw_ep->target_regs = musb_read_target_reg_base(i, mbase);
                hw_ep->rx_reinit = 1;
                hw_ep->tx_reinit = 1;
 #endif
@@ -1612,7 +1596,7 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)
 
        if (!epnum) {
 #ifndef CONFIG_USB_TUSB_OMAP_DMA
-               if (!is_cppi_enabled()) {
+               if (!cppi_ti_dma()) {
                        /* endpoint 0 */
                        if (devctl & MUSB_DEVCTL_HM)
                                musb_h_ep0_irq(musb);
@@ -1671,17 +1655,20 @@ musb_mode_store(struct device *dev, struct device_attribute *attr,
 {
        struct musb     *musb = dev_to_musb(dev);
        unsigned long   flags;
+       int             status;
 
        spin_lock_irqsave(&musb->lock, flags);
-       if (!strncmp(buf, "host", 4))
-               musb_platform_set_mode(musb, MUSB_HOST);
-       if (!strncmp(buf, "peripheral", 10))
-               musb_platform_set_mode(musb, MUSB_PERIPHERAL);
-       if (!strncmp(buf, "otg", 3))
-               musb_platform_set_mode(musb, MUSB_OTG);
+       if (sysfs_streq(buf, "host"))
+               status = musb_platform_set_mode(musb, MUSB_HOST);
+       else if (sysfs_streq(buf, "peripheral"))
+               status = musb_platform_set_mode(musb, MUSB_PERIPHERAL);
+       else if (sysfs_streq(buf, "otg"))
+               status = musb_platform_set_mode(musb, MUSB_OTG);
+       else
+               status = -EINVAL;
        spin_unlock_irqrestore(&musb->lock, flags);
 
-       return n;
+       return (status == 0) ? n : status;
 }
 static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store);
 
@@ -1810,7 +1797,6 @@ allocate_instance(struct device *dev,
        for (epnum = 0, ep = musb->endpoints;
                        epnum < musb->config->num_eps;
                        epnum++, ep++) {
-
                ep->musb = musb;
                ep->epnum = epnum;
        }
@@ -1838,7 +1824,7 @@ static void musb_free(struct musb *musb)
        musb_gadget_cleanup(musb);
 #endif
 
-       if (musb->nIrq >= 0) {
+       if (musb->nIrq >= 0 && musb->irq_wake) {
                disable_irq_wake(musb->nIrq);
                free_irq(musb->nIrq, musb);
        }
@@ -1991,8 +1977,12 @@ bad_config:
        }
        musb->nIrq = nIrq;
 /* FIXME this handles wakeup irqs wrong */
-       if (enable_irq_wake(nIrq) == 0)
+       if (enable_irq_wake(nIrq) == 0) {
+               musb->irq_wake = 1;
                device_init_wakeup(dev, 1);
+       } else {
+               musb->irq_wake = 0;
+       }
 
        pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n",
                        musb_driver_name,
index 82227251931b4c8c512f5d66babe9fec3fbafff2..630946a2d9fce2db69bd9a7cd2ab68d513ade60f 100644 (file)
@@ -191,7 +191,7 @@ enum musb_g_ep0_state {
  */
 
 #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \
-               || defined(CONFIG_ARCH_OMAP3430)
+               || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_BLACKFIN)
 /* REVISIT indexed access seemed to
  * misbehave (on DaVinci) for at least peripheral IN ...
  */
@@ -359,6 +359,7 @@ struct musb {
        struct otg_transceiver  xceiv;
 
        int nIrq;
+       unsigned                irq_wake:1;
 
        struct musb_hw_ep        endpoints[MUSB_C_NUM_EPS];
 #define control_ep             endpoints
@@ -447,6 +448,70 @@ static inline struct musb *gadget_to_musb(struct usb_gadget *g)
 }
 #endif
 
+#ifdef CONFIG_BLACKFIN
+static inline int musb_read_fifosize(struct musb *musb,
+               struct musb_hw_ep *hw_ep, u8 epnum)
+{
+       musb->nr_endpoints++;
+       musb->epmask |= (1 << epnum);
+
+       if (epnum < 5) {
+               hw_ep->max_packet_sz_tx = 128;
+               hw_ep->max_packet_sz_rx = 128;
+       } else {
+               hw_ep->max_packet_sz_tx = 1024;
+               hw_ep->max_packet_sz_rx = 1024;
+       }
+       hw_ep->is_shared_fifo = false;
+
+       return 0;
+}
+
+static inline void musb_configure_ep0(struct musb *musb)
+{
+       musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].is_shared_fifo = true;
+}
+
+#else
+
+static inline int musb_read_fifosize(struct musb *musb,
+               struct musb_hw_ep *hw_ep, u8 epnum)
+{
+       u8 reg = 0;
+
+       /* read from core using indexed model */
+       reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
+       /* 0's returned when no more endpoints */
+       if (!reg)
+               return -ENODEV;
+
+       musb->nr_endpoints++;
+       musb->epmask |= (1 << epnum);
+
+       hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
+
+       /* shared TX/RX FIFO? */
+       if ((reg & 0xf0) == 0xf0) {
+               hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
+               hw_ep->is_shared_fifo = true;
+               return 0;
+       } else {
+               hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
+               hw_ep->is_shared_fifo = false;
+       }
+
+       return 0;
+}
+
+static inline void musb_configure_ep0(struct musb *musb)
+{
+       musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+}
+#endif /* CONFIG_BLACKFIN */
+
 
 /***************************** Glue it together *****************************/
 
@@ -467,16 +532,16 @@ extern void musb_platform_disable(struct musb *musb);
 
 extern void musb_hnp_stop(struct musb *musb);
 
-extern void musb_platform_set_mode(struct musb *musb, u8 musb_mode);
+extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
 
-#if defined(CONFIG_USB_TUSB6010) || \
+#if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
        defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
 extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
 #else
 #define musb_platform_try_idle(x, y)           do {} while (0)
 #endif
 
-#ifdef CONFIG_USB_TUSB6010
+#if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN)
 extern int musb_platform_get_vbus_status(struct musb *musb);
 #else
 #define musb_platform_get_vbus_status(x)       0
index 0a2c4e3602c1bce77ab28cec193e5ea51d1bfda6..831375d8cf2ab33d174447fe1a3dc3a510713510 100644 (file)
@@ -69,15 +69,21 @@ struct musb_hw_ep;
 #endif
 
 #ifdef CONFIG_USB_TI_CPPI_DMA
-#define        is_cppi_enabled()       1
+#define        cppi_ti_dma()                   true
 #else
-#define        is_cppi_enabled()       0
+#define        cppi_ti_dma()                   false
 #endif
 
 #ifdef CONFIG_USB_TUSB_OMAP_DMA
-#define tusb_dma_omap()                        1
+#define tusb_dma_omap()                        true
 #else
-#define tusb_dma_omap()                        0
+#define tusb_dma_omap()                        false
+#endif
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+#define musb_inventra_dma()            true
+#else
+#define musb_inventra_dma()            false
 #endif
 
 /*
index d6a802c224fa8d2f7be9ba7fab7fe68db9b4202f..3e565822c74ef06c733fed98090eba836ad53363 100644 (file)
@@ -297,8 +297,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
 
                /* MUSB_TXCSR_P_ISO is still set correctly */
 
-#ifdef CONFIG_USB_INVENTRA_DMA
-               {
+               if (musb_inventra_dma()) {
                        size_t request_size;
 
                        /* setup DMA, then program endpoint CSR */
@@ -332,49 +331,51 @@ static void txstate(struct musb *musb, struct musb_request *req)
                        }
                }
 
-#elif defined(CONFIG_USB_TI_CPPI_DMA)
-               /* program endpoint CSR first, then setup DMA */
-               csr &= ~(MUSB_TXCSR_AUTOSET
-                               | MUSB_TXCSR_DMAMODE
-                               | MUSB_TXCSR_P_UNDERRUN
-                               | MUSB_TXCSR_TXPKTRDY);
-               csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB;
-               musb_writew(epio, MUSB_TXCSR,
-                       (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
-                               | csr);
-
-               /* ensure writebuffer is empty */
-               csr = musb_readw(epio, MUSB_TXCSR);
+               if (cppi_ti_dma()) {
+                       /* program endpoint CSR first, then setup DMA */
+                       csr &= ~(MUSB_TXCSR_AUTOSET
+                                       | MUSB_TXCSR_DMAMODE
+                                       | MUSB_TXCSR_P_UNDERRUN
+                                       | MUSB_TXCSR_TXPKTRDY);
+                       csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB;
+                       musb_writew(epio, MUSB_TXCSR,
+                                       (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
+                                       | csr);
 
-               /* NOTE host side sets DMAENAB later than this; both are
-                * OK since the transfer dma glue (between CPPI and Mentor
-                * fifos) just tells CPPI it could start.  Data only moves
-                * to the USB TX fifo when both fifos are ready.
-                */
+                       /* ensure writebuffer is empty */
+                       csr = musb_readw(epio, MUSB_TXCSR);
 
-               /* "mode" is irrelevant here; handle terminating ZLPs like
-                * PIO does, since the hardware RNDIS mode seems unreliable
-                * except for the last-packet-is-already-short case.
-                */
-               use_dma = use_dma && c->channel_program(
-                               musb_ep->dma, musb_ep->packet_sz,
-                               0,
-                               request->dma,
-                               request->length);
-               if (!use_dma) {
-                       c->channel_release(musb_ep->dma);
-                       musb_ep->dma = NULL;
-                       /* ASSERT: DMAENAB clear */
-                       csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
-                       /* invariant: prequest->buf is non-null */
+                       /* NOTE host side sets DMAENAB later than this; both are
+                        * OK since the transfer dma glue (between CPPI and Mentor
+                        * fifos) just tells CPPI it could start.  Data only moves
+                        * to the USB TX fifo when both fifos are ready.
+                        */
+
+                       /* "mode" is irrelevant here; handle terminating ZLPs like
+                        * PIO does, since the hardware RNDIS mode seems unreliable
+                        * except for the last-packet-is-already-short case.
+                        */
+                       use_dma = use_dma && c->channel_program(
+                                       musb_ep->dma, musb_ep->packet_sz,
+                                       0,
+                                       request->dma,
+                                       request->length);
+                       if (!use_dma) {
+                               c->channel_release(musb_ep->dma);
+                               musb_ep->dma = NULL;
+                               /* ASSERT: DMAENAB clear */
+                               csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
+                               /* invariant: prequest->buf is non-null */
+                       }
+               }
+
+               if (tusb_dma_omap()) {
+                       use_dma = use_dma && c->channel_program(
+                                       musb_ep->dma, musb_ep->packet_sz,
+                                       request->zero,
+                                       request->dma,
+                                       request->length);
                }
-#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
-               use_dma = use_dma && c->channel_program(
-                               musb_ep->dma, musb_ep->packet_sz,
-                               request->zero,
-                               request->dma,
-                               request->length);
-#endif
        }
 #endif
 
@@ -574,27 +575,28 @@ static void rxstate(struct musb *musb, struct musb_request *req)
        const u8                epnum = req->epnum;
        struct usb_request      *request = &req->request;
        struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
+       struct dma_controller   *c = musb->dma_controller;
+       struct dma_channel      *channel = musb_ep->dma;
        void __iomem            *epio = musb->endpoints[epnum].regs;
        u16                     fifo_count = 0;
        u16                     len = musb_ep->packet_sz;
+       int                     use_dma = 0;
 
        csr = musb_readw(epio, MUSB_RXCSR);
 
-       if (is_cppi_enabled() && musb_ep->dma) {
-               struct dma_controller   *c = musb->dma_controller;
-               struct dma_channel      *channel = musb_ep->dma;
-
+       if (cppi_ti_dma() && musb_ep->dma) {
                /* NOTE:  CPPI won't actually stop advancing the DMA
                 * queue after short packet transfers, so this is almost
                 * always going to run as IRQ-per-packet DMA so that
                 * faults will be handled correctly.
                 */
-               if (c->channel_program(channel,
+               use_dma = c->channel_program(channel,
                                musb_ep->packet_sz,
                                !request->short_not_ok,
                                request->dma + request->actual,
-                               request->length - request->actual)) {
+                               request->length - request->actual);
 
+               if (use_dma) {
                        /* make sure that if an rxpkt arrived after the irq,
                         * the cppi engine will be ready to take it as soon
                         * as DMA is enabled
@@ -603,15 +605,34 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                        | MUSB_RXCSR_DMAMODE);
                        csr |= MUSB_RXCSR_DMAENAB | MUSB_RXCSR_P_WZC_BITS;
                        musb_writew(epio, MUSB_RXCSR, csr);
-                       return;
                }
        }
 
        if (csr & MUSB_RXCSR_RXPKTRDY) {
                len = musb_readw(epio, MUSB_RXCOUNT);
                if (request->actual < request->length) {
-#ifdef CONFIG_USB_INVENTRA_DMA
-                       if (is_dma_capable() && musb_ep->dma) {
+
+               /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
+                * mode 0 only. So we do not get endpoint interrupts due to DMA
+                * completion. We only get interrupts from DMA controller.
+                *
+                * We could operate in DMA mode 1 if we knew the size of the tranfer
+                * in advance. For mass storage class, request->length = what the host
+                * sends, so that'd work.  But for pretty much everything else,
+                * request->length is routinely more than what the host sends. For
+                * most these gadgets, end of is signified either by a short packet,
+                * or filling the last byte of the buffer.  (Sending extra data in
+                * that last pckate should trigger an overflow fault.)  But in mode 1,
+                * we don't get DMA completion interrrupt for short packets.
+                *
+                * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
+                * to get endpoint interrupt on every DMA req, but that didn't seem
+                * to work reliably.
+                *
+                * REVISIT an updated g_file_storage can set req->short_not_ok, which
+                * then becomes usable as a runtime "use mode 1" hint...
+                */
+                       if (musb_inventra_dma() && musb_ep->dma) {
                                struct dma_controller   *c;
                                struct dma_channel      *channel;
                                int                     use_dma = 0;
@@ -619,27 +640,6 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                c = musb->dma_controller;
                                channel = musb_ep->dma;
 
-       /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
-        * mode 0 only. So we do not get endpoint interrupts due to DMA
-        * completion. We only get interrupts from DMA controller.
-        *
-        * We could operate in DMA mode 1 if we knew the size of the tranfer
-        * in advance. For mass storage class, request->length = what the host
-        * sends, so that'd work.  But for pretty much everything else,
-        * request->length is routinely more than what the host sends. For
-        * most these gadgets, end of is signified either by a short packet,
-        * or filling the last byte of the buffer.  (Sending extra data in
-        * that last pckate should trigger an overflow fault.)  But in mode 1,
-        * we don't get DMA completion interrrupt for short packets.
-        *
-        * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
-        * to get endpoint interrupt on every DMA req, but that didn't seem
-        * to work reliably.
-        *
-        * REVISIT an updated g_file_storage can set req->short_not_ok, which
-        * then becomes usable as a runtime "use mode 1" hint...
-        */
-
                                csr |= MUSB_RXCSR_DMAENAB;
 #ifdef USE_MODE1
                                csr |= MUSB_RXCSR_AUTOCLEAR;
@@ -650,7 +650,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                 * to get DMAReq to activate
                                 */
                                musb_writew(epio, MUSB_RXCSR,
-                                       csr | MUSB_RXCSR_DMAMODE);
+                                               csr | MUSB_RXCSR_DMAMODE);
 #endif
                                musb_writew(epio, MUSB_RXCSR, csr);
 
@@ -674,12 +674,22 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                                        request->dma
                                                        + request->actual,
                                                        transfer_size);
+                                       if (use_dma)
+                                               return;
                                }
+                       }
+
+                       if (tusb_dma_omap() && musb_ep->dma) {
+                               u32 dma_addr = request->dma + request->actual;
 
+                               use_dma = c->channel_program(channel,
+                                               musb_ep->packet_sz,
+                                               channel->desired_mode,
+                                               dma_addr,
+                                               fifo_count);
                                if (use_dma)
                                        return;
                        }
-#endif /* Mentor's DMA */
 
                        fifo_count = request->length - request->actual;
                        DBG(3, "%s OUT/RX pio fifo %d/%d, maxpacket %d\n",
@@ -689,23 +699,6 @@ static void rxstate(struct musb *musb, struct musb_request *req)
 
                        fifo_count = min(len, fifo_count);
 
-#ifdef CONFIG_USB_TUSB_OMAP_DMA
-                       if (tusb_dma_omap() && musb_ep->dma) {
-                               struct dma_controller *c = musb->dma_controller;
-                               struct dma_channel *channel = musb_ep->dma;
-                               u32 dma_addr = request->dma + request->actual;
-                               int ret;
-
-                               ret = c->channel_program(channel,
-                                               musb_ep->packet_sz,
-                                               channel->desired_mode,
-                                               dma_addr,
-                                               fifo_count);
-                               if (ret)
-                                       return;
-                       }
-#endif
-
                        musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
                                        (request->buf + request->actual));
                        request->actual += fifo_count;
@@ -800,11 +793,11 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                        musb_readw(epio, MUSB_RXCSR),
                        musb_ep->dma->actual_len, request);
 
-#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
                /* Autoclear doesn't clear RxPktRdy for short packets */
-               if ((dma->desired_mode == 0)
+               if ((tusb_dma_omap() || musb_inventra_dma())
+                               && ((dma->desired_mode == 0)
                                || (dma->actual_len
-                                       & (musb_ep->packet_sz - 1))) {
+                                       & (musb_ep->packet_sz - 1)))) {
                        /* ack the read! */
                        csr &= ~MUSB_RXCSR_RXPKTRDY;
                        musb_writew(epio, MUSB_RXCSR, csr);
@@ -815,7 +808,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                                && (musb_ep->dma->actual_len
                                        == musb_ep->packet_sz))
                        goto done;
-#endif
+
                musb_g_giveback(musb_ep, request, 0);
 
                request = next_request(musb_ep);
index cc64462d4c4ee0ee97e5271afa3769bdfdab7686..b5373a8d6e7b4c8405e5316afaf5c79a8d523080 100644 (file)
@@ -112,18 +112,21 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
 {
        void __iomem    *epio = ep->regs;
        u16             csr;
+       u16             lastcsr = 0;
        int             retries = 1000;
 
        csr = musb_readw(epio, MUSB_TXCSR);
        while (csr & MUSB_TXCSR_FIFONOTEMPTY) {
-               DBG(5, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
+               if (csr != lastcsr)
+                       DBG(3, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
+               lastcsr = csr;
                csr |= MUSB_TXCSR_FLUSHFIFO;
                musb_writew(epio, MUSB_TXCSR, csr);
                csr = musb_readw(epio, MUSB_TXCSR);
-               if (retries-- < 1) {
-                       ERR("Could not flush host TX fifo: csr: %04x\n", csr);
+               if (WARN(retries-- < 1,
+                               "Could not flush host TX%d fifo: csr: %04x\n",
+                               ep->epnum, csr))
                        return;
-               }
                mdelay(1);
        }
 }
@@ -257,7 +260,7 @@ start:
 
                if (!hw_ep->tx_channel)
                        musb_h_tx_start(hw_ep);
-               else if (is_cppi_enabled() || tusb_dma_omap())
+               else if (cppi_ti_dma() || tusb_dma_omap())
                        cppi_host_txdma_start(hw_ep);
        }
 }
@@ -268,7 +271,7 @@ __musb_giveback(struct musb *musb, struct urb *urb, int status)
 __releases(musb->lock)
 __acquires(musb->lock)
 {
-       DBG(({ int level; switch (urb->status) {
+       DBG(({ int level; switch (status) {
                                case 0:
                                        level = 4;
                                        break;
@@ -283,8 +286,8 @@ __acquires(musb->lock)
                                        level = 2;
                                        break;
                                }; level; }),
-                       "complete %p (%d), dev%d ep%d%s, %d/%d\n",
-                       urb, urb->status,
+                       "complete %p %pF (%d), dev%d ep%d%s, %d/%d\n",
+                       urb, urb->complete, status,
                        usb_pipedevice(urb->pipe),
                        usb_pipeendpoint(urb->pipe),
                        usb_pipein(urb->pipe) ? "in" : "out",
@@ -593,12 +596,10 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
 
        /* target addr and (for multipoint) hub addr/port */
        if (musb->is_multipoint) {
-               musb_writeb(ep->target_regs, MUSB_RXFUNCADDR,
-                       qh->addr_reg);
-               musb_writeb(ep->target_regs, MUSB_RXHUBADDR,
-                       qh->h_addr_reg);
-               musb_writeb(ep->target_regs, MUSB_RXHUBPORT,
-                       qh->h_port_reg);
+               musb_write_rxfunaddr(ep->target_regs, qh->addr_reg);
+               musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg);
+               musb_write_rxhubport(ep->target_regs, qh->h_port_reg);
+
        } else
                musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
 
@@ -712,15 +713,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 
                /* target addr and (for multipoint) hub addr/port */
                if (musb->is_multipoint) {
-                       musb_writeb(mbase,
-                               MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR),
-                               qh->addr_reg);
-                       musb_writeb(mbase,
-                               MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR),
-                               qh->h_addr_reg);
-                       musb_writeb(mbase,
-                               MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT),
-                               qh->h_port_reg);
+                       musb_write_txfunaddr(mbase, epnum, qh->addr_reg);
+                       musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg);
+                       musb_write_txhubport(mbase, epnum, qh->h_port_reg);
 /* FIXME if !epnum, do the same for RX ... */
                } else
                        musb_writeb(mbase, MUSB_FADDR, qh->addr_reg);
@@ -750,8 +745,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
                else
                        load_count = min((u32) packet_sz, len);
 
-#ifdef CONFIG_USB_INVENTRA_DMA
-               if (dma_channel) {
+               if (musb_inventra_dma() && dma_channel) {
 
                        /* clear previous state */
                        csr = musb_readw(epio, MUSB_TXCSR);
@@ -798,10 +792,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
                                dma_channel = NULL;
                        }
                }
-#endif
 
                /* candidate for DMA */
-               if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
+               if ((cppi_ti_dma() || tusb_dma_omap()) && dma_channel) {
 
                        /* program endpoint CSRs first, then setup DMA.
                         * assume CPPI setup succeeds.
@@ -893,7 +886,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 
                /* kick things off */
 
-               if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
+               if ((cppi_ti_dma() || tusb_dma_omap()) && dma_channel) {
                        /* candidate for DMA */
                        if (dma_channel) {
                                dma_channel->actual_len = 0L;
@@ -988,8 +981,10 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
                if (fifo_count) {
                        fifo_dest = (u8 *) (urb->transfer_buffer
                                        + urb->actual_length);
-                       DBG(3, "Sending %d bytes to %p\n",
-                                       fifo_count, fifo_dest);
+                       DBG(3, "Sending %d byte%s to ep0 fifo %p\n",
+                                       fifo_count,
+                                       (fifo_count == 1) ? "" : "s",
+                                       fifo_dest);
                        musb_write_fifo(hw_ep, fifo_count, fifo_dest);
 
                        urb->actual_length += fifo_count;
@@ -1476,8 +1471,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
 
        /* FIXME this is _way_ too much in-line logic for Mentor DMA */
 
-#ifndef CONFIG_USB_INVENTRA_DMA
-       if (rx_csr & MUSB_RXCSR_H_REQPKT)  {
+       if (!musb_inventra_dma() && (rx_csr & MUSB_RXCSR_H_REQPKT))  {
                /* REVISIT this happened for a while on some short reads...
                 * the cleanup still needs investigation... looks bad...
                 * and also duplicates dma cleanup code above ... plus,
@@ -1498,7 +1492,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                musb_writew(epio, MUSB_RXCSR,
                                MUSB_RXCSR_H_WZC_BITS | rx_csr);
        }
-#endif
+
        if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
                xfer_len = dma->actual_len;
 
@@ -1564,8 +1558,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                }
 
                /* we are expecting IN packets */
-#ifdef CONFIG_USB_INVENTRA_DMA
-               if (dma) {
+               if (musb_inventra_dma() && dma) {
                        struct dma_controller   *c;
                        u16                     rx_count;
                        int                     ret, length;
@@ -1674,7 +1667,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                                /* REVISIT reset CSR */
                        }
                }
-#endif /* Mentor DMA */
 
                if (!dma) {
                        done = musb_host_packet_rx(musb, urb,
index 223f0a514094d1d5cca5969f222adee5c4d4b8f1..b06e9ef00cfc1582d3694cfa40c4fbc1a9a6732f 100644 (file)
@@ -39,7 +39,7 @@
 
 #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
        && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
-       && !defined(CONFIG_PPC64)
+       && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN)
 static inline void readsl(const void __iomem *addr, void *buf, int len)
        { insl((unsigned long)addr, buf, len); }
 static inline void readsw(const void __iomem *addr, void *buf, int len)
@@ -56,6 +56,8 @@ static inline void writesb(const void __iomem *addr, const void *buf, int len)
 
 #endif
 
+#ifndef CONFIG_BLACKFIN
+
 /* NOTE:  these offsets are all in bytes */
 
 static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
@@ -114,4 +116,26 @@ static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
 
 #endif /* CONFIG_USB_TUSB6010 */
 
+#else
+
+static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
+       { return (u8) (bfin_read16(addr + offset)); }
+
+static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
+       { return bfin_read16(addr + offset); }
+
+static inline u32 musb_readl(const void __iomem *addr, unsigned offset)
+       { return (u32) (bfin_read16(addr + offset)); }
+
+static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+       { bfin_write16(addr + offset, (u16) data); }
+
+static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
+       { bfin_write16(addr + offset, data); }
+
+static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
+       { bfin_write16(addr + offset, (u16) data); }
+
+#endif /* CONFIG_BLACKFIN */
+
 #endif
index 9c228661aa5a76dc2294976b147e96a90c78ec9c..de3b2f18db4469943b0e7ce3b437ff98d53e0022 100644 (file)
 
 #define MUSB_EP0_FIFOSIZE      64      /* This is non-configurable */
 
-/*
- * Common USB registers
- */
-
-#define MUSB_FADDR             0x00    /* 8-bit */
-#define MUSB_POWER             0x01    /* 8-bit */
-
-#define MUSB_INTRTX            0x02    /* 16-bit */
-#define MUSB_INTRRX            0x04
-#define MUSB_INTRTXE           0x06
-#define MUSB_INTRRXE           0x08
-#define MUSB_INTRUSB           0x0A    /* 8 bit */
-#define MUSB_INTRUSBE          0x0B    /* 8 bit */
-#define MUSB_FRAME             0x0C
-#define MUSB_INDEX             0x0E    /* 8 bit */
-#define MUSB_TESTMODE          0x0F    /* 8 bit */
-
-/* Get offset for a given FIFO from musb->mregs */
-#ifdef CONFIG_USB_TUSB6010
-#define MUSB_FIFO_OFFSET(epnum)        (0x200 + ((epnum) * 0x20))
-#else
-#define MUSB_FIFO_OFFSET(epnum)        (0x20 + ((epnum) * 4))
-#endif
-
-/*
- * Additional Control Registers
- */
-
-#define MUSB_DEVCTL            0x60    /* 8 bit */
-
-/* These are always controlled through the INDEX register */
-#define MUSB_TXFIFOSZ          0x62    /* 8-bit (see masks) */
-#define MUSB_RXFIFOSZ          0x63    /* 8-bit (see masks) */
-#define MUSB_TXFIFOADD         0x64    /* 16-bit offset shifted right 3 */
-#define MUSB_RXFIFOADD         0x66    /* 16-bit offset shifted right 3 */
-
-/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */
-#define MUSB_HWVERS            0x6C    /* 8 bit */
-
-#define MUSB_EPINFO            0x78    /* 8 bit */
-#define MUSB_RAMINFO           0x79    /* 8 bit */
-#define MUSB_LINKINFO          0x7a    /* 8 bit */
-#define MUSB_VPLEN             0x7b    /* 8 bit */
-#define MUSB_HS_EOF1           0x7c    /* 8 bit */
-#define MUSB_FS_EOF1           0x7d    /* 8 bit */
-#define MUSB_LS_EOF1           0x7e    /* 8 bit */
-
-/* Offsets to endpoint registers */
-#define MUSB_TXMAXP            0x00
-#define MUSB_TXCSR             0x02
-#define MUSB_CSR0              MUSB_TXCSR      /* Re-used for EP0 */
-#define MUSB_RXMAXP            0x04
-#define MUSB_RXCSR             0x06
-#define MUSB_RXCOUNT           0x08
-#define MUSB_COUNT0            MUSB_RXCOUNT    /* Re-used for EP0 */
-#define MUSB_TXTYPE            0x0A
-#define MUSB_TYPE0             MUSB_TXTYPE     /* Re-used for EP0 */
-#define MUSB_TXINTERVAL                0x0B
-#define MUSB_NAKLIMIT0         MUSB_TXINTERVAL /* Re-used for EP0 */
-#define MUSB_RXTYPE            0x0C
-#define MUSB_RXINTERVAL                0x0D
-#define MUSB_FIFOSIZE          0x0F
-#define MUSB_CONFIGDATA                MUSB_FIFOSIZE   /* Re-used for EP0 */
-
-/* Offsets to endpoint registers in indexed model (using INDEX register) */
-#define MUSB_INDEXED_OFFSET(_epnum, _offset)   \
-       (0x10 + (_offset))
-
-/* Offsets to endpoint registers in flat models */
-#define MUSB_FLAT_OFFSET(_epnum, _offset)      \
-       (0x100 + (0x10*(_epnum)) + (_offset))
-
-#ifdef CONFIG_USB_TUSB6010
-/* TUSB6010 EP0 configuration register is special */
-#define MUSB_TUSB_OFFSET(_epnum, _offset)      \
-       (0x10 + _offset)
-#include "tusb6010.h"          /* Needed "only" for TUSB_EP0_CONF */
-#endif
-
-/* "bus control"/target registers, for host side multipoint (external hubs) */
-#define MUSB_TXFUNCADDR                0x00
-#define MUSB_TXHUBADDR         0x02
-#define MUSB_TXHUBPORT         0x03
-
-#define MUSB_RXFUNCADDR                0x04
-#define MUSB_RXHUBADDR         0x06
-#define MUSB_RXHUBPORT         0x07
-
-#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
-       (0x80 + (8*(_epnum)) + (_offset))
-
 /*
  * MUSB Register bits
  */
 
 /* TXCSR in Peripheral and Host mode */
 #define MUSB_TXCSR_AUTOSET             0x8000
-#define MUSB_TXCSR_MODE                        0x2000
 #define MUSB_TXCSR_DMAENAB             0x1000
 #define MUSB_TXCSR_FRCDATATOG          0x0800
 #define MUSB_TXCSR_DMAMODE             0x0400
 /* HUBADDR */
 #define MUSB_HUBADDR_MULTI_TT          0x80
 
+
+#ifndef CONFIG_BLACKFIN
+
+/*
+ * Common USB registers
+ */
+
+#define MUSB_FADDR             0x00    /* 8-bit */
+#define MUSB_POWER             0x01    /* 8-bit */
+
+#define MUSB_INTRTX            0x02    /* 16-bit */
+#define MUSB_INTRRX            0x04
+#define MUSB_INTRTXE           0x06
+#define MUSB_INTRRXE           0x08
+#define MUSB_INTRUSB           0x0A    /* 8 bit */
+#define MUSB_INTRUSBE          0x0B    /* 8 bit */
+#define MUSB_FRAME             0x0C
+#define MUSB_INDEX             0x0E    /* 8 bit */
+#define MUSB_TESTMODE          0x0F    /* 8 bit */
+
+/* Get offset for a given FIFO from musb->mregs */
+#ifdef CONFIG_USB_TUSB6010
+#define MUSB_FIFO_OFFSET(epnum)        (0x200 + ((epnum) * 0x20))
+#else
+#define MUSB_FIFO_OFFSET(epnum)        (0x20 + ((epnum) * 4))
+#endif
+
+/*
+ * Additional Control Registers
+ */
+
+#define MUSB_DEVCTL            0x60    /* 8 bit */
+
+/* These are always controlled through the INDEX register */
+#define MUSB_TXFIFOSZ          0x62    /* 8-bit (see masks) */
+#define MUSB_RXFIFOSZ          0x63    /* 8-bit (see masks) */
+#define MUSB_TXFIFOADD         0x64    /* 16-bit offset shifted right 3 */
+#define MUSB_RXFIFOADD         0x66    /* 16-bit offset shifted right 3 */
+
+/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */
+#define MUSB_HWVERS            0x6C    /* 8 bit */
+
+#define MUSB_EPINFO            0x78    /* 8 bit */
+#define MUSB_RAMINFO           0x79    /* 8 bit */
+#define MUSB_LINKINFO          0x7a    /* 8 bit */
+#define MUSB_VPLEN             0x7b    /* 8 bit */
+#define MUSB_HS_EOF1           0x7c    /* 8 bit */
+#define MUSB_FS_EOF1           0x7d    /* 8 bit */
+#define MUSB_LS_EOF1           0x7e    /* 8 bit */
+
+/* Offsets to endpoint registers */
+#define MUSB_TXMAXP            0x00
+#define MUSB_TXCSR             0x02
+#define MUSB_CSR0              MUSB_TXCSR      /* Re-used for EP0 */
+#define MUSB_RXMAXP            0x04
+#define MUSB_RXCSR             0x06
+#define MUSB_RXCOUNT           0x08
+#define MUSB_COUNT0            MUSB_RXCOUNT    /* Re-used for EP0 */
+#define MUSB_TXTYPE            0x0A
+#define MUSB_TYPE0             MUSB_TXTYPE     /* Re-used for EP0 */
+#define MUSB_TXINTERVAL                0x0B
+#define MUSB_NAKLIMIT0         MUSB_TXINTERVAL /* Re-used for EP0 */
+#define MUSB_RXTYPE            0x0C
+#define MUSB_RXINTERVAL                0x0D
+#define MUSB_FIFOSIZE          0x0F
+#define MUSB_CONFIGDATA                MUSB_FIFOSIZE   /* Re-used for EP0 */
+
+/* Offsets to endpoint registers in indexed model (using INDEX register) */
+#define MUSB_INDEXED_OFFSET(_epnum, _offset)   \
+       (0x10 + (_offset))
+
+/* Offsets to endpoint registers in flat models */
+#define MUSB_FLAT_OFFSET(_epnum, _offset)      \
+       (0x100 + (0x10*(_epnum)) + (_offset))
+
+#ifdef CONFIG_USB_TUSB6010
+/* TUSB6010 EP0 configuration register is special */
+#define MUSB_TUSB_OFFSET(_epnum, _offset)      \
+       (0x10 + _offset)
+#include "tusb6010.h"          /* Needed "only" for TUSB_EP0_CONF */
+#endif
+
+#define MUSB_TXCSR_MODE                        0x2000
+
+/* "bus control"/target registers, for host side multipoint (external hubs) */
+#define MUSB_TXFUNCADDR                0x00
+#define MUSB_TXHUBADDR         0x02
+#define MUSB_TXHUBPORT         0x03
+
+#define MUSB_RXFUNCADDR                0x04
+#define MUSB_RXHUBADDR         0x06
+#define MUSB_RXHUBPORT         0x07
+
+#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
+       (0x80 + (8*(_epnum)) + (_offset))
+
+static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
+{
+       musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
+}
+
+static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off)
+{
+       musb_writew(mbase, MUSB_TXFIFOADD, c_off);
+}
+
+static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size)
+{
+       musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
+}
+
+static inline void  musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
+{
+       musb_writew(mbase, MUSB_RXFIFOADD, c_off);
+}
+
+static inline u8 musb_read_configdata(void __iomem *mbase)
+{
+       return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA);
+}
+
+static inline u16 musb_read_hwvers(void __iomem *mbase)
+{
+       return musb_readw(mbase, MUSB_HWVERS);
+}
+
+static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
+{
+       return (MUSB_BUSCTL_OFFSET(i, 0) + mbase);
+}
+
+static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+               u8 qh_addr_reg)
+{
+       musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg);
+}
+
+static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+               u8 qh_h_addr_reg)
+{
+       musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg);
+}
+
+static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+               u8 qh_h_port_reg)
+{
+       musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg);
+}
+
+static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+       musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR),
+                       qh_addr_reg);
+}
+
+static inline void  musb_write_txhubaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+       musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR),
+                       qh_addr_reg);
+}
+
+static inline void  musb_write_txhubport(void __iomem *mbase, u8 epnum,
+               u8 qh_h_port_reg)
+{
+       musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT),
+                       qh_h_port_reg);
+}
+
+#else /* CONFIG_BLACKFIN */
+
+#define USB_BASE               USB_FADDR
+#define USB_OFFSET(reg)                (reg - USB_BASE)
+
+/*
+ * Common USB registers
+ */
+#define MUSB_FADDR             USB_OFFSET(USB_FADDR)   /* 8-bit */
+#define MUSB_POWER             USB_OFFSET(USB_POWER)   /* 8-bit */
+#define MUSB_INTRTX            USB_OFFSET(USB_INTRTX)  /* 16-bit */
+#define MUSB_INTRRX            USB_OFFSET(USB_INTRRX)
+#define MUSB_INTRTXE           USB_OFFSET(USB_INTRTXE)
+#define MUSB_INTRRXE           USB_OFFSET(USB_INTRRXE)
+#define MUSB_INTRUSB           USB_OFFSET(USB_INTRUSB) /* 8 bit */
+#define MUSB_INTRUSBE          USB_OFFSET(USB_INTRUSBE)/* 8 bit */
+#define MUSB_FRAME             USB_OFFSET(USB_FRAME)
+#define MUSB_INDEX             USB_OFFSET(USB_INDEX)   /* 8 bit */
+#define MUSB_TESTMODE          USB_OFFSET(USB_TESTMODE)/* 8 bit */
+
+/* Get offset for a given FIFO from musb->mregs */
+#define MUSB_FIFO_OFFSET(epnum)        \
+       (USB_OFFSET(USB_EP0_FIFO) + ((epnum) * 8))
+
+/*
+ * Additional Control Registers
+ */
+
+#define MUSB_DEVCTL            USB_OFFSET(USB_OTG_DEV_CTL)     /* 8 bit */
+
+#define MUSB_LINKINFO          USB_OFFSET(USB_LINKINFO)/* 8 bit */
+#define MUSB_VPLEN             USB_OFFSET(USB_VPLEN)   /* 8 bit */
+#define MUSB_HS_EOF1           USB_OFFSET(USB_HS_EOF1) /* 8 bit */
+#define MUSB_FS_EOF1           USB_OFFSET(USB_FS_EOF1) /* 8 bit */
+#define MUSB_LS_EOF1           USB_OFFSET(USB_LS_EOF1) /* 8 bit */
+
+/* Offsets to endpoint registers */
+#define MUSB_TXMAXP            0x00
+#define MUSB_TXCSR             0x04
+#define MUSB_CSR0              MUSB_TXCSR      /* Re-used for EP0 */
+#define MUSB_RXMAXP            0x08
+#define MUSB_RXCSR             0x0C
+#define MUSB_RXCOUNT           0x10
+#define MUSB_COUNT0            MUSB_RXCOUNT    /* Re-used for EP0 */
+#define MUSB_TXTYPE            0x14
+#define MUSB_TYPE0             MUSB_TXTYPE     /* Re-used for EP0 */
+#define MUSB_TXINTERVAL                0x18
+#define MUSB_NAKLIMIT0         MUSB_TXINTERVAL /* Re-used for EP0 */
+#define MUSB_RXTYPE            0x1C
+#define MUSB_RXINTERVAL                0x20
+#define MUSB_TXCOUNT           0x28
+
+/* Offsets to endpoint registers in indexed model (using INDEX register) */
+#define MUSB_INDEXED_OFFSET(_epnum, _offset)   \
+       (0x40 + (_offset))
+
+/* Offsets to endpoint registers in flat models */
+#define MUSB_FLAT_OFFSET(_epnum, _offset)      \
+       (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset))
+
+/* Not implemented - HW has seperate Tx/Rx FIFO */
+#define MUSB_TXCSR_MODE                        0x0000
+
+/*
+ * Dummy stub for clk framework, it will be removed
+ * until Blackfin supports clk framework
+ */
+#define clk_get(dev, id)       NULL
+#define clk_put(clock)         do {} while (0)
+#define clk_enable(clock)      do {} while (0)
+#define clk_disable(clock)     do {} while (0)
+
+static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
+{
+}
+
+static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off)
+{
+}
+
+static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size)
+{
+}
+
+static inline void  musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
+{
+}
+
+static inline u8 musb_read_configdata(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u16 musb_read_hwvers(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u16 musb_read_target_reg_base(u8 i, void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+               u8 qh_addr_req)
+{
+}
+
+static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+               u8 qh_h_addr_reg)
+{
+}
+
+static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+               u8 qh_h_port_reg)
+{
+}
+
+static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+}
+
+static inline void  musb_write_txhubaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+}
+
+static inline void  musb_write_txhubport(void __iomem *mbase, u8 epnum,
+               u8 qh_h_port_reg)
+{
+}
+
+#endif /* CONFIG_BLACKFIN */
+
 #endif /* __MUSB_REGS_H__ */
index 8c734ef2c1ed52a8f39dceca5b7bff647b6d8dd4..75b15ce38f381bbdec65d3db8456511c5cd02b2b 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include "musb_core.h"
-
-#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
-#include "omap2430.h"
-#endif
-
-#define MUSB_HSDMA_BASE                0x200
-#define MUSB_HSDMA_INTR                (MUSB_HSDMA_BASE + 0)
-#define MUSB_HSDMA_CONTROL             0x4
-#define MUSB_HSDMA_ADDRESS             0x8
-#define MUSB_HSDMA_COUNT               0xc
-
-#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset)          \
-               (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
-
-/* control register (16-bit): */
-#define MUSB_HSDMA_ENABLE_SHIFT                0
-#define MUSB_HSDMA_TRANSMIT_SHIFT              1
-#define MUSB_HSDMA_MODE1_SHIFT         2
-#define MUSB_HSDMA_IRQENABLE_SHIFT             3
-#define MUSB_HSDMA_ENDPOINT_SHIFT              4
-#define MUSB_HSDMA_BUSERROR_SHIFT              8
-#define MUSB_HSDMA_BURSTMODE_SHIFT             9
-#define MUSB_HSDMA_BURSTMODE           (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
-#define MUSB_HSDMA_BURSTMODE_UNSPEC    0
-#define MUSB_HSDMA_BURSTMODE_INCR4     1
-#define MUSB_HSDMA_BURSTMODE_INCR8     2
-#define MUSB_HSDMA_BURSTMODE_INCR16    3
-
-#define MUSB_HSDMA_CHANNELS            8
-
-struct musb_dma_controller;
-
-struct musb_dma_channel {
-       struct dma_channel              channel;
-       struct musb_dma_controller      *controller;
-       u32                             start_addr;
-       u32                             len;
-       u16                             max_packet_sz;
-       u8                              idx;
-       u8                              epnum;
-       u8                              transmit;
-};
-
-struct musb_dma_controller {
-       struct dma_controller           controller;
-       struct musb_dma_channel         channel[MUSB_HSDMA_CHANNELS];
-       void                            *private_data;
-       void __iomem                    *base;
-       u8                              channel_count;
-       u8                              used_channels;
-       u8                              irq;
-};
+#include "musbhsdma.h"
 
 static int dma_controller_start(struct dma_controller *c)
 {
@@ -179,36 +128,24 @@ static void configure_channel(struct dma_channel *channel,
        DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
                        channel, packet_sz, dma_addr, len, mode);
 
-       if (mode) {
-               csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
-               BUG_ON(len < packet_sz);
-
-               if (packet_sz >= 64) {
-                       csr |= MUSB_HSDMA_BURSTMODE_INCR16
-                                       << MUSB_HSDMA_BURSTMODE_SHIFT;
-               } else if (packet_sz >= 32) {
-                       csr |= MUSB_HSDMA_BURSTMODE_INCR8
-                                       << MUSB_HSDMA_BURSTMODE_SHIFT;
-               } else if (packet_sz >= 16) {
-                       csr |= MUSB_HSDMA_BURSTMODE_INCR4
-                                       << MUSB_HSDMA_BURSTMODE_SHIFT;
-               }
-       }
+       if (packet_sz >= 64)
+               csr |= MUSB_HSDMA_BURSTMODE_INCR16;
+       else if (packet_sz >= 32)
+               csr |= MUSB_HSDMA_BURSTMODE_INCR8;
+       else if (packet_sz >= 16)
+               csr |= MUSB_HSDMA_BURSTMODE_INCR4;
 
        csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
-               | (1 << MUSB_HSDMA_ENABLE_SHIFT)
-               | (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
+               | MUSB_HSDMA_MODE1
+               | MUSB_HSDMA_ENABLE
+               | MUSB_HSDMA_IRQENABLE
                | (musb_channel->transmit
-                               ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
+                               ? MUSB_HSDMA_TRANSMIT
                                : 0);
 
        /* address/count */
-       musb_writel(mbase,
-               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS),
-               dma_addr);
-       musb_writel(mbase,
-               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT),
-               len);
+       musb_write_hsdma_addr(mbase, bchannel, dma_addr);
+       musb_write_hsdma_count(mbase, bchannel, len);
 
        /* control (this should start things) */
        musb_writew(mbase,
@@ -236,10 +173,7 @@ static int dma_channel_program(struct dma_channel *channel,
        musb_channel->max_packet_sz = packet_sz;
        channel->status = MUSB_DMA_STATUS_BUSY;
 
-       if ((mode == 1) && (len >= packet_sz))
-               configure_channel(channel, packet_sz, 1, dma_addr, len);
-       else
-               configure_channel(channel, packet_sz, 0, dma_addr, len);
+       configure_channel(channel, packet_sz, mode, dma_addr, len);
 
        return true;
 }
@@ -279,13 +213,8 @@ static int dma_channel_abort(struct dma_channel *channel)
                musb_writew(mbase,
                        MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
                        0);
-               musb_writel(mbase,
-                       MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS),
-                       0);
-               musb_writel(mbase,
-                       MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT),
-                       0);
-
+               musb_write_hsdma_addr(mbase, bchannel, 0);
+               musb_write_hsdma_count(mbase, bchannel, 0);
                channel->status = MUSB_DMA_STATUS_FREE;
        }
 
@@ -327,16 +256,14 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
                                        MUSB_HSDMA_CHANNEL_OFFSET(bchannel,
                                                        MUSB_HSDMA_CONTROL));
 
-                       if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) {
+                       if (csr & MUSB_HSDMA_BUSERROR) {
                                musb_channel->channel.status =
                                        MUSB_DMA_STATUS_BUS_ABORT;
                        } else {
                                u8 devctl;
 
-                               addr = musb_readl(mbase,
-                                               MUSB_HSDMA_CHANNEL_OFFSET(
-                                                       bchannel,
-                                                       MUSB_HSDMA_ADDRESS));
+                               addr = musb_read_hsdma_addr(mbase,
+                                               bchannel);
                                channel->actual_len = addr
                                        - musb_channel->start_addr;
 
@@ -375,6 +302,12 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
                        }
                }
        }
+
+#ifdef CONFIG_BLACKFIN
+       /* Clear DMA interrup flags */
+       musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma);
+#endif
+
        retval = IRQ_HANDLED;
 done:
        spin_unlock_irqrestore(&musb->lock, flags);
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h
new file mode 100644 (file)
index 0000000..fb8fcd1
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * MUSB OTG driver - support for Mentor's DMA controller
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2007 by Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
+#include "omap2430.h"
+#endif
+
+#ifndef CONFIG_BLACKFIN
+
+#define MUSB_HSDMA_BASE                0x200
+#define MUSB_HSDMA_INTR                (MUSB_HSDMA_BASE + 0)
+#define MUSB_HSDMA_CONTROL             0x4
+#define MUSB_HSDMA_ADDRESS             0x8
+#define MUSB_HSDMA_COUNT               0xc
+
+#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset)          \
+               (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
+
+#define musb_read_hsdma_addr(mbase, bchannel)  \
+       musb_readl(mbase,       \
+                  MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS))
+
+#define musb_write_hsdma_addr(mbase, bchannel, addr) \
+       musb_writel(mbase, \
+                   MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \
+                   addr)
+
+#define musb_write_hsdma_count(mbase, bchannel, len) \
+       musb_writel(mbase, \
+                   MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \
+                   len)
+#else
+
+#define MUSB_HSDMA_BASE                0x400
+#define MUSB_HSDMA_INTR                (MUSB_HSDMA_BASE + 0)
+#define MUSB_HSDMA_CONTROL             0x04
+#define MUSB_HSDMA_ADDR_LOW            0x08
+#define MUSB_HSDMA_ADDR_HIGH           0x0C
+#define MUSB_HSDMA_COUNT_LOW           0x10
+#define MUSB_HSDMA_COUNT_HIGH          0x14
+
+#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset)          \
+               (MUSB_HSDMA_BASE + (_bchannel * 0x20) + _offset)
+
+static inline u32 musb_read_hsdma_addr(void __iomem *mbase, u8 bchannel)
+{
+       u32 addr = musb_readw(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH));
+
+       addr = addr << 16;
+
+       addr |= musb_readw(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW));
+
+       return addr;
+}
+
+static inline void musb_write_hsdma_addr(void __iomem *mbase,
+                               u8 bchannel, dma_addr_t dma_addr)
+{
+       musb_writew(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW),
+               ((u16)((u32) dma_addr & 0xFFFF)));
+       musb_writew(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH),
+               ((u16)(((u32) dma_addr >> 16) & 0xFFFF)));
+}
+
+static inline void musb_write_hsdma_count(void __iomem *mbase,
+                               u8 bchannel, u32 len)
+{
+       musb_writew(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW),
+               ((u16)((u32) len & 0xFFFF)));
+       musb_writew(mbase,
+               MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH),
+               ((u16)(((u32) len >> 16) & 0xFFFF)));
+}
+
+#endif /* CONFIG_BLACKFIN */
+
+/* control register (16-bit): */
+#define MUSB_HSDMA_ENABLE              (1 << 0)
+#define MUSB_HSDMA_TRANSMIT            (1 << 1)
+#define MUSB_HSDMA_MODE1               (1 << 2)
+#define MUSB_HSDMA_IRQENABLE           (1 << 3)
+#define MUSB_HSDMA_ENDPOINT_SHIFT      4
+#define MUSB_HSDMA_BUSERROR            (1 << 8)
+
+#define MUSB_HSDMA_BURSTMODE_SHIFT     9
+#define MUSB_HSDMA_BURSTMODE_UNSPEC    (0 << MUSB_HSDMA_BURSTMODE_SHIFT)
+#define MUSB_HSDMA_BURSTMODE_INCR4     (1 << MUSB_HSDMA_BURSTMODE_SHIFT)
+#define MUSB_HSDMA_BURSTMODE_INCR8     (2 << MUSB_HSDMA_BURSTMODE_SHIFT)
+#define MUSB_HSDMA_BURSTMODE_INCR16    (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
+
+#define MUSB_HSDMA_CHANNELS            8
+
+struct musb_dma_controller;
+
+struct musb_dma_channel {
+       struct dma_channel              channel;
+       struct musb_dma_controller      *controller;
+       u32                             start_addr;
+       u32                             len;
+       u16                             max_packet_sz;
+       u8                              idx;
+       u8                              epnum;
+       u8                              transmit;
+};
+
+struct musb_dma_controller {
+       struct dma_controller           controller;
+       struct musb_dma_channel         channel[MUSB_HSDMA_CHANNELS];
+       void                            *private_data;
+       void __iomem                    *base;
+       u8                              channel_count;
+       u8                              used_channels;
+       u8                              irq;
+};
index 03fc8640ddaf853fab87a051cef0f87274c93de4..3f9953640bfe3d8ba0f273025a0336dde2730b17 100644 (file)
@@ -58,10 +58,10 @@ static void musb_do_idle(unsigned long _musb)
 #endif
        u8      devctl;
 
-       devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
-
        spin_lock_irqsave(&musb->lock, flags);
 
+       devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+
        switch (musb->xceiv.state) {
        case OTG_STATE_A_WAIT_BCON:
                devctl &= ~MUSB_DEVCTL_SESSION;
@@ -196,7 +196,7 @@ static int omap_set_power(struct otg_transceiver *x, unsigned mA)
 
 static int musb_platform_resume(struct musb *musb);
 
-void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
+int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
 {
        u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
 
@@ -204,15 +204,24 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
        musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 
        switch (musb_mode) {
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
        case MUSB_HOST:
                otg_set_host(&musb->xceiv, musb->xceiv.host);
                break;
+#endif
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
        case MUSB_PERIPHERAL:
                otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget);
                break;
+#endif
+#ifdef CONFIG_USB_MUSB_OTG
        case MUSB_OTG:
                break;
+#endif
+       default:
+               return -EINVAL;
        }
+       return 0;
 }
 
 int __init musb_platform_init(struct musb *musb)
index ee8fca92a4ac4cd0ec58b157941bf8017ecff331..9e20fd070d7134db7727f9a94633d98a35a3ce8e 100644 (file)
@@ -598,7 +598,7 @@ static void tusb_source_power(struct musb *musb, int is_on)
  * and peripheral modes in non-OTG configurations by reconfiguring hardware
  * and then setting musb->board_mode. For now, only support OTG mode.
  */
-void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
+int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
 {
        void __iomem    *tbase = musb->ctrl_base;
        u32             otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf;
@@ -641,7 +641,8 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
 #endif
 
        default:
-               DBG(2, "Trying to set unknown mode %i\n", musb_mode);
+               DBG(2, "Trying to set mode %i\n", musb_mode);
+               return -EINVAL;
        }
 
        musb_writel(tbase, TUSB_PHY_OTG_CTRL,
@@ -655,6 +656,8 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
                !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS))
                        INFO("Cannot be peripheral with mini-A cable "
                        "otg_stat: %08x\n", otg_stat);
+
+       return 0;
 }
 
 static inline unsigned long
index 630962c04ca45363fbf64a7115529f79c0e8bc1d..d6aad0ea603336c2442924fe9f5b10969380ff45 100644 (file)
@@ -47,6 +47,11 @@ struct musb_hdrc_config {
        u8              ram_bits;       /* ram address size */
 
        struct musb_hdrc_eps_bits *eps_bits;
+#ifdef CONFIG_BLACKFIN
+        /* A GPIO controlling VRSEL in Blackfin */
+        unsigned int    gpio_vrsel;
+#endif
+
 };
 
 struct musb_hdrc_platform_data {