Commit 31d648f0 authored by Jeeja KP's avatar Jeeja KP Committed by Mark Brown

ASoC: Intel: bxtn: Store the FW/Library context at boot

Store the DSP firmware/library at boot, so that for S3 to S0 transition
use the stored ctx for downloading the firmware to DSP memory.
Signed-off-by: default avatarJeeja KP <jeeja.kp@intel.com>
Acked-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b3ec72ac
...@@ -50,33 +50,47 @@ static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) ...@@ -50,33 +50,47 @@ static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
} }
static void sst_bxt_release_library(struct skl_lib_info *linfo, int lib_count)
{
int i;
for (i = 1; i < lib_count; i++) {
if (linfo[i].fw) {
release_firmware(linfo[i].fw);
linfo[i].fw = NULL;
}
}
}
static int static int
bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
{ {
struct snd_dma_buffer dmab; struct snd_dma_buffer dmab;
struct skl_sst *skl = ctx->thread_context; struct skl_sst *skl = ctx->thread_context;
const struct firmware *fw = NULL;
struct firmware stripped_fw; struct firmware stripped_fw;
int ret = 0, i, dma_id, stream_tag; int ret = 0, i, dma_id, stream_tag;
/* library indices start from 1 to N. 0 represents base FW */ /* library indices start from 1 to N. 0 represents base FW */
for (i = 1; i < lib_count; i++) { for (i = 1; i < lib_count; i++) {
ret = request_firmware(&fw, linfo[i].name, ctx->dev); if (linfo[i].fw == NULL) {
if (ret < 0) { ret = request_firmware(&linfo[i].fw, linfo[i].name,
dev_err(ctx->dev, "Request lib %s failed:%d\n", ctx->dev);
if (ret < 0) {
dev_err(ctx->dev, "Request lib %s failed:%d\n",
linfo[i].name, ret); linfo[i].name, ret);
return ret; goto load_library_failed;
}
} }
if (skl->is_first_boot) { if (skl->is_first_boot) {
ret = snd_skl_parse_uuids(ctx, fw, ret = snd_skl_parse_uuids(ctx, linfo[i].fw,
BXT_ADSP_FW_BIN_HDR_OFFSET, i); BXT_ADSP_FW_BIN_HDR_OFFSET, i);
if (ret < 0) if (ret < 0)
goto load_library_failed; goto load_library_failed;
} }
stripped_fw.data = fw->data; stripped_fw.data = linfo[i].fw->data;
stripped_fw.size = fw->size; stripped_fw.size = linfo[i].fw->size;
skl_dsp_strip_extended_manifest(&stripped_fw); skl_dsp_strip_extended_manifest(&stripped_fw);
stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
...@@ -99,14 +113,12 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) ...@@ -99,14 +113,12 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
release_firmware(fw);
fw = NULL;
} }
return ret; return ret;
load_library_failed: load_library_failed:
release_firmware(fw); sst_bxt_release_library(linfo, lib_count);
return ret; return ret;
} }
...@@ -208,16 +220,14 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx) ...@@ -208,16 +220,14 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
struct skl_sst *skl = ctx->thread_context; struct skl_sst *skl = ctx->thread_context;
int ret; int ret;
ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); if (ctx->fw == NULL) {
if (ret < 0) { ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
dev_err(ctx->dev, "Request firmware failed %d\n", ret); if (ret < 0) {
goto sst_load_base_firmware_failed; dev_err(ctx->dev, "Request firmware failed %d\n", ret);
return ret;
}
} }
/* check for extended manifest */
if (ctx->fw == NULL)
goto sst_load_base_firmware_failed;
/* prase uuids on first boot */ /* prase uuids on first boot */
if (skl->is_first_boot) { if (skl->is_first_boot) {
ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0); ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
...@@ -265,8 +275,11 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx) ...@@ -265,8 +275,11 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
} }
} }
return ret;
sst_load_base_firmware_failed: sst_load_base_firmware_failed:
release_firmware(ctx->fw); release_firmware(ctx->fw);
ctx->fw = NULL;
return ret; return ret;
} }
...@@ -635,6 +648,10 @@ EXPORT_SYMBOL_GPL(bxt_sst_init_fw); ...@@ -635,6 +648,10 @@ EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
{ {
sst_bxt_release_library(ctx->lib_info, ctx->lib_count);
if (ctx->dsp->fw)
release_firmware(ctx->dsp->fw);
skl_freeup_uuid_list(ctx); skl_freeup_uuid_list(ctx);
skl_ipc_free(&ctx->ipc); skl_ipc_free(&ctx->ipc);
ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment