1 // SPDX-License-Identifier: GPL-2.0-only
3 * AMD ALSA SoC Pink Sardine PDM Driver
5 * Copyright 2022 Advanced Micro Devices, Inc.
8 #include <linux/platform_device.h>
9 #include <linux/module.h>
10 #include <linux/bitfield.h>
11 #include <linux/err.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc.h>
15 #include <sound/soc-dai.h>
16 #include <linux/pm_runtime.h>
20 #define DRV_NAME "acp_ps_pdm_dma"
22 static int pdm_gain
= 3;
23 module_param(pdm_gain
, int, 0644);
24 MODULE_PARM_DESC(pdm_gain
, "Gain control (0-3)");
26 static const struct snd_pcm_hardware acp63_pdm_hardware_capture
= {
27 .info
= SNDRV_PCM_INFO_INTERLEAVED
|
28 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
30 SNDRV_PCM_INFO_MMAP_VALID
|
31 SNDRV_PCM_INFO_PAUSE
| SNDRV_PCM_INFO_RESUME
,
32 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
35 .rates
= SNDRV_PCM_RATE_48000
,
38 .buffer_bytes_max
= CAPTURE_MAX_NUM_PERIODS
* CAPTURE_MAX_PERIOD_SIZE
,
39 .period_bytes_min
= CAPTURE_MIN_PERIOD_SIZE
,
40 .period_bytes_max
= CAPTURE_MAX_PERIOD_SIZE
,
41 .periods_min
= CAPTURE_MIN_NUM_PERIODS
,
42 .periods_max
= CAPTURE_MAX_NUM_PERIODS
,
45 static void acp63_init_pdm_ring_buffer(u32 physical_addr
, u32 buffer_size
,
46 u32 watermark_size
, void __iomem
*acp_base
)
48 writel(physical_addr
, acp_base
+ ACP_WOV_RX_RINGBUFADDR
);
49 writel(buffer_size
, acp_base
+ ACP_WOV_RX_RINGBUFSIZE
);
50 writel(watermark_size
, acp_base
+ ACP_WOV_RX_INTR_WATERMARK_SIZE
);
51 writel(0x01, acp_base
+ ACPAXI2AXI_ATU_CTRL
);
54 static void acp63_enable_pdm_clock(void __iomem
*acp_base
)
56 u32 pdm_clk_enable
, pdm_ctrl
;
58 pdm_clk_enable
= ACP_PDM_CLK_FREQ_MASK
;
61 writel(pdm_clk_enable
, acp_base
+ ACP_WOV_CLK_CTRL
);
62 pdm_ctrl
= readl(acp_base
+ ACP_WOV_MISC_CTRL
);
63 pdm_ctrl
&= ~ACP_WOV_GAIN_CONTROL
;
64 pdm_ctrl
|= FIELD_PREP(ACP_WOV_GAIN_CONTROL
, clamp(pdm_gain
, 0, 3));
65 writel(pdm_ctrl
, acp_base
+ ACP_WOV_MISC_CTRL
);
68 static void acp63_enable_pdm_interrupts(struct pdm_dev_data
*adata
)
72 mutex_lock(adata
->acp_lock
);
73 ext_int_ctrl
= readl(adata
->acp63_base
+ ACP_EXTERNAL_INTR_CNTL
);
74 ext_int_ctrl
|= PDM_DMA_INTR_MASK
;
75 writel(ext_int_ctrl
, adata
->acp63_base
+ ACP_EXTERNAL_INTR_CNTL
);
76 mutex_unlock(adata
->acp_lock
);
79 static void acp63_disable_pdm_interrupts(struct pdm_dev_data
*adata
)
83 mutex_lock(adata
->acp_lock
);
84 ext_int_ctrl
= readl(adata
->acp63_base
+ ACP_EXTERNAL_INTR_CNTL
);
85 ext_int_ctrl
&= ~PDM_DMA_INTR_MASK
;
86 writel(ext_int_ctrl
, adata
->acp63_base
+ ACP_EXTERNAL_INTR_CNTL
);
87 mutex_unlock(adata
->acp_lock
);
90 static bool acp63_check_pdm_dma_status(void __iomem
*acp_base
)
93 u32 pdm_enable
, pdm_dma_enable
;
95 pdm_dma_status
= false;
96 pdm_enable
= readl(acp_base
+ ACP_WOV_PDM_ENABLE
);
97 pdm_dma_enable
= readl(acp_base
+ ACP_WOV_PDM_DMA_ENABLE
);
98 if ((pdm_enable
& ACP_PDM_ENABLE
) && (pdm_dma_enable
& ACP_PDM_DMA_EN_STATUS
))
99 pdm_dma_status
= true;
101 return pdm_dma_status
;
104 static int acp63_start_pdm_dma(void __iomem
*acp_base
)
111 pdm_dma_enable
= 0x01;
113 acp63_enable_pdm_clock(acp_base
);
114 writel(pdm_enable
, acp_base
+ ACP_WOV_PDM_ENABLE
);
115 writel(pdm_dma_enable
, acp_base
+ ACP_WOV_PDM_DMA_ENABLE
);
117 while (++timeout
< ACP_COUNTER
) {
118 pdm_dma_enable
= readl(acp_base
+ ACP_WOV_PDM_DMA_ENABLE
);
119 if ((pdm_dma_enable
& 0x02) == ACP_PDM_DMA_EN_STATUS
)
126 static int acp63_stop_pdm_dma(void __iomem
*acp_base
)
128 u32 pdm_enable
, pdm_dma_enable
;
132 pdm_dma_enable
= 0x00;
134 pdm_enable
= readl(acp_base
+ ACP_WOV_PDM_ENABLE
);
135 pdm_dma_enable
= readl(acp_base
+ ACP_WOV_PDM_DMA_ENABLE
);
136 if (pdm_dma_enable
& 0x01) {
137 pdm_dma_enable
= 0x02;
138 writel(pdm_dma_enable
, acp_base
+ ACP_WOV_PDM_DMA_ENABLE
);
140 while (++timeout
< ACP_COUNTER
) {
141 pdm_dma_enable
= readl(acp_base
+ ACP_WOV_PDM_DMA_ENABLE
);
142 if ((pdm_dma_enable
& 0x02) == 0x00)
146 if (timeout
== ACP_COUNTER
)
149 if (pdm_enable
== ACP_PDM_ENABLE
) {
150 pdm_enable
= ACP_PDM_DISABLE
;
151 writel(pdm_enable
, acp_base
+ ACP_WOV_PDM_ENABLE
);
153 writel(0x01, acp_base
+ ACP_WOV_PDM_FIFO_FLUSH
);
157 static void acp63_config_dma(struct pdm_stream_instance
*rtd
, int direction
)
163 addr
= rtd
->dma_addr
;
164 val
= PDM_PTE_OFFSET
;
167 writel(ACP_SRAM_PTE_OFFSET
| BIT(31), rtd
->acp63_base
+ ACPAXI2AXI_ATU_BASE_ADDR_GRP_1
);
168 writel(PAGE_SIZE_4K_ENABLE
, rtd
->acp63_base
+ ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1
);
169 for (page_idx
= 0; page_idx
< rtd
->num_pages
; page_idx
++) {
170 /* Load the low address of page int ACP SRAM through SRBM */
171 low
= lower_32_bits(addr
);
172 high
= upper_32_bits(addr
);
174 writel(low
, rtd
->acp63_base
+ ACP_SCRATCH_REG_0
+ val
);
176 writel(high
, rtd
->acp63_base
+ ACP_SCRATCH_REG_0
+ val
+ 4);
182 static int acp63_pdm_dma_open(struct snd_soc_component
*component
,
183 struct snd_pcm_substream
*substream
)
185 struct snd_pcm_runtime
*runtime
;
186 struct pdm_dev_data
*adata
;
187 struct pdm_stream_instance
*pdm_data
;
190 runtime
= substream
->runtime
;
191 adata
= dev_get_drvdata(component
->dev
);
192 pdm_data
= kzalloc(sizeof(*pdm_data
), GFP_KERNEL
);
196 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
197 runtime
->hw
= acp63_pdm_hardware_capture
;
199 ret
= snd_pcm_hw_constraint_integer(runtime
,
200 SNDRV_PCM_HW_PARAM_PERIODS
);
202 dev_err(component
->dev
, "set integer constraint failed\n");
207 acp63_enable_pdm_interrupts(adata
);
209 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
210 adata
->capture_stream
= substream
;
212 pdm_data
->acp63_base
= adata
->acp63_base
;
213 runtime
->private_data
= pdm_data
;
217 static int acp63_pdm_dma_hw_params(struct snd_soc_component
*component
,
218 struct snd_pcm_substream
*substream
,
219 struct snd_pcm_hw_params
*params
)
221 struct pdm_stream_instance
*rtd
;
222 size_t size
, period_bytes
;
224 rtd
= substream
->runtime
->private_data
;
227 size
= params_buffer_bytes(params
);
228 period_bytes
= params_period_bytes(params
);
229 rtd
->dma_addr
= substream
->runtime
->dma_addr
;
230 rtd
->num_pages
= (PAGE_ALIGN(size
) >> PAGE_SHIFT
);
231 acp63_config_dma(rtd
, substream
->stream
);
232 acp63_init_pdm_ring_buffer(PDM_MEM_WINDOW_START
, size
,
233 period_bytes
, rtd
->acp63_base
);
237 static u64
acp63_pdm_get_byte_count(struct pdm_stream_instance
*rtd
,
243 high
= readl(rtd
->acp63_base
+ ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH
);
245 low
= readl(rtd
->acp63_base
+ ACP_WOV_RX_LINEARPOSITIONCNTR_LOW
);
246 byte_count
= (byte_count
<< 32) | low
;
250 static snd_pcm_uframes_t
acp63_pdm_dma_pointer(struct snd_soc_component
*comp
,
251 struct snd_pcm_substream
*stream
)
253 struct pdm_stream_instance
*rtd
;
257 rtd
= stream
->runtime
->private_data
;
258 buffersize
= frames_to_bytes(stream
->runtime
,
259 stream
->runtime
->buffer_size
);
260 bytescount
= acp63_pdm_get_byte_count(rtd
, stream
->stream
);
261 if (bytescount
> rtd
->bytescount
)
262 bytescount
-= rtd
->bytescount
;
263 pos
= do_div(bytescount
, buffersize
);
264 return bytes_to_frames(stream
->runtime
, pos
);
267 static int acp63_pdm_dma_new(struct snd_soc_component
*component
,
268 struct snd_soc_pcm_runtime
*rtd
)
270 struct device
*parent
= component
->dev
->parent
;
272 snd_pcm_set_managed_buffer_all(rtd
->pcm
, SNDRV_DMA_TYPE_DEV
,
273 parent
, MIN_BUFFER
, MAX_BUFFER
);
277 static int acp63_pdm_dma_close(struct snd_soc_component
*component
,
278 struct snd_pcm_substream
*substream
)
280 struct pdm_dev_data
*adata
= dev_get_drvdata(component
->dev
);
281 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
283 acp63_disable_pdm_interrupts(adata
);
284 adata
->capture_stream
= NULL
;
285 kfree(runtime
->private_data
);
289 static int acp63_pdm_dai_trigger(struct snd_pcm_substream
*substream
,
290 int cmd
, struct snd_soc_dai
*dai
)
292 struct pdm_stream_instance
*rtd
;
295 unsigned int ch_mask
;
297 rtd
= substream
->runtime
->private_data
;
299 switch (substream
->runtime
->channels
) {
307 case SNDRV_PCM_TRIGGER_START
:
308 case SNDRV_PCM_TRIGGER_RESUME
:
309 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
310 writel(ch_mask
, rtd
->acp63_base
+ ACP_WOV_PDM_NO_OF_CHANNELS
);
311 writel(PDM_DECIMATION_FACTOR
, rtd
->acp63_base
+ ACP_WOV_PDM_DECIMATION_FACTOR
);
312 rtd
->bytescount
= acp63_pdm_get_byte_count(rtd
, substream
->stream
);
313 pdm_status
= acp63_check_pdm_dma_status(rtd
->acp63_base
);
315 ret
= acp63_start_pdm_dma(rtd
->acp63_base
);
317 case SNDRV_PCM_TRIGGER_STOP
:
318 case SNDRV_PCM_TRIGGER_SUSPEND
:
319 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
320 pdm_status
= acp63_check_pdm_dma_status(rtd
->acp63_base
);
322 ret
= acp63_stop_pdm_dma(rtd
->acp63_base
);
331 static const struct snd_soc_dai_ops acp63_pdm_dai_ops
= {
332 .trigger
= acp63_pdm_dai_trigger
,
335 static struct snd_soc_dai_driver acp63_pdm_dai_driver
= {
336 .name
= "acp_ps_pdm_dma.0",
338 .rates
= SNDRV_PCM_RATE_48000
,
339 .formats
= SNDRV_PCM_FMTBIT_S32_LE
,
345 .ops
= &acp63_pdm_dai_ops
,
348 static const struct snd_soc_component_driver acp63_pdm_component
= {
350 .open
= acp63_pdm_dma_open
,
351 .close
= acp63_pdm_dma_close
,
352 .hw_params
= acp63_pdm_dma_hw_params
,
353 .pointer
= acp63_pdm_dma_pointer
,
354 .pcm_construct
= acp63_pdm_dma_new
,
357 static int acp63_pdm_audio_probe(struct platform_device
*pdev
)
359 struct resource
*res
;
360 struct pdm_dev_data
*adata
;
361 struct acp63_dev_data
*acp_data
;
362 struct device
*parent
;
365 parent
= pdev
->dev
.parent
;
366 acp_data
= dev_get_drvdata(parent
);
367 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
369 dev_err(&pdev
->dev
, "IORESOURCE_MEM FAILED\n");
373 adata
= devm_kzalloc(&pdev
->dev
, sizeof(*adata
), GFP_KERNEL
);
377 adata
->acp63_base
= devm_ioremap(&pdev
->dev
, res
->start
, resource_size(res
));
378 if (!adata
->acp63_base
)
381 adata
->capture_stream
= NULL
;
382 adata
->acp_lock
= &acp_data
->acp_lock
;
383 dev_set_drvdata(&pdev
->dev
, adata
);
384 status
= devm_snd_soc_register_component(&pdev
->dev
,
385 &acp63_pdm_component
,
386 &acp63_pdm_dai_driver
, 1);
388 dev_err(&pdev
->dev
, "Fail to register acp pdm dai\n");
392 pm_runtime_set_autosuspend_delay(&pdev
->dev
, ACP_SUSPEND_DELAY_MS
);
393 pm_runtime_use_autosuspend(&pdev
->dev
);
394 pm_runtime_mark_last_busy(&pdev
->dev
);
395 pm_runtime_set_active(&pdev
->dev
);
396 pm_runtime_enable(&pdev
->dev
);
400 static void acp63_pdm_audio_remove(struct platform_device
*pdev
)
402 pm_runtime_disable(&pdev
->dev
);
405 static int __maybe_unused
acp63_pdm_resume(struct device
*dev
)
407 struct pdm_dev_data
*adata
;
408 struct snd_pcm_runtime
*runtime
;
409 struct pdm_stream_instance
*rtd
;
410 u32 period_bytes
, buffer_len
;
412 adata
= dev_get_drvdata(dev
);
413 if (adata
->capture_stream
&& adata
->capture_stream
->runtime
) {
414 runtime
= adata
->capture_stream
->runtime
;
415 rtd
= runtime
->private_data
;
416 period_bytes
= frames_to_bytes(runtime
, runtime
->period_size
);
417 buffer_len
= frames_to_bytes(runtime
, runtime
->buffer_size
);
418 acp63_config_dma(rtd
, SNDRV_PCM_STREAM_CAPTURE
);
419 acp63_init_pdm_ring_buffer(PDM_MEM_WINDOW_START
, buffer_len
,
420 period_bytes
, adata
->acp63_base
);
422 acp63_enable_pdm_interrupts(adata
);
426 static int __maybe_unused
acp63_pdm_suspend(struct device
*dev
)
428 struct pdm_dev_data
*adata
;
430 adata
= dev_get_drvdata(dev
);
431 acp63_disable_pdm_interrupts(adata
);
435 static int __maybe_unused
acp63_pdm_runtime_resume(struct device
*dev
)
437 struct pdm_dev_data
*adata
;
439 adata
= dev_get_drvdata(dev
);
440 acp63_enable_pdm_interrupts(adata
);
444 static const struct dev_pm_ops acp63_pdm_pm_ops
= {
445 SET_RUNTIME_PM_OPS(acp63_pdm_suspend
, acp63_pdm_runtime_resume
, NULL
)
446 SET_SYSTEM_SLEEP_PM_OPS(acp63_pdm_suspend
, acp63_pdm_resume
)
449 static struct platform_driver acp63_pdm_dma_driver
= {
450 .probe
= acp63_pdm_audio_probe
,
451 .remove
= acp63_pdm_audio_remove
,
453 .name
= "acp_ps_pdm_dma",
454 .pm
= &acp63_pdm_pm_ops
,
458 module_platform_driver(acp63_pdm_dma_driver
);
460 MODULE_AUTHOR("Syed.SabaKareem@amd.com");
461 MODULE_DESCRIPTION("AMD PINK SARDINE PDM Driver");
462 MODULE_LICENSE("GPL v2");
463 MODULE_ALIAS("platform:" DRV_NAME
);