0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/module.h>
0016 #include <sound/sof.h>
0017 #include <sound/sof/xtensa.h>
0018 #include <sound/soc-acpi.h>
0019 #include <sound/soc-acpi-intel-match.h>
0020 #include <sound/intel-dsp-config.h>
0021 #include "../ops.h"
0022 #include "shim.h"
0023 #include "../sof-acpi-dev.h"
0024 #include "../sof-audio.h"
0025
0026
0027 #define BDW_DSP_BAR 0
0028 #define BDW_PCI_BAR 1
0029
0030
0031
0032
0033
0034
0035 #define IRAM_OFFSET 0xA0000
0036 #define BDW_IRAM_SIZE (10 * 32 * 1024)
0037 #define DRAM_OFFSET 0x00000
0038 #define BDW_DRAM_SIZE (20 * 32 * 1024)
0039 #define SHIM_OFFSET 0xFB000
0040 #define SHIM_SIZE 0x100
0041 #define MBOX_OFFSET 0x9E000
0042 #define MBOX_SIZE 0x1000
0043 #define MBOX_DUMP_SIZE 0x30
0044 #define EXCEPT_OFFSET 0x800
0045 #define EXCEPT_MAX_HDR_SIZE 0x400
0046
0047
0048 #define DMAC0_OFFSET 0xFE000
0049 #define DMAC1_OFFSET 0xFF000
0050 #define DMAC_SIZE 0x420
0051 #define SSP0_OFFSET 0xFC000
0052 #define SSP1_OFFSET 0xFD000
0053 #define SSP_SIZE 0x100
0054
0055 #define BDW_STACK_DUMP_SIZE 32
0056
0057 #define BDW_PANIC_OFFSET(x) ((x) & 0xFFFF)
0058
0059 static const struct snd_sof_debugfs_map bdw_debugfs[] = {
0060 {"dmac0", BDW_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
0061 SOF_DEBUGFS_ACCESS_ALWAYS},
0062 {"dmac1", BDW_DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
0063 SOF_DEBUGFS_ACCESS_ALWAYS},
0064 {"ssp0", BDW_DSP_BAR, SSP0_OFFSET, SSP_SIZE,
0065 SOF_DEBUGFS_ACCESS_ALWAYS},
0066 {"ssp1", BDW_DSP_BAR, SSP1_OFFSET, SSP_SIZE,
0067 SOF_DEBUGFS_ACCESS_ALWAYS},
0068 {"iram", BDW_DSP_BAR, IRAM_OFFSET, BDW_IRAM_SIZE,
0069 SOF_DEBUGFS_ACCESS_D0_ONLY},
0070 {"dram", BDW_DSP_BAR, DRAM_OFFSET, BDW_DRAM_SIZE,
0071 SOF_DEBUGFS_ACCESS_D0_ONLY},
0072 {"shim", BDW_DSP_BAR, SHIM_OFFSET, SHIM_SIZE,
0073 SOF_DEBUGFS_ACCESS_ALWAYS},
0074 };
0075
0076 static void bdw_host_done(struct snd_sof_dev *sdev);
0077 static void bdw_dsp_done(struct snd_sof_dev *sdev);
0078
0079
0080
0081
0082
0083 static int bdw_run(struct snd_sof_dev *sdev)
0084 {
0085
0086 snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
0087 SHIM_HMDC_HDDA_E0_ALLCH |
0088 SHIM_HMDC_HDDA_E1_ALLCH, 0);
0089
0090
0091 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
0092 SHIM_CSR_STALL, 0x0);
0093
0094
0095 return 1;
0096 }
0097
0098 static int bdw_reset(struct snd_sof_dev *sdev)
0099 {
0100
0101 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
0102 SHIM_CSR_RST | SHIM_CSR_STALL,
0103 SHIM_CSR_RST | SHIM_CSR_STALL);
0104
0105
0106 mdelay(10);
0107
0108
0109 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
0110 SHIM_CSR_RST | SHIM_CSR_STALL,
0111 SHIM_CSR_STALL);
0112
0113 return 0;
0114 }
0115
0116 static int bdw_set_dsp_D0(struct snd_sof_dev *sdev)
0117 {
0118 int tries = 10;
0119 u32 reg;
0120
0121
0122 snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
0123 PCI_VDRTCL2_DCLCGE |
0124 PCI_VDRTCL2_DTCGE, 0);
0125
0126
0127 snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL0,
0128 PCI_VDRTCL0_D3PGD, PCI_VDRTCL0_D3PGD);
0129
0130
0131 snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_PMCS,
0132 PCI_PMCS_PS_MASK, 0);
0133
0134
0135 while (tries--) {
0136 reg = readl(sdev->bar[BDW_PCI_BAR] + PCI_PMCS)
0137 & PCI_PMCS_PS_MASK;
0138 if (reg == 0)
0139 goto finish;
0140
0141 msleep(20);
0142 }
0143
0144 return -ENODEV;
0145
0146 finish:
0147
0148
0149
0150
0151 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
0152 SHIM_CSR_S1IOCS | SHIM_CSR_SBCS1 |
0153 SHIM_CSR_LPCS, 0x0);
0154
0155
0156 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
0157 SHIM_CSR, SHIM_CSR_STALL |
0158 SHIM_CSR_DCS_MASK,
0159 SHIM_CSR_STALL |
0160 SHIM_CSR_DCS(4));
0161
0162
0163 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CLKCTL,
0164 SHIM_CLKCTL_MASK |
0165 SHIM_CLKCTL_DCPLCG |
0166 SHIM_CLKCTL_SCOE0,
0167 SHIM_CLKCTL_MASK |
0168 SHIM_CLKCTL_DCPLCG |
0169 SHIM_CLKCTL_SCOE0);
0170
0171
0172 bdw_reset(sdev);
0173
0174
0175 snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
0176 PCI_VDRTCL2_DCLCGE |
0177 PCI_VDRTCL2_DTCGE,
0178 PCI_VDRTCL2_DCLCGE |
0179 PCI_VDRTCL2_DTCGE);
0180
0181 usleep_range(50, 55);
0182
0183
0184 snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
0185 PCI_VDRTCL2_APLLSE_MASK, 0);
0186
0187
0188
0189
0190
0191
0192 snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL0,
0193 0xfffffffC, 0x0);
0194
0195
0196 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR2,
0197 SHIM_CSR2_SDFD_SSP1,
0198 SHIM_CSR2_SDFD_SSP1);
0199
0200
0201 snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
0202 SHIM_HMDC_HDDA_E0_ALLCH |
0203 SHIM_HMDC_HDDA_E1_ALLCH,
0204 SHIM_HMDC_HDDA_E0_ALLCH |
0205 SHIM_HMDC_HDDA_E1_ALLCH);
0206
0207
0208 snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_IMRX,
0209 (SHIM_IMRX_BUSY | SHIM_IMRX_DONE), 0x0);
0210 snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_IMRD,
0211 (SHIM_IMRD_DONE | SHIM_IMRD_BUSY |
0212 SHIM_IMRD_SSP0 | SHIM_IMRD_DMAC), 0x0);
0213
0214
0215 snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCX, 0x0);
0216 snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCD, 0x0);
0217 snd_sof_dsp_write(sdev, BDW_DSP_BAR, 0x80, 0x6);
0218 snd_sof_dsp_write(sdev, BDW_DSP_BAR, 0xe0, 0x300a);
0219
0220 return 0;
0221 }
0222
0223 static void bdw_get_registers(struct snd_sof_dev *sdev,
0224 struct sof_ipc_dsp_oops_xtensa *xoops,
0225 struct sof_ipc_panic_info *panic_info,
0226 u32 *stack, size_t stack_words)
0227 {
0228 u32 offset = sdev->dsp_oops_offset;
0229
0230
0231 sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
0232
0233
0234
0235
0236 if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
0237 dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
0238 xoops->arch_hdr.totalsize);
0239 return;
0240 }
0241 offset += xoops->arch_hdr.totalsize;
0242 sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
0243
0244
0245 offset += sizeof(*panic_info);
0246 sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
0247 }
0248
0249 static void bdw_dump(struct snd_sof_dev *sdev, u32 flags)
0250 {
0251 struct sof_ipc_dsp_oops_xtensa xoops;
0252 struct sof_ipc_panic_info panic_info;
0253 u32 stack[BDW_STACK_DUMP_SIZE];
0254 u32 status, panic, imrx, imrd;
0255
0256
0257 status = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD);
0258 panic = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX);
0259 bdw_get_registers(sdev, &xoops, &panic_info, stack,
0260 BDW_STACK_DUMP_SIZE);
0261 sof_print_oops_and_stack(sdev, KERN_ERR, status, panic, &xoops,
0262 &panic_info, stack, BDW_STACK_DUMP_SIZE);
0263
0264
0265 imrx = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IMRX);
0266 imrd = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IMRD);
0267 dev_err(sdev->dev,
0268 "error: ipc host -> DSP: pending %s complete %s raw 0x%8.8x\n",
0269 (panic & SHIM_IPCX_BUSY) ? "yes" : "no",
0270 (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic);
0271 dev_err(sdev->dev,
0272 "error: mask host: pending %s complete %s raw 0x%8.8x\n",
0273 (imrx & SHIM_IMRX_BUSY) ? "yes" : "no",
0274 (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx);
0275 dev_err(sdev->dev,
0276 "error: ipc DSP -> host: pending %s complete %s raw 0x%8.8x\n",
0277 (status & SHIM_IPCD_BUSY) ? "yes" : "no",
0278 (status & SHIM_IPCD_DONE) ? "yes" : "no", status);
0279 dev_err(sdev->dev,
0280 "error: mask DSP: pending %s complete %s raw 0x%8.8x\n",
0281 (imrd & SHIM_IMRD_BUSY) ? "yes" : "no",
0282 (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd);
0283 }
0284
0285
0286
0287
0288
0289 static irqreturn_t bdw_irq_handler(int irq, void *context)
0290 {
0291 struct snd_sof_dev *sdev = context;
0292 u32 isr;
0293 int ret = IRQ_NONE;
0294
0295
0296 isr = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_ISRX);
0297 if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY))
0298 ret = IRQ_WAKE_THREAD;
0299
0300 return ret;
0301 }
0302
0303 static irqreturn_t bdw_irq_thread(int irq, void *context)
0304 {
0305 struct snd_sof_dev *sdev = context;
0306 u32 ipcx, ipcd, imrx;
0307
0308 imrx = snd_sof_dsp_read64(sdev, BDW_DSP_BAR, SHIM_IMRX);
0309 ipcx = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX);
0310
0311
0312 if (ipcx & SHIM_IPCX_DONE &&
0313 !(imrx & SHIM_IMRX_DONE)) {
0314
0315 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
0316 SHIM_IMRX, SHIM_IMRX_DONE,
0317 SHIM_IMRX_DONE);
0318
0319 spin_lock_irq(&sdev->ipc_lock);
0320
0321
0322
0323
0324
0325
0326
0327
0328 snd_sof_ipc_process_reply(sdev, ipcx);
0329
0330 bdw_dsp_done(sdev);
0331
0332 spin_unlock_irq(&sdev->ipc_lock);
0333 }
0334
0335 ipcd = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD);
0336
0337
0338 if (ipcd & SHIM_IPCD_BUSY &&
0339 !(imrx & SHIM_IMRX_BUSY)) {
0340
0341 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
0342 SHIM_IMRX, SHIM_IMRX_BUSY,
0343 SHIM_IMRX_BUSY);
0344
0345
0346 if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
0347 snd_sof_dsp_panic(sdev, BDW_PANIC_OFFSET(ipcx) + MBOX_OFFSET,
0348 true);
0349 } else {
0350 snd_sof_ipc_msgs_rx(sdev);
0351 }
0352
0353 bdw_host_done(sdev);
0354 }
0355
0356 return IRQ_HANDLED;
0357 }
0358
0359
0360
0361
0362
0363 static int bdw_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
0364 {
0365
0366 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
0367 msg->msg_size);
0368 snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCX, SHIM_IPCX_BUSY);
0369
0370 return 0;
0371 }
0372
0373 static int bdw_get_mailbox_offset(struct snd_sof_dev *sdev)
0374 {
0375 return MBOX_OFFSET;
0376 }
0377
0378 static int bdw_get_window_offset(struct snd_sof_dev *sdev, u32 id)
0379 {
0380 return MBOX_OFFSET;
0381 }
0382
0383 static void bdw_host_done(struct snd_sof_dev *sdev)
0384 {
0385
0386 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCD,
0387 SHIM_IPCD_BUSY | SHIM_IPCD_DONE,
0388 SHIM_IPCD_DONE);
0389
0390
0391 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX,
0392 SHIM_IMRX_BUSY, 0);
0393 }
0394
0395 static void bdw_dsp_done(struct snd_sof_dev *sdev)
0396 {
0397
0398 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCX,
0399 SHIM_IPCX_DONE, 0);
0400
0401
0402 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX,
0403 SHIM_IMRX_DONE, 0);
0404 }
0405
0406
0407
0408
0409 static int bdw_probe(struct snd_sof_dev *sdev)
0410 {
0411 struct snd_sof_pdata *pdata = sdev->pdata;
0412 const struct sof_dev_desc *desc = pdata->desc;
0413 struct platform_device *pdev =
0414 container_of(sdev->dev, struct platform_device, dev);
0415 const struct sof_intel_dsp_desc *chip;
0416 struct resource *mmio;
0417 u32 base, size;
0418 int ret;
0419
0420 chip = get_chip_info(sdev->pdata);
0421 if (!chip) {
0422 dev_err(sdev->dev, "error: no such device supported\n");
0423 return -EIO;
0424 }
0425
0426 sdev->num_cores = chip->cores_num;
0427
0428
0429 mmio = platform_get_resource(pdev, IORESOURCE_MEM,
0430 desc->resindex_lpe_base);
0431 if (mmio) {
0432 base = mmio->start;
0433 size = resource_size(mmio);
0434 } else {
0435 dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
0436 desc->resindex_lpe_base);
0437 return -EINVAL;
0438 }
0439
0440 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
0441 sdev->bar[BDW_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
0442 if (!sdev->bar[BDW_DSP_BAR]) {
0443 dev_err(sdev->dev,
0444 "error: failed to ioremap LPE base 0x%x size 0x%x\n",
0445 base, size);
0446 return -ENODEV;
0447 }
0448 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BDW_DSP_BAR]);
0449
0450
0451 sdev->mmio_bar = BDW_DSP_BAR;
0452 sdev->mailbox_bar = BDW_DSP_BAR;
0453 sdev->dsp_oops_offset = MBOX_OFFSET;
0454
0455
0456 mmio = platform_get_resource(pdev, IORESOURCE_MEM,
0457 desc->resindex_pcicfg_base);
0458 if (mmio) {
0459 base = mmio->start;
0460 size = resource_size(mmio);
0461 } else {
0462 dev_err(sdev->dev, "error: failed to get PCI base at idx %d\n",
0463 desc->resindex_pcicfg_base);
0464 return -ENODEV;
0465 }
0466
0467 dev_dbg(sdev->dev, "PCI base at 0x%x size 0x%x", base, size);
0468 sdev->bar[BDW_PCI_BAR] = devm_ioremap(sdev->dev, base, size);
0469 if (!sdev->bar[BDW_PCI_BAR]) {
0470 dev_err(sdev->dev,
0471 "error: failed to ioremap PCI base 0x%x size 0x%x\n",
0472 base, size);
0473 return -ENODEV;
0474 }
0475 dev_dbg(sdev->dev, "PCI VADDR %p\n", sdev->bar[BDW_PCI_BAR]);
0476
0477
0478 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
0479 if (sdev->ipc_irq < 0)
0480 return sdev->ipc_irq;
0481
0482 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
0483 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
0484 bdw_irq_handler, bdw_irq_thread,
0485 IRQF_SHARED, "AudioDSP", sdev);
0486 if (ret < 0) {
0487 dev_err(sdev->dev, "error: failed to register IRQ %d\n",
0488 sdev->ipc_irq);
0489 return ret;
0490 }
0491
0492
0493 ret = bdw_set_dsp_D0(sdev);
0494 if (ret < 0) {
0495 dev_err(sdev->dev, "error: failed to set DSP D0\n");
0496 return ret;
0497 }
0498
0499
0500 ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
0501 if (ret < 0) {
0502 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
0503 return ret;
0504 }
0505
0506
0507 sdev->dsp_box.offset = MBOX_OFFSET;
0508
0509 return ret;
0510 }
0511
0512 static struct snd_soc_acpi_mach *bdw_machine_select(struct snd_sof_dev *sdev)
0513 {
0514 struct snd_sof_pdata *sof_pdata = sdev->pdata;
0515 const struct sof_dev_desc *desc = sof_pdata->desc;
0516 struct snd_soc_acpi_mach *mach;
0517
0518 mach = snd_soc_acpi_find_machine(desc->machines);
0519 if (!mach) {
0520 dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
0521 return NULL;
0522 }
0523
0524 sof_pdata->tplg_filename = mach->sof_tplg_filename;
0525 mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc;
0526
0527 return mach;
0528 }
0529
0530 static void bdw_set_mach_params(struct snd_soc_acpi_mach *mach,
0531 struct snd_sof_dev *sdev)
0532 {
0533 struct snd_sof_pdata *pdata = sdev->pdata;
0534 const struct sof_dev_desc *desc = pdata->desc;
0535 struct snd_soc_acpi_mach_params *mach_params;
0536
0537 mach_params = &mach->mach_params;
0538 mach_params->platform = dev_name(sdev->dev);
0539 mach_params->num_dai_drivers = desc->ops->num_drv;
0540 mach_params->dai_drivers = desc->ops->drv;
0541 }
0542
0543
0544 static struct snd_soc_dai_driver bdw_dai[] = {
0545 {
0546 .name = "ssp0-port",
0547 .playback = {
0548 .channels_min = 1,
0549 .channels_max = 8,
0550 },
0551 .capture = {
0552 .channels_min = 1,
0553 .channels_max = 8,
0554 },
0555 },
0556 {
0557 .name = "ssp1-port",
0558 .playback = {
0559 .channels_min = 1,
0560 .channels_max = 8,
0561 },
0562 .capture = {
0563 .channels_min = 1,
0564 .channels_max = 8,
0565 },
0566 },
0567 };
0568
0569
0570 static struct snd_sof_dsp_ops sof_bdw_ops = {
0571
0572 .probe = bdw_probe,
0573
0574
0575 .run = bdw_run,
0576 .reset = bdw_reset,
0577
0578
0579 .write = sof_io_write,
0580 .read = sof_io_read,
0581 .write64 = sof_io_write64,
0582 .read64 = sof_io_read64,
0583
0584
0585 .block_read = sof_block_read,
0586 .block_write = sof_block_write,
0587
0588
0589 .mailbox_read = sof_mailbox_read,
0590 .mailbox_write = sof_mailbox_write,
0591
0592
0593 .send_msg = bdw_send_msg,
0594 .get_mailbox_offset = bdw_get_mailbox_offset,
0595 .get_window_offset = bdw_get_window_offset,
0596
0597 .ipc_msg_data = sof_ipc_msg_data,
0598 .set_stream_data_offset = sof_set_stream_data_offset,
0599
0600
0601 .machine_select = bdw_machine_select,
0602 .machine_register = sof_machine_register,
0603 .machine_unregister = sof_machine_unregister,
0604 .set_mach_params = bdw_set_mach_params,
0605
0606
0607 .debug_map = bdw_debugfs,
0608 .debug_map_count = ARRAY_SIZE(bdw_debugfs),
0609 .dbg_dump = bdw_dump,
0610 .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
0611
0612
0613 .pcm_open = sof_stream_pcm_open,
0614 .pcm_close = sof_stream_pcm_close,
0615
0616
0617 .load_firmware = snd_sof_load_firmware_memcpy,
0618
0619
0620 .drv = bdw_dai,
0621 .num_drv = ARRAY_SIZE(bdw_dai),
0622
0623
0624 .hw_info = SNDRV_PCM_INFO_MMAP |
0625 SNDRV_PCM_INFO_MMAP_VALID |
0626 SNDRV_PCM_INFO_INTERLEAVED |
0627 SNDRV_PCM_INFO_PAUSE |
0628 SNDRV_PCM_INFO_BATCH,
0629
0630 .dsp_arch_ops = &sof_xtensa_arch_ops,
0631 };
0632
0633 static const struct sof_intel_dsp_desc bdw_chip_info = {
0634 .cores_num = 1,
0635 .host_managed_cores_mask = 1,
0636 .hw_ip_version = SOF_INTEL_BROADWELL,
0637 };
0638
0639 static const struct sof_dev_desc sof_acpi_broadwell_desc = {
0640 .machines = snd_soc_acpi_intel_broadwell_machines,
0641 .resindex_lpe_base = 0,
0642 .resindex_pcicfg_base = 1,
0643 .resindex_imr_base = -1,
0644 .irqindex_host_ipc = 0,
0645 .chip_info = &bdw_chip_info,
0646 .ipc_supported_mask = BIT(SOF_IPC),
0647 .ipc_default = SOF_IPC,
0648 .default_fw_path = {
0649 [SOF_IPC] = "intel/sof",
0650 },
0651 .default_tplg_path = {
0652 [SOF_IPC] = "intel/sof-tplg",
0653 },
0654 .default_fw_filename = {
0655 [SOF_IPC] = "sof-bdw.ri",
0656 },
0657 .nocodec_tplg_filename = "sof-bdw-nocodec.tplg",
0658 .ops = &sof_bdw_ops,
0659 };
0660
0661 static const struct acpi_device_id sof_broadwell_match[] = {
0662 { "INT3438", (unsigned long)&sof_acpi_broadwell_desc },
0663 { }
0664 };
0665 MODULE_DEVICE_TABLE(acpi, sof_broadwell_match);
0666
0667 static int sof_broadwell_probe(struct platform_device *pdev)
0668 {
0669 struct device *dev = &pdev->dev;
0670 const struct acpi_device_id *id;
0671 const struct sof_dev_desc *desc;
0672 int ret;
0673
0674 id = acpi_match_device(dev->driver->acpi_match_table, dev);
0675 if (!id)
0676 return -ENODEV;
0677
0678 ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
0679 if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
0680 dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
0681 return -ENODEV;
0682 }
0683
0684 desc = (const struct sof_dev_desc *)id->driver_data;
0685 return sof_acpi_probe(pdev, desc);
0686 }
0687
0688
0689 static struct platform_driver snd_sof_acpi_intel_bdw_driver = {
0690 .probe = sof_broadwell_probe,
0691 .remove = sof_acpi_remove,
0692 .driver = {
0693 .name = "sof-audio-acpi-intel-bdw",
0694 .pm = &sof_acpi_pm,
0695 .acpi_match_table = sof_broadwell_match,
0696 },
0697 };
0698 module_platform_driver(snd_sof_acpi_intel_bdw_driver);
0699
0700 MODULE_LICENSE("Dual BSD/GPL");
0701 MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
0702 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
0703 MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV);