1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // AMD ALSA SoC PCM Driver 4 // 5 //Copyright 2016 Advanced Micro Devices, Inc. 6 7 #include <linux/platform_device.h> 8 #include <linux/module.h> 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/pm_runtime.h> 12 #include <sound/pcm_params.h> 13 #include <sound/soc.h> 14 #include <sound/soc-dai.h> 15 16 #include "acp3x.h" 17 18 #define DRV_NAME "acp3x_rv_i2s_dma" 19 20 static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = { 21 .info = SNDRV_PCM_INFO_INTERLEAVED | 22 SNDRV_PCM_INFO_BLOCK_TRANSFER | 23 SNDRV_PCM_INFO_BATCH | 24 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 25 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, 26 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 27 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | 28 SNDRV_PCM_FMTBIT_S32_LE, 29 .channels_min = 2, 30 .channels_max = 8, 31 .rates = SNDRV_PCM_RATE_8000_96000, 32 .rate_min = 8000, 33 .rate_max = 96000, 34 .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE, 35 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, 36 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, 37 .periods_min = PLAYBACK_MIN_NUM_PERIODS, 38 .periods_max = PLAYBACK_MAX_NUM_PERIODS, 39 }; 40 41 static const struct snd_pcm_hardware acp3x_pcm_hardware_capture = { 42 .info = SNDRV_PCM_INFO_INTERLEAVED | 43 SNDRV_PCM_INFO_BLOCK_TRANSFER | 44 SNDRV_PCM_INFO_BATCH | 45 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 46 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, 47 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 48 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | 49 SNDRV_PCM_FMTBIT_S32_LE, 50 .channels_min = 2, 51 .channels_max = 2, 52 .rates = SNDRV_PCM_RATE_8000_48000, 53 .rate_min = 8000, 54 .rate_max = 48000, 55 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE, 56 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, 57 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, 58 .periods_min = CAPTURE_MIN_NUM_PERIODS, 59 .periods_max = CAPTURE_MAX_NUM_PERIODS, 60 }; 61 62 static irqreturn_t i2s_irq_handler(int irq, void *dev_id) 63 { 64 struct i2s_dev_data *rv_i2s_data; 65 u16 play_flag, cap_flag; 66 u32 val; 67 68 rv_i2s_data = dev_id; 69 if (!rv_i2s_data) 70 return IRQ_NONE; 71 72 play_flag = 0; 73 cap_flag = 0; 74 val = rv_readl(rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT); 75 if ((val & BIT(BT_TX_THRESHOLD)) && rv_i2s_data->play_stream) { 76 rv_writel(BIT(BT_TX_THRESHOLD), rv_i2s_data->acp3x_base + 77 mmACP_EXTERNAL_INTR_STAT); 78 snd_pcm_period_elapsed(rv_i2s_data->play_stream); 79 play_flag = 1; 80 } 81 if ((val & BIT(I2S_TX_THRESHOLD)) && 82 rv_i2s_data->i2ssp_play_stream) { 83 rv_writel(BIT(I2S_TX_THRESHOLD), 84 rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT); 85 snd_pcm_period_elapsed(rv_i2s_data->i2ssp_play_stream); 86 play_flag = 1; 87 } 88 89 if ((val & BIT(BT_RX_THRESHOLD)) && rv_i2s_data->capture_stream) { 90 rv_writel(BIT(BT_RX_THRESHOLD), rv_i2s_data->acp3x_base + 91 mmACP_EXTERNAL_INTR_STAT); 92 snd_pcm_period_elapsed(rv_i2s_data->capture_stream); 93 cap_flag = 1; 94 } 95 if ((val & BIT(I2S_RX_THRESHOLD)) && 96 rv_i2s_data->i2ssp_capture_stream) { 97 rv_writel(BIT(I2S_RX_THRESHOLD), 98 rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT); 99 snd_pcm_period_elapsed(rv_i2s_data->i2ssp_capture_stream); 100 cap_flag = 1; 101 } 102 103 if (play_flag | cap_flag) 104 return IRQ_HANDLED; 105 else 106 return IRQ_NONE; 107 } 108 109 static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction) 110 { 111 u16 page_idx; 112 u32 low, high, val, acp_fifo_addr, reg_fifo_addr; 113 u32 reg_dma_size, reg_fifo_size; 114 dma_addr_t addr; 115 116 addr = rtd->dma_addr; 117 118 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 119 switch (rtd->i2s_instance) { 120 case I2S_BT_INSTANCE: 121 val = ACP_SRAM_BT_PB_PTE_OFFSET; 122 break; 123 case I2S_SP_INSTANCE: 124 default: 125 val = ACP_SRAM_SP_PB_PTE_OFFSET; 126 } 127 } else { 128 switch (rtd->i2s_instance) { 129 case I2S_BT_INSTANCE: 130 val = ACP_SRAM_BT_CP_PTE_OFFSET; 131 break; 132 case I2S_SP_INSTANCE: 133 default: 134 val = ACP_SRAM_SP_CP_PTE_OFFSET; 135 } 136 } 137 /* Group Enable */ 138 rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp3x_base + 139 mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1); 140 rv_writel(PAGE_SIZE_4K_ENABLE, rtd->acp3x_base + 141 mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); 142 143 for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) { 144 /* Load the low address of page int ACP SRAM through SRBM */ 145 low = lower_32_bits(addr); 146 high = upper_32_bits(addr); 147 148 rv_writel(low, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val); 149 high |= BIT(31); 150 rv_writel(high, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val 151 + 4); 152 /* Move to next physically contiguos page */ 153 val += 8; 154 addr += PAGE_SIZE; 155 } 156 157 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 158 switch (rtd->i2s_instance) { 159 case I2S_BT_INSTANCE: 160 reg_dma_size = mmACP_BT_TX_DMA_SIZE; 161 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + 162 BT_PB_FIFO_ADDR_OFFSET; 163 reg_fifo_addr = mmACP_BT_TX_FIFOADDR; 164 reg_fifo_size = mmACP_BT_TX_FIFOSIZE; 165 rv_writel(I2S_BT_TX_MEM_WINDOW_START, 166 rtd->acp3x_base + mmACP_BT_TX_RINGBUFADDR); 167 break; 168 169 case I2S_SP_INSTANCE: 170 default: 171 reg_dma_size = mmACP_I2S_TX_DMA_SIZE; 172 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + 173 SP_PB_FIFO_ADDR_OFFSET; 174 reg_fifo_addr = mmACP_I2S_TX_FIFOADDR; 175 reg_fifo_size = mmACP_I2S_TX_FIFOSIZE; 176 rv_writel(I2S_SP_TX_MEM_WINDOW_START, 177 rtd->acp3x_base + mmACP_I2S_TX_RINGBUFADDR); 178 } 179 } else { 180 switch (rtd->i2s_instance) { 181 case I2S_BT_INSTANCE: 182 reg_dma_size = mmACP_BT_RX_DMA_SIZE; 183 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + 184 BT_CAPT_FIFO_ADDR_OFFSET; 185 reg_fifo_addr = mmACP_BT_RX_FIFOADDR; 186 reg_fifo_size = mmACP_BT_RX_FIFOSIZE; 187 rv_writel(I2S_BT_RX_MEM_WINDOW_START, 188 rtd->acp3x_base + mmACP_BT_RX_RINGBUFADDR); 189 break; 190 191 case I2S_SP_INSTANCE: 192 default: 193 reg_dma_size = mmACP_I2S_RX_DMA_SIZE; 194 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + 195 SP_CAPT_FIFO_ADDR_OFFSET; 196 reg_fifo_addr = mmACP_I2S_RX_FIFOADDR; 197 reg_fifo_size = mmACP_I2S_RX_FIFOSIZE; 198 rv_writel(I2S_SP_RX_MEM_WINDOW_START, 199 rtd->acp3x_base + mmACP_I2S_RX_RINGBUFADDR); 200 } 201 } 202 rv_writel(DMA_SIZE, rtd->acp3x_base + reg_dma_size); 203 rv_writel(acp_fifo_addr, rtd->acp3x_base + reg_fifo_addr); 204 rv_writel(FIFO_SIZE, rtd->acp3x_base + reg_fifo_size); 205 rv_writel(BIT(I2S_RX_THRESHOLD) | BIT(BT_RX_THRESHOLD) 206 | BIT(I2S_TX_THRESHOLD) | BIT(BT_TX_THRESHOLD), 207 rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL); 208 } 209 210 static int acp3x_dma_open(struct snd_soc_component *component, 211 struct snd_pcm_substream *substream) 212 { 213 struct snd_pcm_runtime *runtime; 214 struct snd_soc_pcm_runtime *prtd; 215 struct i2s_dev_data *adata; 216 struct i2s_stream_instance *i2s_data; 217 int ret; 218 219 runtime = substream->runtime; 220 prtd = substream->private_data; 221 component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); 222 adata = dev_get_drvdata(component->dev); 223 i2s_data = kzalloc(sizeof(*i2s_data), GFP_KERNEL); 224 if (!i2s_data) 225 return -EINVAL; 226 227 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 228 runtime->hw = acp3x_pcm_hardware_playback; 229 else 230 runtime->hw = acp3x_pcm_hardware_capture; 231 232 ret = snd_pcm_hw_constraint_integer(runtime, 233 SNDRV_PCM_HW_PARAM_PERIODS); 234 if (ret < 0) { 235 dev_err(component->dev, "set integer constraint failed\n"); 236 kfree(i2s_data); 237 return ret; 238 } 239 240 if (!adata->play_stream && !adata->capture_stream && 241 adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) 242 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 243 244 i2s_data->acp3x_base = adata->acp3x_base; 245 runtime->private_data = i2s_data; 246 return ret; 247 } 248 249 250 static int acp3x_dma_hw_params(struct snd_soc_component *component, 251 struct snd_pcm_substream *substream, 252 struct snd_pcm_hw_params *params) 253 { 254 struct i2s_stream_instance *rtd; 255 struct snd_soc_pcm_runtime *prtd; 256 struct snd_soc_card *card; 257 struct acp3x_platform_info *pinfo; 258 struct i2s_dev_data *adata; 259 u64 size; 260 261 prtd = substream->private_data; 262 card = prtd->card; 263 pinfo = snd_soc_card_get_drvdata(card); 264 adata = dev_get_drvdata(component->dev); 265 rtd = substream->runtime->private_data; 266 if (!rtd) 267 return -EINVAL; 268 269 if (pinfo) { 270 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 271 rtd->i2s_instance = pinfo->play_i2s_instance; 272 switch (rtd->i2s_instance) { 273 case I2S_BT_INSTANCE: 274 adata->play_stream = substream; 275 break; 276 case I2S_SP_INSTANCE: 277 default: 278 adata->i2ssp_play_stream = substream; 279 } 280 } else { 281 rtd->i2s_instance = pinfo->cap_i2s_instance; 282 switch (rtd->i2s_instance) { 283 case I2S_BT_INSTANCE: 284 adata->capture_stream = substream; 285 break; 286 case I2S_SP_INSTANCE: 287 default: 288 adata->i2ssp_capture_stream = substream; 289 } 290 } 291 } else { 292 pr_err("pinfo failed\n"); 293 } 294 size = params_buffer_bytes(params); 295 rtd->dma_addr = substream->dma_buffer.addr; 296 rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); 297 config_acp3x_dma(rtd, substream->stream); 298 return 0; 299 } 300 301 static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component, 302 struct snd_pcm_substream *substream) 303 { 304 struct snd_soc_pcm_runtime *prtd; 305 struct snd_soc_card *card; 306 struct i2s_stream_instance *rtd; 307 u32 pos; 308 u32 buffersize; 309 u64 bytescount; 310 311 prtd = substream->private_data; 312 card = prtd->card; 313 rtd = substream->runtime->private_data; 314 315 buffersize = frames_to_bytes(substream->runtime, 316 substream->runtime->buffer_size); 317 bytescount = acp_get_byte_count(rtd, substream->stream); 318 if (bytescount > rtd->bytescount) 319 bytescount -= rtd->bytescount; 320 pos = do_div(bytescount, buffersize); 321 return bytes_to_frames(substream->runtime, pos); 322 } 323 324 static int acp3x_dma_new(struct snd_soc_component *component, 325 struct snd_soc_pcm_runtime *rtd) 326 { 327 struct device *parent = component->dev->parent; 328 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, 329 parent, MIN_BUFFER, MAX_BUFFER); 330 return 0; 331 } 332 333 static int acp3x_dma_mmap(struct snd_soc_component *component, 334 struct snd_pcm_substream *substream, 335 struct vm_area_struct *vma) 336 { 337 return snd_pcm_lib_default_mmap(substream, vma); 338 } 339 340 static int acp3x_dma_close(struct snd_soc_component *component, 341 struct snd_pcm_substream *substream) 342 { 343 struct snd_soc_pcm_runtime *prtd; 344 struct i2s_dev_data *adata; 345 struct i2s_stream_instance *ins; 346 347 prtd = substream->private_data; 348 component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); 349 adata = dev_get_drvdata(component->dev); 350 ins = substream->runtime->private_data; 351 if (!ins) 352 return -EINVAL; 353 354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 355 switch (ins->i2s_instance) { 356 case I2S_BT_INSTANCE: 357 adata->play_stream = NULL; 358 break; 359 case I2S_SP_INSTANCE: 360 default: 361 adata->i2ssp_play_stream = NULL; 362 } 363 } else { 364 switch (ins->i2s_instance) { 365 case I2S_BT_INSTANCE: 366 adata->capture_stream = NULL; 367 break; 368 case I2S_SP_INSTANCE: 369 default: 370 adata->i2ssp_capture_stream = NULL; 371 } 372 } 373 374 /* Disable ACP irq, when the current stream is being closed and 375 * another stream is also not active. 376 */ 377 if (!adata->play_stream && !adata->capture_stream && 378 !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) 379 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 380 return 0; 381 } 382 383 static const struct snd_soc_component_driver acp3x_i2s_component = { 384 .name = DRV_NAME, 385 .open = acp3x_dma_open, 386 .close = acp3x_dma_close, 387 .hw_params = acp3x_dma_hw_params, 388 .pointer = acp3x_dma_pointer, 389 .mmap = acp3x_dma_mmap, 390 .pcm_construct = acp3x_dma_new, 391 }; 392 393 static int acp3x_audio_probe(struct platform_device *pdev) 394 { 395 struct resource *res; 396 struct i2s_dev_data *adata; 397 unsigned int irqflags; 398 int status; 399 400 if (!pdev->dev.platform_data) { 401 dev_err(&pdev->dev, "platform_data not retrieved\n"); 402 return -ENODEV; 403 } 404 irqflags = *((unsigned int *)(pdev->dev.platform_data)); 405 406 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 407 if (!res) { 408 dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); 409 return -ENODEV; 410 } 411 412 adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL); 413 if (!adata) 414 return -ENOMEM; 415 416 adata->acp3x_base = devm_ioremap(&pdev->dev, res->start, 417 resource_size(res)); 418 if (!adata->acp3x_base) 419 return -ENOMEM; 420 421 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 422 if (!res) { 423 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); 424 return -ENODEV; 425 } 426 427 adata->i2s_irq = res->start; 428 429 dev_set_drvdata(&pdev->dev, adata); 430 status = devm_snd_soc_register_component(&pdev->dev, 431 &acp3x_i2s_component, 432 NULL, 0); 433 if (status) { 434 dev_err(&pdev->dev, "Fail to register acp i2s component\n"); 435 return -ENODEV; 436 } 437 status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler, 438 irqflags, "ACP3x_I2S_IRQ", adata); 439 if (status) { 440 dev_err(&pdev->dev, "ACP3x I2S IRQ request failed\n"); 441 return -ENODEV; 442 } 443 444 pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); 445 pm_runtime_use_autosuspend(&pdev->dev); 446 pm_runtime_enable(&pdev->dev); 447 pm_runtime_allow(&pdev->dev); 448 return 0; 449 } 450 451 static int acp3x_audio_remove(struct platform_device *pdev) 452 { 453 pm_runtime_disable(&pdev->dev); 454 return 0; 455 } 456 457 static int acp3x_resume(struct device *dev) 458 { 459 struct i2s_dev_data *adata; 460 u32 val, reg_val, frmt_val; 461 462 reg_val = 0; 463 frmt_val = 0; 464 adata = dev_get_drvdata(dev); 465 466 if (adata->play_stream && adata->play_stream->runtime) { 467 struct i2s_stream_instance *rtd = 468 adata->play_stream->runtime->private_data; 469 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK); 470 switch (rtd->i2s_instance) { 471 case I2S_BT_INSTANCE: 472 reg_val = mmACP_BTTDM_ITER; 473 frmt_val = mmACP_BTTDM_TXFRMT; 474 break; 475 case I2S_SP_INSTANCE: 476 default: 477 reg_val = mmACP_I2STDM_ITER; 478 frmt_val = mmACP_I2STDM_TXFRMT; 479 } 480 rv_writel((rtd->xfer_resolution << 3), 481 rtd->acp3x_base + reg_val); 482 } 483 if (adata->capture_stream && adata->capture_stream->runtime) { 484 struct i2s_stream_instance *rtd = 485 adata->capture_stream->runtime->private_data; 486 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE); 487 switch (rtd->i2s_instance) { 488 case I2S_BT_INSTANCE: 489 reg_val = mmACP_BTTDM_IRER; 490 frmt_val = mmACP_BTTDM_RXFRMT; 491 break; 492 case I2S_SP_INSTANCE: 493 default: 494 reg_val = mmACP_I2STDM_IRER; 495 frmt_val = mmACP_I2STDM_RXFRMT; 496 } 497 rv_writel((rtd->xfer_resolution << 3), 498 rtd->acp3x_base + reg_val); 499 } 500 if (adata->tdm_mode == TDM_ENABLE) { 501 rv_writel(adata->tdm_fmt, adata->acp3x_base + frmt_val); 502 val = rv_readl(adata->acp3x_base + reg_val); 503 rv_writel(val | 0x2, adata->acp3x_base + reg_val); 504 } 505 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 506 return 0; 507 } 508 509 510 static int acp3x_pcm_runtime_suspend(struct device *dev) 511 { 512 struct i2s_dev_data *adata; 513 514 adata = dev_get_drvdata(dev); 515 516 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 517 518 return 0; 519 } 520 521 static int acp3x_pcm_runtime_resume(struct device *dev) 522 { 523 struct i2s_dev_data *adata; 524 525 adata = dev_get_drvdata(dev); 526 527 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 528 return 0; 529 } 530 531 static const struct dev_pm_ops acp3x_pm_ops = { 532 .runtime_suspend = acp3x_pcm_runtime_suspend, 533 .runtime_resume = acp3x_pcm_runtime_resume, 534 .resume = acp3x_resume, 535 }; 536 537 static struct platform_driver acp3x_dma_driver = { 538 .probe = acp3x_audio_probe, 539 .remove = acp3x_audio_remove, 540 .driver = { 541 .name = "acp3x_rv_i2s_dma", 542 .pm = &acp3x_pm_ops, 543 }, 544 }; 545 546 module_platform_driver(acp3x_dma_driver); 547 548 MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com"); 549 MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com"); 550 MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); 551 MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver"); 552 MODULE_LICENSE("GPL v2"); 553 MODULE_ALIAS("platform:"DRV_NAME); 554