diff options
author | Cezary Rojewski <cezary.rojewski@intel.com> | 2022-03-11 16:35:41 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-03-11 16:24:07 +0000 |
commit | b27f452317236b0cbaa94c4498f8241e2ad871b1 (patch) | |
tree | e67ea17c5e924c67119ee219d1334db2690a1929 /sound/soc/intel/avs/dsp.c | |
parent | 215e67b2d2de1d8d34a53c440b9a19a732ee6fb0 (diff) | |
download | linux-stable-b27f452317236b0cbaa94c4498f8241e2ad871b1.tar.gz linux-stable-b27f452317236b0cbaa94c4498f8241e2ad871b1.tar.bz2 linux-stable-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.c | 26 |
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); } |