linux-omap 2.6.39: add MUSB patch to improve mass storage performance
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-omap-2.6.39 / musb / 0001-usb-musb-Enable-DMA-mode1-RX-for-USB-Mass-Storage.patch
1 From 2adb339e4988632379971febe5696f21d05c71f2 Mon Sep 17 00:00:00 2001
2 From: Anand Gadiyar <gadiyar@ti.com>
3 Date: Tue, 19 Jul 2011 01:52:14 -0700
4 Subject: [PATCH] usb: musb: Enable DMA mode1 RX for USB-Mass-Storage
6 This patch enables the DMA mode1 RX support.
7 This feature is enabled based on the short_not_ok flag passed from
8 gadget drivers.
10 This will result in a thruput performance gain of around
11 40% for USB mass-storage/mtp use cases.
13 Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
14 Signed-off-by: Moiz Sonasath <m-sonasath@ti.com>
15 Tested-by: Vikram Pandita <vikram.pandita@ti.com>
16 Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
17 ---
18  drivers/usb/musb/musb_gadget.c |   68 ++++++++++++++++++++++++---------------
19  1 files changed, 42 insertions(+), 26 deletions(-)
21 diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
22 index f47c201..ca32c63 100644
23 --- a/drivers/usb/musb/musb_gadget.c
24 +++ b/drivers/usb/musb/musb_gadget.c
25 @@ -630,6 +630,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
26         u16                     len;
27         u16                     csr = musb_readw(epio, MUSB_RXCSR);
28         struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
29 +       u8                      use_mode_1;
30  
31         if (hw_ep->is_shared_fifo)
32                 musb_ep = &hw_ep->ep_in;
33 @@ -679,6 +680,18 @@ static void rxstate(struct musb *musb, struct musb_request *req)
34  
35         if (csr & MUSB_RXCSR_RXPKTRDY) {
36                 len = musb_readw(epio, MUSB_RXCOUNT);
37 +
38 +               /*
39 +                * Enable Mode 1 for RX transfers only for mass-storage
40 +                * use-case, based on short_not_ok flag which is set only
41 +                * from file_storage and f_mass_storage drivers
42 +                */
43 +
44 +               if (request->short_not_ok && len == musb_ep->packet_sz)
45 +                       use_mode_1 = 1;
46 +               else
47 +                       use_mode_1 = 0;
48 +
49                 if (request->actual < request->length) {
50  #ifdef CONFIG_USB_INVENTRA_DMA
51                         if (is_buffer_mapped(req)) {
52 @@ -710,37 +723,40 @@ static void rxstate(struct musb *musb, struct musb_request *req)
53          * then becomes usable as a runtime "use mode 1" hint...
54          */
55  
56 -                               csr |= MUSB_RXCSR_DMAENAB;
57 -#ifdef USE_MODE1
58 -                               csr |= MUSB_RXCSR_AUTOCLEAR;
59 -                               /* csr |= MUSB_RXCSR_DMAMODE; */
60 -
61 -                               /* this special sequence (enabling and then
62 -                                * disabling MUSB_RXCSR_DMAMODE) is required
63 -                                * to get DMAReq to activate
64 -                                */
65 -                               musb_writew(epio, MUSB_RXCSR,
66 -                                       csr | MUSB_RXCSR_DMAMODE);
67 -#else
68 -                               if (!musb_ep->hb_mult &&
69 -                                       musb_ep->hw_ep->rx_double_buffered)
70 +                               /* Experimental: Mode1 works with mass storage use cases */
71 +                               if (use_mode_1) {
72                                         csr |= MUSB_RXCSR_AUTOCLEAR;
73 -#endif
74 -                               musb_writew(epio, MUSB_RXCSR, csr);
75 +                                       musb_writew(epio, MUSB_RXCSR, csr);
76 +                                       csr |= MUSB_RXCSR_DMAENAB;
77 +                                       musb_writew(epio, MUSB_RXCSR, csr);
78 +
79 +                                       /* this special sequence (enabling and then
80 +                                       * disabling MUSB_RXCSR_DMAMODE) is required
81 +                                       * to get DMAReq to activate
82 +                                       */
83 +                                       musb_writew(epio, MUSB_RXCSR,
84 +                                               csr | MUSB_RXCSR_DMAMODE);
85 +                                       musb_writew(epio, MUSB_RXCSR, csr);
86 +
87 +                               } else {
88 +                                       if (!musb_ep->hb_mult &&
89 +                                               musb_ep->hw_ep->rx_double_buffered)
90 +                                               csr |= MUSB_RXCSR_AUTOCLEAR;
91 +                                       csr |= MUSB_RXCSR_DMAENAB;
92 +                                       musb_writew(epio, MUSB_RXCSR, csr);
93 +                               }
94  
95                                 if (request->actual < request->length) {
96                                         int transfer_size = 0;
97 -#ifdef USE_MODE1
98 -                                       transfer_size = min(request->length - request->actual,
99 -                                                       channel->max_len);
100 -#else
101 -                                       transfer_size = min(request->length - request->actual,
102 -                                                       (unsigned)len);
103 -#endif
104 -                                       if (transfer_size <= musb_ep->packet_sz)
105 -                                               musb_ep->dma->desired_mode = 0;
106 -                                       else
107 +                                       if (use_mode_1) {
108 +                                               transfer_size = min(request->length - request->actual,
109 +                                                               channel->max_len);
110                                                 musb_ep->dma->desired_mode = 1;
111 +                                       } else {
112 +                                               transfer_size = min(request->length - request->actual,
113 +                                                               (unsigned)len);
114 +                                               musb_ep->dma->desired_mode = 0;
115 +                                       }
116  
117                                         use_dma = c->channel_program(
118                                                         channel,
119 -- 
120 1.6.6.1