diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 15:00:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 15:00:25 -0500 |
commit | 5bb47b9ff3d16d40f8d45380b373497a545fa280 (patch) | |
tree | e13dd34395473342dc75eff5cbaf5b1ea753631c /arch/blackfin/include/asm/dma.h | |
parent | 2f2408a88cf8fa43febfd7fb5783e61b2937b0f9 (diff) | |
parent | 06af15e086e39a5a2a2413973a64af8e10122f28 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (171 commits)
Blackfin arch: fix bug - BF527 0.2 silicon has different CPUID (DSPID) value
Blackfin arch: Enlarge flash partition for kenel for bf533/bf537 boards
Blackfin arch: fix bug: kernel crash when enable SDIO host driver
Blackfin arch: Print FP at level KERN_NOTICE
Blackfin arch: drop ad73311 test code
Blackfin arch: update board default configs
Blackfin arch: Set PB4 as the default irq for bf548 board v1.4+.
Blackfin arch: fix typo in early printk bit size processing
Blackfin arch: enable reprogram cclk and sclk for bf518f-ezbrd
Blackfin arch: add SDIO host driver platform data
Blackfin arch: fix bug - kernel stops at initial console
Blackfin arch: fix bug - kernel crash after config IP for ethernet port
Blackfin arch: add sdh support for bf518f-ezbrd
Blackfin arch: fix bug - kernel detects BF532 incorrectly
Blackfin arch: add () to avoid warnings from gcc
Blackfin arch: change HWTRACE Kconfig and set it on default
Blackfin arch: Clean oprofile build path for blackfin
Blackfin arch: remove hardware PM code, oprofile not use it
Blackfin arch: rewrite get_sclk()/get_vco()
Blackfin arch: cleanup and unify the ins functions
...
Diffstat (limited to 'arch/blackfin/include/asm/dma.h')
-rw-r--r-- | arch/blackfin/include/asm/dma.h | 220 |
1 files changed, 136 insertions, 84 deletions
diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 6509733bb0f6..e4f7b8043f02 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h | |||
@@ -1,44 +1,17 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/simple_bf533_dma.h | 2 | * dma.h - Blackfin DMA defines/structures/etc... |
3 | * Based on: none - original work | ||
4 | * Author: LG Soft India | ||
5 | * Copyright (C) 2004-2005 Analog Devices Inc. | ||
6 | * Created: Tue Sep 21 2004 | ||
7 | * Description: This file contains the major Data structures and constants | ||
8 | * used for DMA Implementation in BF533 | ||
9 | * Modified: | ||
10 | * | 3 | * |
11 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 4 | * Copyright 2004-2008 Analog Devices Inc. |
12 | * | 5 | * Licensed under the GPL-2 or later. |
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2, or (at your option) | ||
16 | * any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; see the file COPYING. | ||
25 | * If not, write to the Free Software Foundation, | ||
26 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
27 | */ | 6 | */ |
28 | 7 | ||
29 | #ifndef _BLACKFIN_DMA_H_ | 8 | #ifndef _BLACKFIN_DMA_H_ |
30 | #define _BLACKFIN_DMA_H_ | 9 | #define _BLACKFIN_DMA_H_ |
31 | 10 | ||
32 | #include <asm/io.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <asm/irq.h> | ||
35 | #include <asm/signal.h> | ||
36 | |||
37 | #include <linux/kernel.h> | ||
38 | #include <mach/dma.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <mach/dma.h> | ||
41 | #include <asm/blackfin.h> | 13 | #include <asm/blackfin.h> |
14 | #include <asm/page.h> | ||
42 | 15 | ||
43 | #define MAX_DMA_ADDRESS PAGE_OFFSET | 16 | #define MAX_DMA_ADDRESS PAGE_OFFSET |
44 | 17 | ||
@@ -79,7 +52,7 @@ enum dma_chan_status { | |||
79 | #define DMA_SYNC_RESTART 1 | 52 | #define DMA_SYNC_RESTART 1 |
80 | 53 | ||
81 | struct dmasg { | 54 | struct dmasg { |
82 | unsigned long next_desc_addr; | 55 | void *next_desc_addr; |
83 | unsigned long start_addr; | 56 | unsigned long start_addr; |
84 | unsigned short cfg; | 57 | unsigned short cfg; |
85 | unsigned short x_count; | 58 | unsigned short x_count; |
@@ -89,7 +62,7 @@ struct dmasg { | |||
89 | } __attribute__((packed)); | 62 | } __attribute__((packed)); |
90 | 63 | ||
91 | struct dma_register { | 64 | struct dma_register { |
92 | unsigned long next_desc_ptr; /* DMA Next Descriptor Pointer register */ | 65 | void *next_desc_ptr; /* DMA Next Descriptor Pointer register */ |
93 | unsigned long start_addr; /* DMA Start address register */ | 66 | unsigned long start_addr; /* DMA Start address register */ |
94 | 67 | ||
95 | unsigned short cfg; /* DMA Configuration register */ | 68 | unsigned short cfg; /* DMA Configuration register */ |
@@ -109,7 +82,7 @@ struct dma_register { | |||
109 | short y_modify; /* DMA y_modify register */ | 82 | short y_modify; /* DMA y_modify register */ |
110 | unsigned short dummy5; | 83 | unsigned short dummy5; |
111 | 84 | ||
112 | unsigned long curr_desc_ptr; /* DMA Current Descriptor Pointer | 85 | void *curr_desc_ptr; /* DMA Current Descriptor Pointer |
113 | register */ | 86 | register */ |
114 | unsigned long curr_addr_ptr; /* DMA Current Address Pointer | 87 | unsigned long curr_addr_ptr; /* DMA Current Address Pointer |
115 | register */ | 88 | register */ |
@@ -131,19 +104,15 @@ struct dma_register { | |||
131 | 104 | ||
132 | }; | 105 | }; |
133 | 106 | ||
134 | typedef irqreturn_t(*dma_interrupt_t) (int irq, void *dev_id); | 107 | struct mutex; |
135 | |||
136 | struct dma_channel { | 108 | struct dma_channel { |
137 | struct mutex dmalock; | 109 | struct mutex dmalock; |
138 | char *device_id; | 110 | const char *device_id; |
139 | enum dma_chan_status chan_status; | 111 | enum dma_chan_status chan_status; |
140 | struct dma_register *regs; | 112 | volatile struct dma_register *regs; |
141 | struct dmasg *sg; /* large mode descriptor */ | 113 | struct dmasg *sg; /* large mode descriptor */ |
142 | unsigned int ctrl_num; /* controller number */ | 114 | unsigned int irq; |
143 | dma_interrupt_t irq_callback; | ||
144 | void *data; | 115 | void *data; |
145 | unsigned int dma_enable_flag; | ||
146 | unsigned int loopback_flag; | ||
147 | #ifdef CONFIG_PM | 116 | #ifdef CONFIG_PM |
148 | unsigned short saved_peripheral_map; | 117 | unsigned short saved_peripheral_map; |
149 | #endif | 118 | #endif |
@@ -157,49 +126,132 @@ void blackfin_dma_resume(void); | |||
157 | /******************************************************************************* | 126 | /******************************************************************************* |
158 | * DMA API's | 127 | * DMA API's |
159 | *******************************************************************************/ | 128 | *******************************************************************************/ |
160 | /* functions to set register mode */ | 129 | extern struct dma_channel dma_ch[MAX_DMA_CHANNELS]; |
161 | void set_dma_start_addr(unsigned int channel, unsigned long addr); | 130 | extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS]; |
162 | void set_dma_next_desc_addr(unsigned int channel, unsigned long addr); | 131 | extern int channel2irq(unsigned int channel); |
163 | void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr); | 132 | |
164 | void set_dma_x_count(unsigned int channel, unsigned short x_count); | 133 | static inline void set_dma_start_addr(unsigned int channel, unsigned long addr) |
165 | void set_dma_x_modify(unsigned int channel, short x_modify); | 134 | { |
166 | void set_dma_y_count(unsigned int channel, unsigned short y_count); | 135 | dma_ch[channel].regs->start_addr = addr; |
167 | void set_dma_y_modify(unsigned int channel, short y_modify); | 136 | } |
168 | void set_dma_config(unsigned int channel, unsigned short config); | 137 | static inline void set_dma_next_desc_addr(unsigned int channel, void *addr) |
169 | unsigned short set_bfin_dma_config(char direction, char flow_mode, | 138 | { |
170 | char intr_mode, char dma_mode, char width, | 139 | dma_ch[channel].regs->next_desc_ptr = addr; |
171 | char syncmode); | 140 | } |
172 | void set_dma_curr_addr(unsigned int channel, unsigned long addr); | 141 | static inline void set_dma_curr_desc_addr(unsigned int channel, void *addr) |
173 | 142 | { | |
174 | /* get curr status for polling */ | 143 | dma_ch[channel].regs->curr_desc_ptr = addr; |
175 | unsigned short get_dma_curr_irqstat(unsigned int channel); | 144 | } |
176 | unsigned short get_dma_curr_xcount(unsigned int channel); | 145 | static inline void set_dma_x_count(unsigned int channel, unsigned short x_count) |
177 | unsigned short get_dma_curr_ycount(unsigned int channel); | 146 | { |
178 | unsigned long get_dma_next_desc_ptr(unsigned int channel); | 147 | dma_ch[channel].regs->x_count = x_count; |
179 | unsigned long get_dma_curr_desc_ptr(unsigned int channel); | 148 | } |
180 | unsigned long get_dma_curr_addr(unsigned int channel); | 149 | static inline void set_dma_y_count(unsigned int channel, unsigned short y_count) |
181 | 150 | { | |
182 | /* set large DMA mode descriptor */ | 151 | dma_ch[channel].regs->y_count = y_count; |
183 | void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg); | 152 | } |
184 | 153 | static inline void set_dma_x_modify(unsigned int channel, short x_modify) | |
185 | /* check if current channel is in use */ | 154 | { |
186 | int dma_channel_active(unsigned int channel); | 155 | dma_ch[channel].regs->x_modify = x_modify; |
187 | 156 | } | |
188 | /* common functions must be called in any mode */ | 157 | static inline void set_dma_y_modify(unsigned int channel, short y_modify) |
158 | { | ||
159 | dma_ch[channel].regs->y_modify = y_modify; | ||
160 | } | ||
161 | static inline void set_dma_config(unsigned int channel, unsigned short config) | ||
162 | { | ||
163 | dma_ch[channel].regs->cfg = config; | ||
164 | } | ||
165 | static inline void set_dma_curr_addr(unsigned int channel, unsigned long addr) | ||
166 | { | ||
167 | dma_ch[channel].regs->curr_addr_ptr = addr; | ||
168 | } | ||
169 | |||
170 | static inline unsigned short | ||
171 | set_bfin_dma_config(char direction, char flow_mode, | ||
172 | char intr_mode, char dma_mode, char width, char syncmode) | ||
173 | { | ||
174 | return (direction << 1) | (width << 2) | (dma_mode << 4) | | ||
175 | (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5); | ||
176 | } | ||
177 | |||
178 | static inline unsigned short get_dma_curr_irqstat(unsigned int channel) | ||
179 | { | ||
180 | return dma_ch[channel].regs->irq_status; | ||
181 | } | ||
182 | static inline unsigned short get_dma_curr_xcount(unsigned int channel) | ||
183 | { | ||
184 | return dma_ch[channel].regs->curr_x_count; | ||
185 | } | ||
186 | static inline unsigned short get_dma_curr_ycount(unsigned int channel) | ||
187 | { | ||
188 | return dma_ch[channel].regs->curr_y_count; | ||
189 | } | ||
190 | static inline void *get_dma_next_desc_ptr(unsigned int channel) | ||
191 | { | ||
192 | return dma_ch[channel].regs->next_desc_ptr; | ||
193 | } | ||
194 | static inline void *get_dma_curr_desc_ptr(unsigned int channel) | ||
195 | { | ||
196 | return dma_ch[channel].regs->curr_desc_ptr; | ||
197 | } | ||
198 | static inline unsigned short get_dma_config(unsigned int channel) | ||
199 | { | ||
200 | return dma_ch[channel].regs->cfg; | ||
201 | } | ||
202 | static inline unsigned long get_dma_curr_addr(unsigned int channel) | ||
203 | { | ||
204 | return dma_ch[channel].regs->curr_addr_ptr; | ||
205 | } | ||
206 | |||
207 | static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize) | ||
208 | { | ||
209 | dma_ch[channel].regs->cfg = | ||
210 | (dma_ch[channel].regs->cfg & ~(0xf << 8)) | | ||
211 | ((ndsize & 0xf) << 8); | ||
212 | dma_ch[channel].regs->next_desc_ptr = sg; | ||
213 | } | ||
214 | |||
215 | static inline int dma_channel_active(unsigned int channel) | ||
216 | { | ||
217 | if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) | ||
218 | return 0; | ||
219 | else | ||
220 | return 1; | ||
221 | } | ||
222 | |||
223 | static inline void disable_dma(unsigned int channel) | ||
224 | { | ||
225 | dma_ch[channel].regs->cfg &= ~DMAEN; | ||
226 | SSYNC(); | ||
227 | dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; | ||
228 | } | ||
229 | static inline void enable_dma(unsigned int channel) | ||
230 | { | ||
231 | dma_ch[channel].regs->curr_x_count = 0; | ||
232 | dma_ch[channel].regs->curr_y_count = 0; | ||
233 | dma_ch[channel].regs->cfg |= DMAEN; | ||
234 | dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED; | ||
235 | } | ||
189 | void free_dma(unsigned int channel); | 236 | void free_dma(unsigned int channel); |
190 | int dma_channel_active(unsigned int channel); /* check if a channel is in use */ | 237 | int request_dma(unsigned int channel, const char *device_id); |
191 | void disable_dma(unsigned int channel); | 238 | int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data); |
192 | void enable_dma(unsigned int channel); | 239 | |
193 | int request_dma(unsigned int channel, char *device_id); | 240 | static inline void dma_disable_irq(unsigned int channel) |
194 | int set_dma_callback(unsigned int channel, dma_interrupt_t callback, | 241 | { |
195 | void *data); | 242 | disable_irq(dma_ch[channel].irq); |
196 | void dma_disable_irq(unsigned int channel); | 243 | } |
197 | void dma_enable_irq(unsigned int channel); | 244 | static inline void dma_enable_irq(unsigned int channel) |
198 | void clear_dma_irqstat(unsigned int channel); | 245 | { |
246 | enable_irq(dma_ch[channel].irq); | ||
247 | } | ||
248 | static inline void clear_dma_irqstat(unsigned int channel) | ||
249 | { | ||
250 | dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR; | ||
251 | } | ||
252 | |||
199 | void *dma_memcpy(void *dest, const void *src, size_t count); | 253 | void *dma_memcpy(void *dest, const void *src, size_t count); |
200 | void *safe_dma_memcpy(void *dest, const void *src, size_t count); | 254 | void *safe_dma_memcpy(void *dest, const void *src, size_t count); |
201 | 255 | void blackfin_dma_early_init(void); | |
202 | extern int channel2irq(unsigned int channel); | ||
203 | extern struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL]; | ||
204 | 256 | ||
205 | #endif | 257 | #endif |