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(®c, 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, ®c); 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