Commit b0a1bdcd authored by Tony Lindgren's avatar Tony Lindgren

musb_hdrc: Transfer remaining bytes with PIO

DMA callback can manually transfer remaining 1 - 31 bytes
after DMA transfer using PIO. This allows transferring
a wider range of sizes with DMA.

This needs to be tested with sync DMA transfers as
PIO may not be mixed with sync DMA.
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 9c97d4aa
......@@ -146,7 +146,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
struct musb_hw_ep *hw_ep = chdat->hw_ep;
void __iomem *ep_conf = hw_ep->conf;
void __iomem *musb_base = musb->pRegs;
unsigned long remaining, flags;
unsigned long remaining, flags, pio;
int ch;
spin_lock_irqsave(&musb->Lock, flags);
......@@ -170,21 +170,25 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
remaining = TUSB_EP_CONFIG_XFR_SIZE(remaining);
channel->dwActualLength = chdat->transfer_len - remaining;
pio = chdat->len - channel->dwActualLength;
DBG(2, "DMA remaining %lu/%u\n", remaining, chdat->transfer_len);
/* Transfer remaining 1 - 31 bytes if DMA worked */
if (remaining == 0) {
u32 pio;
/* Transfer remaining 1 - 31 bytes */
if (pio > 0 && pio < 32) {
u8 *buf;
pio = chdat->len - channel->dwActualLength;
buf = phys_to_virt((u32)chdat->dma_addr)
+ chdat->transfer_len;
if (chdat->tx)
DBG(2, "Using PIO for remaining %i bytes\n", pio);
buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
if (chdat->tx) {
consistent_sync(phys_to_virt((u32)chdat->dma_addr),
chdat->transfer_len, DMA_TO_DEVICE);
musb_write_fifo(hw_ep, pio, buf);
else
} else {
musb_read_fifo(hw_ep, pio, buf);
consistent_sync(phys_to_virt((u32)chdat->dma_addr),
chdat->transfer_len, DMA_FROM_DEVICE);
}
channel->dwActualLength += pio;
}
......@@ -201,7 +205,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
if (!chdat->tx)
musb_dma_completion(musb, chdat->epnum, chdat->tx);
/* We musb terminate short tx transfers manually by setting TXPKTRDY.
/* We must terminate short tx transfers manually by setting TXPKTRDY.
* REVISIT: This same problem may occur with other MUSB dma as well.
* Easy to test with g_ether by pinging the MUSB board with ping -s54.
*/
......@@ -239,7 +243,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
s8 dmareq;
s8 sync_dev;
if (unlikely(dma_addr & 0x1) || len < 32)
if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
return FALSE;
chdat->transfer_len = len & ~0x1f;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment