ASoC: SOF: Add 'non_recoverable' parameter to snd_sof_dsp_panic()

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>
This commit is contained in:
Peter Ujfalusi 2021-12-23 13:36:13 +02:00 committed by Mark Brown
parent 12b401f4de
commit b2b10aa79f
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0
9 changed files with 66 additions and 20 deletions

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);

View 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");

View 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);

View 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