Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/blackfin/include/asm/dma.h
15126 views
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/atomic.h>
14
#include <asm/blackfin.h>
15
#include <asm/page.h>
16
#include <asm-generic/dma.h>
17
#include <asm/bfin_dma.h>
18
19
/*-------------------------
20
* config reg bits value
21
*-------------------------*/
22
#define DATA_SIZE_8 0
23
#define DATA_SIZE_16 1
24
#define DATA_SIZE_32 2
25
26
#define DMA_FLOW_STOP 0
27
#define DMA_FLOW_AUTO 1
28
#define DMA_FLOW_ARRAY 4
29
#define DMA_FLOW_SMALL 6
30
#define DMA_FLOW_LARGE 7
31
32
#define DIMENSION_LINEAR 0
33
#define DIMENSION_2D 1
34
35
#define DIR_READ 0
36
#define DIR_WRITE 1
37
38
#define INTR_DISABLE 0
39
#define INTR_ON_BUF 2
40
#define INTR_ON_ROW 3
41
42
#define DMA_NOSYNC_KEEP_DMA_BUF 0
43
#define DMA_SYNC_RESTART 1
44
45
struct dmasg {
46
void *next_desc_addr;
47
unsigned long start_addr;
48
unsigned short cfg;
49
unsigned short x_count;
50
short x_modify;
51
unsigned short y_count;
52
short y_modify;
53
} __attribute__((packed));
54
55
struct dma_register {
56
void *next_desc_ptr; /* DMA Next Descriptor Pointer register */
57
unsigned long start_addr; /* DMA Start address register */
58
59
unsigned short cfg; /* DMA Configuration register */
60
unsigned short dummy1; /* DMA Configuration register */
61
62
unsigned long reserved;
63
64
unsigned short x_count; /* DMA x_count register */
65
unsigned short dummy2;
66
67
short x_modify; /* DMA x_modify register */
68
unsigned short dummy3;
69
70
unsigned short y_count; /* DMA y_count register */
71
unsigned short dummy4;
72
73
short y_modify; /* DMA y_modify register */
74
unsigned short dummy5;
75
76
void *curr_desc_ptr; /* DMA Current Descriptor Pointer
77
register */
78
unsigned long curr_addr_ptr; /* DMA Current Address Pointer
79
register */
80
unsigned short irq_status; /* DMA irq status register */
81
unsigned short dummy6;
82
83
unsigned short peripheral_map; /* DMA peripheral map register */
84
unsigned short dummy7;
85
86
unsigned short curr_x_count; /* DMA Current x-count register */
87
unsigned short dummy8;
88
89
unsigned long reserved2;
90
91
unsigned short curr_y_count; /* DMA Current y-count register */
92
unsigned short dummy9;
93
94
unsigned long reserved3;
95
96
};
97
98
struct dma_channel {
99
const char *device_id;
100
atomic_t chan_status;
101
volatile struct dma_register *regs;
102
struct dmasg *sg; /* large mode descriptor */
103
unsigned int irq;
104
void *data;
105
#ifdef CONFIG_PM
106
unsigned short saved_peripheral_map;
107
#endif
108
};
109
110
#ifdef CONFIG_PM
111
int blackfin_dma_suspend(void);
112
void blackfin_dma_resume(void);
113
#endif
114
115
/*******************************************************************************
116
* DMA API's
117
*******************************************************************************/
118
extern struct dma_channel dma_ch[MAX_DMA_CHANNELS];
119
extern struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS];
120
extern int channel2irq(unsigned int channel);
121
122
static inline void set_dma_start_addr(unsigned int channel, unsigned long addr)
123
{
124
dma_ch[channel].regs->start_addr = addr;
125
}
126
static inline void set_dma_next_desc_addr(unsigned int channel, void *addr)
127
{
128
dma_ch[channel].regs->next_desc_ptr = addr;
129
}
130
static inline void set_dma_curr_desc_addr(unsigned int channel, void *addr)
131
{
132
dma_ch[channel].regs->curr_desc_ptr = addr;
133
}
134
static inline void set_dma_x_count(unsigned int channel, unsigned short x_count)
135
{
136
dma_ch[channel].regs->x_count = x_count;
137
}
138
static inline void set_dma_y_count(unsigned int channel, unsigned short y_count)
139
{
140
dma_ch[channel].regs->y_count = y_count;
141
}
142
static inline void set_dma_x_modify(unsigned int channel, short x_modify)
143
{
144
dma_ch[channel].regs->x_modify = x_modify;
145
}
146
static inline void set_dma_y_modify(unsigned int channel, short y_modify)
147
{
148
dma_ch[channel].regs->y_modify = y_modify;
149
}
150
static inline void set_dma_config(unsigned int channel, unsigned short config)
151
{
152
dma_ch[channel].regs->cfg = config;
153
}
154
static inline void set_dma_curr_addr(unsigned int channel, unsigned long addr)
155
{
156
dma_ch[channel].regs->curr_addr_ptr = addr;
157
}
158
159
static inline unsigned short
160
set_bfin_dma_config(char direction, char flow_mode,
161
char intr_mode, char dma_mode, char width, char syncmode)
162
{
163
return (direction << 1) | (width << 2) | (dma_mode << 4) |
164
(intr_mode << 6) | (flow_mode << 12) | (syncmode << 5);
165
}
166
167
static inline unsigned short get_dma_curr_irqstat(unsigned int channel)
168
{
169
return dma_ch[channel].regs->irq_status;
170
}
171
static inline unsigned short get_dma_curr_xcount(unsigned int channel)
172
{
173
return dma_ch[channel].regs->curr_x_count;
174
}
175
static inline unsigned short get_dma_curr_ycount(unsigned int channel)
176
{
177
return dma_ch[channel].regs->curr_y_count;
178
}
179
static inline void *get_dma_next_desc_ptr(unsigned int channel)
180
{
181
return dma_ch[channel].regs->next_desc_ptr;
182
}
183
static inline void *get_dma_curr_desc_ptr(unsigned int channel)
184
{
185
return dma_ch[channel].regs->curr_desc_ptr;
186
}
187
static inline unsigned short get_dma_config(unsigned int channel)
188
{
189
return dma_ch[channel].regs->cfg;
190
}
191
static inline unsigned long get_dma_curr_addr(unsigned int channel)
192
{
193
return dma_ch[channel].regs->curr_addr_ptr;
194
}
195
196
static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize)
197
{
198
/* Make sure the internal data buffers in the core are drained
199
* so that the DMA descriptors are completely written when the
200
* DMA engine goes to fetch them below.
201
*/
202
SSYNC();
203
204
dma_ch[channel].regs->next_desc_ptr = sg;
205
dma_ch[channel].regs->cfg =
206
(dma_ch[channel].regs->cfg & ~(0xf << 8)) |
207
((ndsize & 0xf) << 8);
208
}
209
210
static inline int dma_channel_active(unsigned int channel)
211
{
212
return atomic_read(&dma_ch[channel].chan_status);
213
}
214
215
static inline void disable_dma(unsigned int channel)
216
{
217
dma_ch[channel].regs->cfg &= ~DMAEN;
218
SSYNC();
219
}
220
static inline void enable_dma(unsigned int channel)
221
{
222
dma_ch[channel].regs->curr_x_count = 0;
223
dma_ch[channel].regs->curr_y_count = 0;
224
dma_ch[channel].regs->cfg |= DMAEN;
225
}
226
int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data);
227
228
static inline void dma_disable_irq(unsigned int channel)
229
{
230
disable_irq(dma_ch[channel].irq);
231
}
232
static inline void dma_disable_irq_nosync(unsigned int channel)
233
{
234
disable_irq_nosync(dma_ch[channel].irq);
235
}
236
static inline void dma_enable_irq(unsigned int channel)
237
{
238
enable_irq(dma_ch[channel].irq);
239
}
240
static inline void clear_dma_irqstat(unsigned int channel)
241
{
242
dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR;
243
}
244
245
void *dma_memcpy(void *dest, const void *src, size_t count);
246
void *dma_memcpy_nocache(void *dest, const void *src, size_t count);
247
void *safe_dma_memcpy(void *dest, const void *src, size_t count);
248
void blackfin_dma_early_init(void);
249
void early_dma_memcpy(void *dest, const void *src, size_t count);
250
void early_dma_memcpy_done(void);
251
252
#endif
253
254