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