Commit b6726009 authored by Sodhi, VunnyX's avatar Sodhi, VunnyX Committed by Mark Brown

ASoC: Intel: Skylake: Add loadable module support on KBL platform

Kabylake platform expects modules in a library manifest. After loading
base firmware library manifest is loaded using load library IPC. This is
followed by module load using load multiple modules IPC.
Signed-off-by: default avatarSodhi, VunnyX <vunnyx.sodhi@intel.com>
Signed-off-by: default avatarG Kranthi <gudishax.kranthikumar@intel.com>
Signed-off-by: default avatarSubhransu S. Prusty <subhransu.s.prusty@intel.com>
Acked-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 100e7f39
...@@ -427,6 +427,7 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, ...@@ -427,6 +427,7 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
case IPC_GLB_LOAD_MULTIPLE_MODS: case IPC_GLB_LOAD_MULTIPLE_MODS:
case IPC_GLB_LOAD_LIBRARY:
skl->mod_load_complete = true; skl->mod_load_complete = true;
skl->mod_load_status = true; skl->mod_load_status = true;
wake_up(&skl->mod_load_wait); wake_up(&skl->mod_load_wait);
...@@ -443,6 +444,7 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, ...@@ -443,6 +444,7 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
case IPC_GLB_LOAD_MULTIPLE_MODS: case IPC_GLB_LOAD_MULTIPLE_MODS:
case IPC_GLB_LOAD_LIBRARY:
skl->mod_load_complete = true; skl->mod_load_complete = true;
skl->mod_load_status = false; skl->mod_load_status = false;
wake_up(&skl->mod_load_wait); wake_up(&skl->mod_load_wait);
......
...@@ -179,6 +179,18 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) ...@@ -179,6 +179,18 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
dev_err(ctx->dev, "unable to load firmware\n"); dev_err(ctx->dev, "unable to load firmware\n");
return ret; return ret;
} }
/* load libs as they are also lost on D3 */
if (skl->lib_count > 1) {
ret = ctx->fw_ops.load_library(ctx, skl->lib_info,
skl->lib_count);
if (ret < 0) {
dev_err(ctx->dev, "reload libs failed: %d\n",
ret);
return ret;
}
}
} }
/* /*
...@@ -204,7 +216,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) ...@@ -204,7 +216,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
skl->cores.state[core_id] = SKL_DSP_RUNNING; skl->cores.state[core_id] = SKL_DSP_RUNNING;
return ret; return 0;
} }
static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
...@@ -335,13 +347,17 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, ...@@ -335,13 +347,17 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data,
if (bytes_left < 0) if (bytes_left < 0)
return bytes_left; return bytes_left;
if (is_module) { /* load module */ /* check is_module flag to load module or library */
if (is_module)
ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id); ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id);
else
ret = skl_sst_ipc_load_library(&skl->ipc, 0, table_id, false);
if (ret < 0) { if (ret < 0) {
dev_err(ctx->dev, "Failed to Load module: %d\n", ret); dev_err(ctx->dev, "Failed to Load %s with err %d\n",
is_module ? "module" : "lib", ret);
goto out; goto out;
} }
}
/* /*
* if bytes_left > 0 then wait for BDL complete interrupt and * if bytes_left > 0 then wait for BDL complete interrupt and
...@@ -373,6 +389,32 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, ...@@ -373,6 +389,32 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data,
return ret; return ret;
} }
static int
kbl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
{
struct skl_sst *skl = ctx->thread_context;
struct firmware stripped_fw;
int ret, i;
/* library indices start from 1 to N. 0 represents base FW */
for (i = 1; i < lib_count; i++) {
ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw,
SKL_ADSP_FW_BIN_HDR_OFFSET, i);
if (ret < 0)
goto load_library_failed;
ret = skl_transfer_module(ctx, stripped_fw.data,
stripped_fw.size, 0, i, false);
if (ret < 0)
goto load_library_failed;
}
return 0;
load_library_failed:
skl_release_library(linfo, lib_count);
return ret;
}
static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid) static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
{ {
struct skl_module_table *module_entry = NULL; struct skl_module_table *module_entry = NULL;
...@@ -475,6 +517,7 @@ static struct skl_dsp_fw_ops kbl_fw_ops = { ...@@ -475,6 +517,7 @@ static struct skl_dsp_fw_ops kbl_fw_ops = {
.set_state_D3 = skl_set_dsp_D3, .set_state_D3 = skl_set_dsp_D3,
.load_fw = skl_load_base_firmware, .load_fw = skl_load_base_firmware,
.get_fw_errcode = skl_get_errorcode, .get_fw_errcode = skl_get_errorcode,
.load_library = kbl_load_library,
.load_mod = skl_load_module, .load_mod = skl_load_module,
.unload_mod = skl_unload_module, .unload_mod = skl_unload_module,
}; };
...@@ -554,6 +597,15 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) ...@@ -554,6 +597,15 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
} }
skl_dsp_init_core_state(sst); skl_dsp_init_core_state(sst);
if (ctx->lib_count > 1) {
ret = sst->fw_ops.load_library(sst, ctx->lib_info,
ctx->lib_count);
if (ret < 0) {
dev_err(dev, "Load Library failed : %x\n", ret);
return ret;
}
}
ctx->is_first_boot = false; ctx->is_first_boot = false;
return 0; return 0;
......
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