Skip to content

Commit 2a93346

Browse files
ranj063plbossart
authored andcommitted
ASoC: SOF: harden the FW boot sequence for SKL+
It is recommended to attempt FW boot more than once to harden the FW boot sequence for SKL+ platforms. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
1 parent a11707b commit 2a93346

1 file changed

Lines changed: 26 additions & 25 deletions

File tree

sound/soc/sof/intel/hda-loader.c

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "../ops.h"
3333
#include "hda.h"
3434

35+
#define HDA_FW_BOOT_ATTEMPTS 3
36+
3537
static int cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
3638
unsigned int size, struct snd_dma_buffer *dmab,
3739
int direction)
@@ -312,55 +314,54 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
312314
{
313315
struct snd_sof_pdata *plat_data = dev_get_platdata(sdev->dev);
314316
struct firmware stripped_firmware;
315-
int ret, tag;
317+
int ret, tag, i;
316318

317319
stripped_firmware.data = plat_data->fw->data;
318320
stripped_firmware.size = plat_data->fw->size;
319321

320-
tag = cl_dsp_init(sdev, stripped_firmware.data,
321-
stripped_firmware.size);
322+
/* init for booting wait */
323+
init_waitqueue_head(&sdev->boot_wait);
324+
sdev->boot_complete = false;
322325

323-
/* retry enabling core and ROM load. seemed to help */
324-
if (tag < 0) {
326+
/* try attempting fw boot a few times before giving up */
327+
for (i = 0; i < HDA_FW_BOOT_ATTEMPTS; i++) {
325328
tag = cl_dsp_init(sdev, stripped_firmware.data,
326329
stripped_firmware.size);
330+
327331
if (tag <= 0) {
328332
dev_err(sdev->dev, "Error code=0x%x: FW status=0x%x\n",
329333
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
330334
HDA_DSP_SRAM_REG_ROM_ERROR),
331335
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
332336
HDA_DSP_SRAM_REG_ROM_STATUS));
333-
dev_err(sdev->dev, "Core En/ROM load fail:%d\n",
334-
tag);
337+
dev_err(sdev->dev, "iteration %d of Core En/ROM load fail:%d\n",
338+
i, tag);
335339
ret = tag;
336-
goto irq_err;
340+
continue;
337341
}
338-
}
339-
340-
/* init for booting wait */
341-
init_waitqueue_head(&sdev->boot_wait);
342-
sdev->boot_complete = false;
343342

344-
/* at this point DSP ROM has been initialized and should be ready for
345-
* code loading and firmware boot
346-
*/
347-
ret = cl_copy_fw(sdev, tag);
348-
if (ret < 0) {
349-
dev_err(sdev->dev, "error: load fw failed err: %d\n", ret);
350-
goto irq_err;
351-
}
343+
/* at this point DSP ROM has been initialized and
344+
* should be ready for code loading and firmware boot
345+
*/
346+
ret = cl_copy_fw(sdev, tag);
347+
if (ret < 0) {
348+
dev_err(sdev->dev, "error: iteration %d of load fw failed err: %d\n",
349+
i, ret);
350+
continue;
351+
}
352352

353-
dev_dbg(sdev->dev, "Firmware download successful, booting...\n");
354353

355-
return ret;
354+
dev_dbg(sdev->dev, "Firmware download successful, booting...\n");
355+
return ret;
356+
}
356357

357-
irq_err:
358358
hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX);
359359

360360
/* disable DSP */
361361
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
362362
SOF_HDA_PPCTL_GPROCEN, 0);
363-
dev_err(sdev->dev, "error: load fw failed err: %d\n", ret);
363+
dev_err(sdev->dev, "error: load fw failed after %d attempts with err: %d\n",
364+
HDA_FW_BOOT_ATTEMPTS, ret);
364365
return ret;
365366
}
366367

0 commit comments

Comments
 (0)