xref: /openbmc/linux/sound/soc/sof/amd/acp.c (revision 8931ddd8)
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 //
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
5 //
6 // Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
7 //
8 // Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
9 //	    Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
10 
11 /*
12  * Hardware interface for generic AMD ACP processor
13  */
14 
15 #include <linux/io.h>
16 #include <linux/module.h>
17 #include <linux/pci.h>
18 
19 #include "../ops.h"
20 #include "acp.h"
21 #include "acp-dsp-offset.h"
22 
23 static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
24 {
25 	pci_write_config_dword(dev, 0x60, smn_addr);
26 	pci_write_config_dword(dev, 0x64, data);
27 
28 	return 0;
29 }
30 
31 static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data)
32 {
33 	pci_write_config_dword(dev, 0x60, smn_addr);
34 	pci_read_config_dword(dev, 0x64, data);
35 
36 	return 0;
37 }
38 
39 static void configure_acp_groupregisters(struct acp_dev_data *adata)
40 {
41 	struct snd_sof_dev *sdev = adata->dev;
42 
43 	/* Group Enable */
44 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_BASE_ADDR_GRP_1,
45 			  ACP_SRAM_PTE_OFFSET | BIT(31));
46 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1,
47 			  PAGE_SIZE_4K_ENABLE);
48 
49 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_CTRL, ACP_ATU_CACHE_INVALID);
50 }
51 
52 static void init_dma_descriptor(struct acp_dev_data *adata)
53 {
54 	struct snd_sof_dev *sdev = adata->dev;
55 	unsigned int addr;
56 
57 	addr = ACP_SRAM_PTE_OFFSET + offsetof(struct scratch_reg_conf, dma_desc);
58 
59 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_BASE_ADDR, addr);
60 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_MAX_NUM_DSCR, ACP_MAX_DESC_CNT);
61 }
62 
63 static void configure_dma_descriptor(struct acp_dev_data *adata, unsigned short idx,
64 				     struct dma_descriptor *dscr_info)
65 {
66 	struct snd_sof_dev *sdev = adata->dev;
67 	unsigned int offset;
68 
69 	offset = ACP_SCRATCH_REG_0 + offsetof(struct scratch_reg_conf, dma_desc) +
70 		 idx * sizeof(struct dma_descriptor);
71 
72 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, offset, dscr_info->src_addr);
73 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, offset + 0x4, dscr_info->dest_addr);
74 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, offset + 0x8, dscr_info->tx_cnt.u32_all);
75 }
76 
77 static int config_dma_channel(struct acp_dev_data *adata, unsigned int ch,
78 			      unsigned int idx, unsigned int dscr_count)
79 {
80 	struct snd_sof_dev *sdev = adata->dev;
81 	unsigned int val, status;
82 	int ret;
83 
84 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32),
85 			  ACP_DMA_CH_RST | ACP_DMA_CH_GRACEFUL_RST_EN);
86 
87 	ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_DMA_CH_RST_STS, val,
88 					    val & (1 << ch), ACP_REG_POLL_INTERVAL,
89 					    ACP_REG_POLL_TIMEOUT_US);
90 	if (ret < 0) {
91 		status = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_ERROR_STATUS);
92 		val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DMA_ERR_STS_0 + ch * sizeof(u32));
93 
94 		dev_err(sdev->dev, "ACP_DMA_ERR_STS :0x%x ACP_ERROR_STATUS :0x%x\n", val, status);
95 		return ret;
96 	}
97 
98 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, (ACP_DMA_CNTL_0 + ch * sizeof(u32)), 0);
99 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_CNT_0 + ch * sizeof(u32), dscr_count);
100 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_STRT_IDX_0 + ch * sizeof(u32), idx);
101 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_PRIO_0 + ch * sizeof(u32), 0);
102 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32), ACP_DMA_CH_RUN);
103 
104 	return ret;
105 }
106 
107 static int acpbus_dma_start(struct acp_dev_data *adata, unsigned int ch,
108 			    unsigned int dscr_count, struct dma_descriptor *dscr_info)
109 {
110 	struct snd_sof_dev *sdev = adata->dev;
111 	int ret;
112 	u16 dscr;
113 
114 	if (!dscr_info || !dscr_count)
115 		return -EINVAL;
116 
117 	for (dscr = 0; dscr < dscr_count; dscr++)
118 		configure_dma_descriptor(adata, dscr, dscr_info++);
119 
120 	ret = config_dma_channel(adata, ch, 0, dscr_count);
121 	if (ret < 0)
122 		dev_err(sdev->dev, "config dma ch failed:%d\n", ret);
123 
124 	return ret;
125 }
126 
127 int configure_and_run_dma(struct acp_dev_data *adata, unsigned int src_addr,
128 			  unsigned int dest_addr, int dsp_data_size)
129 {
130 	struct snd_sof_dev *sdev = adata->dev;
131 	unsigned int desc_count, index;
132 	int ret;
133 
134 	for (desc_count = 0; desc_count < ACP_MAX_DESC && dsp_data_size >= 0;
135 	     desc_count++, dsp_data_size -= ACP_PAGE_SIZE) {
136 		adata->dscr_info[desc_count].src_addr = src_addr + desc_count * ACP_PAGE_SIZE;
137 		adata->dscr_info[desc_count].dest_addr = dest_addr + desc_count * ACP_PAGE_SIZE;
138 		adata->dscr_info[desc_count].tx_cnt.bits.count = ACP_PAGE_SIZE;
139 		if (dsp_data_size < ACP_PAGE_SIZE)
140 			adata->dscr_info[desc_count].tx_cnt.bits.count = dsp_data_size;
141 	}
142 
143 	ret = acpbus_dma_start(adata, 0, desc_count, adata->dscr_info);
144 	if (ret)
145 		dev_err(sdev->dev, "acpbus_dma_start failed\n");
146 
147 	/* Clear descriptor array */
148 	for (index = 0; index < desc_count; index++)
149 		memset(&adata->dscr_info[index], 0x00, sizeof(struct dma_descriptor));
150 
151 	return ret;
152 }
153 
154 static int psp_fw_validate(struct acp_dev_data *adata)
155 {
156 	struct snd_sof_dev *sdev = adata->dev;
157 	int timeout;
158 	u32 data;
159 
160 	smn_write(adata->smn_dev, MP0_C2PMSG_26_REG, MBOX_ACP_SHA_DMA_COMMAND);
161 
162 	for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
163 		msleep(20);
164 		smn_read(adata->smn_dev, MP0_C2PMSG_26_REG, &data);
165 		if (data & MBOX_READY_MASK)
166 			return 0;
167 	}
168 
169 	dev_err(sdev->dev, "FW validation timedout: status %x\n", data & MBOX_STATUS_MASK);
170 	return -ETIMEDOUT;
171 }
172 
173 int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
174 			      unsigned int start_addr, unsigned int dest_addr,
175 			      unsigned int image_length)
176 {
177 	struct snd_sof_dev *sdev = adata->dev;
178 	unsigned int tx_count, fw_qualifier, val;
179 	int ret;
180 
181 	if (!image_addr) {
182 		dev_err(sdev->dev, "SHA DMA image address is NULL\n");
183 		return -EINVAL;
184 	}
185 
186 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD);
187 	if (val & ACP_SHA_RUN) {
188 		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD, ACP_SHA_RESET);
189 		ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD_STS,
190 						    val, val & ACP_SHA_RESET,
191 						    ACP_REG_POLL_INTERVAL,
192 						    ACP_REG_POLL_TIMEOUT_US);
193 		if (ret < 0) {
194 			dev_err(sdev->dev, "SHA DMA Failed to Reset\n");
195 			return ret;
196 		}
197 	}
198 
199 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_STRT_ADDR, start_addr);
200 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_DESTINATION_ADDR, dest_addr);
201 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_MSG_LENGTH, image_length);
202 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD, ACP_SHA_RUN);
203 
204 	ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SHA_TRANSFER_BYTE_CNT,
205 					    tx_count, tx_count == image_length,
206 					    ACP_REG_POLL_INTERVAL, ACP_DMA_COMPLETE_TIMEOUT_US);
207 	if (ret < 0) {
208 		dev_err(sdev->dev, "SHA DMA Failed to Transfer Length %x\n", tx_count);
209 		return ret;
210 	}
211 
212 	ret = psp_fw_validate(adata);
213 	if (ret)
214 		return ret;
215 
216 	fw_qualifier = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER);
217 	if (!(fw_qualifier & DSP_FW_RUN_ENABLE)) {
218 		dev_err(sdev->dev, "PSP validation failed\n");
219 		return -EINVAL;
220 	}
221 
222 	return 0;
223 }
224 
225 int acp_dma_status(struct acp_dev_data *adata, unsigned char ch)
226 {
227 	struct snd_sof_dev *sdev = adata->dev;
228 	unsigned int val;
229 	int ret = 0;
230 
231 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32));
232 	if (val & ACP_DMA_CH_RUN) {
233 		ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_DMA_CH_STS, val, !val,
234 						    ACP_REG_POLL_INTERVAL,
235 						    ACP_DMA_COMPLETE_TIMEOUT_US);
236 		if (ret < 0)
237 			dev_err(sdev->dev, "DMA_CHANNEL %d status timeout\n", ch);
238 	}
239 
240 	return ret;
241 }
242 
243 void memcpy_from_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *dst, size_t bytes)
244 {
245 	unsigned int reg_offset = offset + ACP_SCRATCH_REG_0;
246 	int i, j;
247 
248 	for (i = 0, j = 0; i < bytes; i = i + 4, j++)
249 		dst[j] = snd_sof_dsp_read(sdev, ACP_DSP_BAR, reg_offset + i);
250 }
251 
252 void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes)
253 {
254 	unsigned int reg_offset = offset + ACP_SCRATCH_REG_0;
255 	int i, j;
256 
257 	for (i = 0, j = 0; i < bytes; i = i + 4, j++)
258 		snd_sof_dsp_write(sdev, ACP_DSP_BAR, reg_offset + i, src[j]);
259 }
260 
261 static int acp_memory_init(struct snd_sof_dev *sdev)
262 {
263 	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
264 
265 	snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_CNTL,
266 				ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK);
267 	configure_acp_groupregisters(adata);
268 	init_dma_descriptor(adata);
269 
270 	return 0;
271 }
272 
273 static irqreturn_t acp_irq_thread(int irq, void *context)
274 {
275 	struct snd_sof_dev *sdev = context;
276 	unsigned int val;
277 
278 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT);
279 	if (val & ACP_SHA_STAT) {
280 		/* Clear SHA interrupt raised by PSP */
281 		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT, val);
282 		return IRQ_HANDLED;
283 	}
284 
285 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
286 	if (val & ACP_DSP_TO_HOST_IRQ) {
287 		sof_ops(sdev)->irq_thread(irq, sdev);
288 		val |= ACP_DSP_TO_HOST_IRQ;
289 		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT, val);
290 		return IRQ_HANDLED;
291 	}
292 
293 	return IRQ_NONE;
294 };
295 
296 static irqreturn_t acp_irq_handler(int irq, void *dev_id)
297 {
298 	struct snd_sof_dev *sdev = dev_id;
299 	unsigned int val;
300 
301 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
302 	if (val)
303 		return IRQ_WAKE_THREAD;
304 
305 	return IRQ_NONE;
306 }
307 
308 static int acp_power_on(struct snd_sof_dev *sdev)
309 {
310 	unsigned int val;
311 	int ret;
312 
313 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_PGFSM_STATUS);
314 
315 	if (val == ACP_POWERED_ON)
316 		return 0;
317 
318 	if (val & ACP_PGFSM_STATUS_MASK)
319 		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_PGFSM_CONTROL,
320 				  ACP_PGFSM_CNTL_POWER_ON_MASK);
321 
322 	ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_PGFSM_STATUS, val, !val,
323 					    ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
324 	if (ret < 0)
325 		dev_err(sdev->dev, "timeout in ACP_PGFSM_STATUS read\n");
326 
327 	return ret;
328 }
329 
330 static int acp_reset(struct snd_sof_dev *sdev)
331 {
332 	unsigned int val;
333 	int ret;
334 
335 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, ACP_ASSERT_RESET);
336 
337 	ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, val,
338 					    val & ACP_SOFT_RESET_DONE_MASK,
339 					    ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
340 	if (ret < 0) {
341 		dev_err(sdev->dev, "timeout asserting reset\n");
342 		return ret;
343 	}
344 
345 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, ACP_RELEASE_RESET);
346 
347 	ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, val, !val,
348 					    ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
349 	if (ret < 0)
350 		dev_err(sdev->dev, "timeout in releasing reset\n");
351 
352 	return ret;
353 }
354 
355 static int acp_init(struct snd_sof_dev *sdev)
356 {
357 	int ret;
358 
359 	/* power on */
360 	ret = acp_power_on(sdev);
361 	if (ret) {
362 		dev_err(sdev->dev, "ACP power on failed\n");
363 		return ret;
364 	}
365 	/* Reset */
366 	return acp_reset(sdev);
367 }
368 
369 int amd_sof_acp_probe(struct snd_sof_dev *sdev)
370 {
371 	struct pci_dev *pci = to_pci_dev(sdev->dev);
372 	struct acp_dev_data *adata;
373 	const struct sof_amd_acp_desc *chip;
374 	unsigned int addr;
375 	int ret;
376 
377 	adata = devm_kzalloc(sdev->dev, sizeof(struct acp_dev_data),
378 			     GFP_KERNEL);
379 	if (!adata)
380 		return -ENOMEM;
381 
382 	adata->dev = sdev;
383 	addr = pci_resource_start(pci, ACP_DSP_BAR);
384 	sdev->bar[ACP_DSP_BAR] = devm_ioremap(sdev->dev, addr, pci_resource_len(pci, ACP_DSP_BAR));
385 	if (!sdev->bar[ACP_DSP_BAR]) {
386 		dev_err(sdev->dev, "ioremap error\n");
387 		return -ENXIO;
388 	}
389 
390 	pci_set_master(pci);
391 
392 	sdev->pdata->hw_pdata = adata;
393 
394 	chip = get_chip_info(sdev->pdata);
395 	if (!chip) {
396 		dev_err(sdev->dev, "no such device supported, chip id:%x\n", pci->device);
397 		return -EIO;
398 	}
399 
400 	adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL);
401 	if (!adata->smn_dev) {
402 		dev_err(sdev->dev, "Failed to get host bridge device\n");
403 		return -ENODEV;
404 	}
405 
406 	sdev->ipc_irq = pci->irq;
407 	ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread,
408 				   IRQF_SHARED, "AudioDSP", sdev);
409 	if (ret < 0) {
410 		dev_err(sdev->dev, "failed to register IRQ %d\n",
411 			sdev->ipc_irq);
412 		pci_dev_put(adata->smn_dev);
413 		return ret;
414 	}
415 
416 	ret = acp_init(sdev);
417 	if (ret < 0) {
418 		free_irq(sdev->ipc_irq, sdev);
419 		pci_dev_put(adata->smn_dev);
420 		return ret;
421 	}
422 
423 	acp_memory_init(sdev);
424 
425 	acp_dsp_stream_init(sdev);
426 
427 	return 0;
428 }
429 EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON);
430 
431 int amd_sof_acp_remove(struct snd_sof_dev *sdev)
432 {
433 	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
434 
435 	if (adata->smn_dev)
436 		pci_dev_put(adata->smn_dev);
437 
438 	if (sdev->ipc_irq)
439 		free_irq(sdev->ipc_irq, sdev);
440 
441 	return acp_reset(sdev);
442 }
443 EXPORT_SYMBOL_NS(amd_sof_acp_remove, SND_SOC_SOF_AMD_COMMON);
444 
445 MODULE_DESCRIPTION("AMD ACP sof driver");
446 MODULE_LICENSE("Dual BSD/GPL");
447