Skip to content

Commit

Permalink
ASoC: SOF: core: Implement IPC version fallback if firmware files are…
Browse files Browse the repository at this point in the history
… missing

If a firmware file is missing for the selected IPC type then try to switch
to other supported IPC type and check if that one can be used instead.

If for example a platform is changed to IPC4 as default version but the
given machine does not yet have the needed topology file created then we
will fall back to IPC3 which should have all the needed files.

Relocate the sof_init_environment() to be done at a later phase, in
sof_probe_continue().

This will only have changes in behavior if
CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE is enabled (Intel HDA platforms) by
not failing the module probe, but it is not going to be different case
compared to for example failed firmware booting or topology loading error.

Signed-off-by: Peter Ujfalusi <[email protected]>
  • Loading branch information
ujfalusi committed Oct 23, 2023
1 parent 15bb550 commit bfd1cf7
Show file tree
Hide file tree
Showing 3 changed files with 293 additions and 49 deletions.
11 changes: 11 additions & 0 deletions sound/soc/sof/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ config SND_SOC_SOF_STRICT_ABI_CHECKS
If you are not involved in SOF releases and CI development,
select "N".

config SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION
bool "SOF allow fallback to newer IPC version"
help
This option will allow the kernel to try to 'fallback' to a newer IPC
version if there are missing firmware files to satisfy the default IPC
version.
IPC version fallback to older versions is not affected by this option,
it is always available.
Say Y if you are involved in SOF development and need this option.
If not, select N.

config SND_SOC_SOF_DEBUG
bool "SOF debugging features"
help
Expand Down
105 changes: 73 additions & 32 deletions sound/soc/sof/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,6 @@ static int sof_select_ipc_and_paths(struct snd_sof_dev *sdev)
struct device *dev = sdev->dev;
int ret;

/* check IPC support */
if (!(BIT(base_profile->ipc_type) & plat_data->desc->ipc_supported_mask)) {
dev_err(dev,
"ipc_type %d is not supported on this platform, mask is %#x\n",
base_profile->ipc_type, plat_data->desc->ipc_supported_mask);
return -EINVAL;
}

if (base_profile->ipc_type != plat_data->desc->ipc_default)
dev_info(dev,
"Module parameter used, overriding default IPC %d to %d\n",
Expand Down Expand Up @@ -260,19 +252,14 @@ static int sof_select_ipc_and_paths(struct snd_sof_dev *sdev)
plat_data->fw_filename_prefix = out_profile.fw_path;
plat_data->fw_lib_prefix = out_profile.fw_lib_path;
plat_data->tplg_filename_prefix = out_profile.tplg_path;
plat_data->tplg_filename = out_profile.tplg_name;

return 0;
}

static int sof_init_environment(struct snd_sof_dev *sdev)
static int validate_sof_ops(struct snd_sof_dev *sdev)
{
int ret;

ret = sof_select_ipc_and_paths(sdev);
if (ret)
return ret;

/* init ops, if necessary */
ret = sof_ops_init(sdev);
if (ret < 0)
Expand All @@ -297,6 +284,72 @@ static int sof_init_environment(struct snd_sof_dev *sdev)
return 0;
}

static int sof_init_sof_ops(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *plat_data = sdev->pdata;
struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base;

/* check IPC support */
if (!(BIT(base_profile->ipc_type) & plat_data->desc->ipc_supported_mask)) {
dev_err(sdev->dev,
"ipc_type %d is not supported on this platform, mask is %#x\n",
base_profile->ipc_type, plat_data->desc->ipc_supported_mask);
return -EINVAL;
}

/*
* Save the selected IPC type and a topology name override before
* selecting ops since platform code might need this information
*/
plat_data->ipc_type = base_profile->ipc_type;
plat_data->tplg_filename = base_profile->tplg_name;

return validate_sof_ops(sdev);

}

static int sof_init_environment(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *plat_data = sdev->pdata;
struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base;
int ret;

/* probe the DSP hardware */
ret = snd_sof_probe(sdev);
if (ret < 0) {
dev_err(sdev->dev, "failed to probe DSP %d\n", ret);
sof_ops_free(sdev);
return ret;
}

/* check machine info */
ret = sof_machine_check(sdev);
if (ret < 0) {
dev_err(sdev->dev, "failed to get machine info %d\n", ret);
goto err_machine_check;
}

ret = sof_select_ipc_and_paths(sdev);
if (!ret && plat_data->ipc_type != base_profile->ipc_type) {
/* IPC type changed, re-initialize the ops */
sof_ops_free(sdev);

ret = validate_sof_ops(sdev);
if (ret < 0) {
snd_sof_remove(sdev);
return ret;
}
}

err_machine_check:
if (ret) {
snd_sof_remove(sdev);
sof_ops_free(sdev);
}

return ret;
}

/*
* FW Boot State Transition Diagram
*
Expand Down Expand Up @@ -342,23 +395,13 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
struct snd_sof_pdata *plat_data = sdev->pdata;
int ret;

/* probe the DSP hardware */
ret = snd_sof_probe(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to probe DSP %d\n", ret);
goto probe_err;
}
/* Initialize loadable file paths and check the environment validity */
ret = sof_init_environment(sdev);
if (ret)
return ret;

sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE);

/* check machine info */
ret = sof_machine_check(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to get machine info %d\n",
ret);
goto dsp_err;
}

/* set up platform component driver */
snd_sof_new_platform_drv(sdev);

Expand Down Expand Up @@ -478,9 +521,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
ipc_err:
dbg_err:
snd_sof_free_debug(sdev);
dsp_err:
snd_sof_remove(sdev);
probe_err:
snd_sof_remove_late(sdev);
sof_ops_free(sdev);

Expand Down Expand Up @@ -535,8 +576,8 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
}
}

/* Initialize loadable file paths and check the environment validity */
ret = sof_init_environment(sdev);
/* Initialize sof_ops based on the initial selected IPC version */
ret = sof_init_sof_ops(sdev);
if (ret)
return ret;

Expand Down
Loading

0 comments on commit bfd1cf7

Please sign in to comment.