1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AMD ACP PCI driver callback routines for ACP6.3, ACP7.0 & ACP7.1
4  * platforms.
5  *
6  * Copyright 2025 Advanced Micro Devices, Inc.
7  * Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
8  */
9 
10 #include <linux/bitops.h>
11 #include <linux/delay.h>
12 #include <linux/export.h>
13 #include <linux/io.h>
14 #include <linux/iopoll.h>
15 #include <linux/pci.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <sound/pcm_params.h>
19 
20 #include "acp63.h"
21 
22 static int acp63_power_on(void __iomem *acp_base)
23 {
24 	u32 val;
25 
26 	val = readl(acp_base + ACP_PGFSM_STATUS);
27 
28 	if (!val)
29 		return val;
30 
31 	if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS)
32 		writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
33 
34 	return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT);
35 }
36 
37 static int acp63_reset(void __iomem *acp_base)
38 {
39 	u32 val;
40 	int ret;
41 
42 	writel(1, acp_base + ACP_SOFT_RESET);
43 
44 	ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val,
45 				 val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK,
46 				 DELAY_US, ACP63_TIMEOUT);
47 	if (ret)
48 		return ret;
49 
50 	writel(0, acp_base + ACP_SOFT_RESET);
51 
52 	return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT);
53 }
54 
55 static void acp63_enable_interrupts(void __iomem *acp_base)
56 {
57 	writel(1, acp_base + ACP_EXTERNAL_INTR_ENB);
58 	writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL);
59 }
60 
61 static void acp63_disable_interrupts(void __iomem *acp_base)
62 {
63 	writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT);
64 	writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL);
65 	writel(0, acp_base + ACP_EXTERNAL_INTR_ENB);
66 }
67 
68 static int acp63_init(void __iomem *acp_base, struct device *dev)
69 {
70 	int ret;
71 
72 	ret = acp63_power_on(acp_base);
73 	if (ret) {
74 		dev_err(dev, "ACP power on failed\n");
75 		return ret;
76 	}
77 	writel(0x01, acp_base + ACP_CONTROL);
78 	ret = acp63_reset(acp_base);
79 	if (ret) {
80 		dev_err(dev, "ACP reset failed\n");
81 		return ret;
82 	}
83 	acp63_enable_interrupts(acp_base);
84 	writel(0, acp_base + ACP_ZSC_DSP_CTRL);
85 	return 0;
86 }
87 
88 static int acp63_deinit(void __iomem *acp_base, struct device *dev)
89 {
90 	int ret;
91 
92 	acp63_disable_interrupts(acp_base);
93 	ret = acp63_reset(acp_base);
94 	if (ret) {
95 		dev_err(dev, "ACP reset failed\n");
96 		return ret;
97 	}
98 	writel(0, acp_base + ACP_CONTROL);
99 	writel(1, acp_base + ACP_ZSC_DSP_CTRL);
100 	return 0;
101 }
102 
103 static void acp63_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data)
104 {
105 	u32 config;
106 
107 	config = readl(acp_data->acp63_base + ACP_PIN_CONFIG);
108 	dev_dbg(&pci->dev, "ACP config value: %d\n", config);
109 	switch (config) {
110 	case ACP_CONFIG_4:
111 	case ACP_CONFIG_5:
112 	case ACP_CONFIG_10:
113 	case ACP_CONFIG_11:
114 		acp_data->is_pdm_config = true;
115 		break;
116 	case ACP_CONFIG_2:
117 	case ACP_CONFIG_3:
118 		acp_data->is_sdw_config = true;
119 		break;
120 	case ACP_CONFIG_6:
121 	case ACP_CONFIG_7:
122 	case ACP_CONFIG_12:
123 	case ACP_CONFIG_8:
124 	case ACP_CONFIG_13:
125 	case ACP_CONFIG_14:
126 		acp_data->is_pdm_config = true;
127 		acp_data->is_sdw_config = true;
128 		break;
129 	default:
130 		break;
131 	}
132 }
133 
134 static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata)
135 {
136 	u32 sdw0_en, sdw1_en;
137 
138 	sdw0_en = readl(adata->acp63_base + ACP_SW0_EN);
139 	sdw1_en = readl(adata->acp63_base + ACP_SW1_EN);
140 	return (sdw0_en || sdw1_en);
141 }
142 
143 static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata)
144 {
145 	u32 val;
146 
147 	val = readl(adata->acp63_base + ACP_SW0_WAKE_EN);
148 	if (val && adata->sdw->pdev[0])
149 		pm_request_resume(&adata->sdw->pdev[0]->dev);
150 
151 	val = readl(adata->acp63_base + ACP_SW1_WAKE_EN);
152 	if (val && adata->sdw->pdev[1])
153 		pm_request_resume(&adata->sdw->pdev[1]->dev);
154 }
155 
156 static int __maybe_unused snd_acp63_suspend(struct device *dev)
157 {
158 	struct acp63_dev_data *adata;
159 	int ret;
160 
161 	adata = dev_get_drvdata(dev);
162 	if (adata->is_sdw_dev) {
163 		adata->sdw_en_stat = check_acp_sdw_enable_status(adata);
164 		if (adata->sdw_en_stat) {
165 			writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL);
166 			return 0;
167 		}
168 	}
169 	ret = acp_hw_deinit(adata, dev);
170 	if (ret)
171 		dev_err(dev, "ACP de-init failed\n");
172 
173 	return ret;
174 }
175 
176 static int __maybe_unused snd_acp63_runtime_resume(struct device *dev)
177 {
178 	struct acp63_dev_data *adata;
179 	int ret;
180 
181 	adata = dev_get_drvdata(dev);
182 	if (adata->sdw_en_stat) {
183 		writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL);
184 		return 0;
185 	}
186 	ret = acp_hw_init(adata, dev);
187 	if (ret) {
188 		dev_err(dev, "ACP init failed\n");
189 		return ret;
190 	}
191 
192 	if (!adata->sdw_en_stat)
193 		handle_acp63_sdw_pme_event(adata);
194 	return 0;
195 }
196 
197 static int __maybe_unused snd_acp63_resume(struct device *dev)
198 {
199 	struct acp63_dev_data *adata;
200 	int ret;
201 
202 	adata = dev_get_drvdata(dev);
203 	if (adata->sdw_en_stat) {
204 		writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL);
205 		return 0;
206 	}
207 
208 	ret = acp_hw_init(adata, dev);
209 	if (ret)
210 		dev_err(dev, "ACP init failed\n");
211 
212 	return ret;
213 }
214 
215 static void acp63_sdw_dma_irq_thread(struct acp63_dev_data *adata)
216 {
217 	struct sdw_dma_dev_data *sdw_data;
218 	u32 stream_id;
219 
220 	sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev);
221 
222 	for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) {
223 		if (adata->acp63_sdw0_dma_intr_stat[stream_id]) {
224 			if (sdw_data->acp63_sdw0_dma_stream[stream_id])
225 				snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]);
226 			adata->acp63_sdw0_dma_intr_stat[stream_id] = 0;
227 		}
228 	}
229 	for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) {
230 		if (adata->acp63_sdw1_dma_intr_stat[stream_id]) {
231 			if (sdw_data->acp63_sdw1_dma_stream[stream_id])
232 				snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]);
233 			adata->acp63_sdw1_dma_intr_stat[stream_id] = 0;
234 		}
235 	}
236 }
237 
238 void acp63_hw_init_ops(struct acp_hw_ops *hw_ops)
239 {
240 	hw_ops->acp_init = acp63_init;
241 	hw_ops->acp_deinit = acp63_deinit;
242 	hw_ops->acp_get_config = acp63_get_config;
243 	hw_ops->acp_sdw_dma_irq_thread = acp63_sdw_dma_irq_thread;
244 	hw_ops->acp_suspend = snd_acp63_suspend;
245 	hw_ops->acp_resume = snd_acp63_resume;
246 	hw_ops->acp_suspend_runtime = snd_acp63_suspend;
247 	hw_ops->acp_resume_runtime = snd_acp63_runtime_resume;
248 }
249 
250 static int acp70_power_on(void __iomem *acp_base)
251 {
252 	u32 val = 0;
253 
254 	val = readl(acp_base + ACP_PGFSM_STATUS);
255 
256 	if (!val)
257 		return 0;
258 	if (val & ACP70_PGFSM_STATUS_MASK)
259 		writel(ACP70_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
260 
261 	return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP70_TIMEOUT);
262 }
263 
264 static int acp70_reset(void __iomem *acp_base)
265 {
266 	u32 val;
267 	int ret;
268 
269 	writel(1, acp_base + ACP_SOFT_RESET);
270 
271 	ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val,
272 				 val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK,
273 				 DELAY_US, ACP70_TIMEOUT);
274 	if (ret)
275 		return ret;
276 
277 	writel(0, acp_base + ACP_SOFT_RESET);
278 
279 	return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP70_TIMEOUT);
280 }
281 
282 static void acp70_enable_sdw_host_wake_interrupts(void __iomem *acp_base)
283 {
284 	u32 ext_intr_cntl1;
285 
286 	ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1);
287 	ext_intr_cntl1 |= ACP70_SDW_HOST_WAKE_MASK;
288 	writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1);
289 }
290 
291 static void acp70_enable_interrupts(void __iomem *acp_base)
292 {
293 	u32 sdw0_wake_en, sdw1_wake_en;
294 
295 	writel(1, acp_base + ACP_EXTERNAL_INTR_ENB);
296 	writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL);
297 	sdw0_wake_en = readl(acp_base + ACP_SW0_WAKE_EN);
298 	sdw1_wake_en = readl(acp_base + ACP_SW1_WAKE_EN);
299 	if (sdw0_wake_en || sdw1_wake_en)
300 		acp70_enable_sdw_host_wake_interrupts(acp_base);
301 }
302 
303 static void acp70_disable_interrupts(void __iomem *acp_base)
304 {
305 	writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT);
306 	writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL);
307 	writel(0, acp_base + ACP_EXTERNAL_INTR_ENB);
308 }
309 
310 static int acp70_init(void __iomem *acp_base, struct device *dev)
311 {
312 	int ret;
313 
314 	ret = acp70_power_on(acp_base);
315 	if (ret) {
316 		dev_err(dev, "ACP power on failed\n");
317 		return ret;
318 	}
319 	writel(0x01, acp_base + ACP_CONTROL);
320 	ret = acp70_reset(acp_base);
321 	if (ret) {
322 		dev_err(dev, "ACP reset failed\n");
323 		return ret;
324 	}
325 	writel(0, acp_base + ACP_ZSC_DSP_CTRL);
326 	acp70_enable_interrupts(acp_base);
327 	writel(0x1, acp_base + ACP_PME_EN);
328 	return 0;
329 }
330 
331 static int acp70_deinit(void __iomem *acp_base, struct device *dev)
332 {
333 	int ret;
334 
335 	acp70_disable_interrupts(acp_base);
336 	ret = acp70_reset(acp_base);
337 	if (ret) {
338 		dev_err(dev, "ACP reset failed\n");
339 		return ret;
340 	}
341 	writel(0x01, acp_base + ACP_ZSC_DSP_CTRL);
342 	return 0;
343 }
344 
345 static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data)
346 {
347 	u32 config;
348 
349 	config = readl(acp_data->acp63_base + ACP_PIN_CONFIG);
350 	dev_dbg(&pci->dev, "ACP config value: %d\n", config);
351 	switch (config) {
352 	case ACP_CONFIG_4:
353 	case ACP_CONFIG_5:
354 	case ACP_CONFIG_10:
355 	case ACP_CONFIG_11:
356 	case ACP_CONFIG_20:
357 		acp_data->is_pdm_config = true;
358 		break;
359 	case ACP_CONFIG_2:
360 	case ACP_CONFIG_3:
361 	case ACP_CONFIG_16:
362 		acp_data->is_sdw_config = true;
363 		break;
364 	case ACP_CONFIG_6:
365 	case ACP_CONFIG_7:
366 	case ACP_CONFIG_12:
367 	case ACP_CONFIG_8:
368 	case ACP_CONFIG_13:
369 	case ACP_CONFIG_14:
370 	case ACP_CONFIG_17:
371 	case ACP_CONFIG_18:
372 	case ACP_CONFIG_19:
373 		acp_data->is_pdm_config = true;
374 		acp_data->is_sdw_config = true;
375 		break;
376 	default:
377 		break;
378 	}
379 }
380 
381 static void acp70_sdw_dma_irq_thread(struct acp63_dev_data *adata)
382 {
383 	struct sdw_dma_dev_data *sdw_data;
384 	u32 stream_id;
385 
386 	sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev);
387 
388 	for (stream_id = 0; stream_id < ACP70_SDW0_DMA_MAX_STREAMS; stream_id++) {
389 		if (adata->acp70_sdw0_dma_intr_stat[stream_id]) {
390 			if (sdw_data->acp70_sdw0_dma_stream[stream_id])
391 				snd_pcm_period_elapsed(sdw_data->acp70_sdw0_dma_stream[stream_id]);
392 			adata->acp70_sdw0_dma_intr_stat[stream_id] = 0;
393 		}
394 	}
395 	for (stream_id = 0; stream_id < ACP70_SDW1_DMA_MAX_STREAMS; stream_id++) {
396 		if (adata->acp70_sdw1_dma_intr_stat[stream_id]) {
397 			if (sdw_data->acp70_sdw1_dma_stream[stream_id])
398 				snd_pcm_period_elapsed(sdw_data->acp70_sdw1_dma_stream[stream_id]);
399 			adata->acp70_sdw1_dma_intr_stat[stream_id] = 0;
400 		}
401 	}
402 }
403 
404 static int __maybe_unused snd_acp70_suspend(struct device *dev)
405 {
406 	struct acp63_dev_data *adata;
407 	int ret;
408 
409 	adata = dev_get_drvdata(dev);
410 	if (adata->is_sdw_dev) {
411 		adata->sdw_en_stat = check_acp_sdw_enable_status(adata);
412 		if (adata->sdw_en_stat) {
413 			writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL);
414 			return 0;
415 		}
416 	}
417 	ret = acp_hw_deinit(adata, dev);
418 	if (ret)
419 		dev_err(dev, "ACP de-init failed\n");
420 
421 	return ret;
422 }
423 
424 static int __maybe_unused snd_acp70_runtime_resume(struct device *dev)
425 {
426 	struct acp63_dev_data *adata;
427 	int ret;
428 
429 	adata = dev_get_drvdata(dev);
430 
431 	if (adata->sdw_en_stat) {
432 		writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL);
433 		writel(1, adata->acp63_base + ACP_PME_EN);
434 		return 0;
435 	}
436 
437 	ret = acp_hw_init(adata, dev);
438 	if (ret) {
439 		dev_err(dev, "ACP init failed\n");
440 		return ret;
441 	}
442 	return 0;
443 }
444 
445 static int __maybe_unused snd_acp70_resume(struct device *dev)
446 {
447 	struct acp63_dev_data *adata;
448 	int ret;
449 
450 	adata = dev_get_drvdata(dev);
451 
452 	if (adata->sdw_en_stat) {
453 		writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL);
454 		writel(1, adata->acp63_base + ACP_PME_EN);
455 		return 0;
456 	}
457 
458 	ret = acp_hw_init(adata, dev);
459 	if (ret)
460 		dev_err(dev, "ACP init failed\n");
461 
462 	return ret;
463 }
464 
465 void acp70_hw_init_ops(struct acp_hw_ops *hw_ops)
466 {
467 	hw_ops->acp_init = acp70_init;
468 	hw_ops->acp_deinit = acp70_deinit;
469 	hw_ops->acp_get_config = acp70_get_config;
470 	hw_ops->acp_sdw_dma_irq_thread = acp70_sdw_dma_irq_thread;
471 	hw_ops->acp_suspend = snd_acp70_suspend;
472 	hw_ops->acp_resume = snd_acp70_resume;
473 	hw_ops->acp_suspend_runtime = snd_acp70_suspend;
474 	hw_ops->acp_resume_runtime = snd_acp70_runtime_resume;
475 }
476