aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/soc/sof/intel/bdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/intel/bdw.c')
-rw-r--r--sound/soc/sof/intel/bdw.c183
1 files changed, 109 insertions, 74 deletions
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
index 99fd0bd7276e..e30ca086f3f8 100644
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -15,8 +15,12 @@
#include <linux/module.h>
#include <sound/sof.h>
#include <sound/sof/xtensa.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+#include <sound/intel-dsp-config.h>
#include "../ops.h"
#include "shim.h"
+#include "../sof-acpi-dev.h"
#include "../sof-audio.h"
/* BARs */
@@ -71,7 +75,6 @@ static const struct snd_sof_debugfs_map bdw_debugfs[] = {
static void bdw_host_done(struct snd_sof_dev *sdev);
static void bdw_dsp_done(struct snd_sof_dev *sdev);
-static void bdw_get_reply(struct snd_sof_dev *sdev);
/*
* DSP Control.
@@ -255,8 +258,8 @@ static void bdw_dump(struct snd_sof_dev *sdev, u32 flags)
panic = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX);
bdw_get_registers(sdev, &xoops, &panic_info, stack,
BDW_STACK_DUMP_SIZE);
- snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
- BDW_STACK_DUMP_SIZE);
+ sof_print_oops_and_stack(sdev, KERN_ERR, status, panic, &xoops,
+ &panic_info, stack, BDW_STACK_DUMP_SIZE);
/* provide some context for firmware debug */
imrx = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IMRX);
@@ -322,8 +325,7 @@ static irqreturn_t bdw_irq_thread(int irq, void *context)
* because the done bit can't be set in cmd_done function
* which is triggered by msg
*/
- bdw_get_reply(sdev);
- snd_sof_ipc_reply(sdev, ipcx);
+ snd_sof_ipc_process_reply(sdev, ipcx);
bdw_dsp_done(sdev);
@@ -342,8 +344,8 @@ static irqreturn_t bdw_irq_thread(int irq, void *context)
/* Handle messages from DSP Core */
if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
- snd_sof_dsp_panic(sdev, BDW_PANIC_OFFSET(ipcx) +
- MBOX_OFFSET);
+ snd_sof_dsp_panic(sdev, BDW_PANIC_OFFSET(ipcx) + MBOX_OFFSET,
+ true);
} else {
snd_sof_ipc_msgs_rx(sdev);
}
@@ -368,45 +370,6 @@ static int bdw_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
return 0;
}
-static void bdw_get_reply(struct snd_sof_dev *sdev)
-{
- struct snd_sof_ipc_msg *msg = sdev->msg;
- struct sof_ipc_reply reply;
- int ret = 0;
-
- /*
- * Sometimes, there is unexpected reply ipc arriving. The reply
- * ipc belongs to none of the ipcs sent from driver.
- * In this case, the driver must ignore the ipc.
- */
- if (!msg) {
- dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n");
- return;
- }
-
- /* get reply */
- sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
-
- if (reply.error < 0) {
- memcpy(msg->reply_data, &reply, sizeof(reply));
- ret = reply.error;
- } else {
- /* reply correct size ? */
- if (reply.hdr.size != msg->reply_size) {
- dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
- msg->reply_size, reply.hdr.size);
- ret = -EINVAL;
- }
-
- /* read the message */
- if (msg->reply_size > 0)
- sof_mailbox_read(sdev, sdev->host_box.offset,
- msg->reply_data, msg->reply_size);
- }
-
- msg->reply_error = ret;
-}
-
static int bdw_get_mailbox_offset(struct snd_sof_dev *sdev)
{
return MBOX_OFFSET;
@@ -449,10 +412,19 @@ static int bdw_probe(struct snd_sof_dev *sdev)
const struct sof_dev_desc *desc = pdata->desc;
struct platform_device *pdev =
container_of(sdev->dev, struct platform_device, dev);
+ const struct sof_intel_dsp_desc *chip;
struct resource *mmio;
u32 base, size;
int ret;
+ 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);
@@ -531,13 +503,13 @@ static int bdw_probe(struct snd_sof_dev *sdev)
return ret;
}
- /* set default mailbox */
- snd_sof_dsp_mailbox_init(sdev, MBOX_OFFSET, MBOX_SIZE, 0, 0);
+ /* set default mailbox offset for FW ready message */
+ sdev->dsp_box.offset = MBOX_OFFSET;
return ret;
}
-static void bdw_machine_select(struct snd_sof_dev *sdev)
+static struct snd_soc_acpi_mach *bdw_machine_select(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *sof_pdata = sdev->pdata;
const struct sof_dev_desc *desc = sof_pdata->desc;
@@ -546,21 +518,26 @@ static void bdw_machine_select(struct snd_sof_dev *sdev)
mach = snd_soc_acpi_find_machine(desc->machines);
if (!mach) {
dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
- return;
+ return NULL;
}
sof_pdata->tplg_filename = mach->sof_tplg_filename;
mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc;
- sof_pdata->machine = mach;
+
+ return mach;
}
-static void bdw_set_mach_params(const struct snd_soc_acpi_mach *mach,
- struct device *dev)
+static void bdw_set_mach_params(struct snd_soc_acpi_mach *mach,
+ struct snd_sof_dev *sdev)
{
+ struct snd_sof_pdata *pdata = sdev->pdata;
+ const struct sof_dev_desc *desc = pdata->desc;
struct snd_soc_acpi_mach_params *mach_params;
- mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params;
- mach_params->platform = dev_name(dev);
+ mach_params = &mach->mach_params;
+ mach_params->platform = dev_name(sdev->dev);
+ mach_params->num_dai_drivers = desc->ops->num_drv;
+ mach_params->dai_drivers = desc->ops->drv;
}
/* Broadwell DAIs */
@@ -590,7 +567,7 @@ static struct snd_soc_dai_driver bdw_dai[] = {
};
/* broadwell ops */
-const struct snd_sof_dsp_ops sof_bdw_ops = {
+static struct snd_sof_dsp_ops sof_bdw_ops = {
/*Device init */
.probe = bdw_probe,
@@ -598,24 +575,23 @@ const struct snd_sof_dsp_ops sof_bdw_ops = {
.run = bdw_run,
.reset = bdw_reset,
- /* Register IO */
- .write = sof_io_write,
- .read = sof_io_read,
- .write64 = sof_io_write64,
- .read64 = sof_io_read64,
+ /* Register IO uses direct mmio */
/* Block IO */
.block_read = sof_block_read,
.block_write = sof_block_write,
+ /* Mailbox IO */
+ .mailbox_read = sof_mailbox_read,
+ .mailbox_write = sof_mailbox_write,
+
/* ipc */
.send_msg = bdw_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = bdw_get_mailbox_offset,
.get_window_offset = bdw_get_window_offset,
- .ipc_msg_data = intel_ipc_msg_data,
- .ipc_pcm_params = intel_ipc_pcm_params,
+ .ipc_msg_data = sof_ipc_msg_data,
+ .set_stream_data_offset = sof_set_stream_data_offset,
/* machine driver */
.machine_select = bdw_machine_select,
@@ -627,13 +603,11 @@ const struct snd_sof_dsp_ops sof_bdw_ops = {
.debug_map = bdw_debugfs,
.debug_map_count = ARRAY_SIZE(bdw_debugfs),
.dbg_dump = bdw_dump,
+ .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
/* stream callbacks */
- .pcm_open = intel_pcm_open,
- .pcm_close = intel_pcm_close,
-
- /* Module loading */
- .load_module = snd_sof_parse_module_memcpy,
+ .pcm_open = sof_stream_pcm_open,
+ .pcm_close = sof_stream_pcm_close,
/*Firmware loading */
.load_firmware = snd_sof_load_firmware_memcpy,
@@ -649,16 +623,77 @@ const struct snd_sof_dsp_ops sof_bdw_ops = {
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_BATCH,
- .arch_ops = &sof_xtensa_arch_ops,
+ .dsp_arch_ops = &sof_xtensa_arch_ops,
};
-EXPORT_SYMBOL_NS(sof_bdw_ops, SND_SOC_SOF_BROADWELL);
-const struct sof_intel_dsp_desc bdw_chip_info = {
+static const struct sof_intel_dsp_desc bdw_chip_info = {
.cores_num = 1,
- .cores_mask = 1,
+ .host_managed_cores_mask = 1,
+ .hw_ip_version = SOF_INTEL_BROADWELL,
+};
+
+static const struct sof_dev_desc sof_acpi_broadwell_desc = {
+ .machines = snd_soc_acpi_intel_broadwell_machines,
+ .resindex_lpe_base = 0,
+ .resindex_pcicfg_base = 1,
+ .resindex_imr_base = -1,
+ .irqindex_host_ipc = 0,
+ .chip_info = &bdw_chip_info,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
+ .default_fw_path = {
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ },
+ .default_tplg_path = {
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ },
+ .default_fw_filename = {
+ [SOF_IPC_TYPE_3] = "sof-bdw.ri",
+ },
+ .nocodec_tplg_filename = "sof-bdw-nocodec.tplg",
+ .ops = &sof_bdw_ops,
+};
+
+static const struct acpi_device_id sof_broadwell_match[] = {
+ { "INT3438", (unsigned long)&sof_acpi_broadwell_desc },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, sof_broadwell_match);
+
+static int sof_broadwell_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct acpi_device_id *id;
+ const struct sof_dev_desc *desc;
+ int ret;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id)
+ return -ENODEV;
+
+ ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
+ if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
+ dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
+ return -ENODEV;
+ }
+
+ desc = (const struct sof_dev_desc *)id->driver_data;
+ return sof_acpi_probe(pdev, desc);
+}
+
+/* acpi_driver definition */
+static struct platform_driver snd_sof_acpi_intel_bdw_driver = {
+ .probe = sof_broadwell_probe,
+ .remove_new = sof_acpi_remove,
+ .driver = {
+ .name = "sof-audio-acpi-intel-bdw",
+ .pm = &sof_acpi_pm,
+ .acpi_match_table = sof_broadwell_match,
+ },
};
-EXPORT_SYMBOL_NS(bdw_chip_info, SND_SOC_SOF_BROADWELL);
+module_platform_driver(snd_sof_acpi_intel_bdw_driver);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
+MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV);