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