xref: /openbmc/linux/sound/soc/sof/intel/byt.c (revision 285880a2)
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 #include "../sof-audio.h"
21 
22 /* DSP memories */
23 #define IRAM_OFFSET		0x0C0000
24 #define IRAM_SIZE		(80 * 1024)
25 #define DRAM_OFFSET		0x100000
26 #define DRAM_SIZE		(160 * 1024)
27 #define SHIM_OFFSET		0x140000
28 #define SHIM_SIZE		0x100
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,
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,
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 	u32 status, panic, imrd, imrx;
150 
151 	/* now try generic SOF status messages */
152 	status = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCD);
153 	panic = snd_sof_dsp_read(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_read(sdev, BYT_DSP_BAR, SHIM_IMRX);
161 	imrd = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IMRD);
162 	dev_err(sdev->dev,
163 		"error: ipc host -> DSP: pending %s complete %s raw 0x%8.8x\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%8.8x\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%8.8x\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%8.8x\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 static void byt_machine_select(struct snd_sof_dev *sdev)
387 {
388 	struct snd_sof_pdata *sof_pdata = sdev->pdata;
389 	const struct sof_dev_desc *desc = sof_pdata->desc;
390 	struct snd_soc_acpi_mach *mach;
391 
392 	mach = snd_soc_acpi_find_machine(desc->machines);
393 	if (!mach) {
394 		dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
395 		return;
396 	}
397 
398 	sof_pdata->tplg_filename = mach->sof_tplg_filename;
399 	mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc;
400 	sof_pdata->machine = mach;
401 }
402 
403 static void byt_set_mach_params(const struct snd_soc_acpi_mach *mach,
404 				struct device *dev)
405 {
406 	struct snd_soc_acpi_mach_params *mach_params;
407 
408 	mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params;
409 	mach_params->platform = dev_name(dev);
410 }
411 
412 /* Baytrail DAIs */
413 static struct snd_soc_dai_driver byt_dai[] = {
414 {
415 	.name = "ssp0-port",
416 },
417 {
418 	.name = "ssp1-port",
419 },
420 {
421 	.name = "ssp2-port",
422 },
423 {
424 	.name = "ssp3-port",
425 },
426 {
427 	.name = "ssp4-port",
428 },
429 {
430 	.name = "ssp5-port",
431 },
432 };
433 
434 /*
435  * Probe and remove.
436  */
437 
438 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
439 
440 static int tangier_pci_probe(struct snd_sof_dev *sdev)
441 {
442 	struct snd_sof_pdata *pdata = sdev->pdata;
443 	const struct sof_dev_desc *desc = pdata->desc;
444 	struct pci_dev *pci = to_pci_dev(sdev->dev);
445 	u32 base, size;
446 	int ret;
447 
448 	/* DSP DMA can only access low 31 bits of host memory */
449 	ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31));
450 	if (ret < 0) {
451 		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
452 		return ret;
453 	}
454 
455 	/* LPE base */
456 	base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET;
457 	size = BYT_PCI_BAR_SIZE;
458 
459 	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
460 	sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
461 	if (!sdev->bar[BYT_DSP_BAR]) {
462 		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
463 			base, size);
464 		return -ENODEV;
465 	}
466 	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
467 
468 	/* IMR base - optional */
469 	if (desc->resindex_imr_base == -1)
470 		goto irq;
471 
472 	base = pci_resource_start(pci, desc->resindex_imr_base);
473 	size = pci_resource_len(pci, desc->resindex_imr_base);
474 
475 	/* some BIOSes don't map IMR */
476 	if (base == 0x55aa55aa || base == 0x0) {
477 		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
478 		goto irq;
479 	}
480 
481 	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
482 	sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
483 	if (!sdev->bar[BYT_IMR_BAR]) {
484 		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
485 			base, size);
486 		return -ENODEV;
487 	}
488 	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
489 
490 irq:
491 	/* register our IRQ */
492 	sdev->ipc_irq = pci->irq;
493 	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
494 	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
495 					byt_irq_handler, byt_irq_thread,
496 					0, "AudioDSP", sdev);
497 	if (ret < 0) {
498 		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
499 			sdev->ipc_irq);
500 		return ret;
501 	}
502 
503 	/* enable Interrupt from both sides */
504 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
505 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
506 
507 	/* set default mailbox offset for FW ready message */
508 	sdev->dsp_box.offset = MBOX_OFFSET;
509 
510 	return ret;
511 }
512 
513 const struct snd_sof_dsp_ops sof_tng_ops = {
514 	/* device init */
515 	.probe		= tangier_pci_probe,
516 
517 	/* DSP core boot / reset */
518 	.run		= byt_run,
519 	.reset		= byt_reset,
520 
521 	/* Register IO */
522 	.write		= sof_io_write,
523 	.read		= sof_io_read,
524 	.write64	= sof_io_write64,
525 	.read64		= sof_io_read64,
526 
527 	/* Block IO */
528 	.block_read	= sof_block_read,
529 	.block_write	= sof_block_write,
530 
531 	/* doorbell */
532 	.irq_handler	= byt_irq_handler,
533 	.irq_thread	= byt_irq_thread,
534 
535 	/* ipc */
536 	.send_msg	= byt_send_msg,
537 	.fw_ready	= sof_fw_ready,
538 	.get_mailbox_offset = byt_get_mailbox_offset,
539 	.get_window_offset = byt_get_window_offset,
540 
541 	.ipc_msg_data	= intel_ipc_msg_data,
542 	.ipc_pcm_params	= intel_ipc_pcm_params,
543 
544 	/* machine driver */
545 	.machine_select = byt_machine_select,
546 	.machine_register = sof_machine_register,
547 	.machine_unregister = sof_machine_unregister,
548 	.set_mach_params = byt_set_mach_params,
549 
550 	/* debug */
551 	.debug_map	= byt_debugfs,
552 	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
553 	.dbg_dump	= byt_dump,
554 
555 	/* stream callbacks */
556 	.pcm_open	= intel_pcm_open,
557 	.pcm_close	= intel_pcm_close,
558 
559 	/* module loading */
560 	.load_module	= snd_sof_parse_module_memcpy,
561 
562 	/*Firmware loading */
563 	.load_firmware	= snd_sof_load_firmware_memcpy,
564 
565 	/* DAI drivers */
566 	.drv = byt_dai,
567 	.num_drv = 3, /* we have only 3 SSPs on byt*/
568 
569 	/* ALSA HW info flags */
570 	.hw_info =	SNDRV_PCM_INFO_MMAP |
571 			SNDRV_PCM_INFO_MMAP_VALID |
572 			SNDRV_PCM_INFO_INTERLEAVED |
573 			SNDRV_PCM_INFO_PAUSE |
574 			SNDRV_PCM_INFO_BATCH,
575 };
576 EXPORT_SYMBOL(sof_tng_ops);
577 
578 const struct sof_intel_dsp_desc tng_chip_info = {
579 	.cores_num = 1,
580 	.cores_mask = 1,
581 };
582 EXPORT_SYMBOL(tng_chip_info);
583 
584 #endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */
585 
586 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
587 
588 static int byt_acpi_probe(struct snd_sof_dev *sdev)
589 {
590 	struct snd_sof_pdata *pdata = sdev->pdata;
591 	const struct sof_dev_desc *desc = pdata->desc;
592 	struct platform_device *pdev =
593 		container_of(sdev->dev, struct platform_device, dev);
594 	struct resource *mmio;
595 	u32 base, size;
596 	int ret;
597 
598 	/* DSP DMA can only access low 31 bits of host memory */
599 	ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
600 	if (ret < 0) {
601 		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
602 		return ret;
603 	}
604 
605 	/* LPE base */
606 	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
607 				     desc->resindex_lpe_base);
608 	if (mmio) {
609 		base = mmio->start;
610 		size = resource_size(mmio);
611 	} else {
612 		dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
613 			desc->resindex_lpe_base);
614 		return -EINVAL;
615 	}
616 
617 	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
618 	sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
619 	if (!sdev->bar[BYT_DSP_BAR]) {
620 		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
621 			base, size);
622 		return -ENODEV;
623 	}
624 	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
625 
626 	/* TODO: add offsets */
627 	sdev->mmio_bar = BYT_DSP_BAR;
628 	sdev->mailbox_bar = BYT_DSP_BAR;
629 
630 	/* IMR base - optional */
631 	if (desc->resindex_imr_base == -1)
632 		goto irq;
633 
634 	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
635 				     desc->resindex_imr_base);
636 	if (mmio) {
637 		base = mmio->start;
638 		size = resource_size(mmio);
639 	} else {
640 		dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n",
641 			desc->resindex_imr_base);
642 		return -ENODEV;
643 	}
644 
645 	/* some BIOSes don't map IMR */
646 	if (base == 0x55aa55aa || base == 0x0) {
647 		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
648 		goto irq;
649 	}
650 
651 	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
652 	sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
653 	if (!sdev->bar[BYT_IMR_BAR]) {
654 		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
655 			base, size);
656 		return -ENODEV;
657 	}
658 	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
659 
660 irq:
661 	/* register our IRQ */
662 	sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
663 	if (sdev->ipc_irq < 0)
664 		return sdev->ipc_irq;
665 
666 	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
667 	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
668 					byt_irq_handler, byt_irq_thread,
669 					IRQF_SHARED, "AudioDSP", sdev);
670 	if (ret < 0) {
671 		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
672 			sdev->ipc_irq);
673 		return ret;
674 	}
675 
676 	/* enable Interrupt from both sides */
677 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
678 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
679 
680 	/* set default mailbox offset for FW ready message */
681 	sdev->dsp_box.offset = MBOX_OFFSET;
682 
683 	return ret;
684 }
685 
686 /* baytrail ops */
687 const struct snd_sof_dsp_ops sof_byt_ops = {
688 	/* device init */
689 	.probe		= byt_acpi_probe,
690 
691 	/* DSP core boot / reset */
692 	.run		= byt_run,
693 	.reset		= byt_reset,
694 
695 	/* Register IO */
696 	.write		= sof_io_write,
697 	.read		= sof_io_read,
698 	.write64	= sof_io_write64,
699 	.read64		= sof_io_read64,
700 
701 	/* Block IO */
702 	.block_read	= sof_block_read,
703 	.block_write	= sof_block_write,
704 
705 	/* doorbell */
706 	.irq_handler	= byt_irq_handler,
707 	.irq_thread	= byt_irq_thread,
708 
709 	/* ipc */
710 	.send_msg	= byt_send_msg,
711 	.fw_ready	= sof_fw_ready,
712 	.get_mailbox_offset = byt_get_mailbox_offset,
713 	.get_window_offset = byt_get_window_offset,
714 
715 	.ipc_msg_data	= intel_ipc_msg_data,
716 	.ipc_pcm_params	= intel_ipc_pcm_params,
717 
718 	/* machine driver */
719 	.machine_select = byt_machine_select,
720 	.machine_register = sof_machine_register,
721 	.machine_unregister = sof_machine_unregister,
722 	.set_mach_params = byt_set_mach_params,
723 
724 	/* debug */
725 	.debug_map	= byt_debugfs,
726 	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
727 	.dbg_dump	= byt_dump,
728 
729 	/* stream callbacks */
730 	.pcm_open	= intel_pcm_open,
731 	.pcm_close	= intel_pcm_close,
732 
733 	/* module loading */
734 	.load_module	= snd_sof_parse_module_memcpy,
735 
736 	/*Firmware loading */
737 	.load_firmware	= snd_sof_load_firmware_memcpy,
738 
739 	/* DAI drivers */
740 	.drv = byt_dai,
741 	.num_drv = 3, /* we have only 3 SSPs on byt*/
742 
743 	/* ALSA HW info flags */
744 	.hw_info =	SNDRV_PCM_INFO_MMAP |
745 			SNDRV_PCM_INFO_MMAP_VALID |
746 			SNDRV_PCM_INFO_INTERLEAVED |
747 			SNDRV_PCM_INFO_PAUSE |
748 			SNDRV_PCM_INFO_BATCH,
749 };
750 EXPORT_SYMBOL(sof_byt_ops);
751 
752 const struct sof_intel_dsp_desc byt_chip_info = {
753 	.cores_num = 1,
754 	.cores_mask = 1,
755 };
756 EXPORT_SYMBOL(byt_chip_info);
757 
758 /* cherrytrail and braswell ops */
759 const struct snd_sof_dsp_ops sof_cht_ops = {
760 	/* device init */
761 	.probe		= byt_acpi_probe,
762 
763 	/* DSP core boot / reset */
764 	.run		= byt_run,
765 	.reset		= byt_reset,
766 
767 	/* Register IO */
768 	.write		= sof_io_write,
769 	.read		= sof_io_read,
770 	.write64	= sof_io_write64,
771 	.read64		= sof_io_read64,
772 
773 	/* Block IO */
774 	.block_read	= sof_block_read,
775 	.block_write	= sof_block_write,
776 
777 	/* doorbell */
778 	.irq_handler	= byt_irq_handler,
779 	.irq_thread	= byt_irq_thread,
780 
781 	/* ipc */
782 	.send_msg	= byt_send_msg,
783 	.fw_ready	= sof_fw_ready,
784 	.get_mailbox_offset = byt_get_mailbox_offset,
785 	.get_window_offset = byt_get_window_offset,
786 
787 	.ipc_msg_data	= intel_ipc_msg_data,
788 	.ipc_pcm_params	= intel_ipc_pcm_params,
789 
790 	/* machine driver */
791 	.machine_select = byt_machine_select,
792 	.machine_register = sof_machine_register,
793 	.machine_unregister = sof_machine_unregister,
794 	.set_mach_params = byt_set_mach_params,
795 
796 	/* debug */
797 	.debug_map	= cht_debugfs,
798 	.debug_map_count	= ARRAY_SIZE(cht_debugfs),
799 	.dbg_dump	= byt_dump,
800 
801 	/* stream callbacks */
802 	.pcm_open	= intel_pcm_open,
803 	.pcm_close	= intel_pcm_close,
804 
805 	/* module loading */
806 	.load_module	= snd_sof_parse_module_memcpy,
807 
808 	/*Firmware loading */
809 	.load_firmware	= snd_sof_load_firmware_memcpy,
810 
811 	/* DAI drivers */
812 	.drv = byt_dai,
813 	/* all 6 SSPs may be available for cherrytrail */
814 	.num_drv = ARRAY_SIZE(byt_dai),
815 
816 	/* ALSA HW info flags */
817 	.hw_info =	SNDRV_PCM_INFO_MMAP |
818 			SNDRV_PCM_INFO_MMAP_VALID |
819 			SNDRV_PCM_INFO_INTERLEAVED |
820 			SNDRV_PCM_INFO_PAUSE |
821 			SNDRV_PCM_INFO_BATCH,
822 };
823 EXPORT_SYMBOL(sof_cht_ops);
824 
825 const struct sof_intel_dsp_desc cht_chip_info = {
826 	.cores_num = 1,
827 	.cores_mask = 1,
828 };
829 EXPORT_SYMBOL(cht_chip_info);
830 
831 #endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */
832 
833 MODULE_LICENSE("Dual BSD/GPL");
834