[alsa-devel] [PATCH 0/6] ASoC: Intel: Skylake: Add loadable module support for
Module loading (which are not part of base firmware) is different for kbl platform compared to skl or bxtn. In kabylake library manifest contains the module information, so load the library to get the module information.
As a pre-work, common code which can be used for kabylake are moved to helper and arguments to few functions are modified to support module load for kabylake.
Separate dsp_fw_ops is registered and load library ops is added for kabylake.
G Kranthi (2): ASoC: Intel: Skylake: Move sst common initialization to a helper function ASoC: Intel: Skylake: Modify arguments to reuse module transfer function
Sodhi, VunnyX (1): ASoC: Intel: Skylake: Add loadable module support on KBL platform
Subhransu S. Prusty (3): ASoC: Intel: Skylake: Commonize library load ASoC: Intel: Skylake: Register dsp_fw_ops for kabylake ASoC: Intel: Skylake: Modify load_lib_ipc arguments for a nowait version
sound/soc/intel/skylake/bxt-sst.c | 68 +++--------------- sound/soc/intel/skylake/skl-messages.c | 2 +- sound/soc/intel/skylake/skl-sst-dsp.h | 13 +++- sound/soc/intel/skylake/skl-sst-ipc.c | 10 ++- sound/soc/intel/skylake/skl-sst-ipc.h | 2 +- sound/soc/intel/skylake/skl-sst-utils.c | 80 +++++++++++++++++++++ sound/soc/intel/skylake/skl-sst.c | 124 ++++++++++++++++++++++++-------- 7 files changed, 207 insertions(+), 92 deletions(-)
From: G Kranthi gudishax.kranthikumar@intel.com
Some skl sst context are not dependent of platform and initializing them independently for each platform can lead to errors. So optimize by moving them to a helper function and platform specific init code can call this.
Signed-off-by: G Kranthi gudishax.kranthikumar@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com --- sound/soc/intel/skylake/bxt-sst.c | 28 +++++-------------------- sound/soc/intel/skylake/skl-sst-dsp.h | 3 +++ sound/soc/intel/skylake/skl-sst-utils.c | 37 +++++++++++++++++++++++++++++++++ sound/soc/intel/skylake/skl-sst.c | 32 ++++++---------------------- 4 files changed, 51 insertions(+), 49 deletions(-)
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 600d95891996..c54f56c568e8 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -590,23 +590,14 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, struct sst_dsp *sst; int ret;
- skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); - if (skl == NULL) - return -ENOMEM; - - skl->dev = dev; - skl_dev.thread_context = skl; - INIT_LIST_HEAD(&skl->uuid_list); - - skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq); - if (!skl->dsp) { - dev_err(skl->dev, "skl_dsp_ctx_init failed\n"); - return -ENODEV; + ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev); + if (ret < 0) { + dev_err(skl->dev, "%s: no device\n", __func__); + return ret; }
+ skl = *dsp; sst = skl->dsp; - sst->fw_name = fw_name; - sst->dsp_ops = dsp_ops; sst->fw_ops = bxt_fw_ops; sst->addr.lpe = mmio_base; sst->addr.shim = mmio_base; @@ -614,24 +605,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
- INIT_LIST_HEAD(&sst->module_list); - ret = skl_ipc_init(dev, skl); - if (ret) - return ret; - /* set the D0i3 check */ skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;
skl->cores.count = 2; skl->boot_complete = false; init_waitqueue_head(&skl->boot_wait); - skl->is_first_boot = true; INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); skl->d0i3.state = SKL_DSP_D0I3_NONE;
- if (dsp) - *dsp = skl; - return 0; } EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 7229a12b4c94..c1f95e23933d 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h @@ -247,5 +247,8 @@ int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
int skl_dsp_strip_extended_manifest(struct firmware *fw); void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable); +int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, + struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, + struct sst_dsp_device *skl_dev);
#endif /*__SKL_SST_DSP_H__*/ diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index 6d5bff04bf65..a72152123c3c 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c @@ -361,3 +361,40 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw)
return 0; } + +int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, + struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, + struct sst_dsp_device *skl_dev) +{ + struct skl_sst *skl; + struct sst_dsp *sst; + int ret; + + skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); + if (skl == NULL) + return -ENOMEM; + + skl->dev = dev; + skl_dev->thread_context = skl; + INIT_LIST_HEAD(&skl->uuid_list); + skl->dsp = skl_dsp_ctx_init(dev, skl_dev, irq); + if (!skl->dsp) { + dev_err(skl->dev, "%s: no device\n", __func__); + return -ENODEV; + } + + sst = skl->dsp; + sst->fw_name = fw_name; + sst->dsp_ops = dsp_ops; + init_waitqueue_head(&skl->mod_load_wait); + INIT_LIST_HEAD(&sst->module_list); + ret = skl_ipc_init(dev, skl); + if (ret) + return ret; + + skl->is_first_boot = true; + if (dsp) + *dsp = skl; + + return ret; +} diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index 539529729e3f..4fdd503a837c 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -330,7 +330,6 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, int ret, bytes_left, curr_pos; struct skl_sst *skl = ctx->thread_context; skl->mod_load_complete = false; - init_waitqueue_head(&skl->mod_load_wait);
bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false); if (bytes_left < 0) @@ -489,43 +488,24 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, struct sst_dsp *sst; int ret;
- skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); - if (skl == NULL) - return -ENOMEM; - - skl->dev = dev; - skl_dev.thread_context = skl; - INIT_LIST_HEAD(&skl->uuid_list); - - skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq); - if (!skl->dsp) { - dev_err(skl->dev, "%s: no device\n", __func__); - return -ENODEV; + ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev); + if (ret < 0) { + dev_err(dev, "%s: no device\n", __func__); + return ret; }
+ skl = *dsp; sst = skl->dsp; - - sst->fw_name = fw_name; sst->addr.lpe = mmio_base; sst->addr.shim = mmio_base; sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
- INIT_LIST_HEAD(&sst->module_list); - sst->dsp_ops = dsp_ops; sst->fw_ops = skl_fw_ops;
- ret = skl_ipc_init(dev, skl); - if (ret) - return ret; - skl->cores.count = 2; - skl->is_first_boot = true; - - if (dsp) - *dsp = skl;
- return ret; + return 0; } EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
The patch
ASoC: Intel: Skylake: Move sst common initialization to a helper function
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 9fe9c71192832a1c63fb94120cb6c2541aca694f Mon Sep 17 00:00:00 2001
From: G Kranthi gudishax.kranthikumar@intel.com Date: Tue, 25 Apr 2017 12:18:19 +0530 Subject: [PATCH] ASoC: Intel: Skylake: Move sst common initialization to a helper function
Some skl sst context are not dependent of platform and initializing them independently for each platform can lead to errors. So optimize by moving them to a helper function and platform specific init code can call this.
Signed-off-by: G Kranthi gudishax.kranthikumar@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Acked-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/bxt-sst.c | 28 +++++-------------------- sound/soc/intel/skylake/skl-sst-dsp.h | 3 +++ sound/soc/intel/skylake/skl-sst-utils.c | 37 +++++++++++++++++++++++++++++++++ sound/soc/intel/skylake/skl-sst.c | 32 ++++++---------------------- 4 files changed, 51 insertions(+), 49 deletions(-)
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 268bdaec8042..2bf6ebe29f50 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -590,23 +590,14 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, struct sst_dsp *sst; int ret;
- skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); - if (skl == NULL) - return -ENOMEM; - - skl->dev = dev; - skl_dev.thread_context = skl; - INIT_LIST_HEAD(&skl->uuid_list); - - skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq); - if (!skl->dsp) { - dev_err(skl->dev, "skl_dsp_ctx_init failed\n"); - return -ENODEV; + ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev); + if (ret < 0) { + dev_err(skl->dev, "%s: no device\n", __func__); + return ret; }
+ skl = *dsp; sst = skl->dsp; - sst->fw_name = fw_name; - sst->dsp_ops = dsp_ops; sst->fw_ops = bxt_fw_ops; sst->addr.lpe = mmio_base; sst->addr.shim = mmio_base; @@ -614,24 +605,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
- INIT_LIST_HEAD(&sst->module_list); - ret = skl_ipc_init(dev, skl); - if (ret) - return ret; - /* set the D0i3 check */ skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;
skl->cores.count = 2; skl->boot_complete = false; init_waitqueue_head(&skl->boot_wait); - skl->is_first_boot = true; INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); skl->d0i3.state = SKL_DSP_D0I3_NONE;
- if (dsp) - *dsp = skl; - return 0; } EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 7229a12b4c94..c1f95e23933d 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h @@ -247,5 +247,8 @@ void skl_freeup_uuid_list(struct skl_sst *ctx);
int skl_dsp_strip_extended_manifest(struct firmware *fw); void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable); +int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, + struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, + struct sst_dsp_device *skl_dev);
#endif /*__SKL_SST_DSP_H__*/ diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index 6d5bff04bf65..a72152123c3c 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c @@ -361,3 +361,40 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw)
return 0; } + +int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, + struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, + struct sst_dsp_device *skl_dev) +{ + struct skl_sst *skl; + struct sst_dsp *sst; + int ret; + + skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); + if (skl == NULL) + return -ENOMEM; + + skl->dev = dev; + skl_dev->thread_context = skl; + INIT_LIST_HEAD(&skl->uuid_list); + skl->dsp = skl_dsp_ctx_init(dev, skl_dev, irq); + if (!skl->dsp) { + dev_err(skl->dev, "%s: no device\n", __func__); + return -ENODEV; + } + + sst = skl->dsp; + sst->fw_name = fw_name; + sst->dsp_ops = dsp_ops; + init_waitqueue_head(&skl->mod_load_wait); + INIT_LIST_HEAD(&sst->module_list); + ret = skl_ipc_init(dev, skl); + if (ret) + return ret; + + skl->is_first_boot = true; + if (dsp) + *dsp = skl; + + return ret; +} diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index 539529729e3f..4fdd503a837c 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -330,7 +330,6 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, int ret, bytes_left, curr_pos; struct skl_sst *skl = ctx->thread_context; skl->mod_load_complete = false; - init_waitqueue_head(&skl->mod_load_wait);
bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false); if (bytes_left < 0) @@ -489,43 +488,24 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, struct sst_dsp *sst; int ret;
- skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); - if (skl == NULL) - return -ENOMEM; - - skl->dev = dev; - skl_dev.thread_context = skl; - INIT_LIST_HEAD(&skl->uuid_list); - - skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq); - if (!skl->dsp) { - dev_err(skl->dev, "%s: no device\n", __func__); - return -ENODEV; + ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev); + if (ret < 0) { + dev_err(dev, "%s: no device\n", __func__); + return ret; }
+ skl = *dsp; sst = skl->dsp; - - sst->fw_name = fw_name; sst->addr.lpe = mmio_base; sst->addr.shim = mmio_base; sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
- INIT_LIST_HEAD(&sst->module_list); - sst->dsp_ops = dsp_ops; sst->fw_ops = skl_fw_ops;
- ret = skl_ipc_init(dev, skl); - if (ret) - return ret; - skl->cores.count = 2; - skl->is_first_boot = true; - - if (dsp) - *dsp = skl;
- return ret; + return 0; } EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
request firmware, strip extended manifest and release library changes are common to kabylake and APL.
So move these common code to utils to be reused in later patches for kabylake library load.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com --- sound/soc/intel/skylake/bxt-sst.c | 38 ++++------------------------- sound/soc/intel/skylake/skl-sst-dsp.h | 7 +++++- sound/soc/intel/skylake/skl-sst-utils.c | 43 +++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 34 deletions(-)
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index c54f56c568e8..2df7d104bfca 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -53,18 +53,6 @@ static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 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 bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) { @@ -75,26 +63,10 @@ static void sst_bxt_release_library(struct skl_lib_info *linfo, int lib_count)
/* library indices start from 1 to N. 0 represents base FW */ for (i = 1; i < lib_count; i++) { - if (linfo[i].fw == NULL) { - ret = request_firmware(&linfo[i].fw, linfo[i].name, - ctx->dev); - if (ret < 0) { - dev_err(ctx->dev, "Request lib %s failed:%d\n", - linfo[i].name, ret); - goto load_library_failed; - } - } - - if (skl->is_first_boot) { - ret = snd_skl_parse_uuids(ctx, linfo[i].fw, + ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw, BXT_ADSP_FW_BIN_HDR_OFFSET, i); - if (ret < 0) - goto load_library_failed; - } - - stripped_fw.data = linfo[i].fw->data; - stripped_fw.size = linfo[i].fw->size; - skl_dsp_strip_extended_manifest(&stripped_fw); + if (ret < 0) + goto load_library_failed;
stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, stripped_fw.size, &dmab); @@ -121,7 +93,7 @@ static void sst_bxt_release_library(struct skl_lib_info *linfo, int lib_count) return ret;
load_library_failed: - sst_bxt_release_library(linfo, lib_count); + skl_release_library(linfo, lib_count); return ret; }
@@ -648,7 +620,7 @@ int bxt_sst_init_fw(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); + skl_release_library(ctx->lib_info, ctx->lib_count); if (ctx->dsp->fw) release_firmware(ctx->dsp->fw); skl_freeup_uuid_list(ctx); diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index c1f95e23933d..6d9aed23d5cd 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h @@ -18,6 +18,7 @@
#include <linux/interrupt.h> #include <linux/uuid.h> +#include <linux/firmware.h> #include <sound/memalloc.h> #include "skl-sst-cldma.h"
@@ -145,7 +146,7 @@ struct skl_dsp_fw_ops { int (*load_fw)(struct sst_dsp *ctx); /* FW module parser/loader */ int (*load_library)(struct sst_dsp *ctx, - struct skl_lib_info *linfo, int count); + struct skl_lib_info *linfo, int lib_count); int (*parse_fw)(struct sst_dsp *ctx); int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); @@ -250,5 +251,9 @@ int skl_get_pvt_instance_id_map(struct skl_sst *ctx, int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, struct sst_dsp_device *skl_dev); +int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, + struct firmware *stripped_fw, + unsigned int hdr_offset, int index); +void skl_release_library(struct skl_lib_info *linfo, int lib_count);
#endif /*__SKL_SST_DSP_H__*/ diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index a72152123c3c..81ee251881b4 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c @@ -398,3 +398,46 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
return ret; } + +int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, + struct firmware *stripped_fw, + unsigned int hdr_offset, int index) +{ + int ret; + struct sst_dsp *dsp = skl->dsp; + + if (linfo->fw == NULL) { + ret = request_firmware(&linfo->fw, linfo->name, + skl->dev); + if (ret < 0) { + dev_err(skl->dev, "Request lib %s failed:%d\n", + linfo->name, ret); + return ret; + } + } + + if (skl->is_first_boot) { + ret = snd_skl_parse_uuids(dsp, linfo->fw, hdr_offset, index); + if (ret < 0) + return ret; + } + + stripped_fw->data = linfo->fw->data; + stripped_fw->size = linfo->fw->size; + skl_dsp_strip_extended_manifest(stripped_fw); + + return 0; +} + +void skl_release_library(struct skl_lib_info *linfo, int lib_count) +{ + int i; + + /* library indices start from 1 to N. 0 represents base FW */ + for (i = 1; i < lib_count; i++) { + if (linfo[i].fw) { + release_firmware(linfo[i].fw); + linfo[i].fw = NULL; + } + } +}
The patch
ASoC: Intel: Skylake: Commonize library load
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From ebe8907687c052b36839b5f9ed09005db4fbe83c Mon Sep 17 00:00:00 2001
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com Date: Tue, 25 Apr 2017 12:18:20 +0530 Subject: [PATCH] ASoC: Intel: Skylake: Commonize library load
request firmware, strip extended manifest and release library changes are common to kabylake and APL.
So move these common code to utils to be reused in later patches for kabylake library load.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Acked-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/bxt-sst.c | 38 ++++------------------------- sound/soc/intel/skylake/skl-sst-dsp.h | 7 +++++- sound/soc/intel/skylake/skl-sst-utils.c | 43 +++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 34 deletions(-)
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 2bf6ebe29f50..d26545ee3e58 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -53,18 +53,6 @@ static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 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 bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) { @@ -75,26 +63,10 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
/* library indices start from 1 to N. 0 represents base FW */ for (i = 1; i < lib_count; i++) { - if (linfo[i].fw == NULL) { - ret = request_firmware(&linfo[i].fw, linfo[i].name, - ctx->dev); - if (ret < 0) { - dev_err(ctx->dev, "Request lib %s failed:%d\n", - linfo[i].name, ret); - goto load_library_failed; - } - } - - if (skl->is_first_boot) { - ret = snd_skl_parse_uuids(ctx, linfo[i].fw, + ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw, BXT_ADSP_FW_BIN_HDR_OFFSET, i); - if (ret < 0) - goto load_library_failed; - } - - stripped_fw.data = linfo[i].fw->data; - stripped_fw.size = linfo[i].fw->size; - skl_dsp_strip_extended_manifest(&stripped_fw); + if (ret < 0) + goto load_library_failed;
stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, stripped_fw.size, &dmab); @@ -121,7 +93,7 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) return ret;
load_library_failed: - sst_bxt_release_library(linfo, lib_count); + skl_release_library(linfo, lib_count); return ret; }
@@ -648,7 +620,7 @@ EXPORT_SYMBOL_GPL(bxt_sst_init_fw); void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) {
- sst_bxt_release_library(ctx->lib_info, ctx->lib_count); + skl_release_library(ctx->lib_info, ctx->lib_count); if (ctx->dsp->fw) release_firmware(ctx->dsp->fw); skl_freeup_uuid_list(ctx); diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index c1f95e23933d..6d9aed23d5cd 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h @@ -18,6 +18,7 @@
#include <linux/interrupt.h> #include <linux/uuid.h> +#include <linux/firmware.h> #include <sound/memalloc.h> #include "skl-sst-cldma.h"
@@ -145,7 +146,7 @@ struct skl_dsp_fw_ops { int (*load_fw)(struct sst_dsp *ctx); /* FW module parser/loader */ int (*load_library)(struct sst_dsp *ctx, - struct skl_lib_info *linfo, int count); + struct skl_lib_info *linfo, int lib_count); int (*parse_fw)(struct sst_dsp *ctx); int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); @@ -250,5 +251,9 @@ void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable); int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, struct sst_dsp_device *skl_dev); +int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, + struct firmware *stripped_fw, + unsigned int hdr_offset, int index); +void skl_release_library(struct skl_lib_info *linfo, int lib_count);
#endif /*__SKL_SST_DSP_H__*/ diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index a72152123c3c..81ee251881b4 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c @@ -398,3 +398,46 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
return ret; } + +int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, + struct firmware *stripped_fw, + unsigned int hdr_offset, int index) +{ + int ret; + struct sst_dsp *dsp = skl->dsp; + + if (linfo->fw == NULL) { + ret = request_firmware(&linfo->fw, linfo->name, + skl->dev); + if (ret < 0) { + dev_err(skl->dev, "Request lib %s failed:%d\n", + linfo->name, ret); + return ret; + } + } + + if (skl->is_first_boot) { + ret = snd_skl_parse_uuids(dsp, linfo->fw, hdr_offset, index); + if (ret < 0) + return ret; + } + + stripped_fw->data = linfo->fw->data; + stripped_fw->size = linfo->fw->size; + skl_dsp_strip_extended_manifest(stripped_fw); + + return 0; +} + +void skl_release_library(struct skl_lib_info *linfo, int lib_count) +{ + int i; + + /* library indices start from 1 to N. 0 represents base FW */ + for (i = 1; i < lib_count; i++) { + if (linfo[i].fw) { + release_firmware(linfo[i].fw); + linfo[i].fw = NULL; + } + } +}
From: G Kranthi gudishax.kranthikumar@intel.com
Kabylake also uses code loader dma for module load and library load. skl_transfer_module can be reused. Modify the arguments to include library index to be passed to lib load ipc and module/lib check to use correct ipc for lib/module load.
Signed-off-by: G Kranthi gudishax.kranthikumar@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com --- sound/soc/intel/skylake/skl-sst.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index 4fdd503a837c..4d4fef0f92ea 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -325,7 +325,7 @@ static struct skl_module_table *skl_module_get_from_id( }
static int skl_transfer_module(struct sst_dsp *ctx, const void *data, - u32 size, u16 mod_id) + u32 size, u16 mod_id, u8 table_id, bool is_module) { int ret, bytes_left, curr_pos; struct skl_sst *skl = ctx->thread_context; @@ -335,10 +335,12 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, if (bytes_left < 0) return bytes_left;
- ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id); - if (ret < 0) { - dev_err(ctx->dev, "Failed to Load module: %d\n", ret); - goto out; + if (is_module) {/* load module */ + ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id); + if (ret < 0) { + dev_err(ctx->dev, "Failed to Load module: %d\n", ret); + goto out; + } }
/* @@ -393,7 +395,8 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
if (!module_entry->usage_cnt) { ret = skl_transfer_module(ctx, module_entry->mod_info->fw->data, - module_entry->mod_info->fw->size, mod_id); + module_entry->mod_info->fw->size, + mod_id, 0, true); if (ret < 0) { dev_err(ctx->dev, "Failed to Load module\n"); return ret;
For audio kabylake is same as skylake except the module load approach. This patch registers different dsp_fw_ops for kabylake and next patch adds the module load support for kabylake.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com --- sound/soc/intel/skylake/skl-messages.c | 2 +- sound/soc/intel/skylake/skl-sst-dsp.h | 3 +++ sound/soc/intel/skylake/skl-sst.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 09730dd8e6a3..ab1adc0c9cc3 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -209,7 +209,7 @@ static struct skl_dsp_loader_ops bxt_get_loader_ops(void) { .id = 0x9d71, .loader_ops = skl_get_loader_ops, - .init = skl_sst_dsp_init, + .init = kbl_sst_dsp_init, .init_fw = skl_sst_init_fw, .cleanup = skl_sst_dsp_cleanup }, diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 6d9aed23d5cd..eba20d37ba8c 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h @@ -230,6 +230,9 @@ int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx, int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp); +int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp); int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp); diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index 4d4fef0f92ea..e7ba0f400726 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -470,6 +470,15 @@ static void skl_clear_module_table(struct sst_dsp *ctx) .unload_mod = skl_unload_module, };
+static struct skl_dsp_fw_ops kbl_fw_ops = { + .set_state_D0 = skl_set_dsp_D0, + .set_state_D3 = skl_set_dsp_D3, + .load_fw = skl_load_base_firmware, + .get_fw_errcode = skl_get_errorcode, + .load_mod = skl_load_module, + .unload_mod = skl_unload_module, +}; + static struct sst_ops skl_ops = { .irq_handler = skl_dsp_sst_interrupt, .write = sst_shim32_write, @@ -512,6 +521,27 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, } EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
+int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp) +{ + struct sst_dsp *sst; + int ret; + + ret = skl_sst_dsp_init(dev, mmio_base, irq, fw_name, dsp_ops, dsp); + if (ret < 0) { + dev_err(dev, "%s: Init failed %d\n", __func__, ret); + return ret; + } + + sst = (*dsp)->dsp; + sst->fw_ops = kbl_fw_ops; + + return 0; + +} +EXPORT_SYMBOL_GPL(kbl_sst_dsp_init); + int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) { int ret;
The patch
ASoC: Intel: Skylake: Register dsp_fw_ops for kabylake
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 89b0d8a5bae91cb8ef23b1834c97d1db367f2db6 Mon Sep 17 00:00:00 2001
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com Date: Tue, 25 Apr 2017 12:18:22 +0530 Subject: [PATCH] ASoC: Intel: Skylake: Register dsp_fw_ops for kabylake
For audio kabylake is same as skylake except the module load approach. This patch registers different dsp_fw_ops for kabylake and next patch adds the module load support for kabylake.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Acked-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/skl-messages.c | 2 +- sound/soc/intel/skylake/skl-sst-dsp.h | 3 +++ sound/soc/intel/skylake/skl-sst.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 09730dd8e6a3..ab1adc0c9cc3 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -209,7 +209,7 @@ static const struct skl_dsp_ops dsp_ops[] = { { .id = 0x9d71, .loader_ops = skl_get_loader_ops, - .init = skl_sst_dsp_init, + .init = kbl_sst_dsp_init, .init_fw = skl_sst_init_fw, .cleanup = skl_sst_dsp_cleanup }, diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index 6d9aed23d5cd..eba20d37ba8c 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h @@ -230,6 +230,9 @@ int skl_dsp_boot(struct sst_dsp *ctx); int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp); +int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp); int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp); diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index b4c3b5c63115..20968e5ec86d 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -470,6 +470,15 @@ static struct skl_dsp_fw_ops skl_fw_ops = { .unload_mod = skl_unload_module, };
+static struct skl_dsp_fw_ops kbl_fw_ops = { + .set_state_D0 = skl_set_dsp_D0, + .set_state_D3 = skl_set_dsp_D3, + .load_fw = skl_load_base_firmware, + .get_fw_errcode = skl_get_errorcode, + .load_mod = skl_load_module, + .unload_mod = skl_unload_module, +}; + static struct sst_ops skl_ops = { .irq_handler = skl_dsp_sst_interrupt, .write = sst_shim32_write, @@ -512,6 +521,27 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, } EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
+int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp) +{ + struct sst_dsp *sst; + int ret; + + ret = skl_sst_dsp_init(dev, mmio_base, irq, fw_name, dsp_ops, dsp); + if (ret < 0) { + dev_err(dev, "%s: Init failed %d\n", __func__, ret); + return ret; + } + + sst = (*dsp)->dsp; + sst->fw_ops = kbl_fw_ops; + + return 0; + +} +EXPORT_SYMBOL_GPL(kbl_sst_dsp_init); + int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) { int ret;
Kabylake uses code loader dma and wait on notification instead of ipc reply for load library ipc status. So modify the argument of skl_sst_ipc_load_library to check on flag to wait for ipc reply.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com --- sound/soc/intel/skylake/bxt-sst.c | 2 +- sound/soc/intel/skylake/skl-sst-ipc.c | 8 ++++++-- sound/soc/intel/skylake/skl-sst-ipc.h | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 2df7d104bfca..a7d1a3ffedcb 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -81,7 +81,7 @@ static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 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); + ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i, true); if (ret < 0) dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", linfo[i].name, ret); diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index d51b483b4d79..c0226dd59445 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c @@ -971,7 +971,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, - u8 dma_id, u8 table_id) + u8 dma_id, u8 table_id, bool wait) { struct skl_ipc_header header = {0}; u64 *ipc_header = (u64 *)(&header); @@ -983,7 +983,11 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, header.primary |= IPC_MOD_INSTANCE_ID(table_id); header.primary |= IPC_MOD_ID(dma_id);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); + if (wait) + ret = sst_ipc_tx_message_wait(ipc, *ipc_header, + NULL, 0, NULL, 0); + else + ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0);
if (ret < 0) dev_err(ipc->dev, "ipc: load lib failed\n"); diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index 4abf98c0e00e..e057da2713c6 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h @@ -197,7 +197,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, struct skl_ipc_large_config_msg *msg, u32 *param);
int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, - u8 dma_id, u8 table_id); + u8 dma_id, u8 table_id, bool wait);
int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg);
The patch
ASoC: Intel: Skylake: Modify load_lib_ipc arguments for a nowait version
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 100e7f396ddf9abd76d5ec93f689be00187512f9 Mon Sep 17 00:00:00 2001
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com Date: Tue, 25 Apr 2017 12:18:23 +0530 Subject: [PATCH] ASoC: Intel: Skylake: Modify load_lib_ipc arguments for a nowait version
Kabylake uses code loader dma and wait on notification instead of ipc reply for load library ipc status. So modify the argument of skl_sst_ipc_load_library to check on flag to wait for ipc reply.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Acked-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/intel/skylake/bxt-sst.c | 2 +- sound/soc/intel/skylake/skl-sst-ipc.c | 8 ++++++-- sound/soc/intel/skylake/skl-sst-ipc.h | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index d26545ee3e58..fde4bc0f35b0 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -81,7 +81,7 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) 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); + ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i, true); if (ret < 0) dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", linfo[i].name, ret); diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index e90fe2c0bf2c..7147eddc6d3c 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c @@ -971,7 +971,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, - u8 dma_id, u8 table_id) + u8 dma_id, u8 table_id, bool wait) { struct skl_ipc_header header = {0}; u64 *ipc_header = (u64 *)(&header); @@ -983,7 +983,11 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, header.primary |= IPC_MOD_INSTANCE_ID(table_id); header.primary |= IPC_MOD_ID(dma_id);
- ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); + if (wait) + ret = sst_ipc_tx_message_wait(ipc, *ipc_header, + NULL, 0, NULL, 0); + else + ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0);
if (ret < 0) dev_err(ipc->dev, "ipc: load lib failed\n"); diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index 4abf98c0e00e..e057da2713c6 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h @@ -197,7 +197,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, struct skl_ipc_large_config_msg *msg, u32 *param);
int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, - u8 dma_id, u8 table_id); + u8 dma_id, u8 table_id, bool wait);
int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg);
From: "Sodhi, VunnyX" vunnyx.sodhi@intel.com
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: Sodhi, VunnyX vunnyx.sodhi@intel.com Signed-off-by: G Kranthi gudishax.kranthikumar@intel.com Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com --- sound/soc/intel/skylake/skl-sst-ipc.c | 2 ++ sound/soc/intel/skylake/skl-sst.c | 63 +++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index c0226dd59445..3679d6c61cbf 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c @@ -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); switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { case IPC_GLB_LOAD_MULTIPLE_MODS: + case IPC_GLB_LOAD_LIBRARY: skl->mod_load_complete = true; skl->mod_load_status = true; wake_up(&skl->mod_load_wait); @@ -443,6 +444,7 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { case IPC_GLB_LOAD_MULTIPLE_MODS: + case IPC_GLB_LOAD_LIBRARY: skl->mod_load_complete = true; skl->mod_load_status = false; wake_up(&skl->mod_load_wait); diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index e7ba0f400726..7282298d2bc9 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -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"); 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)
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) @@ -335,12 +347,15 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, if (bytes_left < 0) return bytes_left;
- if (is_module) {/* load module */ + if (is_module) ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id); - if (ret < 0) { - dev_err(ctx->dev, "Failed to Load module: %d\n", ret); - goto out; - } + else + ret = skl_sst_ipc_load_library(&skl->ipc, 0, table_id, false); + + if (ret < 0) { + dev_err(ctx->dev, "Failed to Load %s with err %d\n", + is_module ? "module" : "lib", ret); + goto out; }
/* @@ -373,6 +388,32 @@ static int skl_transfer_module(struct sst_dsp *ctx, const void *data, 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) { struct skl_module_table *module_entry = NULL; @@ -475,6 +516,7 @@ static void skl_clear_module_table(struct sst_dsp *ctx) .set_state_D3 = skl_set_dsp_D3, .load_fw = skl_load_base_firmware, .get_fw_errcode = skl_get_errorcode, + .load_library = kbl_load_library, .load_mod = skl_load_module, .unload_mod = skl_unload_module, }; @@ -554,6 +596,15 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) }
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;
return 0;
participants (2)
-
Mark Brown
-
Subhransu S. Prusty