]> asedeno.scripts.mit.edu Git - linux.git/blob - sound/soc/sof/intel/bdw.c
Merge branch 'for-5.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[linux.git] / sound / soc / sof / intel / bdw.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 Broadwell
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
22 /* BARs */
23 #define BDW_DSP_BAR 0
24 #define BDW_PCI_BAR 1
25
26 /*
27  * Debug
28  */
29
30 /* DSP memories for BDW */
31 #define IRAM_OFFSET     0xA0000
32 #define BDW_IRAM_SIZE       (10 * 32 * 1024)
33 #define DRAM_OFFSET     0x00000
34 #define BDW_DRAM_SIZE       (20 * 32 * 1024)
35 #define SHIM_OFFSET     0xFB000
36 #define SHIM_SIZE       0x100
37 #define MBOX_OFFSET     0x9E000
38 #define MBOX_SIZE       0x1000
39 #define MBOX_DUMP_SIZE 0x30
40 #define EXCEPT_OFFSET   0x800
41 #define EXCEPT_MAX_HDR_SIZE     0x400
42
43 /* DSP peripherals */
44 #define DMAC0_OFFSET    0xFE000
45 #define DMAC1_OFFSET    0xFF000
46 #define DMAC_SIZE       0x420
47 #define SSP0_OFFSET     0xFC000
48 #define SSP1_OFFSET     0xFD000
49 #define SSP_SIZE        0x100
50
51 #define BDW_STACK_DUMP_SIZE     32
52
53 #define BDW_PANIC_OFFSET(x)     ((x) & 0xFFFF)
54
55 static const struct snd_sof_debugfs_map bdw_debugfs[] = {
56         {"dmac0", BDW_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
57          SOF_DEBUGFS_ACCESS_ALWAYS},
58         {"dmac1", BDW_DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
59          SOF_DEBUGFS_ACCESS_ALWAYS},
60         {"ssp0", BDW_DSP_BAR, SSP0_OFFSET, SSP_SIZE,
61          SOF_DEBUGFS_ACCESS_ALWAYS},
62         {"ssp1", BDW_DSP_BAR, SSP1_OFFSET, SSP_SIZE,
63          SOF_DEBUGFS_ACCESS_ALWAYS},
64         {"iram", BDW_DSP_BAR, IRAM_OFFSET, BDW_IRAM_SIZE,
65          SOF_DEBUGFS_ACCESS_D0_ONLY},
66         {"dram", BDW_DSP_BAR, DRAM_OFFSET, BDW_DRAM_SIZE,
67          SOF_DEBUGFS_ACCESS_D0_ONLY},
68         {"shim", BDW_DSP_BAR, SHIM_OFFSET, SHIM_SIZE,
69          SOF_DEBUGFS_ACCESS_ALWAYS},
70 };
71
72 static void bdw_host_done(struct snd_sof_dev *sdev);
73 static void bdw_dsp_done(struct snd_sof_dev *sdev);
74 static void bdw_get_reply(struct snd_sof_dev *sdev);
75
76 /*
77  * DSP Control.
78  */
79
80 static int bdw_run(struct snd_sof_dev *sdev)
81 {
82         /* set opportunistic mode on engine 0,1 for all channels */
83         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
84                                 SHIM_HMDC_HDDA_E0_ALLCH |
85                                 SHIM_HMDC_HDDA_E1_ALLCH, 0);
86
87         /* set DSP to RUN */
88         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
89                                          SHIM_CSR_STALL, 0x0);
90
91         /* return init core mask */
92         return 1;
93 }
94
95 static int bdw_reset(struct snd_sof_dev *sdev)
96 {
97         /* put DSP into reset and stall */
98         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
99                                          SHIM_CSR_RST | SHIM_CSR_STALL,
100                                          SHIM_CSR_RST | SHIM_CSR_STALL);
101
102         /* keep in reset for 10ms */
103         mdelay(10);
104
105         /* take DSP out of reset and keep stalled for FW loading */
106         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
107                                          SHIM_CSR_RST | SHIM_CSR_STALL,
108                                          SHIM_CSR_STALL);
109
110         return 0;
111 }
112
113 static int bdw_set_dsp_D0(struct snd_sof_dev *sdev)
114 {
115         int tries = 10;
116         u32 reg;
117
118         /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
119         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
120                                          PCI_VDRTCL2_DCLCGE |
121                                          PCI_VDRTCL2_DTCGE, 0);
122
123         /* Disable D3PG (VDRTCTL0.D3PGD = 1) */
124         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL0,
125                                          PCI_VDRTCL0_D3PGD, PCI_VDRTCL0_D3PGD);
126
127         /* Set D0 state */
128         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_PMCS,
129                                          PCI_PMCS_PS_MASK, 0);
130
131         /* check that ADSP shim is enabled */
132         while (tries--) {
133                 reg = readl(sdev->bar[BDW_PCI_BAR] + PCI_PMCS)
134                         & PCI_PMCS_PS_MASK;
135                 if (reg == 0)
136                         goto finish;
137
138                 msleep(20);
139         }
140
141         return -ENODEV;
142
143 finish:
144         /*
145          * select SSP1 19.2MHz base clock, SSP clock 0,
146          * turn off Low Power Clock
147          */
148         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
149                                          SHIM_CSR_S1IOCS | SHIM_CSR_SBCS1 |
150                                          SHIM_CSR_LPCS, 0x0);
151
152         /* stall DSP core, set clk to 192/96Mhz */
153         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
154                                          SHIM_CSR, SHIM_CSR_STALL |
155                                          SHIM_CSR_DCS_MASK,
156                                          SHIM_CSR_STALL |
157                                          SHIM_CSR_DCS(4));
158
159         /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
160         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CLKCTL,
161                                          SHIM_CLKCTL_MASK |
162                                          SHIM_CLKCTL_DCPLCG |
163                                          SHIM_CLKCTL_SCOE0,
164                                          SHIM_CLKCTL_MASK |
165                                          SHIM_CLKCTL_DCPLCG |
166                                          SHIM_CLKCTL_SCOE0);
167
168         /* Stall and reset core, set CSR */
169         bdw_reset(sdev);
170
171         /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
172         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
173                                          PCI_VDRTCL2_DCLCGE |
174                                          PCI_VDRTCL2_DTCGE,
175                                          PCI_VDRTCL2_DCLCGE |
176                                          PCI_VDRTCL2_DTCGE);
177
178         usleep_range(50, 55);
179
180         /* switch on audio PLL */
181         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
182                                          PCI_VDRTCL2_APLLSE_MASK, 0);
183
184         /*
185          * set default power gating control, enable power gating control for
186          * all blocks. that is, can't be accessed, please enable each block
187          * before accessing.
188          */
189         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL0,
190                                          0xfffffffC, 0x0);
191
192         /* disable DMA finish function for SSP0 & SSP1 */
193         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,  SHIM_CSR2,
194                                          SHIM_CSR2_SDFD_SSP1,
195                                          SHIM_CSR2_SDFD_SSP1);
196
197         /* set on-demond mode on engine 0,1 for all channels */
198         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
199                                 SHIM_HMDC_HDDA_E0_ALLCH |
200                                 SHIM_HMDC_HDDA_E1_ALLCH,
201                                 SHIM_HMDC_HDDA_E0_ALLCH |
202                                 SHIM_HMDC_HDDA_E1_ALLCH);
203
204         /* Enable Interrupt from both sides */
205         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_IMRX,
206                                 (SHIM_IMRX_BUSY | SHIM_IMRX_DONE), 0x0);
207         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_IMRD,
208                                 (SHIM_IMRD_DONE | SHIM_IMRD_BUSY |
209                                 SHIM_IMRD_SSP0 | SHIM_IMRD_DMAC), 0x0);
210
211         /* clear IPC registers */
212         snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCX, 0x0);
213         snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCD, 0x0);
214         snd_sof_dsp_write(sdev, BDW_DSP_BAR, 0x80, 0x6);
215         snd_sof_dsp_write(sdev, BDW_DSP_BAR, 0xe0, 0x300a);
216
217         return 0;
218 }
219
220 static void bdw_get_registers(struct snd_sof_dev *sdev,
221                               struct sof_ipc_dsp_oops_xtensa *xoops,
222                               struct sof_ipc_panic_info *panic_info,
223                               u32 *stack, size_t stack_words)
224 {
225         u32 offset = sdev->dsp_oops_offset;
226
227         /* first read registers */
228         sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
229
230         /* note: variable AR register array is not read */
231
232         /* then get panic info */
233         if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
234                 dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
235                         xoops->arch_hdr.totalsize);
236                 return;
237         }
238         offset += xoops->arch_hdr.totalsize;
239         sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
240
241         /* then get the stack */
242         offset += sizeof(*panic_info);
243         sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
244 }
245
246 static void bdw_dump(struct snd_sof_dev *sdev, u32 flags)
247 {
248         struct sof_ipc_dsp_oops_xtensa xoops;
249         struct sof_ipc_panic_info panic_info;
250         u32 stack[BDW_STACK_DUMP_SIZE];
251         u32 status, panic, imrx, imrd;
252
253         /* now try generic SOF status messages */
254         status = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD);
255         panic = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX);
256         bdw_get_registers(sdev, &xoops, &panic_info, stack,
257                           BDW_STACK_DUMP_SIZE);
258         snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
259                            BDW_STACK_DUMP_SIZE);
260
261         /* provide some context for firmware debug */
262         imrx = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IMRX);
263         imrd = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IMRD);
264         dev_err(sdev->dev,
265                 "error: ipc host -> DSP: pending %s complete %s raw 0x%8.8x\n",
266                 (panic & SHIM_IPCX_BUSY) ? "yes" : "no",
267                 (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic);
268         dev_err(sdev->dev,
269                 "error: mask host: pending %s complete %s raw 0x%8.8x\n",
270                 (imrx & SHIM_IMRX_BUSY) ? "yes" : "no",
271                 (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx);
272         dev_err(sdev->dev,
273                 "error: ipc DSP -> host: pending %s complete %s raw 0x%8.8x\n",
274                 (status & SHIM_IPCD_BUSY) ? "yes" : "no",
275                 (status & SHIM_IPCD_DONE) ? "yes" : "no", status);
276         dev_err(sdev->dev,
277                 "error: mask DSP: pending %s complete %s raw 0x%8.8x\n",
278                 (imrd & SHIM_IMRD_BUSY) ? "yes" : "no",
279                 (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd);
280 }
281
282 /*
283  * IPC Doorbell IRQ handler and thread.
284  */
285
286 static irqreturn_t bdw_irq_handler(int irq, void *context)
287 {
288         struct snd_sof_dev *sdev = context;
289         u32 isr;
290         int ret = IRQ_NONE;
291
292         /* Interrupt arrived, check src */
293         isr = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_ISRX);
294         if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY))
295                 ret = IRQ_WAKE_THREAD;
296
297         return ret;
298 }
299
300 static irqreturn_t bdw_irq_thread(int irq, void *context)
301 {
302         struct snd_sof_dev *sdev = context;
303         u32 ipcx, ipcd, imrx;
304
305         imrx = snd_sof_dsp_read64(sdev, BDW_DSP_BAR, SHIM_IMRX);
306         ipcx = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX);
307
308         /* reply message from DSP */
309         if (ipcx & SHIM_IPCX_DONE &&
310             !(imrx & SHIM_IMRX_DONE)) {
311                 /* Mask Done interrupt before return */
312                 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
313                                                  SHIM_IMRX, SHIM_IMRX_DONE,
314                                                  SHIM_IMRX_DONE);
315
316                 spin_lock_irq(&sdev->ipc_lock);
317
318                 /*
319                  * handle immediate reply from DSP core. If the msg is
320                  * found, set done bit in cmd_done which is called at the
321                  * end of message processing function, else set it here
322                  * because the done bit can't be set in cmd_done function
323                  * which is triggered by msg
324                  */
325                 bdw_get_reply(sdev);
326                 snd_sof_ipc_reply(sdev, ipcx);
327
328                 bdw_dsp_done(sdev);
329
330                 spin_unlock_irq(&sdev->ipc_lock);
331         }
332
333         ipcd = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD);
334
335         /* new message from DSP */
336         if (ipcd & SHIM_IPCD_BUSY &&
337             !(imrx & SHIM_IMRX_BUSY)) {
338                 /* Mask Busy interrupt before return */
339                 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
340                                                  SHIM_IMRX, SHIM_IMRX_BUSY,
341                                                  SHIM_IMRX_BUSY);
342
343                 /* Handle messages from DSP Core */
344                 if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
345                         snd_sof_dsp_panic(sdev, BDW_PANIC_OFFSET(ipcx) +
346                                           MBOX_OFFSET);
347                 } else {
348                         snd_sof_ipc_msgs_rx(sdev);
349                 }
350
351                 bdw_host_done(sdev);
352         }
353
354         return IRQ_HANDLED;
355 }
356
357 /*
358  * IPC Mailbox IO
359  */
360
361 static int bdw_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
362 {
363         /* send the message */
364         sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
365                           msg->msg_size);
366         snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCX, SHIM_IPCX_BUSY);
367
368         return 0;
369 }
370
371 static void bdw_get_reply(struct snd_sof_dev *sdev)
372 {
373         struct snd_sof_ipc_msg *msg = sdev->msg;
374         struct sof_ipc_reply reply;
375         int ret = 0;
376
377         /*
378          * Sometimes, there is unexpected reply ipc arriving. The reply
379          * ipc belongs to none of the ipcs sent from driver.
380          * In this case, the driver must ignore the ipc.
381          */
382         if (!msg) {
383                 dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n");
384                 return;
385         }
386
387         /* get reply */
388         sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
389
390         if (reply.error < 0) {
391                 memcpy(msg->reply_data, &reply, sizeof(reply));
392                 ret = reply.error;
393         } else {
394                 /* reply correct size ? */
395                 if (reply.hdr.size != msg->reply_size) {
396                         dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
397                                 msg->reply_size, reply.hdr.size);
398                         ret = -EINVAL;
399                 }
400
401                 /* read the message */
402                 if (msg->reply_size > 0)
403                         sof_mailbox_read(sdev, sdev->host_box.offset,
404                                          msg->reply_data, msg->reply_size);
405         }
406
407         msg->reply_error = ret;
408 }
409
410 static int bdw_get_mailbox_offset(struct snd_sof_dev *sdev)
411 {
412         return MBOX_OFFSET;
413 }
414
415 static int bdw_get_window_offset(struct snd_sof_dev *sdev, u32 id)
416 {
417         return MBOX_OFFSET;
418 }
419
420 static void bdw_host_done(struct snd_sof_dev *sdev)
421 {
422         /* clear BUSY bit and set DONE bit - accept new messages */
423         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCD,
424                                          SHIM_IPCD_BUSY | SHIM_IPCD_DONE,
425                                          SHIM_IPCD_DONE);
426
427         /* unmask busy interrupt */
428         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX,
429                                          SHIM_IMRX_BUSY, 0);
430 }
431
432 static void bdw_dsp_done(struct snd_sof_dev *sdev)
433 {
434         /* clear DONE bit - tell DSP we have completed */
435         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCX,
436                                          SHIM_IPCX_DONE, 0);
437
438         /* unmask Done interrupt */
439         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX,
440                                          SHIM_IMRX_DONE, 0);
441 }
442
443 /*
444  * Probe and remove.
445  */
446 static int bdw_probe(struct snd_sof_dev *sdev)
447 {
448         struct snd_sof_pdata *pdata = sdev->pdata;
449         const struct sof_dev_desc *desc = pdata->desc;
450         struct platform_device *pdev =
451                 container_of(sdev->dev, struct platform_device, dev);
452         struct resource *mmio;
453         u32 base, size;
454         int ret;
455
456         /* LPE base */
457         mmio = platform_get_resource(pdev, IORESOURCE_MEM,
458                                      desc->resindex_lpe_base);
459         if (mmio) {
460                 base = mmio->start;
461                 size = resource_size(mmio);
462         } else {
463                 dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
464                         desc->resindex_lpe_base);
465                 return -EINVAL;
466         }
467
468         dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
469         sdev->bar[BDW_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
470         if (!sdev->bar[BDW_DSP_BAR]) {
471                 dev_err(sdev->dev,
472                         "error: failed to ioremap LPE base 0x%x size 0x%x\n",
473                         base, size);
474                 return -ENODEV;
475         }
476         dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BDW_DSP_BAR]);
477
478         /* TODO: add offsets */
479         sdev->mmio_bar = BDW_DSP_BAR;
480         sdev->mailbox_bar = BDW_DSP_BAR;
481         sdev->dsp_oops_offset = MBOX_OFFSET;
482
483         /* PCI base */
484         mmio = platform_get_resource(pdev, IORESOURCE_MEM,
485                                      desc->resindex_pcicfg_base);
486         if (mmio) {
487                 base = mmio->start;
488                 size = resource_size(mmio);
489         } else {
490                 dev_err(sdev->dev, "error: failed to get PCI base at idx %d\n",
491                         desc->resindex_pcicfg_base);
492                 return -ENODEV;
493         }
494
495         dev_dbg(sdev->dev, "PCI base at 0x%x size 0x%x", base, size);
496         sdev->bar[BDW_PCI_BAR] = devm_ioremap(sdev->dev, base, size);
497         if (!sdev->bar[BDW_PCI_BAR]) {
498                 dev_err(sdev->dev,
499                         "error: failed to ioremap PCI base 0x%x size 0x%x\n",
500                         base, size);
501                 return -ENODEV;
502         }
503         dev_dbg(sdev->dev, "PCI VADDR %p\n", sdev->bar[BDW_PCI_BAR]);
504
505         /* register our IRQ */
506         sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
507         if (sdev->ipc_irq < 0)
508                 return sdev->ipc_irq;
509
510         dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
511         ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
512                                         bdw_irq_handler, bdw_irq_thread,
513                                         IRQF_SHARED, "AudioDSP", sdev);
514         if (ret < 0) {
515                 dev_err(sdev->dev, "error: failed to register IRQ %d\n",
516                         sdev->ipc_irq);
517                 return ret;
518         }
519
520         /* enable the DSP SHIM */
521         ret = bdw_set_dsp_D0(sdev);
522         if (ret < 0) {
523                 dev_err(sdev->dev, "error: failed to set DSP D0\n");
524                 return ret;
525         }
526
527         /* DSP DMA can only access low 31 bits of host memory */
528         ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
529         if (ret < 0) {
530                 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
531                 return ret;
532         }
533
534         /* set default mailbox */
535         snd_sof_dsp_mailbox_init(sdev, MBOX_OFFSET, MBOX_SIZE, 0, 0);
536
537         return ret;
538 }
539
540 static void bdw_machine_select(struct snd_sof_dev *sdev)
541 {
542         struct snd_sof_pdata *sof_pdata = sdev->pdata;
543         const struct sof_dev_desc *desc = sof_pdata->desc;
544         struct snd_soc_acpi_mach *mach;
545
546         mach = snd_soc_acpi_find_machine(desc->machines);
547         if (!mach) {
548                 dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
549                 return;
550         }
551
552         sof_pdata->tplg_filename = mach->sof_tplg_filename;
553         mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc;
554         sof_pdata->machine = mach;
555 }
556
557 static void bdw_set_mach_params(const struct snd_soc_acpi_mach *mach,
558                                 struct device *dev)
559 {
560         struct snd_soc_acpi_mach_params *mach_params;
561
562         mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params;
563         mach_params->platform = dev_name(dev);
564 }
565
566 /* Broadwell DAIs */
567 static struct snd_soc_dai_driver bdw_dai[] = {
568 {
569         .name = "ssp0-port",
570 },
571 {
572         .name = "ssp1-port",
573 },
574 };
575
576 /* broadwell ops */
577 const struct snd_sof_dsp_ops sof_bdw_ops = {
578         /*Device init */
579         .probe          = bdw_probe,
580
581         /* DSP Core Control */
582         .run            = bdw_run,
583         .reset          = bdw_reset,
584
585         /* Register IO */
586         .write          = sof_io_write,
587         .read           = sof_io_read,
588         .write64        = sof_io_write64,
589         .read64         = sof_io_read64,
590
591         /* Block IO */
592         .block_read     = sof_block_read,
593         .block_write    = sof_block_write,
594
595         /* ipc */
596         .send_msg       = bdw_send_msg,
597         .fw_ready       = sof_fw_ready,
598         .get_mailbox_offset = bdw_get_mailbox_offset,
599         .get_window_offset = bdw_get_window_offset,
600
601         .ipc_msg_data   = intel_ipc_msg_data,
602         .ipc_pcm_params = intel_ipc_pcm_params,
603
604         /* machine driver */
605         .machine_select = bdw_machine_select,
606         .machine_register = sof_machine_register,
607         .machine_unregister = sof_machine_unregister,
608         .set_mach_params = bdw_set_mach_params,
609
610         /* debug */
611         .debug_map  = bdw_debugfs,
612         .debug_map_count    = ARRAY_SIZE(bdw_debugfs),
613         .dbg_dump   = bdw_dump,
614
615         /* stream callbacks */
616         .pcm_open       = intel_pcm_open,
617         .pcm_close      = intel_pcm_close,
618
619         /* Module loading */
620         .load_module    = snd_sof_parse_module_memcpy,
621
622         /*Firmware loading */
623         .load_firmware  = snd_sof_load_firmware_memcpy,
624
625         /* DAI drivers */
626         .drv = bdw_dai,
627         .num_drv = ARRAY_SIZE(bdw_dai),
628
629         /* ALSA HW info flags */
630         .hw_info =      SNDRV_PCM_INFO_MMAP |
631                         SNDRV_PCM_INFO_MMAP_VALID |
632                         SNDRV_PCM_INFO_INTERLEAVED |
633                         SNDRV_PCM_INFO_PAUSE |
634                         SNDRV_PCM_INFO_BATCH,
635
636         .arch_ops = &sof_xtensa_arch_ops,
637 };
638 EXPORT_SYMBOL_NS(sof_bdw_ops, SND_SOC_SOF_BROADWELL);
639
640 const struct sof_intel_dsp_desc bdw_chip_info = {
641         .cores_num = 1,
642         .cores_mask = 1,
643 };
644 EXPORT_SYMBOL_NS(bdw_chip_info, SND_SOC_SOF_BROADWELL);
645
646 MODULE_LICENSE("Dual BSD/GPL");
647 MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
648 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);