xref: /linux/sound/soc/sh/rcar/dma.c (revision 747c71b12ee8357e73a88eb25f569e2a20e80df3)
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  */
11 #include "rsnd.h"
12 
13 static void rsnd_dma_complete(void *data)
14 {
15 	struct rsnd_dma *dma = (struct rsnd_dma *)data;
16 	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
17 	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
18 
19 	/*
20 	 * Renesas sound Gen1 needs 1 DMAC,
21 	 * Gen2 needs 2 DMAC.
22 	 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
23 	 * But, Audio-DMAC-peri-peri doesn't have interrupt,
24 	 * and this driver is assuming that here.
25 	 *
26 	 * If Audio-DMAC-peri-peri has interrpt,
27 	 * rsnd_dai_pointer_update() will be called twice,
28 	 * ant it will breaks io->byte_pos
29 	 */
30 
31 	rsnd_dai_pointer_update(io, io->byte_per_period);
32 }
33 
34 #define DMA_NAME_SIZE 16
35 static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
36 {
37 	if (mod)
38 		return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
39 				rsnd_mod_dma_name(mod), rsnd_mod_id(mod));
40 	else
41 		return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem");
42 
43 }
44 
45 static void rsnd_dma_of_name(struct rsnd_mod *mod_from,
46 			     struct rsnd_mod *mod_to,
47 			     char *dma_name)
48 {
49 	int index = 0;
50 
51 	index = _rsnd_dma_of_name(dma_name + index, mod_from);
52 	*(dma_name + index++) = '_';
53 	index = _rsnd_dma_of_name(dma_name + index, mod_to);
54 }
55 
56 void rsnd_dma_stop(struct rsnd_dma *dma)
57 {
58 	dmaengine_terminate_all(dma->chan);
59 }
60 
61 void rsnd_dma_start(struct rsnd_dma *dma)
62 {
63 	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
64 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
65 	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
66 	struct snd_pcm_substream *substream = io->substream;
67 	struct device *dev = rsnd_priv_to_dev(priv);
68 	struct dma_async_tx_descriptor *desc;
69 
70 	desc = dmaengine_prep_dma_cyclic(dma->chan,
71 					 (dma->addr) ? dma->addr :
72 					 substream->runtime->dma_addr,
73 					 snd_pcm_lib_buffer_bytes(substream),
74 					 snd_pcm_lib_period_bytes(substream),
75 					 dma->dir,
76 					 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
77 
78 	if (!desc) {
79 		dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
80 		return;
81 	}
82 
83 	desc->callback		= rsnd_dma_complete;
84 	desc->callback_param	= dma;
85 
86 	if (dmaengine_submit(desc) < 0) {
87 		dev_err(dev, "dmaengine_submit() fail\n");
88 		return;
89 	}
90 
91 	dma_async_issue_pending(dma->chan);
92 }
93 
94 static void rsnd_dma_of_path(struct rsnd_dma *dma,
95 			     int is_play,
96 			     struct rsnd_mod **mod_from,
97 			     struct rsnd_mod **mod_to);
98 
99 static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv,
100 				struct rsnd_mod *mod,
101 				int is_play, int is_from);
102 
103 int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
104 {
105 	struct device *dev = rsnd_priv_to_dev(priv);
106 	struct dma_slave_config cfg = {};
107 	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
108 	struct rsnd_mod *mod_from;
109 	struct rsnd_mod *mod_to;
110 	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
111 	int is_play = rsnd_io_is_play(io);
112 	char dma_name[DMA_NAME_SIZE];
113 	dma_cap_mask_t mask;
114 	int ret;
115 
116 	if (dma->chan) {
117 		dev_err(dev, "it already has dma channel\n");
118 		return -EIO;
119 	}
120 
121 	dma_cap_zero(mask);
122 	dma_cap_set(DMA_SLAVE, mask);
123 
124 	rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
125 	rsnd_dma_of_name(mod_from, mod_to, dma_name);
126 
127 	cfg.direction	= is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
128 	cfg.src_addr	= rsnd_dma_addr(priv, mod_from, is_play, 1);
129 	cfg.dst_addr	= rsnd_dma_addr(priv, mod_to,   is_play, 0);
130 	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
131 	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
132 
133 	dev_dbg(dev, "dma : %s %pad -> %pad\n",
134 		dma_name, &cfg.src_addr, &cfg.dst_addr);
135 
136 	dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
137 						     (void *)id, dev,
138 						     dma_name);
139 	if (!dma->chan) {
140 		dev_err(dev, "can't get dma channel\n");
141 		goto rsnd_dma_channel_err;
142 	}
143 
144 	ret = dmaengine_slave_config(dma->chan, &cfg);
145 	if (ret < 0)
146 		goto rsnd_dma_init_err;
147 
148 	dma->addr = is_play ? cfg.src_addr : cfg.dst_addr;
149 	dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
150 
151 	return 0;
152 
153 rsnd_dma_init_err:
154 	rsnd_dma_quit(dma);
155 rsnd_dma_channel_err:
156 
157 	/*
158 	 * DMA failed. try to PIO mode
159 	 * see
160 	 *	rsnd_ssi_fallback()
161 	 *	rsnd_rdai_continuance_probe()
162 	 */
163 	return -EAGAIN;
164 }
165 
166 void rsnd_dma_quit(struct rsnd_dma *dma)
167 {
168 	if (dma->chan)
169 		dma_release_channel(dma->chan);
170 
171 	dma->chan = NULL;
172 }
173 
174 /*
175  *	DMA read/write register offset
176  *
177  *	RSND_xxx_I_N	for Audio DMAC input
178  *	RSND_xxx_O_N	for Audio DMAC output
179  *	RSND_xxx_I_P	for Audio DMAC peri peri input
180  *	RSND_xxx_O_P	for Audio DMAC peri peri output
181  *
182  *	ex) R-Car H2 case
183  *	      mod        / DMAC in    / DMAC out   / DMAC PP in / DMAC pp out
184  *	SSI : 0xec541000 / 0xec241008 / 0xec24100c
185  *	SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
186  *	SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
187  *	CMD : 0xec500000 /            / 0xec008000                0xec308000
188  */
189 #define RDMA_SSI_I_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
190 #define RDMA_SSI_O_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
191 
192 #define RDMA_SSIU_I_N(addr, i)	(addr ##_reg - 0x00441000 + (0x1000 * i))
193 #define RDMA_SSIU_O_N(addr, i)	(addr ##_reg - 0x00441000 + (0x1000 * i))
194 
195 #define RDMA_SSIU_I_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
196 #define RDMA_SSIU_O_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
197 
198 #define RDMA_SRC_I_N(addr, i)	(addr ##_reg - 0x00500000 + (0x400 * i))
199 #define RDMA_SRC_O_N(addr, i)	(addr ##_reg - 0x004fc000 + (0x400 * i))
200 
201 #define RDMA_SRC_I_P(addr, i)	(addr ##_reg - 0x00200000 + (0x400 * i))
202 #define RDMA_SRC_O_P(addr, i)	(addr ##_reg - 0x001fc000 + (0x400 * i))
203 
204 #define RDMA_CMD_O_N(addr, i)	(addr ##_reg - 0x004f8000 + (0x400 * i))
205 #define RDMA_CMD_O_P(addr, i)	(addr ##_reg - 0x001f8000 + (0x400 * i))
206 
207 static dma_addr_t
208 rsnd_gen2_dma_addr(struct rsnd_priv *priv,
209 		   struct rsnd_mod *mod,
210 		   int is_play, int is_from)
211 {
212 	struct device *dev = rsnd_priv_to_dev(priv);
213 	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
214 	phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
215 	phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
216 	int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
217 	int use_src = !!rsnd_io_to_mod_src(io);
218 	int use_dvc = !!rsnd_io_to_mod_dvc(io);
219 	int id = rsnd_mod_id(mod);
220 	struct dma_addr {
221 		dma_addr_t out_addr;
222 		dma_addr_t in_addr;
223 	} dma_addrs[3][2][3] = {
224 		/* SRC */
225 		{{{ 0,				0 },
226 		  /* Capture */
227 		  { RDMA_SRC_O_N(src, id),	RDMA_SRC_I_P(src, id) },
228 		  { RDMA_CMD_O_N(src, id),	RDMA_SRC_I_P(src, id) } },
229 		 /* Playback */
230 		 {{ 0,				0, },
231 		  { RDMA_SRC_O_P(src, id),	RDMA_SRC_I_N(src, id) },
232 		  { RDMA_CMD_O_P(src, id),	RDMA_SRC_I_N(src, id) } }
233 		},
234 		/* SSI */
235 		/* Capture */
236 		{{{ RDMA_SSI_O_N(ssi, id),	0 },
237 		  { RDMA_SSIU_O_P(ssi, id),	0 },
238 		  { RDMA_SSIU_O_P(ssi, id),	0 } },
239 		 /* Playback */
240 		 {{ 0,				RDMA_SSI_I_N(ssi, id) },
241 		  { 0,				RDMA_SSIU_I_P(ssi, id) },
242 		  { 0,				RDMA_SSIU_I_P(ssi, id) } }
243 		},
244 		/* SSIU */
245 		/* Capture */
246 		{{{ RDMA_SSIU_O_N(ssi, id),	0 },
247 		  { RDMA_SSIU_O_P(ssi, id),	0 },
248 		  { RDMA_SSIU_O_P(ssi, id),	0 } },
249 		 /* Playback */
250 		 {{ 0,				RDMA_SSIU_I_N(ssi, id) },
251 		  { 0,				RDMA_SSIU_I_P(ssi, id) },
252 		  { 0,				RDMA_SSIU_I_P(ssi, id) } } },
253 	};
254 
255 	/* it shouldn't happen */
256 	if (use_dvc && !use_src)
257 		dev_err(dev, "DVC is selected without SRC\n");
258 
259 	/* use SSIU or SSI ? */
260 	if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu")))
261 		is_ssi++;
262 
263 	return (is_from) ?
264 		dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
265 		dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
266 }
267 
268 static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv,
269 				struct rsnd_mod *mod,
270 				int is_play, int is_from)
271 {
272 	/*
273 	 * gen1 uses default DMA addr
274 	 */
275 	if (rsnd_is_gen1(priv))
276 		return 0;
277 
278 	if (!mod)
279 		return 0;
280 
281 	return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
282 }
283 
284 #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
285 static void rsnd_dma_of_path(struct rsnd_dma *dma,
286 			     int is_play,
287 			     struct rsnd_mod **mod_from,
288 			     struct rsnd_mod **mod_to)
289 {
290 	struct rsnd_mod *this = rsnd_dma_to_mod(dma);
291 	struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
292 	struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
293 	struct rsnd_mod *src = rsnd_io_to_mod_src(io);
294 	struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
295 	struct rsnd_mod *mod[MOD_MAX];
296 	int i, index;
297 
298 
299 	for (i = 0; i < MOD_MAX; i++)
300 		mod[i] = NULL;
301 
302 	/*
303 	 * in play case...
304 	 *
305 	 * src -> dst
306 	 *
307 	 * mem -> SSI
308 	 * mem -> SRC -> SSI
309 	 * mem -> SRC -> DVC -> SSI
310 	 */
311 	mod[0] = NULL; /* for "mem" */
312 	index = 1;
313 	for (i = 1; i < MOD_MAX; i++) {
314 		if (!src) {
315 			mod[i] = ssi;
316 		} else if (!dvc) {
317 			mod[i] = src;
318 			src = NULL;
319 		} else {
320 			if ((!is_play) && (this == src))
321 				this = dvc;
322 
323 			mod[i] = (is_play) ? src : dvc;
324 			i++;
325 			mod[i] = (is_play) ? dvc : src;
326 			src = NULL;
327 			dvc = NULL;
328 		}
329 
330 		if (mod[i] == this)
331 			index = i;
332 
333 		if (mod[i] == ssi)
334 			break;
335 	}
336 
337 	if (is_play) {
338 		*mod_from = mod[index - 1];
339 		*mod_to   = mod[index];
340 	} else {
341 		*mod_from = mod[index];
342 		*mod_to   = mod[index - 1];
343 	}
344 }
345 
346