|
@@ -23,6 +23,7 @@
|
|
|
#include "../common/sst-dsp.h"
|
|
|
#include "../common/sst-dsp-priv.h"
|
|
|
#include "skl-sst-ipc.h"
|
|
|
+#include "skl-tplg-interface.h"
|
|
|
|
|
|
#define BXT_BASEFW_TIMEOUT 3000
|
|
|
#define BXT_INIT_TIMEOUT 500
|
|
@@ -40,11 +41,73 @@
|
|
|
#define BXT_INSTANCE_ID 0
|
|
|
#define BXT_BASE_FW_MODULE_ID 0
|
|
|
|
|
|
+#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
|
|
|
+
|
|
|
static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
|
|
|
{
|
|
|
return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
|
|
|
}
|
|
|
|
|
|
+static int
|
|
|
+bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo)
|
|
|
+{
|
|
|
+ struct snd_dma_buffer dmab;
|
|
|
+ struct skl_sst *skl = ctx->thread_context;
|
|
|
+ const struct firmware *fw = NULL;
|
|
|
+ struct firmware stripped_fw;
|
|
|
+ int ret = 0, i, dma_id, stream_tag;
|
|
|
+
|
|
|
+ /* library indices start from 1 to N. 0 represents base FW */
|
|
|
+ for (i = 1; i < minfo->lib_count; i++) {
|
|
|
+ ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev);
|
|
|
+ if (ret < 0) {
|
|
|
+ dev_err(ctx->dev, "Request lib %s failed:%d\n",
|
|
|
+ minfo->lib[i].name, ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (skl->is_first_boot) {
|
|
|
+ ret = snd_skl_parse_uuids(ctx, fw,
|
|
|
+ BXT_ADSP_FW_BIN_HDR_OFFSET, i);
|
|
|
+ if (ret < 0)
|
|
|
+ goto load_library_failed;
|
|
|
+ }
|
|
|
+
|
|
|
+ stripped_fw.data = fw->data;
|
|
|
+ stripped_fw.size = fw->size;
|
|
|
+ skl_dsp_strip_extended_manifest(&stripped_fw);
|
|
|
+
|
|
|
+ stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
|
|
|
+ stripped_fw.size, &dmab);
|
|
|
+ if (stream_tag <= 0) {
|
|
|
+ dev_err(ctx->dev, "Lib prepare DMA err: %x\n",
|
|
|
+ stream_tag);
|
|
|
+ ret = stream_tag;
|
|
|
+ goto load_library_failed;
|
|
|
+ }
|
|
|
+
|
|
|
+ dma_id = stream_tag - 1;
|
|
|
+ memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
|
|
|
+
|
|
|
+ ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
|
|
|
+ ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i);
|
|
|
+ if (ret < 0)
|
|
|
+ dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
|
|
|
+ minfo->lib[i].name, ret);
|
|
|
+
|
|
|
+ ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
|
|
|
+ ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
|
|
|
+ release_firmware(fw);
|
|
|
+ fw = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+
|
|
|
+load_library_failed:
|
|
|
+ release_firmware(fw);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* First boot sequence has some extra steps. Core 0 waits for power
|
|
|
* status on core 1, so power up core 1 also momentarily, keep it in
|
|
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
|
|
|
-
|
|
|
static int bxt_load_base_firmware(struct sst_dsp *ctx)
|
|
|
{
|
|
|
struct firmware stripped_fw;
|
|
@@ -233,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
|
|
|
int ret;
|
|
|
struct skl_ipc_dxstate_info dx;
|
|
|
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
|
|
|
+ struct skl_dfw_manifest *minfo = &skl->manifest;
|
|
|
|
|
|
if (skl->fw_loaded == false) {
|
|
|
skl->boot_complete = false;
|
|
|
ret = bxt_load_base_firmware(ctx);
|
|
|
- if (ret < 0)
|
|
|
+ if (ret < 0) {
|
|
|
dev_err(ctx->dev, "reload fw failed: %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (minfo->lib_count > 1) {
|
|
|
+ ret = bxt_load_library(ctx, minfo);
|
|
|
+ if (ret < 0) {
|
|
|
+ dev_err(ctx->dev, "reload libs failed: %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -344,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = {
|
|
|
.set_state_D3 = bxt_set_dsp_D3,
|
|
|
.load_fw = bxt_load_base_firmware,
|
|
|
.get_fw_errcode = bxt_get_errorcode,
|
|
|
+ .load_library = bxt_load_library,
|
|
|
};
|
|
|
|
|
|
static struct sst_ops skl_ops = {
|
|
@@ -422,6 +495,13 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
|
|
|
|
|
|
skl_dsp_init_core_state(sst);
|
|
|
|
|
|
+ if (ctx->manifest.lib_count > 1) {
|
|
|
+ ret = sst->fw_ops.load_library(sst, &ctx->manifest);
|
|
|
+ if (ret < 0) {
|
|
|
+ dev_err(dev, "Load Library failed : %x", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
ctx->is_first_boot = false;
|
|
|
|
|
|
return 0;
|