From 05225575e4731ccc4306d89aaa8e849caec82d54 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 10 Jun 2021 17:52:53 +0800 Subject: [PATCH 1/4] ASoC: SOF: add _D3_PERSISTENT flag to fw_ready message Add a bit definition to the fw_ready message, to denote if the FW supports the IMR (Isolated Memory Region) restoring feature. If the bit is set, the driver can skip downloading the firmware again during system resume or runtime resume. Bump the ABI version to 3.19 to make it aligned with FW side. Signed-off-by: Keyon Jie --- include/sound/sof/info.h | 1 + include/uapi/sound/sof/abi.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/sound/sof/info.h b/include/sound/sof/info.h index 0b7101aef596d3..65e86e4e9fd8e7 100644 --- a/include/sound/sof/info.h +++ b/include/sound/sof/info.h @@ -25,6 +25,7 @@ #define SOF_IPC_INFO_LOCKS BIT(1) #define SOF_IPC_INFO_LOCKSV BIT(2) #define SOF_IPC_INFO_GDB BIT(3) +#define SOF_IPC_INFO_D3_PERSISTENT BIT(4) /* extended data types that can be appended onto end of sof_ipc_fw_ready */ enum sof_ipc_ext_data { diff --git a/include/uapi/sound/sof/abi.h b/include/uapi/sound/sof/abi.h index fe2cfae94b45fd..f4232d289a22b5 100644 --- a/include/uapi/sound/sof/abi.h +++ b/include/uapi/sound/sof/abi.h @@ -26,7 +26,7 @@ /* SOF ABI version major, minor and patch numbers */ #define SOF_ABI_MAJOR 3 -#define SOF_ABI_MINOR 18 +#define SOF_ABI_MINOR 19 #define SOF_ABI_PATCH 0 /* SOF ABI version number. Format within 32bit word is MMmmmppp */ From 92faaccf1a9d14a3dd221b97ae45f6aa0843d05c Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 17 Jun 2021 10:41:48 +0800 Subject: [PATCH 2/4] ASoC: SOF: Intel: hda-loader: split SSP and SDW resume functions Move the SSP slave mode set function to the hda_set_ssps_slave() helper and the SDW wakeen interrupt enabling to the hda_sdw_resume() helper, then these helpers can be shared to different callers later. Signed-off-by: Keyon Jie --- sound/soc/sof/intel/hda-loader.c | 67 +++++++++++++++++++------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index b7007cbd415af5..2860569cb19a23 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -25,6 +25,44 @@ #define HDA_CL_STREAM_FORMAT 0x40 +static void hda_ssp_resume(struct snd_sof_dev *sdev) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + int i; + + /* DSP is powered up, set all SSPs to slave mode */ + for (i = 0; i < chip->ssp_count; i++) { + snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, + chip->ssp_base_offset + + i * SSP_DEV_MEM_SIZE + + SSP_SSC1_OFFSET, + SSP_SET_SLAVE, + SSP_SET_SLAVE); + } +} + +static void hda_sdw_resume(struct snd_sof_dev *sdev) +{ + /* + * When a SoundWire link is in clock stop state, a secondary + * device may trigger in-band wakes for events such as jack + * insertion or acoustic event detection. This event will lead + * to a WAKEEN interrupt, handled by the PCI device and routed + * to PME if the PCI device is in D3. The resume function in + * audio PCI driver will be invoked by ACPI for PME event and + * initialize the device and process WAKEEN interrupt. + * + * The WAKEEN interrupt should be processed ASAP to prevent an + * interrupt flood, otherwise other interrupts, such IPC, + * cannot work normally. The WAKEEN is handled after the ROM + * is initialized successfully, which ensures power rails are + * enabled before accessing the SoundWire SHIM registers + */ + if (!sdev->first_boot) + hda_sdw_process_wakeen(sdev); +} + 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) @@ -91,7 +129,6 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) char *dump_msg; u32 flags, j; int ret; - int i; /* step 1: power up corex */ ret = hda_dsp_enable_core(sdev, chip->host_managed_cores_mask); @@ -101,15 +138,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag) goto err; } - /* DSP is powered up, set all SSPs to slave mode */ - for (i = 0; i < chip->ssp_count; i++) { - snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, - chip->ssp_base_offset - + i * SSP_DEV_MEM_SIZE - + SSP_SSC1_OFFSET, - SSP_SET_SLAVE, - SSP_SET_SLAVE); - } + hda_ssp_resume(sdev); /* step 2: purge FW request */ snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req, @@ -398,23 +427,7 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) goto cleanup; } - /* - * When a SoundWire link is in clock stop state, a Slave - * device may trigger in-band wakes for events such as jack - * insertion or acoustic event detection. This event will lead - * to a WAKEEN interrupt, handled by the PCI device and routed - * to PME if the PCI device is in D3. The resume function in - * audio PCI driver will be invoked by ACPI for PME event and - * initialize the device and process WAKEEN interrupt. - * - * The WAKEEN interrupt should be processed ASAP to prevent an - * interrupt flood, otherwise other interrupts, such IPC, - * cannot work normally. The WAKEEN is handled after the ROM - * is initialized successfully, which ensures power rails are - * enabled before accessing the SoundWire SHIM registers - */ - if (!sdev->first_boot) - hda_sdw_process_wakeen(sdev); + hda_sdw_resume(sdev); /* * Set the boot_iteration to the last attempt, indicating that the From 6c8a7ba8cb8710e445e20edc65ff2d3c63c9aad8 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 10 Jun 2021 18:33:43 +0800 Subject: [PATCH 3/4] ASoC: SOF: Intel: hda-loader: add IMR restore support If the firmware declares the IMR restore feature, we only need to do a simple powering up for resuming from the suspended state, no firmware re-downloading needed. Add a helper hda_dsp_boot_imr() for this simple DSP rebooting, and use it when it is available. Signed-off-by: Keyon Jie --- sound/soc/sof/intel/hda-loader.c | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 2860569cb19a23..e03c1f4dc7f99d 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -374,6 +374,37 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev) return ret; } +static int hda_dsp_boot_imr(struct snd_sof_dev *sdev) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + unsigned long mask; + u32 j; + int ret; + + /* power up & unstall/run the cores to run the firmware */ + ret = hda_dsp_enable_core(sdev, chip->init_core_mask); + if (ret < 0) { + dev_err(sdev->dev, "dsp core start failed %d\n", ret); + return -EIO; + } + + /* set enabled cores mask and increment ref count for cores in init_core_mask */ + sdev->enabled_cores_mask |= chip->init_core_mask; + mask = sdev->enabled_cores_mask; + for_each_set_bit(j, &mask, SOF_MAX_DSP_NUM_CORES) + sdev->dsp_core_ref_count[j]++; + + hda_ssp_resume(sdev); + + /* enable IPC interrupts */ + hda_dsp_ipc_int_enable(sdev); + + hda_sdw_resume(sdev); + + return ret; +} + int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) { struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; @@ -384,6 +415,12 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) struct firmware stripped_firmware; int ret, ret1, i; + if ((sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) && + !sdev->first_boot) { + dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n"); + return hda_dsp_boot_imr(sdev); + } + chip_info = desc->chip_info; if (plat_data->fw->size <= plat_data->fw_offset) { From 34992b3d582bf00e9bbf224c90baa411bb96b667 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 16 Jun 2021 14:00:22 +0800 Subject: [PATCH 4/4] ASoC: SOF: add flag to disable IMR restore to sof_debug Add flag _IGNORE_D3_PERSISTENT to disable IMR restore feature to the sof_debug module parameter. The IMR restore feature will be enabled for all Intel cAVS platforms by default, but setting the flag _IGNORE_D3_PERSISTENT can help to disable the feature for debug purpose, to rule out any possible regression introduced by the change of not re-downloading firmware to the DSP at resuming from suspended state. Signed-off-by: Keyon Jie --- sound/soc/sof/intel/hda-loader.c | 2 ++ sound/soc/sof/sof-priv.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index e03c1f4dc7f99d..6a1bdcc9c25df1 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -21,6 +21,7 @@ #include #include "ext_manifest.h" #include "../ops.h" +#include "../sof-priv.h" #include "hda.h" #define HDA_CL_STREAM_FORMAT 0x40 @@ -416,6 +417,7 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) int ret, ret1, i; if ((sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) && + !(sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) && !sdev->first_boot) { dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n"); return hda_dsp_boot_imr(sdev); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 96fc06965db1c8..32ae88a2bb6dc0 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -35,6 +35,9 @@ * on primary core */ #define SOF_DBG_PRINT_ALL_DUMPS BIT(6) /* Print all ipc and dsp dumps */ +#define SOF_DBG_IGNORE_D3_PERSISTENT BIT(7) /* ignore the DSP D3 persistent capability + * and always do FW downloading at resume + */ /* Flag definitions used for controlling the DSP dump behavior */ #define SOF_DBG_DUMP_REGS BIT(0)