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