2 * Renesas R-Car Gen1 SRU/SSI support
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
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.
14 void __iomem
*base
[RSND_BASE_MAX
];
16 struct rsnd_gen_ops
*ops
;
18 struct regmap
*regmap
[RSND_BASE_MAX
];
19 struct regmap_field
*regs
[RSND_REG_MAX
];
22 #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
24 struct rsnd_regmap_field_conf
{
26 unsigned int reg_offset
;
27 unsigned int id_offset
;
30 #define RSND_REG_SET(id, offset, _id_offset) \
33 .reg_offset = offset, \
34 .id_offset = _id_offset, \
36 /* single address mapping */
37 #define RSND_GEN_S_REG(id, offset) \
38 RSND_REG_SET(RSND_REG_##id, offset, 0)
40 /* multi address mapping */
41 #define RSND_GEN_M_REG(id, offset, _id_offset) \
42 RSND_REG_SET(RSND_REG_##id, offset, _id_offset)
47 static int rsnd_is_accessible_reg(struct rsnd_priv
*priv
,
48 struct rsnd_gen
*gen
, enum rsnd_reg reg
)
50 if (!gen
->regs
[reg
]) {
51 struct device
*dev
= rsnd_priv_to_dev(priv
);
53 dev_err(dev
, "unsupported register access %x\n", reg
);
60 u32
rsnd_read(struct rsnd_priv
*priv
,
61 struct rsnd_mod
*mod
, enum rsnd_reg reg
)
63 struct device
*dev
= rsnd_priv_to_dev(priv
);
64 struct rsnd_gen
*gen
= rsnd_priv_to_gen(priv
);
67 if (!rsnd_is_accessible_reg(priv
, gen
, reg
))
70 regmap_fields_read(gen
->regs
[reg
], rsnd_mod_id(mod
), &val
);
72 dev_dbg(dev
, "r %s - 0x%04d : %08x\n", rsnd_mod_name(mod
), reg
, val
);
77 void rsnd_write(struct rsnd_priv
*priv
,
79 enum rsnd_reg reg
, u32 data
)
81 struct device
*dev
= rsnd_priv_to_dev(priv
);
82 struct rsnd_gen
*gen
= rsnd_priv_to_gen(priv
);
84 if (!rsnd_is_accessible_reg(priv
, gen
, reg
))
87 regmap_fields_write(gen
->regs
[reg
], rsnd_mod_id(mod
), data
);
89 dev_dbg(dev
, "w %s - 0x%04d : %08x\n", rsnd_mod_name(mod
), reg
, data
);
92 void rsnd_bset(struct rsnd_priv
*priv
, struct rsnd_mod
*mod
,
93 enum rsnd_reg reg
, u32 mask
, u32 data
)
95 struct device
*dev
= rsnd_priv_to_dev(priv
);
96 struct rsnd_gen
*gen
= rsnd_priv_to_gen(priv
);
98 if (!rsnd_is_accessible_reg(priv
, gen
, reg
))
101 regmap_fields_update_bits(gen
->regs
[reg
], rsnd_mod_id(mod
),
104 dev_dbg(dev
, "b %s - 0x%04d : %08x/%08x\n",
105 rsnd_mod_name(mod
), reg
, data
, mask
);
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
,
113 struct rsnd_regmap_field_conf
*conf
,
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
;
127 memset(®c
, 0, sizeof(regc
));
132 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, reg_id
);
136 base
= devm_ioremap_resource(dev
, res
);
138 return PTR_ERR(base
);
140 regmap
= devm_regmap_init_mmio(dev
, base
, ®c
);
142 return PTR_ERR(regmap
);
144 gen
->base
[reg_id
] = base
;
145 gen
->regmap
[reg_id
] = regmap
;
147 for (i
= 0; i
< conf_size
; i
++) {
149 regf
.reg
= conf
[i
].reg_offset
;
150 regf
.id_offset
= conf
[i
].id_offset
;
153 regf
.id_size
= id_size
;
155 regs
= devm_regmap_field_alloc(dev
, regmap
, regf
);
157 return PTR_ERR(regs
);
159 gen
->regs
[conf
[i
].idx
] = regs
;
166 * DMA read/write register offset
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
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
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)
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))
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))
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))
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))
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))
199 rsnd_gen2_dma_addr(struct rsnd_priv
*priv
,
200 struct rsnd_mod
*mod
,
201 int is_play
, int is_from
)
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
);
217 } dma_addrs
[3][2][3] = {
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
) } },
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
) } }
230 {{{ RDMA_SSI_O_N(ssi
, id
), 0 },
231 { RDMA_SSIU_O_P(ssi
, id
), 0 },
232 { RDMA_SSIU_O_P(ssi
, id
), 0 } },
234 {{ 0, RDMA_SSI_I_N(ssi
, id
) },
235 { 0, RDMA_SSIU_I_P(ssi
, id
) },
236 { 0, RDMA_SSIU_I_P(ssi
, id
) } }
240 {{{ RDMA_SSIU_O_N(ssi
, id
), 0 },
241 { RDMA_SSIU_O_P(ssi
, id
), 0 },
242 { RDMA_SSIU_O_P(ssi
, id
), 0 } },
244 {{ 0, RDMA_SSIU_I_N(ssi
, id
) },
245 { 0, RDMA_SSIU_I_P(ssi
, id
) },
246 { 0, RDMA_SSIU_I_P(ssi
, id
) } } },
249 /* it shouldn't happen */
250 if (use_dvc
& !use_src
)
251 dev_err(dev
, "DVC is selected without SRC\n");
253 /* use SSIU or SSI ? */
254 if (is_ssi
&& (0 == strcmp(rsnd_mod_dma_name(mod
), "ssiu")))
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
;
262 dma_addr_t
rsnd_gen_dma_addr(struct rsnd_priv
*priv
,
263 struct rsnd_mod
*mod
,
264 int is_play
, int is_from
)
267 * gen1 uses default DMA addr
269 if (rsnd_is_gen1(priv
))
275 return rsnd_gen2_dma_addr(priv
, mod
, is_play
, is_from
);
281 static int rsnd_gen2_probe(struct platform_device
*pdev
,
282 struct rsnd_priv
*priv
)
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),
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),
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),
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),
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
);
358 return ret_ssiu
| ret_scu
| ret_adg
| ret_ssi
;
360 dev_dbg(dev
, "Gen2 is probed\n");
369 static int rsnd_gen1_probe(struct platform_device
*pdev
,
370 struct rsnd_priv
*priv
)
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),
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),
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),
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
);
418 return ret_sru
| ret_adg
| ret_ssi
;
420 dev_dbg(dev
, "Gen1 is probed\n");
428 static void rsnd_of_parse_gen(struct platform_device
*pdev
,
429 const struct rsnd_of_data
*of_data
,
430 struct rsnd_priv
*priv
)
432 struct rcar_snd_info
*info
= priv
->info
;
437 info
->flags
= of_data
->flags
;
440 int rsnd_gen_probe(struct platform_device
*pdev
,
441 const struct rsnd_of_data
*of_data
,
442 struct rsnd_priv
*priv
)
444 struct device
*dev
= rsnd_priv_to_dev(priv
);
445 struct rsnd_gen
*gen
;
448 rsnd_of_parse_gen(pdev
, of_data
, priv
);
450 gen
= devm_kzalloc(dev
, sizeof(*gen
), GFP_KERNEL
);
452 dev_err(dev
, "GEN allocate failed\n");
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
);
465 dev_err(dev
, "unknown generation R-Car sound device\n");