]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/usb/musb/musbhsdma.c
musb_hdrc: Search and replace MGC_DMA with MUSB_DMA
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / musbhsdma.c
1 /*
2  * MUSB OTG driver internal DMA controller support
3  *
4  * Copyright 2005 Mentor Graphics Corporation
5  * Copyright (C) 2005-2007 by Texas Instruments
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA
20  *
21  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
24  * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33
34 /*
35  * Implementation for the DMA controller within the MUSBMHDRC.
36  */
37
38 #include <linux/device.h>
39 #include <linux/interrupt.h>
40 #include <linux/platform_device.h>
41 #include "musbdefs.h"
42
43 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
44 #include "omap2430.h"
45 #endif
46
47 #define MGC_O_HSDMA_BASE                0x200
48 #define MGC_O_HSDMA_INTR                (MGC_O_HSDMA_BASE + 0)
49 #define MGC_O_HSDMA_CONTROL             0x4
50 #define MGC_O_HSDMA_ADDRESS             0x8
51 #define MGC_O_HSDMA_COUNT               0xc
52
53 #define MGC_HSDMA_CHANNEL_OFFSET(_bChannel, _offset)            \
54                 (MGC_O_HSDMA_BASE + (_bChannel << 4) + _offset)
55
56 /* control register (16-bit): */
57 #define MUSB_HSDMA_ENABLE_SHIFT         0
58 #define MUSB_HSDMA_TRANSMIT_SHIFT               1
59 #define MUSB_HSDMA_MODE1_SHIFT          2
60 #define MUSB_HSDMA_IRQENABLE_SHIFT              3
61 #define MUSB_HSDMA_ENDPOINT_SHIFT               4
62 #define MUSB_HSDMA_BUSERROR_SHIFT               8
63 #define MUSB_HSDMA_BURSTMODE_SHIFT              9
64 #define MUSB_HSDMA_BURSTMODE            (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
65 #define MGC_HSDMA_BURSTMODE_UNSPEC      0
66 #define MGC_HSDMA_BURSTMODE_INCR4       1
67 #define MGC_HSDMA_BURSTMODE_INCR8       2
68 #define MGC_HSDMA_BURSTMODE_INCR16      3
69
70 #define MGC_HSDMA_CHANNELS              8
71
72 struct musb_dma_controller;
73
74 struct musb_dma_channel {
75         struct dma_channel              Channel;
76         struct musb_dma_controller      *controller;
77         u32                             dwStartAddress;
78         u32                             len;
79         u16                             wMaxPacketSize;
80         u8                              bIndex;
81         u8                              epnum;
82         u8                              transmit;
83 };
84
85 struct musb_dma_controller {
86         struct dma_controller           Controller;
87         struct musb_dma_channel         aChannel[MGC_HSDMA_CHANNELS];
88         void                            *pDmaPrivate;
89         void __iomem                    *pCoreBase;
90         u8                              bChannelCount;
91         u8                              bmUsedChannels;
92         u8                              irq;
93 };
94
95 static int dma_controller_start(struct dma_controller *c)
96 {
97         /* nothing to do */
98         return 0;
99 }
100
101 static void dma_channel_release(struct dma_channel *pChannel);
102
103 static int dma_controller_stop(struct dma_controller *c)
104 {
105         struct musb_dma_controller *controller =
106                 container_of(c, struct musb_dma_controller, Controller);
107         struct musb *musb = (struct musb *) controller->pDmaPrivate;
108         struct dma_channel *pChannel;
109         u8 bBit;
110
111         if (controller->bmUsedChannels != 0) {
112                 dev_err(musb->controller,
113                         "Stopping DMA controller while channel active\n");
114
115                 for (bBit = 0; bBit < MGC_HSDMA_CHANNELS; bBit++) {
116                         if (controller->bmUsedChannels & (1 << bBit)) {
117                                 pChannel = &(controller->aChannel[bBit].Channel);
118                                 dma_channel_release(pChannel);
119
120                                 if (!controller->bmUsedChannels)
121                                         break;
122                         }
123                 }
124         }
125         return 0;
126 }
127
128 static struct dma_channel* dma_channel_allocate(struct dma_controller *c,
129                                 struct musb_hw_ep *hw_ep, u8 transmit)
130 {
131         u8 bBit;
132         struct dma_channel *pChannel = NULL;
133         struct musb_dma_channel *pImplChannel = NULL;
134         struct musb_dma_controller *controller =
135                         container_of(c, struct musb_dma_controller, Controller);
136
137         for (bBit = 0; bBit < MGC_HSDMA_CHANNELS; bBit++) {
138                 if (!(controller->bmUsedChannels & (1 << bBit))) {
139                         controller->bmUsedChannels |= (1 << bBit);
140                         pImplChannel = &(controller->aChannel[bBit]);
141                         pImplChannel->controller = controller;
142                         pImplChannel->bIndex = bBit;
143                         pImplChannel->epnum = hw_ep->epnum;
144                         pImplChannel->transmit = transmit;
145                         pChannel = &(pImplChannel->Channel);
146                         pChannel->private_data = pImplChannel;
147                         pChannel->status = MUSB_DMA_STATUS_FREE;
148                         pChannel->max_len = 0x10000;
149                         /* Tx => mode 1; Rx => mode 0 */
150                         pChannel->desired_mode = transmit;
151                         pChannel->actual_len = 0;
152                         break;
153                 }
154         }
155         return pChannel;
156 }
157
158 static void dma_channel_release(struct dma_channel *pChannel)
159 {
160         struct musb_dma_channel *pImplChannel =
161                 (struct musb_dma_channel *) pChannel->private_data;
162
163         pChannel->actual_len = 0;
164         pImplChannel->dwStartAddress = 0;
165         pImplChannel->len = 0;
166
167         pImplChannel->controller->bmUsedChannels &=
168                 ~(1 << pImplChannel->bIndex);
169
170         pChannel->status = MUSB_DMA_STATUS_UNKNOWN;
171 }
172
173 static void configure_channel(struct dma_channel *pChannel,
174                                 u16 packet_sz, u8 mode,
175                                 dma_addr_t dma_addr, u32 len)
176 {
177         struct musb_dma_channel *pImplChannel =
178                 (struct musb_dma_channel *) pChannel->private_data;
179         struct musb_dma_controller *controller = pImplChannel->controller;
180         u8 *mbase = controller->pCoreBase;
181         u8 bChannel = pImplChannel->bIndex;
182         u16 csr = 0;
183
184         DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
185             pChannel, packet_sz, dma_addr, len, mode);
186
187         if (mode) {
188                 csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
189                 if (len < packet_sz) {
190                         return FALSE;
191                 }
192                 if (packet_sz >= 64) {
193                         csr |=
194                             MGC_HSDMA_BURSTMODE_INCR16 << MUSB_HSDMA_BURSTMODE_SHIFT;
195                 } else if (packet_sz >= 32) {
196                         csr |=
197                             MGC_HSDMA_BURSTMODE_INCR8 << MUSB_HSDMA_BURSTMODE_SHIFT;
198                 } else if (packet_sz >= 16) {
199                         csr |=
200                             MGC_HSDMA_BURSTMODE_INCR4 << MUSB_HSDMA_BURSTMODE_SHIFT;
201                 }
202         }
203
204         csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
205                 | (1 << MUSB_HSDMA_ENABLE_SHIFT)
206                 | (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
207                 | (pImplChannel->transmit ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT) : 0);
208
209         /* address/count */
210         musb_writel(mbase,
211                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_ADDRESS),
212                     dma_addr);
213         musb_writel(mbase,
214                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_COUNT),
215                     len);
216
217         /* control (this should start things) */
218         musb_writew(mbase,
219                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_CONTROL),
220                     csr);
221 }
222
223 static int dma_channel_program(struct dma_channel * pChannel,
224                                 u16 packet_sz, u8 mode,
225                                 dma_addr_t dma_addr, u32 len)
226 {
227         struct musb_dma_channel *pImplChannel =
228                         (struct musb_dma_channel *) pChannel->private_data;
229
230         DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
231                 pImplChannel->epnum,
232                 pImplChannel->transmit ? "Tx" : "Rx",
233                 packet_sz, dma_addr, len, mode);
234
235         BUG_ON(pChannel->status == MUSB_DMA_STATUS_UNKNOWN ||
236                 pChannel->status == MUSB_DMA_STATUS_BUSY);
237
238         pChannel->actual_len = 0;
239         pImplChannel->dwStartAddress = dma_addr;
240         pImplChannel->len = len;
241         pImplChannel->wMaxPacketSize = packet_sz;
242         pChannel->status = MUSB_DMA_STATUS_BUSY;
243
244         if ((mode == 1) && (len >= packet_sz)) {
245                 configure_channel(pChannel, packet_sz, 1, dma_addr,
246                                   len);
247         } else
248                 configure_channel(pChannel, packet_sz, 0, dma_addr,
249                                   len);
250
251         return TRUE;
252 }
253
254 static int dma_channel_abort(struct dma_channel *pChannel)
255 {
256         struct musb_dma_channel *pImplChannel =
257                 (struct musb_dma_channel *) pChannel->private_data;
258         u8 bChannel = pImplChannel->bIndex;
259         u8 *mbase = pImplChannel->controller->pCoreBase;
260         u16 csr;
261
262         if (pChannel->status == MUSB_DMA_STATUS_BUSY) {
263                 if (pImplChannel->transmit) {
264
265                         csr = musb_readw(mbase,
266                                 MGC_END_OFFSET(pImplChannel->epnum,MUSB_TXCSR));
267                         csr &= ~(MUSB_TXCSR_AUTOSET |
268                                  MUSB_TXCSR_DMAENAB |
269                                  MUSB_TXCSR_DMAMODE);
270                         musb_writew(mbase,
271                                         MGC_END_OFFSET(pImplChannel->epnum,MUSB_TXCSR),
272                                         csr);
273                 }
274                 else {
275                         csr = musb_readw(mbase,
276                                 MGC_END_OFFSET(pImplChannel->epnum,MUSB_RXCSR));
277                         csr &= ~(MUSB_RXCSR_AUTOCLEAR |
278                                  MUSB_RXCSR_DMAENAB |
279                                  MUSB_RXCSR_DMAMODE);
280                         musb_writew(mbase,
281                                         MGC_END_OFFSET(pImplChannel->epnum,MUSB_RXCSR),
282                                         csr);
283                 }
284
285                 musb_writew(mbase,
286                    MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_CONTROL), 0);
287                 musb_writel(mbase,
288                    MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_ADDRESS), 0);
289                 musb_writel(mbase,
290                    MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_COUNT), 0);
291
292                 pChannel->status = MUSB_DMA_STATUS_FREE;
293         }
294         return 0;
295 }
296
297 static irqreturn_t dma_controller_irq(int irq, void *private_data)
298 {
299         struct musb_dma_controller *controller =
300                 (struct musb_dma_controller *)private_data;
301         struct musb_dma_channel *pImplChannel;
302         u8 *mbase = controller->pCoreBase;
303         struct dma_channel *pChannel;
304         u8 bChannel;
305         u16 csr;
306         u32 dwAddress;
307         u8 int_hsdma;
308         irqreturn_t retval = IRQ_NONE;
309
310         int_hsdma = musb_readb(mbase, MGC_O_HSDMA_INTR);
311         if (!int_hsdma)
312                 goto done;
313
314         for (bChannel = 0; bChannel < MGC_HSDMA_CHANNELS; bChannel++) {
315                 if (int_hsdma & (1 << bChannel)) {
316                         pImplChannel = (struct musb_dma_channel *)
317                                         &(controller->aChannel[bChannel]);
318                         pChannel = &pImplChannel->Channel;
319
320                         csr = musb_readw(mbase,
321                                        MGC_HSDMA_CHANNEL_OFFSET(bChannel,
322                                                         MGC_O_HSDMA_CONTROL));
323
324                         if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) {
325                                 pImplChannel->Channel.status =
326                                     MUSB_DMA_STATUS_BUS_ABORT;
327                         } else {
328                                 dwAddress = musb_readl(mbase,
329                                                 MGC_HSDMA_CHANNEL_OFFSET(
330                                                         bChannel,
331                                                         MGC_O_HSDMA_ADDRESS));
332                                 pChannel->actual_len =
333                                     dwAddress - pImplChannel->dwStartAddress;
334
335                                 DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
336                                     pChannel, pImplChannel->dwStartAddress,
337                                     dwAddress, pChannel->actual_len,
338                                     pImplChannel->len,
339                                     (pChannel->actual_len <
340                                         pImplChannel->len) ?
341                                         "=> reconfig 0": "=> complete");
342
343                                 u8 devctl = musb_readb(mbase,
344                                                 MUSB_DEVCTL);
345
346                                 pChannel->status = MUSB_DMA_STATUS_FREE;
347
348                                 /* completed */
349                                 if ((devctl & MUSB_DEVCTL_HM)
350                                     && (pImplChannel->transmit)
351                                     && ((pChannel->desired_mode == 0)
352                                         || (pChannel->actual_len &
353                                             (pImplChannel->wMaxPacketSize - 1)))
354                                    ) {
355                                         /* Send out the packet */
356                                         musb_ep_select(mbase,
357                                                 pImplChannel->epnum);
358                                         musb_writew(mbase,
359                                                 MGC_END_OFFSET(pImplChannel->epnum,MUSB_TXCSR),
360                                                 MUSB_TXCSR_TXPKTRDY);
361                                 } else
362                                         musb_dma_completion(
363                                                 controller->pDmaPrivate,
364                                                 pImplChannel->epnum,
365                                                 pImplChannel->transmit);
366                         }
367                 }
368         }
369         retval = IRQ_HANDLED;
370 done:
371         return retval;
372 }
373
374 void dma_controller_destroy(struct dma_controller *c)
375 {
376         struct musb_dma_controller *controller =
377                 (struct musb_dma_controller *) c->private_data;
378
379         if (!controller)
380                 return;
381
382         if (controller->irq)
383                 free_irq(controller->irq, c);
384
385         kfree(controller);
386         c->private_data = NULL;
387 }
388
389 struct dma_controller *__init
390 dma_controller_create(struct musb *musb, void __iomem *pCoreBase)
391 {
392         struct musb_dma_controller *controller;
393         struct device *dev = musb->controller;
394         struct platform_device *pdev = to_platform_device(dev);
395         int irq = platform_get_irq(pdev, 1);
396
397         if (irq == 0) {
398                 dev_err(dev, "No DMA interrupt line!\n");
399                 return NULL;
400         }
401
402         if (!(controller = kzalloc(sizeof(struct musb_dma_controller),
403                                 GFP_KERNEL)))
404                 return NULL;
405
406         controller->bChannelCount = MGC_HSDMA_CHANNELS;
407         controller->pDmaPrivate = musb;
408         controller->pCoreBase = pCoreBase;
409
410         controller->Controller.private_data = controller;
411         controller->Controller.start = dma_controller_start;
412         controller->Controller.stop = dma_controller_stop;
413         controller->Controller.channel_alloc = dma_channel_allocate;
414         controller->Controller.channel_release = dma_channel_release;
415         controller->Controller.channel_program = dma_channel_program;
416         controller->Controller.channel_abort = dma_channel_abort;
417
418         if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
419                         musb->controller->bus_id, &controller->Controller)) {
420                 dev_err(dev, "request_irq %d failed!\n", irq);
421                 dma_controller_destroy(&controller->Controller);
422                 return NULL;
423         }
424
425         controller->irq = irq;
426
427         return &controller->Controller;
428 }