1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * AMD ALSA SoC common SoundWire DMA Driver for ACP6.3, ACP7.0 and ACP7.1
4 * platforms.
5 *
6 * Copyright 2023, 2025 Advanced Micro Devices, Inc.
7 */
8
9 #include <linux/err.h>
10 #include <linux/io.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc.h>
15 #include <sound/soc-dai.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/soundwire/sdw_amd.h>
18 #include "acp63.h"
19
20 #define DRV_NAME "amd_ps_sdw_dma"
21
22 static struct sdw_dma_ring_buf_reg acp63_sdw0_dma_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
23 {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE,
24 ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE,
25 ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH},
26 {ACP_AUDIO1_TX_DMA_SIZE, ACP_AUDIO1_TX_FIFOADDR, ACP_AUDIO1_TX_FIFOSIZE,
27 ACP_AUDIO1_TX_RINGBUFSIZE, ACP_AUDIO1_TX_RINGBUFADDR, ACP_AUDIO1_TX_INTR_WATERMARK_SIZE,
28 ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
29 {ACP_AUDIO2_TX_DMA_SIZE, ACP_AUDIO2_TX_FIFOADDR, ACP_AUDIO2_TX_FIFOSIZE,
30 ACP_AUDIO2_TX_RINGBUFSIZE, ACP_AUDIO2_TX_RINGBUFADDR, ACP_AUDIO2_TX_INTR_WATERMARK_SIZE,
31 ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH},
32 {ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE,
33 ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE,
34 ACP_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH},
35 {ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE,
36 ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE,
37 ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
38 {ACP_AUDIO2_RX_DMA_SIZE, ACP_AUDIO2_RX_FIFOADDR, ACP_AUDIO2_RX_FIFOSIZE,
39 ACP_AUDIO2_RX_RINGBUFSIZE, ACP_AUDIO2_RX_RINGBUFADDR, ACP_AUDIO2_RX_INTR_WATERMARK_SIZE,
40 ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH}
41 };
42
43 /*
44 * SDW1 instance supports one TX stream and one RX stream.
45 * For TX/RX streams DMA registers programming for SDW1 instance, it uses ACP_P1_AUDIO1 register
46 * set as per hardware register documentation
47 */
48 static struct sdw_dma_ring_buf_reg acp63_sdw1_dma_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
49 {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE,
50 ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR,
51 ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE,
52 ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
53 {ACP_P1_AUDIO1_RX_DMA_SIZE, ACP_P1_AUDIO1_RX_FIFOADDR, ACP_P1_AUDIO1_RX_FIFOSIZE,
54 ACP_P1_AUDIO1_RX_RINGBUFSIZE, ACP_P1_AUDIO1_RX_RINGBUFADDR,
55 ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE,
56 ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
57 };
58
59 static u32 acp63_sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = {
60 ACP_SW0_AUDIO0_TX_EN,
61 ACP_SW0_AUDIO1_TX_EN,
62 ACP_SW0_AUDIO2_TX_EN,
63 ACP_SW0_AUDIO0_RX_EN,
64 ACP_SW0_AUDIO1_RX_EN,
65 ACP_SW0_AUDIO2_RX_EN,
66 };
67
68 /*
69 * SDW1 instance supports one TX stream and one RX stream.
70 * For TX/RX streams DMA enable register programming for SDW1 instance,
71 * it uses ACP_SW1_AUDIO1_TX_EN and ACP_SW1_AUDIO1_RX_EN registers
72 * as per hardware register documentation.
73 */
74 static u32 acp63_sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = {
75 ACP_SW1_AUDIO1_TX_EN,
76 ACP_SW1_AUDIO1_RX_EN,
77 };
78
79 static struct sdw_dma_ring_buf_reg acp70_sdw0_dma_reg[ACP70_SDW0_DMA_MAX_STREAMS] = {
80 {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE,
81 ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE,
82 ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH},
83 {ACP_AUDIO1_TX_DMA_SIZE, ACP_AUDIO1_TX_FIFOADDR, ACP_AUDIO1_TX_FIFOSIZE,
84 ACP_AUDIO1_TX_RINGBUFSIZE, ACP_AUDIO1_TX_RINGBUFADDR, ACP_AUDIO1_TX_INTR_WATERMARK_SIZE,
85 ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
86 {ACP_AUDIO2_TX_DMA_SIZE, ACP_AUDIO2_TX_FIFOADDR, ACP_AUDIO2_TX_FIFOSIZE,
87 ACP_AUDIO2_TX_RINGBUFSIZE, ACP_AUDIO2_TX_RINGBUFADDR, ACP_AUDIO2_TX_INTR_WATERMARK_SIZE,
88 ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH},
89 {ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE,
90 ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE,
91 ACP_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH},
92 {ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE,
93 ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE,
94 ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
95 {ACP_AUDIO2_RX_DMA_SIZE, ACP_AUDIO2_RX_FIFOADDR, ACP_AUDIO2_RX_FIFOSIZE,
96 ACP_AUDIO2_RX_RINGBUFSIZE, ACP_AUDIO2_RX_RINGBUFADDR, ACP_AUDIO2_RX_INTR_WATERMARK_SIZE,
97 ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH}
98 };
99
100 static struct sdw_dma_ring_buf_reg acp70_sdw1_dma_reg[ACP70_SDW1_DMA_MAX_STREAMS] = {
101 {ACP_P1_AUDIO0_TX_DMA_SIZE, ACP_P1_AUDIO0_TX_FIFOADDR, ACP_P1_AUDIO0_TX_FIFOSIZE,
102 ACP_P1_AUDIO0_TX_RINGBUFSIZE, ACP_P1_AUDIO0_TX_RINGBUFADDR,
103 ACP_P1_AUDIO0_TX_INTR_WATERMARK_SIZE,
104 ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH},
105 {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE,
106 ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR,
107 ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE,
108 ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH},
109 {ACP_P1_AUDIO2_TX_DMA_SIZE, ACP_P1_AUDIO2_TX_FIFOADDR, ACP_P1_AUDIO2_TX_FIFOSIZE,
110 ACP_P1_AUDIO2_TX_RINGBUFSIZE, ACP_P1_AUDIO2_TX_RINGBUFADDR,
111 ACP_P1_AUDIO2_TX_INTR_WATERMARK_SIZE,
112 ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH},
113 {ACP_P1_AUDIO0_RX_DMA_SIZE, ACP_P1_AUDIO0_RX_FIFOADDR, ACP_P1_AUDIO0_RX_FIFOSIZE,
114 ACP_P1_AUDIO0_RX_RINGBUFSIZE, ACP_P1_AUDIO0_RX_RINGBUFADDR,
115 ACP_P1_AUDIO0_RX_INTR_WATERMARK_SIZE,
116 ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH},
117 {ACP_P1_AUDIO1_RX_DMA_SIZE, ACP_P1_AUDIO1_RX_FIFOADDR, ACP_P1_AUDIO1_RX_FIFOSIZE,
118 ACP_P1_AUDIO1_RX_RINGBUFSIZE, ACP_P1_AUDIO1_RX_RINGBUFADDR,
119 ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE,
120 ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH},
121 {ACP_P1_AUDIO2_RX_DMA_SIZE, ACP_P1_AUDIO2_RX_FIFOADDR, ACP_P1_AUDIO2_RX_FIFOSIZE,
122 ACP_P1_AUDIO2_RX_RINGBUFSIZE, ACP_P1_AUDIO2_RX_RINGBUFADDR,
123 ACP_P1_AUDIO2_RX_INTR_WATERMARK_SIZE,
124 ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH}
125 };
126
127 static u32 acp70_sdw0_dma_enable_reg[ACP70_SDW0_DMA_MAX_STREAMS] = {
128 ACP70_SW0_AUDIO0_TX_EN,
129 ACP70_SW0_AUDIO1_TX_EN,
130 ACP70_SW0_AUDIO2_TX_EN,
131 ACP70_SW0_AUDIO0_RX_EN,
132 ACP70_SW0_AUDIO1_RX_EN,
133 ACP70_SW0_AUDIO2_RX_EN,
134 };
135
136 static u32 acp70_sdw1_dma_enable_reg[ACP70_SDW1_DMA_MAX_STREAMS] = {
137 ACP70_SW1_AUDIO0_TX_EN,
138 ACP70_SW1_AUDIO1_TX_EN,
139 ACP70_SW1_AUDIO2_TX_EN,
140 ACP70_SW1_AUDIO0_RX_EN,
141 ACP70_SW1_AUDIO1_RX_EN,
142 ACP70_SW1_AUDIO2_RX_EN,
143 };
144
145 static const struct snd_pcm_hardware acp63_sdw_hardware_playback = {
146 .info = SNDRV_PCM_INFO_INTERLEAVED |
147 SNDRV_PCM_INFO_BLOCK_TRANSFER |
148 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
149 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
150 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
151 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
152 .channels_min = 2,
153 .channels_max = 2,
154 .rates = SNDRV_PCM_RATE_48000,
155 .rate_min = 48000,
156 .rate_max = 48000,
157 .buffer_bytes_max = SDW_PLAYBACK_MAX_NUM_PERIODS * SDW_PLAYBACK_MAX_PERIOD_SIZE,
158 .period_bytes_min = SDW_PLAYBACK_MIN_PERIOD_SIZE,
159 .period_bytes_max = SDW_PLAYBACK_MAX_PERIOD_SIZE,
160 .periods_min = SDW_PLAYBACK_MIN_NUM_PERIODS,
161 .periods_max = SDW_PLAYBACK_MAX_NUM_PERIODS,
162 };
163
164 static const struct snd_pcm_hardware acp63_sdw_hardware_capture = {
165 .info = SNDRV_PCM_INFO_INTERLEAVED |
166 SNDRV_PCM_INFO_BLOCK_TRANSFER |
167 SNDRV_PCM_INFO_MMAP |
168 SNDRV_PCM_INFO_MMAP_VALID |
169 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
170 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
171 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
172 .channels_min = 2,
173 .channels_max = 2,
174 .rates = SNDRV_PCM_RATE_48000,
175 .rate_min = 48000,
176 .rate_max = 48000,
177 .buffer_bytes_max = SDW_CAPTURE_MAX_NUM_PERIODS * SDW_CAPTURE_MAX_PERIOD_SIZE,
178 .period_bytes_min = SDW_CAPTURE_MIN_PERIOD_SIZE,
179 .period_bytes_max = SDW_CAPTURE_MAX_PERIOD_SIZE,
180 .periods_min = SDW_CAPTURE_MIN_NUM_PERIODS,
181 .periods_max = SDW_CAPTURE_MAX_NUM_PERIODS,
182 };
183
acp63_enable_disable_sdw_dma_interrupts(void __iomem * acp_base,u32 irq_mask,u32 irq_mask1,bool enable)184 static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, u32 irq_mask,
185 u32 irq_mask1, bool enable)
186 {
187 u32 ext_intr_cntl, ext_intr_cntl1;
188
189 if (enable) {
190 ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
191 ext_intr_cntl |= irq_mask;
192 writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL);
193 ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1);
194 ext_intr_cntl1 |= irq_mask1;
195 writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1);
196 } else {
197 ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
198 ext_intr_cntl &= ~irq_mask;
199 writel(ext_intr_cntl, acp_base + ACP_EXTERNAL_INTR_CNTL);
200 ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1);
201 ext_intr_cntl1 &= ~irq_mask1;
202 writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1);
203 }
204 }
205
acp63_config_dma(struct acp_sdw_dma_stream * stream,void __iomem * acp_base,u32 stream_id)206 static void acp63_config_dma(struct acp_sdw_dma_stream *stream, void __iomem *acp_base,
207 u32 stream_id)
208 {
209 u16 page_idx;
210 u32 low, high, val;
211 u32 sdw_dma_pte_offset;
212 dma_addr_t addr;
213
214 addr = stream->dma_addr;
215 sdw_dma_pte_offset = SDW_PTE_OFFSET(stream->instance);
216 val = sdw_dma_pte_offset + (stream_id * ACP_SDW_PTE_OFFSET);
217
218 /* Group Enable */
219 writel(ACP_SDW_SRAM_PTE_OFFSET | BIT(31), acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2);
220 writel(PAGE_SIZE_4K_ENABLE, acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2);
221 for (page_idx = 0; page_idx < stream->num_pages; page_idx++) {
222 /* Load the low address of page int ACP SRAM through SRBM */
223 low = lower_32_bits(addr);
224 high = upper_32_bits(addr);
225
226 writel(low, acp_base + ACP_SCRATCH_REG_0 + val);
227 high |= BIT(31);
228 writel(high, acp_base + ACP_SCRATCH_REG_0 + val + 4);
229 val += 8;
230 addr += PAGE_SIZE;
231 }
232 writel(0x1, acp_base + ACPAXI2AXI_ATU_CTRL);
233 }
234
acp63_configure_sdw_ringbuffer(void __iomem * acp_base,u32 stream_id,u32 size,u32 manager_instance,u32 acp_rev)235 static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 size,
236 u32 manager_instance, u32 acp_rev)
237 {
238 u32 reg_dma_size;
239 u32 reg_fifo_addr;
240 u32 reg_fifo_size;
241 u32 reg_ring_buf_size;
242 u32 reg_ring_buf_addr;
243 u32 sdw_fifo_addr;
244 u32 sdw_fifo_offset;
245 u32 sdw_ring_buf_addr;
246 u32 sdw_ring_buf_size;
247 u32 sdw_mem_window_offset;
248
249 switch (acp_rev) {
250 case ACP63_PCI_REV:
251 switch (manager_instance) {
252 case ACP_SDW0:
253 reg_dma_size = acp63_sdw0_dma_reg[stream_id].reg_dma_size;
254 reg_fifo_addr = acp63_sdw0_dma_reg[stream_id].reg_fifo_addr;
255 reg_fifo_size = acp63_sdw0_dma_reg[stream_id].reg_fifo_size;
256 reg_ring_buf_size = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_size;
257 reg_ring_buf_addr = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_addr;
258 break;
259 case ACP_SDW1:
260 reg_dma_size = acp63_sdw1_dma_reg[stream_id].reg_dma_size;
261 reg_fifo_addr = acp63_sdw1_dma_reg[stream_id].reg_fifo_addr;
262 reg_fifo_size = acp63_sdw1_dma_reg[stream_id].reg_fifo_size;
263 reg_ring_buf_size = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_size;
264 reg_ring_buf_addr = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_addr;
265 break;
266 default:
267 return -EINVAL;
268 }
269 break;
270 case ACP70_PCI_REV:
271 case ACP71_PCI_REV:
272 switch (manager_instance) {
273 case ACP_SDW0:
274 reg_dma_size = acp70_sdw0_dma_reg[stream_id].reg_dma_size;
275 reg_fifo_addr = acp70_sdw0_dma_reg[stream_id].reg_fifo_addr;
276 reg_fifo_size = acp70_sdw0_dma_reg[stream_id].reg_fifo_size;
277 reg_ring_buf_size = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_size;
278 reg_ring_buf_addr = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_addr;
279 break;
280 case ACP_SDW1:
281 reg_dma_size = acp70_sdw1_dma_reg[stream_id].reg_dma_size;
282 reg_fifo_addr = acp70_sdw1_dma_reg[stream_id].reg_fifo_addr;
283 reg_fifo_size = acp70_sdw1_dma_reg[stream_id].reg_fifo_size;
284 reg_ring_buf_size = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_size;
285 reg_ring_buf_addr = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_addr;
286 break;
287 default:
288 return -EINVAL;
289 }
290 break;
291 default:
292 return -EINVAL;
293 }
294 sdw_fifo_offset = ACP_SDW_FIFO_OFFSET(manager_instance);
295 sdw_mem_window_offset = SDW_MEM_WINDOW_START(manager_instance);
296 sdw_fifo_addr = sdw_fifo_offset + (stream_id * SDW_FIFO_OFFSET);
297 sdw_ring_buf_addr = sdw_mem_window_offset + (stream_id * ACP_SDW_RING_BUFF_ADDR_OFFSET);
298 sdw_ring_buf_size = size;
299 writel(sdw_ring_buf_size, acp_base + reg_ring_buf_size);
300 writel(sdw_ring_buf_addr, acp_base + reg_ring_buf_addr);
301 writel(sdw_fifo_addr, acp_base + reg_fifo_addr);
302 writel(SDW_DMA_SIZE, acp_base + reg_dma_size);
303 writel(SDW_FIFO_SIZE, acp_base + reg_fifo_size);
304 return 0;
305 }
306
acp63_sdw_dma_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)307 static int acp63_sdw_dma_open(struct snd_soc_component *component,
308 struct snd_pcm_substream *substream)
309 {
310 struct snd_pcm_runtime *runtime;
311 struct acp_sdw_dma_stream *stream;
312 struct snd_soc_dai *cpu_dai;
313 struct amd_sdw_manager *amd_manager;
314 struct snd_soc_pcm_runtime *prtd = snd_soc_substream_to_rtd(substream);
315 int ret;
316
317 runtime = substream->runtime;
318 cpu_dai = snd_soc_rtd_to_cpu(prtd, 0);
319 amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
320 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
321 if (!stream)
322 return -ENOMEM;
323
324 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
325 runtime->hw = acp63_sdw_hardware_playback;
326 else
327 runtime->hw = acp63_sdw_hardware_capture;
328 ret = snd_pcm_hw_constraint_integer(runtime,
329 SNDRV_PCM_HW_PARAM_PERIODS);
330 if (ret < 0) {
331 dev_err(component->dev, "set integer constraint failed\n");
332 kfree(stream);
333 return ret;
334 }
335
336 stream->stream_id = cpu_dai->id;
337 stream->instance = amd_manager->instance;
338 runtime->private_data = stream;
339 return ret;
340 }
341
acp63_sdw_dma_hw_params(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)342 static int acp63_sdw_dma_hw_params(struct snd_soc_component *component,
343 struct snd_pcm_substream *substream,
344 struct snd_pcm_hw_params *params)
345 {
346 struct acp_sdw_dma_stream *stream;
347 struct sdw_dma_dev_data *sdw_data;
348 u32 period_bytes;
349 u32 water_mark_size_reg;
350 u32 irq_mask, ext_intr_ctrl;
351 u64 size;
352 u32 stream_id;
353 u32 acp_ext_intr_cntl_reg;
354 int ret;
355
356 sdw_data = dev_get_drvdata(component->dev);
357 stream = substream->runtime->private_data;
358 if (!stream)
359 return -EINVAL;
360 stream_id = stream->stream_id;
361 switch (sdw_data->acp_rev) {
362 case ACP63_PCI_REV:
363 switch (stream->instance) {
364 case ACP_SDW0:
365 sdw_data->acp63_sdw0_dma_stream[stream_id] = substream;
366 water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg;
367 acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL;
368 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
369 irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id));
370 else
371 irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id));
372 break;
373 case ACP_SDW1:
374 sdw_data->acp63_sdw1_dma_stream[stream_id] = substream;
375 acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1;
376 water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg;
377 irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(stream_id));
378 break;
379 default:
380 return -EINVAL;
381 }
382 break;
383 case ACP70_PCI_REV:
384 case ACP71_PCI_REV:
385 switch (stream->instance) {
386 case ACP_SDW0:
387 sdw_data->acp70_sdw0_dma_stream[stream_id] = substream;
388 water_mark_size_reg = acp70_sdw0_dma_reg[stream_id].water_mark_size_reg;
389 acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL;
390 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
391 irq_mask = BIT(ACP70_SDW0_DMA_TX_IRQ_MASK(stream_id));
392 else
393 irq_mask = BIT(ACP70_SDW0_DMA_RX_IRQ_MASK(stream_id));
394 break;
395 case ACP_SDW1:
396 sdw_data->acp70_sdw1_dma_stream[stream_id] = substream;
397 acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1;
398 water_mark_size_reg = acp70_sdw1_dma_reg[stream_id].water_mark_size_reg;
399 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
400 irq_mask = BIT(ACP70_SDW1_DMA_TX_IRQ_MASK(stream_id));
401 else
402 irq_mask = BIT(ACP70_SDW1_DMA_RX_IRQ_MASK(stream_id));
403
404 break;
405 default:
406 return -EINVAL;
407 }
408 break;
409 default:
410 return -EINVAL;
411 }
412 size = params_buffer_bytes(params);
413 period_bytes = params_period_bytes(params);
414 stream->dma_addr = substream->runtime->dma_addr;
415 stream->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
416 acp63_config_dma(stream, sdw_data->acp_base, stream_id);
417 ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, stream_id, size,
418 stream->instance, sdw_data->acp_rev);
419 if (ret) {
420 dev_err(component->dev, "Invalid DMA channel\n");
421 return -EINVAL;
422 }
423 ext_intr_ctrl = readl(sdw_data->acp_base + acp_ext_intr_cntl_reg);
424 ext_intr_ctrl |= irq_mask;
425 writel(ext_intr_ctrl, sdw_data->acp_base + acp_ext_intr_cntl_reg);
426 writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
427 return 0;
428 }
429
acp63_sdw_get_byte_count(struct acp_sdw_dma_stream * stream,void __iomem * acp_base,u32 acp_rev)430 static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base,
431 u32 acp_rev)
432 {
433 union acp_sdw_dma_count byte_count;
434 u32 pos_low_reg, pos_high_reg;
435
436 byte_count.bytescount = 0;
437 switch (acp_rev) {
438 case ACP63_PCI_REV:
439 switch (stream->instance) {
440 case ACP_SDW0:
441 pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg;
442 pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg;
443 break;
444 case ACP_SDW1:
445 pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg;
446 pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg;
447 break;
448 default:
449 goto POINTER_RETURN_BYTES;
450 }
451 break;
452 case ACP70_PCI_REV:
453 case ACP71_PCI_REV:
454 switch (stream->instance) {
455 case ACP_SDW0:
456 pos_low_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_low_reg;
457 pos_high_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_high_reg;
458 break;
459 case ACP_SDW1:
460 pos_low_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_low_reg;
461 pos_high_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_high_reg;
462 break;
463 default:
464 goto POINTER_RETURN_BYTES;
465 }
466 break;
467 default:
468 goto POINTER_RETURN_BYTES;
469 }
470 if (pos_low_reg) {
471 byte_count.bcount.high = readl(acp_base + pos_high_reg);
472 byte_count.bcount.low = readl(acp_base + pos_low_reg);
473 }
474 POINTER_RETURN_BYTES:
475 return byte_count.bytescount;
476 }
477
acp63_sdw_dma_pointer(struct snd_soc_component * comp,struct snd_pcm_substream * substream)478 static snd_pcm_uframes_t acp63_sdw_dma_pointer(struct snd_soc_component *comp,
479 struct snd_pcm_substream *substream)
480 {
481 struct sdw_dma_dev_data *sdw_data;
482 struct acp_sdw_dma_stream *stream;
483 u32 pos, buffersize;
484 u64 bytescount;
485
486 sdw_data = dev_get_drvdata(comp->dev);
487 stream = substream->runtime->private_data;
488 buffersize = frames_to_bytes(substream->runtime,
489 substream->runtime->buffer_size);
490 bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base, sdw_data->acp_rev);
491 if (bytescount > stream->bytescount)
492 bytescount -= stream->bytescount;
493 pos = do_div(bytescount, buffersize);
494 return bytes_to_frames(substream->runtime, pos);
495 }
496
acp63_sdw_dma_new(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)497 static int acp63_sdw_dma_new(struct snd_soc_component *component,
498 struct snd_soc_pcm_runtime *rtd)
499 {
500 struct device *parent = component->dev->parent;
501
502 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
503 parent, SDW_MIN_BUFFER, SDW_MAX_BUFFER);
504 return 0;
505 }
506
acp63_sdw_dma_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)507 static int acp63_sdw_dma_close(struct snd_soc_component *component,
508 struct snd_pcm_substream *substream)
509 {
510 struct sdw_dma_dev_data *sdw_data;
511 struct acp_sdw_dma_stream *stream;
512
513 sdw_data = dev_get_drvdata(component->dev);
514 stream = substream->runtime->private_data;
515 if (!stream)
516 return -EINVAL;
517 switch (sdw_data->acp_rev) {
518 case ACP63_PCI_REV:
519 switch (stream->instance) {
520 case ACP_SDW0:
521 sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL;
522 break;
523 case ACP_SDW1:
524 sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL;
525 break;
526 default:
527 return -EINVAL;
528 }
529 break;
530 case ACP70_PCI_REV:
531 case ACP71_PCI_REV:
532 switch (stream->instance) {
533 case ACP_SDW0:
534 sdw_data->acp70_sdw0_dma_stream[stream->stream_id] = NULL;
535 break;
536 case ACP_SDW1:
537 sdw_data->acp70_sdw1_dma_stream[stream->stream_id] = NULL;
538 break;
539 default:
540 return -EINVAL;
541 }
542 break;
543 default:
544 return -EINVAL;
545 }
546 kfree(stream);
547 return 0;
548 }
549
acp63_sdw_dma_enable(struct snd_pcm_substream * substream,void __iomem * acp_base,u32 acp_rev,bool sdw_dma_enable)550 static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,
551 void __iomem *acp_base, u32 acp_rev, bool sdw_dma_enable)
552 {
553 struct acp_sdw_dma_stream *stream;
554 u32 stream_id;
555 u32 sdw_dma_en_reg;
556 u32 sdw_dma_en_stat_reg;
557 u32 sdw_dma_stat;
558 u32 dma_enable;
559
560 stream = substream->runtime->private_data;
561 stream_id = stream->stream_id;
562 switch (acp_rev) {
563 case ACP63_PCI_REV:
564 switch (stream->instance) {
565 case ACP_SDW0:
566 sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id];
567 break;
568 case ACP_SDW1:
569 sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[stream_id];
570 break;
571 default:
572 return -EINVAL;
573 }
574 break;
575 case ACP70_PCI_REV:
576 case ACP71_PCI_REV:
577 switch (stream->instance) {
578 case ACP_SDW0:
579 sdw_dma_en_reg = acp70_sdw0_dma_enable_reg[stream_id];
580 break;
581 case ACP_SDW1:
582 sdw_dma_en_reg = acp70_sdw1_dma_enable_reg[stream_id];
583 break;
584 default:
585 return -EINVAL;
586 }
587 break;
588 default:
589 return -EINVAL;
590 }
591 sdw_dma_en_stat_reg = sdw_dma_en_reg + 4;
592 dma_enable = sdw_dma_enable;
593 writel(dma_enable, acp_base + sdw_dma_en_reg);
594 return readl_poll_timeout(acp_base + sdw_dma_en_stat_reg, sdw_dma_stat,
595 (sdw_dma_stat == dma_enable), ACP_DELAY_US, ACP_COUNTER);
596 }
597
acp63_sdw_dma_trigger(struct snd_soc_component * comp,struct snd_pcm_substream * substream,int cmd)598 static int acp63_sdw_dma_trigger(struct snd_soc_component *comp,
599 struct snd_pcm_substream *substream,
600 int cmd)
601 {
602 struct sdw_dma_dev_data *sdw_data;
603 int ret;
604
605 sdw_data = dev_get_drvdata(comp->dev);
606 switch (cmd) {
607 case SNDRV_PCM_TRIGGER_START:
608 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
609 case SNDRV_PCM_TRIGGER_RESUME:
610 ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, true);
611 break;
612 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
613 case SNDRV_PCM_TRIGGER_SUSPEND:
614 case SNDRV_PCM_TRIGGER_STOP:
615 ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, false);
616 break;
617 default:
618 ret = -EINVAL;
619 }
620 if (ret)
621 dev_err(comp->dev, "trigger %d failed: %d", cmd, ret);
622 return ret;
623 }
624
625 static const struct snd_soc_component_driver acp63_sdw_component = {
626 .name = DRV_NAME,
627 .open = acp63_sdw_dma_open,
628 .close = acp63_sdw_dma_close,
629 .hw_params = acp63_sdw_dma_hw_params,
630 .trigger = acp63_sdw_dma_trigger,
631 .pointer = acp63_sdw_dma_pointer,
632 .pcm_construct = acp63_sdw_dma_new,
633 .use_dai_pcm_id = true,
634
635 };
636
acp63_sdw_platform_probe(struct platform_device * pdev)637 static int acp63_sdw_platform_probe(struct platform_device *pdev)
638 {
639 struct resource *res;
640 struct sdw_dma_dev_data *sdw_data;
641 struct acp63_dev_data *acp_data;
642 struct device *parent;
643 int status;
644
645 parent = pdev->dev.parent;
646 acp_data = dev_get_drvdata(parent);
647 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
648 if (!res) {
649 dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
650 return -ENODEV;
651 }
652
653 sdw_data = devm_kzalloc(&pdev->dev, sizeof(*sdw_data), GFP_KERNEL);
654 if (!sdw_data)
655 return -ENOMEM;
656
657 sdw_data->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
658 if (!sdw_data->acp_base)
659 return -ENOMEM;
660
661 sdw_data->acp_lock = &acp_data->acp_lock;
662 sdw_data->acp_rev = acp_data->acp_rev;
663 dev_set_drvdata(&pdev->dev, sdw_data);
664 status = devm_snd_soc_register_component(&pdev->dev,
665 &acp63_sdw_component,
666 NULL, 0);
667 if (status) {
668 dev_err(&pdev->dev, "Fail to register sdw dma component\n");
669 return status;
670 }
671 pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
672 pm_runtime_use_autosuspend(&pdev->dev);
673 pm_runtime_mark_last_busy(&pdev->dev);
674 pm_runtime_set_active(&pdev->dev);
675 pm_runtime_enable(&pdev->dev);
676 return 0;
677 }
678
acp63_sdw_platform_remove(struct platform_device * pdev)679 static void acp63_sdw_platform_remove(struct platform_device *pdev)
680 {
681 pm_runtime_disable(&pdev->dev);
682 }
683
acp63_restore_sdw_dma_config(struct sdw_dma_dev_data * sdw_data)684 static int acp63_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
685 {
686 struct acp_sdw_dma_stream *stream;
687 struct snd_pcm_substream *substream;
688 struct snd_pcm_runtime *runtime;
689 u32 period_bytes, buf_size, water_mark_size_reg;
690 u32 stream_count, irq_mask, irq_mask1;
691 int index, instance, ret;
692
693 irq_mask = ACP63_SDW_DMA_IRQ_MASK;
694 irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK;
695 for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) {
696 if (instance == ACP_SDW0)
697 stream_count = ACP63_SDW0_DMA_MAX_STREAMS;
698 else
699 stream_count = ACP63_SDW1_DMA_MAX_STREAMS;
700
701 for (index = 0; index < stream_count; index++) {
702 if (instance == ACP_SDW0) {
703 substream = sdw_data->acp63_sdw0_dma_stream[index];
704 water_mark_size_reg = acp63_sdw0_dma_reg[index].water_mark_size_reg;
705 } else {
706 substream = sdw_data->acp63_sdw1_dma_stream[index];
707 water_mark_size_reg = acp63_sdw1_dma_reg[index].water_mark_size_reg;
708 }
709
710 if (substream && substream->runtime) {
711 runtime = substream->runtime;
712 stream = runtime->private_data;
713 period_bytes = frames_to_bytes(runtime, runtime->period_size);
714 buf_size = frames_to_bytes(runtime, runtime->buffer_size);
715 acp63_config_dma(stream, sdw_data->acp_base, index);
716 ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index,
717 buf_size, instance,
718 ACP63_PCI_REV);
719 if (ret)
720 return ret;
721 writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
722 }
723 }
724 }
725 acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true);
726 return 0;
727 }
728
acp70_restore_sdw_dma_config(struct sdw_dma_dev_data * sdw_data)729 static int acp70_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
730 {
731 struct acp_sdw_dma_stream *stream;
732 struct snd_pcm_substream *substream;
733 struct snd_pcm_runtime *runtime;
734 u32 period_bytes, buf_size, water_mark_size_reg;
735 u32 stream_count, irq_mask, irq_mask1;
736 int index, instance, ret;
737
738 irq_mask = ACP70_SDW_DMA_IRQ_MASK;
739 irq_mask1 = ACP70_P1_SDW_DMA_IRQ_MASK;
740 stream_count = ACP70_SDW0_DMA_MAX_STREAMS;
741 for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) {
742 for (index = 0; index < stream_count; index++) {
743 if (instance == ACP_SDW0) {
744 substream = sdw_data->acp70_sdw0_dma_stream[index];
745 water_mark_size_reg = acp70_sdw0_dma_reg[index].water_mark_size_reg;
746 } else {
747 substream = sdw_data->acp70_sdw1_dma_stream[index];
748 water_mark_size_reg = acp70_sdw1_dma_reg[index].water_mark_size_reg;
749 }
750
751 if (substream && substream->runtime) {
752 runtime = substream->runtime;
753 stream = runtime->private_data;
754 period_bytes = frames_to_bytes(runtime, runtime->period_size);
755 buf_size = frames_to_bytes(runtime, runtime->buffer_size);
756 acp63_config_dma(stream, sdw_data->acp_base, index);
757 ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index,
758 buf_size, instance,
759 sdw_data->acp_rev);
760 if (ret)
761 return ret;
762 writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
763 }
764 }
765 }
766 acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true);
767 return 0;
768 }
769
acp63_sdw_pcm_resume(struct device * dev)770 static int acp63_sdw_pcm_resume(struct device *dev)
771 {
772 struct sdw_dma_dev_data *sdw_data;
773
774 sdw_data = dev_get_drvdata(dev);
775 if (sdw_data->acp_rev == ACP63_PCI_REV)
776 return acp63_restore_sdw_dma_config(sdw_data);
777 else
778 return acp70_restore_sdw_dma_config(sdw_data);
779 }
780
781 static const struct dev_pm_ops acp63_pm_ops = {
782 SYSTEM_SLEEP_PM_OPS(NULL, acp63_sdw_pcm_resume)
783 };
784
785 static struct platform_driver acp63_sdw_dma_driver = {
786 .probe = acp63_sdw_platform_probe,
787 .remove = acp63_sdw_platform_remove,
788 .driver = {
789 .name = "amd_ps_sdw_dma",
790 .pm = pm_ptr(&acp63_pm_ops),
791 },
792 };
793
794 module_platform_driver(acp63_sdw_dma_driver);
795
796 MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
797 MODULE_DESCRIPTION("AMD common SDW DMA Driver for ACP6.3, ACP7.0 & ACP7.1 platforms");
798 MODULE_LICENSE("GPL");
799 MODULE_ALIAS("platform:" DRV_NAME);
800