]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/usb/musb/musbhsdma.c
Merge omap-upstream
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / musbhsdma.c
1 /******************************************************************
2  * Copyright 2005 Mentor Graphics Corporation
3  * Copyright (C) 2005-2007 by Texas Instruments
4  *
5  * This file is part of the Inventra Controller Driver for Linux.
6  *
7  * The Inventra Controller Driver for Linux is free software; you
8  * can redistribute it and/or modify it under the terms of the GNU
9  * General Public License version 2 as published by the Free Software
10  * Foundation.
11  *
12  * The Inventra Controller Driver for Linux is distributed in
13  * the hope that it will be useful, but WITHOUT ANY WARRANTY;
14  * without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with The Inventra Controller Driver for Linux ; if not,
20  * write to the Free Software Foundation, Inc., 59 Temple Place,
21  * Suite 330, Boston, MA  02111-1307  USA
22  *
23  * ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
24  * OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
25  * OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
26  * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
27  * MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
28  * OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
29  * NON-INFRINGEMENT.  MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
30  * SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
31  * GRAPHICS SUPPORT CUSTOMER.
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, _bOffset)           \
54                 (MGC_O_HSDMA_BASE + (_bChannel << 4) + _bOffset)
55
56 /* control register (16-bit): */
57 #define MGC_S_HSDMA_ENABLE              0
58 #define MGC_S_HSDMA_TRANSMIT            1
59 #define MGC_S_HSDMA_MODE1               2
60 #define MGC_S_HSDMA_IRQENABLE           3
61 #define MGC_S_HSDMA_ENDPOINT            4
62 #define MGC_S_HSDMA_BUSERROR            8
63 #define MGC_S_HSDMA_BURSTMODE           9
64 #define MGC_M_HSDMA_BURSTMODE           (3 << MGC_S_HSDMA_BURSTMODE)
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      *pController;
77         u32                             dwStartAddress;
78         u32                             dwCount;
79         u16                             wMaxPacketSize;
80         u8                              bIndex;
81         u8                              bEnd;
82         u8                              bTransmit;
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 *pController =
106                 container_of(c, struct musb_dma_controller, Controller);
107         struct musb *pThis = (struct musb *) pController->pDmaPrivate;
108         struct dma_channel *pChannel;
109         u8 bBit;
110
111         if (pController->bmUsedChannels != 0) {
112                 dev_err(pThis->controller,
113                         "Stopping DMA controller while channel active\n");
114
115                 for (bBit = 0; bBit < MGC_HSDMA_CHANNELS; bBit++) {
116                         if (pController->bmUsedChannels & (1 << bBit)) {
117                                 pChannel = &(pController->aChannel[bBit].Channel);
118                                 dma_channel_release(pChannel);
119
120                                 if (!pController->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 bTransmit)
130 {
131         u8 bBit;
132         struct dma_channel *pChannel = NULL;
133         struct musb_dma_channel *pImplChannel = NULL;
134         struct musb_dma_controller *pController =
135                         container_of(c, struct musb_dma_controller, Controller);
136
137         for (bBit = 0; bBit < MGC_HSDMA_CHANNELS; bBit++) {
138                 if (!(pController->bmUsedChannels & (1 << bBit))) {
139                         pController->bmUsedChannels |= (1 << bBit);
140                         pImplChannel = &(pController->aChannel[bBit]);
141                         pImplChannel->pController = pController;
142                         pImplChannel->bIndex = bBit;
143                         pImplChannel->bEnd = hw_ep->bLocalEnd;
144                         pImplChannel->bTransmit = bTransmit;
145                         pChannel = &(pImplChannel->Channel);
146                         pChannel->pPrivateData = pImplChannel;
147                         pChannel->bStatus = MGC_DMA_STATUS_FREE;
148                         pChannel->dwMaxLength = 0x10000;
149                         /* Tx => mode 1; Rx => mode 0 */
150                         pChannel->bDesiredMode = bTransmit;
151                         pChannel->dwActualLength = 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->pPrivateData;
162
163         pChannel->dwActualLength = 0;
164         pImplChannel->dwStartAddress = 0;
165         pImplChannel->dwCount = 0;
166
167         pImplChannel->pController->bmUsedChannels &=
168                 ~(1 << pImplChannel->bIndex);
169
170         pChannel->bStatus = MGC_DMA_STATUS_UNKNOWN;
171 }
172
173 static void configure_channel(struct dma_channel *pChannel,
174                                 u16 wPacketSize, u8 bMode,
175                                 dma_addr_t dma_addr, u32 dwLength)
176 {
177         struct musb_dma_channel *pImplChannel =
178                 (struct musb_dma_channel *) pChannel->pPrivateData;
179         struct musb_dma_controller *pController = pImplChannel->pController;
180         u8 *pBase = pController->pCoreBase;
181         u8 bChannel = pImplChannel->bIndex;
182         u16 wCsr = 0;
183
184         DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
185             pChannel, wPacketSize, dma_addr, dwLength, bMode);
186
187         if (bMode) {
188                 wCsr |= 1 << MGC_S_HSDMA_MODE1;
189                 if (dwLength < wPacketSize) {
190                         return FALSE;
191                 }
192                 if (wPacketSize >= 64) {
193                         wCsr |=
194                             MGC_HSDMA_BURSTMODE_INCR16 << MGC_S_HSDMA_BURSTMODE;
195                 } else if (wPacketSize >= 32) {
196                         wCsr |=
197                             MGC_HSDMA_BURSTMODE_INCR8 << MGC_S_HSDMA_BURSTMODE;
198                 } else if (wPacketSize >= 16) {
199                         wCsr |=
200                             MGC_HSDMA_BURSTMODE_INCR4 << MGC_S_HSDMA_BURSTMODE;
201                 }
202         }
203
204         wCsr |= (pImplChannel->bEnd << MGC_S_HSDMA_ENDPOINT)
205                 | (1 << MGC_S_HSDMA_ENABLE)
206                 | (1 << MGC_S_HSDMA_IRQENABLE)
207                 | (pImplChannel->bTransmit ? (1 << MGC_S_HSDMA_TRANSMIT) : 0);
208
209         /* address/count */
210         musb_writel(pBase,
211                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_ADDRESS),
212                     dma_addr);
213         musb_writel(pBase,
214                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_COUNT),
215                     dwLength);
216
217         /* control (this should start things) */
218         musb_writew(pBase,
219                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_CONTROL),
220                     wCsr);
221 }
222
223 static int dma_channel_program(struct dma_channel * pChannel,
224                                 u16 wPacketSize, u8 bMode,
225                                 dma_addr_t dma_addr, u32 dwLength)
226 {
227         struct musb_dma_channel *pImplChannel =
228                         (struct musb_dma_channel *) pChannel->pPrivateData;
229
230         DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
231                 pImplChannel->bEnd,
232                 pImplChannel->bTransmit ? "Tx" : "Rx",
233                 wPacketSize, dma_addr, dwLength, bMode);
234
235         BUG_ON(pChannel->bStatus == MGC_DMA_STATUS_UNKNOWN ||
236                 pChannel->bStatus == MGC_DMA_STATUS_BUSY);
237
238         pChannel->dwActualLength = 0;
239         pImplChannel->dwStartAddress = dma_addr;
240         pImplChannel->dwCount = dwLength;
241         pImplChannel->wMaxPacketSize = wPacketSize;
242         pChannel->bStatus = MGC_DMA_STATUS_BUSY;
243
244         if ((bMode == 1) && (dwLength >= wPacketSize)) {
245                 configure_channel(pChannel, wPacketSize, 1, dma_addr,
246                                   dwLength);
247         } else
248                 configure_channel(pChannel, wPacketSize, 0, dma_addr,
249                                   dwLength);
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->pPrivateData;
258         u8 bChannel = pImplChannel->bIndex;
259         u8 *pBase = pImplChannel->pController->pCoreBase;
260         u16 csr;
261
262         if (pChannel->bStatus == MGC_DMA_STATUS_BUSY) {
263                 if (pImplChannel->bTransmit) {
264
265                         csr = musb_readw(pBase,
266                                 MGC_END_OFFSET(pImplChannel->bEnd,MGC_O_HDRC_TXCSR));
267                         csr &= ~(MGC_M_TXCSR_AUTOSET |
268                                  MGC_M_TXCSR_DMAENAB |
269                                  MGC_M_TXCSR_DMAMODE);
270                         musb_writew(pBase,
271                                         MGC_END_OFFSET(pImplChannel->bEnd,MGC_O_HDRC_TXCSR),
272                                         csr);
273                 }
274                 else {
275                         csr = musb_readw(pBase,
276                                 MGC_END_OFFSET(pImplChannel->bEnd,MGC_O_HDRC_RXCSR));
277                         csr &= ~(MGC_M_RXCSR_AUTOCLEAR |
278                                  MGC_M_RXCSR_DMAENAB |
279                                  MGC_M_RXCSR_DMAMODE);
280                         musb_writew(pBase,
281                                         MGC_END_OFFSET(pImplChannel->bEnd,MGC_O_HDRC_RXCSR),
282                                         csr);
283                 }
284
285                 musb_writew(pBase,
286                    MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_CONTROL), 0);
287                 musb_writel(pBase,
288                    MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_ADDRESS), 0);
289                 musb_writel(pBase,
290                    MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_COUNT), 0);
291
292                 pChannel->bStatus = MGC_DMA_STATUS_FREE;
293         }
294         return 0;
295 }
296
297 static irqreturn_t dma_controller_irq(int irq, void *pPrivateData)
298 {
299         struct musb_dma_controller *pController =
300                 (struct musb_dma_controller *)pPrivateData;
301         struct musb_dma_channel *pImplChannel;
302         u8 *pBase = pController->pCoreBase;
303         struct dma_channel *pChannel;
304         u8 bChannel;
305         u16 wCsr;
306         u32 dwAddress;
307         u8 bIntr;
308         irqreturn_t retval = IRQ_NONE;
309
310         bIntr = musb_readb(pBase, MGC_O_HSDMA_INTR);
311         if (!bIntr)
312                 goto done;
313
314         for (bChannel = 0; bChannel < MGC_HSDMA_CHANNELS; bChannel++) {
315                 if (bIntr & (1 << bChannel)) {
316                         pImplChannel = (struct musb_dma_channel *)
317                                         &(pController->aChannel[bChannel]);
318                         pChannel = &pImplChannel->Channel;
319
320                         wCsr = musb_readw(pBase,
321                                        MGC_HSDMA_CHANNEL_OFFSET(bChannel,
322                                                         MGC_O_HSDMA_CONTROL));
323
324                         if (wCsr & (1 << MGC_S_HSDMA_BUSERROR)) {
325                                 pImplChannel->Channel.bStatus =
326                                     MGC_DMA_STATUS_BUS_ABORT;
327                         } else {
328                                 dwAddress = musb_readl(pBase,
329                                                 MGC_HSDMA_CHANNEL_OFFSET(
330                                                         bChannel,
331                                                         MGC_O_HSDMA_ADDRESS));
332                                 pChannel->dwActualLength =
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->dwActualLength,
338                                     pImplChannel->dwCount,
339                                     (pChannel->dwActualLength <
340                                         pImplChannel->dwCount) ?
341                                         "=> reconfig 0": "=> complete");
342
343                                 u8 devctl = musb_readb(pBase,
344                                                 MGC_O_HDRC_DEVCTL);
345
346                                 pChannel->bStatus = MGC_DMA_STATUS_FREE;
347
348                                 /* completed */
349                                 if ((devctl & MGC_M_DEVCTL_HM)
350                                     && (pImplChannel->bTransmit)
351                                     && ((pChannel->bDesiredMode == 0)
352                                         || (pChannel->dwActualLength &
353                                             (pImplChannel->wMaxPacketSize - 1)))
354                                    ) {
355                                         /* Send out the packet */
356                                         MGC_SelectEnd(pBase,
357                                                 pImplChannel->bEnd);
358                                         musb_writew(pBase,
359                                                 MGC_END_OFFSET(pImplChannel->bEnd,MGC_O_HDRC_TXCSR),
360                                                 MGC_M_TXCSR_TXPKTRDY);
361                                 } else
362                                         musb_dma_completion(
363                                                 pController->pDmaPrivate,
364                                                 pImplChannel->bEnd,
365                                                 pImplChannel->bTransmit);
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 *pController =
377                 (struct musb_dma_controller *) c->pPrivateData;
378
379         if (!pController)
380                 return;
381
382         if (pController->irq)
383                 free_irq(pController->irq, c);
384
385         kfree(pController);
386         c->pPrivateData = NULL;
387 }
388
389 struct dma_controller *__init
390 dma_controller_create(struct musb *pThis, void __iomem *pCoreBase)
391 {
392         struct musb_dma_controller *pController;
393         struct device *dev = pThis->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 (!(pController = kzalloc(sizeof(struct musb_dma_controller),
403                                 GFP_KERNEL)))
404                 return NULL;
405
406         pController->bChannelCount = MGC_HSDMA_CHANNELS;
407         pController->pDmaPrivate = pThis;
408         pController->pCoreBase = pCoreBase;
409
410         pController->Controller.pPrivateData = pController;
411         pController->Controller.start = dma_controller_start;
412         pController->Controller.stop = dma_controller_stop;
413         pController->Controller.channel_alloc = dma_channel_allocate;
414         pController->Controller.channel_release = dma_channel_release;
415         pController->Controller.channel_program = dma_channel_program;
416         pController->Controller.channel_abort = dma_channel_abort;
417
418         if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
419                         pThis->controller->bus_id, &pController->Controller)) {
420                 dev_err(dev, "request_irq %d failed!\n", irq);
421                 dma_controller_destroy(&pController->Controller);
422                 return NULL;
423         }
424
425         pController->irq = irq;
426
427         return &pController->Controller;
428 }