aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/intel/avs/dsp.c
diff options
context:
space:
mode:
authorGravatar Cezary Rojewski <cezary.rojewski@intel.com> 2022-03-11 16:35:41 +0100
committerGravatar Mark Brown <broonie@kernel.org> 2022-03-11 16:24:07 +0000
commitb27f452317236b0cbaa94c4498f8241e2ad871b1 (patch)
treee67ea17c5e924c67119ee219d1334db2690a1929 /sound/soc/intel/avs/dsp.c
parentASoC: Intel: avs: Dynamic firmware resources management (diff)
downloadlinux-b27f452317236b0cbaa94c4498f8241e2ad871b1.tar.gz
linux-b27f452317236b0cbaa94c4498f8241e2ad871b1.tar.bz2
linux-b27f452317236b0cbaa94c4498f8241e2ad871b1.zip
ASoC: Intel: avs: General code loading flow
Code loading is a complex procedure and requires combined effort of DMA and IPCs. With IPCs already in place, lay out ground for specific DMA transfer operations. Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://lore.kernel.org/r/20220311153544.136854-15-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/avs/dsp.c')
-rw-r--r--sound/soc/intel/avs/dsp.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sound/soc/intel/avs/dsp.c b/sound/soc/intel/avs/dsp.c
index 53925eae92b3..3ff17bd22a5a 100644
--- a/sound/soc/intel/avs/dsp.c
+++ b/sound/soc/intel/avs/dsp.c
@@ -198,6 +198,7 @@ int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id,
u16 *instance_id)
{
struct avs_module_entry mentry;
+ bool was_loaded = false;
int ret, id;
id = avs_module_id_alloc(adev, module_id);
@@ -212,6 +213,16 @@ int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id,
if (ret)
goto err_mod_entry;
+ /* Load code into memory if this is the first instance. */
+ if (!id && !avs_module_entry_is_loaded(&mentry)) {
+ ret = avs_dsp_op(adev, transfer_mods, true, &mentry, 1);
+ if (ret) {
+ dev_err(adev->dev, "load modules failed: %d\n", ret);
+ goto err_mod_entry;
+ }
+ was_loaded = true;
+ }
+
ret = avs_ipc_init_instance(adev, module_id, id, ppl_instance_id,
core_id, domain, param, param_size);
if (ret) {
@@ -223,6 +234,8 @@ int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id,
return 0;
err_ipc:
+ if (was_loaded)
+ avs_dsp_op(adev, transfer_mods, false, &mentry, 1);
avs_dsp_put_core(adev, core_id);
err_mod_entry:
avs_module_id_free(adev, module_id, id);
@@ -232,12 +245,25 @@ err_mod_entry:
void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u16 instance_id,
u8 ppl_instance_id, u8 core_id)
{
+ struct avs_module_entry mentry;
+ int ret;
+
/* Modules not owned by any pipeline need to be freed explicitly. */
if (ppl_instance_id == INVALID_PIPELINE_ID)
avs_ipc_delete_instance(adev, module_id, instance_id);
avs_module_id_free(adev, module_id, instance_id);
+ ret = avs_get_module_id_entry(adev, module_id, &mentry);
+ /* Unload occupied memory if this was the last instance. */
+ if (!ret && mentry.type.load_type == AVS_MODULE_LOAD_TYPE_LOADABLE) {
+ if (avs_is_module_ida_empty(adev, module_id)) {
+ ret = avs_dsp_op(adev, transfer_mods, false, &mentry, 1);
+ if (ret)
+ dev_err(adev->dev, "unload modules failed: %d\n", ret);
+ }
+ }
+
avs_dsp_put_core(adev, core_id);
}