ASoC: rsnd: use mod base common method on DMA phase1
[linux-2.6-block.git] / sound / soc / sh / rcar / dma.c
CommitLineData
bfe834be
KM
1/*
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 */
288f392e 11#include <linux/delay.h>
72adc61f 12#include <linux/of_dma.h>
bfe834be
KM
13#include "rsnd.h"
14
288f392e
KM
15/*
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
3e5afa73
KM
25
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;
940e9479
KM
37 struct rsnd_mod mod;
38 struct rsnd_mod *user_mod;
3e5afa73
KM
39 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
288f392e
KM
47struct rsnd_dma_ctrl {
48 void __iomem *base;
940e9479 49 int dmaen_num;
288f392e
KM
50 int dmapp_num;
51};
52
98d358af 53struct rsnd_dma_ops {
ddea1b2e 54 char *name;
98d358af
KM
55 void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
56 void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
98d358af
KM
57 void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
58};
59
288f392e 60#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
940e9479 61#define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod)
3e5afa73
KM
62#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
63#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
288f392e
KM
64
65/*
66 * Audio DMAC
67 */
9b99e9a7
KM
68static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
69 struct rsnd_dai_stream *io)
bfe834be 70{
75defee0 71 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
75defee0
KM
72 bool elapsed = false;
73 unsigned long flags;
bfe834be
KM
74
75 /*
76 * Renesas sound Gen1 needs 1 DMAC,
77 * Gen2 needs 2 DMAC.
78 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
79 * But, Audio-DMAC-peri-peri doesn't have interrupt,
80 * and this driver is assuming that here.
81 *
82 * If Audio-DMAC-peri-peri has interrpt,
83 * rsnd_dai_pointer_update() will be called twice,
84 * ant it will breaks io->byte_pos
85 */
75defee0
KM
86 spin_lock_irqsave(&priv->lock, flags);
87
d5bbe7de 88 if (rsnd_io_is_working(io))
9b99e9a7 89 elapsed = rsnd_dai_pointer_update(io, io->byte_per_period);
bfe834be 90
75defee0 91 spin_unlock_irqrestore(&priv->lock, flags);
bfe834be 92
75defee0
KM
93 if (elapsed)
94 rsnd_dai_period_elapsed(io);
bfe834be
KM
95}
96
9b99e9a7
KM
97static void rsnd_dmaen_complete(void *data)
98{
99 struct rsnd_mod *mod = data;
100
101 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
102}
103
104static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
bfe834be 105{
0d00a521
KM
106 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
107
108 dmaengine_terminate_all(dmaen->chan);
bfe834be
KM
109}
110
9b99e9a7 111static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
bfe834be 112{
0d00a521 113 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
940e9479
KM
114 struct rsnd_mod *user_mod = dma->user_mod;
115 struct rsnd_priv *priv = rsnd_io_to_priv(io);
bfe834be
KM
116 struct snd_pcm_substream *substream = io->substream;
117 struct device *dev = rsnd_priv_to_dev(priv);
118 struct dma_async_tx_descriptor *desc;
aaf4fce0 119 int is_play = rsnd_io_is_play(io);
bfe834be 120
0d00a521 121 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
bfe834be
KM
122 substream->runtime->dma_addr,
123 snd_pcm_lib_buffer_bytes(substream),
124 snd_pcm_lib_period_bytes(substream),
aaf4fce0 125 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
bfe834be
KM
126 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
127
128 if (!desc) {
129 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
130 return;
131 }
132
3c68565b 133 desc->callback = rsnd_dmaen_complete;
940e9479 134 desc->callback_param = user_mod;
bfe834be
KM
135
136 if (dmaengine_submit(desc) < 0) {
137 dev_err(dev, "dmaengine_submit() fail\n");
138 return;
139 }
140
0d00a521 141 dma_async_issue_pending(dmaen->chan);
bfe834be
KM
142}
143
72adc61f
KM
144struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
145 struct rsnd_mod *mod, char *name)
146{
147 struct dma_chan *chan;
148 struct device_node *np;
149 int i = 0;
150
151 for_each_child_of_node(of_node, np) {
152 if (i == rsnd_mod_id(mod))
153 break;
154 i++;
155 }
156
157 chan = of_dma_request_slave_channel(np, name);
158
159 of_node_put(np);
160 of_node_put(of_node);
161
162 return chan;
163}
164
9b99e9a7
KM
165static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
166 struct rsnd_mod *mod_from,
72adc61f
KM
167 struct rsnd_mod *mod_to)
168{
169 if ((!mod_from && !mod_to) ||
170 (mod_from && mod_to))
171 return NULL;
172
173 if (mod_from)
9b99e9a7 174 return rsnd_mod_dma_req(io, mod_from);
72adc61f 175 else
9b99e9a7 176 return rsnd_mod_dma_req(io, mod_to);
72adc61f
KM
177}
178
81ecbb65 179static int rsnd_dmaen_attach(struct rsnd_dai_stream *io,
9b99e9a7 180 struct rsnd_dma *dma, int id,
3c68565b 181 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
bfe834be 182{
0d00a521 183 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
9b99e9a7 184 struct rsnd_priv *priv = rsnd_io_to_priv(io);
940e9479 185 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
bfe834be
KM
186 struct device *dev = rsnd_priv_to_dev(priv);
187 struct dma_slave_config cfg = {};
bfe834be 188 int is_play = rsnd_io_is_play(io);
bfe834be
KM
189 int ret;
190
0d00a521 191 if (dmaen->chan) {
bfe834be
KM
192 dev_err(dev, "it already has dma channel\n");
193 return -EIO;
194 }
195
72adc61f 196 if (dev->of_node) {
9b99e9a7 197 dmaen->chan = rsnd_dmaen_request_channel(io, mod_from, mod_to);
72adc61f
KM
198 } else {
199 dma_cap_mask_t mask;
bfe834be 200
72adc61f
KM
201 dma_cap_zero(mask);
202 dma_cap_set(DMA_SLAVE, mask);
203
204 dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
1af2cc64 205 (void *)(uintptr_t)id);
72adc61f
KM
206 }
207 if (IS_ERR_OR_NULL(dmaen->chan)) {
d1acba2f 208 dmaen->chan = NULL;
72adc61f
KM
209 dev_err(dev, "can't get dma channel\n");
210 goto rsnd_dma_channel_err;
211 }
bfe834be
KM
212
213 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
3c68565b
KM
214 cfg.src_addr = dma->src_addr;
215 cfg.dst_addr = dma->dst_addr;
bfe834be
KM
216 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
217 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
218
ddea1b2e
KM
219 dev_dbg(dev, "%s %pad -> %pad\n",
220 dma->ops->name,
72adc61f 221 &cfg.src_addr, &cfg.dst_addr);
bfe834be 222
0d00a521 223 ret = dmaengine_slave_config(dmaen->chan, &cfg);
bfe834be 224 if (ret < 0)
81ecbb65 225 goto rsnd_dma_attach_err;
bfe834be 226
940e9479
KM
227 dmac->dmaen_num++;
228
bfe834be
KM
229 return 0;
230
81ecbb65 231rsnd_dma_attach_err:
940e9479 232 rsnd_dma_quit(io, rsnd_mod_get(dma));
bfe834be
KM
233rsnd_dma_channel_err:
234
235 /*
236 * DMA failed. try to PIO mode
237 * see
238 * rsnd_ssi_fallback()
239 * rsnd_rdai_continuance_probe()
240 */
241 return -EAGAIN;
242}
243
9b99e9a7 244static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
bfe834be 245{
0d00a521
KM
246 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
247
248 if (dmaen->chan)
249 dma_release_channel(dmaen->chan);
bfe834be 250
0d00a521 251 dmaen->chan = NULL;
bfe834be
KM
252}
253
3c68565b 254static struct rsnd_dma_ops rsnd_dmaen_ops = {
ddea1b2e 255 .name = "audmac",
3c68565b
KM
256 .start = rsnd_dmaen_start,
257 .stop = rsnd_dmaen_stop,
3c68565b
KM
258 .quit = rsnd_dmaen_quit,
259};
260
288f392e
KM
261/*
262 * Audio DMAC peri peri
263 */
264static const u8 gen2_id_table_ssiu[] = {
265 0x00, /* SSI00 */
266 0x04, /* SSI10 */
267 0x08, /* SSI20 */
268 0x0c, /* SSI3 */
269 0x0d, /* SSI4 */
270 0x0e, /* SSI5 */
271 0x0f, /* SSI6 */
272 0x10, /* SSI7 */
273 0x11, /* SSI8 */
274 0x12, /* SSI90 */
275};
276static const u8 gen2_id_table_scu[] = {
277 0x2d, /* SCU_SRCI0 */
278 0x2e, /* SCU_SRCI1 */
279 0x2f, /* SCU_SRCI2 */
280 0x30, /* SCU_SRCI3 */
281 0x31, /* SCU_SRCI4 */
282 0x32, /* SCU_SRCI5 */
283 0x33, /* SCU_SRCI6 */
284 0x34, /* SCU_SRCI7 */
285 0x35, /* SCU_SRCI8 */
286 0x36, /* SCU_SRCI9 */
287};
288static const u8 gen2_id_table_cmd[] = {
289 0x37, /* SCU_CMD0 */
290 0x38, /* SCU_CMD1 */
291};
292
9b99e9a7
KM
293static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
294 struct rsnd_mod *mod)
288f392e 295{
288f392e
KM
296 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
297 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
298 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
299 const u8 *entry = NULL;
300 int id = rsnd_mod_id(mod);
301 int size = 0;
302
303 if (mod == ssi) {
304 entry = gen2_id_table_ssiu;
305 size = ARRAY_SIZE(gen2_id_table_ssiu);
306 } else if (mod == src) {
307 entry = gen2_id_table_scu;
308 size = ARRAY_SIZE(gen2_id_table_scu);
309 } else if (mod == dvc) {
310 entry = gen2_id_table_cmd;
311 size = ARRAY_SIZE(gen2_id_table_cmd);
312 }
313
314 if (!entry)
315 return 0xFF;
316
317 if (size <= id)
318 return 0xFF;
319
320 return entry[id];
321}
322
9b99e9a7
KM
323static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io,
324 struct rsnd_mod *mod_from,
288f392e
KM
325 struct rsnd_mod *mod_to)
326{
9b99e9a7
KM
327 return (rsnd_dmapp_get_id(io, mod_from) << 24) +
328 (rsnd_dmapp_get_id(io, mod_to) << 16);
288f392e
KM
329}
330
331#define rsnd_dmapp_addr(dmac, dma, reg) \
0d00a521
KM
332 (dmac->base + 0x20 + reg + \
333 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
288f392e
KM
334static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
335{
940e9479 336 struct rsnd_mod *mod = rsnd_mod_get(dma);
288f392e
KM
337 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
338 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
339 struct device *dev = rsnd_priv_to_dev(priv);
340
341 dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
342
343 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
344}
345
346static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
347{
940e9479 348 struct rsnd_mod *mod = rsnd_mod_get(dma);
288f392e
KM
349 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
350 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
351
352 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
353}
354
9b99e9a7 355static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
288f392e
KM
356{
357 int i;
358
359 rsnd_dmapp_write(dma, 0, PDMACHCR);
360
361 for (i = 0; i < 1024; i++) {
362 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
363 return;
364 udelay(1);
365 }
366}
367
9b99e9a7 368static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
288f392e 369{
0d00a521
KM
370 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
371
288f392e
KM
372 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
373 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
0d00a521 374 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
288f392e
KM
375}
376
81ecbb65
KM
377static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
378 struct rsnd_dma *dma, int id,
379 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
288f392e 380{
0d00a521 381 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
9b99e9a7 382 struct rsnd_priv *priv = rsnd_io_to_priv(io);
288f392e
KM
383 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
384 struct device *dev = rsnd_priv_to_dev(priv);
385
0d00a521 386 dmapp->dmapp_id = dmac->dmapp_num;
9b99e9a7 387 dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE;
288f392e
KM
388
389 dmac->dmapp_num++;
390
9b99e9a7 391 rsnd_dmapp_stop(io, dma);
288f392e 392
6ec6fb6f
GU
393 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
394 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
288f392e
KM
395
396 return 0;
397}
398
399static struct rsnd_dma_ops rsnd_dmapp_ops = {
ddea1b2e 400 .name = "audmac-pp",
288f392e
KM
401 .start = rsnd_dmapp_start,
402 .stop = rsnd_dmapp_stop,
288f392e
KM
403 .quit = rsnd_dmapp_stop,
404};
405
406/*
407 * Common DMAC Interface
408 */
409
747c71b1
KM
410/*
411 * DMA read/write register offset
412 *
413 * RSND_xxx_I_N for Audio DMAC input
414 * RSND_xxx_O_N for Audio DMAC output
415 * RSND_xxx_I_P for Audio DMAC peri peri input
416 * RSND_xxx_O_P for Audio DMAC peri peri output
417 *
418 * ex) R-Car H2 case
419 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
420 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
421 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
422 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
423 * CMD : 0xec500000 / / 0xec008000 0xec308000
424 */
425#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
426#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
427
428#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
429#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
430
431#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
432#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
433
434#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
435#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
436
437#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
438#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
439
440#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
441#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
442
443static dma_addr_t
9b99e9a7 444rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
747c71b1
KM
445 struct rsnd_mod *mod,
446 int is_play, int is_from)
447{
9b99e9a7 448 struct rsnd_priv *priv = rsnd_io_to_priv(io);
747c71b1 449 struct device *dev = rsnd_priv_to_dev(priv);
747c71b1
KM
450 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
451 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
452 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
453 int use_src = !!rsnd_io_to_mod_src(io);
9269e3c3 454 int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
70fb1052 455 !!rsnd_io_to_mod_mix(io) ||
9269e3c3 456 !!rsnd_io_to_mod_ctu(io);
747c71b1
KM
457 int id = rsnd_mod_id(mod);
458 struct dma_addr {
459 dma_addr_t out_addr;
460 dma_addr_t in_addr;
461 } dma_addrs[3][2][3] = {
462 /* SRC */
463 {{{ 0, 0 },
464 /* Capture */
465 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
466 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
467 /* Playback */
468 {{ 0, 0, },
469 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
470 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
471 },
472 /* SSI */
473 /* Capture */
474 {{{ RDMA_SSI_O_N(ssi, id), 0 },
475 { RDMA_SSIU_O_P(ssi, id), 0 },
476 { RDMA_SSIU_O_P(ssi, id), 0 } },
477 /* Playback */
478 {{ 0, RDMA_SSI_I_N(ssi, id) },
479 { 0, RDMA_SSIU_I_P(ssi, id) },
480 { 0, RDMA_SSIU_I_P(ssi, id) } }
481 },
482 /* SSIU */
483 /* Capture */
484 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
485 { RDMA_SSIU_O_P(ssi, id), 0 },
486 { RDMA_SSIU_O_P(ssi, id), 0 } },
487 /* Playback */
488 {{ 0, RDMA_SSIU_I_N(ssi, id) },
489 { 0, RDMA_SSIU_I_P(ssi, id) },
490 { 0, RDMA_SSIU_I_P(ssi, id) } } },
491 };
492
493 /* it shouldn't happen */
9269e3c3 494 if (use_cmd && !use_src)
747c71b1
KM
495 dev_err(dev, "DVC is selected without SRC\n");
496
497 /* use SSIU or SSI ? */
b415b4d3 498 if (is_ssi && rsnd_ssi_use_busif(io))
747c71b1
KM
499 is_ssi++;
500
501 return (is_from) ?
9269e3c3
KM
502 dma_addrs[is_ssi][is_play][use_src + use_cmd].out_addr :
503 dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr;
747c71b1
KM
504}
505
9b99e9a7 506static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
747c71b1
KM
507 struct rsnd_mod *mod,
508 int is_play, int is_from)
509{
9b99e9a7
KM
510 struct rsnd_priv *priv = rsnd_io_to_priv(io);
511
747c71b1
KM
512 /*
513 * gen1 uses default DMA addr
514 */
515 if (rsnd_is_gen1(priv))
516 return 0;
517
518 if (!mod)
519 return 0;
520
9b99e9a7 521 return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
747c71b1
KM
522}
523
7dfb4919 524#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
940e9479 525static void rsnd_dma_of_path(struct rsnd_mod *this,
9b99e9a7 526 struct rsnd_dai_stream *io,
bfe834be
KM
527 int is_play,
528 struct rsnd_mod **mod_from,
529 struct rsnd_mod **mod_to)
530{
bfe834be
KM
531 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
532 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
9269e3c3 533 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
70fb1052 534 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
bfe834be
KM
535 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
536 struct rsnd_mod *mod[MOD_MAX];
7dfb4919
KM
537 struct rsnd_mod *mod_start, *mod_end;
538 struct rsnd_priv *priv = rsnd_mod_to_priv(this);
539 struct device *dev = rsnd_priv_to_dev(priv);
40854c64 540 int nr, i, idx;
bfe834be 541
7dfb4919
KM
542 if (!ssi)
543 return;
bfe834be 544
7dfb4919
KM
545 nr = 0;
546 for (i = 0; i < MOD_MAX; i++) {
bfe834be 547 mod[i] = NULL;
7dfb4919
KM
548 nr += !!rsnd_io_to_mod(io, i);
549 }
bfe834be
KM
550
551 /*
7dfb4919
KM
552 * [S] -*-> [E]
553 * [S] -*-> SRC -o-> [E]
554 * [S] -*-> SRC -> DVC -o-> [E]
555 * [S] -*-> SRC -> CTU -> MIX -> DVC -o-> [E]
556 *
557 * playback [S] = mem
558 * [E] = SSI
bfe834be 559 *
7dfb4919
KM
560 * capture [S] = SSI
561 * [E] = mem
bfe834be 562 *
7dfb4919
KM
563 * -*-> Audio DMAC
564 * -o-> Audio DMAC peri peri
bfe834be 565 */
7dfb4919
KM
566 mod_start = (is_play) ? NULL : ssi;
567 mod_end = (is_play) ? ssi : NULL;
bfe834be 568
40854c64
KM
569 idx = 0;
570 mod[idx++] = mod_start;
7dfb4919
KM
571 for (i = 1; i < nr; i++) {
572 if (src) {
40854c64 573 mod[idx++] = src;
bfe834be 574 src = NULL;
9269e3c3 575 } else if (ctu) {
40854c64 576 mod[idx++] = ctu;
9269e3c3 577 ctu = NULL;
70fb1052 578 } else if (mix) {
40854c64 579 mod[idx++] = mix;
70fb1052 580 mix = NULL;
7dfb4919 581 } else if (dvc) {
40854c64 582 mod[idx++] = dvc;
bfe834be
KM
583 dvc = NULL;
584 }
bfe834be 585 }
40854c64 586 mod[idx] = mod_end;
bfe834be 587
7dfb4919
KM
588 /*
589 * | SSI | SRC |
590 * -------------+-----+-----+
591 * is_play | o | * |
592 * !is_play | * | o |
593 */
594 if ((this == ssi) == (is_play)) {
40854c64
KM
595 *mod_from = mod[idx - 1];
596 *mod_to = mod[idx];
bfe834be 597 } else {
7dfb4919
KM
598 *mod_from = mod[0];
599 *mod_to = mod[1];
600 }
601
602 dev_dbg(dev, "module connection (this is %s[%d])\n",
603 rsnd_mod_name(this), rsnd_mod_id(this));
40854c64 604 for (i = 0; i <= idx; i++) {
7dfb4919
KM
605 dev_dbg(dev, " %s[%d]%s\n",
606 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
607 (mod[i] == *mod_from) ? " from" :
608 (mod[i] == *mod_to) ? " to" : "");
bfe834be
KM
609 }
610}
611
940e9479 612void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
3c68565b 613{
940e9479
KM
614 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
615
9b99e9a7 616 dma->ops->stop(io, dma);
3c68565b
KM
617}
618
940e9479 619void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
3c68565b 620{
940e9479
KM
621 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
622
9b99e9a7 623 dma->ops->start(io, dma);
3c68565b
KM
624}
625
940e9479 626void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_mod *mod)
3c68565b 627{
940e9479 628 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
8537483a
KM
629 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
630 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
631
632 if (!dmac)
633 return;
634
9b99e9a7 635 dma->ops->quit(io, dma);
3c68565b
KM
636}
637
940e9479
KM
638static struct rsnd_mod_ops rsnd_dma_ops = {
639};
640
641struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io,
81ecbb65 642 struct rsnd_mod *mod, int id)
3c68565b 643{
940e9479 644 struct rsnd_mod *dma_mod;
7dfb4919
KM
645 struct rsnd_mod *mod_from = NULL;
646 struct rsnd_mod *mod_to = NULL;
9b99e9a7 647 struct rsnd_priv *priv = rsnd_io_to_priv(io);
8537483a 648 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
232c00b6 649 struct rsnd_dma *dma;
ddea1b2e 650 struct device *dev = rsnd_priv_to_dev(priv);
81ecbb65
KM
651 int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
652 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
3c68565b 653 int is_play = rsnd_io_is_play(io);
940e9479 654 int ret, dma_id;
3c68565b 655
8537483a
KM
656 /*
657 * DMA failed. try to PIO mode
658 * see
659 * rsnd_ssi_fallback()
660 * rsnd_rdai_continuance_probe()
661 */
662 if (!dmac)
232c00b6
KM
663 return ERR_PTR(-EAGAIN);
664
665 dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
666 if (!dma)
667 return ERR_PTR(-ENOMEM);
668
940e9479 669 rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to);
3c68565b 670
940e9479 671 dma->user_mod = mod;
9b99e9a7
KM
672 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
673 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
3c68565b 674
288f392e 675 /* for Gen2 */
81ecbb65 676 if (mod_from && mod_to) {
288f392e 677 dma->ops = &rsnd_dmapp_ops;
81ecbb65 678 attach = rsnd_dmapp_attach;
940e9479 679 dma_id = dmac->dmapp_num;
81ecbb65 680 } else {
288f392e 681 dma->ops = &rsnd_dmaen_ops;
81ecbb65 682 attach = rsnd_dmaen_attach;
940e9479 683 dma_id = dmac->dmaen_num;
81ecbb65 684 }
288f392e
KM
685
686 /* for Gen1, overwrite */
81ecbb65 687 if (rsnd_is_gen1(priv)) {
288f392e 688 dma->ops = &rsnd_dmaen_ops;
81ecbb65 689 attach = rsnd_dmaen_attach;
940e9479 690 dma_id = dmac->dmaen_num;
81ecbb65 691 }
3c68565b 692
940e9479
KM
693 dma_mod = rsnd_mod_get(dma);
694
ddea1b2e
KM
695 dev_dbg(dev, "%s %s[%d] -> %s[%d]\n",
696 dma->ops->name,
697 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
698 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
699
940e9479
KM
700 ret = rsnd_mod_init(priv, dma_mod,
701 &rsnd_dma_ops, NULL, 0, dma_id);
702 if (ret < 0)
703 return ERR_PTR(ret);
704
81ecbb65 705 ret = attach(io, dma, id, mod_from, mod_to);
232c00b6
KM
706 if (ret < 0)
707 return ERR_PTR(ret);
708
940e9479 709 return rsnd_mod_get(dma);
3c68565b 710}
288f392e
KM
711
712int rsnd_dma_probe(struct platform_device *pdev,
713 const struct rsnd_of_data *of_data,
714 struct rsnd_priv *priv)
715{
716 struct device *dev = rsnd_priv_to_dev(priv);
717 struct rsnd_dma_ctrl *dmac;
718 struct resource *res;
719
720 /*
721 * for Gen1
722 */
723 if (rsnd_is_gen1(priv))
724 return 0;
725
726 /*
727 * for Gen2
728 */
729 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
730 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
731 if (!dmac || !res) {
732 dev_err(dev, "dma allocate failed\n");
8537483a 733 return 0; /* it will be PIO mode */
288f392e
KM
734 }
735
736 dmac->dmapp_num = 0;
737 dmac->base = devm_ioremap_resource(dev, res);
738 if (IS_ERR(dmac->base))
739 return PTR_ERR(dmac->base);
740
741 priv->dma = dmac;
742
743 return 0;
744}