aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/sof.h4
-rw-r--r--include/sound/sof/ipc4/header.h17
-rw-r--r--sound/soc/codecs/hdac_hda.c28
-rw-r--r--sound/soc/codecs/hdac_hda.h4
-rw-r--r--sound/soc/intel/boards/Kconfig4
-rw-r--r--sound/soc/intel/boards/Makefile3
-rw-r--r--sound/soc/intel/boards/sof_sdw.c27
-rw-r--r--sound/soc/intel/boards/sof_sdw_common.h13
-rw-r--r--sound/soc/intel/boards/sof_sdw_cs42l43.c145
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-mtl-match.c78
-rw-r--r--sound/soc/intel/skylake/skl.c1
-rw-r--r--sound/soc/sof/Kconfig2
-rw-r--r--sound/soc/sof/Makefile6
-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/imx/imx8.c20
-rw-r--r--sound/soc/sof/imx/imx8m.c10
-rw-r--r--sound/soc/sof/imx/imx8ulp.c10
-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.c10
-rw-r--r--sound/soc/sof/intel/byt.c30
-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-dai-ops.c4
-rw-r--r--sound/soc/sof/intel/hda-dai.c4
-rw-r--r--sound/soc/sof/intel/hda-loader.c2
-rw-r--r--sound/soc/sof/intel/hda.c16
-rw-r--r--sound/soc/sof/intel/hda.h1
-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.c12
-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/ipc4-control.c175
-rw-r--r--sound/soc/sof/ipc4-mtrace.c34
-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.c49
-rw-r--r--sound/soc/sof/ipc4-topology.h19
-rw-r--r--sound/soc/sof/ipc4.c29
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186.c20
-rw-r--r--sound/soc/sof/mediatek/mt8195/mt8195.c10
-rw-r--r--sound/soc/sof/sof-acpi-dev.c8
-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.c26
-rw-r--r--sound/soc/sof/sof-of-dev.c6
-rw-r--r--sound/soc/sof/sof-pci-dev.c2
-rw-r--r--sound/soc/sof/xtensa/core.c11
63 files changed, 1217 insertions, 320 deletions
diff --git a/include/sound/sof.h b/include/sound/sof.h
index 51294f2ba302..268d0ca0f69f 100644
--- a/include/sound/sof.h
+++ b/include/sound/sof.h
@@ -52,8 +52,8 @@ enum sof_dsp_power_states {
/* Definitions for multiple IPCs */
enum sof_ipc_type {
- SOF_IPC,
- SOF_INTEL_IPC4,
+ SOF_IPC_TYPE_3,
+ SOF_IPC_TYPE_4,
SOF_IPC_TYPE_COUNT
};
diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h
index c58f00ef054a..574a9d581f88 100644
--- a/include/sound/sof/ipc4/header.h
+++ b/include/sound/sof/ipc4/header.h
@@ -515,6 +515,23 @@ struct sof_ipc4_notify_resource_data {
uint32_t data[6];
} __packed __aligned(4);
+#define SOF_IPC4_DEBUG_DESCRIPTOR_SIZE 12 /* 3 x u32 */
+
+/*
+ * The debug memory window is divided into 16 slots, and the
+ * first slot is used as a recorder for the other 15 slots.
+ */
+#define SOF_IPC4_MAX_DEBUG_SLOTS 15
+#define SOF_IPC4_DEBUG_SLOT_SIZE 0x1000
+
+/* debug log slot types */
+#define SOF_IPC4_DEBUG_SLOT_UNUSED 0x00000000
+#define SOF_IPC4_DEBUG_SLOT_CRITICAL_LOG 0x54524300 /* byte 0: core ID */
+#define SOF_IPC4_DEBUG_SLOT_DEBUG_LOG 0x474f4c00 /* byte 0: core ID */
+#define SOF_IPC4_DEBUG_SLOT_GDB_STUB 0x42444700
+#define SOF_IPC4_DEBUG_SLOT_TELEMETRY 0x4c455400
+#define SOF_IPC4_DEBUG_SLOT_BROKEN 0x44414544
+
/** @}*/
#endif
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index be66853afbe2..8f5d97949d3d 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -7,6 +7,7 @@
* codec drivers using hdac_ext_bus_ops ops.
*/
+#include <linux/firmware.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
@@ -35,6 +36,13 @@
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
SNDRV_PCM_RATE_192000)
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+static char *loadable_patch[SNDRV_CARDS];
+
+module_param_array_named(patch, loadable_patch, charp, NULL, 0444);
+MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
+#endif
+
static int hdac_hda_dai_open(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai);
static void hdac_hda_dai_close(struct snd_pcm_substream *substream,
@@ -423,6 +431,26 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component)
dev_err(&hdev->dev, "failed to create hda codec %d\n", ret);
goto error_no_pm;
}
+
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ if (loadable_patch[hda_pvt->dev_index] && *loadable_patch[hda_pvt->dev_index]) {
+ dev_info(&hdev->dev, "Applying patch firmware '%s'\n",
+ loadable_patch[hda_pvt->dev_index]);
+ ret = request_firmware(&hda_pvt->fw, loadable_patch[hda_pvt->dev_index],
+ &hdev->dev);
+ if (ret < 0)
+ goto error_no_pm;
+ if (hda_pvt->fw) {
+ ret = snd_hda_load_patch(hcodec->bus, hda_pvt->fw->size, hda_pvt->fw->data);
+ if (ret < 0) {
+ dev_err(&hdev->dev, "failed to load hda patch %d\n", ret);
+ goto error_no_pm;
+ }
+ release_firmware(hda_pvt->fw);
+ hda_pvt->fw = NULL;
+ }
+ }
+#endif
/*
* Overwrite type to HDA_DEV_ASOC since it is a ASoC driver
* hda_codec.c will check this flag to determine if unregister
diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h
index b65560981abb..b7a12aea8d32 100644
--- a/sound/soc/codecs/hdac_hda.h
+++ b/sound/soc/codecs/hdac_hda.h
@@ -26,6 +26,10 @@ struct hdac_hda_priv {
struct hda_codec *codec;
struct hdac_hda_pcm pcm[HDAC_DAI_ID_NUM];
bool need_display_power;
+ int dev_index;
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ const struct firmware *fw;
+#endif
};
struct hdac_ext_bus_ops *snd_soc_hdac_hda_get_ops(void);
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index 16d66eed80f4..fa3252b6f1bf 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -689,6 +689,10 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
select SND_SOC_RT1318_SDW
select SND_SOC_RT5682_SDW
select SND_SOC_CS42L42_SDW
+ select SND_SOC_CS42L43
+ select SND_SOC_CS42L43_SDW
+ select MFD_CS42L43
+ select MFD_CS42L43_SDW
select SND_SOC_CS35L56_SDW
select SND_SOC_DMIC
select SND_SOC_INTEL_HDA_DSP_COMMON
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index be60ce5ab5b0..ae78e4aa69fc 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -42,7 +42,8 @@ snd-soc-sof-sdw-objs += sof_sdw.o \
sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \
sof_sdw_rt712_sdca.o sof_sdw_rt715.o \
sof_sdw_rt715_sdca.o sof_sdw_dmic.o \
- sof_sdw_cs42l42.o sof_sdw_cs_amp.o \
+ sof_sdw_cs42l42.o sof_sdw_cs42l43.o \
+ sof_sdw_cs_amp.o \
sof_sdw_hdmi.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index 752bfce1ea01..b36cdf374a82 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -916,6 +916,33 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.dai_num = 1,
},
{
+ .part_id = 0x4243,
+ .codec_name = "cs42l43-codec",
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "cs42l43-dp5",
+ .dai_type = SOF_SDW_DAI_TYPE_JACK,
+ .dailink = {SDW_JACK_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
+ .init = sof_sdw_cs42l43_hs_init,
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "cs42l43-dp1",
+ .dai_type = SOF_SDW_DAI_TYPE_JACK,
+ .dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID},
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "cs42l43-dp2",
+ .dai_type = SOF_SDW_DAI_TYPE_MIC,
+ .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
+ .init = sof_sdw_cs42l43_dmic_init,
+ }
+ },
+ .dai_num = 3,
+ },
+ {
.part_id = 0xaaaa, /* generic codec mockup */
.version_id = 0,
.dais = {
diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h
index 270aded488e1..bfdeab4be1a7 100644
--- a/sound/soc/intel/boards/sof_sdw_common.h
+++ b/sound/soc/intel/boards/sof_sdw_common.h
@@ -210,6 +210,19 @@ int sof_sdw_cs42l42_init(struct snd_soc_card *card,
struct sof_sdw_codec_info *info,
bool playback);
+/* CS42L43 support */
+int sof_sdw_cs42l43_hs_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
+ struct snd_soc_dai_link *dai_links,
+ struct sof_sdw_codec_info *info,
+ bool playback);
+
+int sof_sdw_cs42l43_dmic_init(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *link,
+ struct snd_soc_dai_link *dai_links,
+ struct sof_sdw_codec_info *info,
+ bool playback);
+
/* CS AMP support */
int sof_sdw_cs_amp_init(struct snd_soc_card *card,
const struct snd_soc_acpi_link_adr *link,
diff --git a/sound/soc/intel/boards/sof_sdw_cs42l43.c b/sound/soc/intel/boards/sof_sdw_cs42l43.c
new file mode 100644
index 000000000000..e34750b75d76
--- /dev/null
+++ b/sound/soc/intel/boards/sof_sdw_cs42l43.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Based on sof_sdw_rt5682.c
+// Copyright (c) 2023 Intel Corporation
+
+/*
+ * sof_sdw_cs42l43 - Helpers to handle CS42L43 from generic machine driver
+ */
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <sound/jack.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_type.h>
+#include <sound/cs42l43.h>
+#include <sound/control.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-dapm.h>
+#include "sof_sdw_common.h"
+
+static const struct snd_soc_dapm_widget cs42l43_hs_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route cs42l43_hs_map[] = {
+ { "Headphone", NULL, "cs42l43 AMP3_OUT" },
+ { "Headphone", NULL, "cs42l43 AMP4_OUT" },
+ { "cs42l43 ADC1_IN1_P", NULL, "Headset Mic" },
+ { "cs42l43 ADC1_IN1_N", NULL, "Headset Mic" },
+};
+
+static const struct snd_soc_dapm_widget cs42l43_dmic_widgets[] = {
+ SND_SOC_DAPM_MIC("DMIC", NULL),
+};
+
+static const struct snd_soc_dapm_route cs42l43_dmic_map[] = {
+ { "cs42l43 PDM1_DIN", NULL, "DMIC" },
+ { "cs42l43 PDM2_DIN", NULL, "DMIC" },
+};
+
+static int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+ struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_jack *jack = &ctx->sdw_headset;
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l43", card->components);
+ if (!card->components)
+ return -ENOMEM;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, cs42l43_hs_widgets,
+ ARRAY_SIZE(cs42l43_hs_widgets));
+ if (ret) {
+ dev_err(card->dev, "cs42l43 hs widgets addition failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_hs_map,
+ ARRAY_SIZE(cs42l43_hs_map));
+
+ if (ret) {
+ dev_err(card->dev, "cs42l43 hs map addition failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_card_jack_new(card, "Headphone Jack",
+ SND_JACK_MECHANICAL | SND_JACK_AVOUT |
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ jack);
+ if (ret) {
+ dev_err(card->dev, "Failed to create jack: %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ ret = snd_soc_component_set_jack(component, jack, NULL);
+ if (ret) {
+ dev_err(card->dev, "Failed to register jack: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_component_set_sysclk(component, CS42L43_SYSCLK, CS42L43_SYSCLK_SDW,
+ 0, SND_SOC_CLOCK_IN);
+ if (ret)
+ dev_err(card->dev, "Failed to set sysclk: %d\n", ret);
+
+ return ret;
+}
+
+int sof_sdw_cs42l43_hs_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link,
+ struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info,
+ bool playback)
+{
+ /*
+ * No need to test if (!playback) like other codecs as cs42l43 uses separated dai for
+ * playback and capture, and sof_sdw_cs42l43_init is only linked to the playback dai.
+ */
+
+ dai_links->init = cs42l43_hs_rtd_init;
+
+ return 0;
+}
+
+static int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s mic:cs42l43-dmic",
+ card->components);
+ if (!card->components)
+ return -ENOMEM;
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, cs42l43_dmic_widgets,
+ ARRAY_SIZE(cs42l43_dmic_widgets));
+ if (ret) {
+ dev_err(card->dev, "cs42l43 dmic widgets addition failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_dmic_map,
+ ARRAY_SIZE(cs42l43_dmic_map));
+
+ if (ret)
+ dev_err(card->dev, "cs42l43 dmic map addition failed: %d\n", ret);
+
+ return ret;
+}
+
+int sof_sdw_cs42l43_dmic_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link,
+ struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info,
+ bool playback)
+{
+ dai_links->init = cs42l43_dmic_rtd_init;
+ return 0;
+}
diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
index 0304246d2922..b6409d2bd1fb 100644
--- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c
@@ -92,6 +92,20 @@ static const struct snd_soc_acpi_endpoint rt712_endpoints[] = {
},
};
+static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 2,
+ .group_id = 1,
+};
+
+static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 3,
+ .group_id = 1,
+};
+
static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
{
.adr = 0x000030025D071101ull,
@@ -211,6 +225,45 @@ static const struct snd_soc_acpi_link_adr mtl_712_only[] = {
{}
};
+static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
+ {
+ .adr = 0x00003001FA424301ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "cs42l43"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_1_adr[] = {
+ {
+ .adr = 0x00013701FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "cs35l56-8"
+ },
+ {
+ .adr = 0x00013601FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_3_endpoint,
+ .name_prefix = "cs35l56-7"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device cs35l56_2_adr[] = {
+ {
+ .adr = 0x00023301FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "cs35l56-1"
+ },
+ {
+ .adr = 0x00023201FA355601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_2_endpoint,
+ .name_prefix = "cs35l56-2"
+ }
+};
+
static const struct snd_soc_acpi_link_adr rt5682_link2_max98373_link0[] = {
/* Expected order: jack -> amp */
{
@@ -317,6 +370,25 @@ static const struct snd_soc_acpi_link_adr cs42l42_link0_max98363_link2[] = {
{}
};
+static const struct snd_soc_acpi_link_adr mtl_cs42l43_cs35l56[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(cs42l43_0_adr),
+ .adr_d = cs42l43_0_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(cs35l56_1_adr),
+ .adr_d = cs35l56_1_adr,
+ },
+ {
+ .mask = BIT(2),
+ .num_adr = ARRAY_SIZE(cs35l56_2_adr),
+ .adr_d = cs35l56_2_adr,
+ },
+ {}
+};
+
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
/* mockup tests need to be first */
@@ -351,6 +423,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
.sof_tplg_filename = "sof-mtl-rt1318-l12-rt714-l0.tplg"
},
{
+ .link_mask = GENMASK(2, 0),
+ .links = mtl_cs42l43_cs35l56,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-mtl-cs42l43-l0-cs35l56-l12.tplg",
+ },
+ {
.link_mask = GENMASK(3, 0),
.links = mtl_3_in_1_sdca,
.drv_name = "sof_sdw",
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 77408a981b97..d753d393a428 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -736,6 +736,7 @@ static int probe_codec(struct hdac_bus *bus, int addr)
return PTR_ERR(codec);
hda_codec->codec = codec;
+ hda_codec->dev_index = addr;
dev_set_drvdata(&codec->core.dev, hda_codec);
/* use legacy bus only for HDA codecs, idisp uses ext bus */
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/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c
index 9935e457b467..72e211b5f7a4 100644
--- a/sound/soc/sof/amd/pci-rmb.c
+++ b/sound/soc/sof/amd/pci-rmb.c
@@ -47,16 +47,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/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index 2844d9a8040a..65a7041cbab9 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -609,32 +609,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,
diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c
index 1243f8a6141e..9d58dda8f079 100644
--- a/sound/soc/sof/imx/imx8m.c
+++ b/sound/soc/sof/imx/imx8m.c
@@ -471,16 +471,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,
diff --git a/sound/soc/sof/imx/imx8ulp.c b/sound/soc/sof/imx/imx8ulp.c
index 4a562c9856e9..2673c1d4ddea 100644
--- a/sound/soc/sof/imx/imx8ulp.c
+++ b/sound/soc/sof/imx/imx8ulp.c
@@ -478,16 +478,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,
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..511fce8e0e19 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,
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index faf223b38360..a976dc91d2ec 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -374,16 +374,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 +396,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 +418,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,
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-dai-ops.c b/sound/soc/sof/intel/hda-dai-ops.c
index 494ced2b746e..012a75f366ab 100644
--- a/sound/soc/sof/intel/hda-dai-ops.c
+++ b/sound/soc/sof/intel/hda-dai-ops.c
@@ -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..318a21c12cd0 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -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-loader.c b/sound/soc/sof/intel/hda-loader.c
index 1e2669a8088d..46fb2d1425e9 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -643,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.c b/sound/soc/sof/intel/hda.c
index 15e6779efaa3..a1732af2b1be 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;
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 2b228c63905b..7c575ba9462c 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -603,6 +603,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 b84ca58da9d5..0e91169c685e 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..235e31a26106 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,
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/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-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 2462feceda5d..afd23d3f16cd 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -2107,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;
@@ -2192,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 d94f0ab4aee3..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
diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c
index 6c33ee5af32b..3f4d57dba972 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 {
@@ -547,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;
@@ -575,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",
@@ -619,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);
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c
index f587edf9e0a7..8544d65bc2cf 100644
--- a/sound/soc/sof/mediatek/mt8186/mt8186.c
+++ b/sound/soc/sof/mediatek/mt8186/mt8186.c
@@ -607,16 +607,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 +681,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,
diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c
index 7d6a568556ea..fab2d5af8610 100644
--- a/sound/soc/sof/mediatek/mt8195/mt8195.c
+++ b/sound/soc/sof/mediatek/mt8195/mt8195.c
@@ -635,16 +635,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,
diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c
index 1b04dcb33293..5c4e5ab31abf 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;
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..3f636b82173e 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,7 @@ 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 (cdev->sdev->pdata->ipc_type == SOF_IPC_TYPE_3) {
struct sof_ipc_cmd_hdr *hdr = ipc_msg;
if (hdr->size < sizeof(hdr)) {
@@ -324,12 +324,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 +340,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 +463,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 +497,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..b0e8bd06f78a 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;
diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
index 146d25983b08..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;
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 = {