1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 // 3 // This file is provided under a dual BSD/GPLv2 license. When using or 4 // redistributing this file, you may do so under either license. 5 // 6 // Copyright(c) 2021 Advanced Micro Devices, Inc. 7 // 8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> 9 // 10 11 /* 12 * Generic Hardware interface for ACP Audio I2S controller 13 */ 14 15 #include <linux/platform_device.h> 16 #include <linux/module.h> 17 #include <linux/err.h> 18 #include <linux/io.h> 19 #include <sound/pcm_params.h> 20 #include <sound/soc.h> 21 #include <sound/soc-dai.h> 22 #include <linux/dma-mapping.h> 23 24 #include "amd.h" 25 26 #define DRV_NAME "acp_i2s_playcap" 27 28 static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 29 unsigned int fmt) 30 { 31 struct acp_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); 32 int mode; 33 34 mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 35 switch (mode) { 36 case SND_SOC_DAIFMT_I2S: 37 adata->tdm_mode = TDM_DISABLE; 38 break; 39 case SND_SOC_DAIFMT_DSP_A: 40 adata->tdm_mode = TDM_ENABLE; 41 break; 42 default: 43 return -EINVAL; 44 } 45 return 0; 46 } 47 48 static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mask, 49 int slots, int slot_width) 50 { 51 struct device *dev = dai->component->dev; 52 struct acp_dev_data *adata = snd_soc_dai_get_drvdata(dai); 53 struct acp_stream *stream; 54 int slot_len; 55 56 switch (slot_width) { 57 case SLOT_WIDTH_8: 58 slot_len = 8; 59 break; 60 case SLOT_WIDTH_16: 61 slot_len = 16; 62 break; 63 case SLOT_WIDTH_24: 64 slot_len = 24; 65 break; 66 case SLOT_WIDTH_32: 67 slot_len = 0; 68 break; 69 default: 70 dev_err(dev, "Unsupported bitdepth %d\n", slot_width); 71 return -EINVAL; 72 } 73 74 spin_lock_irq(&adata->acp_lock); 75 list_for_each_entry(stream, &adata->stream_list, list) { 76 if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) 77 adata->tdm_tx_fmt[stream->dai_id - 1] = 78 FRM_LEN | (slots << 15) | (slot_len << 18); 79 else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) 80 adata->tdm_rx_fmt[stream->dai_id - 1] = 81 FRM_LEN | (slots << 15) | (slot_len << 18); 82 } 83 spin_unlock_irq(&adata->acp_lock); 84 return 0; 85 } 86 87 static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, 88 struct snd_soc_dai *dai) 89 { 90 struct device *dev = dai->component->dev; 91 struct acp_dev_data *adata; 92 struct acp_resource *rsrc; 93 u32 val; 94 u32 xfer_resolution; 95 u32 reg_val, fmt_reg, tdm_fmt; 96 u32 lrclk_div_val, bclk_div_val; 97 98 adata = snd_soc_dai_get_drvdata(dai); 99 rsrc = adata->rsrc; 100 101 /* These values are as per Hardware Spec */ 102 switch (params_format(params)) { 103 case SNDRV_PCM_FORMAT_U8: 104 case SNDRV_PCM_FORMAT_S8: 105 xfer_resolution = 0x0; 106 break; 107 case SNDRV_PCM_FORMAT_S16_LE: 108 xfer_resolution = 0x02; 109 break; 110 case SNDRV_PCM_FORMAT_S24_LE: 111 xfer_resolution = 0x04; 112 break; 113 case SNDRV_PCM_FORMAT_S32_LE: 114 xfer_resolution = 0x05; 115 break; 116 default: 117 return -EINVAL; 118 } 119 120 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 121 switch (dai->driver->id) { 122 case I2S_BT_INSTANCE: 123 reg_val = ACP_BTTDM_ITER; 124 fmt_reg = ACP_BTTDM_TXFRMT; 125 break; 126 case I2S_SP_INSTANCE: 127 reg_val = ACP_I2STDM_ITER; 128 fmt_reg = ACP_I2STDM_TXFRMT; 129 break; 130 case I2S_HS_INSTANCE: 131 reg_val = ACP_HSTDM_ITER; 132 fmt_reg = ACP_HSTDM_TXFRMT; 133 break; 134 default: 135 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 136 return -EINVAL; 137 } 138 } else { 139 switch (dai->driver->id) { 140 case I2S_BT_INSTANCE: 141 reg_val = ACP_BTTDM_IRER; 142 fmt_reg = ACP_BTTDM_RXFRMT; 143 break; 144 case I2S_SP_INSTANCE: 145 reg_val = ACP_I2STDM_IRER; 146 fmt_reg = ACP_I2STDM_RXFRMT; 147 break; 148 case I2S_HS_INSTANCE: 149 reg_val = ACP_HSTDM_IRER; 150 fmt_reg = ACP_HSTDM_RXFRMT; 151 break; 152 default: 153 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 154 return -EINVAL; 155 } 156 } 157 158 val = readl(adata->acp_base + reg_val); 159 val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK; 160 val = val | (xfer_resolution << 3); 161 writel(val, adata->acp_base + reg_val); 162 163 if (adata->tdm_mode) { 164 val = readl(adata->acp_base + reg_val); 165 writel(val | BIT(1), adata->acp_base + reg_val); 166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 167 tdm_fmt = adata->tdm_tx_fmt[dai->driver->id - 1]; 168 else 169 tdm_fmt = adata->tdm_rx_fmt[dai->driver->id - 1]; 170 writel(tdm_fmt, adata->acp_base + fmt_reg); 171 } 172 173 if (rsrc->soc_mclk) { 174 switch (params_format(params)) { 175 case SNDRV_PCM_FORMAT_S16_LE: 176 switch (params_rate(params)) { 177 case 8000: 178 bclk_div_val = 768; 179 break; 180 case 16000: 181 bclk_div_val = 384; 182 break; 183 case 24000: 184 bclk_div_val = 256; 185 break; 186 case 32000: 187 bclk_div_val = 192; 188 break; 189 case 44100: 190 case 48000: 191 bclk_div_val = 128; 192 break; 193 case 88200: 194 case 96000: 195 bclk_div_val = 64; 196 break; 197 case 192000: 198 bclk_div_val = 32; 199 break; 200 default: 201 return -EINVAL; 202 } 203 lrclk_div_val = 32; 204 break; 205 case SNDRV_PCM_FORMAT_S32_LE: 206 switch (params_rate(params)) { 207 case 8000: 208 bclk_div_val = 384; 209 break; 210 case 16000: 211 bclk_div_val = 192; 212 break; 213 case 24000: 214 bclk_div_val = 128; 215 break; 216 case 32000: 217 bclk_div_val = 96; 218 break; 219 case 44100: 220 case 48000: 221 bclk_div_val = 64; 222 break; 223 case 88200: 224 case 96000: 225 bclk_div_val = 32; 226 break; 227 case 192000: 228 bclk_div_val = 16; 229 break; 230 default: 231 return -EINVAL; 232 } 233 lrclk_div_val = 64; 234 break; 235 default: 236 return -EINVAL; 237 } 238 adata->lrclk_div = lrclk_div_val; 239 adata->bclk_div = bclk_div_val; 240 } 241 return 0; 242 } 243 244 static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) 245 { 246 struct acp_stream *stream = substream->runtime->private_data; 247 struct device *dev = dai->component->dev; 248 struct acp_dev_data *adata = dev_get_drvdata(dev); 249 struct acp_resource *rsrc = adata->rsrc; 250 u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg; 251 252 period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); 253 buf_size = frames_to_bytes(substream->runtime, substream->runtime->buffer_size); 254 255 switch (cmd) { 256 case SNDRV_PCM_TRIGGER_START: 257 case SNDRV_PCM_TRIGGER_RESUME: 258 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 259 stream->bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream); 260 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 261 switch (dai->driver->id) { 262 case I2S_BT_INSTANCE: 263 water_val = ACP_BT_TX_INTR_WATERMARK_SIZE; 264 reg_val = ACP_BTTDM_ITER; 265 ier_val = ACP_BTTDM_IER; 266 buf_reg = ACP_BT_TX_RINGBUFSIZE; 267 break; 268 case I2S_SP_INSTANCE: 269 water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE; 270 reg_val = ACP_I2STDM_ITER; 271 ier_val = ACP_I2STDM_IER; 272 buf_reg = ACP_I2S_TX_RINGBUFSIZE; 273 break; 274 case I2S_HS_INSTANCE: 275 water_val = ACP_HS_TX_INTR_WATERMARK_SIZE; 276 reg_val = ACP_HSTDM_ITER; 277 ier_val = ACP_HSTDM_IER; 278 buf_reg = ACP_HS_TX_RINGBUFSIZE; 279 break; 280 default: 281 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 282 return -EINVAL; 283 } 284 } else { 285 switch (dai->driver->id) { 286 case I2S_BT_INSTANCE: 287 water_val = ACP_BT_RX_INTR_WATERMARK_SIZE; 288 reg_val = ACP_BTTDM_IRER; 289 ier_val = ACP_BTTDM_IER; 290 buf_reg = ACP_BT_RX_RINGBUFSIZE; 291 break; 292 case I2S_SP_INSTANCE: 293 water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE; 294 reg_val = ACP_I2STDM_IRER; 295 ier_val = ACP_I2STDM_IER; 296 buf_reg = ACP_I2S_RX_RINGBUFSIZE; 297 break; 298 case I2S_HS_INSTANCE: 299 water_val = ACP_HS_RX_INTR_WATERMARK_SIZE; 300 reg_val = ACP_HSTDM_IRER; 301 ier_val = ACP_HSTDM_IER; 302 buf_reg = ACP_HS_RX_RINGBUFSIZE; 303 break; 304 default: 305 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 306 return -EINVAL; 307 } 308 } 309 writel(period_bytes, adata->acp_base + water_val); 310 writel(buf_size, adata->acp_base + buf_reg); 311 val = readl(adata->acp_base + reg_val); 312 val = val | BIT(0); 313 writel(val, adata->acp_base + reg_val); 314 writel(1, adata->acp_base + ier_val); 315 if (rsrc->soc_mclk) 316 acp_set_i2s_clk(adata, dai->driver->id); 317 return 0; 318 case SNDRV_PCM_TRIGGER_STOP: 319 case SNDRV_PCM_TRIGGER_SUSPEND: 320 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 321 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 322 switch (dai->driver->id) { 323 case I2S_BT_INSTANCE: 324 reg_val = ACP_BTTDM_ITER; 325 break; 326 case I2S_SP_INSTANCE: 327 reg_val = ACP_I2STDM_ITER; 328 break; 329 case I2S_HS_INSTANCE: 330 reg_val = ACP_HSTDM_ITER; 331 break; 332 default: 333 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 334 return -EINVAL; 335 } 336 337 } else { 338 switch (dai->driver->id) { 339 case I2S_BT_INSTANCE: 340 reg_val = ACP_BTTDM_IRER; 341 break; 342 case I2S_SP_INSTANCE: 343 reg_val = ACP_I2STDM_IRER; 344 break; 345 case I2S_HS_INSTANCE: 346 reg_val = ACP_HSTDM_IRER; 347 break; 348 default: 349 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 350 return -EINVAL; 351 } 352 } 353 val = readl(adata->acp_base + reg_val); 354 val = val & ~BIT(0); 355 writel(val, adata->acp_base + reg_val); 356 357 if (!(readl(adata->acp_base + ACP_BTTDM_ITER) & BIT(0)) && 358 !(readl(adata->acp_base + ACP_BTTDM_IRER) & BIT(0))) 359 writel(0, adata->acp_base + ACP_BTTDM_IER); 360 if (!(readl(adata->acp_base + ACP_I2STDM_ITER) & BIT(0)) && 361 !(readl(adata->acp_base + ACP_I2STDM_IRER) & BIT(0))) 362 writel(0, adata->acp_base + ACP_I2STDM_IER); 363 if (!(readl(adata->acp_base + ACP_HSTDM_ITER) & BIT(0)) && 364 !(readl(adata->acp_base + ACP_HSTDM_IRER) & BIT(0))) 365 writel(0, adata->acp_base + ACP_HSTDM_IER); 366 return 0; 367 default: 368 return -EINVAL; 369 } 370 371 return 0; 372 } 373 374 static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 375 { 376 struct device *dev = dai->component->dev; 377 struct acp_dev_data *adata = dev_get_drvdata(dev); 378 struct acp_resource *rsrc = adata->rsrc; 379 struct acp_stream *stream = substream->runtime->private_data; 380 u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0; 381 u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl; 382 unsigned int dir = substream->stream; 383 384 switch (dai->driver->id) { 385 case I2S_SP_INSTANCE: 386 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 387 reg_dma_size = ACP_I2S_TX_DMA_SIZE; 388 acp_fifo_addr = rsrc->sram_pte_offset + 389 SP_PB_FIFO_ADDR_OFFSET; 390 reg_fifo_addr = ACP_I2S_TX_FIFOADDR; 391 reg_fifo_size = ACP_I2S_TX_FIFOSIZE; 392 393 phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; 394 writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR); 395 } else { 396 reg_dma_size = ACP_I2S_RX_DMA_SIZE; 397 acp_fifo_addr = rsrc->sram_pte_offset + 398 SP_CAPT_FIFO_ADDR_OFFSET; 399 reg_fifo_addr = ACP_I2S_RX_FIFOADDR; 400 reg_fifo_size = ACP_I2S_RX_FIFOSIZE; 401 phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; 402 writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR); 403 } 404 break; 405 case I2S_BT_INSTANCE: 406 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 407 reg_dma_size = ACP_BT_TX_DMA_SIZE; 408 acp_fifo_addr = rsrc->sram_pte_offset + 409 BT_PB_FIFO_ADDR_OFFSET; 410 reg_fifo_addr = ACP_BT_TX_FIFOADDR; 411 reg_fifo_size = ACP_BT_TX_FIFOSIZE; 412 413 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; 414 writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR); 415 } else { 416 reg_dma_size = ACP_BT_RX_DMA_SIZE; 417 acp_fifo_addr = rsrc->sram_pte_offset + 418 BT_CAPT_FIFO_ADDR_OFFSET; 419 reg_fifo_addr = ACP_BT_RX_FIFOADDR; 420 reg_fifo_size = ACP_BT_RX_FIFOSIZE; 421 422 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; 423 writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR); 424 } 425 break; 426 case I2S_HS_INSTANCE: 427 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 428 reg_dma_size = ACP_HS_TX_DMA_SIZE; 429 acp_fifo_addr = rsrc->sram_pte_offset + 430 HS_PB_FIFO_ADDR_OFFSET; 431 reg_fifo_addr = ACP_HS_TX_FIFOADDR; 432 reg_fifo_size = ACP_HS_TX_FIFOSIZE; 433 434 phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; 435 writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR); 436 } else { 437 reg_dma_size = ACP_HS_RX_DMA_SIZE; 438 acp_fifo_addr = rsrc->sram_pte_offset + 439 HS_CAPT_FIFO_ADDR_OFFSET; 440 reg_fifo_addr = ACP_HS_RX_FIFOADDR; 441 reg_fifo_size = ACP_HS_RX_FIFOSIZE; 442 443 phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; 444 writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR); 445 } 446 break; 447 default: 448 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 449 return -EINVAL; 450 } 451 452 writel(DMA_SIZE, adata->acp_base + reg_dma_size); 453 writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); 454 writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); 455 456 ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); 457 ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | 458 BIT(BT_RX_THRESHOLD(rsrc->offset)) | 459 BIT(I2S_TX_THRESHOLD(rsrc->offset)) | 460 BIT(BT_TX_THRESHOLD(rsrc->offset)) | 461 BIT(HS_RX_THRESHOLD(rsrc->offset)) | 462 BIT(HS_TX_THRESHOLD(rsrc->offset)); 463 464 writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); 465 466 return 0; 467 } 468 469 static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 470 { 471 struct acp_stream *stream = substream->runtime->private_data; 472 struct device *dev = dai->component->dev; 473 struct acp_dev_data *adata = dev_get_drvdata(dev); 474 struct acp_resource *rsrc = adata->rsrc; 475 unsigned int dir = substream->stream; 476 unsigned int irq_bit = 0; 477 478 switch (dai->driver->id) { 479 case I2S_SP_INSTANCE: 480 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 481 irq_bit = BIT(I2S_TX_THRESHOLD(rsrc->offset)); 482 stream->pte_offset = ACP_SRAM_SP_PB_PTE_OFFSET; 483 stream->fifo_offset = SP_PB_FIFO_ADDR_OFFSET; 484 } else { 485 irq_bit = BIT(I2S_RX_THRESHOLD(rsrc->offset)); 486 stream->pte_offset = ACP_SRAM_SP_CP_PTE_OFFSET; 487 stream->fifo_offset = SP_CAPT_FIFO_ADDR_OFFSET; 488 } 489 break; 490 case I2S_BT_INSTANCE: 491 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 492 irq_bit = BIT(BT_TX_THRESHOLD(rsrc->offset)); 493 stream->pte_offset = ACP_SRAM_BT_PB_PTE_OFFSET; 494 stream->fifo_offset = BT_PB_FIFO_ADDR_OFFSET; 495 } else { 496 irq_bit = BIT(BT_RX_THRESHOLD(rsrc->offset)); 497 stream->pte_offset = ACP_SRAM_BT_CP_PTE_OFFSET; 498 stream->fifo_offset = BT_CAPT_FIFO_ADDR_OFFSET; 499 } 500 break; 501 case I2S_HS_INSTANCE: 502 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 503 irq_bit = BIT(HS_TX_THRESHOLD(rsrc->offset)); 504 stream->pte_offset = ACP_SRAM_HS_PB_PTE_OFFSET; 505 stream->fifo_offset = HS_PB_FIFO_ADDR_OFFSET; 506 } else { 507 irq_bit = BIT(HS_RX_THRESHOLD(rsrc->offset)); 508 stream->pte_offset = ACP_SRAM_HS_CP_PTE_OFFSET; 509 stream->fifo_offset = HS_CAPT_FIFO_ADDR_OFFSET; 510 } 511 break; 512 default: 513 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 514 return -EINVAL; 515 } 516 517 /* Save runtime dai configuration in stream */ 518 stream->id = dai->driver->id + dir; 519 stream->dai_id = dai->driver->id; 520 stream->irq_bit = irq_bit; 521 stream->dir = substream->stream; 522 523 return 0; 524 } 525 526 const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = { 527 .startup = acp_i2s_startup, 528 .hw_params = acp_i2s_hwparams, 529 .prepare = acp_i2s_prepare, 530 .trigger = acp_i2s_trigger, 531 .set_fmt = acp_i2s_set_fmt, 532 .set_tdm_slot = acp_i2s_set_tdm_slot, 533 }; 534 EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, SND_SOC_ACP_COMMON); 535 536 int asoc_acp_i2s_probe(struct snd_soc_dai *dai) 537 { 538 struct device *dev = dai->component->dev; 539 struct acp_dev_data *adata = dev_get_drvdata(dev); 540 struct acp_resource *rsrc = adata->rsrc; 541 unsigned int val; 542 543 if (!adata->acp_base) { 544 dev_err(dev, "I2S base is NULL\n"); 545 return -EINVAL; 546 } 547 548 val = readl(adata->acp_base + rsrc->i2s_pin_cfg_offset); 549 if (val != rsrc->i2s_mode) { 550 dev_err(dev, "I2S Mode not supported val %x\n", val); 551 return -EINVAL; 552 } 553 554 return 0; 555 } 556 EXPORT_SYMBOL_NS_GPL(asoc_acp_i2s_probe, SND_SOC_ACP_COMMON); 557 558 MODULE_LICENSE("Dual BSD/GPL"); 559 MODULE_ALIAS(DRV_NAME); 560