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