summaryrefslogtreecommitdiff
path: root/sound/soc/sof
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/Kconfig2
-rw-r--r--sound/soc/sof/Makefile6
-rw-r--r--sound/soc/sof/amd/acp-pcm.c2
-rw-r--r--sound/soc/sof/amd/acp.c4
-rw-r--r--sound/soc/sof/amd/acp.h2
-rw-r--r--sound/soc/sof/amd/pci-rmb.c10
-rw-r--r--sound/soc/sof/amd/pci-rn.c10
-rw-r--r--sound/soc/sof/amd/pci-vangogh.c10
-rw-r--r--sound/soc/sof/core.c17
-rw-r--r--sound/soc/sof/imx/imx8.c26
-rw-r--r--sound/soc/sof/imx/imx8m.c16
-rw-r--r--sound/soc/sof/imx/imx8ulp.c16
-rw-r--r--sound/soc/sof/intel/Kconfig14
-rw-r--r--sound/soc/sof/intel/Makefile3
-rw-r--r--sound/soc/sof/intel/apl.c4
-rw-r--r--sound/soc/sof/intel/bdw.c12
-rw-r--r--sound/soc/sof/intel/byt.c36
-rw-r--r--sound/soc/sof/intel/cnl.c4
-rw-r--r--sound/soc/sof/intel/hda-codec.c1
-rw-r--r--sound/soc/sof/intel/hda-common-ops.c2
-rw-r--r--sound/soc/sof/intel/hda-dai-ops.c26
-rw-r--r--sound/soc/sof/intel/hda-dai.c12
-rw-r--r--sound/soc/sof/intel/hda-dsp.c3
-rw-r--r--sound/soc/sof/intel/hda-loader.c44
-rw-r--r--sound/soc/sof/intel/hda-pcm.c4
-rw-r--r--sound/soc/sof/intel/hda-stream.c4
-rw-r--r--sound/soc/sof/intel/hda.c66
-rw-r--r--sound/soc/sof/intel/hda.h8
-rw-r--r--sound/soc/sof/intel/icl.c4
-rw-r--r--sound/soc/sof/intel/mtl.c3
-rw-r--r--sound/soc/sof/intel/pci-apl.c36
-rw-r--r--sound/soc/sof/intel/pci-cnl.c54
-rw-r--r--sound/soc/sof/intel/pci-icl.c36
-rw-r--r--sound/soc/sof/intel/pci-lnl.c10
-rw-r--r--sound/soc/sof/intel/pci-mtl.c43
-rw-r--r--sound/soc/sof/intel/pci-skl.c20
-rw-r--r--sound/soc/sof/intel/pci-tgl.c144
-rw-r--r--sound/soc/sof/intel/pci-tng.c10
-rw-r--r--sound/soc/sof/intel/telemetry.c95
-rw-r--r--sound/soc/sof/intel/telemetry.h35
-rw-r--r--sound/soc/sof/intel/tgl.c5
-rw-r--r--sound/soc/sof/ipc.c6
-rw-r--r--sound/soc/sof/ipc3-dtrace.c2
-rw-r--r--sound/soc/sof/ipc3-pcm.c6
-rw-r--r--sound/soc/sof/ipc4-control.c175
-rw-r--r--sound/soc/sof/ipc4-mtrace.c34
-rw-r--r--sound/soc/sof/ipc4-pcm.c118
-rw-r--r--sound/soc/sof/ipc4-priv.h3
-rw-r--r--sound/soc/sof/ipc4-telemetry.c95
-rw-r--r--sound/soc/sof/ipc4-telemetry.h73
-rw-r--r--sound/soc/sof/ipc4-topology.c76
-rw-r--r--sound/soc/sof/ipc4-topology.h22
-rw-r--r--sound/soc/sof/ipc4.c40
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186.c28
-rw-r--r--sound/soc/sof/mediatek/mt8195/mt8195.c18
-rw-r--r--sound/soc/sof/nocodec.c2
-rw-r--r--sound/soc/sof/ops.h22
-rw-r--r--sound/soc/sof/pcm.c18
-rw-r--r--sound/soc/sof/sof-acpi-dev.c12
-rw-r--r--sound/soc/sof/sof-acpi-dev.h2
-rw-r--r--sound/soc/sof/sof-audio.c7
-rw-r--r--sound/soc/sof/sof-client-ipc-msg-injector.c4
-rw-r--r--sound/soc/sof/sof-client-probes.c6
-rw-r--r--sound/soc/sof/sof-client.c27
-rw-r--r--sound/soc/sof/sof-of-dev.c10
-rw-r--r--sound/soc/sof/sof-of-dev.h2
-rw-r--r--sound/soc/sof/sof-pci-dev.c10
-rw-r--r--sound/soc/sof/sof-priv.h4
-rw-r--r--sound/soc/sof/xtensa/core.c11
69 files changed, 1240 insertions, 452 deletions
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig
index 80361139a49a..a741ed96e789 100644
--- a/sound/soc/sof/Kconfig
+++ b/sound/soc/sof/Kconfig
@@ -283,7 +283,7 @@ config SND_SOC_SOF_PROBE_WORK_QUEUE
config SND_SOC_SOF_IPC3
bool
-config SND_SOC_SOF_INTEL_IPC4
+config SND_SOC_SOF_IPC4
bool
source "sound/soc/sof/amd/Kconfig"
diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile
index 744d40bd8c8b..ef6fd43d0b72 100644
--- a/sound/soc/sof/Makefile
+++ b/sound/soc/sof/Makefile
@@ -8,9 +8,9 @@ ifneq ($(CONFIG_SND_SOC_SOF_IPC3),)
snd-sof-objs += ipc3.o ipc3-loader.o ipc3-topology.o ipc3-control.o ipc3-pcm.o\
ipc3-dtrace.o
endif
-ifneq ($(CONFIG_SND_SOC_SOF_INTEL_IPC4),)
+ifneq ($(CONFIG_SND_SOC_SOF_IPC4),)
snd-sof-objs += ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o ipc4-pcm.o\
- ipc4-mtrace.o
+ ipc4-mtrace.o ipc4-telemetry.o
endif
# SOF client support
@@ -31,7 +31,7 @@ snd-sof-probes-objs := sof-client-probes.o
ifneq ($(CONFIG_SND_SOC_SOF_IPC3),)
snd-sof-probes-objs += sof-client-probes-ipc3.o
endif
-ifneq ($(CONFIG_SND_SOC_SOF_INTEL_IPC4),)
+ifneq ($(CONFIG_SND_SOC_SOF_IPC4),)
snd-sof-probes-objs += sof-client-probes-ipc4.o
endif
diff --git a/sound/soc/sof/amd/acp-pcm.c b/sound/soc/sof/amd/acp-pcm.c
index 0828245bbb99..cee0b1154874 100644
--- a/sound/soc/sof/amd/acp-pcm.c
+++ b/sound/soc/sof/amd/acp-pcm.c
@@ -89,7 +89,7 @@ EXPORT_SYMBOL_NS(acp_pcm_close, SND_SOC_SOF_AMD_COMMON);
snd_pcm_uframes_t acp_pcm_pointer(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *scomp = sdev->component;
struct snd_sof_pcm_stream *stream;
struct sof_ipc_stream_posn posn;
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 19a801908b56..603ea5fc0d0d 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -575,7 +575,7 @@ unregister_dev:
}
EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON);
-int amd_sof_acp_remove(struct snd_sof_dev *sdev)
+void amd_sof_acp_remove(struct snd_sof_dev *sdev)
{
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
@@ -588,7 +588,7 @@ int amd_sof_acp_remove(struct snd_sof_dev *sdev)
if (adata->dmic_dev)
platform_device_unregister(adata->dmic_dev);
- return acp_reset(sdev);
+ acp_reset(sdev);
}
EXPORT_SYMBOL_NS(amd_sof_acp_remove, SND_SOC_SOF_AMD_COMMON);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index 4dcceb764769..6814f2051104 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -220,7 +220,7 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
/* ACP device probe/remove */
int amd_sof_acp_probe(struct snd_sof_dev *sdev);
-int amd_sof_acp_remove(struct snd_sof_dev *sdev);
+void amd_sof_acp_remove(struct snd_sof_dev *sdev);
/* DSP Loader callbacks */
int acp_sof_dsp_run(struct snd_sof_dev *sdev);
diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c
index a7ae76efc2dd..2f288545c426 100644
--- a/sound/soc/sof/amd/pci-rmb.c
+++ b/sound/soc/sof/amd/pci-rmb.c
@@ -46,16 +46,16 @@ static const struct sof_dev_desc rembrandt_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &rembrandt_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "amd/sof",
+ [SOF_IPC_TYPE_3] = "amd/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "amd/sof-tplg",
+ [SOF_IPC_TYPE_3] = "amd/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-rmb.ri",
+ [SOF_IPC_TYPE_3] = "sof-rmb.ri",
},
.nocodec_tplg_filename = "sof-acp.tplg",
.ops = &sof_rembrandt_ops,
diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c
index c72d5d8aff8e..a0195e9b400c 100644
--- a/sound/soc/sof/amd/pci-rn.c
+++ b/sound/soc/sof/amd/pci-rn.c
@@ -47,16 +47,16 @@ static const struct sof_dev_desc renoir_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &renoir_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "amd/sof",
+ [SOF_IPC_TYPE_3] = "amd/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "amd/sof-tplg",
+ [SOF_IPC_TYPE_3] = "amd/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-rn.ri",
+ [SOF_IPC_TYPE_3] = "sof-rn.ri",
},
.nocodec_tplg_filename = "sof-acp.tplg",
.ops = &sof_renoir_ops,
diff --git a/sound/soc/sof/amd/pci-vangogh.c b/sound/soc/sof/amd/pci-vangogh.c
index d8be42fbcb6d..5cd3ac84752f 100644
--- a/sound/soc/sof/amd/pci-vangogh.c
+++ b/sound/soc/sof/amd/pci-vangogh.c
@@ -45,16 +45,16 @@ static const struct sof_dev_desc vangogh_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &vangogh_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "amd/sof",
+ [SOF_IPC_TYPE_3] = "amd/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "amd/sof-tplg",
+ [SOF_IPC_TYPE_3] = "amd/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-vangogh.ri",
+ [SOF_IPC_TYPE_3] = "sof-vangogh.ri",
},
.nocodec_tplg_filename = "sof-acp.tplg",
.ops = &sof_vangogh_ops,
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
index 2d1616b81485..d7b090224f1b 100644
--- a/sound/soc/sof/core.c
+++ b/sound/soc/sof/core.c
@@ -327,6 +327,7 @@ dbg_err:
dsp_err:
snd_sof_remove(sdev);
probe_err:
+ snd_sof_remove_late(sdev);
sof_ops_free(sdev);
/* all resources freed, update state to match */
@@ -436,6 +437,14 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED);
+ /*
+ * first pass of probe which isn't allowed to run in a work-queue,
+ * typically to rely on -EPROBE_DEFER dependencies
+ */
+ ret = snd_sof_probe_early(sdev);
+ if (ret < 0)
+ return ret;
+
if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) {
INIT_WORK(&sdev->probe_work, sof_probe_work);
schedule_work(&sdev->probe_work);
@@ -459,9 +468,10 @@ int snd_sof_device_remove(struct device *dev)
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_sof_pdata *pdata = sdev->pdata;
int ret;
+ bool aborted = false;
if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
- cancel_work_sync(&sdev->probe_work);
+ aborted = cancel_work_sync(&sdev->probe_work);
/*
* Unregister any registered client device first before IPC and debugfs
@@ -486,6 +496,11 @@ int snd_sof_device_remove(struct device *dev)
snd_sof_ipc_free(sdev);
snd_sof_free_debug(sdev);
snd_sof_remove(sdev);
+ snd_sof_remove_late(sdev);
+ sof_ops_free(sdev);
+ } else if (aborted) {
+ /* probe_work never ran */
+ snd_sof_remove_late(sdev);
sof_ops_free(sdev);
}
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index 2844d9a8040a..170740bce839 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -338,7 +338,7 @@ exit_unroll_pm:
return ret;
}
-static int imx8_remove(struct snd_sof_dev *sdev)
+static void imx8_remove(struct snd_sof_dev *sdev)
{
struct imx8_priv *priv = sdev->pdata->hw_pdata;
int i;
@@ -350,8 +350,6 @@ static int imx8_remove(struct snd_sof_dev *sdev)
device_link_del(priv->link[i]);
dev_pm_domain_detach(priv->pd_dev[i], false);
}
-
- return 0;
}
/* on i.MX8 there is 1 to 1 match between type and BAR idx */
@@ -609,32 +607,32 @@ static struct snd_sof_dsp_ops sof_imx8x_ops = {
};
static struct sof_dev_desc sof_of_imx8qxp_desc = {
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "imx/sof",
+ [SOF_IPC_TYPE_3] = "imx/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "imx/sof-tplg",
+ [SOF_IPC_TYPE_3] = "imx/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-imx8x.ri",
+ [SOF_IPC_TYPE_3] = "sof-imx8x.ri",
},
.nocodec_tplg_filename = "sof-imx8-nocodec.tplg",
.ops = &sof_imx8x_ops,
};
static struct sof_dev_desc sof_of_imx8qm_desc = {
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "imx/sof",
+ [SOF_IPC_TYPE_3] = "imx/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "imx/sof-tplg",
+ [SOF_IPC_TYPE_3] = "imx/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-imx8.ri",
+ [SOF_IPC_TYPE_3] = "sof-imx8.ri",
},
.nocodec_tplg_filename = "sof-imx8-nocodec.tplg",
.ops = &sof_imx8_ops,
@@ -650,7 +648,7 @@ MODULE_DEVICE_TABLE(of, sof_of_imx8_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_imx8_driver = {
.probe = sof_of_probe,
- .remove = sof_of_remove,
+ .remove_new = sof_of_remove,
.driver = {
.name = "sof-audio-of-imx8",
.pm = &sof_of_pm,
diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c
index 1243f8a6141e..2680f061ba42 100644
--- a/sound/soc/sof/imx/imx8m.c
+++ b/sound/soc/sof/imx/imx8m.c
@@ -269,14 +269,12 @@ exit_pdev_unregister:
return ret;
}
-static int imx8m_remove(struct snd_sof_dev *sdev)
+static void imx8m_remove(struct snd_sof_dev *sdev)
{
struct imx8m_priv *priv = sdev->pdata->hw_pdata;
imx8_disable_clocks(sdev, priv->clks);
platform_device_unregister(priv->ipc_dev);
-
- return 0;
}
/* on i.MX8 there is 1 to 1 match between type and BAR idx */
@@ -471,16 +469,16 @@ static struct snd_sof_dsp_ops sof_imx8m_ops = {
};
static struct sof_dev_desc sof_of_imx8mp_desc = {
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "imx/sof",
+ [SOF_IPC_TYPE_3] = "imx/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "imx/sof-tplg",
+ [SOF_IPC_TYPE_3] = "imx/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-imx8m.ri",
+ [SOF_IPC_TYPE_3] = "sof-imx8m.ri",
},
.nocodec_tplg_filename = "sof-imx8-nocodec.tplg",
.ops = &sof_imx8m_ops,
@@ -495,7 +493,7 @@ MODULE_DEVICE_TABLE(of, sof_of_imx8m_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_imx8m_driver = {
.probe = sof_of_probe,
- .remove = sof_of_remove,
+ .remove_new = sof_of_remove,
.driver = {
.name = "sof-audio-of-imx8m",
.pm = &sof_of_pm,
diff --git a/sound/soc/sof/imx/imx8ulp.c b/sound/soc/sof/imx/imx8ulp.c
index 4a562c9856e9..ca6edb85ff71 100644
--- a/sound/soc/sof/imx/imx8ulp.c
+++ b/sound/soc/sof/imx/imx8ulp.c
@@ -278,14 +278,12 @@ exit_pdev_unregister:
return ret;
}
-static int imx8ulp_remove(struct snd_sof_dev *sdev)
+static void imx8ulp_remove(struct snd_sof_dev *sdev)
{
struct imx8ulp_priv *priv = sdev->pdata->hw_pdata;
imx8_disable_clocks(sdev, priv->clks);
platform_device_unregister(priv->ipc_dev);
-
- return 0;
}
/* on i.MX8 there is 1 to 1 match between type and BAR idx */
@@ -478,16 +476,16 @@ static struct snd_sof_dsp_ops sof_imx8ulp_ops = {
};
static struct sof_dev_desc sof_of_imx8ulp_desc = {
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "imx/sof",
+ [SOF_IPC_TYPE_3] = "imx/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "imx/sof-tplg",
+ [SOF_IPC_TYPE_3] = "imx/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-imx8ulp.ri",
+ [SOF_IPC_TYPE_3] = "sof-imx8ulp.ri",
},
.nocodec_tplg_filename = "sof-imx8ulp-nocodec.tplg",
.ops = &sof_imx8ulp_ops,
@@ -502,7 +500,7 @@ MODULE_DEVICE_TABLE(of, sof_of_imx8ulp_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_imx8ulp_driver = {
.probe = sof_of_probe,
- .remove = sof_of_remove,
+ .remove_new = sof_of_remove,
.driver = {
.name = "sof-audio-of-imx8ulp",
.pm = &sof_of_pm,
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 9d0107932117..9de86aaa8d07 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -98,7 +98,7 @@ config SND_SOC_SOF_MERRIFIELD
config SND_SOC_SOF_INTEL_SKL
tristate
select SND_SOC_SOF_HDA_COMMON
- select SND_SOC_SOF_INTEL_IPC4
+ select SND_SOC_SOF_IPC4
config SND_SOC_SOF_SKYLAKE
tristate "SOF support for SkyLake"
@@ -124,7 +124,7 @@ config SND_SOC_SOF_INTEL_APL
tristate
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_IPC3
- select SND_SOC_SOF_INTEL_IPC4
+ select SND_SOC_SOF_IPC4
config SND_SOC_SOF_APOLLOLAKE
tristate "SOF support for Apollolake"
@@ -151,7 +151,7 @@ config SND_SOC_SOF_INTEL_CNL
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC3
- select SND_SOC_SOF_INTEL_IPC4
+ select SND_SOC_SOF_IPC4
config SND_SOC_SOF_CANNONLAKE
tristate "SOF support for Cannonlake"
@@ -187,7 +187,7 @@ config SND_SOC_SOF_INTEL_ICL
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC3
- select SND_SOC_SOF_INTEL_IPC4
+ select SND_SOC_SOF_IPC4
config SND_SOC_SOF_ICELAKE
tristate "SOF support for Icelake"
@@ -214,7 +214,7 @@ config SND_SOC_SOF_INTEL_TGL
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC3
- select SND_SOC_SOF_INTEL_IPC4
+ select SND_SOC_SOF_IPC4
config SND_SOC_SOF_TIGERLAKE
tristate "SOF support for Tigerlake"
@@ -250,7 +250,7 @@ config SND_SOC_SOF_INTEL_MTL
tristate
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
- select SND_SOC_SOF_INTEL_IPC4
+ select SND_SOC_SOF_IPC4
config SND_SOC_SOF_METEORLAKE
tristate "SOF support for Meteorlake"
@@ -266,7 +266,7 @@ config SND_SOC_SOF_INTEL_LNL
tristate
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
- select SND_SOC_SOF_INTEL_IPC4
+ select SND_SOC_SOF_IPC4
config SND_SOC_SOF_LUNARLAKE
tristate "SOF support for Lunarlake"
diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile
index 030574dbc998..6489d0660d58 100644
--- a/sound/soc/sof/intel/Makefile
+++ b/sound/soc/sof/intel/Makefile
@@ -7,7 +7,8 @@ snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
hda-dai.o hda-dai-ops.o hda-bus.o \
skl.o hda-loader-skl.o \
- apl.o cnl.o tgl.o icl.o mtl.o lnl.o hda-common-ops.o
+ apl.o cnl.o tgl.o icl.o mtl.o lnl.o hda-common-ops.o \
+ telemetry.o
snd-sof-intel-hda-mlink-objs := hda-mlink.o
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index e1f25a8f0c32..776b66389c34 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -39,7 +39,7 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev)
/* probe/remove/shutdown */
sof_apl_ops.shutdown = hda_dsp_shutdown;
- if (sdev->pdata->ipc_type == SOF_IPC) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
/* doorbell */
sof_apl_ops.irq_thread = hda_dsp_ipc_irq_thread;
@@ -52,7 +52,7 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev)
sof_apl_ops.set_power_state = hda_dsp_set_power_state_ipc3;
}
- if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
index 812a49b1d3f4..e30ca086f3f8 100644
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -639,16 +639,16 @@ static const struct sof_dev_desc sof_acpi_broadwell_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = 0,
.chip_info = &bdw_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
+ [SOF_IPC_TYPE_3] = "intel/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-bdw.ri",
+ [SOF_IPC_TYPE_3] = "sof-bdw.ri",
},
.nocodec_tplg_filename = "sof-bdw-nocodec.tplg",
.ops = &sof_bdw_ops,
@@ -684,7 +684,7 @@ static int sof_broadwell_probe(struct platform_device *pdev)
/* acpi_driver definition */
static struct platform_driver snd_sof_acpi_intel_bdw_driver = {
.probe = sof_broadwell_probe,
- .remove = sof_acpi_remove,
+ .remove_new = sof_acpi_remove,
.driver = {
.name = "sof-audio-acpi-intel-bdw",
.pm = &sof_acpi_pm,
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index faf223b38360..373527b206d7 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -100,11 +100,9 @@ static int byt_resume(struct snd_sof_dev *sdev)
return 0;
}
-static int byt_remove(struct snd_sof_dev *sdev)
+static void byt_remove(struct snd_sof_dev *sdev)
{
byt_reset_dsp_disable_int(sdev);
-
- return 0;
}
static int byt_acpi_probe(struct snd_sof_dev *sdev)
@@ -374,16 +372,16 @@ static const struct sof_dev_desc sof_acpi_baytrailcr_desc = {
.resindex_imr_base = 2,
.irqindex_host_ipc = 0,
.chip_info = &byt_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
+ [SOF_IPC_TYPE_3] = "intel/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-byt.ri",
+ [SOF_IPC_TYPE_3] = "sof-byt.ri",
},
.nocodec_tplg_filename = "sof-byt-nocodec.tplg",
.ops = &sof_byt_ops,
@@ -396,16 +394,16 @@ static const struct sof_dev_desc sof_acpi_baytrail_desc = {
.resindex_imr_base = 2,
.irqindex_host_ipc = 5,
.chip_info = &byt_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
+ [SOF_IPC_TYPE_3] = "intel/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-byt.ri",
+ [SOF_IPC_TYPE_3] = "sof-byt.ri",
},
.nocodec_tplg_filename = "sof-byt-nocodec.tplg",
.ops = &sof_byt_ops,
@@ -418,16 +416,16 @@ static const struct sof_dev_desc sof_acpi_cherrytrail_desc = {
.resindex_imr_base = 2,
.irqindex_host_ipc = 5,
.chip_info = &cht_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
+ [SOF_IPC_TYPE_3] = "intel/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-cht.ri",
+ [SOF_IPC_TYPE_3] = "sof-cht.ri",
},
.nocodec_tplg_filename = "sof-cht-nocodec.tplg",
.ops = &sof_cht_ops,
@@ -467,7 +465,7 @@ static int sof_baytrail_probe(struct platform_device *pdev)
/* acpi_driver definition */
static struct platform_driver snd_sof_acpi_intel_byt_driver = {
.probe = sof_baytrail_probe,
- .remove = sof_acpi_remove,
+ .remove_new = sof_acpi_remove,
.driver = {
.name = "sof-audio-acpi-intel-byt",
.pm = &sof_acpi_pm,
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index c6fbf4285262..598cf50abadb 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -386,7 +386,7 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev)
sof_cnl_ops.shutdown = hda_dsp_shutdown;
/* ipc */
- if (sdev->pdata->ipc_type == SOF_IPC) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
/* doorbell */
sof_cnl_ops.irq_thread = cnl_ipc_irq_thread;
@@ -399,7 +399,7 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev)
sof_cnl_ops.set_power_state = hda_dsp_set_power_state_ipc3;
}
- if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c
index 8a5e99a898ec..28ecbebb4b84 100644
--- a/sound/soc/sof/intel/hda-codec.c
+++ b/sound/soc/sof/intel/hda-codec.c
@@ -169,6 +169,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
return ret;
hda_priv->codec = codec;
+ hda_priv->dev_index = address;
dev_set_drvdata(&codec->core.dev, hda_priv);
if ((resp & 0xFFFF0000) == IDISP_VID_INTEL) {
diff --git a/sound/soc/sof/intel/hda-common-ops.c b/sound/soc/sof/intel/hda-common-ops.c
index 8e1cd0babd32..26105d8f1bdc 100644
--- a/sound/soc/sof/intel/hda-common-ops.c
+++ b/sound/soc/sof/intel/hda-common-ops.c
@@ -16,8 +16,10 @@
struct snd_sof_dsp_ops sof_hda_common_ops = {
/* probe/remove/shutdown */
+ .probe_early = hda_dsp_probe_early,
.probe = hda_dsp_probe,
.remove = hda_dsp_remove,
+ .remove_late = hda_dsp_remove_late,
/* Register IO uses direct mmio */
diff --git a/sound/soc/sof/intel/hda-dai-ops.c b/sound/soc/sof/intel/hda-dai-ops.c
index 494ced2b746e..87935554b1e4 100644
--- a/sound/soc/sof/intel/hda-dai-ops.c
+++ b/sound/soc/sof/intel/hda-dai-ops.c
@@ -43,7 +43,7 @@ static bool hda_check_fes(struct snd_soc_pcm_runtime *rtd,
static struct hdac_ext_stream *
hda_link_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_intel_hda_stream *hda_stream;
const struct sof_intel_dsp_desc *chip;
struct snd_sof_dev *sdev;
@@ -145,12 +145,12 @@ static struct hdac_ext_stream *hda_assign_hext_stream(struct snd_sof_dev *sdev,
struct snd_soc_dai *cpu_dai,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *dai;
struct hdac_ext_stream *hext_stream;
/* only allocate a stream_tag for the first DAI in the dailink */
- dai = asoc_rtd_to_cpu(rtd, 0);
+ dai = snd_soc_rtd_to_cpu(rtd, 0);
if (dai == cpu_dai)
hext_stream = hda_link_stream_assign(sof_to_bus(sdev), substream);
else
@@ -168,11 +168,11 @@ static void hda_release_hext_stream(struct snd_sof_dev *sdev, struct snd_soc_dai
struct snd_pcm_substream *substream)
{
struct hdac_ext_stream *hext_stream = hda_get_hext_stream(sdev, cpu_dai, substream);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *dai;
/* only release a stream_tag for the first DAI in the dailink */
- dai = asoc_rtd_to_cpu(rtd, 0);
+ dai = snd_soc_rtd_to_cpu(rtd, 0);
if (dai == cpu_dai)
snd_hdac_ext_stream_release(hext_stream, HDAC_EXT_STREAM_TYPE_LINK);
snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
@@ -193,8 +193,8 @@ static void hda_codec_dai_set_stream(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
struct hdac_stream *hstream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
- struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
/* set the hdac_stream in the codec dai */
snd_soc_dai_set_stream(codec_dai, hstream, substream->stream);
@@ -204,8 +204,8 @@ static unsigned int hda_calc_stream_format(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
- struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
unsigned int link_bps;
unsigned int format_val;
@@ -226,8 +226,8 @@ static unsigned int hda_calc_stream_format(struct snd_sof_dev *sdev,
static struct hdac_ext_link *hda_get_hlink(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
- struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
struct hdac_bus *bus = sof_to_bus(sdev);
return snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name);
@@ -609,7 +609,7 @@ hda_select_dai_widget_ops(struct snd_sof_dev *sdev, struct snd_sof_widget *swidg
sdai = swidget->private;
switch (sdev->pdata->ipc_type) {
- case SOF_IPC:
+ case SOF_IPC_TYPE_3:
{
struct sof_dai_private_data *private = sdai->private;
@@ -617,7 +617,7 @@ hda_select_dai_widget_ops(struct snd_sof_dev *sdev, struct snd_sof_widget *swidg
return &hda_ipc3_dma_ops;
break;
}
- case SOF_INTEL_IPC4:
+ case SOF_IPC_TYPE_4:
{
struct sof_ipc4_copier *ipc4_copier = sdai->private;
const struct sof_intel_dsp_desc *chip;
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index f3cefd866081..a20deaf3b428 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -316,7 +316,7 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i
static int hda_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
int stream = substream->stream;
return hda_dai_hw_params(substream, &rtd->dpcm[stream].hw_params, dai);
@@ -408,7 +408,7 @@ static int non_hda_dai_hw_params(struct snd_pcm_substream *substream,
static int non_hda_dai_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
int stream = substream->stream;
return non_hda_dai_hw_params(substream, &rtd->dpcm[stream].hw_params, cpu_dai);
@@ -526,8 +526,8 @@ static int hda_dai_suspend(struct hdac_bus *bus)
struct snd_sof_dev *sdev;
struct snd_sof_dai *sdai;
- rtd = asoc_substream_to_rtd(hext_stream->link_substream);
- cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ rtd = snd_soc_substream_to_rtd(hext_stream->link_substream);
+ cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
w = snd_soc_dai_get_widget(cpu_dai, hdac_stream(hext_stream)->direction);
swidget = w->dobj.private;
sdev = widget_to_sdev(w);
@@ -607,7 +607,7 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops)
ssp_set_dai_drv_ops(sdev, ops);
dmic_set_dai_drv_ops(sdev, ops);
- if (sdev->pdata->ipc_type == SOF_INTEL_IPC4 && !hda_use_tplg_nhlt) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4 && !hda_use_tplg_nhlt) {
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
ipc4_data->nhlt = intel_nhlt_init(sdev->dev);
@@ -616,7 +616,7 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops)
void hda_ops_free(struct snd_sof_dev *sdev)
{
- if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
if (!hda_use_tplg_nhlt)
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 44f39a520bb3..2445ae7f6b2e 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -699,6 +699,9 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
if (ret < 0)
return ret;
+ /* make sure that no irq handler is pending before shutdown */
+ synchronize_irq(sdev->ipc_irq);
+
hda_codec_jack_wake_enable(sdev, runtime_suspend);
/* power down all hda links */
diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
index 50ce6b190002..46fb2d1425e9 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -545,11 +545,40 @@ int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev,
memcpy(dmab.area, stripped_firmware.data, stripped_firmware.size);
+ /*
+ * 1st stage: SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE
+ * Message includes the dma_id to be prepared for the library loading.
+ * If the firmware does not have support for the message, we will
+ * receive -EOPNOTSUPP. In this case we will use single step library
+ * loading and proceed to send the LOAD_LIBRARY message.
+ */
msg.primary = hext_stream->hstream.stream_tag - 1;
- msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_LOAD_LIBRARY);
+ msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE);
msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
- msg.primary |= SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(fw_lib->id);
+ ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
+ if (!ret) {
+ int sd_offset = SOF_STREAM_SD_OFFSET(&hext_stream->hstream);
+ unsigned int status;
+
+ /*
+ * Make sure that the FIFOS value is not 0 in SDxFIFOS register
+ * which indicates that the firmware set the GEN bit and we can
+ * continue to start the DMA
+ */
+ ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR,
+ sd_offset + SOF_HDA_ADSP_REG_SD_FIFOSIZE,
+ status,
+ status & SOF_HDA_SD_FIFOSIZE_FIFOS_MASK,
+ HDA_DSP_REG_POLL_INTERVAL_US,
+ HDA_DSP_BASEFW_TIMEOUT_US);
+
+ if (ret < 0)
+ dev_warn(sdev->dev,
+ "%s: timeout waiting for FIFOS\n", __func__);
+ } else if (ret != -EOPNOTSUPP) {
+ goto cleanup;
+ }
ret = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_START);
if (ret < 0) {
@@ -557,8 +586,17 @@ int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev,
goto cleanup;
}
+ /*
+ * 2nd stage: LOAD_LIBRARY
+ * Message includes the dma_id and the lib_id, the dma_id must be
+ * identical to the one sent via LOAD_LIBRARY_PREPARE
+ */
+ msg.primary &= ~SOF_IPC4_MSG_TYPE_MASK;
+ msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_LOAD_LIBRARY);
+ msg.primary |= SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(fw_lib->id);
ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
+ /* Stop the DMA channel */
ret1 = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_STOP);
if (ret1 < 0) {
dev_err(sdev->dev, "%s: DMA trigger stop failed\n", __func__);
@@ -605,7 +643,7 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev)
/* Check if IMR boot is usable */
if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT) &&
(sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT ||
- sdev->pdata->ipc_type == SOF_INTEL_IPC4))
+ sdev->pdata->ipc_type == SOF_IPC_TYPE_4))
hdev->imrboot_supported = true;
}
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index f23c72cdff48..18f07364d219 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -177,7 +177,7 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *scomp = sdev->component;
struct hdac_stream *hstream = substream->runtime->private_data;
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
@@ -208,7 +208,7 @@ found:
int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_component *scomp = sdev->component;
struct hdac_ext_stream *dsp_stream;
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 0b0087abcc50..f2ebadbbcc10 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -38,7 +38,7 @@ static char *hda_hstream_dbg_get_stream_info_str(struct hdac_stream *hstream)
struct snd_soc_pcm_runtime *rtd;
if (hstream->substream)
- rtd = asoc_substream_to_rtd(hstream->substream);
+ rtd = snd_soc_substream_to_rtd(hstream->substream);
else if (hstream->cstream)
rtd = hstream->cstream->private_data;
else
@@ -668,7 +668,7 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
sd_offset +
SOF_HDA_ADSP_REG_SD_FIFOSIZE);
- hstream->fifo_size &= 0xffff;
+ hstream->fifo_size &= SOF_HDA_SD_FIFOSIZE_FIFOS_MASK;
hstream->fifo_size += 1;
} else {
hstream->fifo_size = 0;
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 15e6779efaa3..744c0dd5766d 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -31,6 +31,7 @@
#include "../sof-pci-dev.h"
#include "../ops.h"
#include "hda.h"
+#include "telemetry.h"
#define CREATE_TRACE_POINTS
#include <trace/events/sof_intel.h>
@@ -718,7 +719,7 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
hda_dsp_get_state(sdev, level);
/* The firmware register dump only available with IPC3 */
- if (flags & SOF_DBG_DUMP_REGS && sdev->pdata->ipc_type == SOF_IPC) {
+ if (flags & SOF_DBG_DUMP_REGS && sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
u32 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_STATUS);
u32 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP);
@@ -731,6 +732,19 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
}
}
+void hda_ipc4_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
+{
+ char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
+
+ /* print ROM/FW status */
+ hda_dsp_get_state(sdev, level);
+
+ if (flags & SOF_DBG_DUMP_REGS)
+ sof_ipc4_intel_dump_telemetry_state(sdev, flags);
+ else
+ hda_dsp_dump_ext_rom_status(sdev, level, flags);
+}
+
static bool hda_check_ipc_irq(struct snd_sof_dev *sdev)
{
const struct sof_intel_dsp_desc *chip;
@@ -848,13 +862,21 @@ static int hda_init(struct snd_sof_dev *sdev)
/* init i915 and HDMI codecs */
ret = hda_codec_i915_init(sdev);
- if (ret < 0)
- dev_warn(sdev->dev, "init of i915 and HDMI codec failed\n");
+ if (ret < 0 && ret != -ENODEV) {
+ dev_err_probe(sdev->dev, ret, "init of i915 and HDMI codec failed\n");
+ goto out;
+ }
/* get controller capabilities */
ret = hda_dsp_ctrl_get_caps(sdev);
- if (ret < 0)
+ if (ret < 0) {
dev_err(sdev->dev, "error: get caps error\n");
+ hda_codec_i915_exit(sdev);
+ }
+
+out:
+ if (ret < 0)
+ iounmap(sof_to_bus(sdev)->remap_addr);
return ret;
}
@@ -1118,11 +1140,10 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context)
return IRQ_HANDLED;
}
-int hda_dsp_probe(struct snd_sof_dev *sdev)
+int hda_dsp_probe_early(struct snd_sof_dev *sdev)
{
struct pci_dev *pci = to_pci_dev(sdev->dev);
struct sof_intel_hda_dev *hdev;
- struct hdac_bus *bus;
const struct sof_intel_dsp_desc *chip;
int ret = 0;
@@ -1161,6 +1182,17 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
return -ENOMEM;
sdev->pdata->hw_pdata = hdev;
hdev->desc = chip;
+ ret = hda_init(sdev);
+
+err:
+ return ret;
+}
+
+int hda_dsp_probe(struct snd_sof_dev *sdev)
+{
+ struct pci_dev *pci = to_pci_dev(sdev->dev);
+ struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
+ int ret = 0;
hdev->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec",
PLATFORM_DEVID_NONE,
@@ -1183,12 +1215,6 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
if (sdev->dspless_mode_selected)
hdev->no_ipc_position = 1;
- /* set up HDA base */
- bus = sof_to_bus(sdev);
- ret = hda_init(sdev);
- if (ret < 0)
- goto hdac_bus_unmap;
-
if (sdev->dspless_mode_selected)
goto skip_dsp_setup;
@@ -1297,17 +1323,14 @@ free_streams:
iounmap(sdev->bar[HDA_DSP_BAR]);
hdac_bus_unmap:
platform_device_unregister(hdev->dmic_dev);
- iounmap(bus->remap_addr);
- hda_codec_i915_exit(sdev);
-err:
+
return ret;
}
-int hda_dsp_remove(struct snd_sof_dev *sdev)
+void hda_dsp_remove(struct snd_sof_dev *sdev)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
const struct sof_intel_dsp_desc *chip = hda->desc;
- struct hdac_bus *bus = sof_to_bus(sdev);
struct pci_dev *pci = to_pci_dev(sdev->dev);
struct nhlt_acpi_table *nhlt = hda->nhlt;
@@ -1357,14 +1380,13 @@ skip_disable_dsp:
if (!sdev->dspless_mode_selected)
iounmap(sdev->bar[HDA_DSP_BAR]);
+}
- iounmap(bus->remap_addr);
-
+void hda_dsp_remove_late(struct snd_sof_dev *sdev)
+{
+ iounmap(sof_to_bus(sdev)->remap_addr);
sof_hda_bus_exit(sdev);
-
hda_codec_i915_exit(sdev);
-
- return 0;
}
int hda_power_down_dsp(struct snd_sof_dev *sdev)
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 5c517ec57d4a..d628d6a3a7e5 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -135,6 +135,9 @@
#define SOF_HDA_ADSP_REG_SD_BDLPU 0x1C
#define SOF_HDA_ADSP_SD_ENTRY_SIZE 0x20
+/* SDxFIFOS FIFOS */
+#define SOF_HDA_SD_FIFOSIZE_FIFOS_MASK GENMASK(15, 0)
+
/* CL: Software Position Based FIFO Capability Registers */
#define SOF_DSP_REG_CL_SPBFIFO \
(SOF_HDA_ADSP_LOADER_BASE + 0x20)
@@ -573,8 +576,10 @@ struct sof_intel_hda_stream {
/*
* DSP Core services.
*/
+int hda_dsp_probe_early(struct snd_sof_dev *sdev);
int hda_dsp_probe(struct snd_sof_dev *sdev);
-int hda_dsp_remove(struct snd_sof_dev *sdev);
+void hda_dsp_remove(struct snd_sof_dev *sdev);
+void hda_dsp_remove_late(struct snd_sof_dev *sdev);
int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask);
@@ -600,6 +605,7 @@ int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev);
int hda_dsp_shutdown(struct snd_sof_dev *sdev);
int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev);
void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags);
+void hda_ipc4_dsp_dump(struct snd_sof_dev *sdev, u32 flags);
void hda_ipc_dump(struct snd_sof_dev *sdev);
void hda_ipc_irq_dump(struct snd_sof_dev *sdev);
void hda_dsp_d0i3_work(struct work_struct *work);
diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c
index 7ac10167a90d..8e29d6bb6fe8 100644
--- a/sound/soc/sof/intel/icl.c
+++ b/sound/soc/sof/intel/icl.c
@@ -107,7 +107,7 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev)
/* probe/remove/shutdown */
sof_icl_ops.shutdown = hda_dsp_shutdown;
- if (sdev->pdata->ipc_type == SOF_IPC) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
/* doorbell */
sof_icl_ops.irq_thread = cnl_ipc_irq_thread;
@@ -120,7 +120,7 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev)
sof_icl_ops.set_power_state = hda_dsp_set_power_state_ipc3;
}
- if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index f9412517eaf2..254dbbeac1d0 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -18,6 +18,7 @@
#include "hda-ipc.h"
#include "../sof-audio.h"
#include "mtl.h"
+#include "telemetry.h"
static const struct snd_sof_debugfs_map mtl_dsp_debugfs[] = {
{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
@@ -320,6 +321,8 @@ void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
romdbgsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY + 0x8 * 3);
dev_printk(level, sdev->dev, "ROM feature bit%s enabled\n",
romdbgsts & BIT(24) ? "" : " not");
+
+ sof_ipc4_intel_dump_telemetry_state(sdev, flags);
}
static bool mtl_dsp_primary_core_is_enabled(struct snd_sof_dev *sdev)
diff --git a/sound/soc/sof/intel/pci-apl.c b/sound/soc/sof/intel/pci-apl.c
index 460f87f25dac..4b287b5e9077 100644
--- a/sound/soc/sof/intel/pci-apl.c
+++ b/sound/soc/sof/intel/pci-apl.c
@@ -27,23 +27,23 @@ static const struct sof_dev_desc bxt_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &apl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/apl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/apl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/apl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/apl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-apl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-apl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-apl-nocodec.tplg",
.ops = &sof_apl_ops,
@@ -59,23 +59,23 @@ static const struct sof_dev_desc glk_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &apl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/glk",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/glk",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/glk",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/glk",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-glk.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-glk.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-glk-nocodec.tplg",
.ops = &sof_apl_ops,
diff --git a/sound/soc/sof/intel/pci-cnl.c b/sound/soc/sof/intel/pci-cnl.c
index e2c50e7b0aa7..9fa0cd2eae79 100644
--- a/sound/soc/sof/intel/pci-cnl.c
+++ b/sound/soc/sof/intel/pci-cnl.c
@@ -28,23 +28,23 @@ static const struct sof_dev_desc cnl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &cnl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/cnl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/cnl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/cnl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/cnl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-cnl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-cnl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
.ops = &sof_cnl_ops,
@@ -61,23 +61,23 @@ static const struct sof_dev_desc cfl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &cnl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/cnl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/cnl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/cnl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/cnl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-cfl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-cfl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
.ops = &sof_cnl_ops,
@@ -94,23 +94,23 @@ static const struct sof_dev_desc cml_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &cnl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/cnl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/cnl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/cnl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/cnl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-cml.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-cml.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-cnl-nocodec.tplg",
.ops = &sof_cnl_ops,
diff --git a/sound/soc/sof/intel/pci-icl.c b/sound/soc/sof/intel/pci-icl.c
index 0a65df3ed9e2..b99c7c9aad7d 100644
--- a/sound/soc/sof/intel/pci-icl.c
+++ b/sound/soc/sof/intel/pci-icl.c
@@ -28,23 +28,23 @@ static const struct sof_dev_desc icl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &icl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/icl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/icl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/icl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/icl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-icl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-icl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-icl-nocodec.tplg",
.ops = &sof_icl_ops,
@@ -60,23 +60,23 @@ static const struct sof_dev_desc jsl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &jsl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/jsl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/jsl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/jsl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/jsl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-jsl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-jsl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-jsl-nocodec.tplg",
.ops = &sof_cnl_ops,
diff --git a/sound/soc/sof/intel/pci-lnl.c b/sound/soc/sof/intel/pci-lnl.c
index 1b12c280edb4..78a57eb9cbc3 100644
--- a/sound/soc/sof/intel/pci-lnl.c
+++ b/sound/soc/sof/intel/pci-lnl.c
@@ -29,17 +29,17 @@ static const struct sof_dev_desc lnl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &lnl_chip_info,
- .ipc_supported_mask = BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_INTEL_IPC4,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_4,
.dspless_mode_supported = true,
.default_fw_path = {
- [SOF_INTEL_IPC4] = "intel/sof-ipc4/lnl",
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4/lnl",
},
.default_tplg_path = {
- [SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
+ [SOF_IPC_TYPE_4] = "intel/sof-ace-tplg",
},
.default_fw_filename = {
- [SOF_INTEL_IPC4] = "sof-lnl.ri",
+ [SOF_IPC_TYPE_4] = "sof-lnl.ri",
},
.nocodec_tplg_filename = "sof-lnl-nocodec.tplg",
.ops = &sof_lnl_ops,
diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c
index 7868b0827e84..0f378f45486d 100644
--- a/sound/soc/sof/intel/pci-mtl.c
+++ b/sound/soc/sof/intel/pci-mtl.c
@@ -29,20 +29,20 @@ static const struct sof_dev_desc mtl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &mtl_chip_info,
- .ipc_supported_mask = BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_INTEL_IPC4,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_4,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_INTEL_IPC4] = "intel/sof-ipc4/mtl",
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4/mtl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/sof-ipc4-lib/mtl",
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/mtl",
},
.default_tplg_path = {
- [SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
+ [SOF_IPC_TYPE_4] = "intel/sof-ace-tplg",
},
.default_fw_filename = {
- [SOF_INTEL_IPC4] = "sof-mtl.ri",
+ [SOF_IPC_TYPE_4] = "sof-mtl.ri",
},
.nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
.ops = &sof_mtl_ops,
@@ -50,9 +50,40 @@ static const struct sof_dev_desc mtl_desc = {
.ops_free = hda_ops_free,
};
+static const struct sof_dev_desc arl_desc = {
+ .use_acpi_target_states = true,
+ .machines = snd_soc_acpi_intel_arl_machines,
+ .alt_machines = snd_soc_acpi_intel_arl_sdw_machines,
+ .resindex_lpe_base = 0,
+ .resindex_pcicfg_base = -1,
+ .resindex_imr_base = -1,
+ .irqindex_host_ipc = -1,
+ .chip_info = &mtl_chip_info,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_4,
+ .dspless_mode_supported = true, /* Only supported for HDaudio */
+ .default_fw_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4/arl",
+ },
+ .default_lib_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/arl",
+ },
+ .default_tplg_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ace-tplg",
+ },
+ .default_fw_filename = {
+ [SOF_IPC_TYPE_4] = "sof-arl.ri",
+ },
+ .nocodec_tplg_filename = "sof-arl-nocodec.tplg",
+ .ops = &sof_mtl_ops,
+ .ops_init = sof_mtl_ops_init,
+ .ops_free = hda_ops_free,
+};
+
/* PCI IDs */
static const struct pci_device_id sof_pci_ids[] = {
{ PCI_DEVICE_DATA(INTEL, HDA_MTL, &mtl_desc) },
+ { PCI_DEVICE_DATA(INTEL, HDA_ARL_S, &arl_desc) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, sof_pci_ids);
diff --git a/sound/soc/sof/intel/pci-skl.c b/sound/soc/sof/intel/pci-skl.c
index a6588b138a8c..9dde439a0b0f 100644
--- a/sound/soc/sof/intel/pci-skl.c
+++ b/sound/soc/sof/intel/pci-skl.c
@@ -24,17 +24,17 @@ static struct sof_dev_desc skl_desc = {
.resindex_imr_base = -1,
.chip_info = &skl_chip_info,
.irqindex_host_ipc = -1,
- .ipc_supported_mask = BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_INTEL_IPC4,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_4,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_INTEL_IPC4] = "intel/avs/skl",
+ [SOF_IPC_TYPE_4] = "intel/avs/skl",
},
.default_tplg_path = {
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-skl-nocodec.tplg",
.ops = &sof_skl_ops,
@@ -49,17 +49,17 @@ static struct sof_dev_desc kbl_desc = {
.resindex_imr_base = -1,
.chip_info = &skl_chip_info,
.irqindex_host_ipc = -1,
- .ipc_supported_mask = BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_INTEL_IPC4,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_4,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_INTEL_IPC4] = "intel/avs/kbl",
+ [SOF_IPC_TYPE_4] = "intel/avs/kbl",
},
.default_tplg_path = {
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-kbl-nocodec.tplg",
.ops = &sof_skl_ops,
diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c
index d688f9373fb2..0660d4b2ac96 100644
--- a/sound/soc/sof/intel/pci-tgl.c
+++ b/sound/soc/sof/intel/pci-tgl.c
@@ -28,23 +28,23 @@ static const struct sof_dev_desc tgl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &tgl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/tgl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/tgl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/tgl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/tgl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-tgl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-tgl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
.ops = &sof_tgl_ops,
@@ -61,23 +61,23 @@ static const struct sof_dev_desc tglh_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &tglh_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/tgl-h",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/tgl-h",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/tgl-h",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/tgl-h",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-tgl-h.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-tgl-h.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-tgl-nocodec.tplg",
.ops = &sof_tgl_ops,
@@ -93,23 +93,23 @@ static const struct sof_dev_desc ehl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &ehl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/ehl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/ehl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/ehl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/ehl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-ehl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-ehl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-ehl-nocodec.tplg",
.ops = &sof_tgl_ops,
@@ -126,23 +126,23 @@ static const struct sof_dev_desc adls_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &adls_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/adl-s",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/adl-s",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/adl-s",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/adl-s",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-adl-s.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-adl-s.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
.ops = &sof_tgl_ops,
@@ -159,23 +159,23 @@ static const struct sof_dev_desc adl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &tgl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/adl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/adl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/adl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/adl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-adl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-adl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
.ops = &sof_tgl_ops,
@@ -192,23 +192,23 @@ static const struct sof_dev_desc adl_n_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &tgl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/adl-n",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/adl-n",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/adl-n",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/adl-n",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-adl-n.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-adl-n.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
.ops = &sof_tgl_ops,
@@ -225,23 +225,23 @@ static const struct sof_dev_desc rpls_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &adls_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/rpl-s",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/rpl-s",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/rpl-s",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/rpl-s",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-rpl-s.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-rpl-s.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
.ops = &sof_tgl_ops,
@@ -258,23 +258,23 @@ static const struct sof_dev_desc rpl_desc = {
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &tgl_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3) | BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_3,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
- [SOF_INTEL_IPC4] = "intel/avs/rpl",
+ [SOF_IPC_TYPE_3] = "intel/sof",
+ [SOF_IPC_TYPE_4] = "intel/avs/rpl",
},
.default_lib_path = {
- [SOF_INTEL_IPC4] = "intel/avs-lib/rpl",
+ [SOF_IPC_TYPE_4] = "intel/avs-lib/rpl",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
- [SOF_INTEL_IPC4] = "intel/avs-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_4] = "intel/avs-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-rpl.ri",
- [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+ [SOF_IPC_TYPE_3] = "sof-rpl.ri",
+ [SOF_IPC_TYPE_4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
.ops = &sof_tgl_ops,
diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c
index 4ae4fe17cc0b..c90173003c2b 100644
--- a/sound/soc/sof/intel/pci-tng.c
+++ b/sound/soc/sof/intel/pci-tng.c
@@ -208,16 +208,16 @@ static const struct sof_dev_desc tng_desc = {
.resindex_imr_base = 0,
.irqindex_host_ipc = -1,
.chip_info = &tng_chip_info,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "intel/sof",
+ [SOF_IPC_TYPE_3] = "intel/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "intel/sof-tplg",
+ [SOF_IPC_TYPE_3] = "intel/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-byt.ri",
+ [SOF_IPC_TYPE_3] = "sof-byt.ri",
},
.nocodec_tplg_filename = "sof-byt.tplg",
.ops = &sof_tng_ops,
diff --git a/sound/soc/sof/intel/telemetry.c b/sound/soc/sof/intel/telemetry.c
new file mode 100644
index 000000000000..1a3b5c28a6f0
--- /dev/null
+++ b/sound/soc/sof/intel/telemetry.c
@@ -0,0 +1,95 @@
+// 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) 2023 Intel Corporation. All rights reserved.
+
+/* telemetry data queried from debug window */
+
+#include <sound/sof/ipc4/header.h>
+#include <sound/sof/xtensa.h>
+#include "../ipc4-priv.h"
+#include "../sof-priv.h"
+#include "hda.h"
+#include "telemetry.h"
+
+void sof_ipc4_intel_dump_telemetry_state(struct snd_sof_dev *sdev, u32 flags)
+{
+ static const char invalid_slot_msg[] = "Core dump is not available due to";
+ struct sof_ipc4_telemetry_slot_data *telemetry_data;
+ struct sof_ipc_dsp_oops_xtensa *xoops;
+ struct xtensa_arch_block *block;
+ u32 slot_offset;
+ char *level;
+
+ level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
+
+ slot_offset = sof_ipc4_find_debug_slot_offset_by_type(sdev, SOF_IPC4_DEBUG_SLOT_TELEMETRY);
+ if (!slot_offset)
+ return;
+
+ telemetry_data = kmalloc(sizeof(*telemetry_data), GFP_KERNEL);
+ if (!telemetry_data)
+ return;
+ sof_mailbox_read(sdev, slot_offset, telemetry_data, sizeof(*telemetry_data));
+ if (telemetry_data->separator != XTENSA_CORE_DUMP_SEPARATOR) {
+ dev_err(sdev->dev, "%s invalid separator %#x\n", invalid_slot_msg,
+ telemetry_data->separator);
+ goto free_telemetry_data;
+ }
+
+ block = kmalloc(sizeof(*block), GFP_KERNEL);
+ if (!block)
+ goto free_telemetry_data;
+
+ sof_mailbox_read(sdev, slot_offset + sizeof(*telemetry_data), block, sizeof(*block));
+ if (block->soc != XTENSA_SOC_INTEL_ADSP) {
+ dev_err(sdev->dev, "%s invalid SOC %d\n", invalid_slot_msg, block->soc);
+ goto free_block;
+ }
+
+ if (telemetry_data->hdr.id[0] != COREDUMP_HDR_ID0 ||
+ telemetry_data->hdr.id[1] != COREDUMP_HDR_ID1 ||
+ telemetry_data->arch_hdr.id != COREDUMP_ARCH_HDR_ID) {
+ dev_err(sdev->dev, "%s invalid coredump header %c%c, arch hdr %c\n",
+ invalid_slot_msg, telemetry_data->hdr.id[0],
+ telemetry_data->hdr.id[1],
+ telemetry_data->arch_hdr.id);
+ goto free_block;
+ }
+
+ switch (block->toolchain) {
+ case XTENSA_TOOL_CHAIN_ZEPHYR:
+ dev_printk(level, sdev->dev, "FW is built with Zephyr toolchain\n");
+ break;
+ case XTENSA_TOOL_CHAIN_XCC:
+ dev_printk(level, sdev->dev, "FW is built with XCC toolchain\n");
+ break;
+ default:
+ dev_printk(level, sdev->dev, "Unknown toolchain is used\n");
+ break;
+ }
+
+ xoops = kzalloc(struct_size(xoops, ar, XTENSA_CORE_AR_REGS_COUNT), GFP_KERNEL);
+ if (!xoops)
+ goto free_block;
+
+ xoops->exccause = block->exccause;
+ xoops->excvaddr = block->excvaddr;
+ xoops->epc1 = block->pc;
+ xoops->ps = block->ps;
+ xoops->sar = block->sar;
+
+ xoops->plat_hdr.numaregs = XTENSA_CORE_AR_REGS_COUNT;
+ memcpy((void *)xoops->ar, block->ar, XTENSA_CORE_AR_REGS_COUNT * sizeof(u32));
+
+ sof_oops(sdev, level, xoops);
+ sof_stack(sdev, level, xoops, NULL, 0);
+
+ kfree(xoops);
+free_block:
+ kfree(block);
+free_telemetry_data:
+ kfree(telemetry_data);
+}
diff --git a/sound/soc/sof/intel/telemetry.h b/sound/soc/sof/intel/telemetry.h
new file mode 100644
index 000000000000..3c2b23c75f5d
--- /dev/null
+++ b/sound/soc/sof/intel/telemetry.h
@@ -0,0 +1,35 @@
+/* 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) 2023 Intel Corporation. All rights reserved.
+ *
+ * telemetry data in debug windows
+ */
+
+#ifndef _SOF_INTEL_TELEMETRY_H
+#define _SOF_INTEL_TELEMETRY_H
+
+#include "../ipc4-telemetry.h"
+
+struct xtensa_arch_block {
+ u8 soc; /* should be equal to XTENSA_SOC_INTEL_ADSP */
+ u16 version;
+ u8 toolchain; /* ZEPHYR or XCC */
+
+ u32 pc;
+ u32 exccause;
+ u32 excvaddr;
+ u32 sar;
+ u32 ps;
+ u32 scompare1;
+ u32 ar[XTENSA_CORE_AR_REGS_COUNT];
+ u32 lbeg;
+ u32 lend;
+ u32 lcount;
+} __packed;
+
+void sof_ipc4_intel_dump_telemetry_state(struct snd_sof_dev *sdev, u32 flags);
+
+#endif /* _SOF_INTEL_TELEMETRY_H */
diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
index bb9f20253c99..f7de1f5ba06d 100644
--- a/sound/soc/sof/intel/tgl.c
+++ b/sound/soc/sof/intel/tgl.c
@@ -66,7 +66,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
/* probe/remove/shutdown */
sof_tgl_ops.shutdown = hda_dsp_shutdown_dma_flush;
- if (sdev->pdata->ipc_type == SOF_IPC) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
/* doorbell */
sof_tgl_ops.irq_thread = cnl_ipc_irq_thread;
@@ -79,7 +79,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
sof_tgl_ops.set_power_state = hda_dsp_set_power_state_ipc3;
}
- if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
@@ -102,6 +102,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
/* debug */
sof_tgl_ops.ipc_dump = cnl_ipc4_dump;
+ sof_tgl_ops.dbg_dump = hda_ipc4_dsp_dump;
sof_tgl_ops.set_power_state = hda_dsp_set_power_state_ipc4;
}
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
index b53abc923026..febe372f9aa8 100644
--- a/sound/soc/sof/ipc.c
+++ b/sound/soc/sof/ipc.c
@@ -165,12 +165,12 @@ struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev)
switch (sdev->pdata->ipc_type) {
#if defined(CONFIG_SND_SOC_SOF_IPC3)
- case SOF_IPC:
+ case SOF_IPC_TYPE_3:
ops = &ipc3_ops;
break;
#endif
-#if defined(CONFIG_SND_SOC_SOF_INTEL_IPC4)
- case SOF_INTEL_IPC4:
+#if defined(CONFIG_SND_SOC_SOF_IPC4)
+ case SOF_IPC_TYPE_4:
ops = &ipc4_ops;
break;
#endif
diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c
index bd07f0472efd..0dca139322f3 100644
--- a/sound/soc/sof/ipc3-dtrace.c
+++ b/sound/soc/sof/ipc3-dtrace.c
@@ -494,7 +494,7 @@ static int ipc3_dtrace_init(struct snd_sof_dev *sdev)
int ret;
/* dtrace is only supported with SOF_IPC */
- if (sdev->pdata->ipc_type != SOF_IPC)
+ if (sdev->pdata->ipc_type != SOF_IPC_TYPE_3)
return -EOPNOTSUPP;
if (sdev->fw_trace_data) {
diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c
index cb58ee8c158a..2d0addcbc819 100644
--- a/sound/soc/sof/ipc3-pcm.c
+++ b/sound/soc/sof/ipc3-pcm.c
@@ -17,7 +17,7 @@ static int sof_ipc3_pcm_hw_free(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_ipc_stream stream;
struct snd_sof_pcm *spcm;
@@ -42,7 +42,7 @@ static int sof_ipc3_pcm_hw_params(struct snd_soc_component *component,
struct snd_sof_platform_stream_params *platform_params)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
struct snd_pcm_runtime *runtime = substream->runtime;
struct sof_ipc_pcm_params_reply ipc_params_reply;
@@ -142,7 +142,7 @@ static int sof_ipc3_pcm_hw_params(struct snd_soc_component *component,
static int sof_ipc3_pcm_trigger(struct snd_soc_component *component,
struct snd_pcm_substream *substream, int cmd)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct sof_ipc_stream stream;
struct snd_sof_pcm *spcm;
diff --git a/sound/soc/sof/ipc4-control.c b/sound/soc/sof/ipc4-control.c
index c6d404d44097..938efaceb81c 100644
--- a/sound/soc/sof/ipc4-control.c
+++ b/sound/soc/sof/ipc4-control.c
@@ -201,6 +201,159 @@ static int sof_ipc4_volume_get(struct snd_sof_control *scontrol,
return 0;
}
+static int
+sof_ipc4_set_generic_control_data(struct snd_sof_dev *sdev,
+ struct snd_sof_widget *swidget,
+ struct snd_sof_control *scontrol, bool lock)
+{
+ struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
+ struct sof_ipc4_control_msg_payload *data;
+ struct sof_ipc4_msg *msg = &cdata->msg;
+ size_t data_size;
+ unsigned int i;
+ int ret;
+
+ data_size = struct_size(data, chanv, scontrol->num_channels);
+ data = kzalloc(data_size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->id = cdata->index;
+ data->num_elems = scontrol->num_channels;
+ for (i = 0; i < scontrol->num_channels; i++) {
+ data->chanv[i].channel = cdata->chanv[i].channel;
+ data->chanv[i].value = cdata->chanv[i].value;
+ }
+
+ msg->data_ptr = data;
+ msg->data_size = data_size;
+
+ ret = sof_ipc4_set_get_kcontrol_data(scontrol, true, lock);
+ msg->data_ptr = NULL;
+ msg->data_size = 0;
+ if (ret < 0)
+ dev_err(sdev->dev, "Failed to set control update for %s\n",
+ scontrol->name);
+
+ kfree(data);
+
+ return ret;
+}
+
+static bool sof_ipc4_switch_put(struct snd_sof_control *scontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
+ struct snd_soc_component *scomp = scontrol->scomp;
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct snd_sof_widget *swidget;
+ bool widget_found = false;
+ bool change = false;
+ unsigned int i;
+ u32 value;
+ int ret;
+
+ /* update each channel */
+ for (i = 0; i < scontrol->num_channels; i++) {
+ value = ucontrol->value.integer.value[i];
+ change = change || (value != cdata->chanv[i].value);
+ cdata->chanv[i].channel = i;
+ cdata->chanv[i].value = value;
+ }
+
+ if (!pm_runtime_active(scomp->dev))
+ return change;
+
+ /* find widget associated with the control */
+ list_for_each_entry(swidget, &sdev->widget_list, list) {
+ if (swidget->comp_id == scontrol->comp_id) {
+ widget_found = true;
+ break;
+ }
+ }
+
+ if (!widget_found) {
+ dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name);
+ return false;
+ }
+
+ ret = sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, true);
+ if (ret < 0)
+ return false;
+
+ return change;
+}
+
+static int sof_ipc4_switch_get(struct snd_sof_control *scontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
+ unsigned int i;
+
+ /* read back each channel */
+ for (i = 0; i < scontrol->num_channels; i++)
+ ucontrol->value.integer.value[i] = cdata->chanv[i].value;
+
+ return 0;
+}
+
+static bool sof_ipc4_enum_put(struct snd_sof_control *scontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
+ struct snd_soc_component *scomp = scontrol->scomp;
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct snd_sof_widget *swidget;
+ bool widget_found = false;
+ bool change = false;
+ unsigned int i;
+ u32 value;
+ int ret;
+
+ /* update each channel */
+ for (i = 0; i < scontrol->num_channels; i++) {
+ value = ucontrol->value.enumerated.item[i];
+ change = change || (value != cdata->chanv[i].value);
+ cdata->chanv[i].channel = i;
+ cdata->chanv[i].value = value;
+ }
+
+ if (!pm_runtime_active(scomp->dev))
+ return change;
+
+ /* find widget associated with the control */
+ list_for_each_entry(swidget, &sdev->widget_list, list) {
+ if (swidget->comp_id == scontrol->comp_id) {
+ widget_found = true;
+ break;
+ }
+ }
+
+ if (!widget_found) {
+ dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name);
+ return false;
+ }
+
+ ret = sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, true);
+ if (ret < 0)
+ return false;
+
+ return change;
+}
+
+static int sof_ipc4_enum_get(struct snd_sof_control *scontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
+ unsigned int i;
+
+ /* read back each channel */
+ for (i = 0; i < scontrol->num_channels; i++)
+ ucontrol->value.enumerated.item[i] = cdata->chanv[i].value;
+
+ return 0;
+}
+
static int sof_ipc4_set_get_bytes_data(struct snd_sof_dev *sdev,
struct snd_sof_control *scontrol,
bool set, bool lock)
@@ -438,6 +591,16 @@ static int sof_ipc4_bytes_ext_volatile_get(struct snd_sof_control *scontrol,
return _sof_ipc4_bytes_ext_get(scontrol, binary_data, size, true);
}
+static int
+sof_ipc4_volsw_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
+ struct snd_sof_control *scontrol)
+{
+ if (scontrol->max == 1)
+ return sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, false);
+
+ return sof_ipc4_set_volume_data(sdev, swidget, scontrol, false);
+}
+
/* set up all controls for the widget */
static int sof_ipc4_widget_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
{
@@ -450,13 +613,17 @@ static int sof_ipc4_widget_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_s
case SND_SOC_TPLG_CTL_VOLSW:
case SND_SOC_TPLG_CTL_VOLSW_SX:
case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
- ret = sof_ipc4_set_volume_data(sdev, swidget,
- scontrol, false);
+ ret = sof_ipc4_volsw_setup(sdev, swidget, scontrol);
break;
case SND_SOC_TPLG_CTL_BYTES:
ret = sof_ipc4_set_get_bytes_data(sdev, scontrol,
true, false);
break;
+ case SND_SOC_TPLG_CTL_ENUM:
+ case SND_SOC_TPLG_CTL_ENUM_VALUE:
+ ret = sof_ipc4_set_generic_control_data(sdev, swidget,
+ scontrol, false);
+ break;
default:
break;
}
@@ -498,6 +665,10 @@ sof_ipc4_set_up_volume_table(struct snd_sof_control *scontrol, int tlv[SOF_TLV_I
const struct sof_ipc_tplg_control_ops tplg_ipc4_control_ops = {
.volume_put = sof_ipc4_volume_put,
.volume_get = sof_ipc4_volume_get,
+ .switch_put = sof_ipc4_switch_put,
+ .switch_get = sof_ipc4_switch_get,
+ .enum_put = sof_ipc4_enum_put,
+ .enum_get = sof_ipc4_enum_get,
.bytes_put = sof_ipc4_bytes_put,
.bytes_get = sof_ipc4_bytes_get,
.bytes_ext_put = sof_ipc4_bytes_ext_put,
diff --git a/sound/soc/sof/ipc4-mtrace.c b/sound/soc/sof/ipc4-mtrace.c
index 2b4659a1768e..9f1e33ee8826 100644
--- a/sound/soc/sof/ipc4-mtrace.c
+++ b/sound/soc/sof/ipc4-mtrace.c
@@ -41,24 +41,12 @@
* The two pointers are offsets within the buffer.
*/
-#define SOF_MTRACE_DESCRIPTOR_SIZE 12 /* 3 x u32 */
-
#define FW_EPOCH_DELTA 11644473600LL
-#define INVALID_SLOT_OFFSET 0xffffffff
#define MAX_ALLOWED_LIBRARIES 16
-#define MAX_MTRACE_SLOTS 15
-
-#define SOF_MTRACE_PAGE_SIZE 0x1000
-#define SOF_MTRACE_SLOT_SIZE SOF_MTRACE_PAGE_SIZE
-
-/* debug log slot types */
-#define SOF_MTRACE_SLOT_UNUSED 0x00000000
-#define SOF_MTRACE_SLOT_CRITICAL_LOG 0x54524300 /* byte 0: core ID */
-#define SOF_MTRACE_SLOT_DEBUG_LOG 0x474f4c00 /* byte 0: core ID */
-#define SOF_MTRACE_SLOT_GDB_STUB 0x42444700
-#define SOF_MTRACE_SLOT_TELEMETRY 0x4c455400
-#define SOF_MTRACE_SLOT_BROKEN 0x44414544
+
+#define SOF_IPC4_INVALID_SLOT_OFFSET 0xffffffff
+
/* for debug and critical types */
#define SOF_MTRACE_SLOT_CORE_MASK GENMASK(7, 0)
#define SOF_MTRACE_SLOT_TYPE_MASK GENMASK(31, 8)
@@ -140,7 +128,7 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file)
if (unlikely(ret))
goto out;
- core_data->log_buffer = kmalloc(SOF_MTRACE_SLOT_SIZE, GFP_KERNEL);
+ core_data->log_buffer = kmalloc(SOF_IPC4_DEBUG_SLOT_SIZE, GFP_KERNEL);
if (!core_data->log_buffer) {
debugfs_file_put(file->f_path.dentry);
ret = -ENOMEM;
@@ -212,13 +200,13 @@ static ssize_t sof_ipc4_mtrace_dfs_read(struct file *file, char __user *buffer,
return 0;
}
- if (core_data->slot_offset == INVALID_SLOT_OFFSET)
+ if (core_data->slot_offset == SOF_IPC4_INVALID_SLOT_OFFSET)
return 0;
/* The log data buffer starts after the two pointer in the slot */
log_buffer_offset = core_data->slot_offset + (sizeof(u32) * 2);
/* The log data size excludes the pointers */
- log_buffer_size = SOF_MTRACE_SLOT_SIZE - (sizeof(u32) * 2);
+ log_buffer_size = SOF_IPC4_DEBUG_SLOT_SIZE - (sizeof(u32) * 2);
read_ptr = core_data->host_read_ptr;
write_ptr = core_data->dsp_write_ptr;
@@ -510,13 +498,13 @@ static void sof_mtrace_find_core_slots(struct snd_sof_dev *sdev)
u32 slot_desc_type_offset, type, core;
int i;
- for (i = 0; i < MAX_MTRACE_SLOTS; i++) {
+ for (i = 0; i < SOF_IPC4_MAX_DEBUG_SLOTS; i++) {
/* The type is the second u32 in the slot descriptor */
slot_desc_type_offset = sdev->debug_box.offset;
- slot_desc_type_offset += SOF_MTRACE_DESCRIPTOR_SIZE * i + sizeof(u32);
+ slot_desc_type_offset += SOF_IPC4_DEBUG_DESCRIPTOR_SIZE * i + sizeof(u32);
sof_mailbox_read(sdev, slot_desc_type_offset, &type, sizeof(type));
- if ((type & SOF_MTRACE_SLOT_TYPE_MASK) == SOF_MTRACE_SLOT_DEBUG_LOG) {
+ if ((type & SOF_MTRACE_SLOT_TYPE_MASK) == SOF_IPC4_DEBUG_SLOT_DEBUG_LOG) {
core = type & SOF_MTRACE_SLOT_CORE_MASK;
if (core >= sdev->num_cores) {
@@ -533,7 +521,7 @@ static void sof_mtrace_find_core_slots(struct snd_sof_dev *sdev)
* debug_box + SOF_MTRACE_SLOT_SIZE offset
*/
core_data->slot_offset = sdev->debug_box.offset;
- core_data->slot_offset += SOF_MTRACE_SLOT_SIZE * (i + 1);
+ core_data->slot_offset += SOF_IPC4_DEBUG_SLOT_SIZE * (i + 1);
dev_dbg(sdev->dev, "slot%d is used for core%u\n", i, core);
if (core_data->delayed_pos_update) {
sof_ipc4_mtrace_update_pos(sdev, core);
@@ -633,7 +621,7 @@ int sof_ipc4_mtrace_update_pos(struct snd_sof_dev *sdev, int core)
core_data = &priv->cores[core];
- if (core_data->slot_offset == INVALID_SLOT_OFFSET) {
+ if (core_data->slot_offset == SOF_IPC4_INVALID_SLOT_OFFSET) {
core_data->delayed_pos_update = true;
return 0;
}
diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c
index db19cd03ecad..39039a647cca 100644
--- a/sound/soc/sof/ipc4-pcm.c
+++ b/sound/soc/sof/ipc4-pcm.c
@@ -62,10 +62,37 @@ int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 instance_id, u32 s
}
EXPORT_SYMBOL(sof_ipc4_set_pipeline_state);
+static void sof_ipc4_add_pipeline_by_priority(struct ipc4_pipeline_set_state_data *trigger_list,
+ struct snd_sof_widget *pipe_widget,
+ s8 *pipe_priority, bool ascend)
+{
+ struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
+ int i, j;
+
+ for (i = 0; i < trigger_list->count; i++) {
+ /* add pipeline from low priority to high */
+ if (ascend && pipeline->priority < pipe_priority[i])
+ break;
+ /* add pipeline from high priority to low */
+ else if (!ascend && pipeline->priority > pipe_priority[i])
+ break;
+ }
+
+ for (j = trigger_list->count - 1; j >= i; j--) {
+ trigger_list->pipeline_instance_ids[j + 1] = trigger_list->pipeline_instance_ids[j];
+ pipe_priority[j + 1] = pipe_priority[j];
+ }
+
+ trigger_list->pipeline_instance_ids[i] = pipe_widget->instance_id;
+ trigger_list->count++;
+ pipe_priority[i] = pipeline->priority;
+}
+
static void
sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state,
struct snd_sof_pipeline *spipe,
- struct ipc4_pipeline_set_state_data *trigger_list)
+ struct ipc4_pipeline_set_state_data *trigger_list,
+ s8 *pipe_priority)
{
struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
@@ -80,20 +107,20 @@ sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state,
* for the first time
*/
if (spipe->started_count == spipe->paused_count)
- trigger_list->pipeline_instance_ids[trigger_list->count++] =
- pipe_widget->instance_id;
+ sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority,
+ false);
break;
case SOF_IPC4_PIPE_RESET:
/* RESET if the pipeline is neither running nor paused */
if (!spipe->started_count && !spipe->paused_count)
- trigger_list->pipeline_instance_ids[trigger_list->count++] =
- pipe_widget->instance_id;
+ sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority,
+ true);
break;
case SOF_IPC4_PIPE_PAUSED:
/* Pause the pipeline only when its started_count is 1 more than paused_count */
if (spipe->paused_count == (spipe->started_count - 1))
- trigger_list->pipeline_instance_ids[trigger_list->count++] =
- pipe_widget->instance_id;
+ sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority,
+ true);
break;
default:
break;
@@ -280,7 +307,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
struct snd_pcm_substream *substream, int state, int cmd)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct ipc4_pipeline_set_state_data *trigger_list;
@@ -288,6 +315,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
struct sof_ipc4_pipeline *pipeline;
struct snd_sof_pipeline *spipe;
struct snd_sof_pcm *spcm;
+ u8 *pipe_priority;
int ret;
int i;
@@ -320,6 +348,12 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
if (!trigger_list)
return -ENOMEM;
+ pipe_priority = kzalloc(pipeline_list->count, GFP_KERNEL);
+ if (!pipe_priority) {
+ kfree(trigger_list);
+ return -ENOMEM;
+ }
+
mutex_lock(&ipc4_data->pipeline_state_mutex);
/*
@@ -334,12 +368,14 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
if (state == SOF_IPC4_PIPE_RUNNING || state == SOF_IPC4_PIPE_RESET)
for (i = pipeline_list->count - 1; i >= 0; i--) {
spipe = pipeline_list->pipelines[i];
- sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list);
+ sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list,
+ pipe_priority);
}
else
for (i = 0; i < pipeline_list->count; i++) {
spipe = pipeline_list->pipelines[i];
- sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list);
+ sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list,
+ pipe_priority);
}
/* return if all pipelines are in the requested state already */
@@ -389,6 +425,7 @@ skip_pause_transition:
free:
mutex_unlock(&ipc4_data->pipeline_state_mutex);
kfree(trigger_list);
+ kfree(pipe_priority);
return ret;
}
@@ -517,11 +554,14 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
struct snd_sof_dai *dai = snd_sof_find_dai(component, rtd->dai_link->name);
+ struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct sof_ipc4_audio_format *ipc4_fmt;
struct sof_ipc4_copier *ipc4_copier;
- bool use_chain_dma = false;
- int dir;
+ bool single_fmt = false;
+ u32 valid_bits = 0;
+ int dir, ret;
if (!dai) {
dev_err(component->dev, "%s: No DAI found with name %s\n", __func__,
@@ -540,21 +580,57 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, dir);
if (w) {
+ struct sof_ipc4_available_audio_format *available_fmt =
+ &ipc4_copier->available_fmt;
struct snd_sof_widget *swidget = w->dobj.private;
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
+ /* Chain DMA does not use copiers, so no fixup needed */
if (pipeline->use_chain_dma)
- use_chain_dma = true;
+ return 0;
+
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (sof_ipc4_copier_is_single_format(sdev,
+ available_fmt->output_pin_fmts,
+ available_fmt->num_output_formats)) {
+ ipc4_fmt = &available_fmt->output_pin_fmts->audio_fmt;
+ single_fmt = true;
+ }
+ } else {
+ if (sof_ipc4_copier_is_single_format(sdev,
+ available_fmt->input_pin_fmts,
+ available_fmt->num_input_formats)) {
+ ipc4_fmt = &available_fmt->input_pin_fmts->audio_fmt;
+ single_fmt = true;
+ }
+ }
}
}
- /* Chain DMA does not use copiers, so no fixup needed */
- if (!use_chain_dma) {
- int ret = sof_ipc4_pcm_dai_link_fixup_rate(sdev, params, ipc4_copier);
+ ret = sof_ipc4_pcm_dai_link_fixup_rate(sdev, params, ipc4_copier);
+ if (ret)
+ return ret;
+
+ if (single_fmt) {
+ snd_mask_none(fmt);
+ valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(ipc4_fmt->fmt_cfg);
+ dev_dbg(component->dev, "Set %s to %d bit format\n", dai->name, valid_bits);
+ }
- if (ret)
- return ret;
+ /* Set format if it is specified */
+ switch (valid_bits) {
+ case 16:
+ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
+ break;
+ case 24:
+ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
+ break;
+ case 32:
+ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE);
+ break;
+ default:
+ break;
}
switch (ipc4_copier->dai_type) {
@@ -704,7 +780,7 @@ static int sof_ipc4_pcm_hw_params(struct snd_soc_component *component,
struct snd_sof_platform_stream_params *platform_params)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_ipc4_timestamp_info *time_info;
struct snd_sof_pcm *spcm;
@@ -765,7 +841,7 @@ static snd_pcm_sframes_t sof_ipc4_pcm_delay(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_ipc4_timestamp_info *time_info;
struct sof_ipc4_llp_reading_slot llp;
snd_pcm_uframes_t head_ptr, tail_ptr;
diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h
index a5d0b2eae464..9e69b7c29117 100644
--- a/sound/soc/sof/ipc4-priv.h
+++ b/sound/soc/sof/ipc4-priv.h
@@ -120,4 +120,7 @@ void sof_ipc4_update_cpc_from_manifest(struct snd_sof_dev *sdev,
struct sof_ipc4_fw_module *fw_module,
struct sof_ipc4_base_module_cfg *basecfg);
+size_t sof_ipc4_find_debug_slot_offset_by_type(struct snd_sof_dev *sdev,
+ u32 slot_type);
+
#endif
diff --git a/sound/soc/sof/ipc4-telemetry.c b/sound/soc/sof/ipc4-telemetry.c
new file mode 100644
index 000000000000..ec4ae9674364
--- /dev/null
+++ b/sound/soc/sof/ipc4-telemetry.c
@@ -0,0 +1,95 @@
+// 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-2023 Intel Corporation. All rights reserved.
+//
+
+#include <linux/debugfs.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <sound/sof/debug.h>
+#include <sound/sof/ipc4/header.h>
+#include "sof-priv.h"
+#include "ops.h"
+#include "ipc4-telemetry.h"
+#include "ipc4-priv.h"
+
+static void __iomem *sof_ipc4_query_exception_address(struct snd_sof_dev *sdev)
+{
+ u32 type = SOF_IPC4_DEBUG_SLOT_TELEMETRY;
+ size_t telemetry_slot_offset;
+ u32 offset;
+
+ telemetry_slot_offset = sof_ipc4_find_debug_slot_offset_by_type(sdev, type);
+ if (!telemetry_slot_offset)
+ return NULL;
+
+ /* skip the first separator magic number */
+ offset = telemetry_slot_offset + sizeof(u32);
+
+ return sdev->bar[sdev->mailbox_bar] + offset;
+}
+
+static ssize_t sof_telemetry_entry_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct snd_sof_dfsentry *dfse = file->private_data;
+ struct snd_sof_dev *sdev = dfse->sdev;
+ void __iomem *io_addr;
+ loff_t pos = *ppos;
+ size_t size_ret;
+ u8 *buf;
+
+ if (pos < 0)
+ return -EINVAL;
+ /* skip the first separator magic number */
+ if (pos >= SOF_IPC4_DEBUG_SLOT_SIZE - 4 || !count)
+ return 0;
+ if (count > SOF_IPC4_DEBUG_SLOT_SIZE - 4 - pos)
+ count = SOF_IPC4_DEBUG_SLOT_SIZE - 4 - pos;
+
+ io_addr = sof_ipc4_query_exception_address(sdev);
+ if (!io_addr)
+ return -EFAULT;
+
+ buf = kzalloc(SOF_IPC4_DEBUG_SLOT_SIZE - 4, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ memcpy_fromio(buf, io_addr, SOF_IPC4_DEBUG_SLOT_SIZE - 4);
+ size_ret = copy_to_user(buffer, buf + pos, count);
+ if (size_ret) {
+ kfree(buf);
+ return -EFAULT;
+ }
+
+ *ppos = pos + count;
+ kfree(buf);
+
+ return count;
+}
+
+static const struct file_operations sof_telemetry_fops = {
+ .open = simple_open,
+ .read = sof_telemetry_entry_read,
+};
+
+void sof_ipc4_create_exception_debugfs_node(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_dfsentry *dfse;
+
+ dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL);
+ if (!dfse)
+ return;
+
+ dfse->type = SOF_DFSENTRY_TYPE_IOMEM;
+ dfse->size = SOF_IPC4_DEBUG_SLOT_SIZE - 4;
+ dfse->access_type = SOF_DEBUGFS_ACCESS_ALWAYS;
+ dfse->sdev = sdev;
+
+ list_add(&dfse->list, &sdev->dfsentry_list);
+
+ debugfs_create_file("exception", 0444, sdev->debugfs_root, dfse, &sof_telemetry_fops);
+}
diff --git a/sound/soc/sof/ipc4-telemetry.h b/sound/soc/sof/ipc4-telemetry.h
new file mode 100644
index 000000000000..ab3599e3d87d
--- /dev/null
+++ b/sound/soc/sof/ipc4-telemetry.h
@@ -0,0 +1,73 @@
+/* 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) 2023 Intel Corporation. All rights reserved.
+ */
+
+#ifndef __SOUND_SOC_SOF_IPC4_TELEMETRY_H
+#define __SOUND_SOC_SOF_IPC4_TELEMETRY_H
+
+/* Target code */
+enum sof_ipc4_coredump_tgt_code {
+ COREDUMP_TGT_UNKNOWN = 0,
+ COREDUMP_TGT_X86,
+ COREDUMP_TGT_X86_64,
+ COREDUMP_TGT_ARM_CORTEX_M,
+ COREDUMP_TGT_RISC_V,
+ COREDUMP_TGT_XTENSA,
+};
+
+#define COREDUMP_ARCH_HDR_ID 'A'
+#define COREDUMP_HDR_ID0 'Z'
+#define COREDUMP_HDR_ID1 'E'
+
+#define XTENSA_BLOCK_HDR_VER 2
+#define XTENSA_CORE_DUMP_SEPARATOR 0x0DEC0DEB
+#define XTENSA_CORE_AR_REGS_COUNT 16
+#define XTENSA_SOC_INTEL_ADSP 3
+#define XTENSA_TOOL_CHAIN_ZEPHYR 1
+#define XTENSA_TOOL_CHAIN_XCC 2
+
+/* Coredump header */
+struct sof_ipc4_coredump_hdr {
+ /* 'Z', 'E' as identifier of file */
+ char id[2];
+
+ /* Identify the version of the header */
+ u16 hdr_version;
+
+ /* Indicate which target (e.g. architecture or SoC) */
+ u16 tgt_code;
+
+ /* Size of uintptr_t in power of 2. (e.g. 5 for 32-bit, 6 for 64-bit) */
+ u8 ptr_size_bits;
+
+ u8 flag;
+
+ /* Reason for the fatal error */
+ u32 reason;
+} __packed;
+
+/* Architecture-specific block header */
+struct sof_ipc4_coredump_arch_hdr {
+ /* COREDUMP_ARCH_HDR_ID to indicate this is a architecture-specific block */
+ char id;
+
+ /* Identify the version of this block */
+ u16 hdr_version;
+
+ /* Number of bytes following the header */
+ u16 num_bytes;
+} __packed;
+
+struct sof_ipc4_telemetry_slot_data {
+ u32 separator;
+ struct sof_ipc4_coredump_hdr hdr;
+ struct sof_ipc4_coredump_arch_hdr arch_hdr;
+ u32 arch_data[];
+} __packed;
+
+void sof_ipc4_create_exception_debugfs_node(struct snd_sof_dev *sdev);
+#endif
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 7cb63e6b24dc..b24a64377f68 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -44,6 +44,8 @@ static const struct sof_topology_token ipc4_sched_tokens[] = {
offsetof(struct sof_ipc4_pipeline, use_chain_dma)},
{SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc4_pipeline, core_id)},
+ {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+ offsetof(struct sof_ipc4_pipeline, priority)},
};
static const struct sof_topology_token pipeline_tokens[] = {
@@ -683,9 +685,6 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
goto err;
}
- /* TODO: Get priority from topology */
- pipeline->priority = 0;
-
dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n",
swidget->widget->name, swidget->pipeline_id,
pipeline->priority, pipeline->core_id, pipeline->lp_mode);
@@ -895,7 +894,8 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) {
struct sof_ipc4_base_module_cfg_ext *base_cfg_ext;
u32 ext_size = struct_size(base_cfg_ext, pin_formats,
- swidget->num_input_pins + swidget->num_output_pins);
+ size_add(swidget->num_input_pins,
+ swidget->num_output_pins));
base_cfg_ext = kzalloc(ext_size, GFP_KERNEL);
if (!base_cfg_ext) {
@@ -1369,9 +1369,9 @@ static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_s
}
#endif
-static bool sof_ipc4_copier_is_single_format(struct snd_sof_dev *sdev,
- struct sof_ipc4_pin_format *pin_fmts,
- u32 pin_fmts_size)
+bool sof_ipc4_copier_is_single_format(struct snd_sof_dev *sdev,
+ struct sof_ipc4_pin_format *pin_fmts,
+ u32 pin_fmts_size)
{
struct sof_ipc4_audio_format *fmt;
u32 valid_bits;
@@ -1380,7 +1380,7 @@ static bool sof_ipc4_copier_is_single_format(struct snd_sof_dev *sdev,
fmt = &pin_fmts[0].audio_fmt;
valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
- /* check if all output formats in topology are the same */
+ /* check if all formats in topology are the same */
for (i = 1; i < pin_fmts_size; i++) {
u32 _valid_bits;
@@ -1726,9 +1726,14 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs;
break;
case snd_soc_dapm_aif_in:
- copier_data->gtw_cfg.dma_buffer_size =
- max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) *
- copier_data->base_config.ibs;
+ copier_data->gtw_cfg.dma_buffer_size =
+ max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) *
+ copier_data->base_config.ibs;
+ dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)",
+ swidget->widget->name,
+ deep_buffer_dma_ms ? " (using Deep Buffer)" : "",
+ max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms),
+ copier_data->gtw_cfg.dma_buffer_size);
break;
case snd_soc_dapm_dai_out:
case snd_soc_dapm_aif_out:
@@ -2102,17 +2107,57 @@ static int sof_ipc4_control_load_volume(struct snd_sof_dev *sdev, struct snd_sof
msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
- msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID);
+ /* volume controls with range 0-1 (off/on) are switch controls */
+ if (scontrol->max == 1)
+ msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID);
+ else
+ msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID);
- /* set default volume values to 0dB in control */
for (i = 0; i < scontrol->num_channels; i++) {
control_data->chanv[i].channel = i;
- control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB;
+ /*
+ * Default, initial values:
+ * - 0dB for volume controls
+ * - off (0) for switch controls - value already zero after
+ * memory allocation
+ */
+ if (scontrol->max > 1)
+ control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB;
}
return 0;
}
+static int sof_ipc4_control_load_enum(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
+{
+ struct sof_ipc4_control_data *control_data;
+ struct sof_ipc4_msg *msg;
+ int i;
+
+ scontrol->size = struct_size(control_data, chanv, scontrol->num_channels);
+
+ /* scontrol->ipc_control_data will be freed in sof_control_unload */
+ scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL);
+ if (!scontrol->ipc_control_data)
+ return -ENOMEM;
+
+ control_data = scontrol->ipc_control_data;
+ control_data->index = scontrol->index;
+
+ msg = &control_data->msg;
+ msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET);
+ msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
+ msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
+
+ msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID);
+
+ /* Default, initial value for enums: first enum entry is selected (0) */
+ for (i = 0; i < scontrol->num_channels; i++)
+ control_data->chanv[i].channel = i;
+
+ return 0;
+}
+
static int sof_ipc4_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
{
struct sof_ipc4_control_data *control_data;
@@ -2187,6 +2232,9 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr
return sof_ipc4_control_load_volume(sdev, scontrol);
case SND_SOC_TPLG_CTL_BYTES:
return sof_ipc4_control_load_bytes(sdev, scontrol);
+ case SND_SOC_TPLG_CTL_ENUM:
+ case SND_SOC_TPLG_CTL_ENUM_VALUE:
+ return sof_ipc4_control_load_enum(sdev, scontrol);
default:
break;
}
diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h
index d75f17f4749c..0a57b8ab3e08 100644
--- a/sound/soc/sof/ipc4-topology.h
+++ b/sound/soc/sof/ipc4-topology.h
@@ -319,7 +319,7 @@ struct sof_ipc4_copier {
/**
* struct sof_ipc4_ctrl_value_chan: generic channel mapped value data
* @channel: Channel ID
- * @value: gain value
+ * @value: Value associated with @channel
*/
struct sof_ipc4_ctrl_value_chan {
u32 channel;
@@ -343,6 +343,23 @@ struct sof_ipc4_control_data {
};
};
+#define SOF_IPC4_SWITCH_CONTROL_PARAM_ID 200
+#define SOF_IPC4_ENUM_CONTROL_PARAM_ID 201
+
+/**
+ * struct sof_ipc4_control_msg_payload - IPC payload for kcontrol parameters
+ * @id: unique id of the control
+ * @num_elems: Number of elements in the chanv array
+ * @reserved: reserved for future use, must be set to 0
+ * @chanv: channel ID and value array
+ */
+struct sof_ipc4_control_msg_payload {
+ uint16_t id;
+ uint16_t num_elems;
+ uint32_t reserved[4];
+ DECLARE_FLEX_ARRAY(struct sof_ipc4_ctrl_value_chan, chanv);
+} __packed;
+
/**
* struct sof_ipc4_gain_data - IPC gain blob
* @channels: Channels
@@ -442,4 +459,7 @@ struct sof_ipc4_process {
u32 init_config;
};
+bool sof_ipc4_copier_is_single_format(struct snd_sof_dev *sdev,
+ struct sof_ipc4_pin_format *pin_fmts,
+ u32 pin_fmts_size);
#endif
diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c
index ab6eddd91bb7..8441f4ae4065 100644
--- a/sound/soc/sof/ipc4.c
+++ b/sound/soc/sof/ipc4.c
@@ -15,6 +15,7 @@
#include "sof-audio.h"
#include "ipc4-fw-reg.h"
#include "ipc4-priv.h"
+#include "ipc4-telemetry.h"
#include "ops.h"
static const struct sof_ipc4_fw_status {
@@ -99,6 +100,10 @@ static int sof_ipc4_check_reply_status(struct snd_sof_dev *sdev, u32 status)
to_errno:
switch (status) {
+ case 2:
+ case 15:
+ ret = -EOPNOTSUPP;
+ break;
case 8:
case 11:
case 105 ... 109:
@@ -153,6 +158,7 @@ static const char * const ipc4_dbg_glb_msg_type[] = {
DBG_IPC4_MSG_TYPE_ENTRY(GLB_SAVE_PIPELINE),
DBG_IPC4_MSG_TYPE_ENTRY(GLB_RESTORE_PIPELINE),
DBG_IPC4_MSG_TYPE_ENTRY(GLB_LOAD_LIBRARY),
+ DBG_IPC4_MSG_TYPE_ENTRY(GLB_LOAD_LIBRARY_PREPARE),
DBG_IPC4_MSG_TYPE_ENTRY(GLB_INTERNAL_MESSAGE),
DBG_IPC4_MSG_TYPE_ENTRY(GLB_NOTIFICATION),
};
@@ -513,10 +519,10 @@ static int sof_ipc4_set_get_data(struct snd_sof_dev *sdev, void *data,
if (!set && payload_bytes != offset)
ipc4_msg->data_size = offset;
+out:
if (sof_debug_check_flag(SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD))
sof_ipc4_dump_payload(sdev, ipc4_msg->data_ptr, ipc4_msg->data_size);
-out:
mutex_unlock(&sdev->ipc->tx_mutex);
return ret;
@@ -542,6 +548,29 @@ static int sof_ipc4_init_msg_memory(struct snd_sof_dev *sdev)
return 0;
}
+size_t sof_ipc4_find_debug_slot_offset_by_type(struct snd_sof_dev *sdev,
+ u32 slot_type)
+{
+ size_t slot_desc_type_offset;
+ u32 type;
+ int i;
+
+ /* The type is the second u32 in the slot descriptor */
+ slot_desc_type_offset = sdev->debug_box.offset + sizeof(u32);
+ for (i = 0; i < SOF_IPC4_MAX_DEBUG_SLOTS; i++) {
+ sof_mailbox_read(sdev, slot_desc_type_offset, &type, sizeof(type));
+
+ if (type == slot_type)
+ return sdev->debug_box.offset + (i + 1) * SOF_IPC4_DEBUG_SLOT_SIZE;
+
+ slot_desc_type_offset += SOF_IPC4_DEBUG_DESCRIPTOR_SIZE;
+ }
+
+ dev_dbg(sdev->dev, "Slot type %#x is not available in debug window\n", slot_type);
+ return 0;
+}
+EXPORT_SYMBOL(sof_ipc4_find_debug_slot_offset_by_type);
+
static int ipc4_fw_ready(struct snd_sof_dev *sdev, struct sof_ipc4_msg *ipc4_msg)
{
int inbox_offset, inbox_size, outbox_offset, outbox_size;
@@ -570,6 +599,8 @@ static int ipc4_fw_ready(struct snd_sof_dev *sdev, struct sof_ipc4_msg *ipc4_msg
sdev->debug_box.offset = snd_sof_dsp_get_window_offset(sdev,
SOF_IPC4_DEBUG_WINDOW_IDX);
+ sof_ipc4_create_exception_debugfs_node(sdev);
+
dev_dbg(sdev->dev, "mailbox upstream 0x%x - size 0x%x\n",
inbox_offset, inbox_size);
dev_dbg(sdev->dev, "mailbox downstream 0x%x - size 0x%x\n",
@@ -614,6 +645,9 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev)
case SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS:
sof_ipc4_mtrace_update_pos(sdev, SOF_IPC4_LOG_CORE_GET(ipc4_msg->primary));
break;
+ case SOF_IPC4_NOTIFY_EXCEPTION_CAUGHT:
+ snd_sof_dsp_panic(sdev, 0, true);
+ break;
default:
dev_dbg(sdev->dev, "Unhandled DSP message: %#x|%#x\n",
ipc4_msg->primary, ipc4_msg->extension);
@@ -632,6 +666,10 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev)
sof_ipc4_log_header(sdev->dev, "ipc rx done ", ipc4_msg, true);
if (data_size) {
+ if (sof_debug_check_flag(SOF_DBG_DUMP_IPC_MESSAGE_PAYLOAD))
+ sof_ipc4_dump_payload(sdev, ipc4_msg->data_ptr,
+ ipc4_msg->data_size);
+
kfree(ipc4_msg->data_ptr);
ipc4_msg->data_ptr = NULL;
ipc4_msg->data_size = 0;
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c
index f587edf9e0a7..b69fa788b16f 100644
--- a/sound/soc/sof/mediatek/mt8186/mt8186.c
+++ b/sound/soc/sof/mediatek/mt8186/mt8186.c
@@ -391,7 +391,7 @@ err_adsp_off:
return ret;
}
-static int mt8186_dsp_remove(struct snd_sof_dev *sdev)
+static void mt8186_dsp_remove(struct snd_sof_dev *sdev)
{
struct adsp_priv *priv = sdev->pdata->hw_pdata;
@@ -399,8 +399,6 @@ static int mt8186_dsp_remove(struct snd_sof_dev *sdev)
mt8186_sof_hifixdsp_shutdown(sdev);
adsp_sram_power_off(sdev);
mt8186_adsp_clock_off(sdev);
-
- return 0;
}
static int mt8186_dsp_shutdown(struct snd_sof_dev *sdev)
@@ -457,7 +455,7 @@ static snd_pcm_uframes_t mt8186_pcm_pointer(struct snd_sof_dev *sdev,
struct sof_ipc_stream_posn posn;
struct snd_sof_pcm_stream *stream;
struct snd_soc_component *scomp = sdev->component;
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
spcm = snd_sof_find_spcm_dai(scomp, rtd);
if (!spcm) {
@@ -607,16 +605,16 @@ static struct snd_sof_of_mach sof_mt8186_machs[] = {
static const struct sof_dev_desc sof_of_mt8186_desc = {
.of_machines = sof_mt8186_machs,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "mediatek/sof",
+ [SOF_IPC_TYPE_3] = "mediatek/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "mediatek/sof-tplg",
+ [SOF_IPC_TYPE_3] = "mediatek/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-mt8186.ri",
+ [SOF_IPC_TYPE_3] = "sof-mt8186.ri",
},
.nocodec_tplg_filename = "sof-mt8186-nocodec.tplg",
.ops = &sof_mt8186_ops,
@@ -681,16 +679,16 @@ static struct snd_sof_of_mach sof_mt8188_machs[] = {
static const struct sof_dev_desc sof_of_mt8188_desc = {
.of_machines = sof_mt8188_machs,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "mediatek/sof",
+ [SOF_IPC_TYPE_3] = "mediatek/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "mediatek/sof-tplg",
+ [SOF_IPC_TYPE_3] = "mediatek/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-mt8188.ri",
+ [SOF_IPC_TYPE_3] = "sof-mt8188.ri",
},
.nocodec_tplg_filename = "sof-mt8188-nocodec.tplg",
.ops = &sof_mt8188_ops,
@@ -707,7 +705,7 @@ MODULE_DEVICE_TABLE(of, sof_of_mt8186_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_mt8186_driver = {
.probe = sof_of_probe,
- .remove = sof_of_remove,
+ .remove_new = sof_of_remove,
.shutdown = sof_of_shutdown,
.driver = {
.name = "sof-audio-of-mt8186",
diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c
index 7d6a568556ea..cac0a085f60a 100644
--- a/sound/soc/sof/mediatek/mt8195/mt8195.c
+++ b/sound/soc/sof/mediatek/mt8195/mt8195.c
@@ -388,7 +388,7 @@ static int mt8195_dsp_shutdown(struct snd_sof_dev *sdev)
return snd_sof_suspend(sdev->dev);
}
-static int mt8195_dsp_remove(struct snd_sof_dev *sdev)
+static void mt8195_dsp_remove(struct snd_sof_dev *sdev)
{
struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev);
struct adsp_priv *priv = sdev->pdata->hw_pdata;
@@ -396,8 +396,6 @@ static int mt8195_dsp_remove(struct snd_sof_dev *sdev)
platform_device_unregister(priv->ipc_dev);
adsp_sram_power_on(&pdev->dev, false);
adsp_clock_off(sdev);
-
- return 0;
}
static int mt8195_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
@@ -476,7 +474,7 @@ static snd_pcm_uframes_t mt8195_pcm_pointer(struct snd_sof_dev *sdev,
struct sof_ipc_stream_posn posn;
struct snd_sof_pcm_stream *stream;
struct snd_soc_component *scomp = sdev->component;
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
spcm = snd_sof_find_spcm_dai(scomp, rtd);
if (!spcm) {
@@ -635,16 +633,16 @@ static struct snd_sof_of_mach sof_mt8195_machs[] = {
static const struct sof_dev_desc sof_of_mt8195_desc = {
.of_machines = sof_mt8195_machs,
- .ipc_supported_mask = BIT(SOF_IPC),
- .ipc_default = SOF_IPC,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_3),
+ .ipc_default = SOF_IPC_TYPE_3,
.default_fw_path = {
- [SOF_IPC] = "mediatek/sof",
+ [SOF_IPC_TYPE_3] = "mediatek/sof",
},
.default_tplg_path = {
- [SOF_IPC] = "mediatek/sof-tplg",
+ [SOF_IPC_TYPE_3] = "mediatek/sof-tplg",
},
.default_fw_filename = {
- [SOF_IPC] = "sof-mt8195.ri",
+ [SOF_IPC_TYPE_3] = "sof-mt8195.ri",
},
.nocodec_tplg_filename = "sof-mt8195-nocodec.tplg",
.ops = &sof_mt8195_ops,
@@ -660,7 +658,7 @@ MODULE_DEVICE_TABLE(of, sof_of_mt8195_ids);
/* DT driver definition */
static struct platform_driver snd_sof_of_mt8195_driver = {
.probe = sof_of_probe,
- .remove = sof_of_remove,
+ .remove_new = sof_of_remove,
.shutdown = sof_of_shutdown,
.driver = {
.name = "sof-audio-of-mt8195",
diff --git a/sound/soc/sof/nocodec.c b/sound/soc/sof/nocodec.c
index 7c5bb9badb6c..34aa8a7cfc7d 100644
--- a/sound/soc/sof/nocodec.c
+++ b/sound/soc/sof/nocodec.c
@@ -44,7 +44,7 @@ static int sof_nocodec_bes_setup(struct device *dev,
links[i].stream_name = links[i].name;
links[i].cpus = &dlc[0];
- links[i].codecs = &asoc_dummy_dlc;
+ links[i].codecs = &snd_soc_dummy_dlc;
links[i].platforms = &dlc[1];
links[i].num_cpus = 1;
diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h
index 9ab7b9be765b..6538d9f4fe96 100644
--- a/sound/soc/sof/ops.h
+++ b/sound/soc/sof/ops.h
@@ -38,17 +38,29 @@ static inline void sof_ops_free(struct snd_sof_dev *sdev)
/* Mandatory operations are verified during probing */
/* init */
+static inline int snd_sof_probe_early(struct snd_sof_dev *sdev)
+{
+ if (sof_ops(sdev)->probe_early)
+ return sof_ops(sdev)->probe_early(sdev);
+
+ return 0;
+}
+
static inline int snd_sof_probe(struct snd_sof_dev *sdev)
{
return sof_ops(sdev)->probe(sdev);
}
-static inline int snd_sof_remove(struct snd_sof_dev *sdev)
+static inline void snd_sof_remove(struct snd_sof_dev *sdev)
{
if (sof_ops(sdev)->remove)
- return sof_ops(sdev)->remove(sdev);
+ sof_ops(sdev)->remove(sdev);
+}
- return 0;
+static inline void snd_sof_remove_late(struct snd_sof_dev *sdev)
+{
+ if (sof_ops(sdev)->remove_late)
+ sof_ops(sdev)->remove_late(sdev);
}
static inline int snd_sof_shutdown(struct snd_sof_dev *sdev)
@@ -202,7 +214,7 @@ static inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev)
return sof_ops(sdev)->get_mailbox_offset(sdev);
dev_err(sdev->dev, "error: %s not defined\n", __func__);
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
@@ -212,7 +224,7 @@ static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
return sof_ops(sdev)->get_window_offset(sdev, id);
dev_err(sdev->dev, "error: %s not defined\n", __func__);
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
/* power management */
static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index d778717cab10..33d576b17647 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -25,7 +25,7 @@ static int create_page_table(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
unsigned char *dma_area, size_t size)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_pcm *spcm;
struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream);
int stream = substream->stream;
@@ -60,7 +60,7 @@ void snd_sof_pcm_init_elapsed_work(struct work_struct *work)
*/
void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
struct snd_sof_pcm *spcm;
@@ -124,7 +124,7 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
struct snd_pcm_hw_params *params)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
struct snd_sof_platform_stream_params platform_params = { 0 };
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -194,7 +194,7 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
static int sof_pcm_hw_free(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
struct snd_sof_pcm *spcm;
@@ -246,7 +246,7 @@ static int sof_pcm_hw_free(struct snd_soc_component *component,
static int sof_pcm_prepare(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_pcm *spcm;
int ret;
@@ -283,7 +283,7 @@ static int sof_pcm_prepare(struct snd_soc_component *component,
static int sof_pcm_trigger(struct snd_soc_component *component,
struct snd_pcm_substream *substream, int cmd)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
struct snd_sof_pcm *spcm;
@@ -386,7 +386,7 @@ static int sof_pcm_trigger(struct snd_soc_component *component,
static snd_pcm_uframes_t sof_pcm_pointer(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct snd_sof_pcm *spcm;
snd_pcm_uframes_t host, dai;
@@ -417,7 +417,7 @@ static snd_pcm_uframes_t sof_pcm_pointer(struct snd_soc_component *component,
static int sof_pcm_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct snd_sof_dsp_ops *ops = sof_ops(sdev);
@@ -482,7 +482,7 @@ static int sof_pcm_open(struct snd_soc_component *component,
static int sof_pcm_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct snd_sof_pcm *spcm;
int err;
diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c
index 1b04dcb33293..84a4a0a3318e 100644
--- a/sound/soc/sof/sof-acpi-dev.c
+++ b/sound/soc/sof/sof-acpi-dev.c
@@ -74,20 +74,18 @@ int sof_acpi_probe(struct platform_device *pdev, const struct sof_dev_desc *desc
sof_pdata->desc = desc;
sof_pdata->dev = &pdev->dev;
- sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC];
+ sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC_TYPE_3];
/* alternate fw and tplg filenames ? */
if (fw_path)
sof_pdata->fw_filename_prefix = fw_path;
else
- sof_pdata->fw_filename_prefix =
- sof_pdata->desc->default_fw_path[SOF_IPC];
+ sof_pdata->fw_filename_prefix = desc->default_fw_path[SOF_IPC_TYPE_3];
if (tplg_path)
sof_pdata->tplg_filename_prefix = tplg_path;
else
- sof_pdata->tplg_filename_prefix =
- sof_pdata->desc->default_tplg_path[SOF_IPC];
+ sof_pdata->tplg_filename_prefix = desc->default_tplg_path[SOF_IPC_TYPE_3];
/* set callback to be called on successful device probe to enable runtime_pm */
sof_pdata->sof_probe_complete = sof_acpi_probe_complete;
@@ -97,7 +95,7 @@ int sof_acpi_probe(struct platform_device *pdev, const struct sof_dev_desc *desc
}
EXPORT_SYMBOL_NS(sof_acpi_probe, SND_SOC_SOF_ACPI_DEV);
-int sof_acpi_remove(struct platform_device *pdev)
+void sof_acpi_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -106,8 +104,6 @@ int sof_acpi_remove(struct platform_device *pdev)
/* call sof helper for DSP hardware remove */
snd_sof_device_remove(dev);
-
- return 0;
}
EXPORT_SYMBOL_NS(sof_acpi_remove, SND_SOC_SOF_ACPI_DEV);
diff --git a/sound/soc/sof/sof-acpi-dev.h b/sound/soc/sof/sof-acpi-dev.h
index 5c2b558d2ace..9bf8f75ceaae 100644
--- a/sound/soc/sof/sof-acpi-dev.h
+++ b/sound/soc/sof/sof-acpi-dev.h
@@ -11,6 +11,6 @@
extern const struct dev_pm_ops sof_acpi_pm;
int sof_acpi_probe(struct platform_device *pdev, const struct sof_dev_desc *desc);
-int sof_acpi_remove(struct platform_device *pdev);
+void sof_acpi_remove(struct platform_device *pdev);
#endif
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index e5405f854a91..563fe6f7789f 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -1032,6 +1032,13 @@ int sof_machine_check(struct snd_sof_dev *sdev)
mach = snd_sof_machine_select(sdev);
if (mach) {
sof_pdata->machine = mach;
+
+ if (sof_pdata->subsystem_id_set) {
+ mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor;
+ mach->mach_params.subsystem_device = sof_pdata->subsystem_device;
+ mach->mach_params.subsystem_id_set = true;
+ }
+
snd_sof_set_mach_params(mach, sdev);
return 0;
}
diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c
index 752d5320680f..e249d3a9afb5 100644
--- a/sound/soc/sof/sof-client-ipc-msg-injector.c
+++ b/sound/soc/sof/sof-client-ipc-msg-injector.c
@@ -267,7 +267,7 @@ static int sof_msg_inject_probe(struct auxiliary_device *auxdev,
priv->max_msg_size = sof_client_get_ipc_max_payload_size(cdev);
alloc_size = priv->max_msg_size;
- if (priv->ipc_type == SOF_INTEL_IPC4)
+ if (priv->ipc_type == SOF_IPC_TYPE_4)
alloc_size += sizeof(struct sof_ipc4_msg);
priv->tx_buffer = devm_kmalloc(dev, alloc_size, GFP_KERNEL);
@@ -275,7 +275,7 @@ static int sof_msg_inject_probe(struct auxiliary_device *auxdev,
if (!priv->tx_buffer || !priv->rx_buffer)
return -ENOMEM;
- if (priv->ipc_type == SOF_INTEL_IPC4) {
+ if (priv->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_msg *ipc4_msg;
ipc4_msg = priv->tx_buffer;
diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c
index 740b637822db..7cc9e8f18de7 100644
--- a/sound/soc/sof/sof-client-probes.c
+++ b/sound/soc/sof/sof-client-probes.c
@@ -423,13 +423,13 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev,
priv->host_ops = ops;
switch (sof_client_get_ipc_type(cdev)) {
-#ifdef CONFIG_SND_SOC_SOF_INTEL_IPC4
- case SOF_INTEL_IPC4:
+#ifdef CONFIG_SND_SOC_SOF_IPC4
+ case SOF_IPC_TYPE_4:
priv->ipc_ops = &ipc4_probe_ops;
break;
#endif
#ifdef CONFIG_SND_SOC_SOF_IPC3
- case SOF_IPC:
+ case SOF_IPC_TYPE_3:
priv->ipc_ops = &ipc3_probe_ops;
break;
#endif
diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c
index 284de96e779c..9dce7f53b482 100644
--- a/sound/soc/sof/sof-client.c
+++ b/sound/soc/sof/sof-client.c
@@ -75,7 +75,7 @@ static int sof_register_ipc_flood_test(struct snd_sof_dev *sdev)
int ret = 0;
int i;
- if (sdev->pdata->ipc_type != SOF_IPC)
+ if (sdev->pdata->ipc_type != SOF_IPC_TYPE_3)
return 0;
for (i = 0; i < CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM; i++) {
@@ -131,7 +131,7 @@ static inline void sof_unregister_ipc_msg_injector(struct snd_sof_dev *sdev) {}
static int sof_register_ipc_kernel_injector(struct snd_sof_dev *sdev)
{
/* Only IPC3 supported right now */
- if (sdev->pdata->ipc_type != SOF_IPC)
+ if (sdev->pdata->ipc_type != SOF_IPC_TYPE_3)
return 0;
return sof_client_dev_register(sdev, "kernel_injector", 0, NULL, 0);
@@ -287,12 +287,12 @@ EXPORT_SYMBOL_NS_GPL(sof_client_dev_unregister, SND_SOC_SOF_CLIENT);
int sof_client_ipc_tx_message(struct sof_client_dev *cdev, void *ipc_msg,
void *reply_data, size_t reply_bytes)
{
- if (cdev->sdev->pdata->ipc_type == SOF_IPC) {
+ if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = ipc_msg;
return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, hdr->size,
reply_data, reply_bytes);
- } else if (cdev->sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ } else if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_msg *msg = ipc_msg;
return sof_ipc_tx_message(cdev->sdev->ipc, ipc_msg, msg->data_size,
@@ -305,7 +305,8 @@ EXPORT_SYMBOL_NS_GPL(sof_client_ipc_tx_message, SND_SOC_SOF_CLIENT);
int sof_client_ipc_rx_message(struct sof_client_dev *cdev, void *ipc_msg, void *msg_buf)
{
- if (cdev->sdev->pdata->ipc_type == SOF_IPC) {
+ if (IS_ENABLED(CONFIG_SND_SOC_SOF_IPC3) &&
+ cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = ipc_msg;
if (hdr->size < sizeof(hdr)) {
@@ -324,12 +325,12 @@ EXPORT_SYMBOL_NS_GPL(sof_client_ipc_rx_message, SND_SOC_SOF_CLIENT);
int sof_client_ipc_set_get_data(struct sof_client_dev *cdev, void *ipc_msg,
bool set)
{
- if (cdev->sdev->pdata->ipc_type == SOF_IPC) {
+ if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = ipc_msg;
return sof_ipc_set_get_data(cdev->sdev->ipc, ipc_msg, hdr->size,
set);
- } else if (cdev->sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ } else if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_msg *msg = ipc_msg;
return sof_ipc_set_get_data(cdev->sdev->ipc, ipc_msg,
@@ -340,12 +341,12 @@ int sof_client_ipc_set_get_data(struct sof_client_dev *cdev, void *ipc_msg,
}
EXPORT_SYMBOL_NS_GPL(sof_client_ipc_set_get_data, SND_SOC_SOF_CLIENT);
-#ifdef CONFIG_SND_SOC_SOF_INTEL_IPC4
+#ifdef CONFIG_SND_SOC_SOF_IPC4
struct sof_ipc4_fw_module *sof_client_ipc4_find_module(struct sof_client_dev *c, const guid_t *uuid)
{
struct snd_sof_dev *sdev = c->sdev;
- if (sdev->pdata->ipc_type == SOF_INTEL_IPC4)
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4)
return sof_ipc4_find_module_by_uuid(sdev, uuid);
dev_err(sdev->dev, "Only supported with IPC4\n");
@@ -463,11 +464,11 @@ void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf)
struct sof_ipc_event_entry *event;
u32 msg_type;
- if (sdev->pdata->ipc_type == SOF_IPC) {
+ if (sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = msg_buf;
msg_type = hdr->cmd & SOF_GLB_TYPE_MASK;
- } else if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ } else if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_msg *msg = msg_buf;
msg_type = SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary);
@@ -497,10 +498,10 @@ int sof_client_register_ipc_rx_handler(struct sof_client_dev *cdev,
if (!callback)
return -EINVAL;
- if (cdev->sdev->pdata->ipc_type == SOF_IPC) {
+ if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
if (!(ipc_msg_type & SOF_GLB_TYPE_MASK))
return -EINVAL;
- } else if (cdev->sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
+ } else if (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
if (!(ipc_msg_type & SOF_IPC4_NOTIFICATION_TYPE_MASK))
return -EINVAL;
} else {
diff --git a/sound/soc/sof/sof-of-dev.c b/sound/soc/sof/sof-of-dev.c
index 53faeccedd4f..c6be8a91e74b 100644
--- a/sound/soc/sof/sof-of-dev.c
+++ b/sound/soc/sof/sof-of-dev.c
@@ -64,17 +64,17 @@ int sof_of_probe(struct platform_device *pdev)
sof_pdata->desc = desc;
sof_pdata->dev = &pdev->dev;
- sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC];
+ sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC_TYPE_3];
if (fw_path)
sof_pdata->fw_filename_prefix = fw_path;
else
- sof_pdata->fw_filename_prefix = sof_pdata->desc->default_fw_path[SOF_IPC];
+ sof_pdata->fw_filename_prefix = desc->default_fw_path[SOF_IPC_TYPE_3];
if (tplg_path)
sof_pdata->tplg_filename_prefix = tplg_path;
else
- sof_pdata->tplg_filename_prefix = sof_pdata->desc->default_tplg_path[SOF_IPC];
+ sof_pdata->tplg_filename_prefix = desc->default_tplg_path[SOF_IPC_TYPE_3];
/* set callback to be called on successful device probe to enable runtime_pm */
sof_pdata->sof_probe_complete = sof_of_probe_complete;
@@ -84,14 +84,12 @@ int sof_of_probe(struct platform_device *pdev)
}
EXPORT_SYMBOL(sof_of_probe);
-int sof_of_remove(struct platform_device *pdev)
+void sof_of_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
/* call sof helper for DSP hardware remove */
snd_sof_device_remove(&pdev->dev);
-
- return 0;
}
EXPORT_SYMBOL(sof_of_remove);
diff --git a/sound/soc/sof/sof-of-dev.h b/sound/soc/sof/sof-of-dev.h
index 2948b3a0d9fe..b6cc70595f3b 100644
--- a/sound/soc/sof/sof-of-dev.h
+++ b/sound/soc/sof/sof-of-dev.h
@@ -19,7 +19,7 @@ struct snd_sof_of_mach {
extern const struct dev_pm_ops sof_of_pm;
int sof_of_probe(struct platform_device *pdev);
-int sof_of_remove(struct platform_device *pdev);
+void sof_of_remove(struct platform_device *pdev);
void sof_of_shutdown(struct platform_device *pdev);
#endif
diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
index f5ece43d0ec2..1d706490588e 100644
--- a/sound/soc/sof/sof-pci-dev.c
+++ b/sound/soc/sof/sof-pci-dev.c
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(sof_pci_debug, "SOF PCI debug options (0x0 all off)");
static int sof_pci_ipc_type = -1;
module_param_named(ipc_type, sof_pci_ipc_type, int, 0444);
-MODULE_PARM_DESC(ipc_type, "SOF IPC type (0): SOF, (1) Intel CAVS");
+MODULE_PARM_DESC(ipc_type, "Force SOF IPC type. 0 - IPC3, 1 - IPC4");
static const char *sof_dmi_override_tplg_name;
static bool sof_dmi_use_community_key;
@@ -214,6 +214,14 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
return ret;
sof_pdata->name = pci_name(pci);
+
+ /* PCI defines a vendor ID of 0xFFFF as invalid. */
+ if (pci->subsystem_vendor != 0xFFFF) {
+ sof_pdata->subsystem_vendor = pci->subsystem_vendor;
+ sof_pdata->subsystem_device = pci->subsystem_device;
+ sof_pdata->subsystem_id_set = true;
+ }
+
sof_pdata->desc = desc;
sof_pdata->dev = dev;
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index d4f6702e93dc..f4185012eb69 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -165,8 +165,10 @@ struct sof_firmware {
struct snd_sof_dsp_ops {
/* probe/remove/shutdown */
+ int (*probe_early)(struct snd_sof_dev *sof_dev); /* optional */
int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */
- int (*remove)(struct snd_sof_dev *sof_dev); /* optional */
+ void (*remove)(struct snd_sof_dev *sof_dev); /* optional */
+ void (*remove_late)(struct snd_sof_dev *sof_dev); /* optional */
int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */
/* DSP core boot / reset */
diff --git a/sound/soc/sof/xtensa/core.c b/sound/soc/sof/xtensa/core.c
index bebbe3a2865c..7c91a919eadc 100644
--- a/sound/soc/sof/xtensa/core.c
+++ b/sound/soc/sof/xtensa/core.c
@@ -132,6 +132,17 @@ static void xtensa_stack(struct snd_sof_dev *sdev, const char *level, void *oops
buf, sizeof(buf), false);
dev_printk(level, sdev->dev, "0x%08x: %s\n", stack_ptr + i * 4, buf);
}
+
+ if (!xoops->plat_hdr.numaregs)
+ return;
+
+ dev_printk(level, sdev->dev, "AR registers:\n");
+ /* the number of ar registers is a multiple of 4 */
+ for (i = 0; i < xoops->plat_hdr.numaregs; i += 4) {
+ hex_dump_to_buffer(xoops->ar + i, 16, 16, 4,
+ buf, sizeof(buf), false);
+ dev_printk(level, sdev->dev, "%#x: %s\n", i * 4, buf);
+ }
}
const struct dsp_arch_ops sof_xtensa_arch_ops = {