diff options
author | Thirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.com> | 2011-09-13 17:04:27 +0530 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-09-19 16:12:38 +0200 |
commit | ddd3b4e68f377ba18f235d71af9c7f3abe2c0763 (patch) | |
tree | dc1e5819b26e74ab4c3103f367b1c1fa04ad0bd7 | |
parent | 2a10ab01c0728fe7a610c9018e0976808ab683ae (diff) |
usb:musb:Enable DMA mode1 RX for without short pkt
This patch enables the DMA mode1 RX support
This feature is enabled based on the short_not_ok flag passed from
gadget drivers.
This will result in a thruput performance gain of around
40% for USB mass-storage/mtp use cases.
ST-Ericsson ID: 352334
ST-Ericsson Linux next: NA
ST-Ericsson FOSS-OUT ID: Trivial
Signed-off-by: <thirupathi.chippakurthy@stericsson.com>
Signed-off-by: Anand Gadiyar <gadiyar <at> ti.com>
Signed-off-by: Moiz Sonasath <m-sonasath <at> ti.com>
Signed-off-by: Vikram Pandita <vikram.pandita <at> ti.com>
Tested-by: Vikram Pandita <vikram.pandita <at> ti.com>
Change-Id: I17f58a018c1b5c0a4d89172fd2978a4e5da337f0
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30833
Reviewed-by: Praveena NADAHALLY <praveen.nadahally@stericsson.com>
Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 98 |
1 files changed, 58 insertions, 40 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 548338c2147..f3fd718554d 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -634,6 +634,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) u16 len; u16 csr = musb_readw(epio, MUSB_RXCSR); struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; + u8 use_mode_1; if (hw_ep->is_shared_fifo) musb_ep = &hw_ep->ep_in; @@ -683,6 +684,17 @@ static void rxstate(struct musb *musb, struct musb_request *req) if (csr & MUSB_RXCSR_RXPKTRDY) { len = musb_readw(epio, MUSB_RXCOUNT); + + /* + * Enable Mode 1 on RX transfers only when short_not_ok flag + * is set. Currently short_not_ok flag is set only from + * file_storage and f_mass_storage drivers + */ + + if (request->short_not_ok && len == musb_ep->packet_sz) + use_mode_1 = 1; + else + use_mode_1 = 0; if (request->actual < request->length) { #ifdef CONFIG_USB_INVENTRA_DMA if (is_buffer_mapped(req)) { @@ -714,50 +726,56 @@ static void rxstate(struct musb *musb, struct musb_request *req) * then becomes usable as a runtime "use mode 1" hint... */ - csr |= MUSB_RXCSR_DMAENAB; -#ifdef USE_MODE1 - csr |= MUSB_RXCSR_AUTOCLEAR; - /* csr |= MUSB_RXCSR_DMAMODE; */ + /* Experimental: Mode1 works with mass storage use cases */ + if (use_mode_1) { + csr |= MUSB_RXCSR_AUTOCLEAR; - /* this special sequence (enabling and then - * disabling MUSB_RXCSR_DMAMODE) is required - * to get DMAReq to activate - */ - musb_writew(epio, MUSB_RXCSR, - csr | MUSB_RXCSR_DMAMODE); -#else - if (!musb_ep->hb_mult && - musb_ep->hw_ep->rx_double_buffered) - csr |= MUSB_RXCSR_AUTOCLEAR; -#endif - musb_writew(epio, MUSB_RXCSR, csr); + musb_writew(epio, MUSB_RXCSR, csr); + csr |= MUSB_RXCSR_DMAENAB; + musb_writew(epio, MUSB_RXCSR, csr); - if (request->actual < request->length) { - int transfer_size = 0; -#ifdef USE_MODE1 - transfer_size = min(request->length - request->actual, - channel->max_len); -#else - transfer_size = min(request->length - request->actual, - (unsigned)len); -#endif - if (transfer_size <= musb_ep->packet_sz) - musb_ep->dma->desired_mode = 0; - else - musb_ep->dma->desired_mode = 1; + /* + * this special sequence (enabling and then + * disabling MUSB_RXCSR_DMAMODE) is required + * to get DMAReq to activate + */ - use_dma = c->channel_program( - channel, - musb_ep->packet_sz, - channel->desired_mode, - request->dma - + request->actual, - transfer_size); - } + musb_writew(epio, MUSB_RXCSR, + csr | MUSB_RXCSR_DMAMODE); + musb_writew(epio, MUSB_RXCSR, csr); + } else { + if (!musb_ep->hb_mult && + musb_ep->hw_ep->rx_double_buffered) + csr |= MUSB_RXCSR_AUTOCLEAR; + csr |= MUSB_RXCSR_DMAENAB; + musb_writew(epio, MUSB_RXCSR, csr); + } - if (use_dma) - return; - } + if (request->actual < request->length) { + int transfer_size = 0; + + if (use_mode_1) { + transfer_size = min(request->length - request->actual, + channel->max_len); + musb_ep->dma->desired_mode = 1; + } else { + transfer_size = min(request->length - request->actual, + (unsigned)len); + musb_ep->dma->desired_mode = 0; + } + + use_dma = c->channel_program( + channel, + musb_ep->packet_sz, + channel->desired_mode, + request->dma + + request->actual, + transfer_size); + } + + if (use_dma) + return; + } #elif defined(CONFIG_USB_UX500_DMA) if ((is_buffer_mapped(req)) && (request->actual < request->length)) { |