diff options
Diffstat (limited to 'arch/blackfin/include/asm/dma.h')
-rw-r--r-- | arch/blackfin/include/asm/dma.h | 93 |
1 files changed, 54 insertions, 39 deletions
diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index c9a59622e23f..bd2e62243abe 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h | |||
@@ -10,46 +10,70 @@ | |||
10 | 10 | ||
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <mach/dma.h> | 12 | #include <mach/dma.h> |
13 | #include <asm/atomic.h> | ||
13 | #include <asm/blackfin.h> | 14 | #include <asm/blackfin.h> |
14 | #include <asm/page.h> | 15 | #include <asm/page.h> |
15 | 16 | #include <asm-generic/dma.h> | |
16 | #define MAX_DMA_ADDRESS PAGE_OFFSET | 17 | |
17 | 18 | /* DMA_CONFIG Masks */ | |
18 | /***************************************************************************** | 19 | #define DMAEN 0x0001 /* DMA Channel Enable */ |
19 | * Generic DMA Declarations | 20 | #define WNR 0x0002 /* Channel Direction (W/R*) */ |
20 | * | 21 | #define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ |
21 | ****************************************************************************/ | 22 | #define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ |
22 | enum dma_chan_status { | 23 | #define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ |
23 | DMA_CHANNEL_FREE, | 24 | #define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ |
24 | DMA_CHANNEL_REQUESTED, | 25 | #define RESTART 0x0020 /* DMA Buffer Clear */ |
25 | DMA_CHANNEL_ENABLED, | 26 | #define DI_SEL 0x0040 /* Data Interrupt Timing Select */ |
26 | }; | 27 | #define DI_EN 0x0080 /* Data Interrupt Enable */ |
28 | #define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ | ||
29 | #define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ | ||
30 | #define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ | ||
31 | #define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ | ||
32 | #define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ | ||
33 | #define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ | ||
34 | #define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ | ||
35 | #define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ | ||
36 | #define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ | ||
37 | #define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ | ||
38 | #define NDSIZE 0x0f00 /* Next Descriptor Size */ | ||
39 | #define DMAFLOW 0x7000 /* Flow Control */ | ||
40 | #define DMAFLOW_STOP 0x0000 /* Stop Mode */ | ||
41 | #define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ | ||
42 | #define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ | ||
43 | #define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ | ||
44 | #define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ | ||
45 | |||
46 | /* DMA_IRQ_STATUS Masks */ | ||
47 | #define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ | ||
48 | #define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ | ||
49 | #define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ | ||
50 | #define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ | ||
27 | 51 | ||
28 | /*------------------------- | 52 | /*------------------------- |
29 | * config reg bits value | 53 | * config reg bits value |
30 | *-------------------------*/ | 54 | *-------------------------*/ |
31 | #define DATA_SIZE_8 0 | 55 | #define DATA_SIZE_8 0 |
32 | #define DATA_SIZE_16 1 | 56 | #define DATA_SIZE_16 1 |
33 | #define DATA_SIZE_32 2 | 57 | #define DATA_SIZE_32 2 |
34 | 58 | ||
35 | #define DMA_FLOW_STOP 0 | 59 | #define DMA_FLOW_STOP 0 |
36 | #define DMA_FLOW_AUTO 1 | 60 | #define DMA_FLOW_AUTO 1 |
37 | #define DMA_FLOW_ARRAY 4 | 61 | #define DMA_FLOW_ARRAY 4 |
38 | #define DMA_FLOW_SMALL 6 | 62 | #define DMA_FLOW_SMALL 6 |
39 | #define DMA_FLOW_LARGE 7 | 63 | #define DMA_FLOW_LARGE 7 |
40 | 64 | ||
41 | #define DIMENSION_LINEAR 0 | 65 | #define DIMENSION_LINEAR 0 |
42 | #define DIMENSION_2D 1 | 66 | #define DIMENSION_2D 1 |
43 | 67 | ||
44 | #define DIR_READ 0 | 68 | #define DIR_READ 0 |
45 | #define DIR_WRITE 1 | 69 | #define DIR_WRITE 1 |
46 | 70 | ||
47 | #define INTR_DISABLE 0 | 71 | #define INTR_DISABLE 0 |
48 | #define INTR_ON_BUF 2 | 72 | #define INTR_ON_BUF 2 |
49 | #define INTR_ON_ROW 3 | 73 | #define INTR_ON_ROW 3 |
50 | 74 | ||
51 | #define DMA_NOSYNC_KEEP_DMA_BUF 0 | 75 | #define DMA_NOSYNC_KEEP_DMA_BUF 0 |
52 | #define DMA_SYNC_RESTART 1 | 76 | #define DMA_SYNC_RESTART 1 |
53 | 77 | ||
54 | struct dmasg { | 78 | struct dmasg { |
55 | void *next_desc_addr; | 79 | void *next_desc_addr; |
@@ -104,11 +128,9 @@ struct dma_register { | |||
104 | 128 | ||
105 | }; | 129 | }; |
106 | 130 | ||
107 | struct mutex; | ||
108 | struct dma_channel { | 131 | struct dma_channel { |
109 | struct mutex dmalock; | ||
110 | const char *device_id; | 132 | const char *device_id; |
111 | enum dma_chan_status chan_status; | 133 | atomic_t chan_status; |
112 | volatile struct dma_register *regs; | 134 | volatile struct dma_register *regs; |
113 | struct dmasg *sg; /* large mode descriptor */ | 135 | struct dmasg *sg; /* large mode descriptor */ |
114 | unsigned int irq; | 136 | unsigned int irq; |
@@ -220,27 +242,20 @@ static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize | |||
220 | 242 | ||
221 | static inline int dma_channel_active(unsigned int channel) | 243 | static inline int dma_channel_active(unsigned int channel) |
222 | { | 244 | { |
223 | if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) | 245 | return atomic_read(&dma_ch[channel].chan_status); |
224 | return 0; | ||
225 | else | ||
226 | return 1; | ||
227 | } | 246 | } |
228 | 247 | ||
229 | static inline void disable_dma(unsigned int channel) | 248 | static inline void disable_dma(unsigned int channel) |
230 | { | 249 | { |
231 | dma_ch[channel].regs->cfg &= ~DMAEN; | 250 | dma_ch[channel].regs->cfg &= ~DMAEN; |
232 | SSYNC(); | 251 | SSYNC(); |
233 | dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; | ||
234 | } | 252 | } |
235 | static inline void enable_dma(unsigned int channel) | 253 | static inline void enable_dma(unsigned int channel) |
236 | { | 254 | { |
237 | dma_ch[channel].regs->curr_x_count = 0; | 255 | dma_ch[channel].regs->curr_x_count = 0; |
238 | dma_ch[channel].regs->curr_y_count = 0; | 256 | dma_ch[channel].regs->curr_y_count = 0; |
239 | dma_ch[channel].regs->cfg |= DMAEN; | 257 | dma_ch[channel].regs->cfg |= DMAEN; |
240 | dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED; | ||
241 | } | 258 | } |
242 | void free_dma(unsigned int channel); | ||
243 | int request_dma(unsigned int channel, const char *device_id); | ||
244 | int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data); | 259 | int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data); |
245 | 260 | ||
246 | static inline void dma_disable_irq(unsigned int channel) | 261 | static inline void dma_disable_irq(unsigned int channel) |