xref: /openbmc/linux/sound/soc/sh/rcar/ssiu.c (revision e42dd3ee)
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 << 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 		enum rsnd_reg adinr_reg, mode_reg, dalign_reg;
185 
186 		if ((id == 9) && (busif >= 4)) {
187 			adinr_reg = SSI9_BUSIF_ADINR(busif);
188 			mode_reg = SSI9_BUSIF_MODE(busif);
189 			dalign_reg = SSI9_BUSIF_DALIGN(busif);
190 		} else {
191 			adinr_reg = SSI_BUSIF_ADINR(busif);
192 			mode_reg = SSI_BUSIF_MODE(busif);
193 			dalign_reg = SSI_BUSIF_DALIGN(busif);
194 		}
195 
196 		rsnd_mod_write(mod, adinr_reg,
197 			       rsnd_get_adinr_bit(mod, io) |
198 			       (rsnd_io_is_play(io) ?
199 				rsnd_runtime_channel_after_ctu(io) :
200 				rsnd_runtime_channel_original(io)));
201 		rsnd_mod_write(mod, mode_reg,
202 			       rsnd_get_busif_shift(io, mod) | 1);
203 		rsnd_mod_write(mod, dalign_reg,
204 			       rsnd_get_dalign(mod, io));
205 	}
206 
207 	if (has_hdmi0 || has_hdmi1) {
208 		enum rsnd_mod_type rsnd_ssi_array[] = {
209 			RSND_MOD_SSIM1,
210 			RSND_MOD_SSIM2,
211 			RSND_MOD_SSIM3,
212 		};
213 		struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
214 		struct rsnd_mod *pos;
215 		u32 val;
216 		int i, shift;
217 
218 		i = rsnd_mod_id(ssi_mod);
219 
220 		/* output all same SSI as default */
221 		val =	i << 16 |
222 			i << 20 |
223 			i << 24 |
224 			i << 28 |
225 			i;
226 
227 		for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
228 			shift	= (i * 4) + 16;
229 			val	= (val & ~(0xF << shift)) |
230 				rsnd_mod_id(pos) << shift;
231 		}
232 
233 		if (has_hdmi0)
234 			rsnd_mod_write(mod, HDMI0_SEL, val);
235 		if (has_hdmi1)
236 			rsnd_mod_write(mod, HDMI1_SEL, val);
237 	}
238 
239 	return 0;
240 }
241 
242 static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
243 				struct rsnd_dai_stream *io,
244 				struct rsnd_priv *priv)
245 {
246 	int busif = rsnd_mod_id_sub(mod);
247 
248 	if (!rsnd_ssi_use_busif(io))
249 		return 0;
250 
251 	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 1 << (busif * 4));
252 
253 	if (rsnd_ssi_multi_slaves_runtime(io))
254 		rsnd_mod_write(mod, SSI_CONTROL, 0x1);
255 
256 	return 0;
257 }
258 
259 static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
260 			       struct rsnd_dai_stream *io,
261 			       struct rsnd_priv *priv)
262 {
263 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
264 	int busif = rsnd_mod_id_sub(mod);
265 
266 	if (!rsnd_ssi_use_busif(io))
267 		return 0;
268 
269 	rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 0);
270 
271 	if (--ssiu->usrcnt)
272 		return 0;
273 
274 	if (rsnd_ssi_multi_slaves_runtime(io))
275 		rsnd_mod_write(mod, SSI_CONTROL, 0);
276 
277 	return 0;
278 }
279 
280 static int rsnd_ssiu_id(struct rsnd_mod *mod)
281 {
282 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
283 
284 	/* see rsnd_ssiu_probe() */
285 	return ssiu->id;
286 }
287 
288 static int rsnd_ssiu_id_sub(struct rsnd_mod *mod)
289 {
290 	struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
291 
292 	/* see rsnd_ssiu_probe() */
293 	return ssiu->id_sub;
294 }
295 
296 static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
297 					  struct rsnd_mod *mod)
298 {
299 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
300 	int is_play = rsnd_io_is_play(io);
301 	char *name;
302 
303 	/*
304 	 * It should use "rcar_sound,ssiu" on DT.
305 	 * But, we need to keep compatibility for old version.
306 	 *
307 	 * If it has "rcar_sound.ssiu", it will be used.
308 	 * If not, "rcar_sound.ssi" will be used.
309 	 * see
310 	 *	rsnd_ssi_dma_req()
311 	 *	rsnd_dma_of_path()
312 	 */
313 
314 	name = is_play ? "rx" : "tx";
315 
316 	return rsnd_dma_request_channel(rsnd_ssiu_of_node(priv),
317 					mod, name);
318 }
319 
320 static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
321 	.name		= SSIU_NAME,
322 	.dma_req	= rsnd_ssiu_dma_req,
323 	.init		= rsnd_ssiu_init_gen2,
324 	.start		= rsnd_ssiu_start_gen2,
325 	.stop		= rsnd_ssiu_stop_gen2,
326 	.get_status	= rsnd_ssiu_get_status,
327 };
328 
329 static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
330 {
331 	if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
332 		id = 0;
333 
334 	return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
335 }
336 
337 static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
338 					       struct rsnd_dai_stream *io)
339 {
340 	struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
341 	struct rsnd_mod *mod;
342 	struct rsnd_ssiu *ssiu;
343 	int i;
344 
345 	if (!ssi_mod)
346 		return;
347 
348 	/* select BUSIF0 */
349 	for_each_rsnd_ssiu(ssiu, priv, i) {
350 		mod = rsnd_mod_get(ssiu);
351 
352 		if ((rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
353 		    (rsnd_mod_id_sub(mod) == 0)) {
354 			rsnd_dai_connect(mod, io, mod->type);
355 			return;
356 		}
357 	}
358 }
359 
360 void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
361 			     struct device_node *playback,
362 			     struct device_node *capture)
363 {
364 	struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
365 	struct device_node *node = rsnd_ssiu_of_node(priv);
366 	struct device_node *np;
367 	struct rsnd_mod *mod;
368 	struct rsnd_dai_stream *io_p = &rdai->playback;
369 	struct rsnd_dai_stream *io_c = &rdai->capture;
370 	int i;
371 
372 	/* use rcar_sound,ssiu if exist */
373 	if (node) {
374 		i = 0;
375 		for_each_child_of_node(node, np) {
376 			mod = rsnd_ssiu_mod_get(priv, i);
377 			if (np == playback)
378 				rsnd_dai_connect(mod, io_p, mod->type);
379 			if (np == capture)
380 				rsnd_dai_connect(mod, io_c, mod->type);
381 			i++;
382 		}
383 
384 		of_node_put(node);
385 	}
386 
387 	/* Keep DT compatibility */
388 	if (!rsnd_io_to_mod_ssiu(io_p))
389 		rsnd_parse_connect_ssiu_compatible(priv, io_p);
390 	if (!rsnd_io_to_mod_ssiu(io_c))
391 		rsnd_parse_connect_ssiu_compatible(priv, io_c);
392 }
393 
394 int rsnd_ssiu_probe(struct rsnd_priv *priv)
395 {
396 	struct device *dev = rsnd_priv_to_dev(priv);
397 	struct device_node *node;
398 	struct rsnd_ssiu *ssiu;
399 	struct rsnd_mod_ops *ops;
400 	const int *list = NULL;
401 	int i, nr, ret;
402 
403 	/*
404 	 * Keep DT compatibility.
405 	 * if it has "rcar_sound,ssiu", use it.
406 	 * if not, use "rcar_sound,ssi"
407 	 * see
408 	 *	rsnd_ssiu_bufsif_to_id()
409 	 */
410 	node = rsnd_ssiu_of_node(priv);
411 	if (node)
412 		nr = of_get_child_count(node);
413 	else
414 		nr = priv->ssi_nr;
415 
416 	ssiu	= devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
417 	if (!ssiu)
418 		return -ENOMEM;
419 
420 	priv->ssiu	= ssiu;
421 	priv->ssiu_nr	= nr;
422 
423 	if (rsnd_is_gen1(priv))
424 		ops = &rsnd_ssiu_ops_gen1;
425 	else
426 		ops = &rsnd_ssiu_ops_gen2;
427 
428 	/* Keep compatibility */
429 	nr = 0;
430 	if ((node) &&
431 	    (ops == &rsnd_ssiu_ops_gen2)) {
432 		ops->id		= rsnd_ssiu_id;
433 		ops->id_sub	= rsnd_ssiu_id_sub;
434 
435 		if (rsnd_is_gen2(priv)) {
436 			list	= gen2_id;
437 			nr	= ARRAY_SIZE(gen2_id);
438 		} else if (rsnd_is_gen3(priv)) {
439 			list	= gen3_id;
440 			nr	= ARRAY_SIZE(gen3_id);
441 		} else {
442 			dev_err(dev, "unknown SSIU\n");
443 			return -ENODEV;
444 		}
445 	}
446 
447 	for_each_rsnd_ssiu(ssiu, priv, i) {
448 		if (node) {
449 			int j;
450 
451 			/*
452 			 * see
453 			 *	rsnd_ssiu_get_id()
454 			 *	rsnd_ssiu_get_id_sub()
455 			 */
456 			for (j = 0; j < nr; j++) {
457 				if (list[j] > i)
458 					break;
459 				ssiu->id	= j;
460 				ssiu->id_sub	= i - list[ssiu->id];
461 			}
462 		} else {
463 			ssiu->id = i;
464 		}
465 
466 		ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
467 				    ops, NULL, RSND_MOD_SSIU, i);
468 		if (ret)
469 			return ret;
470 	}
471 
472 	return 0;
473 }
474 
475 void rsnd_ssiu_remove(struct rsnd_priv *priv)
476 {
477 	struct rsnd_ssiu *ssiu;
478 	int i;
479 
480 	for_each_rsnd_ssiu(ssiu, priv, i) {
481 		rsnd_mod_quit(rsnd_mod_get(ssiu));
482 	}
483 }
484