summaryrefslogtreecommitdiff
path: root/sound/soc/sof/ipc4-loader.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>2023-05-22 13:13:13 +0300
committerMark Brown <broonie@kernel.org>2023-05-22 13:18:38 +0300
commitd8a2c987934959dd1f27de75401625650cd25e47 (patch)
tree46a55c6a28ae4ba5147eefa43f99b59d797ad672 /sound/soc/sof/ipc4-loader.c
parent9caa90180512581821d7498132f952ebd4ba05ad (diff)
downloadlinux-d8a2c987934959dd1f27de75401625650cd25e47.tar.xz
ASoC: SOF: ipc4-loader/topology: Query the CPC value from manifest
The manifest's firmware module configuration section contains the measured CPC values along with a matching IBS/OBS values. The CPC can be looked up by looking for a matching IBS/OBS entry. In case of multiple matches we will use the highest CPC value. If there is no mod_cfg or no CPC value (all 0) or no match was found then print warning message and use 0 as CPC value. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20230522101313.12519-6-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/ipc4-loader.c')
-rw-r--r--sound/soc/sof/ipc4-loader.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c
index 3860d3455960..eaa04762eb11 100644
--- a/sound/soc/sof/ipc4-loader.c
+++ b/sound/soc/sof/ipc4-loader.c
@@ -423,6 +423,71 @@ int sof_ipc4_reload_fw_libraries(struct snd_sof_dev *sdev)
return ret;
}
+/**
+ * sof_ipc4_update_cpc_from_manifest - Update the cpc in base config from manifest
+ * @sdev: SOF device
+ * @fw_module: pointer struct sof_ipc4_fw_module to parse
+ * @basecfg: Pointer to the base_config to update
+ */
+void sof_ipc4_update_cpc_from_manifest(struct snd_sof_dev *sdev,
+ struct sof_ipc4_fw_module *fw_module,
+ struct sof_ipc4_base_module_cfg *basecfg)
+{
+ const struct sof_man4_module_config *fw_mod_cfg;
+ u32 cpc_pick = 0;
+ u32 max_cpc = 0;
+ const char *msg;
+ int i;
+
+ if (!fw_module->fw_mod_cfg) {
+ msg = "No mod_cfg available for CPC lookup in the firmware file's manifest";
+ goto no_cpc;
+ }
+
+ /*
+ * Find the best matching (highest) CPC value based on the module's
+ * IBS/OBS configuration inferred from the audio format selection.
+ *
+ * The CPC value in each module config entry has been measured and
+ * recorded as a IBS/OBS/CPC triplet and stored in the firmware file's
+ * manifest
+ */
+ fw_mod_cfg = fw_module->fw_mod_cfg;
+ for (i = 0; i < fw_module->man4_module_entry.cfg_count; i++) {
+ if (basecfg->obs == fw_mod_cfg[i].obs &&
+ basecfg->ibs == fw_mod_cfg[i].ibs &&
+ cpc_pick < fw_mod_cfg[i].cpc)
+ cpc_pick = fw_mod_cfg[i].cpc;
+
+ if (max_cpc < fw_mod_cfg[i].cpc)
+ max_cpc = fw_mod_cfg[i].cpc;
+ }
+
+ basecfg->cpc = cpc_pick;
+
+ /* We have a matching configuration for CPC */
+ if (basecfg->cpc)
+ return;
+
+ /*
+ * No matching IBS/OBS found, the firmware manifest is missing
+ * information in the module's module configuration table.
+ */
+ if (!max_cpc)
+ msg = "No CPC value available in the firmware file's manifest";
+ else if (!cpc_pick)
+ msg = "No CPC match in the firmware file's manifest";
+
+no_cpc:
+ dev_warn(sdev->dev, "%s (UUID: %pUL): %s (ibs/obs: %u/%u)\n",
+ fw_module->man4_module_entry.name,
+ &fw_module->man4_module_entry.uuid, msg, basecfg->ibs,
+ basecfg->obs);
+ dev_warn_once(sdev->dev, "Please try to update the firmware.\n");
+ dev_warn_once(sdev->dev, "If the issue persists, file a bug at\n");
+ dev_warn_once(sdev->dev, "https://github.com/thesofproject/sof/issues/\n");
+}
+
const struct sof_ipc_fw_loader_ops ipc4_loader_ops = {
.validate = sof_ipc4_validate_firmware,
.parse_ext_manifest = sof_ipc4_fw_parse_basefw_ext_man,