]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/usb/musb/musbhsdma.c
Merge branch 'master' of /home/git/linux-omap-2.6
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / musbhsdma.c
1 /******************************************************************
2  * Copyright 2005 Mentor Graphics Corporation
3  * Copyright (C) 2005-2006 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  * DMA implementation for high-speed controllers.
36  */
37
38 #include "musbdefs.h"
39
40
41 /****************************** CONSTANTS ********************************/
42
43 #define MGC_O_HSDMA_BASE    0x200
44 #define MGC_O_HSDMA_INTR    0x200
45
46 #define MGC_O_HSDMA_CONTROL 4
47 #define MGC_O_HSDMA_ADDRESS 8
48 #define MGC_O_HSDMA_COUNT   0xc
49
50 #define MGC_HSDMA_CHANNEL_OFFSET(_bChannel, _bOffset)           \
51                 (MGC_O_HSDMA_BASE + (_bChannel << 4) + _bOffset)
52
53 /* control register (16-bit): */
54 #define MGC_S_HSDMA_ENABLE      0
55 #define MGC_S_HSDMA_TRANSMIT    1
56 #define MGC_S_HSDMA_MODE1       2
57 #define MGC_S_HSDMA_IRQENABLE   3
58 #define MGC_S_HSDMA_ENDPOINT    4
59 #define MGC_S_HSDMA_BUSERROR    8
60 #define MGC_S_HSDMA_BURSTMODE   9
61 #define MGC_M_HSDMA_BURSTMODE   (3 << MGC_S_HSDMA_BURSTMODE)
62 #define MGC_HSDMA_BURSTMODE_UNSPEC  0
63 #define MGC_HSDMA_BURSTMODE_INCR4   1
64 #define MGC_HSDMA_BURSTMODE_INCR8   2
65 #define MGC_HSDMA_BURSTMODE_INCR16  3
66
67 #define MGC_HSDMA_CHANNELS 8
68
69 /******************************* Types ********************************/
70
71 struct _MGC_HsDmaController;
72
73 typedef struct {
74         struct dma_channel Channel;
75         struct _MGC_HsDmaController *pController;
76         u32 dwStartAddress;
77         u32 dwCount;
78         u8 bIndex;
79         u8 bEnd;
80         u8 bTransmit;
81 } MGC_HsDmaChannel;
82
83 struct hsdma {
84         struct dma_controller Controller;
85         MGC_HsDmaChannel aChannel[MGC_HSDMA_CHANNELS];
86         void *pDmaPrivate;
87         void __iomem *pCoreBase;
88         u8 bChannelCount;
89         u8 bmUsedChannels;
90 };
91
92 /* FIXME remove typedef noise */
93 typedef struct hsdma MGC_HsDmaController;
94
95 /****************************** FUNCTIONS ********************************/
96
97 static int MGC_HsDmaStartController(struct dma_controller *c)
98 {
99         /* nothing to do */
100         return 0;
101 }
102
103 static int MGC_HsDmaStopController(struct dma_controller *c)
104 {
105         /* nothing to do */
106         return 0;
107 }
108
109 static struct dma_channel *MGC_HsDmaAllocateChannel(
110                 struct dma_controller *c,
111                 struct musb_hw_ep *hw_ep,
112                 u8 bTransmit)
113 {
114         u8 bBit;
115         struct dma_channel *pChannel = NULL;
116         MGC_HsDmaChannel *pImplChannel = NULL;
117         MGC_HsDmaController *pController;
118
119         pcontroller = container_of(c, struct hsdma, Controller);
120         for (bBit = 0; bBit < MGC_HSDMA_CHANNELS; bBit++) {
121                 if (!(pController->bmUsedChannels & (1 << bBit))) {
122                         pController->bmUsedChannels |= (1 << bBit);
123                         pImplChannel = &(pController->aChannel[bBit]);
124                         pImplChannel->pController = pController;
125                         pImplChannel->bIndex = bBit;
126                         pImplChannel->bEnd = hw_ep->bLocalEnd;
127                         pImplChannel->bTransmit = bTransmit;
128                         pChannel = &(pImplChannel->Channel);
129                         pChannel->pPrivateData = pImplChannel;
130                         pChannel->bStatus = MGC_DMA_STATUS_FREE;
131                         pChannel->dwMaxLength = 0x10000;
132                         /* Tx => mode 1; Rx => mode 0 */
133                         pChannel->bDesiredMode = bTransmit;
134                         pChannel->dwActualLength = 0;
135                         break;
136                 }
137         }
138         return pChannel;
139 }
140
141 static void MGC_HsDmaReleaseChannel(struct dma_channel *pChannel)
142 {
143         MGC_HsDmaChannel *pImplChannel =
144             (MGC_HsDmaChannel *) pChannel->pPrivateData;
145
146         pImplChannel->pController->bmUsedChannels &=
147             ~(1 << pImplChannel->bIndex);
148         pChannel->bStatus = MGC_DMA_STATUS_FREE;
149 }
150
151 static void clear_state(struct dma_channel *pChannel)
152 {
153         MGC_HsDmaChannel *pImplChannel =
154             (MGC_HsDmaChannel *) pChannel->pPrivateData;
155         MGC_HsDmaController *pController = pImplChannel->pController;
156         u8 *pBase = pController->pCoreBase;
157         u8 bChannel = pImplChannel->bIndex;
158
159         musb_writew(pBase,
160                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_CONTROL),
161                     0);
162         musb_writel(pBase,
163                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_ADDRESS),
164                     0);
165         musb_writel(pBase,
166                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_COUNT),
167                     0);
168
169         pChannel->dwActualLength = 0L;
170         pImplChannel->dwStartAddress = 0;
171         pImplChannel->dwCount = 0;
172 }
173
174 static u8 configure_channel(struct dma_channel *pChannel,
175                                   u16 wPacketSize, u8 bMode,
176                                   dma_addr_t dma_addr, u32 dwLength)
177 {
178         MGC_HsDmaChannel *pImplChannel =
179             (MGC_HsDmaChannel *) pChannel->pPrivateData;
180         MGC_HsDmaController *pController = pImplChannel->pController;
181         u8 *pBase = pController->pCoreBase;
182         u8 bChannel = pImplChannel->bIndex;
183         u16 wCsr = 0;
184
185         DBG(2, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
186             pChannel, wPacketSize, dma_addr, dwLength, bMode);
187
188         if (bMode) {
189                 wCsr |= 1 << MGC_S_HSDMA_MODE1;
190                 if (dwLength < wPacketSize) {
191                         return FALSE;
192                 }
193                 if (wPacketSize >= 64) {
194                         wCsr |=
195                             MGC_HSDMA_BURSTMODE_INCR16 << MGC_S_HSDMA_BURSTMODE;
196                 } else if (wPacketSize >= 32) {
197                         wCsr |=
198                             MGC_HSDMA_BURSTMODE_INCR8 << MGC_S_HSDMA_BURSTMODE;
199                 } else if (wPacketSize >= 16) {
200                         wCsr |=
201                             MGC_HSDMA_BURSTMODE_INCR4 << MGC_S_HSDMA_BURSTMODE;
202                 }
203         }
204
205         wCsr |= (pImplChannel->bEnd << MGC_S_HSDMA_ENDPOINT)
206                 | (1 << MGC_S_HSDMA_ENABLE)
207                 | (1 << MGC_S_HSDMA_IRQENABLE)
208                 | (pImplChannel->bTransmit ? (1 << MGC_S_HSDMA_TRANSMIT) : 0);
209
210         /* address/count */
211         musb_writel(pBase,
212                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_ADDRESS),
213                     dma_addr);
214         musb_writel(pBase,
215                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_COUNT),
216                     dwLength);
217
218         /* control (this should start things) */
219         musb_writew(pBase,
220                     MGC_HSDMA_CHANNEL_OFFSET(bChannel, MGC_O_HSDMA_CONTROL),
221                     wCsr);
222
223         return TRUE;
224 }
225
226 static int MGC_HsDmaProgramChannel(struct dma_channel * pChannel,
227                                   u16 wPacketSize, u8 bMode,
228                                   dma_addr_t dma_addr, u32 dwLength)
229 {
230         MGC_HsDmaChannel *pImplChannel =
231             (MGC_HsDmaChannel *) pChannel->pPrivateData;
232
233         DBG(2, "pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
234                wPacketSize, dma_addr, dwLength, bMode);
235
236         BUG_ON(pChannel->bStatus != MGC_DMA_STATUS_FREE);
237
238         pChannel->dwActualLength = 0L;
239         pImplChannel->dwStartAddress = dma_addr;
240         pImplChannel->dwCount = dwLength;
241
242         pChannel->bStatus = MGC_DMA_STATUS_BUSY;
243
244         if ((bMode == 1) && (dwLength >= wPacketSize)) {
245
246 #if 0
247                 /* mode 1 sends an extra IN token at the end of
248                  * full packet transfer in host Rx
249                  */
250                 if (dwLength % wPacketSize == 0)
251                         dwLength -= wPacketSize;
252
253                 /* mode 1 doesn't give an interrupt on short packet */
254                 configure_channel(pChannel, wPacketSize, 1, dma_addr,
255                                   dwLength & ~(wPacketSize - 1));
256                 /* the rest (<= pkt_size) will be transferred in mode 0 */
257 #endif
258
259                 configure_channel(pChannel, wPacketSize, 1, dma_addr,
260                                   dwLength);
261
262         } else
263                 configure_channel(pChannel, wPacketSize, 0, dma_addr,
264                                   dwLength);
265
266         return TRUE;
267 }
268
269 // REVISIT...
270 static int MGC_HsDmaAbortChannel(struct dma_channel *pChannel)
271 {
272         clear_state(pChannel);
273         pChannel->bStatus = MGC_DMA_STATUS_FREE;
274         return 0;
275 }
276
277 static irqreturn_t
278 hsdma_irq(int irq, void *pPrivateData, struct pt_regs *regs)
279 {
280         u8 bChannel;
281         u16 wCsr;
282         u32 dwAddress;
283         MGC_HsDmaChannel *pImplChannel;
284         MGC_HsDmaController *pController = pPrivateData;
285         u8 *pBase = pController->pCoreBase;
286         struct dma_channel *pChannel;
287         u8 bIntr = musb_readb(pBase, MGC_O_HSDMA_INTR);
288
289         if (!bIntr)
290                 return IRQ_NONE;
291
292         for (bChannel = 0; bChannel < MGC_HSDMA_CHANNELS; bChannel++) {
293                 if (bIntr & (1 << bChannel)) {
294
295                         pImplChannel = (MGC_HsDmaChannel *)
296                                         &(pController->aChannel[bChannel]);
297                         pChannel = &pImplChannel->Channel;
298
299                         wCsr = musb_readw(pBase,
300                                        MGC_HSDMA_CHANNEL_OFFSET(bChannel,
301                                                         MGC_O_HSDMA_CONTROL));
302
303                         if (wCsr & (1 << MGC_S_HSDMA_BUSERROR)) {
304                                 pImplChannel->Channel.bStatus =
305                                     MGC_DMA_STATUS_BUS_ABORT;
306                         } else {
307                                 dwAddress = musb_readl(pBase,
308                                                        MGC_HSDMA_CHANNEL_OFFSET
309                                                        (bChannel,
310                                                         MGC_O_HSDMA_ADDRESS));
311                                 pChannel->dwActualLength =
312                                     dwAddress - pImplChannel->dwStartAddress;
313
314                                 DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
315                                     pChannel, pImplChannel->dwStartAddress,
316                                     dwAddress, pChannel->dwActualLength,
317                                     pImplChannel->dwCount,
318                                     (pChannel->dwActualLength <
319                                         pImplChannel->dwCount) ?
320                                         "=> reconfig 0": "=> complete");
321 #if 0
322                                 if (pChannel->dwActualLength <
323                                     pImplChannel->dwCount) {
324                                         /* mode 1 sends an extra IN request if
325                                         the last packet is a complete packet */
326                                         u16 newcsr = MGC_ReadCsr16(pBase,
327                                                         MGC_O_HDRC_RXCSR,
328                                                         pImplChannel->bEnd);
329                                         newcsr &= ~(MGC_M_RXCSR_H_AUTOREQ |
330                                                     MGC_M_RXCSR_H_REQPKT);
331                                         MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR,
332                                                        pImplChannel->bEnd,
333                                                        MGC_M_RXCSR_H_WZC_BITS |
334                                                                 newcsr);
335
336                                         configure_channel(pChannel,
337                                                 pImplChannel->wMaxPacketSize,
338                                                 0, dwAddress,
339                                                 pImplChannel->dwCount -
340                                                     pChannel->dwActualLength);
341                                 }
342                                 else
343 #endif
344                                 {
345                                         pChannel->bStatus = MGC_DMA_STATUS_FREE;
346                                         /* completed */
347                                         musb_dma_completion(
348                                                 pController->pDmaPrivate,
349                                                 pImplChannel->bEnd,
350                                                 pImplChannel->bTransmit);
351                                 }
352                         }
353                 }
354         }
355         return IRQ_HANDLED;
356 }
357
358 static void hsdma_controller_destroy(struct dma_controller *pController)
359 {
360         MGC_HsDmaController *pHsController = pController->pPrivateData;
361
362         if (pHsController) {
363                 pHsController->Controller.pPrivateData = NULL;
364                 kfree(pHsController);
365         }
366 }
367
368 static struct dma_controller *
369 hsdma_controller_new(struct musb *pThis, void __iomem *pCoreBase)
370 {
371         MGC_HsDmaController *pController;
372         struct device *dev = pThis->controller;
373         struct platform_device *pdev = to_platform_device(dev);
374         int irq = platform_get_irq(pdev, 1);
375
376         if (irq == 0) {
377                 dev_err(dev, "No DMA interrupt line!\n");
378                 return NULL;
379         }
380
381         if (!(pController = kzalloc(sizeof(MGC_HsDmaController), GFP_KERNEL)))
382                 return NULL;
383
384         pController->bChannelCount = MGC_HSDMA_CHANNELS;
385         pController->pDmaPrivate = pThis;
386         pController->pCoreBase = pCoreBase;
387
388         pController->Controller.pPrivateData = pController;
389         pController->Controller.start = MGC_HsDmaStartController;
390         pController->Controller.stop = MGC_HsDmaStopController;
391         pController->Controller.channel_alloc = MGC_HsDmaAllocateChannel;
392         pController->Controller.channel_release = MGC_HsDmaReleaseChannel;
393         pController->Controller.channel_program = MGC_HsDmaProgramChannel;
394         pController->Controller.channel_abort = MGC_HsDmaAbortChannel;
395
396         if (request_irq(irq, hsdma_irq, SA_INTERRUPT,
397                         pThis->controller->bus_id, &pController->Controller)) {
398                 dev_err(dev, "request_irq %d failed!\n", irq);
399                 hsdma_controller_destroy(&pController->Controller);
400                 return NULL;
401         }
402
403         return &pController->Controller;
404 }
405
406 const struct dma_controller_factory dma_controller_factory = {
407         .create =       hsdma_controller_new,
408         .destroy =      hsdma_controller_destroy,
409 };