aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorAnand Gadiyar <gadiyar@ti.com>2011-07-20 01:11:58 -0400
committerFelipe Balbi <balbi@ti.com>2011-09-09 06:08:17 -0400
commit0ae52d5458ddb14d5da63054f1d8269a13fe9054 (patch)
tree7b635762c46ee3b94c3e0f0e9d43d9718e68e4ef /drivers/usb/musb
parentb3c3dc22366b15350281b1c273adecd2b91e320f (diff)
usb: musb: Enable DMA mode1 RX for transfers without short packets
This patch enables DMA mode1 for the RX path when we know there won't be any short packets. We check that by looking into the short_no_ok flag, if it's true we enable mode1, otherwise we use mode0 to transfer the data. This will result in a throughput performance gain of around 40% for USB mass-storage/mtp use cases. [ balbi@ti.com : updated commit log and code comments slightly ] Signed-off-by: Anand Gadiyar <gadiyar@ti.com> Signed-off-by: Moiz Sonasath <m-sonasath@ti.com> Signed-off-by: Vikram Pandita <vikram.pandita@ti.com> Tested-by: Vikram Pandita <vikram.pandita@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/musb_gadget.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 44b331a74d58..82434dde6e99 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)
634 u16 len; 634 u16 len;
635 u16 csr = musb_readw(epio, MUSB_RXCSR); 635 u16 csr = musb_readw(epio, MUSB_RXCSR);
636 struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; 636 struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
637 u8 use_mode_1;
637 638
638 if (hw_ep->is_shared_fifo) 639 if (hw_ep->is_shared_fifo)
639 musb_ep = &hw_ep->ep_in; 640 musb_ep = &hw_ep->ep_in;
@@ -683,6 +684,18 @@ static void rxstate(struct musb *musb, struct musb_request *req)
683 684
684 if (csr & MUSB_RXCSR_RXPKTRDY) { 685 if (csr & MUSB_RXCSR_RXPKTRDY) {
685 len = musb_readw(epio, MUSB_RXCOUNT); 686 len = musb_readw(epio, MUSB_RXCOUNT);
687
688 /*
689 * Enable Mode 1 on RX transfers only when short_not_ok flag
690 * is set. Currently short_not_ok flag is set only from
691 * file_storage and f_mass_storage drivers
692 */
693
694 if (request->short_not_ok && len == musb_ep->packet_sz)
695 use_mode_1 = 1;
696 else
697 use_mode_1 = 0;
698
686 if (request->actual < request->length) { 699 if (request->actual < request->length) {
687#ifdef CONFIG_USB_INVENTRA_DMA 700#ifdef CONFIG_USB_INVENTRA_DMA
688 if (is_buffer_mapped(req)) { 701 if (is_buffer_mapped(req)) {
@@ -714,37 +727,41 @@ static void rxstate(struct musb *musb, struct musb_request *req)
714 * then becomes usable as a runtime "use mode 1" hint... 727 * then becomes usable as a runtime "use mode 1" hint...
715 */ 728 */
716 729
717 csr |= MUSB_RXCSR_DMAENAB; 730 /* Experimental: Mode1 works with mass storage use cases */
718#ifdef USE_MODE1 731 if (use_mode_1) {
719 csr |= MUSB_RXCSR_AUTOCLEAR;
720 /* csr |= MUSB_RXCSR_DMAMODE; */
721
722 /* this special sequence (enabling and then
723 * disabling MUSB_RXCSR_DMAMODE) is required
724 * to get DMAReq to activate
725 */
726 musb_writew(epio, MUSB_RXCSR,
727 csr | MUSB_RXCSR_DMAMODE);
728#else
729 if (!musb_ep->hb_mult &&
730 musb_ep->hw_ep->rx_double_buffered)
731 csr |= MUSB_RXCSR_AUTOCLEAR; 732 csr |= MUSB_RXCSR_AUTOCLEAR;
732#endif 733 musb_writew(epio, MUSB_RXCSR, csr);
733 musb_writew(epio, MUSB_RXCSR, csr); 734 csr |= MUSB_RXCSR_DMAENAB;
735 musb_writew(epio, MUSB_RXCSR, csr);
736
737 /*
738 * this special sequence (enabling and then
739 * disabling MUSB_RXCSR_DMAMODE) is required
740 * to get DMAReq to activate
741 */
742 musb_writew(epio, MUSB_RXCSR,
743 csr | MUSB_RXCSR_DMAMODE);
744 musb_writew(epio, MUSB_RXCSR, csr);
745
746 } else {
747 if (!musb_ep->hb_mult &&
748 musb_ep->hw_ep->rx_double_buffered)
749 csr |= MUSB_RXCSR_AUTOCLEAR;
750 csr |= MUSB_RXCSR_DMAENAB;
751 musb_writew(epio, MUSB_RXCSR, csr);
752 }
734 753
735 if (request->actual < request->length) { 754 if (request->actual < request->length) {
736 int transfer_size = 0; 755 int transfer_size = 0;
737#ifdef USE_MODE1 756 if (use_mode_1) {
738 transfer_size = min(request->length - request->actual, 757 transfer_size = min(request->length - request->actual,
739 channel->max_len); 758 channel->max_len);
740#else
741 transfer_size = min(request->length - request->actual,
742 (unsigned)len);
743#endif
744 if (transfer_size <= musb_ep->packet_sz)
745 musb_ep->dma->desired_mode = 0;
746 else
747 musb_ep->dma->desired_mode = 1; 759 musb_ep->dma->desired_mode = 1;
760 } else {
761 transfer_size = min(request->length - request->actual,
762 (unsigned)len);
763 musb_ep->dma->desired_mode = 0;
764 }
748 765
749 use_dma = c->channel_program( 766 use_dma = c->channel_program(
750 channel, 767 channel,