]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/blackfin/include/asm/dma.h
Blackfin arch: move most dma functions into static inlines
[linux-2.6-omap-h63xx.git] / arch / blackfin / include / asm / dma.h
1 /*
2  * dma.h - Blackfin DMA defines/structures/etc...
3  *
4  * Copyright 2004-2008 Analog Devices Inc.
5  * Licensed under the GPL-2 or later.
6  */
7
8 #ifndef _BLACKFIN_DMA_H_
9 #define _BLACKFIN_DMA_H_
10
11 #include <linux/interrupt.h>
12 #include <mach/dma.h>
13 #include <asm/blackfin.h>
14 #include <asm/page.h>
15
16 #define MAX_DMA_ADDRESS PAGE_OFFSET
17
18 /*****************************************************************************
19 *        Generic DMA  Declarations
20 *
21 ****************************************************************************/
22 enum dma_chan_status {
23         DMA_CHANNEL_FREE,
24         DMA_CHANNEL_REQUESTED,
25         DMA_CHANNEL_ENABLED,
26 };
27
28 /*-------------------------
29  * config reg bits value
30  *-------------------------*/
31 #define DATA_SIZE_8             0
32 #define DATA_SIZE_16            1
33 #define DATA_SIZE_32            2
34
35 #define DMA_FLOW_STOP           0
36 #define DMA_FLOW_AUTO           1
37 #define DMA_FLOW_ARRAY          4
38 #define DMA_FLOW_SMALL          6
39 #define DMA_FLOW_LARGE          7
40
41 #define DIMENSION_LINEAR    0
42 #define DIMENSION_2D           1
43
44 #define DIR_READ     0
45 #define DIR_WRITE    1
46
47 #define INTR_DISABLE   0
48 #define INTR_ON_BUF    2
49 #define INTR_ON_ROW    3
50
51 #define DMA_NOSYNC_KEEP_DMA_BUF 0
52 #define DMA_SYNC_RESTART        1
53
54 struct dmasg {
55         unsigned long next_desc_addr;
56         unsigned long start_addr;
57         unsigned short cfg;
58         unsigned short x_count;
59         short x_modify;
60         unsigned short y_count;
61         short y_modify;
62 } __attribute__((packed));
63
64 struct dma_register {
65         unsigned long next_desc_ptr;    /* DMA Next Descriptor Pointer register */
66         unsigned long start_addr;       /* DMA Start address  register */
67
68         unsigned short cfg;     /* DMA Configuration register */
69         unsigned short dummy1;  /* DMA Configuration register */
70
71         unsigned long reserved;
72
73         unsigned short x_count; /* DMA x_count register */
74         unsigned short dummy2;
75
76         short x_modify; /* DMA x_modify register */
77         unsigned short dummy3;
78
79         unsigned short y_count; /* DMA y_count register */
80         unsigned short dummy4;
81
82         short y_modify; /* DMA y_modify register */
83         unsigned short dummy5;
84
85         unsigned long curr_desc_ptr;    /* DMA Current Descriptor Pointer
86                                            register */
87         unsigned long curr_addr_ptr;    /* DMA Current Address Pointer
88                                                    register */
89         unsigned short irq_status;      /* DMA irq status register */
90         unsigned short dummy6;
91
92         unsigned short peripheral_map;  /* DMA peripheral map register */
93         unsigned short dummy7;
94
95         unsigned short curr_x_count;    /* DMA Current x-count register */
96         unsigned short dummy8;
97
98         unsigned long reserved2;
99
100         unsigned short curr_y_count;    /* DMA Current y-count register */
101         unsigned short dummy9;
102
103         unsigned long reserved3;
104
105 };
106
107 struct mutex;
108 struct dma_channel {
109         struct mutex dmalock;
110         const char *device_id;
111         enum dma_chan_status chan_status;
112         struct dma_register *regs;
113         struct dmasg *sg;               /* large mode descriptor */
114         unsigned int ctrl_num;  /* controller number */
115         unsigned int irq;
116         void *data;
117         unsigned int dma_enable_flag;
118         unsigned int loopback_flag;
119 #ifdef CONFIG_PM
120         unsigned short saved_peripheral_map;
121 #endif
122 };
123
124 #ifdef CONFIG_PM
125 int blackfin_dma_suspend(void);
126 void blackfin_dma_resume(void);
127 #endif
128
129 /*******************************************************************************
130 *       DMA API's
131 *******************************************************************************/
132 extern struct dma_channel dma_ch[MAX_DMA_CHANNELS];
133 extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS];
134 extern int channel2irq(unsigned int channel);
135
136 static inline void set_dma_start_addr(unsigned int channel, unsigned long addr)
137 {
138         dma_ch[channel].regs->start_addr = addr;
139 }
140 static inline void set_dma_next_desc_addr(unsigned int channel, unsigned long addr)
141 {
142         dma_ch[channel].regs->next_desc_ptr = addr;
143 }
144 static inline void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr)
145 {
146         dma_ch[channel].regs->curr_desc_ptr = addr;
147 }
148 static inline void set_dma_x_count(unsigned int channel, unsigned short x_count)
149 {
150         dma_ch[channel].regs->x_count = x_count;
151 }
152 static inline void set_dma_y_count(unsigned int channel, unsigned short y_count)
153 {
154         dma_ch[channel].regs->y_count = y_count;
155 }
156 static inline void set_dma_x_modify(unsigned int channel, short x_modify)
157 {
158         dma_ch[channel].regs->x_modify = x_modify;
159 }
160 static inline void set_dma_y_modify(unsigned int channel, short y_modify)
161 {
162         dma_ch[channel].regs->y_modify = y_modify;
163 }
164 static inline void set_dma_config(unsigned int channel, unsigned short config)
165 {
166         dma_ch[channel].regs->cfg = config;
167 }
168 static inline void set_dma_curr_addr(unsigned int channel, unsigned long addr)
169 {
170         dma_ch[channel].regs->curr_addr_ptr = addr;
171 }
172
173 static inline unsigned short
174 set_bfin_dma_config(char direction, char flow_mode,
175                     char intr_mode, char dma_mode, char width, char syncmode)
176 {
177         return (direction << 1) | (width << 2) | (dma_mode << 4) |
178                 (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5);
179 }
180
181 static inline unsigned short get_dma_curr_irqstat(unsigned int channel)
182 {
183         return dma_ch[channel].regs->irq_status;
184 }
185 static inline unsigned short get_dma_curr_xcount(unsigned int channel)
186 {
187         return dma_ch[channel].regs->curr_x_count;
188 }
189 static inline unsigned short get_dma_curr_ycount(unsigned int channel)
190 {
191         return dma_ch[channel].regs->curr_y_count;
192 }
193 static inline unsigned long get_dma_next_desc_ptr(unsigned int channel)
194 {
195         return dma_ch[channel].regs->next_desc_ptr;
196 }
197 static inline unsigned long get_dma_curr_desc_ptr(unsigned int channel)
198 {
199         return dma_ch[channel].regs->curr_desc_ptr;
200 }
201 static inline unsigned long get_dma_curr_addr(unsigned int channel)
202 {
203         return dma_ch[channel].regs->curr_addr_ptr;
204 }
205
206 static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize)
207 {
208         dma_ch[channel].regs->cfg |= ((ndsize & 0x0F) << 8);
209         dma_ch[channel].regs->next_desc_ptr = (unsigned long)sg;
210 }
211
212 static inline int dma_channel_active(unsigned int channel)
213 {
214         if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE)
215                 return 0;
216         else
217                 return 1;
218 }
219
220 static inline void disable_dma(unsigned int channel)
221 {
222         dma_ch[channel].regs->cfg &= ~DMAEN;
223         SSYNC();
224         dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
225 }
226 static inline void enable_dma(unsigned int channel)
227 {
228         dma_ch[channel].regs->curr_x_count = 0;
229         dma_ch[channel].regs->curr_y_count = 0;
230         dma_ch[channel].regs->cfg |= DMAEN;
231         dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED;
232 }
233 void free_dma(unsigned int channel);
234 int request_dma(unsigned int channel, const char *device_id);
235 int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data);
236
237 static inline void dma_disable_irq(unsigned int channel)
238 {
239         disable_irq(dma_ch[channel].irq);
240 }
241 static inline void dma_enable_irq(unsigned int channel)
242 {
243         enable_irq(dma_ch[channel].irq);
244 }
245 static inline void clear_dma_irqstat(unsigned int channel)
246 {
247         dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR;
248 }
249
250 void *dma_memcpy(void *dest, const void *src, size_t count);
251 void *safe_dma_memcpy(void *dest, const void *src, size_t count);
252 void blackfin_dma_early_init(void);
253
254 #endif