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 "atom.h"
0023 #include "shim.h"
0024 #include "../sof-acpi-dev.h"
0025 #include "../sof-audio.h"
0026 #include "../../intel/common/soc-intel-quirks.h"
0027
0028 static const struct snd_sof_debugfs_map byt_debugfs[] = {
0029 {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
0030 SOF_DEBUGFS_ACCESS_ALWAYS},
0031 {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
0032 SOF_DEBUGFS_ACCESS_ALWAYS},
0033 {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
0034 SOF_DEBUGFS_ACCESS_ALWAYS},
0035 {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
0036 SOF_DEBUGFS_ACCESS_ALWAYS},
0037 {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
0038 SOF_DEBUGFS_ACCESS_ALWAYS},
0039 {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
0040 SOF_DEBUGFS_ACCESS_D0_ONLY},
0041 {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
0042 SOF_DEBUGFS_ACCESS_D0_ONLY},
0043 {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
0044 SOF_DEBUGFS_ACCESS_ALWAYS},
0045 };
0046
0047 static const struct snd_sof_debugfs_map cht_debugfs[] = {
0048 {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
0049 SOF_DEBUGFS_ACCESS_ALWAYS},
0050 {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
0051 SOF_DEBUGFS_ACCESS_ALWAYS},
0052 {"dmac2", DSP_BAR, DMAC2_OFFSET, DMAC_SIZE,
0053 SOF_DEBUGFS_ACCESS_ALWAYS},
0054 {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
0055 SOF_DEBUGFS_ACCESS_ALWAYS},
0056 {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
0057 SOF_DEBUGFS_ACCESS_ALWAYS},
0058 {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
0059 SOF_DEBUGFS_ACCESS_ALWAYS},
0060 {"ssp3", DSP_BAR, SSP3_OFFSET, SSP_SIZE,
0061 SOF_DEBUGFS_ACCESS_ALWAYS},
0062 {"ssp4", DSP_BAR, SSP4_OFFSET, SSP_SIZE,
0063 SOF_DEBUGFS_ACCESS_ALWAYS},
0064 {"ssp5", DSP_BAR, SSP5_OFFSET, SSP_SIZE,
0065 SOF_DEBUGFS_ACCESS_ALWAYS},
0066 {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
0067 SOF_DEBUGFS_ACCESS_D0_ONLY},
0068 {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
0069 SOF_DEBUGFS_ACCESS_D0_ONLY},
0070 {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
0071 SOF_DEBUGFS_ACCESS_ALWAYS},
0072 };
0073
0074 static void byt_reset_dsp_disable_int(struct snd_sof_dev *sdev)
0075 {
0076
0077 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 0x3, 0x3);
0078 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRD, 0x3, 0x3);
0079
0080
0081 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR,
0082 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL,
0083 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL);
0084 }
0085
0086 static int byt_suspend(struct snd_sof_dev *sdev, u32 target_state)
0087 {
0088 byt_reset_dsp_disable_int(sdev);
0089
0090 return 0;
0091 }
0092
0093 static int byt_resume(struct snd_sof_dev *sdev)
0094 {
0095
0096 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
0097 SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
0098 SHIM_IMRX_DONE);
0099
0100 return 0;
0101 }
0102
0103 static int byt_remove(struct snd_sof_dev *sdev)
0104 {
0105 byt_reset_dsp_disable_int(sdev);
0106
0107 return 0;
0108 }
0109
0110 static int byt_acpi_probe(struct snd_sof_dev *sdev)
0111 {
0112 struct snd_sof_pdata *pdata = sdev->pdata;
0113 const struct sof_dev_desc *desc = pdata->desc;
0114 struct platform_device *pdev =
0115 container_of(sdev->dev, struct platform_device, dev);
0116 const struct sof_intel_dsp_desc *chip;
0117 struct resource *mmio;
0118 u32 base, size;
0119 int ret;
0120
0121 chip = get_chip_info(sdev->pdata);
0122 if (!chip) {
0123 dev_err(sdev->dev, "error: no such device supported\n");
0124 return -EIO;
0125 }
0126
0127 sdev->num_cores = chip->cores_num;
0128
0129
0130 ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
0131 if (ret < 0) {
0132 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
0133 return ret;
0134 }
0135
0136
0137 mmio = platform_get_resource(pdev, IORESOURCE_MEM,
0138 desc->resindex_lpe_base);
0139 if (mmio) {
0140 base = mmio->start;
0141 size = resource_size(mmio);
0142 } else {
0143 dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
0144 desc->resindex_lpe_base);
0145 return -EINVAL;
0146 }
0147
0148 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
0149 sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size);
0150 if (!sdev->bar[DSP_BAR]) {
0151 dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
0152 base, size);
0153 return -ENODEV;
0154 }
0155 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[DSP_BAR]);
0156
0157
0158 sdev->mmio_bar = DSP_BAR;
0159 sdev->mailbox_bar = DSP_BAR;
0160
0161
0162 if (desc->resindex_imr_base == -1)
0163 goto irq;
0164
0165 mmio = platform_get_resource(pdev, IORESOURCE_MEM,
0166 desc->resindex_imr_base);
0167 if (mmio) {
0168 base = mmio->start;
0169 size = resource_size(mmio);
0170 } else {
0171 dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n",
0172 desc->resindex_imr_base);
0173 return -ENODEV;
0174 }
0175
0176
0177 if (base == 0x55aa55aa || base == 0x0) {
0178 dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
0179 goto irq;
0180 }
0181
0182 dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
0183 sdev->bar[IMR_BAR] = devm_ioremap(sdev->dev, base, size);
0184 if (!sdev->bar[IMR_BAR]) {
0185 dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
0186 base, size);
0187 return -ENODEV;
0188 }
0189 dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[IMR_BAR]);
0190
0191 irq:
0192
0193 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
0194 if (sdev->ipc_irq < 0)
0195 return sdev->ipc_irq;
0196
0197 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
0198 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
0199 atom_irq_handler, atom_irq_thread,
0200 IRQF_SHARED, "AudioDSP", sdev);
0201 if (ret < 0) {
0202 dev_err(sdev->dev, "error: failed to register IRQ %d\n",
0203 sdev->ipc_irq);
0204 return ret;
0205 }
0206
0207
0208 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
0209 SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
0210 SHIM_IMRX_DONE);
0211
0212
0213 sdev->dsp_box.offset = MBOX_OFFSET;
0214
0215 return ret;
0216 }
0217
0218
0219 static struct snd_sof_dsp_ops sof_byt_ops = {
0220
0221 .probe = byt_acpi_probe,
0222 .remove = byt_remove,
0223
0224
0225 .run = atom_run,
0226 .reset = atom_reset,
0227
0228
0229 .write = sof_io_write,
0230 .read = sof_io_read,
0231 .write64 = sof_io_write64,
0232 .read64 = sof_io_read64,
0233
0234
0235 .block_read = sof_block_read,
0236 .block_write = sof_block_write,
0237
0238
0239 .mailbox_read = sof_mailbox_read,
0240 .mailbox_write = sof_mailbox_write,
0241
0242
0243 .irq_handler = atom_irq_handler,
0244 .irq_thread = atom_irq_thread,
0245
0246
0247 .send_msg = atom_send_msg,
0248 .get_mailbox_offset = atom_get_mailbox_offset,
0249 .get_window_offset = atom_get_window_offset,
0250
0251 .ipc_msg_data = sof_ipc_msg_data,
0252 .set_stream_data_offset = sof_set_stream_data_offset,
0253
0254
0255 .machine_select = atom_machine_select,
0256 .machine_register = sof_machine_register,
0257 .machine_unregister = sof_machine_unregister,
0258 .set_mach_params = atom_set_mach_params,
0259
0260
0261 .debug_map = byt_debugfs,
0262 .debug_map_count = ARRAY_SIZE(byt_debugfs),
0263 .dbg_dump = atom_dump,
0264 .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
0265
0266
0267 .pcm_open = sof_stream_pcm_open,
0268 .pcm_close = sof_stream_pcm_close,
0269
0270
0271 .load_firmware = snd_sof_load_firmware_memcpy,
0272
0273
0274 .suspend = byt_suspend,
0275 .resume = byt_resume,
0276
0277
0278 .drv = atom_dai,
0279 .num_drv = 3,
0280
0281
0282 .hw_info = SNDRV_PCM_INFO_MMAP |
0283 SNDRV_PCM_INFO_MMAP_VALID |
0284 SNDRV_PCM_INFO_INTERLEAVED |
0285 SNDRV_PCM_INFO_PAUSE |
0286 SNDRV_PCM_INFO_BATCH,
0287
0288 .dsp_arch_ops = &sof_xtensa_arch_ops,
0289 };
0290
0291 static const struct sof_intel_dsp_desc byt_chip_info = {
0292 .cores_num = 1,
0293 .host_managed_cores_mask = 1,
0294 .hw_ip_version = SOF_INTEL_BAYTRAIL,
0295 };
0296
0297
0298 static struct snd_sof_dsp_ops sof_cht_ops = {
0299
0300 .probe = byt_acpi_probe,
0301 .remove = byt_remove,
0302
0303
0304 .run = atom_run,
0305 .reset = atom_reset,
0306
0307
0308 .write = sof_io_write,
0309 .read = sof_io_read,
0310 .write64 = sof_io_write64,
0311 .read64 = sof_io_read64,
0312
0313
0314 .block_read = sof_block_read,
0315 .block_write = sof_block_write,
0316
0317
0318 .mailbox_read = sof_mailbox_read,
0319 .mailbox_write = sof_mailbox_write,
0320
0321
0322 .irq_handler = atom_irq_handler,
0323 .irq_thread = atom_irq_thread,
0324
0325
0326 .send_msg = atom_send_msg,
0327 .get_mailbox_offset = atom_get_mailbox_offset,
0328 .get_window_offset = atom_get_window_offset,
0329
0330 .ipc_msg_data = sof_ipc_msg_data,
0331 .set_stream_data_offset = sof_set_stream_data_offset,
0332
0333
0334 .machine_select = atom_machine_select,
0335 .machine_register = sof_machine_register,
0336 .machine_unregister = sof_machine_unregister,
0337 .set_mach_params = atom_set_mach_params,
0338
0339
0340 .debug_map = cht_debugfs,
0341 .debug_map_count = ARRAY_SIZE(cht_debugfs),
0342 .dbg_dump = atom_dump,
0343 .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
0344
0345
0346 .pcm_open = sof_stream_pcm_open,
0347 .pcm_close = sof_stream_pcm_close,
0348
0349
0350 .load_firmware = snd_sof_load_firmware_memcpy,
0351
0352
0353 .suspend = byt_suspend,
0354 .resume = byt_resume,
0355
0356
0357 .drv = atom_dai,
0358
0359 .num_drv = 6,
0360
0361
0362 .hw_info = SNDRV_PCM_INFO_MMAP |
0363 SNDRV_PCM_INFO_MMAP_VALID |
0364 SNDRV_PCM_INFO_INTERLEAVED |
0365 SNDRV_PCM_INFO_PAUSE |
0366 SNDRV_PCM_INFO_BATCH,
0367
0368 .dsp_arch_ops = &sof_xtensa_arch_ops,
0369 };
0370
0371 static const struct sof_intel_dsp_desc cht_chip_info = {
0372 .cores_num = 1,
0373 .host_managed_cores_mask = 1,
0374 .hw_ip_version = SOF_INTEL_BAYTRAIL,
0375 };
0376
0377
0378 static const struct sof_dev_desc sof_acpi_baytrailcr_desc = {
0379 .machines = snd_soc_acpi_intel_baytrail_machines,
0380 .resindex_lpe_base = 0,
0381 .resindex_pcicfg_base = 1,
0382 .resindex_imr_base = 2,
0383 .irqindex_host_ipc = 0,
0384 .chip_info = &byt_chip_info,
0385 .ipc_supported_mask = BIT(SOF_IPC),
0386 .ipc_default = SOF_IPC,
0387 .default_fw_path = {
0388 [SOF_IPC] = "intel/sof",
0389 },
0390 .default_tplg_path = {
0391 [SOF_IPC] = "intel/sof-tplg",
0392 },
0393 .default_fw_filename = {
0394 [SOF_IPC] = "sof-byt.ri",
0395 },
0396 .nocodec_tplg_filename = "sof-byt-nocodec.tplg",
0397 .ops = &sof_byt_ops,
0398 };
0399
0400 static const struct sof_dev_desc sof_acpi_baytrail_desc = {
0401 .machines = snd_soc_acpi_intel_baytrail_machines,
0402 .resindex_lpe_base = 0,
0403 .resindex_pcicfg_base = 1,
0404 .resindex_imr_base = 2,
0405 .irqindex_host_ipc = 5,
0406 .chip_info = &byt_chip_info,
0407 .ipc_supported_mask = BIT(SOF_IPC),
0408 .ipc_default = SOF_IPC,
0409 .default_fw_path = {
0410 [SOF_IPC] = "intel/sof",
0411 },
0412 .default_tplg_path = {
0413 [SOF_IPC] = "intel/sof-tplg",
0414 },
0415 .default_fw_filename = {
0416 [SOF_IPC] = "sof-byt.ri",
0417 },
0418 .nocodec_tplg_filename = "sof-byt-nocodec.tplg",
0419 .ops = &sof_byt_ops,
0420 };
0421
0422 static const struct sof_dev_desc sof_acpi_cherrytrail_desc = {
0423 .machines = snd_soc_acpi_intel_cherrytrail_machines,
0424 .resindex_lpe_base = 0,
0425 .resindex_pcicfg_base = 1,
0426 .resindex_imr_base = 2,
0427 .irqindex_host_ipc = 5,
0428 .chip_info = &cht_chip_info,
0429 .ipc_supported_mask = BIT(SOF_IPC),
0430 .ipc_default = SOF_IPC,
0431 .default_fw_path = {
0432 [SOF_IPC] = "intel/sof",
0433 },
0434 .default_tplg_path = {
0435 [SOF_IPC] = "intel/sof-tplg",
0436 },
0437 .default_fw_filename = {
0438 [SOF_IPC] = "sof-cht.ri",
0439 },
0440 .nocodec_tplg_filename = "sof-cht-nocodec.tplg",
0441 .ops = &sof_cht_ops,
0442 };
0443
0444 static const struct acpi_device_id sof_baytrail_match[] = {
0445 { "80860F28", (unsigned long)&sof_acpi_baytrail_desc },
0446 { "808622A8", (unsigned long)&sof_acpi_cherrytrail_desc },
0447 { }
0448 };
0449 MODULE_DEVICE_TABLE(acpi, sof_baytrail_match);
0450
0451 static int sof_baytrail_probe(struct platform_device *pdev)
0452 {
0453 struct device *dev = &pdev->dev;
0454 const struct sof_dev_desc *desc;
0455 const struct acpi_device_id *id;
0456 int ret;
0457
0458 id = acpi_match_device(dev->driver->acpi_match_table, dev);
0459 if (!id)
0460 return -ENODEV;
0461
0462 ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
0463 if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
0464 dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
0465 return -ENODEV;
0466 }
0467
0468 desc = (const struct sof_dev_desc *)id->driver_data;
0469 if (desc == &sof_acpi_baytrail_desc && soc_intel_is_byt_cr(pdev))
0470 desc = &sof_acpi_baytrailcr_desc;
0471
0472 return sof_acpi_probe(pdev, desc);
0473 }
0474
0475
0476 static struct platform_driver snd_sof_acpi_intel_byt_driver = {
0477 .probe = sof_baytrail_probe,
0478 .remove = sof_acpi_remove,
0479 .driver = {
0480 .name = "sof-audio-acpi-intel-byt",
0481 .pm = &sof_acpi_pm,
0482 .acpi_match_table = sof_baytrail_match,
0483 },
0484 };
0485 module_platform_driver(snd_sof_acpi_intel_byt_driver);
0486
0487 MODULE_LICENSE("Dual BSD/GPL");
0488 MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
0489 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
0490 MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV);
0491 MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_ATOM_HIFI_EP);