|
32 | 32 | #include "../ops.h" |
33 | 33 | #include "hda.h" |
34 | 34 |
|
| 35 | +#define HDA_FW_BOOT_ATTEMPTS 3 |
| 36 | + |
35 | 37 | static int cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format, |
36 | 38 | unsigned int size, struct snd_dma_buffer *dmab, |
37 | 39 | int direction) |
@@ -312,55 +314,54 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) |
312 | 314 | { |
313 | 315 | struct snd_sof_pdata *plat_data = dev_get_platdata(sdev->dev); |
314 | 316 | struct firmware stripped_firmware; |
315 | | - int ret, tag; |
| 317 | + int ret, tag, i; |
316 | 318 |
|
317 | 319 | stripped_firmware.data = plat_data->fw->data; |
318 | 320 | stripped_firmware.size = plat_data->fw->size; |
319 | 321 |
|
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; |
322 | 325 |
|
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++) { |
325 | 328 | tag = cl_dsp_init(sdev, stripped_firmware.data, |
326 | 329 | stripped_firmware.size); |
| 330 | + |
327 | 331 | if (tag <= 0) { |
328 | 332 | dev_err(sdev->dev, "Error code=0x%x: FW status=0x%x\n", |
329 | 333 | snd_sof_dsp_read(sdev, HDA_DSP_BAR, |
330 | 334 | HDA_DSP_SRAM_REG_ROM_ERROR), |
331 | 335 | snd_sof_dsp_read(sdev, HDA_DSP_BAR, |
332 | 336 | 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); |
335 | 339 | ret = tag; |
336 | | - goto irq_err; |
| 340 | + continue; |
337 | 341 | } |
338 | | - } |
339 | | - |
340 | | - /* init for booting wait */ |
341 | | - init_waitqueue_head(&sdev->boot_wait); |
342 | | - sdev->boot_complete = false; |
343 | 342 |
|
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 | + } |
352 | 352 |
|
353 | | - dev_dbg(sdev->dev, "Firmware download successful, booting...\n"); |
354 | 353 |
|
355 | | - return ret; |
| 354 | + dev_dbg(sdev->dev, "Firmware download successful, booting...\n"); |
| 355 | + return ret; |
| 356 | + } |
356 | 357 |
|
357 | | -irq_err: |
358 | 358 | hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX); |
359 | 359 |
|
360 | 360 | /* disable DSP */ |
361 | 361 | snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, |
362 | 362 | 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); |
364 | 365 | return ret; |
365 | 366 | } |
366 | 367 |
|
|
0 commit comments