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