Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 //
0003 // This file is provided under a dual BSD/GPLv2 license.  When using or
0004 // redistributing this file, you may do so under either license.
0005 //
0006 // Copyright(c) 2018 Intel Corporation. All rights reserved.
0007 //
0008 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
0009 //
0010 
0011 /*
0012  * Hardware interface for audio DSP on Baytrail, Braswell and Cherrytrail.
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     /* Disable Interrupt from both sides */
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     /* Put DSP into reset, set reset vector */
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     /* enable BUSY and disable DONE Interrupt by default */
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     /* DSP DMA can only access low 31 bits of host memory */
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     /* LPE base */
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     /* TODO: add offsets */
0158     sdev->mmio_bar = DSP_BAR;
0159     sdev->mailbox_bar = DSP_BAR;
0160 
0161     /* IMR base - optional */
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     /* some BIOSes don't map IMR */
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     /* register our IRQ */
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     /* enable BUSY and disable DONE Interrupt by default */
0208     snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
0209                   SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
0210                   SHIM_IMRX_DONE);
0211 
0212     /* set default mailbox offset for FW ready message */
0213     sdev->dsp_box.offset = MBOX_OFFSET;
0214 
0215     return ret;
0216 }
0217 
0218 /* baytrail ops */
0219 static struct snd_sof_dsp_ops sof_byt_ops = {
0220     /* device init */
0221     .probe      = byt_acpi_probe,
0222     .remove     = byt_remove,
0223 
0224     /* DSP core boot / reset */
0225     .run        = atom_run,
0226     .reset      = atom_reset,
0227 
0228     /* Register IO */
0229     .write      = sof_io_write,
0230     .read       = sof_io_read,
0231     .write64    = sof_io_write64,
0232     .read64     = sof_io_read64,
0233 
0234     /* Block IO */
0235     .block_read = sof_block_read,
0236     .block_write    = sof_block_write,
0237 
0238     /* Mailbox IO */
0239     .mailbox_read   = sof_mailbox_read,
0240     .mailbox_write  = sof_mailbox_write,
0241 
0242     /* doorbell */
0243     .irq_handler    = atom_irq_handler,
0244     .irq_thread = atom_irq_thread,
0245 
0246     /* ipc */
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     /* machine driver */
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     /* debug */
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     /* stream callbacks */
0267     .pcm_open   = sof_stream_pcm_open,
0268     .pcm_close  = sof_stream_pcm_close,
0269 
0270     /*Firmware loading */
0271     .load_firmware  = snd_sof_load_firmware_memcpy,
0272 
0273     /* PM */
0274     .suspend = byt_suspend,
0275     .resume = byt_resume,
0276 
0277     /* DAI drivers */
0278     .drv = atom_dai,
0279     .num_drv = 3, /* we have only 3 SSPs on byt*/
0280 
0281     /* ALSA HW info flags */
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 /* cherrytrail and braswell ops */
0298 static struct snd_sof_dsp_ops sof_cht_ops = {
0299     /* device init */
0300     .probe      = byt_acpi_probe,
0301     .remove     = byt_remove,
0302 
0303     /* DSP core boot / reset */
0304     .run        = atom_run,
0305     .reset      = atom_reset,
0306 
0307     /* Register IO */
0308     .write      = sof_io_write,
0309     .read       = sof_io_read,
0310     .write64    = sof_io_write64,
0311     .read64     = sof_io_read64,
0312 
0313     /* Block IO */
0314     .block_read = sof_block_read,
0315     .block_write    = sof_block_write,
0316 
0317     /* Mailbox IO */
0318     .mailbox_read   = sof_mailbox_read,
0319     .mailbox_write  = sof_mailbox_write,
0320 
0321     /* doorbell */
0322     .irq_handler    = atom_irq_handler,
0323     .irq_thread = atom_irq_thread,
0324 
0325     /* ipc */
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     /* machine driver */
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     /* debug */
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     /* stream callbacks */
0346     .pcm_open   = sof_stream_pcm_open,
0347     .pcm_close  = sof_stream_pcm_close,
0348 
0349     /*Firmware loading */
0350     .load_firmware  = snd_sof_load_firmware_memcpy,
0351 
0352     /* PM */
0353     .suspend = byt_suspend,
0354     .resume = byt_resume,
0355 
0356     /* DAI drivers */
0357     .drv = atom_dai,
0358     /* all 6 SSPs may be available for cherrytrail */
0359     .num_drv = 6,
0360 
0361     /* ALSA HW info flags */
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 /* BYTCR uses different IRQ index */
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 /* acpi_driver definition */
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);