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