1 // SPDX-License-Identifier: GPL-2.0+
3 // AMD ALSA SoC PCM Driver
5 //Copyright 2016 Advanced Micro Devices, Inc.
7 #include <linux/platform_device.h>
8 #include <linux/module.h>
11 #include <linux/pm_runtime.h>
12 #include <sound/pcm_params.h>
13 #include <sound/soc.h>
14 #include <sound/soc-dai.h>
18 #define DRV_NAME "acp3x_rv_i2s_dma"
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
,
30 .rates
= SNDRV_PCM_RATE_8000_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
,
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
,
50 .rates
= SNDRV_PCM_RATE_8000_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
,
60 static irqreturn_t
i2s_irq_handler(int irq
, void *dev_id
)
62 struct i2s_dev_data
*rv_i2s_data
;
63 u16 play_flag
, cap_flag
;
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
);
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
);
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
);
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
);
101 if (play_flag
| cap_flag
)
107 static void config_acp3x_dma(struct i2s_stream_instance
*rtd
, int direction
)
110 u32 low
, high
, val
, acp_fifo_addr
, reg_fifo_addr
;
111 u32 reg_dma_size
, reg_fifo_size
;
114 addr
= rtd
->dma_addr
;
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
;
121 case I2S_SP_INSTANCE
:
123 val
= ACP_SRAM_SP_PB_PTE_OFFSET
;
126 switch (rtd
->i2s_instance
) {
127 case I2S_BT_INSTANCE
:
128 val
= ACP_SRAM_BT_CP_PTE_OFFSET
;
130 case I2S_SP_INSTANCE
:
132 val
= ACP_SRAM_SP_CP_PTE_OFFSET
;
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
);
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
);
146 rv_writel(low
, rtd
->acp3x_base
+ mmACP_SCRATCH_REG_0
+ val
);
148 rv_writel(high
, rtd
->acp3x_base
+ mmACP_SCRATCH_REG_0
+ val
150 /* Move to next physically contiguous page */
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
);
167 case I2S_SP_INSTANCE
:
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
);
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
);
189 case I2S_SP_INSTANCE
:
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
);
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
);
208 static int acp3x_dma_open(struct snd_soc_component
*component
,
209 struct snd_pcm_substream
*substream
)
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
;
217 runtime
= substream
->runtime
;
218 prtd
= snd_soc_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
);
225 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
226 runtime
->hw
= acp3x_pcm_hardware_playback
;
228 runtime
->hw
= acp3x_pcm_hardware_capture
;
230 ret
= snd_pcm_hw_constraint_integer(runtime
,
231 SNDRV_PCM_HW_PARAM_PERIODS
);
233 dev_err(component
->dev
, "set integer constraint failed\n");
238 i2s_data
->acp3x_base
= adata
->acp3x_base
;
239 runtime
->private_data
= i2s_data
;
244 static int acp3x_dma_hw_params(struct snd_soc_component
*component
,
245 struct snd_pcm_substream
*substream
,
246 struct snd_pcm_hw_params
*params
)
248 struct i2s_stream_instance
*rtd
;
249 struct snd_soc_pcm_runtime
*prtd
;
250 struct snd_soc_card
*card
;
251 struct acp3x_platform_info
*pinfo
;
252 struct i2s_dev_data
*adata
;
255 prtd
= snd_soc_substream_to_rtd(substream
);
257 pinfo
= snd_soc_card_get_drvdata(card
);
258 adata
= dev_get_drvdata(component
->dev
);
259 rtd
= substream
->runtime
->private_data
;
264 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
265 rtd
->i2s_instance
= pinfo
->play_i2s_instance
;
266 switch (rtd
->i2s_instance
) {
267 case I2S_BT_INSTANCE
:
268 adata
->play_stream
= substream
;
270 case I2S_SP_INSTANCE
:
272 adata
->i2ssp_play_stream
= substream
;
275 rtd
->i2s_instance
= pinfo
->cap_i2s_instance
;
276 switch (rtd
->i2s_instance
) {
277 case I2S_BT_INSTANCE
:
278 adata
->capture_stream
= substream
;
280 case I2S_SP_INSTANCE
:
282 adata
->i2ssp_capture_stream
= substream
;
286 pr_err("pinfo failed\n");
288 size
= params_buffer_bytes(params
);
289 rtd
->dma_addr
= substream
->runtime
->dma_addr
;
290 rtd
->num_pages
= (PAGE_ALIGN(size
) >> PAGE_SHIFT
);
291 config_acp3x_dma(rtd
, substream
->stream
);
295 static snd_pcm_uframes_t
acp3x_dma_pointer(struct snd_soc_component
*component
,
296 struct snd_pcm_substream
*substream
)
298 struct i2s_stream_instance
*rtd
;
303 rtd
= substream
->runtime
->private_data
;
305 buffersize
= frames_to_bytes(substream
->runtime
,
306 substream
->runtime
->buffer_size
);
307 bytescount
= acp_get_byte_count(rtd
, substream
->stream
);
308 if (bytescount
> rtd
->bytescount
)
309 bytescount
-= rtd
->bytescount
;
310 pos
= do_div(bytescount
, buffersize
);
311 return bytes_to_frames(substream
->runtime
, pos
);
314 static int acp3x_dma_new(struct snd_soc_component
*component
,
315 struct snd_soc_pcm_runtime
*rtd
)
317 struct device
*parent
= component
->dev
->parent
;
318 snd_pcm_set_managed_buffer_all(rtd
->pcm
, SNDRV_DMA_TYPE_DEV
,
319 parent
, MIN_BUFFER
, MAX_BUFFER
);
323 static int acp3x_dma_close(struct snd_soc_component
*component
,
324 struct snd_pcm_substream
*substream
)
326 struct snd_soc_pcm_runtime
*prtd
;
327 struct i2s_dev_data
*adata
;
328 struct i2s_stream_instance
*ins
;
330 prtd
= snd_soc_substream_to_rtd(substream
);
331 component
= snd_soc_rtdcom_lookup(prtd
, DRV_NAME
);
332 adata
= dev_get_drvdata(component
->dev
);
333 ins
= substream
->runtime
->private_data
;
337 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
338 switch (ins
->i2s_instance
) {
339 case I2S_BT_INSTANCE
:
340 adata
->play_stream
= NULL
;
342 case I2S_SP_INSTANCE
:
344 adata
->i2ssp_play_stream
= NULL
;
347 switch (ins
->i2s_instance
) {
348 case I2S_BT_INSTANCE
:
349 adata
->capture_stream
= NULL
;
351 case I2S_SP_INSTANCE
:
353 adata
->i2ssp_capture_stream
= NULL
;
360 static const struct snd_soc_component_driver acp3x_i2s_component
= {
362 .open
= acp3x_dma_open
,
363 .close
= acp3x_dma_close
,
364 .hw_params
= acp3x_dma_hw_params
,
365 .pointer
= acp3x_dma_pointer
,
366 .pcm_construct
= acp3x_dma_new
,
369 static int acp3x_audio_probe(struct platform_device
*pdev
)
371 struct resource
*res
;
372 struct i2s_dev_data
*adata
;
373 unsigned int irqflags
;
376 if (!pdev
->dev
.platform_data
) {
377 dev_err(&pdev
->dev
, "platform_data not retrieved\n");
380 irqflags
= *((unsigned int *)(pdev
->dev
.platform_data
));
382 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
384 dev_err(&pdev
->dev
, "IORESOURCE_MEM FAILED\n");
388 adata
= devm_kzalloc(&pdev
->dev
, sizeof(*adata
), GFP_KERNEL
);
392 adata
->acp3x_base
= devm_ioremap(&pdev
->dev
, res
->start
,
394 if (!adata
->acp3x_base
)
397 status
= platform_get_irq(pdev
, 0);
400 adata
->i2s_irq
= status
;
402 dev_set_drvdata(&pdev
->dev
, adata
);
403 status
= devm_snd_soc_register_component(&pdev
->dev
,
404 &acp3x_i2s_component
,
407 dev_err(&pdev
->dev
, "Fail to register acp i2s component\n");
410 status
= devm_request_irq(&pdev
->dev
, adata
->i2s_irq
, i2s_irq_handler
,
411 irqflags
, "ACP3x_I2S_IRQ", adata
);
413 dev_err(&pdev
->dev
, "ACP3x I2S IRQ request failed\n");
417 pm_runtime_set_autosuspend_delay(&pdev
->dev
, 2000);
418 pm_runtime_use_autosuspend(&pdev
->dev
);
419 pm_runtime_mark_last_busy(&pdev
->dev
);
420 pm_runtime_set_active(&pdev
->dev
);
421 pm_runtime_enable(&pdev
->dev
);
425 static void acp3x_audio_remove(struct platform_device
*pdev
)
427 pm_runtime_disable(&pdev
->dev
);
430 static int acp3x_resume(struct device
*dev
)
432 struct i2s_dev_data
*adata
;
433 u32 val
, reg_val
, frmt_val
;
437 adata
= dev_get_drvdata(dev
);
439 if (adata
->play_stream
&& adata
->play_stream
->runtime
) {
440 struct i2s_stream_instance
*rtd
=
441 adata
->play_stream
->runtime
->private_data
;
442 config_acp3x_dma(rtd
, SNDRV_PCM_STREAM_PLAYBACK
);
443 switch (rtd
->i2s_instance
) {
444 case I2S_BT_INSTANCE
:
445 reg_val
= mmACP_BTTDM_ITER
;
446 frmt_val
= mmACP_BTTDM_TXFRMT
;
448 case I2S_SP_INSTANCE
:
450 reg_val
= mmACP_I2STDM_ITER
;
451 frmt_val
= mmACP_I2STDM_TXFRMT
;
453 rv_writel((rtd
->xfer_resolution
<< 3),
454 rtd
->acp3x_base
+ reg_val
);
456 if (adata
->capture_stream
&& adata
->capture_stream
->runtime
) {
457 struct i2s_stream_instance
*rtd
=
458 adata
->capture_stream
->runtime
->private_data
;
459 config_acp3x_dma(rtd
, SNDRV_PCM_STREAM_CAPTURE
);
460 switch (rtd
->i2s_instance
) {
461 case I2S_BT_INSTANCE
:
462 reg_val
= mmACP_BTTDM_IRER
;
463 frmt_val
= mmACP_BTTDM_RXFRMT
;
465 case I2S_SP_INSTANCE
:
467 reg_val
= mmACP_I2STDM_IRER
;
468 frmt_val
= mmACP_I2STDM_RXFRMT
;
470 rv_writel((rtd
->xfer_resolution
<< 3),
471 rtd
->acp3x_base
+ reg_val
);
473 if (adata
->tdm_mode
== TDM_ENABLE
) {
474 rv_writel(adata
->tdm_fmt
, adata
->acp3x_base
+ frmt_val
);
475 val
= rv_readl(adata
->acp3x_base
+ reg_val
);
476 rv_writel(val
| 0x2, adata
->acp3x_base
+ reg_val
);
478 rv_writel(1, adata
->acp3x_base
+ mmACP_EXTERNAL_INTR_ENB
);
483 static int acp3x_pcm_runtime_suspend(struct device
*dev
)
485 struct i2s_dev_data
*adata
;
487 adata
= dev_get_drvdata(dev
);
489 rv_writel(0, adata
->acp3x_base
+ mmACP_EXTERNAL_INTR_ENB
);
494 static int acp3x_pcm_runtime_resume(struct device
*dev
)
496 struct i2s_dev_data
*adata
;
498 adata
= dev_get_drvdata(dev
);
500 rv_writel(1, adata
->acp3x_base
+ mmACP_EXTERNAL_INTR_ENB
);
504 static const struct dev_pm_ops acp3x_pm_ops
= {
505 .runtime_suspend
= acp3x_pcm_runtime_suspend
,
506 .runtime_resume
= acp3x_pcm_runtime_resume
,
507 .resume
= acp3x_resume
,
510 static struct platform_driver acp3x_dma_driver
= {
511 .probe
= acp3x_audio_probe
,
512 .remove
= acp3x_audio_remove
,
514 .name
= "acp3x_rv_i2s_dma",
519 module_platform_driver(acp3x_dma_driver
);
521 MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
522 MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
523 MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
524 MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
525 MODULE_LICENSE("GPL v2");
526 MODULE_ALIAS("platform:"DRV_NAME
);