xref: /openbmc/linux/sound/soc/sh/rcar/gen.c (revision ca460cc2)
1 /*
2  * Renesas R-Car Gen1 SRU/SSI support
3  *
4  * Copyright (C) 2013 Renesas Solutions Corp.
5  * 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 struct rsnd_gen {
14 	void __iomem *base[RSND_BASE_MAX];
15 
16 	struct rsnd_gen_ops *ops;
17 
18 	struct regmap *regmap[RSND_BASE_MAX];
19 	struct regmap_field *regs[RSND_REG_MAX];
20 };
21 
22 #define rsnd_priv_to_gen(p)	((struct rsnd_gen *)(p)->gen)
23 
24 struct rsnd_regmap_field_conf {
25 	int idx;
26 	unsigned int reg_offset;
27 	unsigned int id_offset;
28 };
29 
30 #define RSND_REG_SET(id, offset, _id_offset)	\
31 {						\
32 	.idx = id,				\
33 	.reg_offset = offset,			\
34 	.id_offset = _id_offset,		\
35 }
36 /* single address mapping */
37 #define RSND_GEN_S_REG(id, offset)	\
38 	RSND_REG_SET(RSND_REG_##id, offset, 0)
39 
40 /* multi address mapping */
41 #define RSND_GEN_M_REG(id, offset, _id_offset)	\
42 	RSND_REG_SET(RSND_REG_##id, offset, _id_offset)
43 
44 /*
45  *		basic function
46  */
47 static int rsnd_is_accessible_reg(struct rsnd_priv *priv,
48 				  struct rsnd_gen *gen, enum rsnd_reg reg)
49 {
50 	if (!gen->regs[reg]) {
51 		struct device *dev = rsnd_priv_to_dev(priv);
52 
53 		dev_err(dev, "unsupported register access %x\n", reg);
54 		return 0;
55 	}
56 
57 	return 1;
58 }
59 
60 u32 rsnd_read(struct rsnd_priv *priv,
61 	      struct rsnd_mod *mod, enum rsnd_reg reg)
62 {
63 	struct device *dev = rsnd_priv_to_dev(priv);
64 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
65 	u32 val;
66 
67 	if (!rsnd_is_accessible_reg(priv, gen, reg))
68 		return 0;
69 
70 	regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
71 
72 	dev_dbg(dev, "r %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, val);
73 
74 	return val;
75 }
76 
77 void rsnd_write(struct rsnd_priv *priv,
78 		struct rsnd_mod *mod,
79 		enum rsnd_reg reg, u32 data)
80 {
81 	struct device *dev = rsnd_priv_to_dev(priv);
82 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
83 
84 	if (!rsnd_is_accessible_reg(priv, gen, reg))
85 		return;
86 
87 	regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
88 
89 	dev_dbg(dev, "w %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, data);
90 }
91 
92 void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
93 	       enum rsnd_reg reg, u32 mask, u32 data)
94 {
95 	struct device *dev = rsnd_priv_to_dev(priv);
96 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
97 
98 	if (!rsnd_is_accessible_reg(priv, gen, reg))
99 		return;
100 
101 	regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
102 				  mask, data);
103 
104 	dev_dbg(dev, "b %s - 0x%04d : %08x/%08x\n",
105 		rsnd_mod_name(mod), reg, data, mask);
106 }
107 
108 #define rsnd_gen_regmap_init(priv, id_size, reg_id, conf)		\
109 	_rsnd_gen_regmap_init(priv, id_size, reg_id, conf, ARRAY_SIZE(conf))
110 static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
111 				 int id_size,
112 				 int reg_id,
113 				 struct rsnd_regmap_field_conf *conf,
114 				 int conf_size)
115 {
116 	struct platform_device *pdev = rsnd_priv_to_pdev(priv);
117 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
118 	struct device *dev = rsnd_priv_to_dev(priv);
119 	struct resource *res;
120 	struct regmap_config regc;
121 	struct regmap_field *regs;
122 	struct regmap *regmap;
123 	struct reg_field regf;
124 	void __iomem *base;
125 	int i;
126 
127 	memset(&regc, 0, sizeof(regc));
128 	regc.reg_bits = 32;
129 	regc.val_bits = 32;
130 	regc.reg_stride = 4;
131 
132 	res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id);
133 	if (!res)
134 		return -ENODEV;
135 
136 	base = devm_ioremap_resource(dev, res);
137 	if (IS_ERR(base))
138 		return PTR_ERR(base);
139 
140 	regmap = devm_regmap_init_mmio(dev, base, &regc);
141 	if (IS_ERR(regmap))
142 		return PTR_ERR(regmap);
143 
144 	gen->base[reg_id] = base;
145 	gen->regmap[reg_id] = regmap;
146 
147 	for (i = 0; i < conf_size; i++) {
148 
149 		regf.reg	= conf[i].reg_offset;
150 		regf.id_offset	= conf[i].id_offset;
151 		regf.lsb	= 0;
152 		regf.msb	= 31;
153 		regf.id_size	= id_size;
154 
155 		regs = devm_regmap_field_alloc(dev, regmap, regf);
156 		if (IS_ERR(regs))
157 			return PTR_ERR(regs);
158 
159 		gen->regs[conf[i].idx] = regs;
160 	}
161 
162 	return 0;
163 }
164 
165 /*
166  *	DMA read/write register offset
167  *
168  *	RSND_xxx_I_N	for Audio DMAC input
169  *	RSND_xxx_O_N	for Audio DMAC output
170  *	RSND_xxx_I_P	for Audio DMAC peri peri input
171  *	RSND_xxx_O_P	for Audio DMAC peri peri output
172  *
173  *	ex) R-Car H2 case
174  *	      mod        / DMAC in    / DMAC out   / DMAC PP in / DMAC pp out
175  *	SSI : 0xec541000 / 0xec241008 / 0xec24100c
176  *	SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
177  *	SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
178  *	CMD : 0xec500000 /            / 0xec008000                0xec308000
179  */
180 #define RDMA_SSI_I_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
181 #define RDMA_SSI_O_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
182 
183 #define RDMA_SSIU_I_N(addr, i)	(addr ##_reg - 0x00441000 + (0x1000 * i))
184 #define RDMA_SSIU_O_N(addr, i)	(addr ##_reg - 0x00441000 + (0x1000 * i))
185 
186 #define RDMA_SSIU_I_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
187 #define RDMA_SSIU_O_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
188 
189 #define RDMA_SRC_I_N(addr, i)	(addr ##_reg - 0x00500000 + (0x400 * i))
190 #define RDMA_SRC_O_N(addr, i)	(addr ##_reg - 0x004fc000 + (0x400 * i))
191 
192 #define RDMA_SRC_I_P(addr, i)	(addr ##_reg - 0x00200000 + (0x400 * i))
193 #define RDMA_SRC_O_P(addr, i)	(addr ##_reg - 0x001fc000 + (0x400 * i))
194 
195 #define RDMA_CMD_O_N(addr, i)	(addr ##_reg - 0x004f8000 + (0x400 * i))
196 #define RDMA_CMD_O_P(addr, i)	(addr ##_reg - 0x001f8000 + (0x400 * i))
197 
198 static dma_addr_t
199 rsnd_gen2_dma_addr(struct rsnd_priv *priv,
200 		   struct rsnd_mod *mod,
201 		   int is_play, int is_from)
202 {
203 	struct platform_device *pdev = rsnd_priv_to_pdev(priv);
204 	struct device *dev = rsnd_priv_to_dev(priv);
205 	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
206 	dma_addr_t ssi_reg = platform_get_resource(pdev,
207 				IORESOURCE_MEM, RSND_GEN2_SSI)->start;
208 	dma_addr_t src_reg = platform_get_resource(pdev,
209 				IORESOURCE_MEM, RSND_GEN2_SCU)->start;
210 	int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
211 	int use_src = !!rsnd_io_to_mod_src(io);
212 	int use_dvc = !!rsnd_io_to_mod_dvc(io);
213 	int id = rsnd_mod_id(mod);
214 	struct dma_addr {
215 		dma_addr_t out_addr;
216 		dma_addr_t in_addr;
217 	} dma_addrs[3][2][3] = {
218 		/* SRC */
219 		{{{ 0,				0 },
220 		/* Capture */
221 		  { RDMA_SRC_O_N(src, id),	RDMA_SRC_I_P(src, id) },
222 		  { RDMA_CMD_O_N(src, id),	RDMA_SRC_I_P(src, id) } },
223 		 /* Playback */
224 		 {{ 0,				0, },
225 		  { RDMA_SRC_O_P(src, id),	RDMA_SRC_I_N(src, id) },
226 		  { RDMA_CMD_O_P(src, id),	RDMA_SRC_I_N(src, id) } }
227 		},
228 		/* SSI */
229 		/* Capture */
230 		{{{ RDMA_SSI_O_N(ssi, id),	0 },
231 		  { RDMA_SSIU_O_P(ssi, id),	0 },
232 		  { RDMA_SSIU_O_P(ssi, id),	0 } },
233 		 /* Playback */
234 		 {{ 0,				RDMA_SSI_I_N(ssi, id) },
235 		  { 0,				RDMA_SSIU_I_P(ssi, id) },
236 		  { 0,				RDMA_SSIU_I_P(ssi, id) } }
237 		},
238 		/* SSIU */
239 		/* Capture */
240 		{{{ RDMA_SSIU_O_N(ssi, id),	0 },
241 		  { RDMA_SSIU_O_P(ssi, id),	0 },
242 		  { RDMA_SSIU_O_P(ssi, id),	0 } },
243 		 /* Playback */
244 		 {{ 0,				RDMA_SSIU_I_N(ssi, id) },
245 		  { 0,				RDMA_SSIU_I_P(ssi, id) },
246 		  { 0,				RDMA_SSIU_I_P(ssi, id) } } },
247 	};
248 
249 	/* it shouldn't happen */
250 	if (use_dvc && !use_src)
251 		dev_err(dev, "DVC is selected without SRC\n");
252 
253 	/* use SSIU or SSI ? */
254 	if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu")))
255 		is_ssi++;
256 
257 	return (is_from) ?
258 		dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
259 		dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
260 }
261 
262 dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv,
263 			     struct rsnd_mod *mod,
264 			     int is_play, int is_from)
265 {
266 	/*
267 	 * gen1 uses default DMA addr
268 	 */
269 	if (rsnd_is_gen1(priv))
270 		return 0;
271 
272 	if (!mod)
273 		return 0;
274 
275 	return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
276 }
277 
278 /*
279  *		Gen2
280  */
281 static int rsnd_gen2_probe(struct platform_device *pdev,
282 			   struct rsnd_priv *priv)
283 {
284 	struct device *dev = rsnd_priv_to_dev(priv);
285 	struct rsnd_regmap_field_conf conf_ssiu[] = {
286 		RSND_GEN_S_REG(SSI_MODE0,	0x800),
287 		RSND_GEN_S_REG(SSI_MODE1,	0x804),
288 		/* FIXME: it needs SSI_MODE2/3 in the future */
289 		RSND_GEN_M_REG(SSI_BUSIF_MODE,	0x0,	0x80),
290 		RSND_GEN_M_REG(SSI_BUSIF_ADINR,	0x4,	0x80),
291 		RSND_GEN_M_REG(BUSIF_DALIGN,	0x8,	0x80),
292 		RSND_GEN_M_REG(SSI_CTRL,	0x10,	0x80),
293 		RSND_GEN_M_REG(INT_ENABLE,	0x18,	0x80),
294 	};
295 	struct rsnd_regmap_field_conf conf_scu[] = {
296 		RSND_GEN_M_REG(SRC_BUSIF_MODE,	0x0,	0x20),
297 		RSND_GEN_M_REG(SRC_ROUTE_MODE0,	0xc,	0x20),
298 		RSND_GEN_M_REG(SRC_CTRL,	0x10,	0x20),
299 		RSND_GEN_M_REG(CMD_ROUTE_SLCT,	0x18c,	0x20),
300 		RSND_GEN_M_REG(CMD_CTRL,	0x190,	0x20),
301 		RSND_GEN_M_REG(SRC_SWRSR,	0x200,	0x40),
302 		RSND_GEN_M_REG(SRC_SRCIR,	0x204,	0x40),
303 		RSND_GEN_M_REG(SRC_ADINR,	0x214,	0x40),
304 		RSND_GEN_M_REG(SRC_IFSCR,	0x21c,	0x40),
305 		RSND_GEN_M_REG(SRC_IFSVR,	0x220,	0x40),
306 		RSND_GEN_M_REG(SRC_SRCCR,	0x224,	0x40),
307 		RSND_GEN_M_REG(SRC_BSDSR,	0x22c,	0x40),
308 		RSND_GEN_M_REG(SRC_BSISR,	0x238,	0x40),
309 		RSND_GEN_M_REG(DVC_SWRSR,	0xe00,	0x100),
310 		RSND_GEN_M_REG(DVC_DVUIR,	0xe04,	0x100),
311 		RSND_GEN_M_REG(DVC_ADINR,	0xe08,	0x100),
312 		RSND_GEN_M_REG(DVC_DVUCR,	0xe10,	0x100),
313 		RSND_GEN_M_REG(DVC_ZCMCR,	0xe14,	0x100),
314 		RSND_GEN_M_REG(DVC_VOL0R,	0xe28,	0x100),
315 		RSND_GEN_M_REG(DVC_VOL1R,	0xe2c,	0x100),
316 		RSND_GEN_M_REG(DVC_DVUER,	0xe48,	0x100),
317 	};
318 	struct rsnd_regmap_field_conf conf_adg[] = {
319 		RSND_GEN_S_REG(BRRA,		0x00),
320 		RSND_GEN_S_REG(BRRB,		0x04),
321 		RSND_GEN_S_REG(SSICKR,		0x08),
322 		RSND_GEN_S_REG(AUDIO_CLK_SEL0,	0x0c),
323 		RSND_GEN_S_REG(AUDIO_CLK_SEL1,	0x10),
324 		RSND_GEN_S_REG(AUDIO_CLK_SEL2,	0x14),
325 		RSND_GEN_S_REG(DIV_EN,		0x30),
326 		RSND_GEN_S_REG(SRCIN_TIMSEL0,	0x34),
327 		RSND_GEN_S_REG(SRCIN_TIMSEL1,	0x38),
328 		RSND_GEN_S_REG(SRCIN_TIMSEL2,	0x3c),
329 		RSND_GEN_S_REG(SRCIN_TIMSEL3,	0x40),
330 		RSND_GEN_S_REG(SRCIN_TIMSEL4,	0x44),
331 		RSND_GEN_S_REG(SRCOUT_TIMSEL0,	0x48),
332 		RSND_GEN_S_REG(SRCOUT_TIMSEL1,	0x4c),
333 		RSND_GEN_S_REG(SRCOUT_TIMSEL2,	0x50),
334 		RSND_GEN_S_REG(SRCOUT_TIMSEL3,	0x54),
335 		RSND_GEN_S_REG(SRCOUT_TIMSEL4,	0x58),
336 		RSND_GEN_S_REG(CMDOUT_TIMSEL,	0x5c),
337 	};
338 	struct rsnd_regmap_field_conf conf_ssi[] = {
339 		RSND_GEN_M_REG(SSICR,		0x00,	0x40),
340 		RSND_GEN_M_REG(SSISR,		0x04,	0x40),
341 		RSND_GEN_M_REG(SSITDR,		0x08,	0x40),
342 		RSND_GEN_M_REG(SSIRDR,		0x0c,	0x40),
343 		RSND_GEN_M_REG(SSIWSR,		0x20,	0x40),
344 	};
345 	int ret_ssiu;
346 	int ret_scu;
347 	int ret_adg;
348 	int ret_ssi;
349 
350 	ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, conf_ssiu);
351 	ret_scu  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU,  conf_scu);
352 	ret_adg  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG,  conf_adg);
353 	ret_ssi  = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI,  conf_ssi);
354 	if (ret_ssiu < 0 ||
355 	    ret_scu  < 0 ||
356 	    ret_adg  < 0 ||
357 	    ret_ssi  < 0)
358 		return ret_ssiu | ret_scu | ret_adg | ret_ssi;
359 
360 	dev_dbg(dev, "Gen2 is probed\n");
361 
362 	return 0;
363 }
364 
365 /*
366  *		Gen1
367  */
368 
369 static int rsnd_gen1_probe(struct platform_device *pdev,
370 			   struct rsnd_priv *priv)
371 {
372 	struct device *dev = rsnd_priv_to_dev(priv);
373 	struct rsnd_regmap_field_conf conf_sru[] = {
374 		RSND_GEN_S_REG(SRC_ROUTE_SEL,	0x00),
375 		RSND_GEN_S_REG(SRC_TMG_SEL0,	0x08),
376 		RSND_GEN_S_REG(SRC_TMG_SEL1,	0x0c),
377 		RSND_GEN_S_REG(SRC_TMG_SEL2,	0x10),
378 		RSND_GEN_S_REG(SRC_ROUTE_CTRL,	0xc0),
379 		RSND_GEN_S_REG(SSI_MODE0,	0xD0),
380 		RSND_GEN_S_REG(SSI_MODE1,	0xD4),
381 		RSND_GEN_M_REG(SRC_BUSIF_MODE,	0x20,	0x4),
382 		RSND_GEN_M_REG(SRC_ROUTE_MODE0,	0x50,	0x8),
383 		RSND_GEN_M_REG(SRC_SWRSR,	0x200,	0x40),
384 		RSND_GEN_M_REG(SRC_SRCIR,	0x204,	0x40),
385 		RSND_GEN_M_REG(SRC_ADINR,	0x214,	0x40),
386 		RSND_GEN_M_REG(SRC_IFSCR,	0x21c,	0x40),
387 		RSND_GEN_M_REG(SRC_IFSVR,	0x220,	0x40),
388 		RSND_GEN_M_REG(SRC_SRCCR,	0x224,	0x40),
389 		RSND_GEN_M_REG(SRC_MNFSR,	0x228,	0x40),
390 	};
391 	struct rsnd_regmap_field_conf conf_adg[] = {
392 		RSND_GEN_S_REG(BRRA,		0x00),
393 		RSND_GEN_S_REG(BRRB,		0x04),
394 		RSND_GEN_S_REG(SSICKR,		0x08),
395 		RSND_GEN_S_REG(AUDIO_CLK_SEL0,	0x0c),
396 		RSND_GEN_S_REG(AUDIO_CLK_SEL1,	0x10),
397 		RSND_GEN_S_REG(AUDIO_CLK_SEL3,	0x18),
398 		RSND_GEN_S_REG(AUDIO_CLK_SEL4,	0x1c),
399 		RSND_GEN_S_REG(AUDIO_CLK_SEL5,	0x20),
400 	};
401 	struct rsnd_regmap_field_conf conf_ssi[] = {
402 		RSND_GEN_M_REG(SSICR,		0x00,	0x40),
403 		RSND_GEN_M_REG(SSISR,		0x04,	0x40),
404 		RSND_GEN_M_REG(SSITDR,		0x08,	0x40),
405 		RSND_GEN_M_REG(SSIRDR,		0x0c,	0x40),
406 		RSND_GEN_M_REG(SSIWSR,		0x20,	0x40),
407 	};
408 	int ret_sru;
409 	int ret_adg;
410 	int ret_ssi;
411 
412 	ret_sru  = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU,  conf_sru);
413 	ret_adg  = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG,  conf_adg);
414 	ret_ssi  = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI,  conf_ssi);
415 	if (ret_sru  < 0 ||
416 	    ret_adg  < 0 ||
417 	    ret_ssi  < 0)
418 		return ret_sru | ret_adg | ret_ssi;
419 
420 	dev_dbg(dev, "Gen1 is probed\n");
421 
422 	return 0;
423 }
424 
425 /*
426  *		Gen
427  */
428 static void rsnd_of_parse_gen(struct platform_device *pdev,
429 			      const struct rsnd_of_data *of_data,
430 			      struct rsnd_priv *priv)
431 {
432 	struct rcar_snd_info *info = priv->info;
433 
434 	if (!of_data)
435 		return;
436 
437 	info->flags = of_data->flags;
438 }
439 
440 int rsnd_gen_probe(struct platform_device *pdev,
441 		   const struct rsnd_of_data *of_data,
442 		   struct rsnd_priv *priv)
443 {
444 	struct device *dev = rsnd_priv_to_dev(priv);
445 	struct rsnd_gen *gen;
446 	int ret;
447 
448 	rsnd_of_parse_gen(pdev, of_data, priv);
449 
450 	gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
451 	if (!gen) {
452 		dev_err(dev, "GEN allocate failed\n");
453 		return -ENOMEM;
454 	}
455 
456 	priv->gen = gen;
457 
458 	ret = -ENODEV;
459 	if (rsnd_is_gen1(priv))
460 		ret = rsnd_gen1_probe(pdev, priv);
461 	else if (rsnd_is_gen2(priv))
462 		ret = rsnd_gen2_probe(pdev, priv);
463 
464 	if (ret < 0)
465 		dev_err(dev, "unknown generation R-Car sound device\n");
466 
467 	return ret;
468 }
469