blob: 229b68d2cf7027a436441e265901ef50df7b66fc [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
25struct rsnd_dma_ctrl {
26 void __iomem *base;
27 int dmapp_num;
28};
29
Kuninori Morimoto98d358a2015-07-15 07:15:27 +000030struct rsnd_dma_ops {
Kuninori Morimotoddea1b22015-07-15 07:16:03 +000031 char *name;
Kuninori Morimoto98d358a2015-07-15 07:15:27 +000032 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
Kuninori Morimoto288f3922015-02-20 10:27:42 +000039#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
40
41/*
42 * Audio DMAC
43 */
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +000044static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
45 struct rsnd_dai_stream *io)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000046{
Kuninori Morimoto75defee2015-06-15 06:21:15 +000047 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
Kuninori Morimoto75defee2015-06-15 06:21:15 +000048 bool elapsed = false;
49 unsigned long flags;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000050
51 /*
52 * Renesas sound Gen1 needs 1 DMAC,
53 * Gen2 needs 2 DMAC.
54 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
55 * But, Audio-DMAC-peri-peri doesn't have interrupt,
56 * and this driver is assuming that here.
57 *
58 * If Audio-DMAC-peri-peri has interrpt,
59 * rsnd_dai_pointer_update() will be called twice,
60 * ant it will breaks io->byte_pos
61 */
Kuninori Morimoto75defee2015-06-15 06:21:15 +000062 spin_lock_irqsave(&priv->lock, flags);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000063
Kuninori Morimotod5bbe7d2015-06-15 06:27:47 +000064 if (rsnd_io_is_working(io))
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +000065 elapsed = rsnd_dai_pointer_update(io, io->byte_per_period);
Kuninori Morimoto75defee2015-06-15 06:21:15 +000066
67 spin_unlock_irqrestore(&priv->lock, flags);
68
69 if (elapsed)
70 rsnd_dai_period_elapsed(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000071}
72
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +000073static void rsnd_dmaen_complete(void *data)
74{
75 struct rsnd_mod *mod = data;
76
77 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
78}
79
80static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000081{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +000082 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
83
84 dmaengine_terminate_all(dmaen->chan);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000085}
86
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +000087static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000088{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +000089 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000090 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
91 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000092 struct snd_pcm_substream *substream = io->substream;
93 struct device *dev = rsnd_priv_to_dev(priv);
94 struct dma_async_tx_descriptor *desc;
Kuninori Morimotoaaf4fce2015-02-20 10:28:32 +000095 int is_play = rsnd_io_is_play(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000096
Kuninori Morimoto0d00a522015-02-20 10:29:13 +000097 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
Kuninori Morimotobfe834b2015-02-20 10:25:55 +000098 substream->runtime->dma_addr,
99 snd_pcm_lib_buffer_bytes(substream),
100 snd_pcm_lib_period_bytes(substream),
Kuninori Morimotoaaf4fce2015-02-20 10:28:32 +0000101 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000102 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
103
104 if (!desc) {
105 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
106 return;
107 }
108
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000109 desc->callback = rsnd_dmaen_complete;
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000110 desc->callback_param = mod;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000111
112 if (dmaengine_submit(desc) < 0) {
113 dev_err(dev, "dmaengine_submit() fail\n");
114 return;
115 }
116
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000117 dma_async_issue_pending(dmaen->chan);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000118}
119
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000120struct 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;
126
127 for_each_child_of_node(of_node, np) {
128 if (i == rsnd_mod_id(mod))
129 break;
130 i++;
131 }
132
133 chan = of_dma_request_slave_channel(np, name);
134
135 of_node_put(np);
136 of_node_put(of_node);
137
138 return chan;
139}
140
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000141static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
142 struct rsnd_mod *mod_from,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000143 struct rsnd_mod *mod_to)
144{
145 if ((!mod_from && !mod_to) ||
146 (mod_from && mod_to))
147 return NULL;
148
149 if (mod_from)
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000150 return rsnd_mod_dma_req(io, mod_from);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000151 else
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000152 return rsnd_mod_dma_req(io, mod_to);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000153}
154
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000155static int rsnd_dmaen_init(struct rsnd_dai_stream *io,
156 struct rsnd_dma *dma, int id,
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000157 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000158{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000159 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000160 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000161 struct device *dev = rsnd_priv_to_dev(priv);
162 struct dma_slave_config cfg = {};
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000163 int is_play = rsnd_io_is_play(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000164 int ret;
165
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000166 if (dmaen->chan) {
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000167 dev_err(dev, "it already has dma channel\n");
168 return -EIO;
169 }
170
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000171 if (dev->of_node) {
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000172 dmaen->chan = rsnd_dmaen_request_channel(io, mod_from, mod_to);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000173 } else {
174 dma_cap_mask_t mask;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000175
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000176 dma_cap_zero(mask);
177 dma_cap_set(DMA_SLAVE, mask);
178
179 dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
180 (void *)id);
181 }
182 if (IS_ERR_OR_NULL(dmaen->chan)) {
Kuninori Morimotod1acba22015-04-13 06:00:45 +0000183 dmaen->chan = NULL;
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000184 dev_err(dev, "can't get dma channel\n");
185 goto rsnd_dma_channel_err;
186 }
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000187
188 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000189 cfg.src_addr = dma->src_addr;
190 cfg.dst_addr = dma->dst_addr;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000191 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
192 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
193
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000194 dev_dbg(dev, "%s %pad -> %pad\n",
195 dma->ops->name,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000196 &cfg.src_addr, &cfg.dst_addr);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000197
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000198 ret = dmaengine_slave_config(dmaen->chan, &cfg);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000199 if (ret < 0)
200 goto rsnd_dma_init_err;
201
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000202 return 0;
203
204rsnd_dma_init_err:
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000205 rsnd_dma_quit(io, dma);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000206rsnd_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
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000217static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000218{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000219 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000220
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000221 if (dmaen->chan)
222 dma_release_channel(dmaen->chan);
223
224 dmaen->chan = NULL;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000225}
226
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000227static struct rsnd_dma_ops rsnd_dmaen_ops = {
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000228 .name = "audmac",
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000229 .start = rsnd_dmaen_start,
230 .stop = rsnd_dmaen_stop,
231 .init = rsnd_dmaen_init,
232 .quit = rsnd_dmaen_quit,
233};
234
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000235/*
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000236 * Audio DMAC peri peri
237 */
238static const u8 gen2_id_table_ssiu[] = {
239 0x00, /* SSI00 */
240 0x04, /* SSI10 */
241 0x08, /* SSI20 */
242 0x0c, /* SSI3 */
243 0x0d, /* SSI4 */
244 0x0e, /* SSI5 */
245 0x0f, /* SSI6 */
246 0x10, /* SSI7 */
247 0x11, /* SSI8 */
248 0x12, /* SSI90 */
249};
250static const u8 gen2_id_table_scu[] = {
251 0x2d, /* SCU_SRCI0 */
252 0x2e, /* SCU_SRCI1 */
253 0x2f, /* SCU_SRCI2 */
254 0x30, /* SCU_SRCI3 */
255 0x31, /* SCU_SRCI4 */
256 0x32, /* SCU_SRCI5 */
257 0x33, /* SCU_SRCI6 */
258 0x34, /* SCU_SRCI7 */
259 0x35, /* SCU_SRCI8 */
260 0x36, /* SCU_SRCI9 */
261};
262static const u8 gen2_id_table_cmd[] = {
263 0x37, /* SCU_CMD0 */
264 0x38, /* SCU_CMD1 */
265};
266
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000267static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
268 struct rsnd_mod *mod)
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000269{
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000270 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
271 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
272 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
273 const u8 *entry = NULL;
274 int id = rsnd_mod_id(mod);
275 int size = 0;
276
277 if (mod == ssi) {
278 entry = gen2_id_table_ssiu;
279 size = ARRAY_SIZE(gen2_id_table_ssiu);
280 } else if (mod == src) {
281 entry = gen2_id_table_scu;
282 size = ARRAY_SIZE(gen2_id_table_scu);
283 } else if (mod == dvc) {
284 entry = gen2_id_table_cmd;
285 size = ARRAY_SIZE(gen2_id_table_cmd);
286 }
287
288 if (!entry)
289 return 0xFF;
290
291 if (size <= id)
292 return 0xFF;
293
294 return entry[id];
295}
296
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000297static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io,
298 struct rsnd_mod *mod_from,
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000299 struct rsnd_mod *mod_to)
300{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000301 return (rsnd_dmapp_get_id(io, mod_from) << 24) +
302 (rsnd_dmapp_get_id(io, mod_to) << 16);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000303}
304
305#define rsnd_dmapp_addr(dmac, dma, reg) \
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000306 (dmac->base + 0x20 + reg + \
307 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000308static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
309{
310 struct rsnd_mod *mod = rsnd_dma_to_mod(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{
322 struct rsnd_mod *mod = rsnd_dma_to_mod(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
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000329static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000330{
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))
337 return;
338 udelay(1);
339 }
340}
341
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000342static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000343{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000344 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
345
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000346 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
347 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000348 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000349}
350
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000351static int rsnd_dmapp_init(struct rsnd_dai_stream *io,
352 struct rsnd_dma *dma, int id,
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000353 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
354{
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000355 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000356 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000357 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
358 struct device *dev = rsnd_priv_to_dev(priv);
359
Kuninori Morimoto0d00a522015-02-20 10:29:13 +0000360 dmapp->dmapp_id = dmac->dmapp_num;
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000361 dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE;
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000362
363 dmac->dmapp_num++;
364
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000365 rsnd_dmapp_stop(io, dma);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000366
Geert Uytterhoeven6ec6fb62015-03-10 11:48:05 +0100367 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
368 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000369
370 return 0;
371}
372
373static struct rsnd_dma_ops rsnd_dmapp_ops = {
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000374 .name = "audmac-pp",
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000375 .start = rsnd_dmapp_start,
376 .stop = rsnd_dmapp_stop,
377 .init = rsnd_dmapp_init,
378 .quit = rsnd_dmapp_stop,
379};
380
381/*
382 * Common DMAC Interface
383 */
384
385/*
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000386 * DMA read/write register offset
387 *
388 * RSND_xxx_I_N for Audio DMAC input
389 * RSND_xxx_O_N for Audio DMAC output
390 * RSND_xxx_I_P for Audio DMAC peri peri input
391 * RSND_xxx_O_P for Audio DMAC peri peri output
392 *
393 * ex) R-Car H2 case
394 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
395 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
396 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
397 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
398 * CMD : 0xec500000 / / 0xec008000 0xec308000
399 */
400#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
401#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
402
403#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
404#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
405
406#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
407#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
408
409#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
410#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
411
412#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
413#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
414
415#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
416#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
417
418static dma_addr_t
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000419rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000420 struct rsnd_mod *mod,
421 int is_play, int is_from)
422{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000423 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000424 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000425 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
426 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
427 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
428 int use_src = !!rsnd_io_to_mod_src(io);
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000429 int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
430 !!rsnd_io_to_mod_ctu(io);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000431 int id = rsnd_mod_id(mod);
432 struct dma_addr {
433 dma_addr_t out_addr;
434 dma_addr_t in_addr;
435 } dma_addrs[3][2][3] = {
436 /* SRC */
437 {{{ 0, 0 },
438 /* Capture */
439 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
440 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
441 /* Playback */
442 {{ 0, 0, },
443 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
444 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
445 },
446 /* SSI */
447 /* Capture */
448 {{{ RDMA_SSI_O_N(ssi, id), 0 },
449 { RDMA_SSIU_O_P(ssi, id), 0 },
450 { RDMA_SSIU_O_P(ssi, id), 0 } },
451 /* Playback */
452 {{ 0, RDMA_SSI_I_N(ssi, id) },
453 { 0, RDMA_SSIU_I_P(ssi, id) },
454 { 0, RDMA_SSIU_I_P(ssi, id) } }
455 },
456 /* SSIU */
457 /* Capture */
458 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
459 { RDMA_SSIU_O_P(ssi, id), 0 },
460 { RDMA_SSIU_O_P(ssi, id), 0 } },
461 /* Playback */
462 {{ 0, RDMA_SSIU_I_N(ssi, id) },
463 { 0, RDMA_SSIU_I_P(ssi, id) },
464 { 0, RDMA_SSIU_I_P(ssi, id) } } },
465 };
466
467 /* it shouldn't happen */
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000468 if (use_cmd && !use_src)
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000469 dev_err(dev, "DVC is selected without SRC\n");
470
471 /* use SSIU or SSI ? */
Kuninori Morimotobfc0cfe2015-06-15 06:26:56 +0000472 if (is_ssi && rsnd_ssi_use_busif(io, mod))
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000473 is_ssi++;
474
475 return (is_from) ?
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000476 dma_addrs[is_ssi][is_play][use_src + use_cmd].out_addr :
477 dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr;
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000478}
479
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000480static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000481 struct rsnd_mod *mod,
482 int is_play, int is_from)
483{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000484 struct rsnd_priv *priv = rsnd_io_to_priv(io);
485
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000486 /*
487 * gen1 uses default DMA addr
488 */
489 if (rsnd_is_gen1(priv))
490 return 0;
491
492 if (!mod)
493 return 0;
494
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000495 return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
Kuninori Morimoto747c71b2015-02-20 10:26:29 +0000496}
497
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000498#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000499static void rsnd_dma_of_path(struct rsnd_dma *dma,
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000500 struct rsnd_dai_stream *io,
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000501 int is_play,
502 struct rsnd_mod **mod_from,
503 struct rsnd_mod **mod_to)
504{
505 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000506 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
507 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000508 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000509 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
510 struct rsnd_mod *mod[MOD_MAX];
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000511 struct rsnd_mod *mod_start, *mod_end;
512 struct rsnd_priv *priv = rsnd_mod_to_priv(this);
513 struct device *dev = rsnd_priv_to_dev(priv);
514 int nr, i;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000515
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000516 if (!ssi)
517 return;
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000518
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000519 nr = 0;
520 for (i = 0; i < MOD_MAX; i++) {
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000521 mod[i] = NULL;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000522 nr += !!rsnd_io_to_mod(io, i);
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000523 }
524
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000525 /*
526 * [S] -*-> [E]
527 * [S] -*-> SRC -o-> [E]
528 * [S] -*-> SRC -> DVC -o-> [E]
529 * [S] -*-> SRC -> CTU -> MIX -> DVC -o-> [E]
530 *
531 * playback [S] = mem
532 * [E] = SSI
533 *
534 * capture [S] = SSI
535 * [E] = mem
536 *
537 * -*-> Audio DMAC
538 * -o-> Audio DMAC peri peri
539 */
540 mod_start = (is_play) ? NULL : ssi;
541 mod_end = (is_play) ? ssi : NULL;
542
543 mod[0] = mod_start;
544 for (i = 1; i < nr; i++) {
545 if (src) {
546 mod[i] = src;
547 src = NULL;
Kuninori Morimoto9269e3c2015-07-15 07:17:17 +0000548 } else if (ctu) {
549 mod[i] = ctu;
550 ctu = NULL;
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000551 } else if (dvc) {
552 mod[i] = dvc;
553 dvc = NULL;
554 }
555 }
556 mod[i] = mod_end;
557
558 /*
559 * | SSI | SRC |
560 * -------------+-----+-----+
561 * is_play | o | * |
562 * !is_play | * | o |
563 */
564 if ((this == ssi) == (is_play)) {
565 *mod_from = mod[nr - 1];
566 *mod_to = mod[nr];
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000567 } else {
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000568 *mod_from = mod[0];
569 *mod_to = mod[1];
570 }
571
572 dev_dbg(dev, "module connection (this is %s[%d])\n",
573 rsnd_mod_name(this), rsnd_mod_id(this));
574 for (i = 0; i <= nr; i++) {
575 dev_dbg(dev, " %s[%d]%s\n",
576 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
577 (mod[i] == *mod_from) ? " from" :
578 (mod[i] == *mod_to) ? " to" : "");
Kuninori Morimotobfe834b2015-02-20 10:25:55 +0000579 }
580}
581
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000582void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000583{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000584 dma->ops->stop(io, dma);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000585}
586
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000587void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000588{
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000589 dma->ops->start(io, dma);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000590}
591
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000592void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000593{
Kuninori Morimoto85374832015-03-10 01:25:01 +0000594 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
595 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
596 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
597
598 if (!dmac)
599 return;
600
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000601 dma->ops->quit(io, dma);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000602}
603
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000604int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000605{
Kuninori Morimoto7dfb4912015-07-15 07:16:56 +0000606 struct rsnd_mod *mod_from = NULL;
607 struct rsnd_mod *mod_to = NULL;
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000608 struct rsnd_priv *priv = rsnd_io_to_priv(io);
Kuninori Morimoto85374832015-03-10 01:25:01 +0000609 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000610 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000611 int is_play = rsnd_io_is_play(io);
612
Kuninori Morimoto85374832015-03-10 01:25:01 +0000613 /*
614 * DMA failed. try to PIO mode
615 * see
616 * rsnd_ssi_fallback()
617 * rsnd_rdai_continuance_probe()
618 */
619 if (!dmac)
620 return -EAGAIN;
621
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000622 rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000623
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000624 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
625 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000626
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000627 /* for Gen2 */
628 if (mod_from && mod_to)
629 dma->ops = &rsnd_dmapp_ops;
630 else
631 dma->ops = &rsnd_dmaen_ops;
632
633 /* for Gen1, overwrite */
634 if (rsnd_is_gen1(priv))
635 dma->ops = &rsnd_dmaen_ops;
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000636
Kuninori Morimotoddea1b22015-07-15 07:16:03 +0000637 dev_dbg(dev, "%s %s[%d] -> %s[%d]\n",
638 dma->ops->name,
639 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
640 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
641
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000642 return dma->ops->init(io, dma, id, mod_from, mod_to);
Kuninori Morimoto3c685652015-02-20 10:27:12 +0000643}
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000644
645int rsnd_dma_probe(struct platform_device *pdev,
646 const struct rsnd_of_data *of_data,
647 struct rsnd_priv *priv)
648{
649 struct device *dev = rsnd_priv_to_dev(priv);
650 struct rsnd_dma_ctrl *dmac;
651 struct resource *res;
652
653 /*
654 * for Gen1
655 */
656 if (rsnd_is_gen1(priv))
657 return 0;
658
659 /*
660 * for Gen2
661 */
662 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
663 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
664 if (!dmac || !res) {
665 dev_err(dev, "dma allocate failed\n");
Kuninori Morimoto85374832015-03-10 01:25:01 +0000666 return 0; /* it will be PIO mode */
Kuninori Morimoto288f3922015-02-20 10:27:42 +0000667 }
668
669 dmac->dmapp_num = 0;
670 dmac->base = devm_ioremap_resource(dev, res);
671 if (IS_ERR(dmac->base))
672 return PTR_ERR(dmac->base);
673
674 priv->dma = dmac;
675
676 return 0;
677}