aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx/include/mach/dma.h
blob: 6e7049a796a4eaff8021684b794180f4eb3e541a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/**
 * DOC: EP93xx DMA M2P memory to peripheral and peripheral to memory engine
 *
 * The EP93xx DMA M2P subsystem handles DMA transfers between memory and
 * peripherals. DMA M2P channels are available for audio, UARTs and IrDA.
 * See chapter 10 of the EP93xx users guide for full details on the DMA M2P
 * engine.
 *
 * See sound/soc/ep93xx/ep93xx-pcm.c for an example use of the DMA M2P code.
 *
 */

#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H

#include <linux/list.h>
#include <linux/types.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>

/**
 * struct ep93xx_dma_buffer - Information about a buffer to be transferred
 * using the DMA M2P engine
 *
 * @list: Entry in DMA buffer list
 * @bus_addr: Physical address of the buffer
 * @size: Size of the buffer in bytes
 */
struct ep93xx_dma_buffer {
	struct list_head	list;
	u32			bus_addr;
	u16			size;
};

/**
 * struct ep93xx_dma_m2p_client - Information about a DMA M2P client
 *
 * @name: Unique name for this client
 * @flags: Client flags
 * @cookie: User data to pass to callback functions
 * @buffer_started: Non NULL function to call when a transfer is started.
 * 			The arguments are the user data cookie and the DMA
 *			buffer which is starting.
 * @buffer_finished: Non NULL function to call when a transfer is completed.
 *			The arguments are the user data cookie, the DMA buffer
 *			which has completed, and a boolean flag indicating if
 *			the transfer had an error.
 */
struct ep93xx_dma_m2p_client {
	char			*name;
	u8			flags;
	void			*cookie;
	void			(*buffer_started)(void *cookie,
					struct ep93xx_dma_buffer *buf);
	void			(*buffer_finished)(void *cookie,
					struct ep93xx_dma_buffer *buf,
					int bytes, int error);

	/* private: Internal use only */
	void			*channel;
};

/* DMA M2P ports */
#define EP93XX_DMA_M2P_PORT_I2S1	0x00
#define EP93XX_DMA_M2P_PORT_I2S2	0x01
#define EP93XX_DMA_M2P_PORT_AAC1	0x02
#define EP93XX_DMA_M2P_PORT_AAC2	0x03
#define EP93XX_DMA_M2P_PORT_AAC3	0x04
#define EP93XX_DMA_M2P_PORT_I2S3	0x05
#define EP93XX_DMA_M2P_PORT_UART1	0x06
#define EP93XX_DMA_M2P_PORT_UART2	0x07
#define EP93XX_DMA_M2P_PORT_UART3	0x08
#define EP93XX_DMA_M2P_PORT_IRDA	0x09
#define EP93XX_DMA_M2P_PORT_MASK	0x0f

/* DMA M2P client flags */
#define EP93XX_DMA_M2P_TX		0x00	/* Memory to peripheral */
#define EP93XX_DMA_M2P_RX		0x10	/* Peripheral to memory */

/*
 * DMA M2P client error handling flags. See the EP93xx users guide
 * documentation on the DMA M2P CONTROL register for more details
 */
#define EP93XX_DMA_M2P_ABORT_ON_ERROR	0x20	/* Abort on peripheral error */
#define EP93XX_DMA_M2P_IGNORE_ERROR	0x40	/* Ignore peripheral errors */
#define EP93XX_DMA_M2P_ERROR_MASK	0x60	/* Mask of error bits */

/**
 * ep93xx_dma_m2p_client_register - Register a client with the DMA M2P
 * subsystem
 *
 * @m2p: Client information to register
 * returns 0 on success
 *
 * The DMA M2P subsystem allocates a channel and an interrupt line for the DMA
 * client
 */
int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);

/**
 * ep93xx_dma_m2p_client_unregister - Unregister a client from the DMA M2P
 * subsystem
 *
 * @m2p: Client to unregister
 *
 * Any transfers currently in progress will be completed in hardware, but
 * ignored in software.
 */
void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p);

/**
 * ep93xx_dma_m2p_submit - Submit a DMA M2P transfer
 *
 * @m2p: DMA Client to submit the transfer on
 * @buf: DMA Buffer to submit
 *
 * If the current or next transfer positions are free on the M2P client then
 * the transfer is started immediately. If not, the transfer is added to the
 * list of pending transfers. This function must not be called from the
 * buffer_finished callback for an M2P channel.
 *
 */
void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p,
			   struct ep93xx_dma_buffer *buf);

/**
 * ep93xx_dma_m2p_submit_recursive - Put a DMA transfer on the pending list
 * for an M2P channel
 *
 * @m2p: DMA Client to submit the transfer on
 * @buf: DMA Buffer to submit
 *
 * This function must only be called from the buffer_finished callback for an
 * M2P channel. It is commonly used to add the next transfer in a chained list
 * of DMA transfers.
 */
void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p,
				     struct ep93xx_dma_buffer *buf);

/**
 * ep93xx_dma_m2p_flush - Flush all pending transfers on a DMA M2P client
 *
 * @m2p: DMA client to flush transfers on
 *
 * Any transfers currently in progress will be completed in hardware, but
 * ignored in software.
 *
 */
void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p);

/*
 * M2P channels.
 *
 * Note that these values are also directly used for setting the PPALLOC
 * register.
 */
#define EP93XX_DMA_I2S1		0
#define EP93XX_DMA_I2S2		1
#define EP93XX_DMA_AAC1		2
#define EP93XX_DMA_AAC2		3
#define EP93XX_DMA_AAC3		4
#define EP93XX_DMA_I2S3		5
#define EP93XX_DMA_UART1	6
#define EP93XX_DMA_UART2	7
#define EP93XX_DMA_UART3	8
#define EP93XX_DMA_IRDA		9
/* M2M channels */
#define EP93XX_DMA_SSP		10
#define EP93XX_DMA_IDE		11

/**
 * struct ep93xx_dma_data - configuration data for the EP93xx dmaengine
 * @port: peripheral which is requesting the channel
 * @direction: TX/RX channel
 * @name: optional name for the channel, this is displayed in /proc/interrupts
 *
 * This information is passed as private channel parameter in a filter
 * function. Note that this is only needed for slave/cyclic channels.  For
 * memcpy channels %NULL data should be passed.
 */
struct ep93xx_dma_data {
	int				port;
	enum dma_data_direction		direction;
	const char			*name;
};

/**
 * struct ep93xx_dma_chan_data - platform specific data for a DMA channel
 * @name: name of the channel, used for getting the right clock for the channel
 * @base: mapped registers
 * @irq: interrupt number used by this channel
 */
struct ep93xx_dma_chan_data {
	const char			*name;
	void __iomem			*base;
	int				irq;
};

/**
 * struct ep93xx_dma_platform_data - platform data for the dmaengine driver
 * @channels: array of channels which are passed to the driver
 * @num_channels: number of channels in the array
 *
 * This structure is passed to the DMA engine driver via platform data. For
 * M2P channels, contract is that even channels are for TX and odd for RX.
 * There is no requirement for the M2M channels.
 */
struct ep93xx_dma_platform_data {
	struct ep93xx_dma_chan_data	*channels;
	size_t				num_channels;
};

static inline bool ep93xx_dma_chan_is_m2p(struct dma_chan *chan)
{
	return !strcmp(dev_name(chan->device->dev), "ep93xx-dma-m2p");
}

/**
 * ep93xx_dma_chan_direction - returns direction the channel can be used
 * @chan: channel
 *
 * This function can be used in filter functions to find out whether the
 * channel supports given DMA direction. Only M2P channels have such
 * limitation, for M2M channels the direction is configurable.
 */
static inline enum dma_data_direction
ep93xx_dma_chan_direction(struct dma_chan *chan)
{
	if (!ep93xx_dma_chan_is_m2p(chan))
		return DMA_NONE;

	/* even channels are for TX, odd for RX */
	return (chan->chan_id % 2 == 0) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
}

#endif /* __ASM_ARCH_DMA_H */