xref: /openbmc/linux/sound/soc/sof/intel/byt.c (revision 6fbbc18e)
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 	/* first read regsisters */
269 	sof_mailbox_read(sdev, sdev->dsp_oops_offset, xoops, sizeof(*xoops));
270 
271 	/* then get panic info */
272 	sof_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops),
273 			 panic_info, sizeof(*panic_info));
274 
275 	/* then get the stack */
276 	sof_mailbox_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops) +
277 			   sizeof(*panic_info), stack,
278 			   stack_words * sizeof(u32));
279 }
280 
281 static void byt_dump(struct snd_sof_dev *sdev, u32 flags)
282 {
283 	struct sof_ipc_dsp_oops_xtensa xoops;
284 	struct sof_ipc_panic_info panic_info;
285 	u32 stack[BYT_STACK_DUMP_SIZE];
286 	u32 status, panic;
287 
288 	/* now try generic SOF status messages */
289 	status = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCD);
290 	panic = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCX);
291 	byt_get_registers(sdev, &xoops, &panic_info, stack,
292 			  BYT_STACK_DUMP_SIZE);
293 	snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
294 			   BYT_STACK_DUMP_SIZE);
295 }
296 
297 /*
298  * IPC Doorbell IRQ handler and thread.
299  */
300 
301 static irqreturn_t byt_irq_handler(int irq, void *context)
302 {
303 	struct snd_sof_dev *sdev = context;
304 	u64 isr;
305 	int ret = IRQ_NONE;
306 
307 	/* Interrupt arrived, check src */
308 	isr = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_ISRX);
309 	if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY))
310 		ret = IRQ_WAKE_THREAD;
311 
312 	return ret;
313 }
314 
315 static irqreturn_t byt_irq_thread(int irq, void *context)
316 {
317 	struct snd_sof_dev *sdev = context;
318 	u64 ipcx, ipcd;
319 	u64 imrx;
320 
321 	imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX);
322 	ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
323 
324 	/* reply message from DSP */
325 	if (ipcx & SHIM_BYT_IPCX_DONE &&
326 	    !(imrx & SHIM_IMRX_DONE)) {
327 		/* Mask Done interrupt before first */
328 		snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR,
329 						   SHIM_IMRX,
330 						   SHIM_IMRX_DONE,
331 						   SHIM_IMRX_DONE);
332 
333 		spin_lock_irq(&sdev->ipc_lock);
334 
335 		/*
336 		 * handle immediate reply from DSP core. If the msg is
337 		 * found, set done bit in cmd_done which is called at the
338 		 * end of message processing function, else set it here
339 		 * because the done bit can't be set in cmd_done function
340 		 * which is triggered by msg
341 		 */
342 		byt_get_reply(sdev);
343 		snd_sof_ipc_reply(sdev, ipcx);
344 
345 		byt_dsp_done(sdev);
346 
347 		spin_unlock_irq(&sdev->ipc_lock);
348 	}
349 
350 	/* new message from DSP */
351 	ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
352 	if (ipcd & SHIM_BYT_IPCD_BUSY &&
353 	    !(imrx & SHIM_IMRX_BUSY)) {
354 		/* Mask Busy interrupt before return */
355 		snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR,
356 						   SHIM_IMRX,
357 						   SHIM_IMRX_BUSY,
358 						   SHIM_IMRX_BUSY);
359 
360 		/* Handle messages from DSP Core */
361 		if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
362 			snd_sof_dsp_panic(sdev, BYT_PANIC_OFFSET(ipcd) +
363 					  MBOX_OFFSET);
364 		} else {
365 			snd_sof_ipc_msgs_rx(sdev);
366 		}
367 
368 		byt_host_done(sdev);
369 	}
370 
371 	return IRQ_HANDLED;
372 }
373 
374 static int byt_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
375 {
376 	/* send the message */
377 	sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
378 			  msg->msg_size);
379 	snd_sof_dsp_write64(sdev, BYT_DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY);
380 
381 	return 0;
382 }
383 
384 static void byt_get_reply(struct snd_sof_dev *sdev)
385 {
386 	struct snd_sof_ipc_msg *msg = sdev->msg;
387 	struct sof_ipc_reply reply;
388 	int ret = 0;
389 
390 	/*
391 	 * Sometimes, there is unexpected reply ipc arriving. The reply
392 	 * ipc belongs to none of the ipcs sent from driver.
393 	 * In this case, the driver must ignore the ipc.
394 	 */
395 	if (!msg) {
396 		dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n");
397 		return;
398 	}
399 
400 	/* get reply */
401 	sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
402 
403 	if (reply.error < 0) {
404 		memcpy(msg->reply_data, &reply, sizeof(reply));
405 		ret = reply.error;
406 	} else {
407 		/* reply correct size ? */
408 		if (reply.hdr.size != msg->reply_size) {
409 			dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
410 				msg->reply_size, reply.hdr.size);
411 			ret = -EINVAL;
412 		}
413 
414 		/* read the message */
415 		if (msg->reply_size > 0)
416 			sof_mailbox_read(sdev, sdev->host_box.offset,
417 					 msg->reply_data, msg->reply_size);
418 	}
419 
420 	msg->reply_error = ret;
421 }
422 
423 static void byt_host_done(struct snd_sof_dev *sdev)
424 {
425 	/* clear BUSY bit and set DONE bit - accept new messages */
426 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCD,
427 					   SHIM_BYT_IPCD_BUSY |
428 					   SHIM_BYT_IPCD_DONE,
429 					   SHIM_BYT_IPCD_DONE);
430 
431 	/* unmask busy interrupt */
432 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
433 					   SHIM_IMRX_BUSY, 0);
434 }
435 
436 static void byt_dsp_done(struct snd_sof_dev *sdev)
437 {
438 	/* clear DONE bit - tell DSP we have completed */
439 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX,
440 					   SHIM_BYT_IPCX_DONE, 0);
441 
442 	/* unmask Done interrupt */
443 	snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX,
444 					   SHIM_IMRX_DONE, 0);
445 }
446 
447 /*
448  * DSP control.
449  */
450 
451 static int byt_run(struct snd_sof_dev *sdev)
452 {
453 	int tries = 10;
454 
455 	/* release stall and wait to unstall */
456 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
457 				  SHIM_BYT_CSR_STALL, 0x0);
458 	while (tries--) {
459 		if (!(snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_CSR) &
460 		      SHIM_BYT_CSR_PWAITMODE))
461 			break;
462 		msleep(100);
463 	}
464 	if (tries < 0) {
465 		dev_err(sdev->dev, "error:  unable to run DSP firmware\n");
466 		byt_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX);
467 		return -ENODEV;
468 	}
469 
470 	/* return init core mask */
471 	return 1;
472 }
473 
474 static int byt_reset(struct snd_sof_dev *sdev)
475 {
476 	/* put DSP into reset, set reset vector and stall */
477 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
478 				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
479 				  SHIM_BYT_CSR_STALL,
480 				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL |
481 				  SHIM_BYT_CSR_STALL);
482 
483 	usleep_range(10, 15);
484 
485 	/* take DSP out of reset and keep stalled for FW loading */
486 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR,
487 				  SHIM_BYT_CSR_RST, 0);
488 
489 	return 0;
490 }
491 
492 /* Baytrail DAIs */
493 static struct snd_soc_dai_driver byt_dai[] = {
494 {
495 	.name = "ssp0-port",
496 },
497 {
498 	.name = "ssp1-port",
499 },
500 {
501 	.name = "ssp2-port",
502 },
503 {
504 	.name = "ssp3-port",
505 },
506 {
507 	.name = "ssp4-port",
508 },
509 {
510 	.name = "ssp5-port",
511 },
512 };
513 
514 /*
515  * Probe and remove.
516  */
517 
518 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
519 
520 static int tangier_pci_probe(struct snd_sof_dev *sdev)
521 {
522 	struct snd_sof_pdata *pdata = sdev->pdata;
523 	const struct sof_dev_desc *desc = pdata->desc;
524 	struct pci_dev *pci = to_pci_dev(sdev->dev);
525 	u32 base, size;
526 	int ret;
527 
528 	/* DSP DMA can only access low 31 bits of host memory */
529 	ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31));
530 	if (ret < 0) {
531 		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
532 		return ret;
533 	}
534 
535 	/* LPE base */
536 	base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET;
537 	size = BYT_PCI_BAR_SIZE;
538 
539 	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
540 	sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
541 	if (!sdev->bar[BYT_DSP_BAR]) {
542 		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
543 			base, size);
544 		return -ENODEV;
545 	}
546 	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
547 
548 	/* IMR base - optional */
549 	if (desc->resindex_imr_base == -1)
550 		goto irq;
551 
552 	base = pci_resource_start(pci, desc->resindex_imr_base);
553 	size = pci_resource_len(pci, desc->resindex_imr_base);
554 
555 	/* some BIOSes don't map IMR */
556 	if (base == 0x55aa55aa || base == 0x0) {
557 		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
558 		goto irq;
559 	}
560 
561 	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
562 	sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
563 	if (!sdev->bar[BYT_IMR_BAR]) {
564 		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
565 			base, size);
566 		return -ENODEV;
567 	}
568 	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
569 
570 irq:
571 	/* register our IRQ */
572 	sdev->ipc_irq = pci->irq;
573 	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
574 	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
575 					byt_irq_handler, byt_irq_thread,
576 					0, "AudioDSP", sdev);
577 	if (ret < 0) {
578 		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
579 			sdev->ipc_irq);
580 		return ret;
581 	}
582 
583 	/* enable Interrupt from both sides */
584 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
585 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
586 
587 	/* set default mailbox offset for FW ready message */
588 	sdev->dsp_box.offset = MBOX_OFFSET;
589 
590 	return ret;
591 }
592 
593 const struct snd_sof_dsp_ops sof_tng_ops = {
594 	/* device init */
595 	.probe		= tangier_pci_probe,
596 
597 	/* DSP core boot / reset */
598 	.run		= byt_run,
599 	.reset		= byt_reset,
600 
601 	/* Register IO */
602 	.write		= sof_io_write,
603 	.read		= sof_io_read,
604 	.write64	= sof_io_write64,
605 	.read64		= sof_io_read64,
606 
607 	/* Block IO */
608 	.block_read	= sof_block_read,
609 	.block_write	= sof_block_write,
610 
611 	/* doorbell */
612 	.irq_handler	= byt_irq_handler,
613 	.irq_thread	= byt_irq_thread,
614 
615 	/* ipc */
616 	.send_msg	= byt_send_msg,
617 	.fw_ready	= byt_fw_ready,
618 
619 	.ipc_msg_data	= intel_ipc_msg_data,
620 	.ipc_pcm_params	= intel_ipc_pcm_params,
621 
622 	/* debug */
623 	.debug_map	= byt_debugfs,
624 	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
625 	.dbg_dump	= byt_dump,
626 
627 	/* stream callbacks */
628 	.pcm_open	= intel_pcm_open,
629 	.pcm_close	= intel_pcm_close,
630 
631 	/* module loading */
632 	.load_module	= snd_sof_parse_module_memcpy,
633 
634 	/*Firmware loading */
635 	.load_firmware	= snd_sof_load_firmware_memcpy,
636 
637 	/* DAI drivers */
638 	.drv = byt_dai,
639 	.num_drv = 3, /* we have only 3 SSPs on byt*/
640 };
641 EXPORT_SYMBOL(sof_tng_ops);
642 
643 const struct sof_intel_dsp_desc tng_chip_info = {
644 	.cores_num = 1,
645 	.cores_mask = 1,
646 };
647 EXPORT_SYMBOL(tng_chip_info);
648 
649 #endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */
650 
651 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
652 
653 static int byt_acpi_probe(struct snd_sof_dev *sdev)
654 {
655 	struct snd_sof_pdata *pdata = sdev->pdata;
656 	const struct sof_dev_desc *desc = pdata->desc;
657 	struct platform_device *pdev =
658 		container_of(sdev->dev, struct platform_device, dev);
659 	struct resource *mmio;
660 	u32 base, size;
661 	int ret;
662 
663 	/* DSP DMA can only access low 31 bits of host memory */
664 	ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
665 	if (ret < 0) {
666 		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
667 		return ret;
668 	}
669 
670 	/* LPE base */
671 	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
672 				     desc->resindex_lpe_base);
673 	if (mmio) {
674 		base = mmio->start;
675 		size = resource_size(mmio);
676 	} else {
677 		dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
678 			desc->resindex_lpe_base);
679 		return -EINVAL;
680 	}
681 
682 	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
683 	sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
684 	if (!sdev->bar[BYT_DSP_BAR]) {
685 		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
686 			base, size);
687 		return -ENODEV;
688 	}
689 	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]);
690 
691 	/* TODO: add offsets */
692 	sdev->mmio_bar = BYT_DSP_BAR;
693 	sdev->mailbox_bar = BYT_DSP_BAR;
694 
695 	/* IMR base - optional */
696 	if (desc->resindex_imr_base == -1)
697 		goto irq;
698 
699 	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
700 				     desc->resindex_imr_base);
701 	if (mmio) {
702 		base = mmio->start;
703 		size = resource_size(mmio);
704 	} else {
705 		dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n",
706 			desc->resindex_imr_base);
707 		return -ENODEV;
708 	}
709 
710 	/* some BIOSes don't map IMR */
711 	if (base == 0x55aa55aa || base == 0x0) {
712 		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
713 		goto irq;
714 	}
715 
716 	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
717 	sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size);
718 	if (!sdev->bar[BYT_IMR_BAR]) {
719 		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
720 			base, size);
721 		return -ENODEV;
722 	}
723 	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]);
724 
725 irq:
726 	/* register our IRQ */
727 	sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
728 	if (sdev->ipc_irq < 0) {
729 		dev_err(sdev->dev, "error: failed to get IRQ at index %d\n",
730 			desc->irqindex_host_ipc);
731 		return sdev->ipc_irq;
732 	}
733 
734 	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
735 	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
736 					byt_irq_handler, byt_irq_thread,
737 					IRQF_SHARED, "AudioDSP", sdev);
738 	if (ret < 0) {
739 		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
740 			sdev->ipc_irq);
741 		return ret;
742 	}
743 
744 	/* enable Interrupt from both sides */
745 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0);
746 	snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0);
747 
748 	/* set default mailbox offset for FW ready message */
749 	sdev->dsp_box.offset = MBOX_OFFSET;
750 
751 	return ret;
752 }
753 
754 /* baytrail ops */
755 const struct snd_sof_dsp_ops sof_byt_ops = {
756 	/* device init */
757 	.probe		= byt_acpi_probe,
758 
759 	/* DSP core boot / reset */
760 	.run		= byt_run,
761 	.reset		= byt_reset,
762 
763 	/* Register IO */
764 	.write		= sof_io_write,
765 	.read		= sof_io_read,
766 	.write64	= sof_io_write64,
767 	.read64		= sof_io_read64,
768 
769 	/* Block IO */
770 	.block_read	= sof_block_read,
771 	.block_write	= sof_block_write,
772 
773 	/* doorbell */
774 	.irq_handler	= byt_irq_handler,
775 	.irq_thread	= byt_irq_thread,
776 
777 	/* ipc */
778 	.send_msg	= byt_send_msg,
779 	.fw_ready	= byt_fw_ready,
780 
781 	.ipc_msg_data	= intel_ipc_msg_data,
782 	.ipc_pcm_params	= intel_ipc_pcm_params,
783 
784 	/* debug */
785 	.debug_map	= byt_debugfs,
786 	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
787 	.dbg_dump	= byt_dump,
788 
789 	/* stream callbacks */
790 	.pcm_open	= intel_pcm_open,
791 	.pcm_close	= intel_pcm_close,
792 
793 	/* module loading */
794 	.load_module	= snd_sof_parse_module_memcpy,
795 
796 	/*Firmware loading */
797 	.load_firmware	= snd_sof_load_firmware_memcpy,
798 
799 	/* DAI drivers */
800 	.drv = byt_dai,
801 	.num_drv = 3, /* we have only 3 SSPs on byt*/
802 };
803 EXPORT_SYMBOL(sof_byt_ops);
804 
805 const struct sof_intel_dsp_desc byt_chip_info = {
806 	.cores_num = 1,
807 	.cores_mask = 1,
808 };
809 EXPORT_SYMBOL(byt_chip_info);
810 
811 /* cherrytrail and braswell ops */
812 const struct snd_sof_dsp_ops sof_cht_ops = {
813 	/* device init */
814 	.probe		= byt_acpi_probe,
815 
816 	/* DSP core boot / reset */
817 	.run		= byt_run,
818 	.reset		= byt_reset,
819 
820 	/* Register IO */
821 	.write		= sof_io_write,
822 	.read		= sof_io_read,
823 	.write64	= sof_io_write64,
824 	.read64		= sof_io_read64,
825 
826 	/* Block IO */
827 	.block_read	= sof_block_read,
828 	.block_write	= sof_block_write,
829 
830 	/* doorbell */
831 	.irq_handler	= byt_irq_handler,
832 	.irq_thread	= byt_irq_thread,
833 
834 	/* ipc */
835 	.send_msg	= byt_send_msg,
836 	.fw_ready	= byt_fw_ready,
837 
838 	.ipc_msg_data	= intel_ipc_msg_data,
839 	.ipc_pcm_params	= intel_ipc_pcm_params,
840 
841 	/* debug */
842 	.debug_map	= cht_debugfs,
843 	.debug_map_count	= ARRAY_SIZE(cht_debugfs),
844 	.dbg_dump	= byt_dump,
845 
846 	/* stream callbacks */
847 	.pcm_open	= intel_pcm_open,
848 	.pcm_close	= intel_pcm_close,
849 
850 	/* module loading */
851 	.load_module	= snd_sof_parse_module_memcpy,
852 
853 	/*Firmware loading */
854 	.load_firmware	= snd_sof_load_firmware_memcpy,
855 
856 	/* DAI drivers */
857 	.drv = byt_dai,
858 	/* all 6 SSPs may be available for cherrytrail */
859 	.num_drv = ARRAY_SIZE(byt_dai),
860 };
861 EXPORT_SYMBOL(sof_cht_ops);
862 
863 const struct sof_intel_dsp_desc cht_chip_info = {
864 	.cores_num = 1,
865 	.cores_mask = 1,
866 };
867 EXPORT_SYMBOL(cht_chip_info);
868 
869 #endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */
870 
871 MODULE_LICENSE("Dual BSD/GPL");
872