diff options
Diffstat (limited to 'drivers/usb/musb')
| -rw-r--r-- | drivers/usb/musb/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/usb/musb/Makefile | 8 | ||||
| -rw-r--r-- | drivers/usb/musb/blackfin.c | 320 | ||||
| -rw-r--r-- | drivers/usb/musb/blackfin.h | 52 | ||||
| -rw-r--r-- | drivers/usb/musb/davinci.c | 18 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_core.c | 84 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_core.h | 73 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_gadget.c | 2 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_host.c | 45 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_io.h | 26 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_regs.h | 397 | ||||
| -rw-r--r-- | drivers/usb/musb/musbhsdma.c | 84 | ||||
| -rw-r--r-- | drivers/usb/musb/musbhsdma.h | 149 | ||||
| -rw-r--r-- | drivers/usb/musb/omap2430.c | 15 | ||||
| -rw-r--r-- | drivers/usb/musb/tusb6010.c | 7 |
15 files changed, 1043 insertions, 249 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 4b9542bbb35c..5af7379cd9a3 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
| @@ -11,7 +11,7 @@ config USB_MUSB_HDRC | |||
| 11 | depends on (USB || USB_GADGET) && HAVE_CLK | 11 | depends on (USB || USB_GADGET) && HAVE_CLK |
| 12 | depends on !SUPERH | 12 | depends on !SUPERH |
| 13 | select TWL4030_USB if MACH_OMAP_3430SDP | 13 | select TWL4030_USB if MACH_OMAP_3430SDP |
| 14 | tristate 'Inventra Highspeed Dual Role Controller (TI, ...)' | 14 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
| 15 | help | 15 | help |
| 16 | Say Y here if your system has a dual role high speed USB | 16 | Say Y here if your system has a dual role high speed USB |
| 17 | controller based on the Mentor Graphics silicon IP. Then | 17 | controller based on the Mentor Graphics silicon IP. Then |
| @@ -22,6 +22,9 @@ config USB_MUSB_HDRC | |||
| 22 | Texas Instruments parts using this IP include DaVinci 644x, | 22 | Texas Instruments parts using this IP include DaVinci 644x, |
| 23 | OMAP 243x, OMAP 343x, and TUSB 6010. | 23 | OMAP 243x, OMAP 343x, and TUSB 6010. |
| 24 | 24 | ||
| 25 | Analog Devices parts using this IP include Blackfin BF54x, | ||
| 26 | BF525 and BF527. | ||
| 27 | |||
| 25 | If you do not know what this is, please say N. | 28 | If you do not know what this is, please say N. |
| 26 | 29 | ||
| 27 | To compile this driver as a module, choose M here; the | 30 | To compile this driver as a module, choose M here; the |
| @@ -33,6 +36,8 @@ config USB_MUSB_SOC | |||
| 33 | default y if ARCH_DAVINCI | 36 | default y if ARCH_DAVINCI |
| 34 | default y if ARCH_OMAP2430 | 37 | default y if ARCH_OMAP2430 |
| 35 | default y if ARCH_OMAP34XX | 38 | default y if ARCH_OMAP34XX |
| 39 | default y if (BF54x && !BF544) | ||
| 40 | default y if (BF52x && !BF522 && !BF523) | ||
| 36 | 41 | ||
| 37 | comment "DaVinci 644x USB support" | 42 | comment "DaVinci 644x USB support" |
| 38 | depends on USB_MUSB_HDRC && ARCH_DAVINCI | 43 | depends on USB_MUSB_HDRC && ARCH_DAVINCI |
| @@ -43,6 +48,9 @@ comment "OMAP 243x high speed USB support" | |||
| 43 | comment "OMAP 343x high speed USB support" | 48 | comment "OMAP 343x high speed USB support" |
| 44 | depends on USB_MUSB_HDRC && ARCH_OMAP34XX | 49 | depends on USB_MUSB_HDRC && ARCH_OMAP34XX |
| 45 | 50 | ||
| 51 | comment "Blackfin high speed USB Support" | ||
| 52 | depends on USB_MUSB_HDRC && (BF54x && !BF544) || (BF52x && !BF522 && !BF523) | ||
| 53 | |||
| 46 | config USB_TUSB6010 | 54 | config USB_TUSB6010 |
| 47 | boolean "TUSB 6010 support" | 55 | boolean "TUSB 6010 support" |
| 48 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC | 56 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC |
| @@ -142,7 +150,7 @@ config MUSB_PIO_ONLY | |||
| 142 | config USB_INVENTRA_DMA | 150 | config USB_INVENTRA_DMA |
| 143 | bool | 151 | bool |
| 144 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY | 152 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY |
| 145 | default ARCH_OMAP2430 || ARCH_OMAP34XX | 153 | default ARCH_OMAP2430 || ARCH_OMAP34XX || BLACKFIN |
| 146 | help | 154 | help |
| 147 | Enable DMA transfers using Mentor's engine. | 155 | Enable DMA transfers using Mentor's engine. |
| 148 | 156 | ||
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index b6af0d687a73..85710ccc1887 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile | |||
| @@ -22,6 +22,14 @@ ifeq ($(CONFIG_ARCH_OMAP3430),y) | |||
| 22 | musb_hdrc-objs += omap2430.o | 22 | musb_hdrc-objs += omap2430.o |
| 23 | endif | 23 | endif |
| 24 | 24 | ||
| 25 | ifeq ($(CONFIG_BF54x),y) | ||
| 26 | musb_hdrc-objs += blackfin.o | ||
| 27 | endif | ||
| 28 | |||
| 29 | ifeq ($(CONFIG_BF52x),y) | ||
| 30 | musb_hdrc-objs += blackfin.o | ||
| 31 | endif | ||
| 32 | |||
| 25 | ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y) | 33 | ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y) |
| 26 | musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o | 34 | musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o |
| 27 | endif | 35 | endif |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c new file mode 100644 index 000000000000..786134852092 --- /dev/null +++ b/drivers/usb/musb/blackfin.c | |||
| @@ -0,0 +1,320 @@ | |||
| 1 | /* | ||
| 2 | * MUSB OTG controller driver for Blackfin Processors | ||
| 3 | * | ||
| 4 | * Copyright 2006-2008 Analog Devices Inc. | ||
| 5 | * | ||
| 6 | * Enter bugs at http://blackfin.uclinux.org/ | ||
| 7 | * | ||
| 8 | * Licensed under the GPL-2 or later. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/sched.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/list.h> | ||
| 17 | #include <linux/clk.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <linux/io.h> | ||
| 20 | |||
| 21 | #include <asm/cacheflush.h> | ||
| 22 | |||
| 23 | #include "musb_core.h" | ||
| 24 | #include "blackfin.h" | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Load an endpoint's FIFO | ||
| 28 | */ | ||
| 29 | void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | ||
| 30 | { | ||
| 31 | void __iomem *fifo = hw_ep->fifo; | ||
| 32 | void __iomem *epio = hw_ep->regs; | ||
| 33 | |||
| 34 | prefetch((u8 *)src); | ||
| 35 | |||
| 36 | musb_writew(epio, MUSB_TXCOUNT, len); | ||
| 37 | |||
| 38 | DBG(4, "TX ep%d fifo %p count %d buf %p, epio %p\n", | ||
| 39 | hw_ep->epnum, fifo, len, src, epio); | ||
| 40 | |||
| 41 | dump_fifo_data(src, len); | ||
| 42 | |||
| 43 | if (unlikely((unsigned long)src & 0x01)) | ||
| 44 | outsw_8((unsigned long)fifo, src, | ||
| 45 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 46 | else | ||
| 47 | outsw((unsigned long)fifo, src, | ||
| 48 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 49 | } | ||
| 50 | |||
| 51 | /* | ||
| 52 | * Unload an endpoint's FIFO | ||
| 53 | */ | ||
| 54 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | ||
| 55 | { | ||
| 56 | void __iomem *fifo = hw_ep->fifo; | ||
| 57 | u8 epnum = hw_ep->epnum; | ||
| 58 | u16 dma_reg = 0; | ||
| 59 | |||
| 60 | DBG(4, "%cX ep%d fifo %p count %d buf %p\n", | ||
| 61 | 'R', hw_ep->epnum, fifo, len, dst); | ||
| 62 | |||
| 63 | #ifdef CONFIG_BF52x | ||
| 64 | invalidate_dcache_range((unsigned int)dst, | ||
| 65 | (unsigned int)(dst + len)); | ||
| 66 | |||
| 67 | /* Setup DMA address register */ | ||
| 68 | dma_reg = (u16) ((u32) dst & 0xFFFF); | ||
| 69 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); | ||
| 70 | SSYNC(); | ||
| 71 | |||
| 72 | dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); | ||
| 73 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | ||
| 74 | SSYNC(); | ||
| 75 | |||
| 76 | /* Setup DMA count register */ | ||
| 77 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); | ||
| 78 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); | ||
| 79 | SSYNC(); | ||
| 80 | |||
| 81 | /* Enable the DMA */ | ||
| 82 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; | ||
| 83 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); | ||
| 84 | SSYNC(); | ||
| 85 | |||
| 86 | /* Wait for compelete */ | ||
| 87 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) | ||
| 88 | cpu_relax(); | ||
| 89 | |||
| 90 | /* acknowledge dma interrupt */ | ||
| 91 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); | ||
| 92 | SSYNC(); | ||
| 93 | |||
| 94 | /* Reset DMA */ | ||
| 95 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | ||
| 96 | SSYNC(); | ||
| 97 | #else | ||
| 98 | if (unlikely((unsigned long)dst & 0x01)) | ||
| 99 | insw_8((unsigned long)fifo, dst, | ||
| 100 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 101 | else | ||
| 102 | insw((unsigned long)fifo, dst, | ||
| 103 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 104 | #endif | ||
| 105 | |||
| 106 | dump_fifo_data(dst, len); | ||
| 107 | } | ||
| 108 | |||
| 109 | static irqreturn_t blackfin_interrupt(int irq, void *__hci) | ||
| 110 | { | ||
| 111 | unsigned long flags; | ||
| 112 | irqreturn_t retval = IRQ_NONE; | ||
| 113 | struct musb *musb = __hci; | ||
| 114 | |||
| 115 | spin_lock_irqsave(&musb->lock, flags); | ||
| 116 | |||
| 117 | musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); | ||
| 118 | musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); | ||
| 119 | musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); | ||
| 120 | |||
| 121 | if (musb->int_usb || musb->int_tx || musb->int_rx) { | ||
| 122 | musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb); | ||
| 123 | musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx); | ||
| 124 | musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx); | ||
| 125 | retval = musb_interrupt(musb); | ||
| 126 | } | ||
| 127 | |||
| 128 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 129 | |||
| 130 | /* REVISIT we sometimes get spurious IRQs on g_ep0 | ||
| 131 | * not clear why... fall in BF54x too. | ||
| 132 | */ | ||
| 133 | if (retval != IRQ_HANDLED) | ||
| 134 | DBG(5, "spurious?\n"); | ||
| 135 | |||
| 136 | return IRQ_HANDLED; | ||
| 137 | } | ||
| 138 | |||
| 139 | static void musb_conn_timer_handler(unsigned long _musb) | ||
| 140 | { | ||
| 141 | struct musb *musb = (void *)_musb; | ||
| 142 | unsigned long flags; | ||
| 143 | u16 val; | ||
| 144 | |||
| 145 | spin_lock_irqsave(&musb->lock, flags); | ||
| 146 | switch (musb->xceiv.state) { | ||
| 147 | case OTG_STATE_A_IDLE: | ||
| 148 | case OTG_STATE_A_WAIT_BCON: | ||
| 149 | /* Start a new session */ | ||
| 150 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | ||
| 151 | val |= MUSB_DEVCTL_SESSION; | ||
| 152 | musb_writew(musb->mregs, MUSB_DEVCTL, val); | ||
| 153 | |||
| 154 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | ||
| 155 | if (!(val & MUSB_DEVCTL_BDEVICE)) { | ||
| 156 | gpio_set_value(musb->config->gpio_vrsel, 1); | ||
| 157 | musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | ||
| 158 | } else { | ||
| 159 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
| 160 | |||
| 161 | /* Ignore VBUSERROR and SUSPEND IRQ */ | ||
| 162 | val = musb_readb(musb->mregs, MUSB_INTRUSBE); | ||
| 163 | val &= ~MUSB_INTR_VBUSERROR; | ||
| 164 | musb_writeb(musb->mregs, MUSB_INTRUSBE, val); | ||
| 165 | |||
| 166 | val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; | ||
| 167 | musb_writeb(musb->mregs, MUSB_INTRUSB, val); | ||
| 168 | |||
| 169 | val = MUSB_POWER_HSENAB; | ||
| 170 | musb_writeb(musb->mregs, MUSB_POWER, val); | ||
| 171 | } | ||
| 172 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
| 173 | break; | ||
| 174 | |||
| 175 | default: | ||
| 176 | DBG(1, "%s state not handled\n", otg_state_string(musb)); | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 180 | |||
| 181 | DBG(4, "state is %s\n", otg_state_string(musb)); | ||
| 182 | } | ||
| 183 | |||
| 184 | void musb_platform_enable(struct musb *musb) | ||
| 185 | { | ||
| 186 | if (is_host_enabled(musb)) { | ||
| 187 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
| 188 | musb->a_wait_bcon = TIMER_DELAY; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | void musb_platform_disable(struct musb *musb) | ||
| 193 | { | ||
| 194 | } | ||
| 195 | |||
| 196 | static void bfin_vbus_power(struct musb *musb, int is_on, int sleeping) | ||
| 197 | { | ||
| 198 | } | ||
| 199 | |||
| 200 | static void bfin_set_vbus(struct musb *musb, int is_on) | ||
| 201 | { | ||
| 202 | if (is_on) | ||
| 203 | gpio_set_value(musb->config->gpio_vrsel, 1); | ||
| 204 | else | ||
| 205 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
| 206 | |||
| 207 | DBG(1, "VBUS %s, devctl %02x " | ||
| 208 | /* otg %3x conf %08x prcm %08x */ "\n", | ||
| 209 | otg_state_string(musb), | ||
| 210 | musb_readb(musb->mregs, MUSB_DEVCTL)); | ||
| 211 | } | ||
| 212 | |||
| 213 | static int bfin_set_power(struct otg_transceiver *x, unsigned mA) | ||
| 214 | { | ||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | ||
| 219 | { | ||
| 220 | if (is_host_enabled(musb)) | ||
| 221 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
| 222 | } | ||
| 223 | |||
| 224 | int musb_platform_get_vbus_status(struct musb *musb) | ||
| 225 | { | ||
| 226 | return 0; | ||
| 227 | } | ||
| 228 | |||
| 229 | void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | ||
| 230 | { | ||
| 231 | } | ||
| 232 | |||
| 233 | int __init musb_platform_init(struct musb *musb) | ||
| 234 | { | ||
| 235 | |||
| 236 | /* | ||
| 237 | * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE | ||
| 238 | * and OTG HOST modes, while rev 1.1 and greater require PE7 to | ||
| 239 | * be low for DEVICE mode and high for HOST mode. We set it high | ||
| 240 | * here because we are in host mode | ||
| 241 | */ | ||
| 242 | |||
| 243 | if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { | ||
| 244 | printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n", | ||
| 245 | musb->config->gpio_vrsel); | ||
| 246 | return -ENODEV; | ||
| 247 | } | ||
| 248 | gpio_direction_output(musb->config->gpio_vrsel, 0); | ||
| 249 | |||
| 250 | if (ANOMALY_05000346) { | ||
| 251 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); | ||
| 252 | SSYNC(); | ||
| 253 | } | ||
| 254 | |||
| 255 | if (ANOMALY_05000347) { | ||
| 256 | bfin_write_USB_APHY_CNTRL(0x0); | ||
| 257 | SSYNC(); | ||
| 258 | } | ||
| 259 | |||
| 260 | /* TODO | ||
| 261 | * Set SIC-IVG register | ||
| 262 | */ | ||
| 263 | |||
| 264 | /* Configure PLL oscillator register */ | ||
| 265 | bfin_write_USB_PLLOSC_CTRL(0x30a8); | ||
| 266 | SSYNC(); | ||
| 267 | |||
| 268 | bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1); | ||
| 269 | SSYNC(); | ||
| 270 | |||
| 271 | bfin_write_USB_EP_NI0_RXMAXP(64); | ||
| 272 | SSYNC(); | ||
| 273 | |||
| 274 | bfin_write_USB_EP_NI0_TXMAXP(64); | ||
| 275 | SSYNC(); | ||
| 276 | |||
| 277 | /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/ | ||
| 278 | bfin_write_USB_GLOBINTR(0x7); | ||
| 279 | SSYNC(); | ||
| 280 | |||
| 281 | bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA | | ||
| 282 | EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA | | ||
| 283 | EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA | | ||
| 284 | EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | | ||
| 285 | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); | ||
| 286 | SSYNC(); | ||
| 287 | |||
| 288 | if (is_host_enabled(musb)) { | ||
| 289 | musb->board_set_vbus = bfin_set_vbus; | ||
| 290 | setup_timer(&musb_conn_timer, | ||
| 291 | musb_conn_timer_handler, (unsigned long) musb); | ||
| 292 | } | ||
| 293 | if (is_peripheral_enabled(musb)) | ||
| 294 | musb->xceiv.set_power = bfin_set_power; | ||
| 295 | |||
| 296 | musb->isr = blackfin_interrupt; | ||
| 297 | |||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | int musb_platform_suspend(struct musb *musb) | ||
| 302 | { | ||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | int musb_platform_resume(struct musb *musb) | ||
| 307 | { | ||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | |||
| 312 | int musb_platform_exit(struct musb *musb) | ||
| 313 | { | ||
| 314 | |||
| 315 | bfin_vbus_power(musb, 0 /*off*/, 1); | ||
| 316 | gpio_free(musb->config->gpio_vrsel); | ||
| 317 | musb_platform_suspend(musb); | ||
| 318 | |||
| 319 | return 0; | ||
| 320 | } | ||
diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h new file mode 100644 index 000000000000..a240c1e53d16 --- /dev/null +++ b/drivers/usb/musb/blackfin.h | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 by Analog Devices, Inc. | ||
| 3 | * | ||
| 4 | * The Inventra Controller Driver for Linux is free software; you | ||
| 5 | * can redistribute it and/or modify it under the terms of the GNU | ||
| 6 | * General Public License version 2 as published by the Free Software | ||
| 7 | * Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef __MUSB_BLACKFIN_H__ | ||
| 11 | #define __MUSB_BLACKFIN_H__ | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Blackfin specific definitions | ||
| 15 | */ | ||
| 16 | |||
| 17 | #undef DUMP_FIFO_DATA | ||
| 18 | #ifdef DUMP_FIFO_DATA | ||
| 19 | static void dump_fifo_data(u8 *buf, u16 len) | ||
| 20 | { | ||
| 21 | u8 *tmp = buf; | ||
| 22 | int i; | ||
| 23 | |||
| 24 | for (i = 0; i < len; i++) { | ||
| 25 | if (!(i % 16) && i) | ||
| 26 | pr_debug("\n"); | ||
| 27 | pr_debug("%02x ", *tmp++); | ||
| 28 | } | ||
| 29 | pr_debug("\n"); | ||
| 30 | } | ||
| 31 | #else | ||
| 32 | #define dump_fifo_data(buf, len) do {} while (0) | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef CONFIG_BF52x | ||
| 36 | |||
| 37 | #define USB_DMA_BASE USB_DMA_INTERRUPT | ||
| 38 | #define USB_DMAx_CTRL 0x04 | ||
| 39 | #define USB_DMAx_ADDR_LOW 0x08 | ||
| 40 | #define USB_DMAx_ADDR_HIGH 0x0C | ||
| 41 | #define USB_DMAx_COUNT_LOW 0x10 | ||
| 42 | #define USB_DMAx_COUNT_HIGH 0x14 | ||
| 43 | |||
| 44 | #define USB_DMA_REG(ep, reg) (USB_DMA_BASE + 0x20 * ep + reg) | ||
| 45 | #endif | ||
| 46 | |||
| 47 | /* Almost 1 second */ | ||
| 48 | #define TIMER_DELAY (1 * HZ) | ||
| 49 | |||
| 50 | static struct timer_list musb_conn_timer; | ||
| 51 | |||
| 52 | #endif /* __MUSB_BLACKFIN_H__ */ | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index dfb3bcbe00fc..0d566dc5ce06 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
| @@ -32,9 +32,9 @@ | |||
| 32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
| 33 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
| 34 | 34 | ||
| 35 | #include <asm/arch/hardware.h> | 35 | #include <mach/arch/hardware.h> |
| 36 | #include <asm/arch/memory.h> | 36 | #include <mach/arch/memory.h> |
| 37 | #include <asm/arch/gpio.h> | 37 | #include <mach/arch/gpio.h> |
| 38 | #include <asm/mach-types.h> | 38 | #include <asm/mach-types.h> |
| 39 | 39 | ||
| 40 | #include "musb_core.h" | 40 | #include "musb_core.h" |
| @@ -364,6 +364,18 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
| 364 | return IRQ_HANDLED; | 364 | return IRQ_HANDLED; |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | int musb_platform_set_mode(struct musb *musb, u8 mode) | ||
| 368 | { | ||
| 369 | /* EVM can't do this (right?) */ | ||
| 370 | return -EIO; | ||
| 371 | } | ||
| 372 | |||
| 373 | int musb_platform_set_mode(struct musb *musb, u8 mode) | ||
| 374 | { | ||
| 375 | /* EVM can't do this (right?) */ | ||
| 376 | return -EIO; | ||
| 377 | } | ||
| 378 | |||
| 367 | int __init musb_platform_init(struct musb *musb) | 379 | int __init musb_platform_init(struct musb *musb) |
| 368 | { | 380 | { |
| 369 | void __iomem *tibase = musb->ctrl_base; | 381 | void __iomem *tibase = musb->ctrl_base; |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 5280dba9b1fb..6c7faacfb535 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -148,7 +148,8 @@ static inline struct musb *dev_to_musb(struct device *dev) | |||
| 148 | 148 | ||
| 149 | /*-------------------------------------------------------------------------*/ | 149 | /*-------------------------------------------------------------------------*/ |
| 150 | 150 | ||
| 151 | #ifndef CONFIG_USB_TUSB6010 | 151 | #if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN) |
| 152 | |||
| 152 | /* | 153 | /* |
| 153 | * Load an endpoint's FIFO | 154 | * Load an endpoint's FIFO |
| 154 | */ | 155 | */ |
| @@ -1124,25 +1125,25 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, | |||
| 1124 | #endif | 1125 | #endif |
| 1125 | switch (cfg->style) { | 1126 | switch (cfg->style) { |
| 1126 | case FIFO_TX: | 1127 | case FIFO_TX: |
| 1127 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); | 1128 | musb_write_txfifosz(mbase, c_size); |
| 1128 | musb_writew(mbase, MUSB_TXFIFOADD, c_off); | 1129 | musb_write_txfifoadd(mbase, c_off); |
| 1129 | hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); | 1130 | hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); |
| 1130 | hw_ep->max_packet_sz_tx = maxpacket; | 1131 | hw_ep->max_packet_sz_tx = maxpacket; |
| 1131 | break; | 1132 | break; |
| 1132 | case FIFO_RX: | 1133 | case FIFO_RX: |
| 1133 | musb_writeb(mbase, MUSB_RXFIFOSZ, c_size); | 1134 | musb_write_rxfifosz(mbase, c_size); |
| 1134 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | 1135 | musb_write_rxfifoadd(mbase, c_off); |
| 1135 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); | 1136 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); |
| 1136 | hw_ep->max_packet_sz_rx = maxpacket; | 1137 | hw_ep->max_packet_sz_rx = maxpacket; |
| 1137 | break; | 1138 | break; |
| 1138 | case FIFO_RXTX: | 1139 | case FIFO_RXTX: |
| 1139 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); | 1140 | musb_write_txfifosz(mbase, c_size); |
| 1140 | musb_writew(mbase, MUSB_TXFIFOADD, c_off); | 1141 | musb_write_txfifoadd(mbase, c_off); |
| 1141 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); | 1142 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); |
| 1142 | hw_ep->max_packet_sz_rx = maxpacket; | 1143 | hw_ep->max_packet_sz_rx = maxpacket; |
| 1143 | 1144 | ||
| 1144 | musb_writeb(mbase, MUSB_RXFIFOSZ, c_size); | 1145 | musb_write_rxfifosz(mbase, c_size); |
| 1145 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | 1146 | musb_write_rxfifoadd(mbase, c_off); |
| 1146 | hw_ep->tx_double_buffered = hw_ep->rx_double_buffered; | 1147 | hw_ep->tx_double_buffered = hw_ep->rx_double_buffered; |
| 1147 | hw_ep->max_packet_sz_tx = maxpacket; | 1148 | hw_ep->max_packet_sz_tx = maxpacket; |
| 1148 | 1149 | ||
| @@ -1212,7 +1213,7 @@ static int __init ep_config_from_table(struct musb *musb) | |||
| 1212 | if (epn >= musb->config->num_eps) { | 1213 | if (epn >= musb->config->num_eps) { |
| 1213 | pr_debug("%s: invalid ep %d\n", | 1214 | pr_debug("%s: invalid ep %d\n", |
| 1214 | musb_driver_name, epn); | 1215 | musb_driver_name, epn); |
| 1215 | continue; | 1216 | return -EINVAL; |
| 1216 | } | 1217 | } |
| 1217 | offset = fifo_setup(musb, hw_ep + epn, cfg++, offset); | 1218 | offset = fifo_setup(musb, hw_ep + epn, cfg++, offset); |
| 1218 | if (offset < 0) { | 1219 | if (offset < 0) { |
| @@ -1246,9 +1247,10 @@ static int __init ep_config_from_table(struct musb *musb) | |||
| 1246 | */ | 1247 | */ |
| 1247 | static int __init ep_config_from_hw(struct musb *musb) | 1248 | static int __init ep_config_from_hw(struct musb *musb) |
| 1248 | { | 1249 | { |
| 1249 | u8 epnum = 0, reg; | 1250 | u8 epnum = 0; |
| 1250 | struct musb_hw_ep *hw_ep; | 1251 | struct musb_hw_ep *hw_ep; |
| 1251 | void *mbase = musb->mregs; | 1252 | void *mbase = musb->mregs; |
| 1253 | int ret = 0; | ||
| 1252 | 1254 | ||
| 1253 | DBG(2, "<== static silicon ep config\n"); | 1255 | DBG(2, "<== static silicon ep config\n"); |
| 1254 | 1256 | ||
| @@ -1258,26 +1260,9 @@ static int __init ep_config_from_hw(struct musb *musb) | |||
| 1258 | musb_ep_select(mbase, epnum); | 1260 | musb_ep_select(mbase, epnum); |
| 1259 | hw_ep = musb->endpoints + epnum; | 1261 | hw_ep = musb->endpoints + epnum; |
| 1260 | 1262 | ||
| 1261 | /* read from core using indexed model */ | 1263 | ret = musb_read_fifosize(musb, hw_ep, epnum); |
| 1262 | reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE); | 1264 | if (ret < 0) |
| 1263 | if (!reg) { | ||
| 1264 | /* 0's returned when no more endpoints */ | ||
| 1265 | break; | 1265 | break; |
| 1266 | } | ||
| 1267 | musb->nr_endpoints++; | ||
| 1268 | musb->epmask |= (1 << epnum); | ||
| 1269 | |||
| 1270 | hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f); | ||
| 1271 | |||
| 1272 | /* shared TX/RX FIFO? */ | ||
| 1273 | if ((reg & 0xf0) == 0xf0) { | ||
| 1274 | hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx; | ||
| 1275 | hw_ep->is_shared_fifo = true; | ||
| 1276 | continue; | ||
| 1277 | } else { | ||
| 1278 | hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4); | ||
| 1279 | hw_ep->is_shared_fifo = false; | ||
| 1280 | } | ||
| 1281 | 1266 | ||
| 1282 | /* FIXME set up hw_ep->{rx,tx}_double_buffered */ | 1267 | /* FIXME set up hw_ep->{rx,tx}_double_buffered */ |
| 1283 | 1268 | ||
| @@ -1326,7 +1311,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
| 1326 | 1311 | ||
| 1327 | /* log core options (read using indexed model) */ | 1312 | /* log core options (read using indexed model) */ |
| 1328 | musb_ep_select(mbase, 0); | 1313 | musb_ep_select(mbase, 0); |
| 1329 | reg = musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); | 1314 | reg = musb_read_configdata(mbase); |
| 1330 | 1315 | ||
| 1331 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); | 1316 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); |
| 1332 | if (reg & MUSB_CONFIGDATA_DYNFIFO) | 1317 | if (reg & MUSB_CONFIGDATA_DYNFIFO) |
| @@ -1391,7 +1376,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
| 1391 | } | 1376 | } |
| 1392 | 1377 | ||
| 1393 | /* log release info */ | 1378 | /* log release info */ |
| 1394 | hwvers = musb_readw(mbase, MUSB_HWVERS); | 1379 | hwvers = musb_read_hwvers(mbase); |
| 1395 | rev_major = (hwvers >> 10) & 0x1f; | 1380 | rev_major = (hwvers >> 10) & 0x1f; |
| 1396 | rev_minor = hwvers & 0x3ff; | 1381 | rev_minor = hwvers & 0x3ff; |
| 1397 | snprintf(aRevision, 32, "%d.%d%s", rev_major, | 1382 | snprintf(aRevision, 32, "%d.%d%s", rev_major, |
| @@ -1400,8 +1385,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
| 1400 | musb_driver_name, type, aRevision, aDate); | 1385 | musb_driver_name, type, aRevision, aDate); |
| 1401 | 1386 | ||
| 1402 | /* configure ep0 */ | 1387 | /* configure ep0 */ |
| 1403 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | 1388 | musb_configure_ep0(musb); |
| 1404 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | ||
| 1405 | 1389 | ||
| 1406 | /* discover endpoint configuration */ | 1390 | /* discover endpoint configuration */ |
| 1407 | musb->nr_endpoints = 1; | 1391 | musb->nr_endpoints = 1; |
| @@ -1445,7 +1429,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
| 1445 | 1429 | ||
| 1446 | hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase; | 1430 | hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase; |
| 1447 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1431 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
| 1448 | hw_ep->target_regs = MUSB_BUSCTL_OFFSET(i, 0) + mbase; | 1432 | hw_ep->target_regs = musb_read_target_reg_base(i, mbase); |
| 1449 | hw_ep->rx_reinit = 1; | 1433 | hw_ep->rx_reinit = 1; |
| 1450 | hw_ep->tx_reinit = 1; | 1434 | hw_ep->tx_reinit = 1; |
| 1451 | #endif | 1435 | #endif |
| @@ -1671,17 +1655,20 @@ musb_mode_store(struct device *dev, struct device_attribute *attr, | |||
| 1671 | { | 1655 | { |
| 1672 | struct musb *musb = dev_to_musb(dev); | 1656 | struct musb *musb = dev_to_musb(dev); |
| 1673 | unsigned long flags; | 1657 | unsigned long flags; |
| 1658 | int status; | ||
| 1674 | 1659 | ||
| 1675 | spin_lock_irqsave(&musb->lock, flags); | 1660 | spin_lock_irqsave(&musb->lock, flags); |
| 1676 | if (!strncmp(buf, "host", 4)) | 1661 | if (sysfs_streq(buf, "host")) |
| 1677 | musb_platform_set_mode(musb, MUSB_HOST); | 1662 | status = musb_platform_set_mode(musb, MUSB_HOST); |
| 1678 | if (!strncmp(buf, "peripheral", 10)) | 1663 | else if (sysfs_streq(buf, "peripheral")) |
| 1679 | musb_platform_set_mode(musb, MUSB_PERIPHERAL); | 1664 | status = musb_platform_set_mode(musb, MUSB_PERIPHERAL); |
| 1680 | if (!strncmp(buf, "otg", 3)) | 1665 | else if (sysfs_streq(buf, "otg")) |
| 1681 | musb_platform_set_mode(musb, MUSB_OTG); | 1666 | status = musb_platform_set_mode(musb, MUSB_OTG); |
| 1667 | else | ||
| 1668 | status = -EINVAL; | ||
| 1682 | spin_unlock_irqrestore(&musb->lock, flags); | 1669 | spin_unlock_irqrestore(&musb->lock, flags); |
| 1683 | 1670 | ||
| 1684 | return n; | 1671 | return (status == 0) ? n : status; |
| 1685 | } | 1672 | } |
| 1686 | static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store); | 1673 | static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store); |
| 1687 | 1674 | ||
| @@ -1781,7 +1768,7 @@ allocate_instance(struct device *dev, | |||
| 1781 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1768 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
| 1782 | struct usb_hcd *hcd; | 1769 | struct usb_hcd *hcd; |
| 1783 | 1770 | ||
| 1784 | hcd = usb_create_hcd(&musb_hc_driver, dev, dev->bus_id); | 1771 | hcd = usb_create_hcd(&musb_hc_driver, dev, dev_name(dev)); |
| 1785 | if (!hcd) | 1772 | if (!hcd) |
| 1786 | return NULL; | 1773 | return NULL; |
| 1787 | /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */ | 1774 | /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */ |
| @@ -1810,7 +1797,6 @@ allocate_instance(struct device *dev, | |||
| 1810 | for (epnum = 0, ep = musb->endpoints; | 1797 | for (epnum = 0, ep = musb->endpoints; |
| 1811 | epnum < musb->config->num_eps; | 1798 | epnum < musb->config->num_eps; |
| 1812 | epnum++, ep++) { | 1799 | epnum++, ep++) { |
| 1813 | |||
| 1814 | ep->musb = musb; | 1800 | ep->musb = musb; |
| 1815 | ep->epnum = epnum; | 1801 | ep->epnum = epnum; |
| 1816 | } | 1802 | } |
| @@ -1838,7 +1824,7 @@ static void musb_free(struct musb *musb) | |||
| 1838 | musb_gadget_cleanup(musb); | 1824 | musb_gadget_cleanup(musb); |
| 1839 | #endif | 1825 | #endif |
| 1840 | 1826 | ||
| 1841 | if (musb->nIrq >= 0) { | 1827 | if (musb->nIrq >= 0 && musb->irq_wake) { |
| 1842 | disable_irq_wake(musb->nIrq); | 1828 | disable_irq_wake(musb->nIrq); |
| 1843 | free_irq(musb->nIrq, musb); | 1829 | free_irq(musb->nIrq, musb); |
| 1844 | } | 1830 | } |
| @@ -1984,15 +1970,19 @@ bad_config: | |||
| 1984 | INIT_WORK(&musb->irq_work, musb_irq_work); | 1970 | INIT_WORK(&musb->irq_work, musb_irq_work); |
| 1985 | 1971 | ||
| 1986 | /* attach to the IRQ */ | 1972 | /* attach to the IRQ */ |
| 1987 | if (request_irq(nIrq, musb->isr, 0, dev->bus_id, musb)) { | 1973 | if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) { |
| 1988 | dev_err(dev, "request_irq %d failed!\n", nIrq); | 1974 | dev_err(dev, "request_irq %d failed!\n", nIrq); |
| 1989 | status = -ENODEV; | 1975 | status = -ENODEV; |
| 1990 | goto fail2; | 1976 | goto fail2; |
| 1991 | } | 1977 | } |
| 1992 | musb->nIrq = nIrq; | 1978 | musb->nIrq = nIrq; |
| 1993 | /* FIXME this handles wakeup irqs wrong */ | 1979 | /* FIXME this handles wakeup irqs wrong */ |
| 1994 | if (enable_irq_wake(nIrq) == 0) | 1980 | if (enable_irq_wake(nIrq) == 0) { |
| 1981 | musb->irq_wake = 1; | ||
| 1995 | device_init_wakeup(dev, 1); | 1982 | device_init_wakeup(dev, 1); |
| 1983 | } else { | ||
| 1984 | musb->irq_wake = 0; | ||
| 1985 | } | ||
| 1996 | 1986 | ||
| 1997 | pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n", | 1987 | pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n", |
| 1998 | musb_driver_name, | 1988 | musb_driver_name, |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 82227251931b..630946a2d9fc 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
| @@ -191,7 +191,7 @@ enum musb_g_ep0_state { | |||
| 191 | */ | 191 | */ |
| 192 | 192 | ||
| 193 | #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \ | 193 | #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \ |
| 194 | || defined(CONFIG_ARCH_OMAP3430) | 194 | || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_BLACKFIN) |
| 195 | /* REVISIT indexed access seemed to | 195 | /* REVISIT indexed access seemed to |
| 196 | * misbehave (on DaVinci) for at least peripheral IN ... | 196 | * misbehave (on DaVinci) for at least peripheral IN ... |
| 197 | */ | 197 | */ |
| @@ -359,6 +359,7 @@ struct musb { | |||
| 359 | struct otg_transceiver xceiv; | 359 | struct otg_transceiver xceiv; |
| 360 | 360 | ||
| 361 | int nIrq; | 361 | int nIrq; |
| 362 | unsigned irq_wake:1; | ||
| 362 | 363 | ||
| 363 | struct musb_hw_ep endpoints[MUSB_C_NUM_EPS]; | 364 | struct musb_hw_ep endpoints[MUSB_C_NUM_EPS]; |
| 364 | #define control_ep endpoints | 365 | #define control_ep endpoints |
| @@ -447,6 +448,70 @@ static inline struct musb *gadget_to_musb(struct usb_gadget *g) | |||
| 447 | } | 448 | } |
| 448 | #endif | 449 | #endif |
| 449 | 450 | ||
| 451 | #ifdef CONFIG_BLACKFIN | ||
| 452 | static inline int musb_read_fifosize(struct musb *musb, | ||
| 453 | struct musb_hw_ep *hw_ep, u8 epnum) | ||
| 454 | { | ||
| 455 | musb->nr_endpoints++; | ||
| 456 | musb->epmask |= (1 << epnum); | ||
| 457 | |||
| 458 | if (epnum < 5) { | ||
| 459 | hw_ep->max_packet_sz_tx = 128; | ||
| 460 | hw_ep->max_packet_sz_rx = 128; | ||
| 461 | } else { | ||
| 462 | hw_ep->max_packet_sz_tx = 1024; | ||
| 463 | hw_ep->max_packet_sz_rx = 1024; | ||
| 464 | } | ||
| 465 | hw_ep->is_shared_fifo = false; | ||
| 466 | |||
| 467 | return 0; | ||
| 468 | } | ||
| 469 | |||
| 470 | static inline void musb_configure_ep0(struct musb *musb) | ||
| 471 | { | ||
| 472 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | ||
| 473 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | ||
| 474 | musb->endpoints[0].is_shared_fifo = true; | ||
| 475 | } | ||
| 476 | |||
| 477 | #else | ||
| 478 | |||
| 479 | static inline int musb_read_fifosize(struct musb *musb, | ||
| 480 | struct musb_hw_ep *hw_ep, u8 epnum) | ||
| 481 | { | ||
| 482 | u8 reg = 0; | ||
| 483 | |||
| 484 | /* read from core using indexed model */ | ||
| 485 | reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE); | ||
| 486 | /* 0's returned when no more endpoints */ | ||
| 487 | if (!reg) | ||
| 488 | return -ENODEV; | ||
| 489 | |||
| 490 | musb->nr_endpoints++; | ||
| 491 | musb->epmask |= (1 << epnum); | ||
| 492 | |||
| 493 | hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f); | ||
| 494 | |||
| 495 | /* shared TX/RX FIFO? */ | ||
| 496 | if ((reg & 0xf0) == 0xf0) { | ||
| 497 | hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx; | ||
| 498 | hw_ep->is_shared_fifo = true; | ||
| 499 | return 0; | ||
| 500 | } else { | ||
| 501 | hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4); | ||
| 502 | hw_ep->is_shared_fifo = false; | ||
| 503 | } | ||
| 504 | |||
| 505 | return 0; | ||
| 506 | } | ||
| 507 | |||
| 508 | static inline void musb_configure_ep0(struct musb *musb) | ||
| 509 | { | ||
| 510 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | ||
| 511 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | ||
| 512 | } | ||
| 513 | #endif /* CONFIG_BLACKFIN */ | ||
| 514 | |||
| 450 | 515 | ||
| 451 | /***************************** Glue it together *****************************/ | 516 | /***************************** Glue it together *****************************/ |
| 452 | 517 | ||
| @@ -467,16 +532,16 @@ extern void musb_platform_disable(struct musb *musb); | |||
| 467 | 532 | ||
| 468 | extern void musb_hnp_stop(struct musb *musb); | 533 | extern void musb_hnp_stop(struct musb *musb); |
| 469 | 534 | ||
| 470 | extern void musb_platform_set_mode(struct musb *musb, u8 musb_mode); | 535 | extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); |
| 471 | 536 | ||
| 472 | #if defined(CONFIG_USB_TUSB6010) || \ | 537 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ |
| 473 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) | 538 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) |
| 474 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); | 539 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); |
| 475 | #else | 540 | #else |
| 476 | #define musb_platform_try_idle(x, y) do {} while (0) | 541 | #define musb_platform_try_idle(x, y) do {} while (0) |
| 477 | #endif | 542 | #endif |
| 478 | 543 | ||
| 479 | #ifdef CONFIG_USB_TUSB6010 | 544 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) |
| 480 | extern int musb_platform_get_vbus_status(struct musb *musb); | 545 | extern int musb_platform_get_vbus_status(struct musb *musb); |
| 481 | #else | 546 | #else |
| 482 | #define musb_platform_get_vbus_status(x) 0 | 547 | #define musb_platform_get_vbus_status(x) 0 |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d6a802c224fa..6197daeab8f9 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -1633,7 +1633,7 @@ int __init musb_gadget_setup(struct musb *musb) | |||
| 1633 | musb->g.speed = USB_SPEED_UNKNOWN; | 1633 | musb->g.speed = USB_SPEED_UNKNOWN; |
| 1634 | 1634 | ||
| 1635 | /* this "gadget" abstracts/virtualizes the controller */ | 1635 | /* this "gadget" abstracts/virtualizes the controller */ |
| 1636 | strcpy(musb->g.dev.bus_id, "gadget"); | 1636 | dev_set_name(&musb->g.dev, "gadget"); |
| 1637 | musb->g.dev.parent = musb->controller; | 1637 | musb->g.dev.parent = musb->controller; |
| 1638 | musb->g.dev.dma_mask = musb->controller->dma_mask; | 1638 | musb->g.dev.dma_mask = musb->controller->dma_mask; |
| 1639 | musb->g.dev.release = musb_gadget_release; | 1639 | musb->g.dev.release = musb_gadget_release; |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index cc64462d4c4e..99fa61234876 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -112,18 +112,21 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) | |||
| 112 | { | 112 | { |
| 113 | void __iomem *epio = ep->regs; | 113 | void __iomem *epio = ep->regs; |
| 114 | u16 csr; | 114 | u16 csr; |
| 115 | u16 lastcsr = 0; | ||
| 115 | int retries = 1000; | 116 | int retries = 1000; |
| 116 | 117 | ||
| 117 | csr = musb_readw(epio, MUSB_TXCSR); | 118 | csr = musb_readw(epio, MUSB_TXCSR); |
| 118 | while (csr & MUSB_TXCSR_FIFONOTEMPTY) { | 119 | while (csr & MUSB_TXCSR_FIFONOTEMPTY) { |
| 119 | DBG(5, "Host TX FIFONOTEMPTY csr: %02x\n", csr); | 120 | if (csr != lastcsr) |
| 121 | DBG(3, "Host TX FIFONOTEMPTY csr: %02x\n", csr); | ||
| 122 | lastcsr = csr; | ||
| 120 | csr |= MUSB_TXCSR_FLUSHFIFO; | 123 | csr |= MUSB_TXCSR_FLUSHFIFO; |
| 121 | musb_writew(epio, MUSB_TXCSR, csr); | 124 | musb_writew(epio, MUSB_TXCSR, csr); |
| 122 | csr = musb_readw(epio, MUSB_TXCSR); | 125 | csr = musb_readw(epio, MUSB_TXCSR); |
| 123 | if (retries-- < 1) { | 126 | if (WARN(retries-- < 1, |
| 124 | ERR("Could not flush host TX fifo: csr: %04x\n", csr); | 127 | "Could not flush host TX%d fifo: csr: %04x\n", |
| 128 | ep->epnum, csr)) | ||
| 125 | return; | 129 | return; |
| 126 | } | ||
| 127 | mdelay(1); | 130 | mdelay(1); |
| 128 | } | 131 | } |
| 129 | } | 132 | } |
| @@ -268,7 +271,7 @@ __musb_giveback(struct musb *musb, struct urb *urb, int status) | |||
| 268 | __releases(musb->lock) | 271 | __releases(musb->lock) |
| 269 | __acquires(musb->lock) | 272 | __acquires(musb->lock) |
| 270 | { | 273 | { |
| 271 | DBG(({ int level; switch (urb->status) { | 274 | DBG(({ int level; switch (status) { |
| 272 | case 0: | 275 | case 0: |
| 273 | level = 4; | 276 | level = 4; |
| 274 | break; | 277 | break; |
| @@ -283,8 +286,8 @@ __acquires(musb->lock) | |||
| 283 | level = 2; | 286 | level = 2; |
| 284 | break; | 287 | break; |
| 285 | }; level; }), | 288 | }; level; }), |
| 286 | "complete %p (%d), dev%d ep%d%s, %d/%d\n", | 289 | "complete %p %pF (%d), dev%d ep%d%s, %d/%d\n", |
| 287 | urb, urb->status, | 290 | urb, urb->complete, status, |
| 288 | usb_pipedevice(urb->pipe), | 291 | usb_pipedevice(urb->pipe), |
| 289 | usb_pipeendpoint(urb->pipe), | 292 | usb_pipeendpoint(urb->pipe), |
| 290 | usb_pipein(urb->pipe) ? "in" : "out", | 293 | 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) | |||
| 593 | 596 | ||
| 594 | /* target addr and (for multipoint) hub addr/port */ | 597 | /* target addr and (for multipoint) hub addr/port */ |
| 595 | if (musb->is_multipoint) { | 598 | if (musb->is_multipoint) { |
| 596 | musb_writeb(ep->target_regs, MUSB_RXFUNCADDR, | 599 | musb_write_rxfunaddr(ep->target_regs, qh->addr_reg); |
| 597 | qh->addr_reg); | 600 | musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg); |
| 598 | musb_writeb(ep->target_regs, MUSB_RXHUBADDR, | 601 | musb_write_rxhubport(ep->target_regs, qh->h_port_reg); |
| 599 | qh->h_addr_reg); | 602 | |
| 600 | musb_writeb(ep->target_regs, MUSB_RXHUBPORT, | ||
| 601 | qh->h_port_reg); | ||
| 602 | } else | 603 | } else |
| 603 | musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg); | 604 | musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg); |
| 604 | 605 | ||
| @@ -712,15 +713,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
| 712 | 713 | ||
| 713 | /* target addr and (for multipoint) hub addr/port */ | 714 | /* target addr and (for multipoint) hub addr/port */ |
| 714 | if (musb->is_multipoint) { | 715 | if (musb->is_multipoint) { |
| 715 | musb_writeb(mbase, | 716 | musb_write_txfunaddr(mbase, epnum, qh->addr_reg); |
| 716 | MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR), | 717 | musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg); |
| 717 | qh->addr_reg); | 718 | musb_write_txhubport(mbase, epnum, qh->h_port_reg); |
| 718 | musb_writeb(mbase, | ||
| 719 | MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR), | ||
| 720 | qh->h_addr_reg); | ||
| 721 | musb_writeb(mbase, | ||
| 722 | MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT), | ||
| 723 | qh->h_port_reg); | ||
| 724 | /* FIXME if !epnum, do the same for RX ... */ | 719 | /* FIXME if !epnum, do the same for RX ... */ |
| 725 | } else | 720 | } else |
| 726 | musb_writeb(mbase, MUSB_FADDR, qh->addr_reg); | 721 | musb_writeb(mbase, MUSB_FADDR, qh->addr_reg); |
| @@ -988,8 +983,10 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
| 988 | if (fifo_count) { | 983 | if (fifo_count) { |
| 989 | fifo_dest = (u8 *) (urb->transfer_buffer | 984 | fifo_dest = (u8 *) (urb->transfer_buffer |
| 990 | + urb->actual_length); | 985 | + urb->actual_length); |
| 991 | DBG(3, "Sending %d bytes to %p\n", | 986 | DBG(3, "Sending %d byte%s to ep0 fifo %p\n", |
| 992 | fifo_count, fifo_dest); | 987 | fifo_count, |
| 988 | (fifo_count == 1) ? "" : "s", | ||
| 989 | fifo_dest); | ||
| 993 | musb_write_fifo(hw_ep, fifo_count, fifo_dest); | 990 | musb_write_fifo(hw_ep, fifo_count, fifo_dest); |
| 994 | 991 | ||
| 995 | urb->actual_length += fifo_count; | 992 | urb->actual_length += fifo_count; |
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 223f0a514094..b06e9ef00cfc 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ | 40 | #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ |
| 41 | && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ | 41 | && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ |
| 42 | && !defined(CONFIG_PPC64) | 42 | && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) |
| 43 | static inline void readsl(const void __iomem *addr, void *buf, int len) | 43 | static inline void readsl(const void __iomem *addr, void *buf, int len) |
| 44 | { insl((unsigned long)addr, buf, len); } | 44 | { insl((unsigned long)addr, buf, len); } |
| 45 | static inline void readsw(const void __iomem *addr, void *buf, int len) | 45 | 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) | |||
| 56 | 56 | ||
| 57 | #endif | 57 | #endif |
| 58 | 58 | ||
| 59 | #ifndef CONFIG_BLACKFIN | ||
| 60 | |||
| 59 | /* NOTE: these offsets are all in bytes */ | 61 | /* NOTE: these offsets are all in bytes */ |
| 60 | 62 | ||
| 61 | static inline u16 musb_readw(const void __iomem *addr, unsigned offset) | 63 | 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) | |||
| 114 | 116 | ||
| 115 | #endif /* CONFIG_USB_TUSB6010 */ | 117 | #endif /* CONFIG_USB_TUSB6010 */ |
| 116 | 118 | ||
| 119 | #else | ||
| 120 | |||
| 121 | static inline u8 musb_readb(const void __iomem *addr, unsigned offset) | ||
| 122 | { return (u8) (bfin_read16(addr + offset)); } | ||
| 123 | |||
| 124 | static inline u16 musb_readw(const void __iomem *addr, unsigned offset) | ||
| 125 | { return bfin_read16(addr + offset); } | ||
| 126 | |||
| 127 | static inline u32 musb_readl(const void __iomem *addr, unsigned offset) | ||
| 128 | { return (u32) (bfin_read16(addr + offset)); } | ||
| 129 | |||
| 130 | static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) | ||
| 131 | { bfin_write16(addr + offset, (u16) data); } | ||
| 132 | |||
| 133 | static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data) | ||
| 134 | { bfin_write16(addr + offset, data); } | ||
| 135 | |||
| 136 | static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) | ||
| 137 | { bfin_write16(addr + offset, (u16) data); } | ||
| 138 | |||
| 139 | #endif /* CONFIG_BLACKFIN */ | ||
| 140 | |||
| 117 | #endif | 141 | #endif |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 9c228661aa5a..de3b2f18db44 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
| @@ -38,97 +38,6 @@ | |||
| 38 | #define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */ | 38 | #define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */ |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * Common USB registers | ||
| 42 | */ | ||
| 43 | |||
| 44 | #define MUSB_FADDR 0x00 /* 8-bit */ | ||
| 45 | #define MUSB_POWER 0x01 /* 8-bit */ | ||
| 46 | |||
| 47 | #define MUSB_INTRTX 0x02 /* 16-bit */ | ||
| 48 | #define MUSB_INTRRX 0x04 | ||
| 49 | #define MUSB_INTRTXE 0x06 | ||
| 50 | #define MUSB_INTRRXE 0x08 | ||
| 51 | #define MUSB_INTRUSB 0x0A /* 8 bit */ | ||
| 52 | #define MUSB_INTRUSBE 0x0B /* 8 bit */ | ||
| 53 | #define MUSB_FRAME 0x0C | ||
| 54 | #define MUSB_INDEX 0x0E /* 8 bit */ | ||
| 55 | #define MUSB_TESTMODE 0x0F /* 8 bit */ | ||
| 56 | |||
| 57 | /* Get offset for a given FIFO from musb->mregs */ | ||
| 58 | #ifdef CONFIG_USB_TUSB6010 | ||
| 59 | #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) | ||
| 60 | #else | ||
| 61 | #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) | ||
| 62 | #endif | ||
| 63 | |||
| 64 | /* | ||
| 65 | * Additional Control Registers | ||
| 66 | */ | ||
| 67 | |||
| 68 | #define MUSB_DEVCTL 0x60 /* 8 bit */ | ||
| 69 | |||
| 70 | /* These are always controlled through the INDEX register */ | ||
| 71 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ | ||
| 72 | #define MUSB_RXFIFOSZ 0x63 /* 8-bit (see masks) */ | ||
| 73 | #define MUSB_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ | ||
| 74 | #define MUSB_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ | ||
| 75 | |||
| 76 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ | ||
| 77 | #define MUSB_HWVERS 0x6C /* 8 bit */ | ||
| 78 | |||
| 79 | #define MUSB_EPINFO 0x78 /* 8 bit */ | ||
| 80 | #define MUSB_RAMINFO 0x79 /* 8 bit */ | ||
| 81 | #define MUSB_LINKINFO 0x7a /* 8 bit */ | ||
| 82 | #define MUSB_VPLEN 0x7b /* 8 bit */ | ||
| 83 | #define MUSB_HS_EOF1 0x7c /* 8 bit */ | ||
| 84 | #define MUSB_FS_EOF1 0x7d /* 8 bit */ | ||
| 85 | #define MUSB_LS_EOF1 0x7e /* 8 bit */ | ||
| 86 | |||
| 87 | /* Offsets to endpoint registers */ | ||
| 88 | #define MUSB_TXMAXP 0x00 | ||
| 89 | #define MUSB_TXCSR 0x02 | ||
| 90 | #define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ | ||
| 91 | #define MUSB_RXMAXP 0x04 | ||
| 92 | #define MUSB_RXCSR 0x06 | ||
| 93 | #define MUSB_RXCOUNT 0x08 | ||
| 94 | #define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ | ||
| 95 | #define MUSB_TXTYPE 0x0A | ||
| 96 | #define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ | ||
| 97 | #define MUSB_TXINTERVAL 0x0B | ||
| 98 | #define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ | ||
| 99 | #define MUSB_RXTYPE 0x0C | ||
| 100 | #define MUSB_RXINTERVAL 0x0D | ||
| 101 | #define MUSB_FIFOSIZE 0x0F | ||
| 102 | #define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */ | ||
| 103 | |||
| 104 | /* Offsets to endpoint registers in indexed model (using INDEX register) */ | ||
| 105 | #define MUSB_INDEXED_OFFSET(_epnum, _offset) \ | ||
| 106 | (0x10 + (_offset)) | ||
| 107 | |||
| 108 | /* Offsets to endpoint registers in flat models */ | ||
| 109 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | ||
| 110 | (0x100 + (0x10*(_epnum)) + (_offset)) | ||
| 111 | |||
| 112 | #ifdef CONFIG_USB_TUSB6010 | ||
| 113 | /* TUSB6010 EP0 configuration register is special */ | ||
| 114 | #define MUSB_TUSB_OFFSET(_epnum, _offset) \ | ||
| 115 | (0x10 + _offset) | ||
| 116 | #include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */ | ||
| 117 | #endif | ||
| 118 | |||
| 119 | /* "bus control"/target registers, for host side multipoint (external hubs) */ | ||
| 120 | #define MUSB_TXFUNCADDR 0x00 | ||
| 121 | #define MUSB_TXHUBADDR 0x02 | ||
| 122 | #define MUSB_TXHUBPORT 0x03 | ||
| 123 | |||
| 124 | #define MUSB_RXFUNCADDR 0x04 | ||
| 125 | #define MUSB_RXHUBADDR 0x06 | ||
| 126 | #define MUSB_RXHUBPORT 0x07 | ||
| 127 | |||
| 128 | #define MUSB_BUSCTL_OFFSET(_epnum, _offset) \ | ||
| 129 | (0x80 + (8*(_epnum)) + (_offset)) | ||
| 130 | |||
| 131 | /* | ||
| 132 | * MUSB Register bits | 41 | * MUSB Register bits |
| 133 | */ | 42 | */ |
| 134 | 43 | ||
| @@ -228,7 +137,6 @@ | |||
| 228 | 137 | ||
| 229 | /* TXCSR in Peripheral and Host mode */ | 138 | /* TXCSR in Peripheral and Host mode */ |
| 230 | #define MUSB_TXCSR_AUTOSET 0x8000 | 139 | #define MUSB_TXCSR_AUTOSET 0x8000 |
| 231 | #define MUSB_TXCSR_MODE 0x2000 | ||
| 232 | #define MUSB_TXCSR_DMAENAB 0x1000 | 140 | #define MUSB_TXCSR_DMAENAB 0x1000 |
| 233 | #define MUSB_TXCSR_FRCDATATOG 0x0800 | 141 | #define MUSB_TXCSR_FRCDATATOG 0x0800 |
| 234 | #define MUSB_TXCSR_DMAMODE 0x0400 | 142 | #define MUSB_TXCSR_DMAMODE 0x0400 |
| @@ -297,4 +205,309 @@ | |||
| 297 | /* HUBADDR */ | 205 | /* HUBADDR */ |
| 298 | #define MUSB_HUBADDR_MULTI_TT 0x80 | 206 | #define MUSB_HUBADDR_MULTI_TT 0x80 |
| 299 | 207 | ||
| 208 | |||
| 209 | #ifndef CONFIG_BLACKFIN | ||
| 210 | |||
| 211 | /* | ||
| 212 | * Common USB registers | ||
| 213 | */ | ||
| 214 | |||
| 215 | #define MUSB_FADDR 0x00 /* 8-bit */ | ||
| 216 | #define MUSB_POWER 0x01 /* 8-bit */ | ||
| 217 | |||
| 218 | #define MUSB_INTRTX 0x02 /* 16-bit */ | ||
| 219 | #define MUSB_INTRRX 0x04 | ||
| 220 | #define MUSB_INTRTXE 0x06 | ||
| 221 | #define MUSB_INTRRXE 0x08 | ||
| 222 | #define MUSB_INTRUSB 0x0A /* 8 bit */ | ||
| 223 | #define MUSB_INTRUSBE 0x0B /* 8 bit */ | ||
| 224 | #define MUSB_FRAME 0x0C | ||
| 225 | #define MUSB_INDEX 0x0E /* 8 bit */ | ||
| 226 | #define MUSB_TESTMODE 0x0F /* 8 bit */ | ||
| 227 | |||
| 228 | /* Get offset for a given FIFO from musb->mregs */ | ||
| 229 | #ifdef CONFIG_USB_TUSB6010 | ||
| 230 | #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) | ||
| 231 | #else | ||
| 232 | #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) | ||
| 233 | #endif | ||
| 234 | |||
| 235 | /* | ||
| 236 | * Additional Control Registers | ||
| 237 | */ | ||
| 238 | |||
| 239 | #define MUSB_DEVCTL 0x60 /* 8 bit */ | ||
| 240 | |||
| 241 | /* These are always controlled through the INDEX register */ | ||
| 242 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ | ||
| 243 | #define MUSB_RXFIFOSZ 0x63 /* 8-bit (see masks) */ | ||
| 244 | #define MUSB_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ | ||
| 245 | #define MUSB_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ | ||
| 246 | |||
| 247 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ | ||
| 248 | #define MUSB_HWVERS 0x6C /* 8 bit */ | ||
| 249 | |||
| 250 | #define MUSB_EPINFO 0x78 /* 8 bit */ | ||
| 251 | #define MUSB_RAMINFO 0x79 /* 8 bit */ | ||
| 252 | #define MUSB_LINKINFO 0x7a /* 8 bit */ | ||
| 253 | #define MUSB_VPLEN 0x7b /* 8 bit */ | ||
| 254 | #define MUSB_HS_EOF1 0x7c /* 8 bit */ | ||
| 255 | #define MUSB_FS_EOF1 0x7d /* 8 bit */ | ||
| 256 | #define MUSB_LS_EOF1 0x7e /* 8 bit */ | ||
| 257 | |||
| 258 | /* Offsets to endpoint registers */ | ||
| 259 | #define MUSB_TXMAXP 0x00 | ||
| 260 | #define MUSB_TXCSR 0x02 | ||
| 261 | #define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ | ||
| 262 | #define MUSB_RXMAXP 0x04 | ||
| 263 | #define MUSB_RXCSR 0x06 | ||
| 264 | #define MUSB_RXCOUNT 0x08 | ||
| 265 | #define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ | ||
| 266 | #define MUSB_TXTYPE 0x0A | ||
| 267 | #define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ | ||
| 268 | #define MUSB_TXINTERVAL 0x0B | ||
| 269 | #define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ | ||
| 270 | #define MUSB_RXTYPE 0x0C | ||
| 271 | #define MUSB_RXINTERVAL 0x0D | ||
| 272 | #define MUSB_FIFOSIZE 0x0F | ||
| 273 | #define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */ | ||
| 274 | |||
| 275 | /* Offsets to endpoint registers in indexed model (using INDEX register) */ | ||
| 276 | #define MUSB_INDEXED_OFFSET(_epnum, _offset) \ | ||
| 277 | (0x10 + (_offset)) | ||
| 278 | |||
| 279 | /* Offsets to endpoint registers in flat models */ | ||
| 280 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | ||
| 281 | (0x100 + (0x10*(_epnum)) + (_offset)) | ||
| 282 | |||
| 283 | #ifdef CONFIG_USB_TUSB6010 | ||
| 284 | /* TUSB6010 EP0 configuration register is special */ | ||
| 285 | #define MUSB_TUSB_OFFSET(_epnum, _offset) \ | ||
| 286 | (0x10 + _offset) | ||
| 287 | #include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */ | ||
| 288 | #endif | ||
| 289 | |||
| 290 | #define MUSB_TXCSR_MODE 0x2000 | ||
| 291 | |||
| 292 | /* "bus control"/target registers, for host side multipoint (external hubs) */ | ||
| 293 | #define MUSB_TXFUNCADDR 0x00 | ||
| 294 | #define MUSB_TXHUBADDR 0x02 | ||
| 295 | #define MUSB_TXHUBPORT 0x03 | ||
| 296 | |||
| 297 | #define MUSB_RXFUNCADDR 0x04 | ||
| 298 | #define MUSB_RXHUBADDR 0x06 | ||
| 299 | #define MUSB_RXHUBPORT 0x07 | ||
| 300 | |||
| 301 | #define MUSB_BUSCTL_OFFSET(_epnum, _offset) \ | ||
| 302 | (0x80 + (8*(_epnum)) + (_offset)) | ||
| 303 | |||
| 304 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) | ||
| 305 | { | ||
| 306 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); | ||
| 307 | } | ||
| 308 | |||
| 309 | static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off) | ||
| 310 | { | ||
| 311 | musb_writew(mbase, MUSB_TXFIFOADD, c_off); | ||
| 312 | } | ||
| 313 | |||
| 314 | static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size) | ||
| 315 | { | ||
| 316 | musb_writeb(mbase, MUSB_RXFIFOSZ, c_size); | ||
| 317 | } | ||
| 318 | |||
| 319 | static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | ||
| 320 | { | ||
| 321 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | ||
| 322 | } | ||
| 323 | |||
| 324 | static inline u8 musb_read_configdata(void __iomem *mbase) | ||
| 325 | { | ||
| 326 | return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); | ||
| 327 | } | ||
| 328 | |||
| 329 | static inline u16 musb_read_hwvers(void __iomem *mbase) | ||
| 330 | { | ||
| 331 | return musb_readw(mbase, MUSB_HWVERS); | ||
| 332 | } | ||
| 333 | |||
| 334 | static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) | ||
| 335 | { | ||
| 336 | return (MUSB_BUSCTL_OFFSET(i, 0) + mbase); | ||
| 337 | } | ||
| 338 | |||
| 339 | static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, | ||
| 340 | u8 qh_addr_reg) | ||
| 341 | { | ||
| 342 | musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg); | ||
| 343 | } | ||
| 344 | |||
| 345 | static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, | ||
| 346 | u8 qh_h_addr_reg) | ||
| 347 | { | ||
| 348 | musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg); | ||
| 349 | } | ||
| 350 | |||
| 351 | static inline void musb_write_rxhubport(void __iomem *ep_target_regs, | ||
| 352 | u8 qh_h_port_reg) | ||
| 353 | { | ||
| 354 | musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg); | ||
| 355 | } | ||
| 356 | |||
| 357 | static inline void musb_write_txfunaddr(void __iomem *mbase, u8 epnum, | ||
| 358 | u8 qh_addr_reg) | ||
| 359 | { | ||
| 360 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR), | ||
| 361 | qh_addr_reg); | ||
| 362 | } | ||
| 363 | |||
| 364 | static inline void musb_write_txhubaddr(void __iomem *mbase, u8 epnum, | ||
| 365 | u8 qh_addr_reg) | ||
| 366 | { | ||
| 367 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR), | ||
| 368 | qh_addr_reg); | ||
| 369 | } | ||
| 370 | |||
| 371 | static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | ||
| 372 | u8 qh_h_port_reg) | ||
| 373 | { | ||
| 374 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT), | ||
| 375 | qh_h_port_reg); | ||
| 376 | } | ||
| 377 | |||
| 378 | #else /* CONFIG_BLACKFIN */ | ||
| 379 | |||
| 380 | #define USB_BASE USB_FADDR | ||
| 381 | #define USB_OFFSET(reg) (reg - USB_BASE) | ||
| 382 | |||
| 383 | /* | ||
| 384 | * Common USB registers | ||
| 385 | */ | ||
| 386 | #define MUSB_FADDR USB_OFFSET(USB_FADDR) /* 8-bit */ | ||
| 387 | #define MUSB_POWER USB_OFFSET(USB_POWER) /* 8-bit */ | ||
| 388 | #define MUSB_INTRTX USB_OFFSET(USB_INTRTX) /* 16-bit */ | ||
| 389 | #define MUSB_INTRRX USB_OFFSET(USB_INTRRX) | ||
| 390 | #define MUSB_INTRTXE USB_OFFSET(USB_INTRTXE) | ||
| 391 | #define MUSB_INTRRXE USB_OFFSET(USB_INTRRXE) | ||
| 392 | #define MUSB_INTRUSB USB_OFFSET(USB_INTRUSB) /* 8 bit */ | ||
| 393 | #define MUSB_INTRUSBE USB_OFFSET(USB_INTRUSBE)/* 8 bit */ | ||
| 394 | #define MUSB_FRAME USB_OFFSET(USB_FRAME) | ||
| 395 | #define MUSB_INDEX USB_OFFSET(USB_INDEX) /* 8 bit */ | ||
| 396 | #define MUSB_TESTMODE USB_OFFSET(USB_TESTMODE)/* 8 bit */ | ||
| 397 | |||
| 398 | /* Get offset for a given FIFO from musb->mregs */ | ||
| 399 | #define MUSB_FIFO_OFFSET(epnum) \ | ||
| 400 | (USB_OFFSET(USB_EP0_FIFO) + ((epnum) * 8)) | ||
| 401 | |||
| 402 | /* | ||
| 403 | * Additional Control Registers | ||
| 404 | */ | ||
| 405 | |||
| 406 | #define MUSB_DEVCTL USB_OFFSET(USB_OTG_DEV_CTL) /* 8 bit */ | ||
| 407 | |||
| 408 | #define MUSB_LINKINFO USB_OFFSET(USB_LINKINFO)/* 8 bit */ | ||
| 409 | #define MUSB_VPLEN USB_OFFSET(USB_VPLEN) /* 8 bit */ | ||
| 410 | #define MUSB_HS_EOF1 USB_OFFSET(USB_HS_EOF1) /* 8 bit */ | ||
| 411 | #define MUSB_FS_EOF1 USB_OFFSET(USB_FS_EOF1) /* 8 bit */ | ||
| 412 | #define MUSB_LS_EOF1 USB_OFFSET(USB_LS_EOF1) /* 8 bit */ | ||
| 413 | |||
| 414 | /* Offsets to endpoint registers */ | ||
| 415 | #define MUSB_TXMAXP 0x00 | ||
| 416 | #define MUSB_TXCSR 0x04 | ||
| 417 | #define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ | ||
| 418 | #define MUSB_RXMAXP 0x08 | ||
| 419 | #define MUSB_RXCSR 0x0C | ||
| 420 | #define MUSB_RXCOUNT 0x10 | ||
| 421 | #define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ | ||
| 422 | #define MUSB_TXTYPE 0x14 | ||
| 423 | #define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ | ||
| 424 | #define MUSB_TXINTERVAL 0x18 | ||
| 425 | #define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ | ||
| 426 | #define MUSB_RXTYPE 0x1C | ||
| 427 | #define MUSB_RXINTERVAL 0x20 | ||
| 428 | #define MUSB_TXCOUNT 0x28 | ||
| 429 | |||
| 430 | /* Offsets to endpoint registers in indexed model (using INDEX register) */ | ||
| 431 | #define MUSB_INDEXED_OFFSET(_epnum, _offset) \ | ||
| 432 | (0x40 + (_offset)) | ||
| 433 | |||
| 434 | /* Offsets to endpoint registers in flat models */ | ||
| 435 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | ||
| 436 | (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset)) | ||
| 437 | |||
| 438 | /* Not implemented - HW has seperate Tx/Rx FIFO */ | ||
| 439 | #define MUSB_TXCSR_MODE 0x0000 | ||
| 440 | |||
| 441 | /* | ||
| 442 | * Dummy stub for clk framework, it will be removed | ||
| 443 | * until Blackfin supports clk framework | ||
| 444 | */ | ||
| 445 | #define clk_get(dev, id) NULL | ||
| 446 | #define clk_put(clock) do {} while (0) | ||
| 447 | #define clk_enable(clock) do {} while (0) | ||
| 448 | #define clk_disable(clock) do {} while (0) | ||
| 449 | |||
| 450 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) | ||
| 451 | { | ||
| 452 | } | ||
| 453 | |||
| 454 | static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off) | ||
| 455 | { | ||
| 456 | } | ||
| 457 | |||
| 458 | static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size) | ||
| 459 | { | ||
| 460 | } | ||
| 461 | |||
| 462 | static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | ||
| 463 | { | ||
| 464 | } | ||
| 465 | |||
| 466 | static inline u8 musb_read_configdata(void __iomem *mbase) | ||
| 467 | { | ||
| 468 | return 0; | ||
| 469 | } | ||
| 470 | |||
| 471 | static inline u16 musb_read_hwvers(void __iomem *mbase) | ||
| 472 | { | ||
| 473 | return 0; | ||
| 474 | } | ||
| 475 | |||
| 476 | static inline u16 musb_read_target_reg_base(u8 i, void __iomem *mbase) | ||
| 477 | { | ||
| 478 | return 0; | ||
| 479 | } | ||
| 480 | |||
| 481 | static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, | ||
| 482 | u8 qh_addr_req) | ||
| 483 | { | ||
| 484 | } | ||
| 485 | |||
| 486 | static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, | ||
| 487 | u8 qh_h_addr_reg) | ||
| 488 | { | ||
| 489 | } | ||
| 490 | |||
| 491 | static inline void musb_write_rxhubport(void __iomem *ep_target_regs, | ||
| 492 | u8 qh_h_port_reg) | ||
| 493 | { | ||
| 494 | } | ||
| 495 | |||
| 496 | static inline void musb_write_txfunaddr(void __iomem *mbase, u8 epnum, | ||
| 497 | u8 qh_addr_reg) | ||
| 498 | { | ||
| 499 | } | ||
| 500 | |||
| 501 | static inline void musb_write_txhubaddr(void __iomem *mbase, u8 epnum, | ||
| 502 | u8 qh_addr_reg) | ||
| 503 | { | ||
| 504 | } | ||
| 505 | |||
| 506 | static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | ||
| 507 | u8 qh_h_port_reg) | ||
| 508 | { | ||
| 509 | } | ||
| 510 | |||
| 511 | #endif /* CONFIG_BLACKFIN */ | ||
| 512 | |||
| 300 | #endif /* __MUSB_REGS_H__ */ | 513 | #endif /* __MUSB_REGS_H__ */ |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 8c734ef2c1ed..8662e9e159c3 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
| @@ -34,58 +34,7 @@ | |||
| 34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
| 35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
| 36 | #include "musb_core.h" | 36 | #include "musb_core.h" |
| 37 | 37 | #include "musbhsdma.h" | |
| 38 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) | ||
| 39 | #include "omap2430.h" | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #define MUSB_HSDMA_BASE 0x200 | ||
| 43 | #define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0) | ||
| 44 | #define MUSB_HSDMA_CONTROL 0x4 | ||
| 45 | #define MUSB_HSDMA_ADDRESS 0x8 | ||
| 46 | #define MUSB_HSDMA_COUNT 0xc | ||
| 47 | |||
| 48 | #define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ | ||
| 49 | (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset) | ||
| 50 | |||
| 51 | /* control register (16-bit): */ | ||
| 52 | #define MUSB_HSDMA_ENABLE_SHIFT 0 | ||
| 53 | #define MUSB_HSDMA_TRANSMIT_SHIFT 1 | ||
| 54 | #define MUSB_HSDMA_MODE1_SHIFT 2 | ||
| 55 | #define MUSB_HSDMA_IRQENABLE_SHIFT 3 | ||
| 56 | #define MUSB_HSDMA_ENDPOINT_SHIFT 4 | ||
| 57 | #define MUSB_HSDMA_BUSERROR_SHIFT 8 | ||
| 58 | #define MUSB_HSDMA_BURSTMODE_SHIFT 9 | ||
| 59 | #define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT) | ||
| 60 | #define MUSB_HSDMA_BURSTMODE_UNSPEC 0 | ||
| 61 | #define MUSB_HSDMA_BURSTMODE_INCR4 1 | ||
| 62 | #define MUSB_HSDMA_BURSTMODE_INCR8 2 | ||
| 63 | #define MUSB_HSDMA_BURSTMODE_INCR16 3 | ||
| 64 | |||
| 65 | #define MUSB_HSDMA_CHANNELS 8 | ||
| 66 | |||
| 67 | struct musb_dma_controller; | ||
| 68 | |||
| 69 | struct musb_dma_channel { | ||
| 70 | struct dma_channel channel; | ||
| 71 | struct musb_dma_controller *controller; | ||
| 72 | u32 start_addr; | ||
| 73 | u32 len; | ||
| 74 | u16 max_packet_sz; | ||
| 75 | u8 idx; | ||
| 76 | u8 epnum; | ||
| 77 | u8 transmit; | ||
| 78 | }; | ||
| 79 | |||
| 80 | struct musb_dma_controller { | ||
| 81 | struct dma_controller controller; | ||
| 82 | struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS]; | ||
| 83 | void *private_data; | ||
| 84 | void __iomem *base; | ||
| 85 | u8 channel_count; | ||
| 86 | u8 used_channels; | ||
| 87 | u8 irq; | ||
| 88 | }; | ||
| 89 | 38 | ||
| 90 | static int dma_controller_start(struct dma_controller *c) | 39 | static int dma_controller_start(struct dma_controller *c) |
| 91 | { | 40 | { |
| @@ -203,12 +152,8 @@ static void configure_channel(struct dma_channel *channel, | |||
| 203 | : 0); | 152 | : 0); |
| 204 | 153 | ||
| 205 | /* address/count */ | 154 | /* address/count */ |
| 206 | musb_writel(mbase, | 155 | musb_write_hsdma_addr(mbase, bchannel, dma_addr); |
| 207 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), | 156 | musb_write_hsdma_count(mbase, bchannel, len); |
| 208 | dma_addr); | ||
| 209 | musb_writel(mbase, | ||
| 210 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), | ||
| 211 | len); | ||
| 212 | 157 | ||
| 213 | /* control (this should start things) */ | 158 | /* control (this should start things) */ |
| 214 | musb_writew(mbase, | 159 | musb_writew(mbase, |
| @@ -279,13 +224,8 @@ static int dma_channel_abort(struct dma_channel *channel) | |||
| 279 | musb_writew(mbase, | 224 | musb_writew(mbase, |
| 280 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL), | 225 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL), |
| 281 | 0); | 226 | 0); |
| 282 | musb_writel(mbase, | 227 | musb_write_hsdma_addr(mbase, bchannel, 0); |
| 283 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), | 228 | musb_write_hsdma_count(mbase, bchannel, 0); |
| 284 | 0); | ||
| 285 | musb_writel(mbase, | ||
| 286 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), | ||
| 287 | 0); | ||
| 288 | |||
| 289 | channel->status = MUSB_DMA_STATUS_FREE; | 229 | channel->status = MUSB_DMA_STATUS_FREE; |
| 290 | } | 230 | } |
| 291 | 231 | ||
| @@ -333,10 +273,8 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
| 333 | } else { | 273 | } else { |
| 334 | u8 devctl; | 274 | u8 devctl; |
| 335 | 275 | ||
| 336 | addr = musb_readl(mbase, | 276 | addr = musb_read_hsdma_addr(mbase, |
| 337 | MUSB_HSDMA_CHANNEL_OFFSET( | 277 | bchannel); |
| 338 | bchannel, | ||
| 339 | MUSB_HSDMA_ADDRESS)); | ||
| 340 | channel->actual_len = addr | 278 | channel->actual_len = addr |
| 341 | - musb_channel->start_addr; | 279 | - musb_channel->start_addr; |
| 342 | 280 | ||
| @@ -375,6 +313,12 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
| 375 | } | 313 | } |
| 376 | } | 314 | } |
| 377 | } | 315 | } |
| 316 | |||
| 317 | #ifdef CONFIG_BLACKFIN | ||
| 318 | /* Clear DMA interrup flags */ | ||
| 319 | musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma); | ||
| 320 | #endif | ||
| 321 | |||
| 378 | retval = IRQ_HANDLED; | 322 | retval = IRQ_HANDLED; |
| 379 | done: | 323 | done: |
| 380 | spin_unlock_irqrestore(&musb->lock, flags); | 324 | spin_unlock_irqrestore(&musb->lock, flags); |
| @@ -424,7 +368,7 @@ dma_controller_create(struct musb *musb, void __iomem *base) | |||
| 424 | controller->controller.channel_abort = dma_channel_abort; | 368 | controller->controller.channel_abort = dma_channel_abort; |
| 425 | 369 | ||
| 426 | if (request_irq(irq, dma_controller_irq, IRQF_DISABLED, | 370 | if (request_irq(irq, dma_controller_irq, IRQF_DISABLED, |
| 427 | musb->controller->bus_id, &controller->controller)) { | 371 | dev_name(musb->controller), &controller->controller)) { |
| 428 | dev_err(dev, "request_irq %d failed!\n", irq); | 372 | dev_err(dev, "request_irq %d failed!\n", irq); |
| 429 | dma_controller_destroy(&controller->controller); | 373 | dma_controller_destroy(&controller->controller); |
| 430 | 374 | ||
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h new file mode 100644 index 000000000000..1299d92dc83f --- /dev/null +++ b/drivers/usb/musb/musbhsdma.h | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | /* | ||
| 2 | * MUSB OTG driver - support for Mentor's DMA controller | ||
| 3 | * | ||
| 4 | * Copyright 2005 Mentor Graphics Corporation | ||
| 5 | * Copyright (C) 2005-2007 by Texas Instruments | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * version 2 as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, but | ||
| 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 19 | * 02110-1301 USA | ||
| 20 | * | ||
| 21 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 22 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 23 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
| 24 | * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
| 27 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
| 28 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 31 | * | ||
| 32 | */ | ||
| 33 | |||
| 34 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) | ||
| 35 | #include "omap2430.h" | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #ifndef CONFIG_BLACKFIN | ||
| 39 | |||
| 40 | #define MUSB_HSDMA_BASE 0x200 | ||
| 41 | #define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0) | ||
| 42 | #define MUSB_HSDMA_CONTROL 0x4 | ||
| 43 | #define MUSB_HSDMA_ADDRESS 0x8 | ||
| 44 | #define MUSB_HSDMA_COUNT 0xc | ||
| 45 | |||
| 46 | #define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ | ||
| 47 | (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset) | ||
| 48 | |||
| 49 | #define musb_read_hsdma_addr(mbase, bchannel) \ | ||
| 50 | musb_readl(mbase, \ | ||
| 51 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS)) | ||
| 52 | |||
| 53 | #define musb_write_hsdma_addr(mbase, bchannel, addr) \ | ||
| 54 | musb_writel(mbase, \ | ||
| 55 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \ | ||
| 56 | addr) | ||
| 57 | |||
| 58 | #define musb_write_hsdma_count(mbase, bchannel, len) \ | ||
| 59 | musb_writel(mbase, \ | ||
| 60 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \ | ||
| 61 | len) | ||
| 62 | #else | ||
| 63 | |||
| 64 | #define MUSB_HSDMA_BASE 0x400 | ||
| 65 | #define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0) | ||
| 66 | #define MUSB_HSDMA_CONTROL 0x04 | ||
| 67 | #define MUSB_HSDMA_ADDR_LOW 0x08 | ||
| 68 | #define MUSB_HSDMA_ADDR_HIGH 0x0C | ||
| 69 | #define MUSB_HSDMA_COUNT_LOW 0x10 | ||
| 70 | #define MUSB_HSDMA_COUNT_HIGH 0x14 | ||
| 71 | |||
| 72 | #define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ | ||
| 73 | (MUSB_HSDMA_BASE + (_bchannel * 0x20) + _offset) | ||
| 74 | |||
| 75 | static inline u32 musb_read_hsdma_addr(void __iomem *mbase, u8 bchannel) | ||
| 76 | { | ||
| 77 | u32 addr = musb_readw(mbase, | ||
| 78 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH)); | ||
| 79 | |||
| 80 | addr = addr << 16; | ||
| 81 | |||
| 82 | addr |= musb_readw(mbase, | ||
| 83 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW)); | ||
| 84 | |||
| 85 | return addr; | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline void musb_write_hsdma_addr(void __iomem *mbase, | ||
| 89 | u8 bchannel, dma_addr_t dma_addr) | ||
| 90 | { | ||
| 91 | musb_writew(mbase, | ||
| 92 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW), | ||
| 93 | ((u16)((u32) dma_addr & 0xFFFF))); | ||
| 94 | musb_writew(mbase, | ||
| 95 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH), | ||
| 96 | ((u16)(((u32) dma_addr >> 16) & 0xFFFF))); | ||
| 97 | } | ||
| 98 | |||
| 99 | static inline void musb_write_hsdma_count(void __iomem *mbase, | ||
| 100 | u8 bchannel, u32 len) | ||
| 101 | { | ||
| 102 | musb_writew(mbase, | ||
| 103 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW), | ||
| 104 | ((u16)((u32) len & 0xFFFF))); | ||
| 105 | musb_writew(mbase, | ||
| 106 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH), | ||
| 107 | ((u16)(((u32) len >> 16) & 0xFFFF))); | ||
| 108 | } | ||
| 109 | |||
| 110 | #endif /* CONFIG_BLACKFIN */ | ||
| 111 | |||
| 112 | /* control register (16-bit): */ | ||
| 113 | #define MUSB_HSDMA_ENABLE_SHIFT 0 | ||
| 114 | #define MUSB_HSDMA_TRANSMIT_SHIFT 1 | ||
| 115 | #define MUSB_HSDMA_MODE1_SHIFT 2 | ||
| 116 | #define MUSB_HSDMA_IRQENABLE_SHIFT 3 | ||
| 117 | #define MUSB_HSDMA_ENDPOINT_SHIFT 4 | ||
| 118 | #define MUSB_HSDMA_BUSERROR_SHIFT 8 | ||
| 119 | #define MUSB_HSDMA_BURSTMODE_SHIFT 9 | ||
| 120 | #define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT) | ||
| 121 | #define MUSB_HSDMA_BURSTMODE_UNSPEC 0 | ||
| 122 | #define MUSB_HSDMA_BURSTMODE_INCR4 1 | ||
| 123 | #define MUSB_HSDMA_BURSTMODE_INCR8 2 | ||
| 124 | #define MUSB_HSDMA_BURSTMODE_INCR16 3 | ||
| 125 | |||
| 126 | #define MUSB_HSDMA_CHANNELS 8 | ||
| 127 | |||
| 128 | struct musb_dma_controller; | ||
| 129 | |||
| 130 | struct musb_dma_channel { | ||
| 131 | struct dma_channel channel; | ||
| 132 | struct musb_dma_controller *controller; | ||
| 133 | u32 start_addr; | ||
| 134 | u32 len; | ||
| 135 | u16 max_packet_sz; | ||
| 136 | u8 idx; | ||
| 137 | u8 epnum; | ||
| 138 | u8 transmit; | ||
| 139 | }; | ||
| 140 | |||
| 141 | struct musb_dma_controller { | ||
| 142 | struct dma_controller controller; | ||
| 143 | struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS]; | ||
| 144 | void *private_data; | ||
| 145 | void __iomem *base; | ||
| 146 | u8 channel_count; | ||
| 147 | u8 used_channels; | ||
| 148 | u8 irq; | ||
| 149 | }; | ||
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index ce6c162920f7..901dffdf23b1 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
| @@ -58,10 +58,10 @@ static void musb_do_idle(unsigned long _musb) | |||
| 58 | #endif | 58 | #endif |
| 59 | u8 devctl; | 59 | u8 devctl; |
| 60 | 60 | ||
| 61 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
| 62 | |||
| 63 | spin_lock_irqsave(&musb->lock, flags); | 61 | spin_lock_irqsave(&musb->lock, flags); |
| 64 | 62 | ||
| 63 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
| 64 | |||
| 65 | switch (musb->xceiv.state) { | 65 | switch (musb->xceiv.state) { |
| 66 | case OTG_STATE_A_WAIT_BCON: | 66 | case OTG_STATE_A_WAIT_BCON: |
| 67 | devctl &= ~MUSB_DEVCTL_SESSION; | 67 | devctl &= ~MUSB_DEVCTL_SESSION; |
| @@ -196,7 +196,7 @@ static int omap_set_power(struct otg_transceiver *x, unsigned mA) | |||
| 196 | 196 | ||
| 197 | static int musb_platform_resume(struct musb *musb); | 197 | static int musb_platform_resume(struct musb *musb); |
| 198 | 198 | ||
| 199 | void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 199 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) |
| 200 | { | 200 | { |
| 201 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 201 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
| 202 | 202 | ||
| @@ -204,15 +204,24 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
| 204 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | 204 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); |
| 205 | 205 | ||
| 206 | switch (musb_mode) { | 206 | switch (musb_mode) { |
| 207 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
| 207 | case MUSB_HOST: | 208 | case MUSB_HOST: |
| 208 | otg_set_host(&musb->xceiv, musb->xceiv.host); | 209 | otg_set_host(&musb->xceiv, musb->xceiv.host); |
| 209 | break; | 210 | break; |
| 211 | #endif | ||
| 212 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
| 210 | case MUSB_PERIPHERAL: | 213 | case MUSB_PERIPHERAL: |
| 211 | otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget); | 214 | otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget); |
| 212 | break; | 215 | break; |
| 216 | #endif | ||
| 217 | #ifdef CONFIG_USB_MUSB_OTG | ||
| 213 | case MUSB_OTG: | 218 | case MUSB_OTG: |
| 214 | break; | 219 | break; |
| 220 | #endif | ||
| 221 | default: | ||
| 222 | return -EINVAL; | ||
| 215 | } | 223 | } |
| 224 | return 0; | ||
| 216 | } | 225 | } |
| 217 | 226 | ||
| 218 | int __init musb_platform_init(struct musb *musb) | 227 | int __init musb_platform_init(struct musb *musb) |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index ee8fca92a4ac..9e20fd070d71 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
| @@ -598,7 +598,7 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
| 598 | * and peripheral modes in non-OTG configurations by reconfiguring hardware | 598 | * and peripheral modes in non-OTG configurations by reconfiguring hardware |
| 599 | * and then setting musb->board_mode. For now, only support OTG mode. | 599 | * and then setting musb->board_mode. For now, only support OTG mode. |
| 600 | */ | 600 | */ |
| 601 | void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 601 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) |
| 602 | { | 602 | { |
| 603 | void __iomem *tbase = musb->ctrl_base; | 603 | void __iomem *tbase = musb->ctrl_base; |
| 604 | u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf; | 604 | 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) | |||
| 641 | #endif | 641 | #endif |
| 642 | 642 | ||
| 643 | default: | 643 | default: |
| 644 | DBG(2, "Trying to set unknown mode %i\n", musb_mode); | 644 | DBG(2, "Trying to set mode %i\n", musb_mode); |
| 645 | return -EINVAL; | ||
| 645 | } | 646 | } |
| 646 | 647 | ||
| 647 | musb_writel(tbase, TUSB_PHY_OTG_CTRL, | 648 | musb_writel(tbase, TUSB_PHY_OTG_CTRL, |
| @@ -655,6 +656,8 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
| 655 | !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) | 656 | !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) |
| 656 | INFO("Cannot be peripheral with mini-A cable " | 657 | INFO("Cannot be peripheral with mini-A cable " |
| 657 | "otg_stat: %08x\n", otg_stat); | 658 | "otg_stat: %08x\n", otg_stat); |
| 659 | |||
| 660 | return 0; | ||
| 658 | } | 661 | } |
| 659 | 662 | ||
| 660 | static inline unsigned long | 663 | static inline unsigned long |
