dma.c (d1208404dd477c142680437137c9996b95bfd508) dma.c (5ba17b42e1755c3c5cfe96370cfd47f34d01f62c)
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

--- 8 unchanged lines hidden (view full) ---

17 */
18#define PDMASAR 0x00
19#define PDMADAR 0x04
20#define PDMACHCR 0x0c
21
22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0)
24
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

--- 8 unchanged lines hidden (view full) ---

17 */
18#define PDMASAR 0x00
19#define PDMADAR 0x04
20#define PDMACHCR 0x0c
21
22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0)
24
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_mod mod;
37 dma_addr_t src_addr;
38 dma_addr_t dst_addr;
39 union {
40 struct rsnd_dmaen en;
41 struct rsnd_dmapp pp;
42 } dma;
43};
44
25struct rsnd_dma_ctrl {
26 void __iomem *base;
45struct rsnd_dma_ctrl {
46 void __iomem *base;
47 int dmaen_num;
27 int dmapp_num;
28};
29
48 int dmapp_num;
49};
50
30struct rsnd_dma_ops {
31 char *name;
32 void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
33 void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
34 int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
35 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
36 void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
37};
38
39#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
51#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
52#define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod)
53#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
54#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
40
41/*
42 * Audio DMAC
43 */
44static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
45 struct rsnd_dai_stream *io)
46{
47 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);

--- 24 unchanged lines hidden (view full) ---

72
73static void rsnd_dmaen_complete(void *data)
74{
75 struct rsnd_mod *mod = data;
76
77 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
78}
79
55
56/*
57 * Audio DMAC
58 */
59static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
60 struct rsnd_dai_stream *io)
61{
62 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);

--- 24 unchanged lines hidden (view full) ---

87
88static void rsnd_dmaen_complete(void *data)
89{
90 struct rsnd_mod *mod = data;
91
92 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
93}
94
80static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
95static int rsnd_dmaen_stop(struct rsnd_mod *mod,
96 struct rsnd_dai_stream *io,
97 struct rsnd_priv *priv)
81{
98{
99 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
82 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
83
84 dmaengine_terminate_all(dmaen->chan);
100 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
101
102 dmaengine_terminate_all(dmaen->chan);
103
104 return 0;
85}
86
105}
106
87static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
107static int rsnd_dmaen_start(struct rsnd_mod *mod,
108 struct rsnd_dai_stream *io,
109 struct rsnd_priv *priv)
88{
110{
111 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
89 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
112 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
90 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
91 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
92 struct snd_pcm_substream *substream = io->substream;
93 struct device *dev = rsnd_priv_to_dev(priv);
94 struct dma_async_tx_descriptor *desc;
95 int is_play = rsnd_io_is_play(io);
96
97 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
98 substream->runtime->dma_addr,
99 snd_pcm_lib_buffer_bytes(substream),
100 snd_pcm_lib_period_bytes(substream),
101 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
102 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
103
104 if (!desc) {
105 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
113 struct snd_pcm_substream *substream = io->substream;
114 struct device *dev = rsnd_priv_to_dev(priv);
115 struct dma_async_tx_descriptor *desc;
116 int is_play = rsnd_io_is_play(io);
117
118 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
119 substream->runtime->dma_addr,
120 snd_pcm_lib_buffer_bytes(substream),
121 snd_pcm_lib_period_bytes(substream),
122 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
123 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
124
125 if (!desc) {
126 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
106 return;
127 return -EIO;
107 }
108
109 desc->callback = rsnd_dmaen_complete;
128 }
129
130 desc->callback = rsnd_dmaen_complete;
110 desc->callback_param = mod;
131 desc->callback_param = rsnd_mod_get(dma);
111
112 if (dmaengine_submit(desc) < 0) {
113 dev_err(dev, "dmaengine_submit() fail\n");
132
133 if (dmaengine_submit(desc) < 0) {
134 dev_err(dev, "dmaengine_submit() fail\n");
114 return;
135 return -EIO;
115 }
116
117 dma_async_issue_pending(dmaen->chan);
136 }
137
138 dma_async_issue_pending(dmaen->chan);
139
140 return 0;
118}
119
120struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
121 struct rsnd_mod *mod, char *name)
122{
123 struct dma_chan *chan;
124 struct device_node *np;
125 int i = 0;

--- 21 unchanged lines hidden (view full) ---

147 return NULL;
148
149 if (mod_from)
150 return rsnd_mod_dma_req(io, mod_from);
151 else
152 return rsnd_mod_dma_req(io, mod_to);
153}
154
141}
142
143struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
144 struct rsnd_mod *mod, char *name)
145{
146 struct dma_chan *chan;
147 struct device_node *np;
148 int i = 0;

--- 21 unchanged lines hidden (view full) ---

170 return NULL;
171
172 if (mod_from)
173 return rsnd_mod_dma_req(io, mod_from);
174 else
175 return rsnd_mod_dma_req(io, mod_to);
176}
177
155static int rsnd_dmaen_init(struct rsnd_dai_stream *io,
178static int rsnd_dmaen_remove(struct rsnd_mod *mod,
179 struct rsnd_dai_stream *io,
180 struct rsnd_priv *priv)
181{
182 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
183 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
184
185 if (dmaen->chan)
186 dma_release_channel(dmaen->chan);
187
188 dmaen->chan = NULL;
189
190 return 0;
191}
192
193static int rsnd_dmaen_attach(struct rsnd_dai_stream *io,
156 struct rsnd_dma *dma, int id,
157 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
158{
194 struct rsnd_dma *dma, int id,
195 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
196{
197 struct rsnd_mod *mod = rsnd_mod_get(dma);
159 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
160 struct rsnd_priv *priv = rsnd_io_to_priv(io);
198 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
199 struct rsnd_priv *priv = rsnd_io_to_priv(io);
200 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
161 struct device *dev = rsnd_priv_to_dev(priv);
162 struct dma_slave_config cfg = {};
163 int is_play = rsnd_io_is_play(io);
164 int ret;
165
166 if (dmaen->chan) {
167 dev_err(dev, "it already has dma channel\n");
168 return -EIO;

--- 17 unchanged lines hidden (view full) ---

186 }
187
188 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
189 cfg.src_addr = dma->src_addr;
190 cfg.dst_addr = dma->dst_addr;
191 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
192 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
193
201 struct device *dev = rsnd_priv_to_dev(priv);
202 struct dma_slave_config cfg = {};
203 int is_play = rsnd_io_is_play(io);
204 int ret;
205
206 if (dmaen->chan) {
207 dev_err(dev, "it already has dma channel\n");
208 return -EIO;

--- 17 unchanged lines hidden (view full) ---

226 }
227
228 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
229 cfg.src_addr = dma->src_addr;
230 cfg.dst_addr = dma->dst_addr;
231 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
232 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
233
194 dev_dbg(dev, "%s %pad -> %pad\n",
195 dma->ops->name,
234 dev_dbg(dev, "%s[%d] %pad -> %pad\n",
235 rsnd_mod_name(mod), rsnd_mod_id(mod),
196 &cfg.src_addr, &cfg.dst_addr);
197
198 ret = dmaengine_slave_config(dmaen->chan, &cfg);
199 if (ret < 0)
236 &cfg.src_addr, &cfg.dst_addr);
237
238 ret = dmaengine_slave_config(dmaen->chan, &cfg);
239 if (ret < 0)
200 goto rsnd_dma_init_err;
240 goto rsnd_dma_attach_err;
201
241
242 dmac->dmaen_num++;
243
202 return 0;
203
244 return 0;
245
204rsnd_dma_init_err:
205 rsnd_dma_quit(io, dma);
246rsnd_dma_attach_err:
247 rsnd_dmaen_remove(mod, io, priv);
206rsnd_dma_channel_err:
207
208 /*
209 * DMA failed. try to PIO mode
210 * see
211 * rsnd_ssi_fallback()
212 * rsnd_rdai_continuance_probe()
213 */
214 return -EAGAIN;
215}
216
248rsnd_dma_channel_err:
249
250 /*
251 * DMA failed. try to PIO mode
252 * see
253 * rsnd_ssi_fallback()
254 * rsnd_rdai_continuance_probe()
255 */
256 return -EAGAIN;
257}
258
217static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
218{
219 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
220
221 if (dmaen->chan)
222 dma_release_channel(dmaen->chan);
223
224 dmaen->chan = NULL;
225}
226
227static struct rsnd_dma_ops rsnd_dmaen_ops = {
259static struct rsnd_mod_ops rsnd_dmaen_ops = {
228 .name = "audmac",
229 .start = rsnd_dmaen_start,
230 .stop = rsnd_dmaen_stop,
260 .name = "audmac",
261 .start = rsnd_dmaen_start,
262 .stop = rsnd_dmaen_stop,
231 .init = rsnd_dmaen_init,
232 .quit = rsnd_dmaen_quit,
263 .remove = rsnd_dmaen_remove,
233};
234
235/*
236 * Audio DMAC peri peri
237 */
238static const u8 gen2_id_table_ssiu[] = {
239 0x00, /* SSI00 */
240 0x04, /* SSI10 */

--- 61 unchanged lines hidden (view full) ---

302 (rsnd_dmapp_get_id(io, mod_to) << 16);
303}
304
305#define rsnd_dmapp_addr(dmac, dma, reg) \
306 (dmac->base + 0x20 + reg + \
307 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
308static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
309{
264};
265
266/*
267 * Audio DMAC peri peri
268 */
269static const u8 gen2_id_table_ssiu[] = {
270 0x00, /* SSI00 */
271 0x04, /* SSI10 */

--- 61 unchanged lines hidden (view full) ---

333 (rsnd_dmapp_get_id(io, mod_to) << 16);
334}
335
336#define rsnd_dmapp_addr(dmac, dma, reg) \
337 (dmac->base + 0x20 + reg + \
338 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
339static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
340{
310 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
341 struct rsnd_mod *mod = rsnd_mod_get(dma);
311 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
312 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
313 struct device *dev = rsnd_priv_to_dev(priv);
314
315 dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
316
317 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
318}
319
320static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
321{
342 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
343 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
344 struct device *dev = rsnd_priv_to_dev(priv);
345
346 dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
347
348 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
349}
350
351static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
352{
322 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
353 struct rsnd_mod *mod = rsnd_mod_get(dma);
323 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
324 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
325
326 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
327}
328
354 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
355 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
356
357 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
358}
359
329static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
360static int rsnd_dmapp_stop(struct rsnd_mod *mod,
361 struct rsnd_dai_stream *io,
362 struct rsnd_priv *priv)
330{
363{
364 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
331 int i;
332
333 rsnd_dmapp_write(dma, 0, PDMACHCR);
334
335 for (i = 0; i < 1024; i++) {
336 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
365 int i;
366
367 rsnd_dmapp_write(dma, 0, PDMACHCR);
368
369 for (i = 0; i < 1024; i++) {
370 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
337 return;
371 return 0;
338 udelay(1);
339 }
372 udelay(1);
373 }
374
375 return -EIO;
340}
341
376}
377
342static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
378static int rsnd_dmapp_start(struct rsnd_mod *mod,
379 struct rsnd_dai_stream *io,
380 struct rsnd_priv *priv)
343{
381{
382 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
344 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
345
346 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
347 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
348 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
383 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
384
385 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
386 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
387 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
388
389 return 0;
349}
350
390}
391
351static int rsnd_dmapp_init(struct rsnd_dai_stream *io,
352 struct rsnd_dma *dma, int id,
353 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
392static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
393 struct rsnd_dma *dma, int id,
394 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
354{
355 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
356 struct rsnd_priv *priv = rsnd_io_to_priv(io);
357 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
358 struct device *dev = rsnd_priv_to_dev(priv);
359
360 dmapp->dmapp_id = dmac->dmapp_num;
361 dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE;
362
363 dmac->dmapp_num++;
364
395{
396 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
397 struct rsnd_priv *priv = rsnd_io_to_priv(io);
398 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
399 struct device *dev = rsnd_priv_to_dev(priv);
400
401 dmapp->dmapp_id = dmac->dmapp_num;
402 dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE;
403
404 dmac->dmapp_num++;
405
365 rsnd_dmapp_stop(io, dma);
366
367 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
368 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
369
370 return 0;
371}
372
406 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
407 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
408
409 return 0;
410}
411
373static struct rsnd_dma_ops rsnd_dmapp_ops = {
412static struct rsnd_mod_ops rsnd_dmapp_ops = {
374 .name = "audmac-pp",
375 .start = rsnd_dmapp_start,
376 .stop = rsnd_dmapp_stop,
413 .name = "audmac-pp",
414 .start = rsnd_dmapp_start,
415 .stop = rsnd_dmapp_stop,
377 .init = rsnd_dmapp_init,
378 .quit = rsnd_dmapp_stop,
379};
380
381/*
382 * Common DMAC Interface
383 */
384
385/*

--- 106 unchanged lines hidden (view full) ---

492
493 if (!mod)
494 return 0;
495
496 return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
497}
498
499#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
416 .quit = rsnd_dmapp_stop,
417};
418
419/*
420 * Common DMAC Interface
421 */
422
423/*

--- 106 unchanged lines hidden (view full) ---

530
531 if (!mod)
532 return 0;
533
534 return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
535}
536
537#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
500static void rsnd_dma_of_path(struct rsnd_dma *dma,
538static void rsnd_dma_of_path(struct rsnd_mod *this,
501 struct rsnd_dai_stream *io,
502 int is_play,
503 struct rsnd_mod **mod_from,
504 struct rsnd_mod **mod_to)
505{
539 struct rsnd_dai_stream *io,
540 int is_play,
541 struct rsnd_mod **mod_from,
542 struct rsnd_mod **mod_to)
543{
506 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
507 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
508 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
509 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
510 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
511 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
512 struct rsnd_mod *mod[MOD_MAX];
513 struct rsnd_mod *mod_start, *mod_end;
514 struct rsnd_priv *priv = rsnd_mod_to_priv(this);
515 struct device *dev = rsnd_priv_to_dev(priv);
544 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
545 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
546 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
547 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
548 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
549 struct rsnd_mod *mod[MOD_MAX];
550 struct rsnd_mod *mod_start, *mod_end;
551 struct rsnd_priv *priv = rsnd_mod_to_priv(this);
552 struct device *dev = rsnd_priv_to_dev(priv);
516 int nr, i;
553 int nr, i, idx;
517
518 if (!ssi)
519 return;
520
521 nr = 0;
522 for (i = 0; i < MOD_MAX; i++) {
523 mod[i] = NULL;
524 nr += !!rsnd_io_to_mod(io, i);

--- 12 unchanged lines hidden (view full) ---

537 * [E] = mem
538 *
539 * -*-> Audio DMAC
540 * -o-> Audio DMAC peri peri
541 */
542 mod_start = (is_play) ? NULL : ssi;
543 mod_end = (is_play) ? ssi : NULL;
544
554
555 if (!ssi)
556 return;
557
558 nr = 0;
559 for (i = 0; i < MOD_MAX; i++) {
560 mod[i] = NULL;
561 nr += !!rsnd_io_to_mod(io, i);

--- 12 unchanged lines hidden (view full) ---

574 * [E] = mem
575 *
576 * -*-> Audio DMAC
577 * -o-> Audio DMAC peri peri
578 */
579 mod_start = (is_play) ? NULL : ssi;
580 mod_end = (is_play) ? ssi : NULL;
581
545 mod[0] = mod_start;
582 idx = 0;
583 mod[idx++] = mod_start;
546 for (i = 1; i < nr; i++) {
547 if (src) {
584 for (i = 1; i < nr; i++) {
585 if (src) {
548 mod[i] = src;
586 mod[idx++] = src;
549 src = NULL;
550 } else if (ctu) {
587 src = NULL;
588 } else if (ctu) {
551 mod[i] = ctu;
589 mod[idx++] = ctu;
552 ctu = NULL;
553 } else if (mix) {
590 ctu = NULL;
591 } else if (mix) {
554 mod[i] = mix;
592 mod[idx++] = mix;
555 mix = NULL;
556 } else if (dvc) {
593 mix = NULL;
594 } else if (dvc) {
557 mod[i] = dvc;
595 mod[idx++] = dvc;
558 dvc = NULL;
559 }
560 }
596 dvc = NULL;
597 }
598 }
561 mod[i] = mod_end;
599 mod[idx] = mod_end;
562
563 /*
564 * | SSI | SRC |
565 * -------------+-----+-----+
566 * is_play | o | * |
567 * !is_play | * | o |
568 */
569 if ((this == ssi) == (is_play)) {
600
601 /*
602 * | SSI | SRC |
603 * -------------+-----+-----+
604 * is_play | o | * |
605 * !is_play | * | o |
606 */
607 if ((this == ssi) == (is_play)) {
570 *mod_from = mod[nr - 1];
571 *mod_to = mod[nr];
608 *mod_from = mod[idx - 1];
609 *mod_to = mod[idx];
572 } else {
573 *mod_from = mod[0];
574 *mod_to = mod[1];
575 }
576
577 dev_dbg(dev, "module connection (this is %s[%d])\n",
578 rsnd_mod_name(this), rsnd_mod_id(this));
610 } else {
611 *mod_from = mod[0];
612 *mod_to = mod[1];
613 }
614
615 dev_dbg(dev, "module connection (this is %s[%d])\n",
616 rsnd_mod_name(this), rsnd_mod_id(this));
579 for (i = 0; i <= nr; i++) {
617 for (i = 0; i <= idx; i++) {
580 dev_dbg(dev, " %s[%d]%s\n",
581 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
582 (mod[i] == *mod_from) ? " from" :
583 (mod[i] == *mod_to) ? " to" : "");
584 }
585}
586
618 dev_dbg(dev, " %s[%d]%s\n",
619 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
620 (mod[i] == *mod_from) ? " from" :
621 (mod[i] == *mod_to) ? " to" : "");
622 }
623}
624
587void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
625struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io,
626 struct rsnd_mod *mod, int id)
588{
627{
589 dma->ops->stop(io, dma);
590}
591
592void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
593{
594 dma->ops->start(io, dma);
595}
596
597void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
598{
599 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
600 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
601 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
602
603 if (!dmac)
604 return;
605
606 dma->ops->quit(io, dma);
607}
608
609int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
610{
628 struct rsnd_mod *dma_mod;
611 struct rsnd_mod *mod_from = NULL;
612 struct rsnd_mod *mod_to = NULL;
613 struct rsnd_priv *priv = rsnd_io_to_priv(io);
614 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
629 struct rsnd_mod *mod_from = NULL;
630 struct rsnd_mod *mod_to = NULL;
631 struct rsnd_priv *priv = rsnd_io_to_priv(io);
632 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
633 struct rsnd_dma *dma;
615 struct device *dev = rsnd_priv_to_dev(priv);
634 struct device *dev = rsnd_priv_to_dev(priv);
635 struct rsnd_mod_ops *ops;
636 enum rsnd_mod_type type;
637 int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
638 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
616 int is_play = rsnd_io_is_play(io);
639 int is_play = rsnd_io_is_play(io);
640 int ret, dma_id;
617
618 /*
619 * DMA failed. try to PIO mode
620 * see
621 * rsnd_ssi_fallback()
622 * rsnd_rdai_continuance_probe()
623 */
624 if (!dmac)
641
642 /*
643 * DMA failed. try to PIO mode
644 * see
645 * rsnd_ssi_fallback()
646 * rsnd_rdai_continuance_probe()
647 */
648 if (!dmac)
625 return -EAGAIN;
649 return ERR_PTR(-EAGAIN);
626
650
627 rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to);
651 dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
652 if (!dma)
653 return ERR_PTR(-ENOMEM);
628
654
655 rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to);
656
629 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
630 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
631
632 /* for Gen2 */
657 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
658 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
659
660 /* for Gen2 */
633 if (mod_from && mod_to)
634 dma->ops = &rsnd_dmapp_ops;
635 else
636 dma->ops = &rsnd_dmaen_ops;
661 if (mod_from && mod_to) {
662 ops = &rsnd_dmapp_ops;
663 attach = rsnd_dmapp_attach;
664 dma_id = dmac->dmapp_num;
665 type = RSND_MOD_AUDMAPP;
666 } else {
667 ops = &rsnd_dmaen_ops;
668 attach = rsnd_dmaen_attach;
669 dma_id = dmac->dmaen_num;
670 type = RSND_MOD_AUDMA;
671 }
637
638 /* for Gen1, overwrite */
672
673 /* for Gen1, overwrite */
639 if (rsnd_is_gen1(priv))
640 dma->ops = &rsnd_dmaen_ops;
674 if (rsnd_is_gen1(priv)) {
675 ops = &rsnd_dmaen_ops;
676 attach = rsnd_dmaen_attach;
677 dma_id = dmac->dmaen_num;
678 type = RSND_MOD_AUDMA;
679 }
641
680
642 dev_dbg(dev, "%s %s[%d] -> %s[%d]\n",
643 dma->ops->name,
681 dma_mod = rsnd_mod_get(dma);
682
683 ret = rsnd_mod_init(priv, dma_mod,
684 ops, NULL, rsnd_mod_get_status, type, dma_id);
685 if (ret < 0)
686 return ERR_PTR(ret);
687
688 dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n",
689 rsnd_mod_name(dma_mod), rsnd_mod_id(dma_mod),
644 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
645 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
646
690 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
691 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
692
647 return dma->ops->init(io, dma, id, mod_from, mod_to);
693 ret = attach(io, dma, id, mod_from, mod_to);
694 if (ret < 0)
695 return ERR_PTR(ret);
696
697 ret = rsnd_dai_connect(dma_mod, io, type);
698 if (ret < 0)
699 return ERR_PTR(ret);
700
701 return rsnd_mod_get(dma);
648}
649
702}
703
650int rsnd_dma_probe(struct platform_device *pdev,
651 const struct rsnd_of_data *of_data,
652 struct rsnd_priv *priv)
704int rsnd_dma_probe(struct rsnd_priv *priv)
653{
705{
706 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
654 struct device *dev = rsnd_priv_to_dev(priv);
655 struct rsnd_dma_ctrl *dmac;
656 struct resource *res;
657
658 /*
659 * for Gen1
660 */
661 if (rsnd_is_gen1(priv))

--- 21 unchanged lines hidden ---
707 struct device *dev = rsnd_priv_to_dev(priv);
708 struct rsnd_dma_ctrl *dmac;
709 struct resource *res;
710
711 /*
712 * for Gen1
713 */
714 if (rsnd_is_gen1(priv))

--- 21 unchanged lines hidden ---