ASoC: SOF: Add 'non_recoverable' parameter to snd_sof_dsp_panic()
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Thu, 23 Dec 2021 11:36:13 +0000 (13:36 +0200)
committerMark Brown <broonie@kernel.org>
Thu, 23 Dec 2021 13:38:13 +0000 (13:38 +0000)
Some platforms use retries during firmware boot to overcome DSP startup
issues.
In these cases we might receive a DSP panic message which should not be
treated as fatal if it happens during boot.

Pass this information to snd_sof_dsp_panic() and omit the panic print if
it is not fatal or the user does not want to see all dumps.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20211223113628.18582-6-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/imx/imx8.c
sound/soc/sof/imx/imx8m.c
sound/soc/sof/intel/atom.c
sound/soc/sof/intel/bdw.c
sound/soc/sof/intel/cnl.c
sound/soc/sof/intel/hda-ipc.c
sound/soc/sof/intel/hda-loader.c
sound/soc/sof/ops.c
sound/soc/sof/ops.h

index 099b435..f6baecb 100644 (file)
@@ -97,7 +97,7 @@ static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc)
 
        /* Check to see if the message is a panic code (0x0dead***) */
        if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC)
-               snd_sof_dsp_panic(priv->sdev, p);
+               snd_sof_dsp_panic(priv->sdev, p, true);
        else
                snd_sof_ipc_msgs_rx(priv->sdev);
 }
index c026cae..788e77b 100644 (file)
@@ -90,7 +90,7 @@ static void imx8m_dsp_handle_request(struct imx_dsp_ipc *ipc)
 
        /* Check to see if the message is a panic code (0x0dead***) */
        if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC)
-               snd_sof_dsp_panic(priv->sdev, p);
+               snd_sof_dsp_panic(priv->sdev, p, true);
        else
                snd_sof_ipc_msgs_rx(priv->sdev);
 }
index 5aa064b..bcb2eb2 100644 (file)
@@ -165,8 +165,8 @@ irqreturn_t atom_irq_thread(int irq, void *context)
 
                /* Handle messages from DSP Core */
                if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
-                       snd_sof_dsp_panic(sdev, PANIC_OFFSET(ipcd) +
-                                         MBOX_OFFSET);
+                       snd_sof_dsp_panic(sdev, PANIC_OFFSET(ipcd) + MBOX_OFFSET,
+                                         true);
                } else {
                        snd_sof_ipc_msgs_rx(sdev);
                }
index 1121711..10c9a0b 100644 (file)
@@ -344,8 +344,8 @@ static irqreturn_t bdw_irq_thread(int irq, void *context)
 
                /* Handle messages from DSP Core */
                if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
-                       snd_sof_dsp_panic(sdev, BDW_PANIC_OFFSET(ipcx) +
-                                         MBOX_OFFSET);
+                       snd_sof_dsp_panic(sdev, BDW_PANIC_OFFSET(ipcx) + MBOX_OFFSET,
+                                         true);
                } else {
                        snd_sof_ipc_msgs_rx(sdev);
                }
index 3da158d..e615125 100644 (file)
@@ -82,9 +82,24 @@ irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
                         msg, msg_ext);
 
                /* handle messages from DSP */
-               if ((hipctdr & SOF_IPC_PANIC_MAGIC_MASK) ==
-                  SOF_IPC_PANIC_MAGIC) {
-                       snd_sof_dsp_panic(sdev, HDA_DSP_PANIC_OFFSET(msg_ext));
+               if ((hipctdr & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
+                       struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+                       bool non_recoverable = true;
+
+                       /*
+                        * This is a PANIC message!
+                        *
+                        * If it is arriving during firmware boot and it is not
+                        * the last boot attempt then change the non_recoverable
+                        * to false as the DSP might be able to boot in the next
+                        * iteration(s)
+                        */
+                       if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS &&
+                           hda->boot_iteration < HDA_FW_BOOT_ATTEMPTS)
+                               non_recoverable = false;
+
+                       snd_sof_dsp_panic(sdev, HDA_DSP_PANIC_OFFSET(msg_ext),
+                                         non_recoverable);
                } else {
                        snd_sof_ipc_msgs_rx(sdev);
                }
index 2019087..f0cf801 100644 (file)
@@ -173,8 +173,23 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context)
 
                /* handle messages from DSP */
                if ((hipct & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
-                       /* this is a PANIC message !! */
-                       snd_sof_dsp_panic(sdev, HDA_DSP_PANIC_OFFSET(msg_ext));
+                       struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+                       bool non_recoverable = true;
+
+                       /*
+                        * This is a PANIC message!
+                        *
+                        * If it is arriving during firmware boot and it is not
+                        * the last boot attempt then change the non_recoverable
+                        * to false as the DSP might be able to boot in the next
+                        * iteration(s)
+                        */
+                       if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS &&
+                           hda->boot_iteration < HDA_FW_BOOT_ATTEMPTS)
+                               non_recoverable = false;
+
+                       snd_sof_dsp_panic(sdev, HDA_DSP_PANIC_OFFSET(msg_ext),
+                                         non_recoverable);
                } else {
                        /* normal message - process normally */
                        snd_sof_ipc_msgs_rx(sdev);
index 5f5f396..8ef16f1 100644 (file)
@@ -413,9 +413,13 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
                hda_sdw_process_wakeen(sdev);
 
        /*
-        * at this point DSP ROM has been initialized and
-        * should be ready for code loading and firmware boot
+        * Set the boot_iteration to the last attempt, indicating that the
+        * DSP ROM has been initialized and from this point there will be no
+        * retry done to boot.
+        *
+        * Continue with code loading and firmware boot
         */
+       hda->boot_iteration = HDA_FW_BOOT_ATTEMPTS;
        ret = cl_copy_fw(sdev, stream);
        if (!ret) {
                dev_dbg(sdev->dev, "Firmware download successful, booting...\n");
index 1d6a95a..9abf7a8 100644 (file)
@@ -142,7 +142,13 @@ void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar,
 }
 EXPORT_SYMBOL(snd_sof_dsp_update_bits_forced);
 
-void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset)
+/**
+ * snd_sof_dsp_panic - handle a received DSP panic message
+ * @sdev: Pointer to the device's sdev
+ * @offset: offset of panic information
+ * @non_recoverable: the panic is fatal, no recovery will be done by the caller
+ */
+void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset, bool non_recoverable)
 {
        /*
         * if DSP is not ready and the dsp_oops_offset is not yet set, use the
@@ -160,12 +166,18 @@ void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset)
                         "%s: dsp_oops_offset %zu differs from panic offset %u\n",
                         __func__, sdev->dsp_oops_offset, offset);
 
-       dev_err(sdev->dev, "DSP panic!\n");
+       /*
+        * Only print the panic information if we have non recoverable panic or
+        * if all dumps should be printed
+        */
+       if (non_recoverable || sof_debug_check_flag(SOF_DBG_PRINT_ALL_DUMPS)) {
+               dev_err(sdev->dev, "DSP panic!\n");
 
-       /* We want to see the DSP panic! */
-       sdev->dbg_dump_printed = false;
+               /* We want to see the DSP panic! */
+               sdev->dbg_dump_printed = false;
 
-       snd_sof_dsp_dbg_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX);
-       snd_sof_trace_notify_for_error(sdev);
+               snd_sof_dsp_dbg_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX);
+               snd_sof_trace_notify_for_error(sdev);
+       }
 }
 EXPORT_SYMBOL(snd_sof_dsp_panic);
index b0ffb2a..bca7d35 100644 (file)
@@ -643,5 +643,5 @@ int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset,
                              u32 mask, u32 target, u32 timeout_ms,
                              u32 interval_us);
 
-void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset);
+void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset, bool non_recoverable);
 #endif