aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <[email protected]>2022-07-12 16:10:05 +0100
committerMark Brown <[email protected]>2022-07-12 16:10:05 +0100
commit67e1b7700cb9cb5ca0cbdb2137533568b427e541 (patch)
tree3923d4a0f915d2516662e40e19baeb0ba12b63eb
parent98418a08a20d3a72e14d88ccb3a48d0bf961ab6a (diff)
parent57724db17a946476f11c1b1be9750bc0cf877adc (diff)
ASoC: SOF: Intel: hda: Use cold/purge boot after firmware crash
Merge series from Peter Ujfalusi <[email protected]>: In case of a firmware crash we force the DSP to be powered down and rebooted. To make sure that the next boot is going to be clean, force the boot process to skip the IMR booting and re-download the firmware.
-rw-r--r--sound/soc/sof/intel/hda-dsp.c7
-rw-r--r--sound/soc/sof/intel/hda-loader.c10
-rw-r--r--sound/soc/sof/intel/hda.h1
3 files changed, 14 insertions, 4 deletions
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 2afaee91b982..eddfd77ad90f 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -617,6 +617,13 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
#endif
int ret, j;
+ /*
+ * The memory used for IMR boot loses its content in deeper than S3 state
+ * We must not try IMR boot on next power up (as it will fail).
+ */
+ if (sdev->system_suspend_target > SOF_SUSPEND_S3)
+ hda->skip_imr_boot = true;
+
hda_sdw_int_enable(sdev, false);
/* disable IPC interrupts */
diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
index 819b3b08c655..eb22eb3f6fee 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -395,8 +395,7 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
struct snd_dma_buffer dmab;
int ret, ret1, i;
- if (sdev->system_suspend_target < SOF_SUSPEND_S4 &&
- hda->imrboot_supported && !sdev->first_boot) {
+ if (hda->imrboot_supported && !sdev->first_boot && !hda->skip_imr_boot) {
dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n");
hda->boot_iteration = 0;
ret = hda_dsp_boot_imr(sdev);
@@ -480,11 +479,14 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
*/
hda->boot_iteration = HDA_FW_BOOT_ATTEMPTS;
ret = hda_cl_copy_fw(sdev, hext_stream);
- if (!ret)
+ if (!ret) {
dev_dbg(sdev->dev, "Firmware download successful, booting...\n");
- else
+ hda->skip_imr_boot = false;
+ } else {
snd_sof_dsp_dbg_dump(sdev, "Firmware download failed",
SOF_DBG_DUMP_PCI | SOF_DBG_DUMP_MBOX);
+ hda->skip_imr_boot = true;
+ }
cleanup:
/*
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index dc713c20ba1d..2b4d23af6054 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -419,6 +419,7 @@ enum sof_hda_D0_substate {
/* represents DSP HDA controller frontend - i.e. host facing control */
struct sof_intel_hda_dev {
bool imrboot_supported;
+ bool skip_imr_boot;
int boot_iteration;