aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_cppi41.c (follow)
AgeCommit message (Collapse)AuthorFilesLines
2014-06-27usb: musb: Ensure that cppi41 timer gets armed on premature DMA TX irqThomas Gleixner1-1/+1
Some TI chips raise the DMA complete interrupt before the actual transfer has been completed. The code tries to busy wait for a few microseconds and if that fails it arms an hrtimer to recheck. So far so good, but that has the following issue: CPU 0 CPU1 start_next_transfer(RQ1); DMA interrupt if (premature_irq(RQ1)) if (!hrtimer_active(timer)) hrtimer_start(timer); hrtimer expires timer->state = CALLBACK_RUNNING; timer->fn() cppi41_recheck_tx_req() complete_request(RQ1); if (requests_pending()) start_next_transfer(RQ2); DMA interrupt if (premature_irq(RQ2)) if (!hrtimer_active(timer)) hrtimer_start(timer); timer->state = INACTIVE; The premature interrupt of request2 on CPU1 does not arm the timer and therefor the request completion never happens because it checks for !hrtimer_active(). hrtimer_active() evaluates: timer->state != HRTIMER_STATE_INACTIVE which of course evaluates to true in the above case as timer->state is CALLBACK_RUNNING. That's clearly documented: * A timer is active, when it is enqueued into the rbtree or the * callback function is running or it's in the state of being migrated * to another cpu. But that's not what the code wants to check. The code wants to check whether the timer is queued, i.e. whether its armed and waiting for expiry. We have a helper function for this: hrtimer_is_queued(). This evaluates: timer->state & HRTIMER_STATE_QUEUED So in the above case this evaluates to false and therefor forces the DMA interrupt on CPU1 to call hrtimer_start(). Use hrtimer_is_queued() instead of hrtimer_active() and evrything is good. Reported-by: Torben Hohn <torbenh@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-03-05usb: musb: musb_cppi41: Dont reprogram DMA if tear down is initiatedGeorge Cherian1-1/+2
Reprogramming the DMA after tear down is initiated leads to warning. This is mainly seen with ISOCH since we do a delayed completion for ISOCH transfers. In ISOCH transfers dma_completion should not reprogram if the channel tear down is initiated. Signed-off-by: George Cherian <george.cherian@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-02-18usb: musb: musb_cppi41: Handle ISOCH differently and not use the hrtimer.George Cherian1-0/+53
In case of ISOCH transfers the hrtimer workaround for the hardware issue is not very reliable. Instead of checking musb_is_tx_fifo_empty() in hrtimer routine, schedule a completion work and check the same in completion work. Signed-off-by: George Cherian <george.cherian@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-02-18usb: musb: musb_cppi41: Make CPPI aware of high bandwidth transfersGeorge Cherian1-0/+13
Enable CPPI to handle high bandwidth transfers, especially to support webcam captures. Use a single bd to get the whole of the data in case of high bandwidth transfers. Signed-off-by: George Cherian <george.cherian@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
2014-01-03USB: musb: correct spelling mistakes in comment and error stringRahul Bedarkar1-1/+1
Signed-off-by: Rahul Bedarkar <rahulbedarkar89@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-11-25usb: musb: musb_cppi41: handle pre-mature TX complete interruptSebastian Andrzej Siewior1-5/+108
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>
2013-11-25usb: musb: musb_cppi41: factor most of cppi41_dma_callback() into cppi41_trans_done()Sebastian Andrzej Siewior1-23/+36
This patch moves most of the logic in cppi41_dma_callback() into cppi41_trans_done() where it can be called from another function. Instead of computing "transferred" (the number of bytes transferred in the last transaction) in cppi41_trans_done() the member "cppi41_channel->prog_len" is now set to 0 if the transfer as a whole can be considered as done. If it is != 0 then the next iteration is assumed. This is a preparation for a workaround. Cc: stable@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
2013-10-17usb: musb: cppi41: allow to defer probing if DMA isn't yet availableSebastian Andrzej Siewior1-2/+6
If everything (musb, cppi41, phy) is built-in then musb will start without the dma engine printing only |musb-hdrc musb-hdrc.0.auto: Falied to request rx1. The reason for this is that the musb device structs are created & probed before those of the cppi41 device. So the cppi41 device is probed too late. As a workaround for this allow the musb_cppi41 part to defer the probe if everything is fine except for the missing DMA controller. In case of another error we continue. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
2013-08-27usb: musb: cppi41: fix missing unlock on error in cppi41_dma_callback()Wei Yongjun1-1/+3
Add the missing unlock before return from function cppi41_dma_callback() in the error handling case. Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn> Signed-off-by: Felipe Balbi <balbi@ti.com>
2013-08-13usb: musb: cppi41: Enable in device-TX modeSebastian Andrzej Siewior1-0/+3
Since the musb-gadget code now calls the dma engine properly it is possible to enable it for the TX path in device mode. AM335x Advisory 1.0.13 says that we may lose the toggle bit on multiple RX transfers. There is a workaround in host mode but none in device mode and therefore RX transfers are disabled. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
2013-08-09usb: musb dma: add cppi41 dma driverSebastian Andrzej Siewior1-0/+552
This driver is currently used by musb' cppi41 couter part. I may merge both dma engine user of musb at some point but not just yet. The driver seems to work in RX/TX mode in host mode, tested on mass storage. I increaed the size of the TX / RX transfers and waited for the core code to cancel a transfers and it seems to recover. v2..3: - use mall transfers on RX side and check data toggle. - use rndis mode on tx side so we haveon interrupt for 4096 transfers. - remove custom "transferred" hack and use dmaengine_tx_status() to compute the total amount of data that has been transferred. - cancel transfers and reclaim descriptors v1..v2: - RX path added - dma mode 0 & 1 is working - device tree nodes re-created. Cc: Vinod Koul <vinod.koul@intel.com> Cc: Dan Williams <djbw@fb.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>