summaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-11-12 16:37:47 +0100
committerFelipe Balbi <balbi@ti.com>2013-11-25 10:54:14 -0600
commita655f481d83d6d37bec0a2ddfdd24c30ff8f541f (patch)
tree6f1c0217ababbd4c3fd0bd167a4793503d5023ba /drivers/usb/host
parentd373a8534d5e1e7a350e40d3c11961a7cd8d530b (diff)
usb: musb: musb_cppi41: handle pre-mature TX complete interrupt
The TX-complete interrupt of the CPPI41 on AM335x fires too early. Adding a loop and counting how long it takes until the MUSB_TXCSR_TXPKTRDY bit is cleared I see FS: |musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadc54002, len=1514 is_tx=1 |cppi41_dma_callback() 74 loops |musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadcd8802, len=1514 is_tx=1 |cppi41_dma_callback() 66 loops |musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadcd8002, len=1514 is_tx=1 |cppi41_dma_callback() 136 loops |musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadf55802, len=1514 is_tx=1 |cppi41_dma_callback() 136 loops avg: 110 - 150us HS: |musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xaca6f002, len=1514 is_tx=1 |cppi41_dma_callback() 0 loops |musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xadd6f802, len=1514 is_tx=1 |cppi41_dma_callback() 2 loops |musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xadd6f002, len=1514 is_tx=1 |cppi41_dma_callback() 13 loops avg: 2us for the same test case. One loop means a udelay(1). The delay seems to depend on the packet size. On HS the bit is always cleared for small packet sizes while on FS it is never the case, it mostly around 110us. This testing has been performed with g_ether (musb as device) and using BULK transfers. INTR transfers are way more fun: during init the gadget sends a INT packet to the host and cppi41 says "transfer done" shortly after. The MUSB_TXCSR_TXPKTRDY bit is set even seconds later. The reason is that the host did not try to receive it, it does so after the interface (on host side) has been configured. Until this happens, that packet remains in musb's FIFO. To fix this, two things are done: - No DMA transfers for INT based endpoints. These transfer are usually very small and rare so it is likely better to skip the DMA engine and stuff the four bytes directly into the FIFO - on HS we poll up to 25us and hope that bit goes away. If not we setup a hrtimer to poll for it. The 140us delay is a rule of thumb. In FS the command | ping 10.10.10.10 -c1 -s65130 creates about 44 1514bytes transfers. About 19 of them need a second timer to complete. Reported-by: Bin Liu <b-liu@ti.com> Cc: stable@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/host')
0 files changed, 0 insertions, 0 deletions