aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/musb_host.c')
-rw-r--r--drivers/usb/musb/musb_host.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 521fd83f5b9d..518abfca1243 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -4,6 +4,7 @@
4 * Copyright 2005 Mentor Graphics Corporation 4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments 5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation 6 * Copyright (C) 2006-2007 Nokia Corporation
7 * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -168,13 +169,15 @@ static inline void musb_h_tx_start(struct musb_hw_ep *ep)
168 169
169} 170}
170 171
171static inline void cppi_host_txdma_start(struct musb_hw_ep *ep) 172static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep)
172{ 173{
173 u16 txcsr; 174 u16 txcsr;
174 175
175 /* NOTE: no locks here; caller should lock and select EP */ 176 /* NOTE: no locks here; caller should lock and select EP */
176 txcsr = musb_readw(ep->regs, MUSB_TXCSR); 177 txcsr = musb_readw(ep->regs, MUSB_TXCSR);
177 txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; 178 txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS;
179 if (is_cppi_enabled())
180 txcsr |= MUSB_TXCSR_DMAMODE;
178 musb_writew(ep->regs, MUSB_TXCSR, txcsr); 181 musb_writew(ep->regs, MUSB_TXCSR, txcsr);
179} 182}
180 183
@@ -279,7 +282,7 @@ start:
279 if (!hw_ep->tx_channel) 282 if (!hw_ep->tx_channel)
280 musb_h_tx_start(hw_ep); 283 musb_h_tx_start(hw_ep);
281 else if (is_cppi_enabled() || tusb_dma_omap()) 284 else if (is_cppi_enabled() || tusb_dma_omap())
282 cppi_host_txdma_start(hw_ep); 285 musb_h_tx_dma_start(hw_ep);
283 } 286 }
284} 287}
285 288
@@ -1250,6 +1253,67 @@ void musb_host_tx(struct musb *musb, u8 epnum)
1250 1253
1251 } 1254 }
1252 1255
1256 if (is_dma_capable() && dma && !status) {
1257 /*
1258 * DMA has completed. But if we're using DMA mode 1 (multi
1259 * packet DMA), we need a terminal TXPKTRDY interrupt before
1260 * we can consider this transfer completed, lest we trash
1261 * its last packet when writing the next URB's data. So we
1262 * switch back to mode 0 to get that interrupt; we'll come
1263 * back here once it happens.
1264 */
1265 if (tx_csr & MUSB_TXCSR_DMAMODE) {
1266 /*
1267 * We shouldn't clear DMAMODE with DMAENAB set; so
1268 * clear them in a safe order. That should be OK
1269 * once TXPKTRDY has been set (and I've never seen
1270 * it being 0 at this moment -- DMA interrupt latency
1271 * is significant) but if it hasn't been then we have
1272 * no choice but to stop being polite and ignore the
1273 * programmer's guide... :-)
1274 *
1275 * Note that we must write TXCSR with TXPKTRDY cleared
1276 * in order not to re-trigger the packet send (this bit
1277 * can't be cleared by CPU), and there's another caveat:
1278 * TXPKTRDY may be set shortly and then cleared in the
1279 * double-buffered FIFO mode, so we do an extra TXCSR
1280 * read for debouncing...
1281 */
1282 tx_csr &= musb_readw(epio, MUSB_TXCSR);
1283 if (tx_csr & MUSB_TXCSR_TXPKTRDY) {
1284 tx_csr &= ~(MUSB_TXCSR_DMAENAB |
1285 MUSB_TXCSR_TXPKTRDY);
1286 musb_writew(epio, MUSB_TXCSR,
1287 tx_csr | MUSB_TXCSR_H_WZC_BITS);
1288 }
1289 tx_csr &= ~(MUSB_TXCSR_DMAMODE |
1290 MUSB_TXCSR_TXPKTRDY);
1291 musb_writew(epio, MUSB_TXCSR,
1292 tx_csr | MUSB_TXCSR_H_WZC_BITS);
1293
1294 /*
1295 * There is no guarantee that we'll get an interrupt
1296 * after clearing DMAMODE as we might have done this
1297 * too late (after TXPKTRDY was cleared by controller).
1298 * Re-read TXCSR as we have spoiled its previous value.
1299 */
1300 tx_csr = musb_readw(epio, MUSB_TXCSR);
1301 }
1302
1303 /*
1304 * We may get here from a DMA completion or TXPKTRDY interrupt.
1305 * In any case, we must check the FIFO status here and bail out
1306 * only if the FIFO still has data -- that should prevent the
1307 * "missed" TXPKTRDY interrupts and deal with double-buffered
1308 * FIFO mode too...
1309 */
1310 if (tx_csr & (MUSB_TXCSR_FIFONOTEMPTY | MUSB_TXCSR_TXPKTRDY)) {
1311 DBG(2, "DMA complete but packet still in FIFO, "
1312 "CSR %04x\n", tx_csr);
1313 return;
1314 }
1315 }
1316
1253 /* REVISIT this looks wrong... */ 1317 /* REVISIT this looks wrong... */
1254 if (!status || dma || usb_pipeisoc(pipe)) { 1318 if (!status || dma || usb_pipeisoc(pipe)) {
1255 if (dma) 1319 if (dma)