blob: 4905e82c378862c96eb613498424b212dd314ad7 [file] [log] [blame]
Kuninori Morimotobfe834b2015-02-20 10:25:55 +00001/*
2 * Renesas R-Car Audio DMAC support
3 *
4 * Copyright (C) 2015 Renesas Electronics Corp.
5 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
Kuninori Morimoto288f3922015-02-20 10:27:42 +000011#include <linux/delay.h>
Kuninori Morimoto72adc612015-02-20 10:31:23 +000012#include <linux/of_dma.h>
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000013#include "rsnd.h"
14
Kuninori Morimoto288f3922015-02-20 10:27:42 +000015/*
16 * Audio DMAC peri peri register
17 */
18#define PDMASAR 0x00
19#define PDMADAR 0x04
20#define PDMACHCR 0x0c
21
22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0)
24
Kuninori Morimoto3e5afa72015-10-26 08:38:58 +000025
26struct rsnd_dmaen {
27 struct dma_chan *chan;
28};
29
30struct rsnd_dmapp {
31 int dmapp_id;
32 u32 chcr;
33};
34
35struct rsnd_dma {
36 struct rsnd_dma_ops *ops;
Kuninori Morimoto940e9472015-10-26 08:42:25 +000037 struct rsnd_mod mod;
38 struct rsnd_mod *user_mod;
Kuninori Morimoto3e5afa72015-10-26 08:38:58 +000039 dma_addr_t src_addr;
40 dma_addr_t dst_addr;
41 union {
42 struct rsnd_dmaen en;
43 struct rsnd_dmapp pp;
44 } dma;
45};
46
Kuninori Morimoto288f3922015-02-20 10:27:42 +000047struct rsnd_dma_ctrl {
48 void __iomem *base;
Kuninori Morimoto940e9472015-10-26 08:42:25 +000049 int dmaen_num;
Kuninori Morimoto288f3922015-02-20 10:27:42 +000050 int dmapp_num;
51};
52
Kuninori Morimoto98d358a2015-07-15 07:15:27 +000053struct rsnd_dma_ops {
Kuninori Morimotoddea1b22015-07-15 07:16:03 +000054 char *name;
Kuninori Morimoto76c80b52015-10-26 08:42:46 +000055 void (*start)(struct rsnd_mod *mod,
56 struct rsnd_dai_stream *io,
57 struct rsnd_priv *priv);
58 void (*stop)(struct rsnd_mod *mod,
59 struct rsnd_dai_stream *io,
60 struct rsnd_priv *priv);
61 void (*quit)(struct rsnd_mod *mod,
62 struct rsnd_dai_stream *io,
63 struct rsnd_priv *priv);
Kuninori Morimoto98d358a2015-07-15 07:15:27 +000064};
65
Kuninori Morimoto288f3922015-02-20 10:27:42 +000066#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
Kuninori Morimoto940e9472015-10-26 08:42:25 +000067#define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod)
Kuninori Morimoto3e5afa72015-10-26 08:38:58 +000068#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
69#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
Kuninori Morimoto288f3922015-02-20 10:27:42 +000070
71/*
72 * Audio DMAC
73 */
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +000074static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
75 struct rsnd_dai_stream *io)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000076{
Kuninori Morimoto75defee2015-06-15 06:21:15 +000077 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
Kuninori Morimoto75defee2015-06-15 06:21:15 +000078 bool elapsed = false;
79 unsigned long flags;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000080
81 /*
82 * Renesas sound Gen1 needs 1 DMAC,
83 * Gen2 needs 2 DMAC.
84 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
85 * But, Audio-DMAC-peri-peri doesn't have interrupt,
86 * and this driver is assuming that here.
87 *
88 * If Audio-DMAC-peri-peri has interrpt,
89 * rsnd_dai_pointer_update() will be called twice,
90 * ant it will breaks io->byte_pos
91 */
Kuninori Morimoto75defee2015-06-15 06:21:15 +000092 spin_lock_irqsave(&priv->lock, flags);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000093
Kuninori Morimotod5bbe7d2015-06-15 06:27:47 +000094 if (rsnd_io_is_working(io))
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +000095 elapsed = rsnd_dai_pointer_update(io, io->byte_per_period);
Kuninori Morimoto75defee2015-06-15 06:21:15 +000096
97 spin_unlock_irqrestore(&priv->lock, flags);
98
99 if (elapsed)
100 rsnd_dai_period_elapsed(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000101}
102
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000103static void rsnd_dmaen_complete(void *data)
104{
105 struct rsnd_mod *mod = data;
106
107 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
108}
109
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000110static void rsnd_dmaen_stop(struct rsnd_mod *mod,
111 struct rsnd_dai_stream *io,
112 struct rsnd_priv *priv)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000113{
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000114 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000115 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
116
117 dmaengine_terminate_all(dmaen->chan);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000118}
119
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000120static void rsnd_dmaen_start(struct rsnd_mod *mod,
121 struct rsnd_dai_stream *io,
122 struct rsnd_priv *priv)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000123{
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000124 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000125 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000126 struct rsnd_mod *user_mod = dma->user_mod;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000127 struct snd_pcm_substream *substream = io->substream;
128 struct device *dev = rsnd_priv_to_dev(priv);
129 struct dma_async_tx_descriptor *desc;
Kuninori Morimotoaaf4fce2015-02-20 10:28:32 +0000130 int is_play = rsnd_io_is_play(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000131
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000132 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000133 substream->runtime->dma_addr,
134 snd_pcm_lib_buffer_bytes(substream),
135 snd_pcm_lib_period_bytes(substream),
Kuninori Morimotoaaf4fce2015-02-20 10:28:32 +0000136 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000137 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
138
139 if (!desc) {
140 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
141 return;
142 }
143
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000144 desc->callback = rsnd_dmaen_complete;
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000145 desc->callback_param = user_mod;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000146
147 if (dmaengine_submit(desc) < 0) {
148 dev_err(dev, "dmaengine_submit() fail\n");
149 return;
150 }
151
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000152 dma_async_issue_pending(dmaen->chan);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000153}
154
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000155struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
156 struct rsnd_mod *mod, char *name)
157{
158 struct dma_chan *chan;
159 struct device_node *np;
160 int i = 0;
161
162 for_each_child_of_node(of_node, np) {
163 if (i == rsnd_mod_id(mod))
164 break;
165 i++;
166 }
167
168 chan = of_dma_request_slave_channel(np, name);
169
170 of_node_put(np);
171 of_node_put(of_node);
172
173 return chan;
174}
175
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000176static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
177 struct rsnd_mod *mod_from,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000178 struct rsnd_mod *mod_to)
179{
180 if ((!mod_from && !mod_to) ||
181 (mod_from && mod_to))
182 return NULL;
183
184 if (mod_from)
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000185 return rsnd_mod_dma_req(io, mod_from);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000186 else
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000187 return rsnd_mod_dma_req(io, mod_to);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000188}
189
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000190static int rsnd_dmaen_attach(struct rsnd_dai_stream *io,
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000191 struct rsnd_dma *dma, int id,
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000192 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000193{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000194 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000195 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000196 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000197 struct device *dev = rsnd_priv_to_dev(priv);
198 struct dma_slave_config cfg = {};
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000199 int is_play = rsnd_io_is_play(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000200 int ret;
201
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000202 if (dmaen->chan) {
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000203 dev_err(dev, "it already has dma channel\n");
204 return -EIO;
205 }
206
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000207 if (dev->of_node) {
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000208 dmaen->chan = rsnd_dmaen_request_channel(io, mod_from, mod_to);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000209 } else {
210 dma_cap_mask_t mask;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000211
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000212 dma_cap_zero(mask);
213 dma_cap_set(DMA_SLAVE, mask);
214
215 dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
Geert Uytterhoeven1af2cc62015-08-11 14:47:18 +0200216 (void *)(uintptr_t)id);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000217 }
218 if (IS_ERR_OR_NULL(dmaen->chan)) {
Kuninori Morimotod1acba22015-04-13 06:00:45 +0000219 dmaen->chan = NULL;
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000220 dev_err(dev, "can't get dma channel\n");
221 goto rsnd_dma_channel_err;
222 }
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000223
224 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000225 cfg.src_addr = dma->src_addr;
226 cfg.dst_addr = dma->dst_addr;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000227 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
228 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
229
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000230 dev_dbg(dev, "%s %pad -> %pad\n",
231 dma->ops->name,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000232 &cfg.src_addr, &cfg.dst_addr);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000233
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000234 ret = dmaengine_slave_config(dmaen->chan, &cfg);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000235 if (ret < 0)
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000236 goto rsnd_dma_attach_err;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000237
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000238 dmac->dmaen_num++;
239
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000240 return 0;
241
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000242rsnd_dma_attach_err:
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000243 rsnd_dma_quit(rsnd_mod_get(dma), io, priv);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000244rsnd_dma_channel_err:
245
246 /*
247 * DMA failed. try to PIO mode
248 * see
249 * rsnd_ssi_fallback()
250 * rsnd_rdai_continuance_probe()
251 */
252 return -EAGAIN;
253}
254
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000255static void rsnd_dmaen_quit(struct rsnd_mod *mod,
256 struct rsnd_dai_stream *io,
257 struct rsnd_priv *priv)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000258{
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000259 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000260 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000261
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000262 if (dmaen->chan)
263 dma_release_channel(dmaen->chan);
264
265 dmaen->chan = NULL;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000266}
267
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000268static struct rsnd_dma_ops rsnd_dmaen_ops = {
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000269 .name = "audmac",
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000270 .start = rsnd_dmaen_start,
271 .stop = rsnd_dmaen_stop,
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000272 .quit = rsnd_dmaen_quit,
273};
274
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000275/*
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000276 * Audio DMAC peri peri
277 */
278static const u8 gen2_id_table_ssiu[] = {
279 0x00, /* SSI00 */
280 0x04, /* SSI10 */
281 0x08, /* SSI20 */
282 0x0c, /* SSI3 */
283 0x0d, /* SSI4 */
284 0x0e, /* SSI5 */
285 0x0f, /* SSI6 */
286 0x10, /* SSI7 */
287 0x11, /* SSI8 */
288 0x12, /* SSI90 */
289};
290static const u8 gen2_id_table_scu[] = {
291 0x2d, /* SCU_SRCI0 */
292 0x2e, /* SCU_SRCI1 */
293 0x2f, /* SCU_SRCI2 */
294 0x30, /* SCU_SRCI3 */
295 0x31, /* SCU_SRCI4 */
296 0x32, /* SCU_SRCI5 */
297 0x33, /* SCU_SRCI6 */
298 0x34, /* SCU_SRCI7 */
299 0x35, /* SCU_SRCI8 */
300 0x36, /* SCU_SRCI9 */
301};
302static const u8 gen2_id_table_cmd[] = {
303 0x37, /* SCU_CMD0 */
304 0x38, /* SCU_CMD1 */
305};
306
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000307static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
308 struct rsnd_mod *mod)
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000309{
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000310 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
311 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
312 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
313 const u8 *entry = NULL;
314 int id = rsnd_mod_id(mod);
315 int size = 0;
316
317 if (mod == ssi) {
318 entry = gen2_id_table_ssiu;
319 size = ARRAY_SIZE(gen2_id_table_ssiu);
320 } else if (mod == src) {
321 entry = gen2_id_table_scu;
322 size = ARRAY_SIZE(gen2_id_table_scu);
323 } else if (mod == dvc) {
324 entry = gen2_id_table_cmd;
325 size = ARRAY_SIZE(gen2_id_table_cmd);
326 }
327
328 if (!entry)
329 return 0xFF;
330
331 if (size <= id)
332 return 0xFF;
333
334 return entry[id];
335}
336
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000337static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io,
338 struct rsnd_mod *mod_from,
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000339 struct rsnd_mod *mod_to)
340{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000341 return (rsnd_dmapp_get_id(io, mod_from) << 24) +
342 (rsnd_dmapp_get_id(io, mod_to) << 16);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000343}
344
345#define rsnd_dmapp_addr(dmac, dma, reg) \
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000346 (dmac->base + 0x20 + reg + \
347 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000348static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
349{
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000350 struct rsnd_mod *mod = rsnd_mod_get(dma);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000351 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
352 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
353 struct device *dev = rsnd_priv_to_dev(priv);
354
355 dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
356
357 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
358}
359
360static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
361{
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000362 struct rsnd_mod *mod = rsnd_mod_get(dma);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000363 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
364 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
365
366 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
367}
368
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000369static void rsnd_dmapp_stop(struct rsnd_mod *mod,
370 struct rsnd_dai_stream *io,
371 struct rsnd_priv *priv)
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000372{
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000373 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000374 int i;
375
376 rsnd_dmapp_write(dma, 0, PDMACHCR);
377
378 for (i = 0; i < 1024; i++) {
379 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
380 return;
381 udelay(1);
382 }
383}
384
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000385static void rsnd_dmapp_start(struct rsnd_mod *mod,
386 struct rsnd_dai_stream *io,
387 struct rsnd_priv *priv)
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000388{
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000389 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000390 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
391
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000392 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
393 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000394 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000395}
396
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000397static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
398 struct rsnd_dma *dma, int id,
399 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000400{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000401 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000402 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000403 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
404 struct device *dev = rsnd_priv_to_dev(priv);
405
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000406 dmapp->dmapp_id = dmac->dmapp_num;
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000407 dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE;
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000408
409 dmac->dmapp_num++;
410
Geert Uytterhoeven6ec6fb62015-03-10 11:48:05 +0100411 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
412 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000413
414 return 0;
415}
416
417static struct rsnd_dma_ops rsnd_dmapp_ops = {
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000418 .name = "audmac-pp",
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000419 .start = rsnd_dmapp_start,
420 .stop = rsnd_dmapp_stop,
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000421 .quit = rsnd_dmapp_stop,
422};
423
424/*
425 * Common DMAC Interface
426 */
427
428/*
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000429 * DMA read/write register offset
430 *
431 * RSND_xxx_I_N for Audio DMAC input
432 * RSND_xxx_O_N for Audio DMAC output
433 * RSND_xxx_I_P for Audio DMAC peri peri input
434 * RSND_xxx_O_P for Audio DMAC peri peri output
435 *
436 * ex) R-Car H2 case
437 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
438 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
439 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
440 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
441 * CMD : 0xec500000 / / 0xec008000 0xec308000
442 */
443#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
444#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
445
446#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
447#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
448
449#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
450#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
451
452#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
453#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
454
455#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
456#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
457
458#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
459#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
460
461static dma_addr_t
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000462rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000463 struct rsnd_mod *mod,
464 int is_play, int is_from)
465{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000466 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000467 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000468 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
469 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
470 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
471 int use_src = !!rsnd_io_to_mod_src(io);
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000472 int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
Kuninori Morimoto70fb1052015-07-15 07:17:36 +0000473 !!rsnd_io_to_mod_mix(io) ||
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000474 !!rsnd_io_to_mod_ctu(io);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000475 int id = rsnd_mod_id(mod);
476 struct dma_addr {
477 dma_addr_t out_addr;
478 dma_addr_t in_addr;
479 } dma_addrs[3][2][3] = {
480 /* SRC */
481 {{{ 0, 0 },
482 /* Capture */
483 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
484 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
485 /* Playback */
486 {{ 0, 0, },
487 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
488 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
489 },
490 /* SSI */
491 /* Capture */
492 {{{ RDMA_SSI_O_N(ssi, id), 0 },
493 { RDMA_SSIU_O_P(ssi, id), 0 },
494 { RDMA_SSIU_O_P(ssi, id), 0 } },
495 /* Playback */
496 {{ 0, RDMA_SSI_I_N(ssi, id) },
497 { 0, RDMA_SSIU_I_P(ssi, id) },
498 { 0, RDMA_SSIU_I_P(ssi, id) } }
499 },
500 /* SSIU */
501 /* Capture */
502 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
503 { RDMA_SSIU_O_P(ssi, id), 0 },
504 { RDMA_SSIU_O_P(ssi, id), 0 } },
505 /* Playback */
506 {{ 0, RDMA_SSIU_I_N(ssi, id) },
507 { 0, RDMA_SSIU_I_P(ssi, id) },
508 { 0, RDMA_SSIU_I_P(ssi, id) } } },
509 };
510
511 /* it shouldn't happen */
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000512 if (use_cmd && !use_src)
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000513 dev_err(dev, "DVC is selected without SRC\n");
514
515 /* use SSIU or SSI ? */
Kuninori Morimotob415b4d2015-10-22 03:15:46 +0000516 if (is_ssi && rsnd_ssi_use_busif(io))
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000517 is_ssi++;
518
519 return (is_from) ?
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000520 dma_addrs[is_ssi][is_play][use_src + use_cmd].out_addr :
521 dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr;
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000522}
523
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000524static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000525 struct rsnd_mod *mod,
526 int is_play, int is_from)
527{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000528 struct rsnd_priv *priv = rsnd_io_to_priv(io);
529
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000530 /*
531 * gen1 uses default DMA addr
532 */
533 if (rsnd_is_gen1(priv))
534 return 0;
535
536 if (!mod)
537 return 0;
538
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000539 return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000540}
541
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000542#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000543static void rsnd_dma_of_path(struct rsnd_mod *this,
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000544 struct rsnd_dai_stream *io,
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000545 int is_play,
546 struct rsnd_mod **mod_from,
547 struct rsnd_mod **mod_to)
548{
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000549 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
550 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000551 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
Kuninori Morimoto70fb1052015-07-15 07:17:36 +0000552 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000553 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
554 struct rsnd_mod *mod[MOD_MAX];
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000555 struct rsnd_mod *mod_start, *mod_end;
556 struct rsnd_priv *priv = rsnd_mod_to_priv(this);
557 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000558 int nr, i, idx;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000559
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000560 if (!ssi)
561 return;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000562
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000563 nr = 0;
564 for (i = 0; i < MOD_MAX; i++) {
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000565 mod[i] = NULL;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000566 nr += !!rsnd_io_to_mod(io, i);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000567 }
568
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000569 /*
570 * [S] -*-> [E]
571 * [S] -*-> SRC -o-> [E]
572 * [S] -*-> SRC -> DVC -o-> [E]
573 * [S] -*-> SRC -> CTU -> MIX -> DVC -o-> [E]
574 *
575 * playback [S] = mem
576 * [E] = SSI
577 *
578 * capture [S] = SSI
579 * [E] = mem
580 *
581 * -*-> Audio DMAC
582 * -o-> Audio DMAC peri peri
583 */
584 mod_start = (is_play) ? NULL : ssi;
585 mod_end = (is_play) ? ssi : NULL;
586
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000587 idx = 0;
588 mod[idx++] = mod_start;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000589 for (i = 1; i < nr; i++) {
590 if (src) {
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000591 mod[idx++] = src;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000592 src = NULL;
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000593 } else if (ctu) {
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000594 mod[idx++] = ctu;
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000595 ctu = NULL;
Kuninori Morimoto70fb1052015-07-15 07:17:36 +0000596 } else if (mix) {
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000597 mod[idx++] = mix;
Kuninori Morimoto70fb1052015-07-15 07:17:36 +0000598 mix = NULL;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000599 } else if (dvc) {
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000600 mod[idx++] = dvc;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000601 dvc = NULL;
602 }
603 }
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000604 mod[idx] = mod_end;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000605
606 /*
607 * | SSI | SRC |
608 * -------------+-----+-----+
609 * is_play | o | * |
610 * !is_play | * | o |
611 */
612 if ((this == ssi) == (is_play)) {
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000613 *mod_from = mod[idx - 1];
614 *mod_to = mod[idx];
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000615 } else {
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000616 *mod_from = mod[0];
617 *mod_to = mod[1];
618 }
619
620 dev_dbg(dev, "module connection (this is %s[%d])\n",
621 rsnd_mod_name(this), rsnd_mod_id(this));
Kuninori Morimoto40854c62015-10-26 08:40:19 +0000622 for (i = 0; i <= idx; i++) {
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000623 dev_dbg(dev, " %s[%d]%s\n",
624 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
625 (mod[i] == *mod_from) ? " from" :
626 (mod[i] == *mod_to) ? " to" : "");
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000627 }
628}
629
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000630void rsnd_dma_stop(struct rsnd_mod *mod,
631 struct rsnd_dai_stream *io,
632 struct rsnd_priv *priv)
633
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000634{
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000635 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
636
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000637 dma->ops->stop(mod, io, priv);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000638}
639
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000640void rsnd_dma_start(struct rsnd_mod *mod,
641 struct rsnd_dai_stream *io,
642 struct rsnd_priv *priv)
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000643{
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000644 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
645
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000646 dma->ops->start(mod, io, priv);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000647}
648
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000649void rsnd_dma_quit(struct rsnd_mod *mod,
650 struct rsnd_dai_stream *io,
651 struct rsnd_priv *priv)
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000652{
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000653 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
Kuninori Morimoto85374832015-03-10 01:25:01 +0000654 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
655
656 if (!dmac)
657 return;
658
Kuninori Morimoto76c80b52015-10-26 08:42:46 +0000659 dma->ops->quit(mod, io, priv);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000660}
661
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000662static struct rsnd_mod_ops rsnd_dma_ops = {
663};
664
665struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io,
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000666 struct rsnd_mod *mod, int id)
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000667{
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000668 struct rsnd_mod *dma_mod;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000669 struct rsnd_mod *mod_from = NULL;
670 struct rsnd_mod *mod_to = NULL;
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000671 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimoto85374832015-03-10 01:25:01 +0000672 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000673 struct rsnd_dma *dma;
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000674 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000675 int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
676 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000677 int is_play = rsnd_io_is_play(io);
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000678 int ret, dma_id;
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000679
Kuninori Morimoto85374832015-03-10 01:25:01 +0000680 /*
681 * DMA failed. try to PIO mode
682 * see
683 * rsnd_ssi_fallback()
684 * rsnd_rdai_continuance_probe()
685 */
686 if (!dmac)
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000687 return ERR_PTR(-EAGAIN);
688
689 dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
690 if (!dma)
691 return ERR_PTR(-ENOMEM);
692
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000693 rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to);
Kuninori Morimoto85374832015-03-10 01:25:01 +0000694
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000695 dma->user_mod = mod;
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000696 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
697 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000698
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000699 /* for Gen2 */
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000700 if (mod_from && mod_to) {
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000701 dma->ops = &rsnd_dmapp_ops;
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000702 attach = rsnd_dmapp_attach;
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000703 dma_id = dmac->dmapp_num;
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000704 } else {
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000705 dma->ops = &rsnd_dmaen_ops;
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000706 attach = rsnd_dmaen_attach;
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000707 dma_id = dmac->dmaen_num;
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000708 }
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000709
710 /* for Gen1, overwrite */
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000711 if (rsnd_is_gen1(priv)) {
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000712 dma->ops = &rsnd_dmaen_ops;
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000713 attach = rsnd_dmaen_attach;
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000714 dma_id = dmac->dmaen_num;
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000715 }
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000716
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000717 dma_mod = rsnd_mod_get(dma);
718
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000719 dev_dbg(dev, "%s %s[%d] -> %s[%d]\n",
720 dma->ops->name,
721 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
722 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
723
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000724 ret = rsnd_mod_init(priv, dma_mod,
725 &rsnd_dma_ops, NULL, 0, dma_id);
726 if (ret < 0)
727 return ERR_PTR(ret);
728
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000729 ret = attach(io, dma, id, mod_from, mod_to);
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000730 if (ret < 0)
731 return ERR_PTR(ret);
732
Kuninori Morimoto940e9472015-10-26 08:42:25 +0000733 return rsnd_mod_get(dma);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000734}
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000735
736int rsnd_dma_probe(struct platform_device *pdev,
737 const struct rsnd_of_data *of_data,
738 struct rsnd_priv *priv)
739{
740 struct device *dev = rsnd_priv_to_dev(priv);
741 struct rsnd_dma_ctrl *dmac;
742 struct resource *res;
743
744 /*
745 * for Gen1
746 */
747 if (rsnd_is_gen1(priv))
748 return 0;
749
750 /*
751 * for Gen2
752 */
753 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
754 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
755 if (!dmac || !res) {
756 dev_err(dev, "dma allocate failed\n");
Kuninori Morimoto85374832015-03-10 01:25:01 +0000757 return 0; /* it will be PIO mode */
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000758 }
759
760 dmac->dmapp_num = 0;
761 dmac->base = devm_ioremap_resource(dev, res);
762 if (IS_ERR(dmac->base))
763 return PTR_ERR(dmac->base);
764
765 priv->dma = dmac;
766
767 return 0;
768}