aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-03-11 20:39:49 -0400
committerVinod Koul <vinod.koul@intel.com>2015-03-18 04:27:54 -0400
commit3cd44dcd35a6618df88c51561290dc02fb35b8e2 (patch)
tree35654cc0a5248615f501a5502eec561e1faf38e0 /drivers/dma/sh
parentc078c62a752872fb83f56e41794dd61d5ea570a0 (diff)
dmaengine: remove Renesas Audio DMAC peri peri
Renesas R-Car sound (= rsnd) needs 2 DMAC which are called as Audio DMAC (= 1st DMAC) and Audio DMAC peri peri (2nd DMAC). And rsnd had assumed that 1st / 2nd DMACs are implemented as DMAEngine. But, in result of DMA ML discussion, 2nd DMAC was concluded that it is not a general purpose DMAC (2nd DMAC is for Device to Device inside sound system). Additionally, current DMAEngine can't support Device to Device, and we don't have correct DT bindings for it at this point. So the easiest solution for it is that move it from DMAEngine to rsnd driver. Audio DMAC peri peri on DMAEngine is no longer needed. remove it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/dma/sh')
-rw-r--r--drivers/dma/sh/Kconfig6
-rw-r--r--drivers/dma/sh/Makefile1
-rw-r--r--drivers/dma/sh/rcar-audmapp.c376
3 files changed, 0 insertions, 383 deletions
diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig
index 8190ad225a1b..725f6b4d7625 100644
--- a/drivers/dma/sh/Kconfig
+++ b/drivers/dma/sh/Kconfig
@@ -51,12 +51,6 @@ config RCAR_HPB_DMAE
51 help 51 help
52 Enable support for the Renesas R-Car series DMA controllers. 52 Enable support for the Renesas R-Car series DMA controllers.
53 53
54config RCAR_AUDMAC_PP
55 tristate "Renesas R-Car Audio DMAC Peripheral Peripheral support"
56 depends on SH_DMAE_BASE
57 help
58 Enable support for the Renesas R-Car Audio DMAC Peripheral Peripheral controllers.
59
60config RCAR_DMAC 54config RCAR_DMAC
61 tristate "Renesas R-Car Gen2 DMA Controller" 55 tristate "Renesas R-Car Gen2 DMA Controller"
62 depends on ARCH_SHMOBILE || COMPILE_TEST 56 depends on ARCH_SHMOBILE || COMPILE_TEST
diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
index 2852f9db61a4..489609b7fbd1 100644
--- a/drivers/dma/sh/Makefile
+++ b/drivers/dma/sh/Makefile
@@ -15,5 +15,4 @@ obj-$(CONFIG_SH_DMAE) += shdma.o
15 15
16obj-$(CONFIG_SUDMAC) += sudmac.o 16obj-$(CONFIG_SUDMAC) += sudmac.o
17obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o 17obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o
18obj-$(CONFIG_RCAR_AUDMAC_PP) += rcar-audmapp.o
19obj-$(CONFIG_RCAR_DMAC) += rcar-dmac.o 18obj-$(CONFIG_RCAR_DMAC) += rcar-dmac.o
diff --git a/drivers/dma/sh/rcar-audmapp.c b/drivers/dma/sh/rcar-audmapp.c
deleted file mode 100644
index d95bbdd721f4..000000000000
--- a/drivers/dma/sh/rcar-audmapp.c
+++ /dev/null
@@ -1,376 +0,0 @@
1/*
2 * This is for Renesas R-Car Audio-DMAC-peri-peri.
3 *
4 * Copyright (C) 2014 Renesas Electronics Corporation
5 * Copyright (C) 2014 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * based on the drivers/dma/sh/shdma.c
8 *
9 * Copyright (C) 2011-2012 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
10 * Copyright (C) 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
11 * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved.
12 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
13 *
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 */
20#include <linux/delay.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/dmaengine.h>
25#include <linux/of_dma.h>
26#include <linux/platform_data/dma-rcar-audmapp.h>
27#include <linux/platform_device.h>
28#include <linux/shdma-base.h>
29
30/*
31 * DMA register
32 */
33#define PDMASAR 0x00
34#define PDMADAR 0x04
35#define PDMACHCR 0x0c
36
37/* PDMACHCR */
38#define PDMACHCR_DE (1 << 0)
39
40#define AUDMAPP_MAX_CHANNELS 29
41
42/* Default MEMCPY transfer size = 2^2 = 4 bytes */
43#define LOG2_DEFAULT_XFER_SIZE 2
44#define AUDMAPP_SLAVE_NUMBER 256
45#define AUDMAPP_LEN_MAX (16 * 1024 * 1024)
46
47struct audmapp_chan {
48 struct shdma_chan shdma_chan;
49 void __iomem *base;
50 dma_addr_t slave_addr;
51 u32 chcr;
52};
53
54struct audmapp_device {
55 struct shdma_dev shdma_dev;
56 struct audmapp_pdata *pdata;
57 struct device *dev;
58 void __iomem *chan_reg;
59};
60
61struct audmapp_desc {
62 struct shdma_desc shdma_desc;
63 dma_addr_t src;
64 dma_addr_t dst;
65};
66
67#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
68
69#define to_chan(chan) container_of(chan, struct audmapp_chan, shdma_chan)
70#define to_desc(sdesc) container_of(sdesc, struct audmapp_desc, shdma_desc)
71#define to_dev(chan) container_of(chan->shdma_chan.dma_chan.device, \
72 struct audmapp_device, shdma_dev.dma_dev)
73
74static void audmapp_write(struct audmapp_chan *auchan, u32 data, u32 reg)
75{
76 struct audmapp_device *audev = to_dev(auchan);
77 struct device *dev = audev->dev;
78
79 dev_dbg(dev, "w %p : %08x\n", auchan->base + reg, data);
80
81 iowrite32(data, auchan->base + reg);
82}
83
84static u32 audmapp_read(struct audmapp_chan *auchan, u32 reg)
85{
86 return ioread32(auchan->base + reg);
87}
88
89static void audmapp_halt(struct shdma_chan *schan)
90{
91 struct audmapp_chan *auchan = to_chan(schan);
92 int i;
93
94 audmapp_write(auchan, 0, PDMACHCR);
95
96 for (i = 0; i < 1024; i++) {
97 if (0 == audmapp_read(auchan, PDMACHCR))
98 return;
99 udelay(1);
100 }
101}
102
103static void audmapp_start_xfer(struct shdma_chan *schan,
104 struct shdma_desc *sdesc)
105{
106 struct audmapp_chan *auchan = to_chan(schan);
107 struct audmapp_device *audev = to_dev(auchan);
108 struct audmapp_desc *desc = to_desc(sdesc);
109 struct device *dev = audev->dev;
110 u32 chcr = auchan->chcr | PDMACHCR_DE;
111
112 dev_dbg(dev, "src/dst/chcr = %pad/%pad/%08x\n",
113 &desc->src, &desc->dst, chcr);
114
115 audmapp_write(auchan, desc->src, PDMASAR);
116 audmapp_write(auchan, desc->dst, PDMADAR);
117 audmapp_write(auchan, chcr, PDMACHCR);
118}
119
120static int audmapp_get_config(struct audmapp_chan *auchan, int slave_id,
121 u32 *chcr, dma_addr_t *dst)
122{
123 struct audmapp_device *audev = to_dev(auchan);
124 struct audmapp_pdata *pdata = audev->pdata;
125 struct audmapp_slave_config *cfg;
126 int i;
127
128 *chcr = 0;
129 *dst = 0;
130
131 if (!pdata) { /* DT */
132 *chcr = ((u32)slave_id) << 16;
133 auchan->shdma_chan.slave_id = (slave_id) >> 8;
134 return 0;
135 }
136
137 /* non-DT */
138
139 if (slave_id >= AUDMAPP_SLAVE_NUMBER)
140 return -ENXIO;
141
142 for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++)
143 if (cfg->slave_id == slave_id) {
144 *chcr = cfg->chcr;
145 *dst = cfg->dst;
146 return 0;
147 }
148
149 return -ENXIO;
150}
151
152static int audmapp_set_slave(struct shdma_chan *schan, int slave_id,
153 dma_addr_t slave_addr, bool try)
154{
155 struct audmapp_chan *auchan = to_chan(schan);
156 u32 chcr;
157 dma_addr_t dst;
158 int ret;
159
160 ret = audmapp_get_config(auchan, slave_id, &chcr, &dst);
161 if (ret < 0)
162 return ret;
163
164 if (try)
165 return 0;
166
167 auchan->chcr = chcr;
168 auchan->slave_addr = slave_addr ? : dst;
169
170 return 0;
171}
172
173static int audmapp_desc_setup(struct shdma_chan *schan,
174 struct shdma_desc *sdesc,
175 dma_addr_t src, dma_addr_t dst, size_t *len)
176{
177 struct audmapp_desc *desc = to_desc(sdesc);
178
179 if (*len > (size_t)AUDMAPP_LEN_MAX)
180 *len = (size_t)AUDMAPP_LEN_MAX;
181
182 desc->src = src;
183 desc->dst = dst;
184
185 return 0;
186}
187
188static void audmapp_setup_xfer(struct shdma_chan *schan,
189 int slave_id)
190{
191}
192
193static dma_addr_t audmapp_slave_addr(struct shdma_chan *schan)
194{
195 struct audmapp_chan *auchan = to_chan(schan);
196
197 return auchan->slave_addr;
198}
199
200static bool audmapp_channel_busy(struct shdma_chan *schan)
201{
202 struct audmapp_chan *auchan = to_chan(schan);
203 u32 chcr = audmapp_read(auchan, PDMACHCR);
204
205 return chcr & ~PDMACHCR_DE;
206}
207
208static bool audmapp_desc_completed(struct shdma_chan *schan,
209 struct shdma_desc *sdesc)
210{
211 return true;
212}
213
214static struct shdma_desc *audmapp_embedded_desc(void *buf, int i)
215{
216 return &((struct audmapp_desc *)buf)[i].shdma_desc;
217}
218
219static const struct shdma_ops audmapp_shdma_ops = {
220 .halt_channel = audmapp_halt,
221 .desc_setup = audmapp_desc_setup,
222 .set_slave = audmapp_set_slave,
223 .start_xfer = audmapp_start_xfer,
224 .embedded_desc = audmapp_embedded_desc,
225 .setup_xfer = audmapp_setup_xfer,
226 .slave_addr = audmapp_slave_addr,
227 .channel_busy = audmapp_channel_busy,
228 .desc_completed = audmapp_desc_completed,
229};
230
231static int audmapp_chan_probe(struct platform_device *pdev,
232 struct audmapp_device *audev, int id)
233{
234 struct shdma_dev *sdev = &audev->shdma_dev;
235 struct audmapp_chan *auchan;
236 struct shdma_chan *schan;
237 struct device *dev = audev->dev;
238
239 auchan = devm_kzalloc(dev, sizeof(*auchan), GFP_KERNEL);
240 if (!auchan)
241 return -ENOMEM;
242
243 schan = &auchan->shdma_chan;
244 schan->max_xfer_len = AUDMAPP_LEN_MAX;
245
246 shdma_chan_probe(sdev, schan, id);
247
248 auchan->base = audev->chan_reg + 0x20 + (0x10 * id);
249 dev_dbg(dev, "%02d : %p / %p", id, auchan->base, audev->chan_reg);
250
251 return 0;
252}
253
254static void audmapp_chan_remove(struct audmapp_device *audev)
255{
256 struct shdma_chan *schan;
257 int i;
258
259 shdma_for_each_chan(schan, &audev->shdma_dev, i) {
260 BUG_ON(!schan);
261 shdma_chan_remove(schan);
262 }
263}
264
265static struct dma_chan *audmapp_of_xlate(struct of_phandle_args *dma_spec,
266 struct of_dma *ofdma)
267{
268 dma_cap_mask_t mask;
269 struct dma_chan *chan;
270 u32 chcr = dma_spec->args[0];
271
272 if (dma_spec->args_count != 1)
273 return NULL;
274
275 dma_cap_zero(mask);
276 dma_cap_set(DMA_SLAVE, mask);
277
278 chan = dma_request_channel(mask, shdma_chan_filter, NULL);
279 if (chan)
280 to_shdma_chan(chan)->hw_req = chcr;
281
282 return chan;
283}
284
285static int audmapp_probe(struct platform_device *pdev)
286{
287 struct audmapp_pdata *pdata = pdev->dev.platform_data;
288 struct device_node *np = pdev->dev.of_node;
289 struct audmapp_device *audev;
290 struct shdma_dev *sdev;
291 struct dma_device *dma_dev;
292 struct resource *res;
293 int err, i;
294
295 if (np)
296 of_dma_controller_register(np, audmapp_of_xlate, pdev);
297 else if (!pdata)
298 return -ENODEV;
299
300 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
301
302 audev = devm_kzalloc(&pdev->dev, sizeof(*audev), GFP_KERNEL);
303 if (!audev)
304 return -ENOMEM;
305
306 audev->dev = &pdev->dev;
307 audev->pdata = pdata;
308 audev->chan_reg = devm_ioremap_resource(&pdev->dev, res);
309 if (IS_ERR(audev->chan_reg))
310 return PTR_ERR(audev->chan_reg);
311
312 sdev = &audev->shdma_dev;
313 sdev->ops = &audmapp_shdma_ops;
314 sdev->desc_size = sizeof(struct audmapp_desc);
315
316 dma_dev = &sdev->dma_dev;
317 dma_dev->copy_align = LOG2_DEFAULT_XFER_SIZE;
318 dma_cap_set(DMA_SLAVE, dma_dev->cap_mask);
319
320 err = shdma_init(&pdev->dev, sdev, AUDMAPP_MAX_CHANNELS);
321 if (err < 0)
322 return err;
323
324 platform_set_drvdata(pdev, audev);
325
326 /* Create DMA Channel */
327 for (i = 0; i < AUDMAPP_MAX_CHANNELS; i++) {
328 err = audmapp_chan_probe(pdev, audev, i);
329 if (err)
330 goto chan_probe_err;
331 }
332
333 err = dma_async_device_register(dma_dev);
334 if (err < 0)
335 goto chan_probe_err;
336
337 return err;
338
339chan_probe_err:
340 audmapp_chan_remove(audev);
341 shdma_cleanup(sdev);
342
343 return err;
344}
345
346static int audmapp_remove(struct platform_device *pdev)
347{
348 struct audmapp_device *audev = platform_get_drvdata(pdev);
349 struct dma_device *dma_dev = &audev->shdma_dev.dma_dev;
350
351 dma_async_device_unregister(dma_dev);
352
353 audmapp_chan_remove(audev);
354 shdma_cleanup(&audev->shdma_dev);
355
356 return 0;
357}
358
359static const struct of_device_id audmapp_of_match[] = {
360 { .compatible = "renesas,rcar-audmapp", },
361 {},
362};
363
364static struct platform_driver audmapp_driver = {
365 .probe = audmapp_probe,
366 .remove = audmapp_remove,
367 .driver = {
368 .name = "rcar-audmapp-engine",
369 .of_match_table = audmapp_of_match,
370 },
371};
372module_platform_driver(audmapp_driver);
373
374MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
375MODULE_DESCRIPTION("Renesas R-Car Audio DMAC peri-peri driver");
376MODULE_LICENSE("GPL");