xref: /openbmc/linux/sound/soc/sof/intel/byt.c (revision f84337c3)
1 // SPDX-License-Identifier: (GPL-2.0 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) 2018 Intel Corporation. All rights reserved.
7 //
8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9 //
10 
11 /*
12  * Hardware interface for audio DSP on Baytrail, Braswell and Cherrytrail.
13  */
14 
15 #include <linux/module.h>
16 #include <sound/sof.h>
17 #include <sound/sof/xtensa.h>
18 #include "../ops.h"
19 #include "shim.h"
20 
21 /* DSP memories */
22 #define IRAM_OFFSET		0x0C0000
23 #define IRAM_SIZE		(80 * 1024)
24 #define DRAM_OFFSET		0x100000
25 #define DRAM_SIZE		(160 * 1024)
26 #define SHIM_OFFSET		0x140000
27 #define SHIM_SIZE_BYT		0x100
28 #define SHIM_SIZE_CHT		0x118
29 #define MBOX_OFFSET		0x144000
30 #define MBOX_SIZE		0x1000
31 #define EXCEPT_OFFSET		0x800
32 #define EXCEPT_MAX_HDR_SIZE	0x400
33 
34 /* DSP peripherals */
35 #define DMAC0_OFFSET		0x098000
36 #define DMAC1_OFFSET		0x09c000
37 #define DMAC2_OFFSET		0x094000
38 #define DMAC_SIZE		0x420
39 #define SSP0_OFFSET		0x0a0000
40 #define SSP1_OFFSET		0x0a1000
41 #define SSP2_OFFSET		0x0a2000
42 #define SSP3_OFFSET		0x0a4000
43 #define SSP4_OFFSET		0x0a5000
44 #define SSP5_OFFSET		0x0a6000
45 #define SSP_SIZE		0x100
46 
47 #define BYT_STACK_DUMP_SIZE	32
48 
49 #define BYT_PCI_BAR_SIZE	0x200000
50 
51 #define BYT_PANIC_OFFSET(x)	(((x) & GENMASK_ULL(47, 32)) >> 32)
52 
53 /*
54  * Debug
55  */
56 
57 #define MBOX_DUMP_SIZE	0x30
58 
59 /* BARs */
60 #define BYT_DSP_BAR		0
61 #define BYT_PCI_BAR		1
62 #define BYT_IMR_BAR		2
63 
64 static const struct snd_sof_debugfs_map byt_debugfs[] = {
65 	{"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
66 	 SOF_DEBUGFS_ACCESS_ALWAYS},
67 	{"dmac1", BYT_DSP_BAR,  DMAC1_OFFSET, DMAC_SIZE,
68 	 SOF_DEBUGFS_ACCESS_ALWAYS},
69 	{"ssp0",  BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE,
70 	 SOF_DEBUGFS_ACCESS_ALWAYS},
71 	{"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE,
72 	 SOF_DEBUGFS_ACCESS_ALWAYS},
73 	{"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE,
74 	 SOF_DEBUGFS_ACCESS_ALWAYS},
75 	{"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
76 	 SOF_DEBUGFS_ACCESS_D0_ONLY},
77 	{"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
78 	 SOF_DEBUGFS_ACCESS_D0_ONLY},
79 	{"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
80 	 SOF_DEBUGFS_ACCESS_ALWAYS},
81 };
82 
83 static const struct snd_sof_debugfs_map cht_debugfs[] = {
84 	{"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
85 	 SOF_DEBUGFS_ACCESS_ALWAYS},
86 	{"dmac1", BYT_DSP_BAR,  DMAC1_OFFSET, DMAC_SIZE,
87 	 SOF_DEBUGFS_ACCESS_ALWAYS},
88 	{"dmac2", BYT_DSP_BAR,  DMAC2_OFFSET, DMAC_SIZE,
89 	 SOF_DEBUGFS_ACCESS_ALWAYS},
90 	{"ssp0",  BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE,
91 	 SOF_DEBUGFS_ACCESS_ALWAYS},
92 	{"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE,
93 	 SOF_DEBUGFS_ACCESS_ALWAYS},
94 	{"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE,
95 	 SOF_DEBUGFS_ACCESS_ALWAYS},
96 	{"ssp3", BYT_DSP_BAR, SSP3_OFFSET, SSP_SIZE,
97 	 SOF_DEBUGFS_ACCESS_ALWAYS},
98 	{"ssp4", BYT_DSP_BAR, SSP4_OFFSET, SSP_SIZE,
99 	 SOF_DEBUGFS_ACCESS_ALWAYS},
100 	{"ssp5", BYT_DSP_BAR, SSP5_OFFSET, SSP_SIZE,
101 	 SOF_DEBUGFS_ACCESS_ALWAYS},
102 	{"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
103 	 SOF_DEBUGFS_ACCESS_D0_ONLY},
104 	{"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
105 	 SOF_DEBUGFS_ACCESS_D0_ONLY},
106 	{"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
107 	 SOF_DEBUGFS_ACCESS_ALWAYS},
108 };
109 
110 static void byt_host_done(struct snd_sof_dev *sdev);
111 static void byt_dsp_done(struct snd_sof_dev *sdev);
112 static void byt_get_reply(struct snd_sof_dev *sdev);
113 
114 /*
115  * Debug
116  */
117 
118 static void byt_get_registers(struct snd_sof_dev *sdev,
119 			      struct sof_ipc_dsp_oops_xtensa *xoops,
120 			      struct sof_ipc_panic_info *panic_info,
121 			      u32 *stack, size_t stack_words)
122 {
123 	u32 offset = sdev->dsp_oops_offset;
124 
125 	/* first read regsisters */
126 	sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
127 
128 	/* note: variable AR register array is not read */
129 
130 	/* then get panic info */
131 	if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
132 		dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
133 			xoops->arch_hdr.totalsize);
134 		return;
135 	}
136 	offset += xoops->arch_hdr.totalsize;
137 	sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
138 
139 	/* then get the stack */
140 	offset += sizeof(*panic_info);
141 	sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
142 }
143 
144 static void byt_dump(struct snd_sof_dev *sdev, u32 flags)
145 {
146 	struct sof_ipc_dsp_oops_xtensa xoops;
147 	struct sof_ipc_panic_info panic_info;
148 	u32 stack[BYT_STACK_DUMP_SIZE];
149 	u64 status, panic, imrd, imrx;
150 
151 	/* now try generic SOF status messages */
152 	status = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
153 	panic = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
154 	byt_get_registers(sdev, &xoops, &panic_info, stack,
155 			  BYT_STACK_DUMP_SIZE);
156 	snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
157 			   BYT_STACK_DUMP_SIZE);
158 
159 	/* provide some context for firmware debug */
160 	imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX);
161 	imrd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRD);
162 	dev_err(sdev->dev,
163 		"error: ipc host -> DSP: pending %s complete %s raw 0x%llx\n",
164 		(panic & SHIM_IPCX_BUSY) ? "yes" : "no",
165 		(panic & SHIM_IPCX_DONE) ? "yes" : "no", panic);
166 	dev_err(sdev->dev,
167 		"error: mask host: pending %s complete %s raw 0x%llx\n",
168 		(imrx & SHIM_IMRX_BUSY) ? "yes" : "no",
169 		(imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx);
170 	dev_err(sdev->dev,
171 		"error: ipc DSP -> host: pending %s complete %s raw 0x%llx\n",
172 		(status & SHIM_IPCD_BUSY) ? "yes" : "no",
173 		(status & SHIM_IPCD_DONE) ? "yes" : "no", status);
174 	dev_err(sdev->dev,
175 		"error: mask DSP: pending %s complete %s raw 0x%llx\n",
176 		(imrd & SHIM_IMRD_BUSY) ? "yes" : "no",
177 		(imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd);
178 
179 }
180 
181 /*
182  * IPC Doorbell IRQ handler and thread.
183  */
184 
185 static irqreturn_t byt_irq_handler(int irq, void *context)
186 {
187 	struct snd_sof_dev *sdev = context;
188 	u64 isr;
189 	int ret = IRQ_NONE;
190 
191 	/* Interrupt arrived, check src */
192 	isr = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_ISRX);
193 	if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY))
194 		ret = IRQ_WAKE_THREAD;
195 
196 	return ret;
197 }
198 
199 static irqreturn_t byt_irq_thread(int irq, void *context)
200 {
201 	struct snd_sof_dev *sdev = context;
202 	u64 ipcx, ipcd;
203 	u64 imrx;
204 
205 	imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX);
206 	ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
207 
208 	/* reply message from DSP */
209 	if (ipcx & SHIM_BYT_IPCX_DONE &&
210 	    !(imrx & SHIM_IMRX_DONE)) {
211 		/* Mask Done interrupt before first */
212 		snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR,
213 						   SHIM_IMRX,
214 						   SHIM_IMRX_DONE,
215 						   SHIM_IMRX_DONE);
216 
217 		spin_lock_irq(&sdev->ipc_lock);
218 
219 		/*
220 		 * handle immediate reply from DSP core. If the msg is
221 		 * found, set done bit in cmd_done which is called at the
222 		 * end of message processing function, else set it here
223 		 * because the done bit can't be set in cmd_done function
224 		 * which is triggered by msg
225 		 */
226 		byt_get_reply(sdev);
227 		snd_sof_ipc_reply(sdev, ipcx);
228 
229 		byt_dsp_done(sdev);
230 
231 		spin_unlock_irq(&sdev->ipc_lock);
232 	}
233 
234 	/* new message from DSP */
235 	ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
236 	if (ipcd & SHIM_BYT_IPCD_BUSY &&
237 	    !(imrx & SHIM_IMRX_BUSY)) {
238 		/* Mask Busy interrupt before return */
239 		snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR,
240 						   SHIM_IMRX,
241 						   SHIM_IMRX_BUSY,
242 						   SHIM_IMRX_BUSY);
243 
244 		/* Handle messages from DSP Core */
245 		if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
246 			snd_sof_dsp_panic(sdev, BYT_PANIC_OFFSET(ipcd) +
247 					  MBOX_OFFSET);
248 		} else {
249 			snd_sof_ipc_msgs_rx(sdev);
250 		}
251 
252 		byt_host_done(sdev);
253 	}
254 
255 	return IRQ_HANDLED;
256 }
257 
258 static int byt_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
259 {
260 	/* send the message */
261 	sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
262 			  msg->msg_size);
263 	snd_sof_dsp_write64(sdev, BYT_DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY);
264 
265 	return 0;
266 }
267 
268 static void byt_get_reply(struct snd_sof_dev *sdev)
269 {
270 	struct snd_sof_ipc_msg *msg = sdev->msg;
271 	struct sof_ipc_reply reply;
272 	int ret = 0;
273 
274 	/*
275 	 * Sometimes, there is unexpected reply ipc arriving. The reply
276 	 * ipc belongs to none of the ipcs sent from driver.
277 	 * In this case, the driver must ignore the ipc.
278 	 */
279 	if (!msg) {
280 		dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n");
281 		return;
282 	}
283 
284 	/* get reply */
285 	sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
286 
287 	if (reply.error < 0) {
288 		memcpy(msg->reply_data, &reply, sizeof(reply));
289 		ret = reply.error;
290 	} else {
291 		/* reply correct size ? */
292 		if (reply.hdr.size != msg->reply_size) {
293 			dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
294 				msg->reply_size, reply.hdr.size);
295 			ret = -EINVAL;
296 		}
297 
298 		/* read the message */
299 		if (msg->reply_size > 0)
300 			sof_mailbox_read(sdev, sdev->host_box.offset,
301 					 msg->reply_data, msg->reply_size);
302 	}
303 
304 	msg->reply_error = ret;
305 }
306 
307 static int byt_get_mailbox_offset(struct snd_sof_dev *sdev)
308 {
309 	return MBOX_OFFSET;
310 }
311 
312 static int byt_get_window_offset(struct snd_sof_dev *sdev, u32 id)
313 {
314 	return MBOX_OFFSET;
315 }
316 
317 static void byt_host_done(struct snd_sof_dev *sdev)
318 {
319 	/* clear BUSY bit and set DONE bit - accept new messages */
320 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCD,
321 					   SHIM_BYT_IPCD_BUSY |
322 					   SHIM_BYT_IPCD_DONE,
323 					   SHIM_BYT_IPCD_DONE);
324 
325 	/* unmask busy interrupt */
326 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
327 					   SHIM_IMRX_BUSY, 0);
328 }
329 
330 static void byt_dsp_done(struct snd_sof_dev *sdev)
331 {
332 	/* clear DONE bit - tell DSP we have completed */
333 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX,
334 					   SHIM_BYT_IPCX_DONE, 0);
335 
336 	/* unmask Done interrupt */
337 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
338 					   SHIM_IMRX_DONE, 0);
339 }
340 
341 /*
342  * DSP control.
343  */
344 
345 static int byt_run(struct snd_sof_dev *sdev)
346 {
347 	int tries = 10;
348 
349 	/* release stall and wait to unstall */
350 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
351 				  SHIM_BYT_CSR_STALL, 0x0);
352 	while (tries--) {
353 		if (!(snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_CSR) &
354 		      SHIM_BYT_CSR_PWAITMODE))
355 			break;
356 		msleep(100);
357 	}
358 	if (tries < 0) {
359 		dev_err(sdev->dev, "error:  unable to run DSP firmware\n");
360 		byt_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX);
361 		return -ENODEV;
362 	}
363 
364 	/* return init core mask */
365 	return 1;
366 }
367 
368 static int byt_reset(struct snd_sof_dev *sdev)
369 {
370 	/* put DSP into reset, set reset vector and stall */
371 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
372 				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
373 				  SHIM_BYT_CSR_STALL,
374 				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
375 				  SHIM_BYT_CSR_STALL);
376 
377 	usleep_range(10, 15);
378 
379 	/* take DSP out of reset and keep stalled for FW loading */
380 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
381 				  SHIM_BYT_CSR_RST, 0);
382 
383 	return 0;
384 }
385 
386 /* Baytrail DAIs */
387 static struct snd_soc_dai_driver byt_dai[] = {
388 {
389 	.name = "ssp0-port",
390 },
391 {
392 	.name = "ssp1-port",
393 },
394 {
395 	.name = "ssp2-port",
396 },
397 {
398 	.name = "ssp3-port",
399 },
400 {
401 	.name = "ssp4-port",
402 },
403 {
404 	.name = "ssp5-port",
405 },
406 };
407 
408 /*
409  * Probe and remove.
410  */
411 
412 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
413 
414 static int tangier_pci_probe(struct snd_sof_dev *sdev)
415 {
416 	struct snd_sof_pdata *pdata = sdev->pdata;
417 	const struct sof_dev_desc *desc = pdata->desc;
418 	struct pci_dev *pci = to_pci_dev(sdev->dev);
419 	u32 base, size;
420 	int ret;
421 
422 	/* DSP DMA can only access low 31 bits of host memory */
423 	ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31));
424 	if (ret < 0) {
425 		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
426 		return ret;
427 	}
428 
429 	/* LPE base */
430 	base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET;
431 	size = BYT_PCI_BAR_SIZE;
432 
433 	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
434 	sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
435 	if (!sdev->bar[BYT_DSP_BAR]) {
436 		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
437 			base, size);
438 		return -ENODEV;
439 	}
440 	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
441 
442 	/* IMR base - optional */
443 	if (desc->resindex_imr_base == -1)
444 		goto irq;
445 
446 	base = pci_resource_start(pci, desc->resindex_imr_base);
447 	size = pci_resource_len(pci, desc->resindex_imr_base);
448 
449 	/* some BIOSes don't map IMR */
450 	if (base == 0x55aa55aa || base == 0x0) {
451 		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
452 		goto irq;
453 	}
454 
455 	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
456 	sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
457 	if (!sdev->bar[BYT_IMR_BAR]) {
458 		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
459 			base, size);
460 		return -ENODEV;
461 	}
462 	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
463 
464 irq:
465 	/* register our IRQ */
466 	sdev->ipc_irq = pci->irq;
467 	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
468 	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
469 					byt_irq_handler, byt_irq_thread,
470 					0, "AudioDSP", sdev);
471 	if (ret < 0) {
472 		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
473 			sdev->ipc_irq);
474 		return ret;
475 	}
476 
477 	/* enable Interrupt from both sides */
478 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
479 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
480 
481 	/* set default mailbox offset for FW ready message */
482 	sdev->dsp_box.offset = MBOX_OFFSET;
483 
484 	return ret;
485 }
486 
487 const struct snd_sof_dsp_ops sof_tng_ops = {
488 	/* device init */
489 	.probe		= tangier_pci_probe,
490 
491 	/* DSP core boot / reset */
492 	.run		= byt_run,
493 	.reset		= byt_reset,
494 
495 	/* Register IO */
496 	.write		= sof_io_write,
497 	.read		= sof_io_read,
498 	.write64	= sof_io_write64,
499 	.read64		= sof_io_read64,
500 
501 	/* Block IO */
502 	.block_read	= sof_block_read,
503 	.block_write	= sof_block_write,
504 
505 	/* doorbell */
506 	.irq_handler	= byt_irq_handler,
507 	.irq_thread	= byt_irq_thread,
508 
509 	/* ipc */
510 	.send_msg	= byt_send_msg,
511 	.fw_ready	= sof_fw_ready,
512 	.get_mailbox_offset = byt_get_mailbox_offset,
513 	.get_window_offset = byt_get_window_offset,
514 
515 	.ipc_msg_data	= intel_ipc_msg_data,
516 	.ipc_pcm_params	= intel_ipc_pcm_params,
517 
518 	/* debug */
519 	.debug_map	= byt_debugfs,
520 	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
521 	.dbg_dump	= byt_dump,
522 
523 	/* stream callbacks */
524 	.pcm_open	= intel_pcm_open,
525 	.pcm_close	= intel_pcm_close,
526 
527 	/* module loading */
528 	.load_module	= snd_sof_parse_module_memcpy,
529 
530 	/*Firmware loading */
531 	.load_firmware	= snd_sof_load_firmware_memcpy,
532 
533 	/* DAI drivers */
534 	.drv = byt_dai,
535 	.num_drv = 3, /* we have only 3 SSPs on byt*/
536 
537 	/* ALSA HW info flags */
538 	.hw_info =	SNDRV_PCM_INFO_MMAP |
539 			SNDRV_PCM_INFO_MMAP_VALID |
540 			SNDRV_PCM_INFO_INTERLEAVED |
541 			SNDRV_PCM_INFO_PAUSE |
542 			SNDRV_PCM_INFO_BATCH,
543 };
544 EXPORT_SYMBOL(sof_tng_ops);
545 
546 const struct sof_intel_dsp_desc tng_chip_info = {
547 	.cores_num = 1,
548 	.cores_mask = 1,
549 };
550 EXPORT_SYMBOL(tng_chip_info);
551 
552 #endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */
553 
554 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
555 
556 static int byt_acpi_probe(struct snd_sof_dev *sdev)
557 {
558 	struct snd_sof_pdata *pdata = sdev->pdata;
559 	const struct sof_dev_desc *desc = pdata->desc;
560 	struct platform_device *pdev =
561 		container_of(sdev->dev, struct platform_device, dev);
562 	struct resource *mmio;
563 	u32 base, size;
564 	int ret;
565 
566 	/* DSP DMA can only access low 31 bits of host memory */
567 	ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
568 	if (ret < 0) {
569 		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
570 		return ret;
571 	}
572 
573 	/* LPE base */
574 	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
575 				     desc->resindex_lpe_base);
576 	if (mmio) {
577 		base = mmio->start;
578 		size = resource_size(mmio);
579 	} else {
580 		dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
581 			desc->resindex_lpe_base);
582 		return -EINVAL;
583 	}
584 
585 	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
586 	sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
587 	if (!sdev->bar[BYT_DSP_BAR]) {
588 		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
589 			base, size);
590 		return -ENODEV;
591 	}
592 	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
593 
594 	/* TODO: add offsets */
595 	sdev->mmio_bar = BYT_DSP_BAR;
596 	sdev->mailbox_bar = BYT_DSP_BAR;
597 
598 	/* IMR base - optional */
599 	if (desc->resindex_imr_base == -1)
600 		goto irq;
601 
602 	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
603 				     desc->resindex_imr_base);
604 	if (mmio) {
605 		base = mmio->start;
606 		size = resource_size(mmio);
607 	} else {
608 		dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n",
609 			desc->resindex_imr_base);
610 		return -ENODEV;
611 	}
612 
613 	/* some BIOSes don't map IMR */
614 	if (base == 0x55aa55aa || base == 0x0) {
615 		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
616 		goto irq;
617 	}
618 
619 	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
620 	sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
621 	if (!sdev->bar[BYT_IMR_BAR]) {
622 		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
623 			base, size);
624 		return -ENODEV;
625 	}
626 	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
627 
628 irq:
629 	/* register our IRQ */
630 	sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
631 	if (sdev->ipc_irq < 0)
632 		return sdev->ipc_irq;
633 
634 	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
635 	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
636 					byt_irq_handler, byt_irq_thread,
637 					IRQF_SHARED, "AudioDSP", sdev);
638 	if (ret < 0) {
639 		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
640 			sdev->ipc_irq);
641 		return ret;
642 	}
643 
644 	/* enable Interrupt from both sides */
645 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
646 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
647 
648 	/* set default mailbox offset for FW ready message */
649 	sdev->dsp_box.offset = MBOX_OFFSET;
650 
651 	return ret;
652 }
653 
654 /* baytrail ops */
655 const struct snd_sof_dsp_ops sof_byt_ops = {
656 	/* device init */
657 	.probe		= byt_acpi_probe,
658 
659 	/* DSP core boot / reset */
660 	.run		= byt_run,
661 	.reset		= byt_reset,
662 
663 	/* Register IO */
664 	.write		= sof_io_write,
665 	.read		= sof_io_read,
666 	.write64	= sof_io_write64,
667 	.read64		= sof_io_read64,
668 
669 	/* Block IO */
670 	.block_read	= sof_block_read,
671 	.block_write	= sof_block_write,
672 
673 	/* doorbell */
674 	.irq_handler	= byt_irq_handler,
675 	.irq_thread	= byt_irq_thread,
676 
677 	/* ipc */
678 	.send_msg	= byt_send_msg,
679 	.fw_ready	= sof_fw_ready,
680 	.get_mailbox_offset = byt_get_mailbox_offset,
681 	.get_window_offset = byt_get_window_offset,
682 
683 	.ipc_msg_data	= intel_ipc_msg_data,
684 	.ipc_pcm_params	= intel_ipc_pcm_params,
685 
686 	/* debug */
687 	.debug_map	= byt_debugfs,
688 	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
689 	.dbg_dump	= byt_dump,
690 
691 	/* stream callbacks */
692 	.pcm_open	= intel_pcm_open,
693 	.pcm_close	= intel_pcm_close,
694 
695 	/* module loading */
696 	.load_module	= snd_sof_parse_module_memcpy,
697 
698 	/*Firmware loading */
699 	.load_firmware	= snd_sof_load_firmware_memcpy,
700 
701 	/* DAI drivers */
702 	.drv = byt_dai,
703 	.num_drv = 3, /* we have only 3 SSPs on byt*/
704 
705 	/* ALSA HW info flags */
706 	.hw_info =	SNDRV_PCM_INFO_MMAP |
707 			SNDRV_PCM_INFO_MMAP_VALID |
708 			SNDRV_PCM_INFO_INTERLEAVED |
709 			SNDRV_PCM_INFO_PAUSE |
710 			SNDRV_PCM_INFO_BATCH,
711 };
712 EXPORT_SYMBOL(sof_byt_ops);
713 
714 const struct sof_intel_dsp_desc byt_chip_info = {
715 	.cores_num = 1,
716 	.cores_mask = 1,
717 };
718 EXPORT_SYMBOL(byt_chip_info);
719 
720 /* cherrytrail and braswell ops */
721 const struct snd_sof_dsp_ops sof_cht_ops = {
722 	/* device init */
723 	.probe		= byt_acpi_probe,
724 
725 	/* DSP core boot / reset */
726 	.run		= byt_run,
727 	.reset		= byt_reset,
728 
729 	/* Register IO */
730 	.write		= sof_io_write,
731 	.read		= sof_io_read,
732 	.write64	= sof_io_write64,
733 	.read64		= sof_io_read64,
734 
735 	/* Block IO */
736 	.block_read	= sof_block_read,
737 	.block_write	= sof_block_write,
738 
739 	/* doorbell */
740 	.irq_handler	= byt_irq_handler,
741 	.irq_thread	= byt_irq_thread,
742 
743 	/* ipc */
744 	.send_msg	= byt_send_msg,
745 	.fw_ready	= sof_fw_ready,
746 	.get_mailbox_offset = byt_get_mailbox_offset,
747 	.get_window_offset = byt_get_window_offset,
748 
749 	.ipc_msg_data	= intel_ipc_msg_data,
750 	.ipc_pcm_params	= intel_ipc_pcm_params,
751 
752 	/* debug */
753 	.debug_map	= cht_debugfs,
754 	.debug_map_count	= ARRAY_SIZE(cht_debugfs),
755 	.dbg_dump	= byt_dump,
756 
757 	/* stream callbacks */
758 	.pcm_open	= intel_pcm_open,
759 	.pcm_close	= intel_pcm_close,
760 
761 	/* module loading */
762 	.load_module	= snd_sof_parse_module_memcpy,
763 
764 	/*Firmware loading */
765 	.load_firmware	= snd_sof_load_firmware_memcpy,
766 
767 	/* DAI drivers */
768 	.drv = byt_dai,
769 	/* all 6 SSPs may be available for cherrytrail */
770 	.num_drv = ARRAY_SIZE(byt_dai),
771 
772 	/* ALSA HW info flags */
773 	.hw_info =	SNDRV_PCM_INFO_MMAP |
774 			SNDRV_PCM_INFO_MMAP_VALID |
775 			SNDRV_PCM_INFO_INTERLEAVED |
776 			SNDRV_PCM_INFO_PAUSE |
777 			SNDRV_PCM_INFO_BATCH,
778 };
779 EXPORT_SYMBOL(sof_cht_ops);
780 
781 const struct sof_intel_dsp_desc cht_chip_info = {
782 	.cores_num = 1,
783 	.cores_mask = 1,
784 };
785 EXPORT_SYMBOL(cht_chip_info);
786 
787 #endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */
788 
789 MODULE_LICENSE("Dual BSD/GPL");
790