ASoC: Intel: Allow for ROM init retry on CNL platforms
authorCezary Rojewski <cezary.rojewski@intel.com>
Thu, 5 Mar 2020 14:53:13 +0000 (15:53 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 10 Mar 2020 17:44:28 +0000 (17:44 +0000)
Due to unconditional initial timeouts, firmware may fail to load during
its initialization. This issue cannot be resolved on driver side as it
is caused by external sources such as CSME but has to be accounted for
nonetheless.

Fixes: cb6a55284629 ("ASoC: Intel: cnl: Add sst library functions for cnl platform")
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200305145314.32579-7-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/skylake/bxt-sst.c
sound/soc/intel/skylake/cnl-sst.c
sound/soc/intel/skylake/skl-sst-dsp.h

index 92a82e6b5fe621e8a1e294b77fa28a76c044e4cf..cdafade8abd67222ae11e3b1900c66edf71d63cf 100644 (file)
@@ -38,8 +38,6 @@
 /* Delay before scheduling D0i3 entry */
 #define BXT_D0I3_DELAY 5000
 
-#define BXT_FW_ROM_INIT_RETRY 3
-
 static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
 {
         return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
index 4f64f097e9ae36a7248a1b961760b6a779365f11..060e47ae339149f760f0b4178ee5dbb157d4575f 100644 (file)
@@ -109,7 +109,7 @@ static int cnl_load_base_firmware(struct sst_dsp *ctx)
 {
        struct firmware stripped_fw;
        struct skl_dev *cnl = ctx->thread_context;
-       int ret;
+       int ret, i;
 
        if (!ctx->fw) {
                ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
@@ -131,12 +131,16 @@ static int cnl_load_base_firmware(struct sst_dsp *ctx)
        stripped_fw.size = ctx->fw->size;
        skl_dsp_strip_extended_manifest(&stripped_fw);
 
-       ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
-       if (ret < 0) {
-               dev_err(ctx->dev, "prepare firmware failed: %d\n", ret);
-               goto cnl_load_base_firmware_failed;
+       for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) {
+               ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
+               if (!ret)
+                       break;
+               dev_dbg(ctx->dev, "prepare firmware failed: %d\n", ret);
        }
 
+       if (ret < 0)
+               goto cnl_load_base_firmware_failed;
+
        ret = sst_transfer_fw_host_dma(ctx);
        if (ret < 0) {
                dev_err(ctx->dev, "transfer firmware failed: %d\n", ret);
@@ -158,6 +162,7 @@ static int cnl_load_base_firmware(struct sst_dsp *ctx)
        return 0;
 
 cnl_load_base_firmware_failed:
+       dev_err(ctx->dev, "firmware load failed: %d\n", ret);
        release_firmware(ctx->fw);
        ctx->fw = NULL;
 
index cdfec0fca5773d36f4db12e0e4217fbafdcb1a3e..067d1ea11cde4f56dfea18108b7846f960a3915c 100644 (file)
@@ -67,6 +67,7 @@ struct skl_dev;
 
 #define SKL_FW_INIT                    0x1
 #define SKL_FW_RFW_START               0xf
+#define BXT_FW_ROM_INIT_RETRY          3
 
 #define SKL_ADSPIC_IPC                 1
 #define SKL_ADSPIS_IPC                 1