xref: /openbmc/linux/sound/soc/sh/rcar/ssiu.c (revision 047f2d94)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Renesas R-Car SSIU support
4 //
5 // Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 
7 #include "rsnd.h"
8 
9 #define SSIU_NAME "ssiu"
10 
11 struct rsnd_ssiu {
12 	struct rsnd_mod mod;
13 	u32 busif_status[8]; /* for BUSIF0 - BUSIF7 */
14 	unsigned int usrcnt;
15 	int id;
16 	int id_sub;
17 };
18 
19 /* SSI_MODE */
20 #define TDM_EXT		(1 << 0)
21 #define TDM_SPLIT	(1 << 8)
22 
23 #define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
24 #define rsnd_mod_to_ssiu(_mod) container_of((_mod), struct rsnd_ssiu, mod)
25 #define for_each_rsnd_ssiu(pos, priv, i)				\
26 	for (i = 0;							\
27 	     (i < rsnd_ssiu_nr(priv)) &&				\
28 		     ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i));	\
29 	     i++)
30 
31 /*
32  *	SSI	Gen2		Gen3
33  *	0	BUSIF0-3	BUSIF0-7
34  *	1	BUSIF0-3	BUSIF0-7
35  *	2	BUSIF0-3	BUSIF0-7
36  *	3	BUSIF0		BUSIF0-7
37  *	4	BUSIF0		BUSIF0-7
38  *	5	BUSIF0		BUSIF0
39  *	6	BUSIF0		BUSIF0
40  *	7	BUSIF0		BUSIF0
41  *	8	BUSIF0		BUSIF0
42  *	9	BUSIF0-3	BUSIF0-7
43  *	total	22		52
44  */
45 static const int gen2_id[] = { 0, 4,  8, 12, 13, 14, 15, 16, 17, 18 };
46 static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
47 
48 static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
49 				 struct rsnd_dai_stream *io,
50 				 enum rsnd_mod_type type)
51 {
52 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
53 	int busif = rsnd_mod_id_sub(mod);
54 
55 	return &ssiu->busif_status[busif];
56 }
57 
58 static int rsnd_ssiu_init(struct rsnd_mod *mod,
59 			  struct rsnd_dai_stream *io,
60 			  struct rsnd_priv *priv)
61 {
62 	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
63 	u32 multi_ssi_slaves = rsnd_ssi_multi_slaves_runtime(io);
64 	int use_busif = rsnd_ssi_use_busif(io);
65 	int id = rsnd_mod_id(mod);
66 	u32 mask1, val1;
67 	u32 mask2, val2;
68 	int i;
69 
70 	/* clear status */
71 	switch (id) {
72 	case 0:
73 	case 1:
74 	case 2:
75 	case 3:
76 	case 4:
77 		for (i = 0; i < 4; i++)
78 			rsnd_mod_write(mod, SSI_SYS_STATUS(i * 2), 0xf << (id * 4));
79 		break;
80 	case 9:
81 		for (i = 0; i < 4; i++)
82 			rsnd_mod_write(mod, SSI_SYS_STATUS((i * 2) + 1), 0xf << (id * 4));
83 		break;
84 	}
85 
86 	/*
87 	 * SSI_MODE0
88 	 */
89 	rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
90 
91 	/*
92 	 * SSI_MODE1
93 	 */
94 	mask1 = (1 << 4) | (1 << 20);	/* mask sync bit */
95 	mask2 = (1 << 4);		/* mask sync bit */
96 	val1  = val2  = 0;
97 	if (id == 8) {
98 		/*
99 		 * SSI8 pin is sharing with SSI7, nothing to do.
100 		 */
101 	} else if (rsnd_ssi_is_pin_sharing(io)) {
102 		int shift = -1;
103 
104 		switch (id) {
105 		case 1:
106 			shift = 0;
107 			break;
108 		case 2:
109 			shift = 2;
110 			break;
111 		case 4:
112 			shift = 16;
113 			break;
114 		default:
115 			return -EINVAL;
116 		}
117 
118 		mask1 |= 0x3 << shift;
119 		val1 = rsnd_rdai_is_clk_master(rdai) ?
120 			0x2 << shift : 0x1 << shift;
121 
122 	} else if (multi_ssi_slaves) {
123 
124 		mask2 |= 0x00000007;
125 		mask1 |= 0x0000000f;
126 
127 		switch (multi_ssi_slaves) {
128 		case 0x0206: /* SSI0/1/2/9 */
129 			val2 = (1 << 4) | /* SSI0129 sync */
130 				(rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1);
131 			/* fall through */
132 		case 0x0006: /* SSI0/1/2 */
133 			val1 = rsnd_rdai_is_clk_master(rdai) ?
134 				0xa : 0x5;
135 
136 			if (!val2)  /* SSI012 sync */
137 				val1 |= (1 << 4);
138 		}
139 	}
140 
141 	rsnd_mod_bset(mod, SSI_MODE1, mask1, val1);
142 	rsnd_mod_bset(mod, SSI_MODE2, mask2, val2);
143 
144 	return 0;
145 }
146 
147 static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
148 	.name		= SSIU_NAME,
149 	.init		= rsnd_ssiu_init,
150 	.get_status	= rsnd_ssiu_get_status,
151 };
152 
153 static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
154 			       struct rsnd_dai_stream *io,
155 			       struct rsnd_priv *priv)
156 {
157 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
158 	u32 has_hdmi0 = rsnd_flags_has(io, RSND_STREAM_HDMI0);
159 	u32 has_hdmi1 = rsnd_flags_has(io, RSND_STREAM_HDMI1);
160 	int ret;
161 	u32 mode = 0;
162 
163 	ret = rsnd_ssiu_init(mod, io, priv);
164 	if (ret < 0)
165 		return ret;
166 
167 	ssiu->usrcnt++;
168 
169 	/*
170 	 * TDM Extend/Split Mode
171 	 * see
172 	 *	rsnd_ssi_config_init()
173 	 */
174 	if (rsnd_runtime_is_tdm(io))
175 		mode = TDM_EXT;
176 	else if (rsnd_runtime_is_tdm_split(io))
177 		mode = TDM_SPLIT;
178 
179 	rsnd_mod_write(mod, SSI_MODE, mode);
180 
181 	if (rsnd_ssi_use_busif(io)) {
182 		int id = rsnd_mod_id(mod);
183 		int busif = rsnd_mod_id_sub(mod);
184 
185 		/*
186 		 * FIXME
187 		 *
188 		 * We can't support SSI9-4/5/6/7, because its address is
189 		 * out of calculation rule
190 		 */
191 		if ((id == 9) && (busif >= 4)) {
192 			struct device *dev = rsnd_priv_to_dev(priv);
193 
194 			dev_err(dev, "This driver doesn't support SSI%d-%d, so far",
195 				id, busif);
196 		}
197 
198 		rsnd_mod_write(mod, SSI_BUSIF_ADINR(busif),
199 			       rsnd_get_adinr_bit(mod, io) |
200 			       (rsnd_io_is_play(io) ?
201 				rsnd_runtime_channel_after_ctu(io) :
202 				rsnd_runtime_channel_original(io)));
203 		rsnd_mod_write(mod, SSI_BUSIF_MODE(busif),
204 			       rsnd_get_busif_shift(io, mod) | 1);
205 		rsnd_mod_write(mod, SSI_BUSIF_DALIGN(busif),
206 			       rsnd_get_dalign(mod, io));
207 	}
208 
209 	if (has_hdmi0 || has_hdmi1) {
210 		enum rsnd_mod_type rsnd_ssi_array[] = {
211 			RSND_MOD_SSIM1,
212 			RSND_MOD_SSIM2,
213 			RSND_MOD_SSIM3,
214 		};
215 		struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
216 		struct rsnd_mod *pos;
217 		u32 val;
218 		int i, shift;
219 
220 		i = rsnd_mod_id(ssi_mod);
221 
222 		/* output all same SSI as default */
223 		val =	i << 16 |
224 			i << 20 |
225 			i << 24 |
226 			i << 28 |
227 			i;
228 
229 		for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
230 			shift	= (i * 4) + 16;
231 			val	= (val & ~(0xF << shift)) |
232 				rsnd_mod_id(pos) << shift;
233 		}
234 
235 		if (has_hdmi0)
236 			rsnd_mod_write(mod, HDMI0_SEL, val);
237 		if (has_hdmi1)
238 			rsnd_mod_write(mod, HDMI1_SEL, val);
239 	}
240 
241 	return 0;
242 }
243 
244 static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
245 				struct rsnd_dai_stream *io,
246 				struct rsnd_priv *priv)
247 {
248 	int busif = rsnd_mod_id_sub(mod);
249 
250 	if (!rsnd_ssi_use_busif(io))
251 		return 0;
252 
253 	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 1 << (busif * 4));
254 
255 	if (rsnd_ssi_multi_slaves_runtime(io))
256 		rsnd_mod_write(mod, SSI_CONTROL, 0x1);
257 
258 	return 0;
259 }
260 
261 static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
262 			       struct rsnd_dai_stream *io,
263 			       struct rsnd_priv *priv)
264 {
265 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
266 	int busif = rsnd_mod_id_sub(mod);
267 
268 	if (!rsnd_ssi_use_busif(io))
269 		return 0;
270 
271 	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 0);
272 
273 	if (--ssiu->usrcnt)
274 		return 0;
275 
276 	if (rsnd_ssi_multi_slaves_runtime(io))
277 		rsnd_mod_write(mod, SSI_CONTROL, 0);
278 
279 	return 0;
280 }
281 
282 static int rsnd_ssiu_id(struct rsnd_mod *mod)
283 {
284 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
285 
286 	/* see rsnd_ssiu_probe() */
287 	return ssiu->id;
288 }
289 
290 static int rsnd_ssiu_id_sub(struct rsnd_mod *mod)
291 {
292 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
293 
294 	/* see rsnd_ssiu_probe() */
295 	return ssiu->id_sub;
296 }
297 
298 static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
299 					  struct rsnd_mod *mod)
300 {
301 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
302 	int is_play = rsnd_io_is_play(io);
303 	char *name;
304 
305 	/*
306 	 * It should use "rcar_sound,ssiu" on DT.
307 	 * But, we need to keep compatibility for old version.
308 	 *
309 	 * If it has "rcar_sound.ssiu", it will be used.
310 	 * If not, "rcar_sound.ssi" will be used.
311 	 * see
312 	 *	rsnd_ssi_dma_req()
313 	 *	rsnd_dma_of_path()
314 	 */
315 
316 	name = is_play ? "rx" : "tx";
317 
318 	return rsnd_dma_request_channel(rsnd_ssiu_of_node(priv),
319 					mod, name);
320 }
321 
322 static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
323 	.name		= SSIU_NAME,
324 	.dma_req	= rsnd_ssiu_dma_req,
325 	.init		= rsnd_ssiu_init_gen2,
326 	.start		= rsnd_ssiu_start_gen2,
327 	.stop		= rsnd_ssiu_stop_gen2,
328 	.get_status	= rsnd_ssiu_get_status,
329 };
330 
331 static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
332 {
333 	if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
334 		id = 0;
335 
336 	return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
337 }
338 
339 static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
340 					       struct rsnd_dai_stream *io)
341 {
342 	struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
343 	struct rsnd_mod *mod;
344 	struct rsnd_ssiu *ssiu;
345 	int i;
346 
347 	if (!ssi_mod)
348 		return;
349 
350 	/* select BUSIF0 */
351 	for_each_rsnd_ssiu(ssiu, priv, i) {
352 		mod = rsnd_mod_get(ssiu);
353 
354 		if ((rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
355 		    (rsnd_mod_id_sub(mod) == 0)) {
356 			rsnd_dai_connect(mod, io, mod->type);
357 			return;
358 		}
359 	}
360 }
361 
362 void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
363 			     struct device_node *playback,
364 			     struct device_node *capture)
365 {
366 	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
367 	struct device_node *node = rsnd_ssiu_of_node(priv);
368 	struct device_node *np;
369 	struct rsnd_mod *mod;
370 	struct rsnd_dai_stream *io_p = &rdai->playback;
371 	struct rsnd_dai_stream *io_c = &rdai->capture;
372 	int i;
373 
374 	/* use rcar_sound,ssiu if exist */
375 	if (node) {
376 		i = 0;
377 		for_each_child_of_node(node, np) {
378 			mod = rsnd_ssiu_mod_get(priv, i);
379 			if (np == playback)
380 				rsnd_dai_connect(mod, io_p, mod->type);
381 			if (np == capture)
382 				rsnd_dai_connect(mod, io_c, mod->type);
383 			i++;
384 		}
385 
386 		of_node_put(node);
387 	}
388 
389 	/* Keep DT compatibility */
390 	if (!rsnd_io_to_mod_ssiu(io_p))
391 		rsnd_parse_connect_ssiu_compatible(priv, io_p);
392 	if (!rsnd_io_to_mod_ssiu(io_c))
393 		rsnd_parse_connect_ssiu_compatible(priv, io_c);
394 }
395 
396 int rsnd_ssiu_probe(struct rsnd_priv *priv)
397 {
398 	struct device *dev = rsnd_priv_to_dev(priv);
399 	struct device_node *node;
400 	struct rsnd_ssiu *ssiu;
401 	struct rsnd_mod_ops *ops;
402 	const int *list = NULL;
403 	int i, nr, ret;
404 
405 	/*
406 	 * Keep DT compatibility.
407 	 * if it has "rcar_sound,ssiu", use it.
408 	 * if not, use "rcar_sound,ssi"
409 	 * see
410 	 *	rsnd_ssiu_bufsif_to_id()
411 	 */
412 	node = rsnd_ssiu_of_node(priv);
413 	if (node)
414 		nr = of_get_child_count(node);
415 	else
416 		nr = priv->ssi_nr;
417 
418 	ssiu	= devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
419 	if (!ssiu)
420 		return -ENOMEM;
421 
422 	priv->ssiu	= ssiu;
423 	priv->ssiu_nr	= nr;
424 
425 	if (rsnd_is_gen1(priv))
426 		ops = &rsnd_ssiu_ops_gen1;
427 	else
428 		ops = &rsnd_ssiu_ops_gen2;
429 
430 	/* Keep compatibility */
431 	nr = 0;
432 	if ((node) &&
433 	    (ops == &rsnd_ssiu_ops_gen2)) {
434 		ops->id		= rsnd_ssiu_id;
435 		ops->id_sub	= rsnd_ssiu_id_sub;
436 
437 		if (rsnd_is_gen2(priv)) {
438 			list	= gen2_id;
439 			nr	= ARRAY_SIZE(gen2_id);
440 		} else if (rsnd_is_gen3(priv)) {
441 			list	= gen3_id;
442 			nr	= ARRAY_SIZE(gen3_id);
443 		} else {
444 			dev_err(dev, "unknown SSIU\n");
445 			return -ENODEV;
446 		}
447 	}
448 
449 	for_each_rsnd_ssiu(ssiu, priv, i) {
450 		if (node) {
451 			int j;
452 
453 			/*
454 			 * see
455 			 *	rsnd_ssiu_get_id()
456 			 *	rsnd_ssiu_get_id_sub()
457 			 */
458 			for (j = 0; j < nr; j++) {
459 				if (list[j] > i)
460 					break;
461 				ssiu->id	= j;
462 				ssiu->id_sub	= i - list[ssiu->id];
463 			}
464 		} else {
465 			ssiu->id = i;
466 		}
467 
468 		ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
469 				    ops, NULL, RSND_MOD_SSIU, i);
470 		if (ret)
471 			return ret;
472 	}
473 
474 	return 0;
475 }
476 
477 void rsnd_ssiu_remove(struct rsnd_priv *priv)
478 {
479 	struct rsnd_ssiu *ssiu;
480 	int i;
481 
482 	for_each_rsnd_ssiu(ssiu, priv, i) {
483 		rsnd_mod_quit(rsnd_mod_get(ssiu));
484 	}
485 }
486