aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/jz4740
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-05-30 12:25:05 -0400
committerVinod Koul <vinod.koul@intel.com>2013-07-05 02:10:52 -0400
commit25ce6c35fea0588c7a1b68e55d700c22d9e97ce0 (patch)
tree11b3054e16aaf08282f0c406137c30d0fe8bfd25 /arch/mips/jz4740
parentcdcb90ad48816f51fdb4e93b2a33fe6038ce0949 (diff)
MIPS: jz4740: Remove custom DMA API
Now that all users of the custom jz4740 DMA API have been converted to use the dmaengine API instead we can remove the custom API and move all the code talking to the hardware to the dmaengine driver. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'arch/mips/jz4740')
-rw-r--r--arch/mips/jz4740/Makefile2
-rw-r--r--arch/mips/jz4740/dma.c307
2 files changed, 1 insertions, 308 deletions
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 63bad0e491d0..28e5535dfa9e 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -4,7 +4,7 @@
4 4
5# Object file lists. 5# Object file lists.
6 6
7obj-y += prom.o irq.o time.o reset.o setup.o dma.o \ 7obj-y += prom.o irq.o time.o reset.o setup.o \
8 gpio.o clock.o platform.o timer.o serial.o 8 gpio.o clock.o platform.o timer.o serial.o
9 9
10obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o 10obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
diff --git a/arch/mips/jz4740/dma.c b/arch/mips/jz4740/dma.c
deleted file mode 100644
index 0e34b97efa8c..000000000000
--- a/arch/mips/jz4740/dma.c
+++ /dev/null
@@ -1,307 +0,0 @@
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC DMA support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/spinlock.h>
19#include <linux/clk.h>
20#include <linux/interrupt.h>
21
22#include <linux/dma-mapping.h>
23#include <asm/mach-jz4740/dma.h>
24#include <asm/mach-jz4740/base.h>
25
26#define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20)
27#define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20)
28#define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20)
29#define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20)
30#define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20)
31#define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20)
32#define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20)
33
34#define JZ_REG_DMA_CTRL 0x300
35#define JZ_REG_DMA_IRQ 0x304
36#define JZ_REG_DMA_DOORBELL 0x308
37#define JZ_REG_DMA_DOORBELL_SET 0x30C
38
39#define JZ_DMA_STATUS_CTRL_NO_DESC BIT(31)
40#define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6)
41#define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4)
42#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3)
43#define JZ_DMA_STATUS_CTRL_HALT BIT(2)
44#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1)
45#define JZ_DMA_STATUS_CTRL_ENABLE BIT(0)
46
47#define JZ_DMA_CMD_SRC_INC BIT(23)
48#define JZ_DMA_CMD_DST_INC BIT(22)
49#define JZ_DMA_CMD_RDIL_MASK (0xf << 16)
50#define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14)
51#define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12)
52#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8)
53#define JZ_DMA_CMD_BLOCK_MODE BIT(7)
54#define JZ_DMA_CMD_DESC_VALID BIT(4)
55#define JZ_DMA_CMD_DESC_VALID_MODE BIT(3)
56#define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2)
57#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1)
58#define JZ_DMA_CMD_LINK_ENABLE BIT(0)
59
60#define JZ_DMA_CMD_FLAGS_OFFSET 22
61#define JZ_DMA_CMD_RDIL_OFFSET 16
62#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
63#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
64#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
65#define JZ_DMA_CMD_MODE_OFFSET 7
66
67#define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8)
68#define JZ_DMA_CTRL_HALT BIT(3)
69#define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2)
70#define JZ_DMA_CTRL_ENABLE BIT(0)
71
72
73static void __iomem *jz4740_dma_base;
74static spinlock_t jz4740_dma_lock;
75
76static inline uint32_t jz4740_dma_read(size_t reg)
77{
78 return readl(jz4740_dma_base + reg);
79}
80
81static inline void jz4740_dma_write(size_t reg, uint32_t val)
82{
83 writel(val, jz4740_dma_base + reg);
84}
85
86static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
87{
88 uint32_t val2;
89 val2 = jz4740_dma_read(reg);
90 val2 &= ~mask;
91 val2 |= val;
92 jz4740_dma_write(reg, val2);
93}
94
95struct jz4740_dma_chan {
96 unsigned int id;
97 void *dev;
98 const char *name;
99
100 enum jz4740_dma_flags flags;
101 uint32_t transfer_shift;
102
103 jz4740_dma_complete_callback_t complete_cb;
104
105 unsigned used:1;
106};
107
108#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
109
110struct jz4740_dma_chan jz4740_dma_channels[] = {
111 JZ4740_DMA_CHANNEL(0),
112 JZ4740_DMA_CHANNEL(1),
113 JZ4740_DMA_CHANNEL(2),
114 JZ4740_DMA_CHANNEL(3),
115 JZ4740_DMA_CHANNEL(4),
116 JZ4740_DMA_CHANNEL(5),
117};
118
119struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name)
120{
121 unsigned int i;
122 struct jz4740_dma_chan *dma = NULL;
123
124 spin_lock(&jz4740_dma_lock);
125
126 for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
127 if (!jz4740_dma_channels[i].used) {
128 dma = &jz4740_dma_channels[i];
129 dma->used = 1;
130 break;
131 }
132 }
133
134 spin_unlock(&jz4740_dma_lock);
135
136 if (!dma)
137 return NULL;
138
139 dma->dev = dev;
140 dma->name = name;
141
142 return dma;
143}
144EXPORT_SYMBOL_GPL(jz4740_dma_request);
145
146void jz4740_dma_configure(struct jz4740_dma_chan *dma,
147 const struct jz4740_dma_config *config)
148{
149 uint32_t cmd;
150
151 switch (config->transfer_size) {
152 case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
153 dma->transfer_shift = 1;
154 break;
155 case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
156 dma->transfer_shift = 2;
157 break;
158 case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
159 dma->transfer_shift = 4;
160 break;
161 case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
162 dma->transfer_shift = 5;
163 break;
164 default:
165 dma->transfer_shift = 0;
166 break;
167 }
168
169 cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
170 cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
171 cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
172 cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
173 cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
174 cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
175
176 jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
177 jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), 0);
178 jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
179}
180EXPORT_SYMBOL_GPL(jz4740_dma_configure);
181
182void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
183{
184 jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
185}
186EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
187
188void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
189{
190 jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
191}
192EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
193
194void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
195{
196 count >>= dma->transfer_shift;
197 jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
198}
199EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
200
201void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
202 jz4740_dma_complete_callback_t cb)
203{
204 dma->complete_cb = cb;
205}
206EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
207
208void jz4740_dma_free(struct jz4740_dma_chan *dma)
209{
210 dma->dev = NULL;
211 dma->complete_cb = NULL;
212 dma->used = 0;
213}
214EXPORT_SYMBOL_GPL(jz4740_dma_free);
215
216void jz4740_dma_enable(struct jz4740_dma_chan *dma)
217{
218 jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
219 JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE,
220 JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC |
221 JZ_DMA_STATUS_CTRL_ENABLE);
222
223 jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
224 JZ_DMA_CTRL_ENABLE,
225 JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE);
226}
227EXPORT_SYMBOL_GPL(jz4740_dma_enable);
228
229void jz4740_dma_disable(struct jz4740_dma_chan *dma)
230{
231 jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
232 JZ_DMA_STATUS_CTRL_ENABLE);
233}
234EXPORT_SYMBOL_GPL(jz4740_dma_disable);
235
236uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
237{
238 uint32_t residue;
239 residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
240 return residue << dma->transfer_shift;
241}
242EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
243
244static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
245{
246 (void) jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
247
248 jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
249 JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
250
251 if (dma->complete_cb)
252 dma->complete_cb(dma, 0, dma->dev);
253}
254
255static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
256{
257 uint32_t irq_status;
258 unsigned int i;
259
260 irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
261
262 for (i = 0; i < 6; ++i) {
263 if (irq_status & (1 << i))
264 jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
265 }
266
267 return IRQ_HANDLED;
268}
269
270static int jz4740_dma_init(void)
271{
272 struct clk *clk;
273 unsigned int ret;
274
275 jz4740_dma_base = ioremap(JZ4740_DMAC_BASE_ADDR, 0x400);
276
277 if (!jz4740_dma_base)
278 return -EBUSY;
279
280 spin_lock_init(&jz4740_dma_lock);
281
282 clk = clk_get(NULL, "dma");
283 if (IS_ERR(clk)) {
284 ret = PTR_ERR(clk);
285 printk(KERN_ERR "JZ4740 DMA: Failed to request clock: %d\n",
286 ret);
287 goto err_iounmap;
288 }
289
290 ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
291 if (ret) {
292 printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret);
293 goto err_clkput;
294 }
295
296 clk_prepare_enable(clk);
297
298 return 0;
299
300err_clkput:
301 clk_put(clk);
302
303err_iounmap:
304 iounmap(jz4740_dma_base);
305 return ret;
306}
307arch_initcall(jz4740_dma_init);