xref: /linux/sound/soc/amd/ps/ps-sdw-dma.c (revision f09fc24dd9a5ec989dfdde7090624924ede6ddc7)
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 
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 
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 
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 	case ACP72_PCI_REV:
273 		switch (manager_instance) {
274 		case ACP_SDW0:
275 			reg_dma_size = acp70_sdw0_dma_reg[stream_id].reg_dma_size;
276 			reg_fifo_addr =	acp70_sdw0_dma_reg[stream_id].reg_fifo_addr;
277 			reg_fifo_size = acp70_sdw0_dma_reg[stream_id].reg_fifo_size;
278 			reg_ring_buf_size = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_size;
279 			reg_ring_buf_addr = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_addr;
280 			break;
281 		case ACP_SDW1:
282 			reg_dma_size = acp70_sdw1_dma_reg[stream_id].reg_dma_size;
283 			reg_fifo_addr =	acp70_sdw1_dma_reg[stream_id].reg_fifo_addr;
284 			reg_fifo_size = acp70_sdw1_dma_reg[stream_id].reg_fifo_size;
285 			reg_ring_buf_size = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_size;
286 			reg_ring_buf_addr = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_addr;
287 			break;
288 		default:
289 			return -EINVAL;
290 		}
291 		break;
292 	default:
293 		return -EINVAL;
294 	}
295 	sdw_fifo_offset = ACP_SDW_FIFO_OFFSET(manager_instance);
296 	sdw_mem_window_offset = SDW_MEM_WINDOW_START(manager_instance);
297 	sdw_fifo_addr = sdw_fifo_offset + (stream_id * SDW_FIFO_OFFSET);
298 	sdw_ring_buf_addr = sdw_mem_window_offset + (stream_id * ACP_SDW_RING_BUFF_ADDR_OFFSET);
299 	sdw_ring_buf_size = size;
300 	writel(sdw_ring_buf_size, acp_base + reg_ring_buf_size);
301 	writel(sdw_ring_buf_addr, acp_base + reg_ring_buf_addr);
302 	writel(sdw_fifo_addr, acp_base + reg_fifo_addr);
303 	writel(SDW_DMA_SIZE, acp_base + reg_dma_size);
304 	writel(SDW_FIFO_SIZE, acp_base + reg_fifo_size);
305 	return 0;
306 }
307 
308 static int acp63_sdw_dma_open(struct snd_soc_component *component,
309 			      struct snd_pcm_substream *substream)
310 {
311 	struct snd_pcm_runtime *runtime;
312 	struct acp_sdw_dma_stream *stream;
313 	struct snd_soc_dai *cpu_dai;
314 	struct amd_sdw_manager *amd_manager;
315 	struct snd_soc_pcm_runtime *prtd = snd_soc_substream_to_rtd(substream);
316 	int ret;
317 
318 	runtime = substream->runtime;
319 	cpu_dai = snd_soc_rtd_to_cpu(prtd, 0);
320 	amd_manager = snd_soc_dai_get_drvdata(cpu_dai);
321 	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
322 	if (!stream)
323 		return -ENOMEM;
324 
325 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
326 		runtime->hw = acp63_sdw_hardware_playback;
327 	else
328 		runtime->hw = acp63_sdw_hardware_capture;
329 	ret = snd_pcm_hw_constraint_integer(runtime,
330 					    SNDRV_PCM_HW_PARAM_PERIODS);
331 	if (ret < 0) {
332 		dev_err(component->dev, "set integer constraint failed\n");
333 		kfree(stream);
334 		return ret;
335 	}
336 
337 	stream->stream_id = cpu_dai->id;
338 	stream->instance = amd_manager->instance;
339 	runtime->private_data = stream;
340 	return ret;
341 }
342 
343 static int acp63_sdw_dma_hw_params(struct snd_soc_component *component,
344 				   struct snd_pcm_substream *substream,
345 				   struct snd_pcm_hw_params *params)
346 {
347 	struct acp_sdw_dma_stream *stream;
348 	struct sdw_dma_dev_data *sdw_data;
349 	u32 period_bytes;
350 	u32 water_mark_size_reg;
351 	u32 irq_mask, ext_intr_ctrl;
352 	u64 size;
353 	u32 stream_id;
354 	u32 acp_ext_intr_cntl_reg;
355 	int ret;
356 
357 	sdw_data = dev_get_drvdata(component->dev);
358 	stream = substream->runtime->private_data;
359 	if (!stream)
360 		return -EINVAL;
361 	stream_id = stream->stream_id;
362 	switch (sdw_data->acp_rev) {
363 	case ACP63_PCI_REV:
364 		switch (stream->instance) {
365 		case ACP_SDW0:
366 			sdw_data->acp63_sdw0_dma_stream[stream_id] = substream;
367 			water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg;
368 			acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL;
369 			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
370 				irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id));
371 			else
372 				irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id));
373 			break;
374 		case ACP_SDW1:
375 			sdw_data->acp63_sdw1_dma_stream[stream_id] = substream;
376 			acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1;
377 			water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg;
378 			irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(stream_id));
379 			break;
380 		default:
381 			return -EINVAL;
382 		}
383 		break;
384 	case ACP70_PCI_REV:
385 	case ACP71_PCI_REV:
386 	case ACP72_PCI_REV:
387 		switch (stream->instance) {
388 		case ACP_SDW0:
389 			sdw_data->acp70_sdw0_dma_stream[stream_id] = substream;
390 			water_mark_size_reg = acp70_sdw0_dma_reg[stream_id].water_mark_size_reg;
391 			acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL;
392 			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
393 				irq_mask = BIT(ACP70_SDW0_DMA_TX_IRQ_MASK(stream_id));
394 			else
395 				irq_mask = BIT(ACP70_SDW0_DMA_RX_IRQ_MASK(stream_id));
396 			break;
397 		case ACP_SDW1:
398 			sdw_data->acp70_sdw1_dma_stream[stream_id] = substream;
399 			acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1;
400 			water_mark_size_reg = acp70_sdw1_dma_reg[stream_id].water_mark_size_reg;
401 			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
402 				irq_mask = BIT(ACP70_SDW1_DMA_TX_IRQ_MASK(stream_id));
403 			else
404 				irq_mask = BIT(ACP70_SDW1_DMA_RX_IRQ_MASK(stream_id));
405 
406 			break;
407 		default:
408 			return -EINVAL;
409 		}
410 		break;
411 	default:
412 		return -EINVAL;
413 	}
414 	size = params_buffer_bytes(params);
415 	period_bytes = params_period_bytes(params);
416 	stream->dma_addr = substream->runtime->dma_addr;
417 	stream->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
418 	acp63_config_dma(stream, sdw_data->acp_base, stream_id);
419 	ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, stream_id, size,
420 					     stream->instance, sdw_data->acp_rev);
421 	if (ret) {
422 		dev_err(component->dev, "Invalid DMA channel\n");
423 		return -EINVAL;
424 	}
425 	ext_intr_ctrl = readl(sdw_data->acp_base + acp_ext_intr_cntl_reg);
426 	ext_intr_ctrl |= irq_mask;
427 	writel(ext_intr_ctrl, sdw_data->acp_base + acp_ext_intr_cntl_reg);
428 	writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
429 	return 0;
430 }
431 
432 static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base,
433 				    u32 acp_rev)
434 {
435 	union acp_sdw_dma_count byte_count;
436 	u32 pos_low_reg, pos_high_reg;
437 
438 	byte_count.bytescount = 0;
439 	switch (acp_rev) {
440 	case ACP63_PCI_REV:
441 		switch (stream->instance) {
442 		case ACP_SDW0:
443 			pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg;
444 			pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg;
445 			break;
446 		case ACP_SDW1:
447 			pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg;
448 			pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg;
449 			break;
450 		default:
451 			goto POINTER_RETURN_BYTES;
452 		}
453 		break;
454 	case ACP70_PCI_REV:
455 	case ACP71_PCI_REV:
456 	case ACP72_PCI_REV:
457 		switch (stream->instance) {
458 		case ACP_SDW0:
459 			pos_low_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_low_reg;
460 			pos_high_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_high_reg;
461 			break;
462 		case ACP_SDW1:
463 			pos_low_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_low_reg;
464 			pos_high_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_high_reg;
465 			break;
466 		default:
467 			goto POINTER_RETURN_BYTES;
468 		}
469 		break;
470 	default:
471 		goto POINTER_RETURN_BYTES;
472 	}
473 	if (pos_low_reg) {
474 		byte_count.bcount.high = readl(acp_base + pos_high_reg);
475 		byte_count.bcount.low = readl(acp_base + pos_low_reg);
476 	}
477 POINTER_RETURN_BYTES:
478 	return byte_count.bytescount;
479 }
480 
481 static snd_pcm_uframes_t acp63_sdw_dma_pointer(struct snd_soc_component *comp,
482 					       struct snd_pcm_substream *substream)
483 {
484 	struct sdw_dma_dev_data *sdw_data;
485 	struct acp_sdw_dma_stream *stream;
486 	u32 pos, buffersize;
487 	u64 bytescount;
488 
489 	sdw_data = dev_get_drvdata(comp->dev);
490 	stream = substream->runtime->private_data;
491 	buffersize = frames_to_bytes(substream->runtime,
492 				     substream->runtime->buffer_size);
493 	bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base, sdw_data->acp_rev);
494 	if (bytescount > stream->bytescount)
495 		bytescount -= stream->bytescount;
496 	pos = do_div(bytescount, buffersize);
497 	return bytes_to_frames(substream->runtime, pos);
498 }
499 
500 static int acp63_sdw_dma_new(struct snd_soc_component *component,
501 			     struct snd_soc_pcm_runtime *rtd)
502 {
503 	struct device *parent = component->dev->parent;
504 
505 	snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
506 				       parent, SDW_MIN_BUFFER, SDW_MAX_BUFFER);
507 	return 0;
508 }
509 
510 static int acp63_sdw_dma_close(struct snd_soc_component *component,
511 			       struct snd_pcm_substream *substream)
512 {
513 	struct sdw_dma_dev_data *sdw_data;
514 	struct acp_sdw_dma_stream *stream;
515 
516 	sdw_data = dev_get_drvdata(component->dev);
517 	stream = substream->runtime->private_data;
518 	if (!stream)
519 		return -EINVAL;
520 	switch (sdw_data->acp_rev) {
521 	case ACP63_PCI_REV:
522 		switch (stream->instance) {
523 		case ACP_SDW0:
524 			sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL;
525 			break;
526 		case ACP_SDW1:
527 			sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL;
528 			break;
529 		default:
530 			return -EINVAL;
531 		}
532 		break;
533 	case ACP70_PCI_REV:
534 	case ACP71_PCI_REV:
535 	case ACP72_PCI_REV:
536 		switch (stream->instance) {
537 		case ACP_SDW0:
538 			sdw_data->acp70_sdw0_dma_stream[stream->stream_id] = NULL;
539 			break;
540 		case ACP_SDW1:
541 			sdw_data->acp70_sdw1_dma_stream[stream->stream_id] = NULL;
542 			break;
543 		default:
544 			return -EINVAL;
545 		}
546 		break;
547 	default:
548 		return -EINVAL;
549 	}
550 	kfree(stream);
551 	return 0;
552 }
553 
554 static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream,
555 				void __iomem *acp_base, u32 acp_rev, bool sdw_dma_enable)
556 {
557 	struct acp_sdw_dma_stream *stream;
558 	u32 stream_id;
559 	u32 sdw_dma_en_reg;
560 	u32 sdw_dma_en_stat_reg;
561 	u32 sdw_dma_stat;
562 	u32 dma_enable;
563 
564 	stream = substream->runtime->private_data;
565 	stream_id = stream->stream_id;
566 	switch (acp_rev) {
567 	case ACP63_PCI_REV:
568 		switch (stream->instance) {
569 		case ACP_SDW0:
570 			sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id];
571 			break;
572 		case ACP_SDW1:
573 			sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[stream_id];
574 			break;
575 		default:
576 			return -EINVAL;
577 		}
578 		break;
579 	case ACP70_PCI_REV:
580 	case ACP71_PCI_REV:
581 	case ACP72_PCI_REV:
582 		switch (stream->instance) {
583 		case ACP_SDW0:
584 			sdw_dma_en_reg = acp70_sdw0_dma_enable_reg[stream_id];
585 			break;
586 		case ACP_SDW1:
587 			sdw_dma_en_reg = acp70_sdw1_dma_enable_reg[stream_id];
588 			break;
589 		default:
590 			return -EINVAL;
591 		}
592 		break;
593 	default:
594 		return -EINVAL;
595 	}
596 	sdw_dma_en_stat_reg = sdw_dma_en_reg + 4;
597 	dma_enable = sdw_dma_enable;
598 	writel(dma_enable, acp_base + sdw_dma_en_reg);
599 	return readl_poll_timeout(acp_base + sdw_dma_en_stat_reg, sdw_dma_stat,
600 				  (sdw_dma_stat == dma_enable), ACP_DELAY_US, ACP_COUNTER);
601 }
602 
603 static int acp63_sdw_dma_trigger(struct snd_soc_component *comp,
604 				 struct snd_pcm_substream *substream,
605 				 int cmd)
606 {
607 	struct sdw_dma_dev_data *sdw_data;
608 	int ret;
609 
610 	sdw_data = dev_get_drvdata(comp->dev);
611 	switch (cmd) {
612 	case SNDRV_PCM_TRIGGER_START:
613 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
614 	case SNDRV_PCM_TRIGGER_RESUME:
615 		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, true);
616 		break;
617 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
618 	case SNDRV_PCM_TRIGGER_SUSPEND:
619 	case SNDRV_PCM_TRIGGER_STOP:
620 		ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, false);
621 		break;
622 	default:
623 		ret = -EINVAL;
624 	}
625 	if (ret)
626 		dev_err(comp->dev, "trigger %d failed: %d", cmd, ret);
627 	return ret;
628 }
629 
630 static const struct snd_soc_component_driver acp63_sdw_component = {
631 	.name		= DRV_NAME,
632 	.open		= acp63_sdw_dma_open,
633 	.close		= acp63_sdw_dma_close,
634 	.hw_params	= acp63_sdw_dma_hw_params,
635 	.trigger	= acp63_sdw_dma_trigger,
636 	.pointer	= acp63_sdw_dma_pointer,
637 	.pcm_construct	= acp63_sdw_dma_new,
638 	.use_dai_pcm_id = true,
639 
640 };
641 
642 static int acp63_sdw_platform_probe(struct platform_device *pdev)
643 {
644 	struct resource *res;
645 	struct sdw_dma_dev_data *sdw_data;
646 	struct acp63_dev_data *acp_data;
647 	struct device *parent;
648 	int status;
649 
650 	parent = pdev->dev.parent;
651 	acp_data = dev_get_drvdata(parent);
652 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
653 	if (!res) {
654 		dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
655 		return -ENODEV;
656 	}
657 
658 	sdw_data = devm_kzalloc(&pdev->dev, sizeof(*sdw_data), GFP_KERNEL);
659 	if (!sdw_data)
660 		return -ENOMEM;
661 
662 	sdw_data->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
663 	if (!sdw_data->acp_base)
664 		return -ENOMEM;
665 
666 	sdw_data->acp_lock = &acp_data->acp_lock;
667 	sdw_data->acp_rev = acp_data->acp_rev;
668 	dev_set_drvdata(&pdev->dev, sdw_data);
669 	status = devm_snd_soc_register_component(&pdev->dev,
670 						 &acp63_sdw_component,
671 						 NULL, 0);
672 	if (status) {
673 		dev_err(&pdev->dev, "Fail to register sdw dma component\n");
674 		return status;
675 	}
676 	pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
677 	pm_runtime_use_autosuspend(&pdev->dev);
678 	pm_runtime_mark_last_busy(&pdev->dev);
679 	pm_runtime_set_active(&pdev->dev);
680 	pm_runtime_enable(&pdev->dev);
681 	return 0;
682 }
683 
684 static void acp63_sdw_platform_remove(struct platform_device *pdev)
685 {
686 	pm_runtime_disable(&pdev->dev);
687 }
688 
689 static int acp63_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
690 {
691 	struct acp_sdw_dma_stream *stream;
692 	struct snd_pcm_substream *substream;
693 	struct snd_pcm_runtime *runtime;
694 	u32 period_bytes, buf_size, water_mark_size_reg;
695 	u32 stream_count, irq_mask, irq_mask1;
696 	int index, instance, ret;
697 
698 	irq_mask = ACP63_SDW_DMA_IRQ_MASK;
699 	irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK;
700 	for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) {
701 		if (instance == ACP_SDW0)
702 			stream_count = ACP63_SDW0_DMA_MAX_STREAMS;
703 		else
704 			stream_count = ACP63_SDW1_DMA_MAX_STREAMS;
705 
706 		for (index = 0; index < stream_count; index++) {
707 			if (instance == ACP_SDW0) {
708 				substream = sdw_data->acp63_sdw0_dma_stream[index];
709 				water_mark_size_reg = acp63_sdw0_dma_reg[index].water_mark_size_reg;
710 			} else {
711 				substream = sdw_data->acp63_sdw1_dma_stream[index];
712 				water_mark_size_reg = acp63_sdw1_dma_reg[index].water_mark_size_reg;
713 			}
714 
715 			if (substream && substream->runtime) {
716 				runtime = substream->runtime;
717 				stream = runtime->private_data;
718 				period_bytes = frames_to_bytes(runtime, runtime->period_size);
719 				buf_size = frames_to_bytes(runtime, runtime->buffer_size);
720 				acp63_config_dma(stream, sdw_data->acp_base, index);
721 				ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index,
722 								     buf_size, instance,
723 								     ACP63_PCI_REV);
724 				if (ret)
725 					return ret;
726 				writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
727 			}
728 		}
729 	}
730 	acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true);
731 	return 0;
732 }
733 
734 static int acp70_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
735 {
736 	struct acp_sdw_dma_stream *stream;
737 	struct snd_pcm_substream *substream;
738 	struct snd_pcm_runtime *runtime;
739 	u32 period_bytes, buf_size, water_mark_size_reg;
740 	u32 stream_count, irq_mask, irq_mask1;
741 	int index, instance, ret;
742 
743 	irq_mask = ACP70_SDW_DMA_IRQ_MASK;
744 	irq_mask1 = ACP70_P1_SDW_DMA_IRQ_MASK;
745 	stream_count = ACP70_SDW0_DMA_MAX_STREAMS;
746 	for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) {
747 		for (index = 0; index < stream_count; index++) {
748 			if (instance == ACP_SDW0) {
749 				substream = sdw_data->acp70_sdw0_dma_stream[index];
750 				water_mark_size_reg = acp70_sdw0_dma_reg[index].water_mark_size_reg;
751 			} else {
752 				substream = sdw_data->acp70_sdw1_dma_stream[index];
753 				water_mark_size_reg = acp70_sdw1_dma_reg[index].water_mark_size_reg;
754 			}
755 
756 			if (substream && substream->runtime) {
757 				runtime = substream->runtime;
758 				stream = runtime->private_data;
759 				period_bytes = frames_to_bytes(runtime, runtime->period_size);
760 				buf_size = frames_to_bytes(runtime, runtime->buffer_size);
761 				acp63_config_dma(stream, sdw_data->acp_base, index);
762 				ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index,
763 								     buf_size, instance,
764 								     sdw_data->acp_rev);
765 				if (ret)
766 					return ret;
767 				writel(period_bytes, sdw_data->acp_base + water_mark_size_reg);
768 			}
769 		}
770 	}
771 	acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true);
772 	return 0;
773 }
774 
775 static int acp63_sdw_pcm_resume(struct device *dev)
776 {
777 	struct sdw_dma_dev_data *sdw_data;
778 
779 	sdw_data = dev_get_drvdata(dev);
780 	if (sdw_data->acp_rev == ACP63_PCI_REV)
781 		return acp63_restore_sdw_dma_config(sdw_data);
782 	else
783 		return acp70_restore_sdw_dma_config(sdw_data);
784 }
785 
786 static const struct dev_pm_ops acp63_pm_ops = {
787 	SYSTEM_SLEEP_PM_OPS(NULL, acp63_sdw_pcm_resume)
788 };
789 
790 static struct platform_driver acp63_sdw_dma_driver = {
791 	.probe = acp63_sdw_platform_probe,
792 	.remove = acp63_sdw_platform_remove,
793 	.driver = {
794 		.name = "amd_ps_sdw_dma",
795 		.pm = pm_ptr(&acp63_pm_ops),
796 	},
797 };
798 
799 module_platform_driver(acp63_sdw_dma_driver);
800 
801 MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
802 MODULE_DESCRIPTION("AMD common SDW DMA Driver for ACP6.3, ACP7.0 & ACP7.1 platforms");
803 MODULE_LICENSE("GPL");
804 MODULE_ALIAS("platform:" DRV_NAME);
805