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