1414#include <sound/sof.h>
1515#include "ops.h"
1616
17+ #define FW_BOOT_RETRIES 5
18+
1719static int get_ext_windows (struct snd_sof_dev * sdev ,
1820 struct sof_ipc_ext_data_hdr * ext_hdr )
1921{
@@ -507,6 +509,7 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev)
507509{
508510 int ret ;
509511 int init_core_mask ;
512+ int i ;
510513
511514 init_waitqueue_head (& sdev -> boot_wait );
512515 sdev -> boot_complete = false;
@@ -532,25 +535,51 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev)
532535
533536 dev_dbg (sdev -> dev , "booting DSP firmware\n" );
534537
535- /* boot the firmware on the DSP */
536- ret = snd_sof_dsp_run (sdev );
537- if (ret < 0 ) {
538- dev_err (sdev -> dev , "error: failed to reset DSP\n" );
539- return ret ;
540- }
538+ for (i = 0 ; i < FW_BOOT_RETRIES ; i ++ ) {
539+ /* prepare the DSP for FW loading for subsequent tries */
540+ if (i > 0 ) {
541+ ret = snd_sof_dsp_reset (sdev );
542+ if (ret < 0 ) {
543+ dev_err (sdev -> dev , "error: failed to reset DSP\n" );
544+ return ret ;
545+ }
546+ }
547+
548+ /* boot the firmware on the DSP */
549+ ret = snd_sof_dsp_run (sdev );
550+ if (ret < 0 ) {
551+ if (i == FW_BOOT_RETRIES ) {
552+ dev_err (sdev -> dev , "error: failed to reset DSP\n" );
553+ return ret ;
554+ }
555+
556+ /* try again */
557+ continue ;
558+ }
559+
560+ init_core_mask = ret ;
561+
562+ /* now wait for the DSP to boot */
563+ ret = wait_event_timeout (sdev -> boot_wait , sdev -> boot_complete ,
564+ msecs_to_jiffies (sdev -> boot_timeout ));
565+ if (ret == 0 ) {
566+ if (i == FW_BOOT_RETRIES ) {
567+ dev_err (sdev -> dev ,
568+ "error: firmware boot failure after %d iterations\n" ,
569+ i );
570+ snd_sof_dsp_dbg_dump (sdev , SOF_DBG_REGS |
571+ SOF_DBG_MBOX |
572+ SOF_DBG_TEXT |
573+ SOF_DBG_PCI );
574+
575+ /* FW_READY msg ignored from now on */
576+ sdev -> boot_complete = true;
577+ return - EIO ;
578+ }
579+ }
541580
542- init_core_mask = ret ;
543-
544- /* now wait for the DSP to boot */
545- ret = wait_event_timeout (sdev -> boot_wait , sdev -> boot_complete ,
546- msecs_to_jiffies (sdev -> boot_timeout ));
547- if (ret == 0 ) {
548- dev_err (sdev -> dev , "error: firmware boot failure\n" );
549- snd_sof_dsp_dbg_dump (sdev , SOF_DBG_REGS | SOF_DBG_MBOX |
550- SOF_DBG_TEXT | SOF_DBG_PCI );
551- /* after this point FW_READY msg should be ignored */
552- sdev -> boot_complete = true;
553- return - EIO ;
581+ /* FW boot successful */
582+ break ;
554583 }
555584
556585 dev_info (sdev -> dev , "firmware boot complete\n" );
0 commit comments