diff options
Diffstat (limited to 'sound/soc/sof/intel')
-rw-r--r-- | sound/soc/sof/intel/Kconfig | 31 | ||||
-rw-r--r-- | sound/soc/sof/intel/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/sof/intel/apl.c | 2 | ||||
-rw-r--r-- | sound/soc/sof/intel/bdw.c | 2 | ||||
-rw-r--r-- | sound/soc/sof/intel/byt.c | 6 | ||||
-rw-r--r-- | sound/soc/sof/intel/cnl.c | 40 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-codec.c | 28 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-dsp.c | 20 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-ipc.h | 4 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-loader.c | 196 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-stream.c | 69 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.c | 47 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.h | 12 | ||||
-rw-r--r-- | sound/soc/sof/intel/shim.h | 2 | ||||
-rw-r--r-- | sound/soc/sof/intel/tgl.c | 153 |
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); |