xref: /kernel/linux/linux-5.10/sound/soc/sh/rcar/src.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0
2//
3// Renesas R-Car SRC support
4//
5// Copyright (C) 2013 Renesas Solutions Corp.
6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7
8/*
9 * you can enable below define if you don't need
10 * SSI interrupt status debug message when debugging
11 * see rsnd_dbg_irq_status()
12 *
13 * #define RSND_DEBUG_NO_IRQ_STATUS 1
14 */
15
16#include "rsnd.h"
17
18#define SRC_NAME "src"
19
20/* SCU_SYSTEM_STATUS0/1 */
21#define OUF_SRC(id)	((1 << (id + 16)) | (1 << id))
22
23struct rsnd_src {
24	struct rsnd_mod mod;
25	struct rsnd_mod *dma;
26	struct rsnd_kctrl_cfg_s sen;  /* sync convert enable */
27	struct rsnd_kctrl_cfg_s sync; /* sync convert */
28	int irq;
29};
30
31#define RSND_SRC_NAME_SIZE 16
32
33#define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id)
34#define rsnd_src_nr(priv) ((priv)->src_nr)
35#define rsnd_src_sync_is_enabled(mod) (rsnd_mod_to_src(mod)->sen.val)
36
37#define rsnd_mod_to_src(_mod)				\
38	container_of((_mod), struct rsnd_src, mod)
39
40#define for_each_rsnd_src(pos, priv, i)				\
41	for ((i) = 0;						\
42	     ((i) < rsnd_src_nr(priv)) &&			\
43	     ((pos) = (struct rsnd_src *)(priv)->src + i);	\
44	     i++)
45
46
47/*
48 *		image of SRC (Sampling Rate Converter)
49 *
50 * 96kHz   <-> +-----+	48kHz	+-----+	 48kHz	+-------+
51 * 48kHz   <-> | SRC | <------>	| SSI |	<----->	| codec |
52 * 44.1kHz <-> +-----+		+-----+		+-------+
53 * ...
54 *
55 */
56
57static void rsnd_src_activation(struct rsnd_mod *mod)
58{
59	rsnd_mod_write(mod, SRC_SWRSR, 0);
60	rsnd_mod_write(mod, SRC_SWRSR, 1);
61}
62
63static void rsnd_src_halt(struct rsnd_mod *mod)
64{
65	rsnd_mod_write(mod, SRC_SRCIR, 1);
66	rsnd_mod_write(mod, SRC_SWRSR, 0);
67}
68
69static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
70					 struct rsnd_mod *mod)
71{
72	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
73	int is_play = rsnd_io_is_play(io);
74
75	return rsnd_dma_request_channel(rsnd_src_of_node(priv),
76					mod,
77					is_play ? "rx" : "tx");
78}
79
80static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
81				 struct rsnd_mod *mod)
82{
83	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
84	struct rsnd_src *src = rsnd_mod_to_src(mod);
85	u32 convert_rate;
86
87	if (!runtime)
88		return 0;
89
90	if (!rsnd_src_sync_is_enabled(mod))
91		return rsnd_io_converted_rate(io);
92
93	convert_rate = src->sync.val;
94
95	if (!convert_rate)
96		convert_rate = rsnd_io_converted_rate(io);
97
98	if (!convert_rate)
99		convert_rate = runtime->rate;
100
101	return convert_rate;
102}
103
104unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,
105			       struct rsnd_dai_stream *io,
106			       int is_in)
107{
108	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
109	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
110	unsigned int rate = 0;
111	int is_play = rsnd_io_is_play(io);
112
113	/*
114	 * Playback
115	 * runtime_rate -> [SRC] -> convert_rate
116	 *
117	 * Capture
118	 * convert_rate -> [SRC] -> runtime_rate
119	 */
120
121	if (is_play == is_in)
122		return runtime->rate;
123
124	/*
125	 * return convert rate if SRC is used,
126	 * otherwise, return runtime->rate as usual
127	 */
128	if (src_mod)
129		rate = rsnd_src_convert_rate(io, src_mod);
130
131	if (!rate)
132		rate = runtime->rate;
133
134	return rate;
135}
136
137static const u32 bsdsr_table_pattern1[] = {
138	0x01800000, /* 6 - 1/6 */
139	0x01000000, /* 6 - 1/4 */
140	0x00c00000, /* 6 - 1/3 */
141	0x00800000, /* 6 - 1/2 */
142	0x00600000, /* 6 - 2/3 */
143	0x00400000, /* 6 - 1   */
144};
145
146static const u32 bsdsr_table_pattern2[] = {
147	0x02400000, /* 6 - 1/6 */
148	0x01800000, /* 6 - 1/4 */
149	0x01200000, /* 6 - 1/3 */
150	0x00c00000, /* 6 - 1/2 */
151	0x00900000, /* 6 - 2/3 */
152	0x00600000, /* 6 - 1   */
153};
154
155static const u32 bsisr_table[] = {
156	0x00100060, /* 6 - 1/6 */
157	0x00100040, /* 6 - 1/4 */
158	0x00100030, /* 6 - 1/3 */
159	0x00100020, /* 6 - 1/2 */
160	0x00100020, /* 6 - 2/3 */
161	0x00100020, /* 6 - 1   */
162};
163
164static const u32 chan288888[] = {
165	0x00000006, /* 1 to 2 */
166	0x000001fe, /* 1 to 8 */
167	0x000001fe, /* 1 to 8 */
168	0x000001fe, /* 1 to 8 */
169	0x000001fe, /* 1 to 8 */
170	0x000001fe, /* 1 to 8 */
171};
172
173static const u32 chan244888[] = {
174	0x00000006, /* 1 to 2 */
175	0x0000001e, /* 1 to 4 */
176	0x0000001e, /* 1 to 4 */
177	0x000001fe, /* 1 to 8 */
178	0x000001fe, /* 1 to 8 */
179	0x000001fe, /* 1 to 8 */
180};
181
182static const u32 chan222222[] = {
183	0x00000006, /* 1 to 2 */
184	0x00000006, /* 1 to 2 */
185	0x00000006, /* 1 to 2 */
186	0x00000006, /* 1 to 2 */
187	0x00000006, /* 1 to 2 */
188	0x00000006, /* 1 to 2 */
189};
190
191static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
192				      struct rsnd_mod *mod)
193{
194	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
195	struct device *dev = rsnd_priv_to_dev(priv);
196	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
197	int is_play = rsnd_io_is_play(io);
198	int use_src = 0;
199	u32 fin, fout;
200	u32 ifscr, fsrate, adinr;
201	u32 cr, route;
202	u32 i_busif, o_busif, tmp;
203	const u32 *bsdsr_table;
204	const u32 *chptn;
205	uint ratio;
206	int chan;
207	int idx;
208
209	if (!runtime)
210		return;
211
212	fin  = rsnd_src_get_in_rate(priv, io);
213	fout = rsnd_src_get_out_rate(priv, io);
214
215	chan = rsnd_runtime_channel_original(io);
216
217	/* 6 - 1/6 are very enough ratio for SRC_BSDSR */
218	if (fin == fout)
219		ratio = 0;
220	else if (fin > fout)
221		ratio = 100 * fin / fout;
222	else
223		ratio = 100 * fout / fin;
224
225	if (ratio > 600) {
226		dev_err(dev, "FSO/FSI ratio error\n");
227		return;
228	}
229
230	use_src = (fin != fout) | rsnd_src_sync_is_enabled(mod);
231
232	/*
233	 * SRC_ADINR
234	 */
235	adinr = rsnd_get_adinr_bit(mod, io) | chan;
236
237	/*
238	 * SRC_IFSCR / SRC_IFSVR
239	 */
240	ifscr = 0;
241	fsrate = 0;
242	if (use_src) {
243		u64 n;
244
245		ifscr = 1;
246		n = (u64)0x0400000 * fin;
247		do_div(n, fout);
248		fsrate = n;
249	}
250
251	/*
252	 * SRC_SRCCR / SRC_ROUTE_MODE0
253	 */
254	cr	= 0x00011110;
255	route	= 0x0;
256	if (use_src) {
257		route	= 0x1;
258
259		if (rsnd_src_sync_is_enabled(mod)) {
260			cr |= 0x1;
261			route |= rsnd_io_is_play(io) ?
262				(0x1 << 24) : (0x1 << 25);
263		}
264	}
265
266	/*
267	 * SRC_BSDSR / SRC_BSISR
268	 *
269	 * see
270	 *	Combination of Register Setting Related to
271	 *	FSO/FSI Ratio and Channel, Latency
272	 */
273	switch (rsnd_mod_id(mod)) {
274	case 0:
275		chptn		= chan288888;
276		bsdsr_table	= bsdsr_table_pattern1;
277		break;
278	case 1:
279	case 3:
280	case 4:
281		chptn		= chan244888;
282		bsdsr_table	= bsdsr_table_pattern1;
283		break;
284	case 2:
285	case 9:
286		chptn		= chan222222;
287		bsdsr_table	= bsdsr_table_pattern1;
288		break;
289	case 5:
290	case 6:
291	case 7:
292	case 8:
293		chptn		= chan222222;
294		bsdsr_table	= bsdsr_table_pattern2;
295		break;
296	default:
297		goto convert_rate_err;
298	}
299
300	/*
301	 * E3 need to overwrite
302	 */
303	if (rsnd_is_e3(priv))
304		switch (rsnd_mod_id(mod)) {
305		case 0:
306		case 4:
307			chptn	= chan222222;
308		}
309
310	for (idx = 0; idx < ARRAY_SIZE(chan222222); idx++)
311		if (chptn[idx] & (1 << chan))
312			break;
313
314	if (chan > 8 ||
315	    idx >= ARRAY_SIZE(chan222222))
316		goto convert_rate_err;
317
318	/* BUSIF_MODE */
319	tmp = rsnd_get_busif_shift(io, mod);
320	i_busif = ( is_play ? tmp : 0) | 1;
321	o_busif = (!is_play ? tmp : 0) | 1;
322
323	rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
324
325	rsnd_mod_write(mod, SRC_SRCIR, 1);	/* initialize */
326	rsnd_mod_write(mod, SRC_ADINR, adinr);
327	rsnd_mod_write(mod, SRC_IFSCR, ifscr);
328	rsnd_mod_write(mod, SRC_IFSVR, fsrate);
329	rsnd_mod_write(mod, SRC_SRCCR, cr);
330	rsnd_mod_write(mod, SRC_BSDSR, bsdsr_table[idx]);
331	rsnd_mod_write(mod, SRC_BSISR, bsisr_table[idx]);
332	rsnd_mod_write(mod, SRC_SRCIR, 0);	/* cancel initialize */
333
334	rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif);
335	rsnd_mod_write(mod, SRC_O_BUSIF_MODE, o_busif);
336
337	rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
338
339	rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout);
340
341	return;
342
343convert_rate_err:
344	dev_err(dev, "unknown BSDSR/BSDIR settings\n");
345}
346
347static int rsnd_src_irq(struct rsnd_mod *mod,
348			struct rsnd_dai_stream *io,
349			struct rsnd_priv *priv,
350			int enable)
351{
352	struct rsnd_src *src = rsnd_mod_to_src(mod);
353	u32 sys_int_val, int_val, sys_int_mask;
354	int irq = src->irq;
355	int id = rsnd_mod_id(mod);
356
357	sys_int_val =
358	sys_int_mask = OUF_SRC(id);
359	int_val = 0x3300;
360
361	/*
362	 * IRQ is not supported on non-DT
363	 * see
364	 *	rsnd_src_probe_()
365	 */
366	if ((irq <= 0) || !enable) {
367		sys_int_val = 0;
368		int_val = 0;
369	}
370
371	/*
372	 * WORKAROUND
373	 *
374	 * ignore over flow error when rsnd_src_sync_is_enabled()
375	 */
376	if (rsnd_src_sync_is_enabled(mod))
377		sys_int_val = sys_int_val & 0xffff;
378
379	rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
380	rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
381	rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
382
383	return 0;
384}
385
386static void rsnd_src_status_clear(struct rsnd_mod *mod)
387{
388	u32 val = OUF_SRC(rsnd_mod_id(mod));
389
390	rsnd_mod_write(mod, SCU_SYS_STATUS0, val);
391	rsnd_mod_write(mod, SCU_SYS_STATUS1, val);
392}
393
394static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
395{
396	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
397	struct device *dev = rsnd_priv_to_dev(priv);
398	u32 val0, val1;
399	u32 status0, status1;
400	bool ret = false;
401
402	val0 = val1 = OUF_SRC(rsnd_mod_id(mod));
403
404	/*
405	 * WORKAROUND
406	 *
407	 * ignore over flow error when rsnd_src_sync_is_enabled()
408	 */
409	if (rsnd_src_sync_is_enabled(mod))
410		val0 = val0 & 0xffff;
411
412	status0 = rsnd_mod_read(mod, SCU_SYS_STATUS0);
413	status1 = rsnd_mod_read(mod, SCU_SYS_STATUS1);
414	if ((status0 & val0) || (status1 & val1)) {
415		rsnd_dbg_irq_status(dev, "%s err status : 0x%08x, 0x%08x\n",
416			rsnd_mod_name(mod), status0, status1);
417
418		ret = true;
419	}
420
421	return ret;
422}
423
424static int rsnd_src_start(struct rsnd_mod *mod,
425			  struct rsnd_dai_stream *io,
426			  struct rsnd_priv *priv)
427{
428	u32 val;
429
430	/*
431	 * WORKAROUND
432	 *
433	 * Enable SRC output if you want to use sync convert together with DVC
434	 */
435	val = (rsnd_io_to_mod_dvc(io) && !rsnd_src_sync_is_enabled(mod)) ?
436		0x01 : 0x11;
437
438	rsnd_mod_write(mod, SRC_CTRL, val);
439
440	return 0;
441}
442
443static int rsnd_src_stop(struct rsnd_mod *mod,
444			 struct rsnd_dai_stream *io,
445			 struct rsnd_priv *priv)
446{
447	rsnd_mod_write(mod, SRC_CTRL, 0);
448
449	return 0;
450}
451
452static int rsnd_src_init(struct rsnd_mod *mod,
453			 struct rsnd_dai_stream *io,
454			 struct rsnd_priv *priv)
455{
456	struct rsnd_src *src = rsnd_mod_to_src(mod);
457	int ret;
458
459	/* reset sync convert_rate */
460	src->sync.val = 0;
461
462	ret = rsnd_mod_power_on(mod);
463	if (ret < 0)
464		return ret;
465
466	rsnd_src_activation(mod);
467
468	rsnd_src_set_convert_rate(io, mod);
469
470	rsnd_src_status_clear(mod);
471
472	return 0;
473}
474
475static int rsnd_src_quit(struct rsnd_mod *mod,
476			 struct rsnd_dai_stream *io,
477			 struct rsnd_priv *priv)
478{
479	struct rsnd_src *src = rsnd_mod_to_src(mod);
480
481	rsnd_src_halt(mod);
482
483	rsnd_mod_power_off(mod);
484
485	/* reset sync convert_rate */
486	src->sync.val = 0;
487
488	return 0;
489}
490
491static void __rsnd_src_interrupt(struct rsnd_mod *mod,
492				 struct rsnd_dai_stream *io)
493{
494	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
495	bool stop = false;
496
497	spin_lock(&priv->lock);
498
499	/* ignore all cases if not working */
500	if (!rsnd_io_is_working(io))
501		goto rsnd_src_interrupt_out;
502
503	if (rsnd_src_error_occurred(mod))
504		stop = true;
505
506	rsnd_src_status_clear(mod);
507rsnd_src_interrupt_out:
508
509	spin_unlock(&priv->lock);
510
511	if (stop)
512		snd_pcm_stop_xrun(io->substream);
513}
514
515static irqreturn_t rsnd_src_interrupt(int irq, void *data)
516{
517	struct rsnd_mod *mod = data;
518
519	rsnd_mod_interrupt(mod, __rsnd_src_interrupt);
520
521	return IRQ_HANDLED;
522}
523
524static int rsnd_src_probe_(struct rsnd_mod *mod,
525			   struct rsnd_dai_stream *io,
526			   struct rsnd_priv *priv)
527{
528	struct rsnd_src *src = rsnd_mod_to_src(mod);
529	struct device *dev = rsnd_priv_to_dev(priv);
530	int irq = src->irq;
531	int ret;
532
533	if (irq > 0) {
534		/*
535		 * IRQ is not supported on non-DT
536		 * see
537		 *	rsnd_src_irq()
538		 */
539		ret = devm_request_irq(dev, irq,
540				       rsnd_src_interrupt,
541				       IRQF_SHARED,
542				       dev_name(dev), mod);
543		if (ret)
544			return ret;
545	}
546
547	ret = rsnd_dma_attach(io, mod, &src->dma);
548
549	return ret;
550}
551
552static int rsnd_src_pcm_new(struct rsnd_mod *mod,
553			    struct rsnd_dai_stream *io,
554			    struct snd_soc_pcm_runtime *rtd)
555{
556	struct rsnd_src *src = rsnd_mod_to_src(mod);
557	int ret;
558
559	/*
560	 * enable SRC sync convert if possible
561	 */
562
563	/*
564	 * It can't use SRC Synchronous convert
565	 * when Capture if it uses CMD
566	 */
567	if (rsnd_io_to_mod_cmd(io) && !rsnd_io_is_play(io))
568		return 0;
569
570	/*
571	 * enable sync convert
572	 */
573	ret = rsnd_kctrl_new_s(mod, io, rtd,
574			       rsnd_io_is_play(io) ?
575			       "SRC Out Rate Switch" :
576			       "SRC In Rate Switch",
577			       rsnd_kctrl_accept_anytime,
578			       rsnd_src_set_convert_rate,
579			       &src->sen, 1);
580	if (ret < 0)
581		return ret;
582
583	ret = rsnd_kctrl_new_s(mod, io, rtd,
584			       rsnd_io_is_play(io) ?
585			       "SRC Out Rate" :
586			       "SRC In Rate",
587			       rsnd_kctrl_accept_runtime,
588			       rsnd_src_set_convert_rate,
589			       &src->sync, 192000);
590
591	return ret;
592}
593
594static struct rsnd_mod_ops rsnd_src_ops = {
595	.name		= SRC_NAME,
596	.dma_req	= rsnd_src_dma_req,
597	.probe		= rsnd_src_probe_,
598	.init		= rsnd_src_init,
599	.quit		= rsnd_src_quit,
600	.start		= rsnd_src_start,
601	.stop		= rsnd_src_stop,
602	.irq		= rsnd_src_irq,
603	.pcm_new	= rsnd_src_pcm_new,
604	.get_status	= rsnd_mod_get_status,
605};
606
607struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
608{
609	if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
610		id = 0;
611
612	return rsnd_mod_get(rsnd_src_get(priv, id));
613}
614
615int rsnd_src_probe(struct rsnd_priv *priv)
616{
617	struct device_node *node;
618	struct device_node *np;
619	struct device *dev = rsnd_priv_to_dev(priv);
620	struct rsnd_src *src;
621	struct clk *clk;
622	char name[RSND_SRC_NAME_SIZE];
623	int i, nr, ret;
624
625	/* This driver doesn't support Gen1 at this point */
626	if (rsnd_is_gen1(priv))
627		return 0;
628
629	node = rsnd_src_of_node(priv);
630	if (!node)
631		return 0; /* not used is not error */
632
633	nr = of_get_child_count(node);
634	if (!nr) {
635		ret = -EINVAL;
636		goto rsnd_src_probe_done;
637	}
638
639	src	= devm_kcalloc(dev, nr, sizeof(*src), GFP_KERNEL);
640	if (!src) {
641		ret = -ENOMEM;
642		goto rsnd_src_probe_done;
643	}
644
645	priv->src_nr	= nr;
646	priv->src	= src;
647
648	i = 0;
649	for_each_child_of_node(node, np) {
650		if (!of_device_is_available(np))
651			goto skip;
652
653		src = rsnd_src_get(priv, i);
654
655		snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
656			 SRC_NAME, i);
657
658		src->irq = irq_of_parse_and_map(np, 0);
659		if (!src->irq) {
660			ret = -EINVAL;
661			of_node_put(np);
662			goto rsnd_src_probe_done;
663		}
664
665		clk = devm_clk_get(dev, name);
666		if (IS_ERR(clk)) {
667			ret = PTR_ERR(clk);
668			of_node_put(np);
669			goto rsnd_src_probe_done;
670		}
671
672		ret = rsnd_mod_init(priv, rsnd_mod_get(src),
673				    &rsnd_src_ops, clk, RSND_MOD_SRC, i);
674		if (ret) {
675			of_node_put(np);
676			goto rsnd_src_probe_done;
677		}
678
679skip:
680		i++;
681	}
682
683	ret = 0;
684
685rsnd_src_probe_done:
686	of_node_put(node);
687
688	return ret;
689}
690
691void rsnd_src_remove(struct rsnd_priv *priv)
692{
693	struct rsnd_src *src;
694	int i;
695
696	for_each_rsnd_src(src, priv, i) {
697		rsnd_mod_quit(rsnd_mod_get(src));
698	}
699}
700