]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/usb/musb/musbhsdma.c
Merge ../linux-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 hsdma_irq(int irq, void *pPrivateData)
278 {
279         u8 bChannel;
280         u16 wCsr;
281         u32 dwAddress;
282         MGC_HsDmaChannel *pImplChannel;
283         MGC_HsDmaController *pController = pPrivateData;
284         u8 *pBase = pController->pCoreBase;
285         struct dma_channel *pChannel;
286         u8 bIntr = musb_readb(pBase, MGC_O_HSDMA_INTR);
287
288         if (!bIntr)
289                 return IRQ_NONE;
290
291         for (bChannel = 0; bChannel < MGC_HSDMA_CHANNELS; bChannel++) {
292                 if (bIntr & (1 << bChannel)) {
293
294                         pImplChannel = (MGC_HsDmaChannel *)
295                                         &(pController->aChannel[bChannel]);
296                         pChannel = &pImplChannel->Channel;
297
298                         wCsr = musb_readw(pBase,
299                                        MGC_HSDMA_CHANNEL_OFFSET(bChannel,
300                                                         MGC_O_HSDMA_CONTROL));
301
302                         if (wCsr & (1 << MGC_S_HSDMA_BUSERROR)) {
303                                 pImplChannel->Channel.bStatus =
304                                     MGC_DMA_STATUS_BUS_ABORT;
305                         } else {
306                                 dwAddress = musb_readl(pBase,
307                                                        MGC_HSDMA_CHANNEL_OFFSET
308                                                        (bChannel,
309                                                         MGC_O_HSDMA_ADDRESS));
310                                 pChannel->dwActualLength =
311                                     dwAddress - pImplChannel->dwStartAddress;
312
313                                 DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
314                                     pChannel, pImplChannel->dwStartAddress,
315                                     dwAddress, pChannel->dwActualLength,
316                                     pImplChannel->dwCount,
317                                     (pChannel->dwActualLength <
318                                         pImplChannel->dwCount) ?
319                                         "=> reconfig 0": "=> complete");
320 #if 0
321                                 if (pChannel->dwActualLength <
322                                     pImplChannel->dwCount) {
323                                         /* mode 1 sends an extra IN request if
324                                         the last packet is a complete packet */
325                                         u16 newcsr = MGC_ReadCsr16(pBase,
326                                                         MGC_O_HDRC_RXCSR,
327                                                         pImplChannel->bEnd);
328                                         newcsr &= ~(MGC_M_RXCSR_H_AUTOREQ |
329                                                     MGC_M_RXCSR_H_REQPKT);
330                                         MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR,
331                                                        pImplChannel->bEnd,
332                                                        MGC_M_RXCSR_H_WZC_BITS |
333                                                                 newcsr);
334
335                                         configure_channel(pChannel,
336                                                 pImplChannel->wMaxPacketSize,
337                                                 0, dwAddress,
338                                                 pImplChannel->dwCount -
339                                                     pChannel->dwActualLength);
340                                 }
341                                 else
342 #endif
343                                 {
344                                         pChannel->bStatus = MGC_DMA_STATUS_FREE;
345                                         /* completed */
346                                         musb_dma_completion(
347                                                 pController->pDmaPrivate,
348                                                 pImplChannel->bEnd,
349                                                 pImplChannel->bTransmit);
350                                 }
351                         }
352                 }
353         }
354         return IRQ_HANDLED;
355 }
356
357 static void hsdma_controller_destroy(struct dma_controller *pController)
358 {
359         MGC_HsDmaController *pHsController = pController->pPrivateData;
360
361         if (pHsController) {
362                 pHsController->Controller.pPrivateData = NULL;
363                 kfree(pHsController);
364         }
365 }
366
367 static struct dma_controller *
368 hsdma_controller_new(struct musb *pThis, void __iomem *pCoreBase)
369 {
370         MGC_HsDmaController *pController;
371         struct device *dev = pThis->controller;
372         struct platform_device *pdev = to_platform_device(dev);
373         int irq = platform_get_irq(pdev, 1);
374
375         if (irq == 0) {
376                 dev_err(dev, "No DMA interrupt line!\n");
377                 return NULL;
378         }
379
380         if (!(pController = kzalloc(sizeof(MGC_HsDmaController), GFP_KERNEL)))
381                 return NULL;
382
383         pController->bChannelCount = MGC_HSDMA_CHANNELS;
384         pController->pDmaPrivate = pThis;
385         pController->pCoreBase = pCoreBase;
386
387         pController->Controller.pPrivateData = pController;
388         pController->Controller.start = MGC_HsDmaStartController;
389         pController->Controller.stop = MGC_HsDmaStopController;
390         pController->Controller.channel_alloc = MGC_HsDmaAllocateChannel;
391         pController->Controller.channel_release = MGC_HsDmaReleaseChannel;
392         pController->Controller.channel_program = MGC_HsDmaProgramChannel;
393         pController->Controller.channel_abort = MGC_HsDmaAbortChannel;
394
395         if (request_irq(irq, hsdma_irq, SA_INTERRUPT,
396                         pThis->controller->bus_id, &pController->Controller)) {
397                 dev_err(dev, "request_irq %d failed!\n", irq);
398                 hsdma_controller_destroy(&pController->Controller);
399                 return NULL;
400         }
401
402         return &pController->Controller;
403 }
404
405 const struct dma_controller_factory dma_controller_factory = {
406         .create =       hsdma_controller_new,
407         .destroy =      hsdma_controller_destroy,
408 };