// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) // // This file is provided under a dual BSD/GPLv2 license. When using or // redistributing this file, you may do so under either license. // // Copyright(c) 2018 Intel Corporation // // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> //
/* * Hardware interface for audio DSP on Broadwell
*/
staticint bdw_run(struct snd_sof_dev *sdev)
{ /* set opportunistic mode on engine 0,1 for all channels */
snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
SHIM_HMDC_HDDA_E0_ALLCH |
SHIM_HMDC_HDDA_E1_ALLCH, 0);
/* set DSP to RUN */
snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
SHIM_CSR_STALL, 0x0);
/* return init core mask */ return 1;
}
staticint bdw_reset(struct snd_sof_dev *sdev)
{ /* put DSP into reset and stall */
snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
SHIM_CSR_RST | SHIM_CSR_STALL,
SHIM_CSR_RST | SHIM_CSR_STALL);
/* keep in reset for 10ms */
mdelay(10);
/* take DSP out of reset and keep stalled for FW loading */
snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
SHIM_CSR_RST | SHIM_CSR_STALL,
SHIM_CSR_STALL);
/* * set default power gating control, enable power gating control for * all blocks. that is, can't be accessed, please enable each block * before accessing.
*/
snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL0,
0xfffffffC, 0x0);
/* disable DMA finish function for SSP0 & SSP1 */
snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR2,
SHIM_CSR2_SDFD_SSP1,
SHIM_CSR2_SDFD_SSP1);
/* set on-demond mode on engine 0,1 for all channels */
snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
SHIM_HMDC_HDDA_E0_ALLCH |
SHIM_HMDC_HDDA_E1_ALLCH,
SHIM_HMDC_HDDA_E0_ALLCH |
SHIM_HMDC_HDDA_E1_ALLCH);
/* reply message from DSP */ if (ipcx & SHIM_IPCX_DONE &&
!(imrx & SHIM_IMRX_DONE)) { /* Mask Done interrupt before return */
snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
SHIM_IMRX, SHIM_IMRX_DONE,
SHIM_IMRX_DONE);
spin_lock_irq(&sdev->ipc_lock);
/* * handle immediate reply from DSP core. If the msg is * found, set done bit in cmd_done which is called at the * end of message processing function, else set it here * because the done bit can't be set in cmd_done function * which is triggered by msg
*/
snd_sof_ipc_process_reply(sdev, ipcx);
staticvoid bdw_host_done(struct snd_sof_dev *sdev)
{ /* clear BUSY bit and set DONE bit - accept new messages */
snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCD,
SHIM_IPCD_BUSY | SHIM_IPCD_DONE,
SHIM_IPCD_DONE);
chip = get_chip_info(sdev->pdata); if (!chip) {
dev_err(sdev->dev, "error: no such device supported\n"); return -EIO;
}
sdev->num_cores = chip->cores_num;
/* LPE base */
mmio = platform_get_resource(pdev, IORESOURCE_MEM,
desc->resindex_lpe_base); if (mmio) {
base = mmio->start;
size = resource_size(mmio);
} else {
dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
desc->resindex_lpe_base); return -EINVAL;
}
dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
sdev->bar[BDW_DSP_BAR] = devm_ioremap(sdev->dev, base, size); if (!sdev->bar[BDW_DSP_BAR]) {
dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
base, size); return -ENODEV;
}
dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BDW_DSP_BAR]);
/* PCI base */
mmio = platform_get_resource(pdev, IORESOURCE_MEM,
desc->resindex_pcicfg_base); if (mmio) {
base = mmio->start;
size = resource_size(mmio);
} else {
dev_err(sdev->dev, "error: failed to get PCI base at idx %d\n",
desc->resindex_pcicfg_base); return -ENODEV;
}
dev_dbg(sdev->dev, "PCI base at 0x%x size 0x%x", base, size);
sdev->bar[BDW_PCI_BAR] = devm_ioremap(sdev->dev, base, size); if (!sdev->bar[BDW_PCI_BAR]) {
dev_err(sdev->dev, "error: failed to ioremap PCI base 0x%x size 0x%x\n",
base, size); return -ENODEV;
}
dev_dbg(sdev->dev, "PCI VADDR %p\n", sdev->bar[BDW_PCI_BAR]);
dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
bdw_irq_handler, bdw_irq_thread,
IRQF_SHARED, "AudioDSP", sdev); if (ret < 0) {
dev_err(sdev->dev, "error: failed to register IRQ %d\n",
sdev->ipc_irq); return ret;
}
/* enable the DSP SHIM */
ret = bdw_set_dsp_D0(sdev); if (ret < 0) {
dev_err(sdev->dev, "error: failed to set DSP D0\n"); return ret;
}
/* DSP DMA can only access low 31 bits of host memory */
ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31)); if (ret < 0) {
dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); return ret;
}
/* set default mailbox offset for FW ready message */
sdev->dsp_box.offset = MBOX_OFFSET;
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("SOF support for Broadwell platforms");
MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA");
MODULE_IMPORT_NS("SND_SOC_SOF_ACPI_DEV");
Messung V0.5
¤ Dauer der Verarbeitung: 0.37 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.