Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / include / asm-arm / arch-s3c2410 / dma.h
1 /* linux/include/asm-arm/arch-bast/dma.h
2  *
3  * Copyright (C) 2003,2004 Simtec Electronics
4  *      Ben Dooks <ben@simtec.co.uk>
5  *
6  * Samsung S3C2410X DMA support
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * Changelog:
13  *  ??-May-2003 BJD   Created file
14  *  ??-Jun-2003 BJD   Added more dma functionality to go with arch
15  *  10-Nov-2004 BJD   Added sys_device support
16 */
17
18 #ifndef __ASM_ARCH_DMA_H
19 #define __ASM_ARCH_DMA_H __FILE__
20
21 #include <linux/config.h>
22 #include <linux/sysdev.h>
23 #include "hardware.h"
24
25
26 /*
27  * This is the maximum DMA address(physical address) that can be DMAd to.
28  *
29  */
30 #define MAX_DMA_ADDRESS         0x20000000
31 #define MAX_DMA_TRANSFER_SIZE   0x100000 /* Data Unit is half word  */
32
33
34 /* according to the samsung port, we cannot use the regular
35  * dma channels... we must therefore provide our own interface
36  * for DMA, and allow our drivers to use that.
37  */
38
39 #define MAX_DMA_CHANNELS        0
40
41
42 /* we have 4 dma channels */
43 #define S3C2410_DMA_CHANNELS        (4)
44
45 /* types */
46
47 typedef enum {
48         S3C2410_DMA_IDLE,
49         S3C2410_DMA_RUNNING,
50         S3C2410_DMA_PAUSED
51 } s3c2410_dma_state_t;
52
53
54 /* s3c2410_dma_loadst_t
55  *
56  * This represents the state of the DMA engine, wrt to the loaded / running
57  * transfers. Since we don't have any way of knowing exactly the state of
58  * the DMA transfers, we need to know the state to make decisions on wether
59  * we can
60  *
61  * S3C2410_DMA_NONE
62  *
63  * There are no buffers loaded (the channel should be inactive)
64  *
65  * S3C2410_DMA_1LOADED
66  *
67  * There is one buffer loaded, however it has not been confirmed to be
68  * loaded by the DMA engine. This may be because the channel is not
69  * yet running, or the DMA driver decided that it was too costly to
70  * sit and wait for it to happen.
71  *
72  * S3C2410_DMA_1RUNNING
73  *
74  * The buffer has been confirmed running, and not finisged
75  *
76  * S3C2410_DMA_1LOADED_1RUNNING
77  *
78  * There is a buffer waiting to be loaded by the DMA engine, and one
79  * currently running.
80 */
81
82 typedef enum {
83         S3C2410_DMALOAD_NONE,
84         S3C2410_DMALOAD_1LOADED,
85         S3C2410_DMALOAD_1RUNNING,
86         S3C2410_DMALOAD_1LOADED_1RUNNING,
87 } s3c2410_dma_loadst_t;
88
89 typedef enum {
90         S3C2410_RES_OK,
91         S3C2410_RES_ERR,
92         S3C2410_RES_ABORT
93 } s3c2410_dma_buffresult_t;
94
95
96 typedef enum s3c2410_dmasrc_e s3c2410_dmasrc_t;
97
98 enum s3c2410_dmasrc_e {
99         S3C2410_DMASRC_HW,      /* source is memory */
100         S3C2410_DMASRC_MEM      /* source is hardware */
101 };
102
103 /* enum s3c2410_chan_op_e
104  *
105  * operation codes passed to the DMA code by the user, and also used
106  * to inform the current channel owner of any changes to the system state
107 */
108
109 enum s3c2410_chan_op_e {
110         S3C2410_DMAOP_START,
111         S3C2410_DMAOP_STOP,
112         S3C2410_DMAOP_PAUSE,
113         S3C2410_DMAOP_RESUME,
114         S3C2410_DMAOP_FLUSH,
115         S3C2410_DMAOP_TIMEOUT,           /* internal signal to handler */
116 };
117
118 typedef enum s3c2410_chan_op_e s3c2410_chan_op_t;
119
120 /* flags */
121
122 #define S3C2410_DMAF_SLOW         (1<<0)   /* slow, so don't worry about
123                                             * waiting for reloads */
124 #define S3C2410_DMAF_AUTOSTART    (1<<1)   /* auto-start if buffer queued */
125
126 /* dma buffer */
127
128 typedef struct s3c2410_dma_buf_s s3c2410_dma_buf_t;
129
130 struct s3c2410_dma_client {
131         char                *name;
132 };
133
134 typedef struct s3c2410_dma_client s3c2410_dma_client_t;
135
136 /* s3c2410_dma_buf_s
137  *
138  * internally used buffer structure to describe a queued or running
139  * buffer.
140 */
141
142 struct s3c2410_dma_buf_s {
143         s3c2410_dma_buf_t   *next;
144         int                  magic;        /* magic */
145         int                  size;         /* buffer size in bytes */
146         dma_addr_t           data;         /* start of DMA data */
147         dma_addr_t           ptr;          /* where the DMA got to [1] */
148         void                *id;           /* client's id */
149 };
150
151 /* [1] is this updated for both recv/send modes? */
152
153 typedef struct s3c2410_dma_chan_s s3c2410_dma_chan_t;
154
155 /* s3c2410_dma_cbfn_t
156  *
157  * buffer callback routine type
158 */
159
160 typedef void (*s3c2410_dma_cbfn_t)(s3c2410_dma_chan_t *, void *buf, int size,
161                                    s3c2410_dma_buffresult_t result);
162
163 typedef int  (*s3c2410_dma_opfn_t)(s3c2410_dma_chan_t *,
164                                    s3c2410_chan_op_t );
165
166 struct s3c2410_dma_stats_s {
167         unsigned long          loads;
168         unsigned long          timeout_longest;
169         unsigned long          timeout_shortest;
170         unsigned long          timeout_avg;
171         unsigned long          timeout_failed;
172 };
173
174 typedef struct s3c2410_dma_stats_s s3c2410_dma_stats_t;
175
176 /* struct s3c2410_dma_chan_s
177  *
178  * full state information for each DMA channel
179 */
180
181 struct s3c2410_dma_chan_s {
182         /* channel state flags and information */
183         unsigned char          number;      /* number of this dma channel */
184         unsigned char          in_use;      /* channel allocated */
185         unsigned char          irq_claimed; /* irq claimed for channel */
186         unsigned char          irq_enabled; /* irq enabled for channel */
187         unsigned char          xfer_unit;   /* size of an transfer */
188
189         /* channel state */
190
191         s3c2410_dma_state_t    state;
192         s3c2410_dma_loadst_t   load_state;
193         s3c2410_dma_client_t  *client;
194
195         /* channel configuration */
196         s3c2410_dmasrc_t       source;
197         unsigned long          dev_addr;
198         unsigned long          load_timeout;
199         unsigned int           flags;        /* channel flags */
200
201         /* channel's hardware position and configuration */
202         void __iomem           *regs;        /* channels registers */
203         void __iomem           *addr_reg;    /* data address register */
204         unsigned int           irq;          /* channel irq */
205         unsigned long          dcon;         /* default value of DCON */
206
207         /* driver handles */
208         s3c2410_dma_cbfn_t     callback_fn;  /* buffer done callback */
209         s3c2410_dma_opfn_t     op_fn;        /* channel operation callback */
210
211         /* stats gathering */
212         s3c2410_dma_stats_t   *stats;
213         s3c2410_dma_stats_t    stats_store;
214
215         /* buffer list and information */
216         s3c2410_dma_buf_t      *curr;        /* current dma buffer */
217         s3c2410_dma_buf_t      *next;        /* next buffer to load */
218         s3c2410_dma_buf_t      *end;         /* end of queue */
219
220         /* system device */
221         struct sys_device       dev;
222 };
223
224 /* the currently allocated channel information */
225 extern s3c2410_dma_chan_t s3c2410_chans[];
226
227 /* note, we don't really use dma_device_t at the moment */
228 typedef unsigned long dma_device_t;
229
230 /* functions --------------------------------------------------------------- */
231
232 /* s3c2410_dma_request
233  *
234  * request a dma channel exclusivley
235 */
236
237 extern int s3c2410_dma_request(dmach_t channel,
238                                s3c2410_dma_client_t *, void *dev);
239
240
241 /* s3c2410_dma_ctrl
242  *
243  * change the state of the dma channel
244 */
245
246 extern int s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op);
247
248 /* s3c2410_dma_setflags
249  *
250  * set the channel's flags to a given state
251 */
252
253 extern int s3c2410_dma_setflags(dmach_t channel,
254                                 unsigned int flags);
255
256 /* s3c2410_dma_free
257  *
258  * free the dma channel (will also abort any outstanding operations)
259 */
260
261 extern int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *);
262
263 /* s3c2410_dma_enqueue
264  *
265  * place the given buffer onto the queue of operations for the channel.
266  * The buffer must be allocated from dma coherent memory, or the Dcache/WB
267  * drained before the buffer is given to the DMA system.
268 */
269
270 extern int s3c2410_dma_enqueue(dmach_t channel, void *id,
271                                dma_addr_t data, int size);
272
273 /* s3c2410_dma_config
274  *
275  * configure the dma channel
276 */
277
278 extern int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon);
279
280 /* s3c2410_dma_devconfig
281  *
282  * configure the device we're talking to
283 */
284
285 extern int s3c2410_dma_devconfig(int channel, s3c2410_dmasrc_t source,
286                                  int hwcfg, unsigned long devaddr);
287
288 /* s3c2410_dma_getposition
289  *
290  * get the position that the dma transfer is currently at
291 */
292
293 extern int s3c2410_dma_getposition(dmach_t channel,
294                                    dma_addr_t *src, dma_addr_t *dest);
295
296 extern int s3c2410_dma_set_opfn(dmach_t, s3c2410_dma_opfn_t rtn);
297 extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
298
299 /* DMA Register definitions */
300
301 #define S3C2410_DMA_DISRC       (0x00)
302 #define S3C2410_DMA_DISRCC      (0x04)
303 #define S3C2410_DMA_DIDST       (0x08)
304 #define S3C2410_DMA_DIDSTC      (0x0C)
305 #define S3C2410_DMA_DCON        (0x10)
306 #define S3C2410_DMA_DSTAT       (0x14)
307 #define S3C2410_DMA_DCSRC       (0x18)
308 #define S3C2410_DMA_DCDST       (0x1C)
309 #define S3C2410_DMA_DMASKTRIG   (0x20)
310
311 #define S3C2410_DISRCC_INC      (1<<0)
312 #define S3C2410_DISRCC_APB      (1<<1)
313
314 #define S3C2410_DMASKTRIG_STOP   (1<<2)
315 #define S3C2410_DMASKTRIG_ON     (1<<1)
316 #define S3C2410_DMASKTRIG_SWTRIG (1<<0)
317
318 #define S3C2410_DCON_DEMAND     (0<<31)
319 #define S3C2410_DCON_HANDSHAKE  (1<<31)
320 #define S3C2410_DCON_SYNC_PCLK  (0<<30)
321 #define S3C2410_DCON_SYNC_HCLK  (1<<30)
322
323 #define S3C2410_DCON_INTREQ     (1<<29)
324
325 #define S3C2410_DCON_CH0_XDREQ0 (0<<24)
326 #define S3C2410_DCON_CH0_UART0  (1<<24)
327 #define S3C2410_DCON_CH0_SDI    (2<<24)
328 #define S3C2410_DCON_CH0_TIMER  (3<<24)
329 #define S3C2410_DCON_CH0_USBEP1 (4<<24)
330
331 #define S3C2410_DCON_CH1_XDREQ1 (0<<24)
332 #define S3C2410_DCON_CH1_UART1  (1<<24)
333 #define S3C2410_DCON_CH1_I2SSDI (2<<24)
334 #define S3C2410_DCON_CH1_SPI    (3<<24)
335 #define S3C2410_DCON_CH1_USBEP2 (4<<24)
336
337 #define S3C2410_DCON_CH2_I2SSDO (0<<24)
338 #define S3C2410_DCON_CH2_I2SSDI (1<<24)
339 #define S3C2410_DCON_CH2_SDI    (2<<24)
340 #define S3C2410_DCON_CH2_TIMER  (3<<24)
341 #define S3C2410_DCON_CH2_USBEP3 (4<<24)
342
343 #define S3C2410_DCON_CH3_UART2  (0<<24)
344 #define S3C2410_DCON_CH3_SDI    (1<<24)
345 #define S3C2410_DCON_CH3_SPI    (2<<24)
346 #define S3C2410_DCON_CH3_TIMER  (3<<24)
347 #define S3C2410_DCON_CH3_USBEP4 (4<<24)
348
349 #define S3C2410_DCON_SRCSHIFT   (24)
350 #define S3C2410_DCON_SRCMASK    (7<<24)
351
352 #define S3C2410_DCON_BYTE       (0<<20)
353 #define S3C2410_DCON_HALFWORD   (1<<20)
354 #define S3C2410_DCON_WORD       (2<<20)
355
356 #define S3C2410_DCON_AUTORELOAD (0<<22)
357 #define S3C2410_DCON_NORELOAD   (1<<22)
358 #define S3C2410_DCON_HWTRIG     (1<<23)
359
360 #ifdef CONFIG_CPU_S3C2440
361 #define S3C2440_DIDSTC_CHKINT   (1<<2)
362
363 #define S3C2440_DCON_CH0_I2SSDO (5<<24)
364 #define S3C2440_DCON_CH0_PCMIN  (6<<24)
365
366 #define S3C2440_DCON_CH1_PCMOUT (5<<24)
367 #define S3C2440_DCON_CH1_SDI    (6<<24)
368
369 #define S3C2440_DCON_CH2_PCMIN  (5<<24)
370 #define S3C2440_DCON_CH2_MICIN  (6<<24)
371
372 #define S3C2440_DCON_CH3_MICIN  (5<<24)
373 #define S3C2440_DCON_CH3_PCMOUT (6<<24)
374 #endif
375
376 #endif /* __ASM_ARCH_DMA_H */