diff options
Diffstat (limited to 'arch/blackfin/include/asm/dma.h')
-rw-r--r-- | arch/blackfin/include/asm/dma.h | 137 |
1 files changed, 117 insertions, 20 deletions
diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index dac0c97242bb..40e9c2bbc6e3 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h | |||
@@ -22,12 +22,22 @@ | |||
22 | #define DATA_SIZE_8 0 | 22 | #define DATA_SIZE_8 0 |
23 | #define DATA_SIZE_16 1 | 23 | #define DATA_SIZE_16 1 |
24 | #define DATA_SIZE_32 2 | 24 | #define DATA_SIZE_32 2 |
25 | #ifdef CONFIG_BF60x | ||
26 | #define DATA_SIZE_64 3 | ||
27 | #endif | ||
25 | 28 | ||
26 | #define DMA_FLOW_STOP 0 | 29 | #define DMA_FLOW_STOP 0 |
27 | #define DMA_FLOW_AUTO 1 | 30 | #define DMA_FLOW_AUTO 1 |
31 | #ifdef CONFIG_BF60x | ||
32 | #define DMA_FLOW_LIST 4 | ||
33 | #define DMA_FLOW_ARRAY 5 | ||
34 | #define DMA_FLOW_LIST_DEMAND 6 | ||
35 | #define DMA_FLOW_ARRAY_DEMAND 7 | ||
36 | #else | ||
28 | #define DMA_FLOW_ARRAY 4 | 37 | #define DMA_FLOW_ARRAY 4 |
29 | #define DMA_FLOW_SMALL 6 | 38 | #define DMA_FLOW_SMALL 6 |
30 | #define DMA_FLOW_LARGE 7 | 39 | #define DMA_FLOW_LARGE 7 |
40 | #endif | ||
31 | 41 | ||
32 | #define DIMENSION_LINEAR 0 | 42 | #define DIMENSION_LINEAR 0 |
33 | #define DIMENSION_2D 1 | 43 | #define DIMENSION_2D 1 |
@@ -36,26 +46,80 @@ | |||
36 | #define DIR_WRITE 1 | 46 | #define DIR_WRITE 1 |
37 | 47 | ||
38 | #define INTR_DISABLE 0 | 48 | #define INTR_DISABLE 0 |
49 | #ifdef CONFIG_BF60x | ||
50 | #define INTR_ON_PERI 1 | ||
51 | #endif | ||
39 | #define INTR_ON_BUF 2 | 52 | #define INTR_ON_BUF 2 |
40 | #define INTR_ON_ROW 3 | 53 | #define INTR_ON_ROW 3 |
41 | 54 | ||
42 | #define DMA_NOSYNC_KEEP_DMA_BUF 0 | 55 | #define DMA_NOSYNC_KEEP_DMA_BUF 0 |
43 | #define DMA_SYNC_RESTART 1 | 56 | #define DMA_SYNC_RESTART 1 |
44 | 57 | ||
58 | #ifdef DMA_MMR_SIZE_32 | ||
59 | #define DMA_MMR_SIZE_TYPE long | ||
60 | #define DMA_MMR_READ bfin_read32 | ||
61 | #define DMA_MMR_WRITE bfin_write32 | ||
62 | #else | ||
63 | #define DMA_MMR_SIZE_TYPE short | ||
64 | #define DMA_MMR_READ bfin_read16 | ||
65 | #define DMA_MMR_WRITE bfin_write16 | ||
66 | #endif | ||
67 | |||
68 | struct dma_desc_array { | ||
69 | unsigned long start_addr; | ||
70 | unsigned DMA_MMR_SIZE_TYPE cfg; | ||
71 | unsigned DMA_MMR_SIZE_TYPE x_count; | ||
72 | DMA_MMR_SIZE_TYPE x_modify; | ||
73 | } __attribute__((packed)); | ||
74 | |||
45 | struct dmasg { | 75 | struct dmasg { |
46 | void *next_desc_addr; | 76 | void *next_desc_addr; |
47 | unsigned long start_addr; | 77 | unsigned long start_addr; |
48 | unsigned short cfg; | 78 | unsigned DMA_MMR_SIZE_TYPE cfg; |
49 | unsigned short x_count; | 79 | unsigned DMA_MMR_SIZE_TYPE x_count; |
50 | short x_modify; | 80 | DMA_MMR_SIZE_TYPE x_modify; |
51 | unsigned short y_count; | 81 | unsigned DMA_MMR_SIZE_TYPE y_count; |
52 | short y_modify; | 82 | DMA_MMR_SIZE_TYPE y_modify; |
53 | } __attribute__((packed)); | 83 | } __attribute__((packed)); |
54 | 84 | ||
55 | struct dma_register { | 85 | struct dma_register { |
56 | void *next_desc_ptr; /* DMA Next Descriptor Pointer register */ | 86 | void *next_desc_ptr; /* DMA Next Descriptor Pointer register */ |
57 | unsigned long start_addr; /* DMA Start address register */ | 87 | unsigned long start_addr; /* DMA Start address register */ |
88 | #ifdef CONFIG_BF60x | ||
89 | unsigned long cfg; /* DMA Configuration register */ | ||
58 | 90 | ||
91 | unsigned long x_count; /* DMA x_count register */ | ||
92 | |||
93 | long x_modify; /* DMA x_modify register */ | ||
94 | |||
95 | unsigned long y_count; /* DMA y_count register */ | ||
96 | |||
97 | long y_modify; /* DMA y_modify register */ | ||
98 | |||
99 | unsigned long reserved; | ||
100 | unsigned long reserved2; | ||
101 | |||
102 | void *curr_desc_ptr; /* DMA Current Descriptor Pointer | ||
103 | register */ | ||
104 | void *prev_desc_ptr; /* DMA previous initial Descriptor Pointer | ||
105 | register */ | ||
106 | unsigned long curr_addr_ptr; /* DMA Current Address Pointer | ||
107 | register */ | ||
108 | unsigned long irq_status; /* DMA irq status register */ | ||
109 | |||
110 | unsigned long curr_x_count; /* DMA Current x-count register */ | ||
111 | |||
112 | unsigned long curr_y_count; /* DMA Current y-count register */ | ||
113 | |||
114 | unsigned long reserved3; | ||
115 | |||
116 | unsigned long bw_limit_count; /* DMA band width limit count register */ | ||
117 | unsigned long curr_bw_limit_count; /* DMA Current band width limit | ||
118 | count register */ | ||
119 | unsigned long bw_monitor_count; /* DMA band width limit count register */ | ||
120 | unsigned long curr_bw_monitor_count; /* DMA Current band width limit | ||
121 | count register */ | ||
122 | #else | ||
59 | unsigned short cfg; /* DMA Configuration register */ | 123 | unsigned short cfg; /* DMA Configuration register */ |
60 | unsigned short dummy1; /* DMA Configuration register */ | 124 | unsigned short dummy1; /* DMA Configuration register */ |
61 | 125 | ||
@@ -92,6 +156,7 @@ struct dma_register { | |||
92 | unsigned short dummy9; | 156 | unsigned short dummy9; |
93 | 157 | ||
94 | unsigned long reserved3; | 158 | unsigned long reserved3; |
159 | #endif | ||
95 | 160 | ||
96 | }; | 161 | }; |
97 | 162 | ||
@@ -131,23 +196,23 @@ static inline void set_dma_curr_desc_addr(unsigned int channel, void *addr) | |||
131 | { | 196 | { |
132 | dma_ch[channel].regs->curr_desc_ptr = addr; | 197 | dma_ch[channel].regs->curr_desc_ptr = addr; |
133 | } | 198 | } |
134 | static inline void set_dma_x_count(unsigned int channel, unsigned short x_count) | 199 | static inline void set_dma_x_count(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE x_count) |
135 | { | 200 | { |
136 | dma_ch[channel].regs->x_count = x_count; | 201 | dma_ch[channel].regs->x_count = x_count; |
137 | } | 202 | } |
138 | static inline void set_dma_y_count(unsigned int channel, unsigned short y_count) | 203 | static inline void set_dma_y_count(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE y_count) |
139 | { | 204 | { |
140 | dma_ch[channel].regs->y_count = y_count; | 205 | dma_ch[channel].regs->y_count = y_count; |
141 | } | 206 | } |
142 | static inline void set_dma_x_modify(unsigned int channel, short x_modify) | 207 | static inline void set_dma_x_modify(unsigned int channel, DMA_MMR_SIZE_TYPE x_modify) |
143 | { | 208 | { |
144 | dma_ch[channel].regs->x_modify = x_modify; | 209 | dma_ch[channel].regs->x_modify = x_modify; |
145 | } | 210 | } |
146 | static inline void set_dma_y_modify(unsigned int channel, short y_modify) | 211 | static inline void set_dma_y_modify(unsigned int channel, DMA_MMR_SIZE_TYPE y_modify) |
147 | { | 212 | { |
148 | dma_ch[channel].regs->y_modify = y_modify; | 213 | dma_ch[channel].regs->y_modify = y_modify; |
149 | } | 214 | } |
150 | static inline void set_dma_config(unsigned int channel, unsigned short config) | 215 | static inline void set_dma_config(unsigned int channel, unsigned DMA_MMR_SIZE_TYPE config) |
151 | { | 216 | { |
152 | dma_ch[channel].regs->cfg = config; | 217 | dma_ch[channel].regs->cfg = config; |
153 | } | 218 | } |
@@ -156,23 +221,55 @@ static inline void set_dma_curr_addr(unsigned int channel, unsigned long addr) | |||
156 | dma_ch[channel].regs->curr_addr_ptr = addr; | 221 | dma_ch[channel].regs->curr_addr_ptr = addr; |
157 | } | 222 | } |
158 | 223 | ||
159 | static inline unsigned short | 224 | #ifdef CONFIG_BF60x |
225 | static inline unsigned long | ||
226 | set_bfin_dma_config2(char direction, char flow_mode, char intr_mode, | ||
227 | char dma_mode, char mem_width, char syncmode, char peri_width) | ||
228 | { | ||
229 | unsigned long config = 0; | ||
230 | |||
231 | switch (intr_mode) { | ||
232 | case INTR_ON_BUF: | ||
233 | if (dma_mode == DIMENSION_2D) | ||
234 | config = DI_EN_Y; | ||
235 | else | ||
236 | config = DI_EN_X; | ||
237 | break; | ||
238 | case INTR_ON_ROW: | ||
239 | config = DI_EN_X; | ||
240 | break; | ||
241 | case INTR_ON_PERI: | ||
242 | config = DI_EN_P; | ||
243 | break; | ||
244 | }; | ||
245 | |||
246 | return config | (direction << 1) | (mem_width << 8) | (dma_mode << 26) | | ||
247 | (flow_mode << 12) | (syncmode << 2) | (peri_width << 4); | ||
248 | } | ||
249 | #endif | ||
250 | |||
251 | static inline unsigned DMA_MMR_SIZE_TYPE | ||
160 | set_bfin_dma_config(char direction, char flow_mode, | 252 | set_bfin_dma_config(char direction, char flow_mode, |
161 | char intr_mode, char dma_mode, char width, char syncmode) | 253 | char intr_mode, char dma_mode, char mem_width, char syncmode) |
162 | { | 254 | { |
163 | return (direction << 1) | (width << 2) | (dma_mode << 4) | | 255 | #ifdef CONFIG_BF60x |
256 | return set_bfin_dma_config2(direction, flow_mode, intr_mode, dma_mode, | ||
257 | mem_width, syncmode, mem_width); | ||
258 | #else | ||
259 | return (direction << 1) | (mem_width << 2) | (dma_mode << 4) | | ||
164 | (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5); | 260 | (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5); |
261 | #endif | ||
165 | } | 262 | } |
166 | 263 | ||
167 | static inline unsigned short get_dma_curr_irqstat(unsigned int channel) | 264 | static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_irqstat(unsigned int channel) |
168 | { | 265 | { |
169 | return dma_ch[channel].regs->irq_status; | 266 | return dma_ch[channel].regs->irq_status; |
170 | } | 267 | } |
171 | static inline unsigned short get_dma_curr_xcount(unsigned int channel) | 268 | static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_xcount(unsigned int channel) |
172 | { | 269 | { |
173 | return dma_ch[channel].regs->curr_x_count; | 270 | return dma_ch[channel].regs->curr_x_count; |
174 | } | 271 | } |
175 | static inline unsigned short get_dma_curr_ycount(unsigned int channel) | 272 | static inline unsigned DMA_MMR_SIZE_TYPE get_dma_curr_ycount(unsigned int channel) |
176 | { | 273 | { |
177 | return dma_ch[channel].regs->curr_y_count; | 274 | return dma_ch[channel].regs->curr_y_count; |
178 | } | 275 | } |
@@ -184,7 +281,7 @@ static inline void *get_dma_curr_desc_ptr(unsigned int channel) | |||
184 | { | 281 | { |
185 | return dma_ch[channel].regs->curr_desc_ptr; | 282 | return dma_ch[channel].regs->curr_desc_ptr; |
186 | } | 283 | } |
187 | static inline unsigned short get_dma_config(unsigned int channel) | 284 | static inline unsigned DMA_MMR_SIZE_TYPE get_dma_config(unsigned int channel) |
188 | { | 285 | { |
189 | return dma_ch[channel].regs->cfg; | 286 | return dma_ch[channel].regs->cfg; |
190 | } | 287 | } |
@@ -203,8 +300,8 @@ static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize | |||
203 | 300 | ||
204 | dma_ch[channel].regs->next_desc_ptr = sg; | 301 | dma_ch[channel].regs->next_desc_ptr = sg; |
205 | dma_ch[channel].regs->cfg = | 302 | dma_ch[channel].regs->cfg = |
206 | (dma_ch[channel].regs->cfg & ~(0xf << 8)) | | 303 | (dma_ch[channel].regs->cfg & ~NDSIZE) | |
207 | ((ndsize & 0xf) << 8); | 304 | ((ndsize << NDSIZE_OFFSET) & NDSIZE); |
208 | } | 305 | } |
209 | 306 | ||
210 | static inline int dma_channel_active(unsigned int channel) | 307 | static inline int dma_channel_active(unsigned int channel) |
@@ -239,7 +336,7 @@ static inline void dma_enable_irq(unsigned int channel) | |||
239 | } | 336 | } |
240 | static inline void clear_dma_irqstat(unsigned int channel) | 337 | static inline void clear_dma_irqstat(unsigned int channel) |
241 | { | 338 | { |
242 | dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR; | 339 | dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR | DMA_PIRQ; |
243 | } | 340 | } |
244 | 341 | ||
245 | void *dma_memcpy(void *dest, const void *src, size_t count); | 342 | void *dma_memcpy(void *dest, const void *src, size_t count); |