summaryrefslogtreecommitdiff
path: root/sound/soc/sof/intel
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/intel')
-rw-r--r--sound/soc/sof/intel/Kconfig31
-rw-r--r--sound/soc/sof/intel/Makefile2
-rw-r--r--sound/soc/sof/intel/apl.c2
-rw-r--r--sound/soc/sof/intel/bdw.c2
-rw-r--r--sound/soc/sof/intel/byt.c6
-rw-r--r--sound/soc/sof/intel/cnl.c40
-rw-r--r--sound/soc/sof/intel/hda-codec.c28
-rw-r--r--sound/soc/sof/intel/hda-dsp.c20
-rw-r--r--sound/soc/sof/intel/hda-ipc.h4
-rw-r--r--sound/soc/sof/intel/hda-loader.c196
-rw-r--r--sound/soc/sof/intel/hda-stream.c69
-rw-r--r--sound/soc/sof/intel/hda.c47
-rw-r--r--sound/soc/sof/intel/hda.h12
-rw-r--r--sound/soc/sof/intel/shim.h2
-rw-r--r--sound/soc/sof/intel/tgl.c153
15 files changed, 469 insertions, 145 deletions
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 3aaf25e4f766..a066e08860cb 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -166,6 +166,7 @@ config SND_SOC_SOF_CANNONLAKE_SUPPORT
config SND_SOC_SOF_CANNONLAKE
tristate
select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level
@@ -181,6 +182,7 @@ config SND_SOC_SOF_COFFEELAKE_SUPPORT
config SND_SOC_SOF_COFFEELAKE
tristate
select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level
@@ -196,6 +198,7 @@ config SND_SOC_SOF_ICELAKE_SUPPORT
config SND_SOC_SOF_ICELAKE
tristate
select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level
@@ -203,6 +206,7 @@ config SND_SOC_SOF_ICELAKE
config SND_SOC_SOF_COMETLAKE
tristate
select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level
@@ -229,6 +233,7 @@ config SND_SOC_SOF_TIGERLAKE_SUPPORT
config SND_SOC_SOF_TIGERLAKE
tristate
select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level
@@ -244,6 +249,7 @@ config SND_SOC_SOF_ELKHARTLAKE_SUPPORT
config SND_SOC_SOF_ELKHARTLAKE
tristate
select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level
@@ -305,7 +311,7 @@ config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1
bool "SOF enable DMI Link L1"
help
This option enables DMI L1 for both playback and capture
- and disables known workarounds for specific HDaudio platforms.
+ and disables known workarounds for specific HDAudio platforms.
Only use to look into power optimizations on platforms not
affected by DMI L1 issues. This option is not recommended.
Say Y if you want to enable DMI Link L1
@@ -329,6 +335,29 @@ config SND_SOC_SOF_HDA
This option is not user-selectable but automagically handled by
'select' statements at a higher level
+config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK
+ bool "SOF support for SoundWire"
+ depends on SOUNDWIRE && ACPI
+ help
+ This adds support for SoundWire with Sound Open Firmware
+ for Intel(R) platforms.
+ Say Y if you want to enable SoundWire links with SOF.
+ If unsure select "N".
+
+config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
+ tristate
+ select SND_SOC_SOF_INTEL_SOUNDWIRE if SND_SOC_SOF_INTEL_SOUNDWIRE_LINK
+ help
+ This option is not user-selectable but automagically handled by
+ 'select' statements at a higher level
+
+config SND_SOC_SOF_INTEL_SOUNDWIRE
+ tristate
+ select SOUNDWIRE_INTEL
+ help
+ This option is not user-selectable but automagically handled by
+ 'select' statements at a higher level
+
endif ## SND_SOC_SOF_INTEL_PCI
endif ## SND_SOC_SOF_INTEL_TOPLEVEL
diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile
index f7e9358f1f06..72d85b25df7d 100644
--- a/sound/soc/sof/intel/Makefile
+++ b/sound/soc/sof/intel/Makefile
@@ -8,7 +8,7 @@ snd-sof-intel-ipc-objs := intel-ipc.o
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-bus.o \
- apl.o cnl.o
+ apl.o cnl.o tgl.o
snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o
snd-sof-intel-hda-objs := hda-codec.o
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index 9e29d4fd393a..4eeade2e77f7 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -129,7 +129,7 @@ const struct sof_intel_dsp_desc apl_chip_info = {
/* Apollolake */
.cores_num = 2,
.init_core_mask = 1,
- .cores_mask = HDA_DSP_CORE_MASK(0) | HDA_DSP_CORE_MASK(1),
+ .host_managed_cores_mask = GENMASK(1, 0),
.ipc_req = HDA_DSP_REG_HIPCI,
.ipc_req_mask = HDA_DSP_REG_HIPCI_BUSY,
.ipc_ack = HDA_DSP_REG_HIPCIE,
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
index 99fd0bd7276e..50a4a73e6b9f 100644
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -655,7 +655,7 @@ EXPORT_SYMBOL_NS(sof_bdw_ops, SND_SOC_SOF_BROADWELL);
const struct sof_intel_dsp_desc bdw_chip_info = {
.cores_num = 1,
- .cores_mask = 1,
+ .host_managed_cores_mask = 1,
};
EXPORT_SYMBOL_NS(bdw_chip_info, SND_SOC_SOF_BROADWELL);
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index 49f67f1b94e0..186736ee5fc2 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -651,7 +651,7 @@ EXPORT_SYMBOL_NS(sof_tng_ops, SND_SOC_SOF_MERRIFIELD);
const struct sof_intel_dsp_desc tng_chip_info = {
.cores_num = 1,
- .cores_mask = 1,
+ .host_managed_cores_mask = 1,
};
EXPORT_SYMBOL_NS(tng_chip_info, SND_SOC_SOF_MERRIFIELD);
@@ -896,7 +896,7 @@ EXPORT_SYMBOL_NS(sof_byt_ops, SND_SOC_SOF_BAYTRAIL);
const struct sof_intel_dsp_desc byt_chip_info = {
.cores_num = 1,
- .cores_mask = 1,
+ .host_managed_cores_mask = 1,
};
EXPORT_SYMBOL_NS(byt_chip_info, SND_SOC_SOF_BAYTRAIL);
@@ -976,7 +976,7 @@ EXPORT_SYMBOL_NS(sof_cht_ops, SND_SOC_SOF_BAYTRAIL);
const struct sof_intel_dsp_desc cht_chip_info = {
.cores_num = 1,
- .cores_mask = 1,
+ .host_managed_cores_mask = 1,
};
EXPORT_SYMBOL_NS(cht_chip_info, SND_SOC_SOF_BAYTRAIL);
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 16db0f50d139..a5d3258104c0 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -29,7 +29,7 @@ static const struct snd_sof_debugfs_map cnl_dsp_debugfs[] = {
static void cnl_ipc_host_done(struct snd_sof_dev *sdev);
static void cnl_ipc_dsp_done(struct snd_sof_dev *sdev);
-static irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
+irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
{
struct snd_sof_dev *sdev = context;
u32 hipci;
@@ -163,8 +163,7 @@ static bool cnl_compact_ipc_compress(struct snd_sof_ipc_msg *msg,
return false;
}
-static int cnl_ipc_send_msg(struct snd_sof_dev *sdev,
- struct snd_sof_ipc_msg *msg)
+int cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
{
struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
struct sof_ipc_cmd_hdr *hdr;
@@ -202,7 +201,7 @@ static int cnl_ipc_send_msg(struct snd_sof_dev *sdev,
* IPCs are sent at a high-rate. mod_delayed_work()
* modifies the timer if the work is pending.
* Also, a new delayed work should not be queued after the
- * the CTX_SAVE IPC, which is sent before the DSP enters D3.
+ * CTX_SAVE IPC, which is sent before the DSP enters D3.
*/
if (hdr->cmd != (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CTX_SAVE))
mod_delayed_work(system_wq, &hdev->d0i3_work,
@@ -211,7 +210,7 @@ static int cnl_ipc_send_msg(struct snd_sof_dev *sdev,
return 0;
}
-static void cnl_ipc_dump(struct snd_sof_dev *sdev)
+void cnl_ipc_dump(struct snd_sof_dev *sdev)
{
u32 hipcctl;
u32 hipcida;
@@ -335,10 +334,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
/* Cannonlake */
.cores_num = 4,
.init_core_mask = 1,
- .cores_mask = HDA_DSP_CORE_MASK(0) |
- HDA_DSP_CORE_MASK(1) |
- HDA_DSP_CORE_MASK(2) |
- HDA_DSP_CORE_MASK(3),
+ .host_managed_cores_mask = GENMASK(3, 0),
.ipc_req = CNL_DSP_REG_HIPCIDR,
.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
.ipc_ack = CNL_DSP_REG_HIPCIDA,
@@ -354,10 +350,7 @@ const struct sof_intel_dsp_desc icl_chip_info = {
/* Icelake */
.cores_num = 4,
.init_core_mask = 1,
- .cores_mask = HDA_DSP_CORE_MASK(0) |
- HDA_DSP_CORE_MASK(1) |
- HDA_DSP_CORE_MASK(2) |
- HDA_DSP_CORE_MASK(3),
+ .host_managed_cores_mask = GENMASK(3, 0),
.ipc_req = CNL_DSP_REG_HIPCIDR,
.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
.ipc_ack = CNL_DSP_REG_HIPCIDA,
@@ -369,27 +362,11 @@ const struct sof_intel_dsp_desc icl_chip_info = {
};
EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
-const struct sof_intel_dsp_desc tgl_chip_info = {
- /* Tigerlake */
- .cores_num = 4,
- .init_core_mask = 1,
- .cores_mask = HDA_DSP_CORE_MASK(0),
- .ipc_req = CNL_DSP_REG_HIPCIDR,
- .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
- .ipc_ack = CNL_DSP_REG_HIPCIDA,
- .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
- .ipc_ctl = CNL_DSP_REG_HIPCCTL,
- .rom_init_timeout = 300,
- .ssp_count = ICL_SSP_COUNT,
- .ssp_base_offset = CNL_SSP_BASE_OFFSET,
-};
-EXPORT_SYMBOL_NS(tgl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
-
const struct sof_intel_dsp_desc ehl_chip_info = {
/* Elkhartlake */
.cores_num = 4,
.init_core_mask = 1,
- .cores_mask = HDA_DSP_CORE_MASK(0),
+ .host_managed_cores_mask = BIT(0),
.ipc_req = CNL_DSP_REG_HIPCIDR,
.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
.ipc_ack = CNL_DSP_REG_HIPCIDA,
@@ -405,8 +382,7 @@ const struct sof_intel_dsp_desc jsl_chip_info = {
/* Jasperlake */
.cores_num = 2,
.init_core_mask = 1,
- .cores_mask = HDA_DSP_CORE_MASK(0) |
- HDA_DSP_CORE_MASK(1),
+ .host_managed_cores_mask = GENMASK(1, 0),
.ipc_req = CNL_DSP_REG_HIPCIDR,
.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
.ipc_ack = CNL_DSP_REG_HIPCIDA,
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c
index 2c5c451fa19d..6875fa570c2c 100644
--- a/sound/soc/sof/intel/hda-codec.c
+++ b/sound/soc/sof/intel/hda-codec.c
@@ -116,10 +116,11 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
{
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
struct hdac_hda_priv *hda_priv;
+ struct hda_codec *codec;
+ int type = HDA_DEV_LEGACY;
#endif
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_device *hdev;
- struct hda_codec *codec;
u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) |
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
u32 resp = -1;
@@ -143,7 +144,11 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
hdev = &hda_priv->codec.core;
codec = &hda_priv->codec;
- ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev);
+ /* only probe ASoC codec drivers for HDAC-HDMI */
+ if (!hda_codec_use_common_hdmi && (resp & 0xFFFF0000) == IDISP_VID_INTEL)
+ type = HDA_DEV_ASOC;
+
+ ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev, type);
if (ret < 0)
return ret;
@@ -151,7 +156,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
if (!hdev->bus->audio_component) {
dev_dbg(sdev->dev,
"iDisp hw present but no driver\n");
- return -ENOENT;
+ goto error;
}
hda_priv->need_display_power = true;
}
@@ -161,29 +166,28 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
else
codec->probe_id = 0;
- /*
- * if common HDMI codec driver is not used, codec load
- * is skipped here and hdac_hdmi is used instead
- */
- if (hda_codec_use_common_hdmi ||
- (resp & 0xFFFF0000) != IDISP_VID_INTEL) {
- hdev->type = HDA_DEV_LEGACY;
+ if (type == HDA_DEV_LEGACY) {
ret = hda_codec_load_module(codec);
/*
* handle ret==0 (no driver bound) as an error, but pass
* other return codes without modification
*/
if (ret == 0)
- ret = -ENOENT;
+ goto error;
}
return ret;
+
+error:
+ snd_hdac_ext_bus_device_exit(hdev);
+ return -ENOENT;
+
#else
hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
if (!hdev)
return -ENOMEM;
- ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev);
+ ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev, HDA_DEV_ASOC);
return ret;
#endif
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index ed4d65a29d3a..18ff1c2f5376 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -239,10 +239,15 @@ bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev,
int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask)
{
+ struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+ const struct sof_intel_dsp_desc *chip = hda->desc;
int ret;
- /* return if core is already enabled */
- if (hda_dsp_core_is_enabled(sdev, core_mask))
+ /* restrict core_mask to host managed cores mask */
+ core_mask &= chip->host_managed_cores_mask;
+
+ /* return if core_mask is not valid or cores are already enabled */
+ if (!core_mask || hda_dsp_core_is_enabled(sdev, core_mask))
return 0;
/* power up */
@@ -259,8 +264,17 @@ int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask)
int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
unsigned int core_mask)
{
+ struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+ const struct sof_intel_dsp_desc *chip = hda->desc;
int ret;
+ /* restrict core_mask to host managed cores mask */
+ core_mask &= chip->host_managed_cores_mask;
+
+ /* return if core_mask is not valid */
+ if (!core_mask)
+ return 0;
+
/* place core in reset prior to power down */
ret = hda_dsp_core_stall_reset(sdev, core_mask);
if (ret < 0) {
@@ -610,7 +624,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
#endif
/* power down DSP */
- ret = hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
+ ret = hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask);
if (ret < 0) {
dev_err(sdev->dev,
"error: failed to power down core during suspend\n");
diff --git a/sound/soc/sof/intel/hda-ipc.h b/sound/soc/sof/intel/hda-ipc.h
index ade4c3191a39..10fbca5939db 100644
--- a/sound/soc/sof/intel/hda-ipc.h
+++ b/sound/soc/sof/intel/hda-ipc.h
@@ -48,4 +48,8 @@
#define HDA_PM_PG_STREAMING BIT(1)
#define HDA_PM_PG_RSVD BIT(0)
+irqreturn_t cnl_ipc_irq_thread(int irq, void *context);
+int cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
+void cnl_ipc_dump(struct snd_sof_dev *sdev);
+
#endif
diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
index 441d05cda604..2707a16c6a4d 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -17,31 +17,28 @@
#include <linux/firmware.h>
#include <sound/hdaudio_ext.h>
+#include <sound/hda_register.h>
#include <sound/sof.h>
#include "../ops.h"
#include "hda.h"
#define HDA_FW_BOOT_ATTEMPTS 3
+#define HDA_CL_STREAM_FORMAT 0x40
-static int cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
- unsigned int size, struct snd_dma_buffer *dmab,
- int direction)
+static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
+ unsigned int size, struct snd_dma_buffer *dmab,
+ int direction)
{
struct hdac_ext_stream *dsp_stream;
struct hdac_stream *hstream;
struct pci_dev *pci = to_pci_dev(sdev->dev);
int ret;
- if (direction != SNDRV_PCM_STREAM_PLAYBACK) {
- dev_err(sdev->dev, "error: code loading DMA is playback only\n");
- return -EINVAL;
- }
-
dsp_stream = hda_dsp_stream_get(sdev, direction);
if (!dsp_stream) {
dev_err(sdev->dev, "error: no stream available\n");
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
}
hstream = &dsp_stream->hstream;
hstream->substream = NULL;
@@ -57,20 +54,27 @@ static int cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
hstream->format_val = format;
hstream->bufsize = size;
- ret = hda_dsp_stream_hw_params(sdev, dsp_stream, dmab, NULL);
- if (ret < 0) {
- dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret);
- goto error;
+ if (direction == SNDRV_PCM_STREAM_CAPTURE) {
+ ret = hda_dsp_iccmax_stream_hw_params(sdev, dsp_stream, dmab, NULL);
+ if (ret < 0) {
+ dev_err(sdev->dev, "error: iccmax stream prepare failed: %x\n", ret);
+ goto error;
+ }
+ } else {
+ ret = hda_dsp_stream_hw_params(sdev, dsp_stream, dmab, NULL);
+ if (ret < 0) {
+ dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret);
+ goto error;
+ }
+ hda_dsp_stream_spib_config(sdev, dsp_stream, HDA_DSP_SPIB_ENABLE, size);
}
- hda_dsp_stream_spib_config(sdev, dsp_stream, HDA_DSP_SPIB_ENABLE, size);
-
- return hstream->stream_tag;
+ return dsp_stream;
error:
hda_dsp_stream_put(sdev, direction, hstream->stream_tag);
snd_dma_free_pages(dmab);
- return ret;
+ return ERR_PTR(ret);
}
/*
@@ -78,8 +82,7 @@ error:
* status on core 1, so power up core 1 also momentarily, keep it in
* reset/stall and then turn it off
*/
-static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
- u32 fwsize, int stream_tag)
+static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
const struct sof_intel_dsp_desc *chip = hda->desc;
@@ -88,9 +91,10 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
int i;
/* step 1: power up corex */
- ret = hda_dsp_core_power_up(sdev, chip->cores_mask);
+ ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask);
if (ret < 0) {
- dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n");
+ if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
+ dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n");
goto err;
}
@@ -110,9 +114,11 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
((stream_tag - 1) << 9)));
/* step 3: unset core 0 reset state & unstall/run core 0 */
- ret = hda_dsp_core_run(sdev, HDA_DSP_CORE_MASK(0));
+ ret = hda_dsp_core_run(sdev, BIT(0));
if (ret < 0) {
- dev_err(sdev->dev, "error: dsp core start failed %d\n", ret);
+ if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
+ dev_err(sdev->dev,
+ "error: dsp core start failed %d\n", ret);
ret = -EIO;
goto err;
}
@@ -126,8 +132,10 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
HDA_DSP_INIT_TIMEOUT_US);
if (ret < 0) {
- dev_err(sdev->dev, "error: %s: timeout for HIPCIE done\n",
- __func__);
+ if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
+ dev_err(sdev->dev,
+ "error: %s: timeout for HIPCIE done\n",
+ __func__);
goto err;
}
@@ -138,10 +146,11 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
chip->ipc_ack_mask);
/* step 5: power down corex */
- ret = hda_dsp_core_power_down(sdev,
- chip->cores_mask & ~(HDA_DSP_CORE_MASK(0)));
+ ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & ~(BIT(0)));
if (ret < 0) {
- dev_err(sdev->dev, "error: dsp core x power down failed\n");
+ if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
+ dev_err(sdev->dev,
+ "error: dsp core x power down failed\n");
goto err;
}
@@ -159,13 +168,14 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, const void *fwdata,
if (!ret)
return 0;
- dev_err(sdev->dev,
- "error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n",
- __func__);
+ if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
+ dev_err(sdev->dev,
+ "error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n",
+ __func__);
err:
hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX);
- hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
+ hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask);
return ret;
}
@@ -197,34 +207,20 @@ static int cl_trigger(struct snd_sof_dev *sdev,
}
}
-static struct hdac_ext_stream *get_stream_with_tag(struct snd_sof_dev *sdev,
- int tag)
-{
- struct hdac_bus *bus = sof_to_bus(sdev);
- struct hdac_stream *s;
-
- /* get stream with tag */
- list_for_each_entry(s, &bus->stream_list, list) {
- if (s->direction == SNDRV_PCM_STREAM_PLAYBACK &&
- s->stream_tag == tag) {
- return stream_to_hdac_ext_stream(s);
- }
- }
-
- return NULL;
-}
-
static int cl_cleanup(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab,
struct hdac_ext_stream *stream)
{
struct hdac_stream *hstream = &stream->hstream;
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
- int ret;
+ int ret = 0;
- ret = hda_dsp_stream_spib_config(sdev, stream, HDA_DSP_SPIB_DISABLE, 0);
+ if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK)
+ ret = hda_dsp_stream_spib_config(sdev, stream, HDA_DSP_SPIB_DISABLE, 0);
+ else
+ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
+ SOF_HDA_SD_CTL_DMA_START, 0);
- hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_PLAYBACK,
- hstream->stream_tag);
+ hda_dsp_stream_put(sdev, hstream->direction, hstream->stream_tag);
hstream->running = 0;
hstream->substream = NULL;
@@ -282,14 +278,63 @@ static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream)
return status;
}
+int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_pdata *plat_data = sdev->pdata;
+ struct hdac_ext_stream *iccmax_stream;
+ struct hdac_bus *bus = sof_to_bus(sdev);
+ struct firmware stripped_firmware;
+ int ret, ret1;
+ u8 original_gb;
+
+ /* save the original LTRP guardband value */
+ original_gb = snd_hdac_chip_readb(bus, VS_LTRP) & HDA_VS_INTEL_LTRP_GB_MASK;
+
+ if (plat_data->fw->size <= plat_data->fw_offset) {
+ dev_err(sdev->dev, "error: firmware size must be greater than firmware offset\n");
+ return -EINVAL;
+ }
+
+ stripped_firmware.size = plat_data->fw->size - plat_data->fw_offset;
+
+ /* prepare capture stream for ICCMAX */
+ iccmax_stream = cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT, stripped_firmware.size,
+ &sdev->dmab_bdl, SNDRV_PCM_STREAM_CAPTURE);
+ if (IS_ERR(iccmax_stream)) {
+ dev_err(sdev->dev, "error: dma prepare for ICCMAX stream failed\n");
+ return PTR_ERR(iccmax_stream);
+ }
+
+ ret = hda_dsp_cl_boot_firmware(sdev);
+
+ /*
+ * Perform iccmax stream cleanup. This should be done even if firmware loading fails.
+ * If the cleanup also fails, we return the initial error
+ */
+ ret1 = cl_cleanup(sdev, &sdev->dmab_bdl, iccmax_stream);
+ if (ret1 < 0) {
+ dev_err(sdev->dev, "error: ICCMAX stream cleanup failed\n");
+
+ /* set return value to indicate cleanup failure */
+ if (!ret)
+ ret = ret1;
+ }
+
+ /* restore the original guardband value after FW boot */
+ snd_hdac_chip_updateb(bus, VS_LTRP, HDA_VS_INTEL_LTRP_GB_MASK, original_gb);
+
+ return ret;
+}
+
int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
{
+ struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct snd_sof_pdata *plat_data = sdev->pdata;
const struct sof_dev_desc *desc = plat_data->desc;
const struct sof_intel_dsp_desc *chip_info;
struct hdac_ext_stream *stream;
struct firmware stripped_firmware;
- int ret, ret1, tag, i;
+ int ret, ret1, i;
chip_info = desc->chip_info;
@@ -305,23 +350,11 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
init_waitqueue_head(&sdev->boot_wait);
/* prepare DMA for code loader stream */
- tag = cl_stream_prepare(sdev, 0x40, stripped_firmware.size,
- &sdev->dmab, SNDRV_PCM_STREAM_PLAYBACK);
-
- if (tag < 0) {
- dev_err(sdev->dev, "error: dma prepare for fw loading err: %x\n",
- tag);
- return tag;
- }
-
- /* get stream with tag */
- stream = get_stream_with_tag(sdev, tag);
- if (!stream) {
- dev_err(sdev->dev,
- "error: could not get stream with stream tag %d\n",
- tag);
- ret = -ENODEV;
- goto err;
+ stream = cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT, stripped_firmware.size,
+ &sdev->dmab, SNDRV_PCM_STREAM_PLAYBACK);
+ if (IS_ERR(stream)) {
+ dev_err(sdev->dev, "error: dma prepare for fw loading failed\n");
+ return PTR_ERR(stream);
}
memcpy(sdev->dmab.area, stripped_firmware.data,
@@ -329,25 +362,25 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
/* try ROM init a few times before giving up */
for (i = 0; i < HDA_FW_BOOT_ATTEMPTS; i++) {
- ret = cl_dsp_init(sdev, stripped_firmware.data,
- stripped_firmware.size, tag);
+ dev_dbg(sdev->dev,
+ "Attempting iteration %d of Core En/ROM load...\n", i);
+
+ hda->boot_iteration = i + 1;
+ ret = cl_dsp_init(sdev, stream->hstream.stream_tag);
/* don't retry anymore if successful */
if (!ret)
break;
+ }
- dev_dbg(sdev->dev, "iteration %d of Core En/ROM load failed: %d\n",
+ if (i == HDA_FW_BOOT_ATTEMPTS) {
+ dev_err(sdev->dev, "error: dsp init failed after %d attempts with err: %d\n",
i, ret);
- dev_dbg(sdev->dev, "Error code=0x%x: FW status=0x%x\n",
+ dev_err(sdev->dev, "ROM error=0x%x: FW status=0x%x\n",
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
HDA_DSP_SRAM_REG_ROM_ERROR),
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
HDA_DSP_SRAM_REG_ROM_STATUS));
- }
-
- if (i == HDA_FW_BOOT_ATTEMPTS) {
- dev_err(sdev->dev, "error: dsp init failed after %d attempts with err: %d\n",
- i, ret);
goto cleanup;
}
@@ -395,14 +428,13 @@ cleanup:
}
/*
- * return master core id if both fw copy
+ * return primary core id if both fw copy
* and stream clean up are successful
*/
if (!ret)
return chip_info->init_core_mask;
/* dump dsp registers and disable DSP upon error */
-err:
hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX);
/* disable DSP */
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 1bda14c3590c..0e09ede922c7 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -23,6 +23,8 @@
#include "../sof-audio.h"
#include "hda.h"
+#define HDA_LTRP_GB_VALUE_US 95
+
/*
* set up one of BDL entries for a stream
*/
@@ -322,6 +324,73 @@ int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
return 0;
}
+/* minimal recommended programming for ICCMAX stream */
+int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream,
+ struct snd_dma_buffer *dmab,
+ struct snd_pcm_hw_params *params)
+{
+ struct hdac_bus *bus = sof_to_bus(sdev);
+ struct hdac_stream *hstream = &stream->hstream;
+ int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
+ int ret;
+ u32 mask = 0x1 << hstream->index;
+
+ if (!stream) {
+ dev_err(sdev->dev, "error: no stream available\n");
+ return -ENODEV;
+ }
+
+ if (hstream->posbuf)
+ *hstream->posbuf = 0;
+
+ /* reset BDL address */
+ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
+ sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
+ 0x0);
+ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
+ sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
+ 0x0);
+
+ hstream->frags = 0;
+
+ ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
+ if (ret < 0) {
+ dev_err(sdev->dev, "error: set up of BDL failed\n");
+ return ret;
+ }
+
+ /* program BDL address */
+ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
+ sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
+ (u32)hstream->bdl.addr);
+ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
+ sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
+ upper_32_bits(hstream->bdl.addr));
+
+ /* program cyclic buffer length */
+ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
+ sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
+ hstream->bufsize);
+
+ /* program last valid index */
+ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
+ sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
+ 0xffff, (hstream->frags - 1));
+
+ /* decouple host and link DMA, enable DSP features */
+ snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
+ mask, mask);
+
+ /* Follow HW recommendation to set the guardband value to 95us during FW boot */
+ snd_hdac_chip_updateb(bus, VS_LTRP, HDA_VS_INTEL_LTRP_GB_MASK, HDA_LTRP_GB_VALUE_US);
+
+ /* start DMA */
+ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
+ SOF_HDA_SD_CTL_DMA_START, SOF_HDA_SD_CTL_DMA_START);
+
+ return 0;
+}
+
/*
* prepare for common hdac registers settings, for both code loader
* and normal stream.
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 63ca920c8e6e..bb4128a72a42 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -37,6 +37,7 @@
#include "shim.h"
#define EXCEPT_MAX_HDR_SIZE 0x400
+#define HDA_EXT_ROM_STATUS_SIZE 8
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
@@ -414,8 +415,28 @@ void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags)
}
}
+/* dump the first 8 dwords representing the extended ROM status */
+static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev)
+{
+ struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+ char msg[128];
+ int len = 0;
+ u32 value;
+ int i;
+
+ for (i = 0; i < HDA_EXT_ROM_STATUS_SIZE; i++) {
+ value = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_ROM_STATUS + i * 0x4);
+ len += snprintf(msg + len, sizeof(msg) - len, " 0x%x", value);
+ }
+
+ sof_dev_dbg_or_err(sdev->dev, hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS,
+ "extended rom status: %s", msg);
+
+}
+
void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
{
+ struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct sof_ipc_dsp_oops_xtensa xoops;
struct sof_ipc_panic_info panic_info;
u32 stack[HDA_DSP_STACK_DUMP_SIZE];
@@ -435,8 +456,11 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
stack, HDA_DSP_STACK_DUMP_SIZE);
} else {
- dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n",
- status, panic);
+ sof_dev_dbg_or_err(sdev->dev, hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS,
+ "status = 0x%8.8x panic = 0x%8.8x\n",
+ status, panic);
+
+ hda_dsp_dump_ext_rom_status(sdev);
hda_dsp_get_status(sdev);
}
}
@@ -544,7 +568,7 @@ static int check_nhlt_dmic(struct snd_sof_dev *sdev)
if (nhlt) {
dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt);
intel_nhlt_free(nhlt);
- if (dmic_num == 2 || dmic_num == 4)
+ if (dmic_num >= 1 && dmic_num <= 4)
return dmic_num;
}
@@ -910,7 +934,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev)
/* disable cores */
if (chip)
- hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
+ hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask);
/* disable DSP */
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
@@ -992,9 +1016,15 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev)
dmic_num = hda_dmic_num;
switch (dmic_num) {
+ case 1:
+ dmic_str = "-1ch";
+ break;
case 2:
dmic_str = "-2ch";
break;
+ case 3:
+ dmic_str = "-3ch";
+ break;
case 4:
dmic_str = "-4ch";
break;
@@ -1179,7 +1209,13 @@ void hda_machine_select(struct snd_sof_dev *sdev)
mach = snd_soc_acpi_find_machine(desc->machines);
if (mach) {
- sof_pdata->tplg_filename = mach->sof_tplg_filename;
+ /*
+ * If tplg file name is overridden, use it instead of
+ * the one set in mach table
+ */
+ if (!sof_pdata->tplg_filename)
+ sof_pdata->tplg_filename = mach->sof_tplg_filename;
+
sof_pdata->machine = mach;
if (mach->link_mask) {
@@ -1207,3 +1243,4 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC);
MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
+MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index fe452f0d0ec7..1bc4dabdd394 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -246,6 +246,7 @@
/* Intel Vendor Specific Registers */
#define HDA_VS_INTEL_EM2 0x1030
#define HDA_VS_INTEL_EM2_L1SEN BIT(13)
+#define HDA_VS_INTEL_LTRP_GB_MASK 0x3F
/* HIPCI */
#define HDA_DSP_REG_HIPCI_BUSY BIT(31)
@@ -273,6 +274,7 @@
#define BXT_D0I3_DELAY 5000
#define FW_CL_STREAM_NUMBER 0x1
+#define HDA_FW_BOOT_ATTEMPTS 3
/* ADSPCS - Audio DSP Control & Status */
@@ -304,9 +306,6 @@
#define HDA_DSP_ADSPCS_CPA_SHIFT 24
#define HDA_DSP_ADSPCS_CPA_MASK(cm) ((cm) << HDA_DSP_ADSPCS_CPA_SHIFT)
-/* Mask for a given core index, c = 0.. number of supported cores - 1 */
-#define HDA_DSP_CORE_MASK(c) BIT(c)
-
/*
* Mask for a given number of cores
* nc = number of supported cores
@@ -418,6 +417,7 @@ enum sof_hda_D0_substate {
/* represents DSP HDA controller frontend - i.e. host facing control */
struct sof_intel_hda_dev {
+ int boot_iteration;
struct hda_bus hbus;
@@ -546,6 +546,9 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
struct hdac_ext_stream *stream,
struct snd_dma_buffer *dmab,
struct snd_pcm_hw_params *params);
+int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream,
+ struct snd_dma_buffer *dmab,
+ struct snd_pcm_hw_params *params);
int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
struct hdac_ext_stream *stream, int cmd);
irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context);
@@ -608,6 +611,7 @@ int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir);
* DSP Code loader.
*/
int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev);
+int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev);
int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev);
/* pre and post fw run ops */
@@ -728,12 +732,14 @@ extern struct snd_soc_dai_driver skl_dai[];
*/
extern const struct snd_sof_dsp_ops sof_apl_ops;
extern const struct snd_sof_dsp_ops sof_cnl_ops;
+extern const struct snd_sof_dsp_ops sof_tgl_ops;
extern const struct sof_intel_dsp_desc apl_chip_info;
extern const struct sof_intel_dsp_desc cnl_chip_info;
extern const struct sof_intel_dsp_desc skl_chip_info;
extern const struct sof_intel_dsp_desc icl_chip_info;
extern const struct sof_intel_dsp_desc tgl_chip_info;
+extern const struct sof_intel_dsp_desc tglh_chip_info;
extern const struct sof_intel_dsp_desc ehl_chip_info;
extern const struct sof_intel_dsp_desc jsl_chip_info;
diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h
index 6fe8b004b50e..1e0afb5c8720 100644
--- a/sound/soc/sof/intel/shim.h
+++ b/sound/soc/sof/intel/shim.h
@@ -154,7 +154,7 @@
/* DSP hardware descriptor */
struct sof_intel_dsp_desc {
int cores_num;
- int cores_mask;
+ int host_managed_cores_mask;
int init_core_mask; /* cores available after fw boot */
int ipc_req;
int ipc_req_mask;
diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
new file mode 100644
index 000000000000..0278b67de1ec
--- /dev/null
+++ b/sound/soc/sof/intel/tgl.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// Copyright(c) 2020 Intel Corporation. All rights reserved.
+//
+// Authors: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+//
+
+/*
+ * Hardware interface for audio DSP on Tigerlake.
+ */
+
+#include "../ops.h"
+#include "hda.h"
+#include "hda-ipc.h"
+#include "../sof-audio.h"
+
+static const struct snd_sof_debugfs_map tgl_dsp_debugfs[] = {
+ {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
+ {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
+ {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
+};
+
+/* Tigerlake ops */
+const struct snd_sof_dsp_ops sof_tgl_ops = {
+ /* probe and remove */
+ .probe = hda_dsp_probe,
+ .remove = hda_dsp_remove,
+
+ /* Register IO */
+ .write = sof_io_write,
+ .read = sof_io_read,
+ .write64 = sof_io_write64,
+ .read64 = sof_io_read64,
+
+ /* Block IO */
+ .block_read = sof_block_read,
+ .block_write = sof_block_write,
+
+ /* doorbell */
+ .irq_thread = cnl_ipc_irq_thread,
+
+ /* ipc */
+ .send_msg = cnl_ipc_send_msg,
+ .fw_ready = sof_fw_ready,
+ .get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset,
+ .get_window_offset = hda_dsp_ipc_get_window_offset,
+
+ .ipc_msg_data = hda_ipc_msg_data,
+ .ipc_pcm_params = hda_ipc_pcm_params,
+
+ /* machine driver */
+ .machine_select = hda_machine_select,
+ .machine_register = sof_machine_register,
+ .machine_unregister = sof_machine_unregister,
+ .set_mach_params = hda_set_mach_params,
+
+ /* debug */
+ .debug_map = tgl_dsp_debugfs,
+ .debug_map_count = ARRAY_SIZE(tgl_dsp_debugfs),
+ .dbg_dump = hda_dsp_dump,
+ .ipc_dump = cnl_ipc_dump,
+
+ /* stream callbacks */
+ .pcm_open = hda_dsp_pcm_open,
+ .pcm_close = hda_dsp_pcm_close,
+ .pcm_hw_params = hda_dsp_pcm_hw_params,
+ .pcm_hw_free = hda_dsp_stream_hw_free,
+ .pcm_trigger = hda_dsp_pcm_trigger,
+ .pcm_pointer = hda_dsp_pcm_pointer,
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
+ /* probe callbacks */
+ .probe_assign = hda_probe_compr_assign,
+ .probe_free = hda_probe_compr_free,
+ .probe_set_params = hda_probe_compr_set_params,
+ .probe_trigger = hda_probe_compr_trigger,
+ .probe_pointer = hda_probe_compr_pointer,
+#endif
+
+ /* firmware loading */
+ .load_firmware = snd_sof_load_firmware_raw,
+
+ /* pre/post fw run */
+ .pre_fw_run = hda_dsp_pre_fw_run,
+ .post_fw_run = hda_dsp_post_fw_run,
+
+ /* dsp core power up/down */
+ .core_power_up = hda_dsp_enable_core,
+ .core_power_down = hda_dsp_core_reset_power_down,
+
+ /* firmware run */
+ .run = hda_dsp_cl_boot_firmware_iccmax,
+
+ /* trace callback */
+ .trace_init = hda_dsp_trace_init,
+ .trace_release = hda_dsp_trace_release,
+ .trace_trigger = hda_dsp_trace_trigger,
+
+ /* DAI drivers */
+ .drv = skl_dai,
+ .num_drv = SOF_SKL_NUM_DAIS,
+
+ /* PM */
+ .suspend = hda_dsp_suspend,
+ .resume = hda_dsp_resume,
+ .runtime_suspend = hda_dsp_runtime_suspend,
+ .runtime_resume = hda_dsp_runtime_resume,
+ .runtime_idle = hda_dsp_runtime_idle,
+ .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume,
+ .set_power_state = hda_dsp_set_power_state,
+
+ /* ALSA HW info flags */
+ .hw_info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
+
+ .arch_ops = &sof_xtensa_arch_ops,
+};
+EXPORT_SYMBOL_NS(sof_tgl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
+
+const struct sof_intel_dsp_desc tgl_chip_info = {
+ /* Tigerlake */
+ .cores_num = 4,
+ .init_core_mask = 1,
+ .host_managed_cores_mask = BIT(0),
+ .ipc_req = CNL_DSP_REG_HIPCIDR,
+ .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
+ .ipc_ack = CNL_DSP_REG_HIPCIDA,
+ .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
+ .ipc_ctl = CNL_DSP_REG_HIPCCTL,
+ .rom_init_timeout = 300,
+ .ssp_count = ICL_SSP_COUNT,
+ .ssp_base_offset = CNL_SSP_BASE_OFFSET,
+};
+EXPORT_SYMBOL_NS(tgl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
+
+const struct sof_intel_dsp_desc tglh_chip_info = {
+ /* Tigerlake-H */
+ .cores_num = 2,
+ .init_core_mask = 1,
+ .host_managed_cores_mask = BIT(0),
+ .ipc_req = CNL_DSP_REG_HIPCIDR,
+ .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
+ .ipc_ack = CNL_DSP_REG_HIPCIDA,
+ .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
+ .ipc_ctl = CNL_DSP_REG_HIPCCTL,
+ .rom_init_timeout = 300,
+ .ssp_count = ICL_SSP_COUNT,
+ .ssp_base_offset = CNL_SSP_BASE_OFFSET,
+};
+EXPORT_SYMBOL_NS(tglh_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);