mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
ASoC: SOF: Introduce container struct for SOF firmware
Move the firmware related information under a new struct (sof_firmware) and add it to the high level snd_sof_dev struct. Convert the generic code to use this new container when working with the basefw and for compatibility reasons set the old plat_data members used by the platforms. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Chao Song <chao.song@intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Link: https://lore.kernel.org/r/20221020121238.18339-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
9b9db0d69b
commit
4f373ccf22
@ -138,8 +138,7 @@ static ssize_t ipc3_fw_ext_man_size(struct snd_sof_dev *sdev, const struct firmw
|
||||
|
||||
static size_t sof_ipc3_fw_parse_ext_man(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct snd_sof_pdata *plat_data = sdev->pdata;
|
||||
const struct firmware *fw = plat_data->fw;
|
||||
const struct firmware *fw = sdev->basefw.fw;
|
||||
const struct sof_ext_man_elem_header *elem_hdr;
|
||||
const struct sof_ext_man_header *head;
|
||||
ssize_t ext_man_size;
|
||||
@ -310,18 +309,18 @@ static int sof_ipc3_parse_module_memcpy(struct snd_sof_dev *sdev,
|
||||
|
||||
static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct snd_sof_pdata *plat_data = sdev->pdata;
|
||||
const struct firmware *fw = plat_data->fw;
|
||||
u32 payload_offset = sdev->basefw.payload_offset;
|
||||
const struct firmware *fw = sdev->basefw.fw;
|
||||
struct snd_sof_fw_header *header;
|
||||
struct snd_sof_mod_hdr *module;
|
||||
int (*load_module)(struct snd_sof_dev *sof_dev, struct snd_sof_mod_hdr *hdr);
|
||||
size_t remaining;
|
||||
int ret, count;
|
||||
|
||||
if (!plat_data->fw)
|
||||
if (!fw)
|
||||
return -EINVAL;
|
||||
|
||||
header = (struct snd_sof_fw_header *)(fw->data + plat_data->fw_offset);
|
||||
header = (struct snd_sof_fw_header *)(fw->data + payload_offset);
|
||||
load_module = sof_ops(sdev)->load_module;
|
||||
if (!load_module) {
|
||||
dev_dbg(sdev->dev, "Using generic module loading\n");
|
||||
@ -331,9 +330,8 @@ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev)
|
||||
}
|
||||
|
||||
/* parse each module */
|
||||
module = (struct snd_sof_mod_hdr *)(fw->data + plat_data->fw_offset +
|
||||
sizeof(*header));
|
||||
remaining = fw->size - sizeof(*header) - plat_data->fw_offset;
|
||||
module = (struct snd_sof_mod_hdr *)(fw->data + payload_offset + sizeof(*header));
|
||||
remaining = fw->size - sizeof(*header) - payload_offset;
|
||||
/* check for wrap */
|
||||
if (remaining > fw->size) {
|
||||
dev_err(sdev->dev, "%s: fw size smaller than header size\n", __func__);
|
||||
@ -374,19 +372,19 @@ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev)
|
||||
|
||||
static int sof_ipc3_validate_firmware(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct snd_sof_pdata *plat_data = sdev->pdata;
|
||||
const struct firmware *fw = plat_data->fw;
|
||||
u32 payload_offset = sdev->basefw.payload_offset;
|
||||
const struct firmware *fw = sdev->basefw.fw;
|
||||
struct snd_sof_fw_header *header;
|
||||
size_t fw_size = fw->size - plat_data->fw_offset;
|
||||
size_t fw_size = fw->size - payload_offset;
|
||||
|
||||
if (fw->size <= plat_data->fw_offset) {
|
||||
if (fw->size <= payload_offset) {
|
||||
dev_err(sdev->dev,
|
||||
"firmware size must be greater than firmware offset\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Read the header information from the data pointer */
|
||||
header = (struct snd_sof_fw_header *)(fw->data + plat_data->fw_offset);
|
||||
header = (struct snd_sof_fw_header *)(fw->data + payload_offset);
|
||||
|
||||
/* verify FW sig */
|
||||
if (strncmp(header->sig, SND_SOF_FW_SIG, SND_SOF_FW_SIG_SIZE) != 0) {
|
||||
|
@ -17,9 +17,8 @@
|
||||
static size_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
|
||||
struct snd_sof_pdata *plat_data = sdev->pdata;
|
||||
struct sof_man4_fw_binary_header *fw_header;
|
||||
const struct firmware *fw = plat_data->fw;
|
||||
const struct firmware *fw = sdev->basefw.fw;
|
||||
struct sof_ext_manifest4_hdr *ext_man_hdr;
|
||||
struct sof_man4_module_config *fm_config;
|
||||
struct sof_ipc4_fw_module *fw_module;
|
||||
@ -138,9 +137,8 @@ static int sof_ipc4_validate_firmware(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
|
||||
u32 fw_hdr_offset = ipc4_data->manifest_fw_hdr_offset;
|
||||
struct snd_sof_pdata *plat_data = sdev->pdata;
|
||||
struct sof_man4_fw_binary_header *fw_header;
|
||||
const struct firmware *fw = plat_data->fw;
|
||||
const struct firmware *fw = sdev->basefw.fw;
|
||||
struct sof_ext_manifest4_hdr *ext_man_hdr;
|
||||
|
||||
ext_man_hdr = (struct sof_ext_manifest4_hdr *)fw->data;
|
||||
|
@ -22,7 +22,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
|
||||
int ret;
|
||||
|
||||
/* Don't request firmware again if firmware is already requested */
|
||||
if (plat_data->fw)
|
||||
if (sdev->basefw.fw)
|
||||
return 0;
|
||||
|
||||
fw_filename = kasprintf(GFP_KERNEL, "%s/%s",
|
||||
@ -31,7 +31,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
|
||||
if (!fw_filename)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = request_firmware(&plat_data->fw, fw_filename, sdev->dev);
|
||||
ret = request_firmware(&sdev->basefw.fw, fw_filename, sdev->dev);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(sdev->dev,
|
||||
@ -48,7 +48,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
|
||||
ext_man_size = sdev->ipc->ops->fw_loader->parse_ext_manifest(sdev);
|
||||
if (ext_man_size > 0) {
|
||||
/* when no error occurred, drop extended manifest */
|
||||
plat_data->fw_offset = ext_man_size;
|
||||
sdev->basefw.payload_offset = ext_man_size;
|
||||
} else if (!ext_man_size) {
|
||||
/* No extended manifest, so nothing to skip during FW load */
|
||||
dev_dbg(sdev->dev, "firmware doesn't contain extended manifest\n");
|
||||
@ -58,6 +58,12 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
|
||||
fw_filename, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Until the platform code is switched to use the new container the fw
|
||||
* and payload offset must be set in plat_data
|
||||
*/
|
||||
plat_data->fw = sdev->basefw.fw;
|
||||
plat_data->fw_offset = sdev->basefw.payload_offset;
|
||||
err:
|
||||
kfree(fw_filename);
|
||||
|
||||
@ -100,7 +106,8 @@ int snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
release_firmware(plat_data->fw);
|
||||
release_firmware(sdev->basefw.fw);
|
||||
sdev->basefw.fw = NULL;
|
||||
plat_data->fw = NULL;
|
||||
return ret;
|
||||
|
||||
@ -185,7 +192,8 @@ EXPORT_SYMBOL(snd_sof_run_firmware);
|
||||
void snd_sof_fw_unload(struct snd_sof_dev *sdev)
|
||||
{
|
||||
/* TODO: support module unloading at runtime */
|
||||
release_firmware(sdev->pdata->fw);
|
||||
release_firmware(sdev->basefw.fw);
|
||||
sdev->basefw.fw = NULL;
|
||||
sdev->pdata->fw = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_sof_fw_unload);
|
||||
|
@ -136,6 +136,17 @@ struct snd_sof_platform_stream_params {
|
||||
bool cont_update_posn;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sof_firmware - Container struct for SOF firmware
|
||||
* @fw: Pointer to the firmware
|
||||
* @payload_offset: Offset of the data within the loaded firmware image to be
|
||||
* loaded to the DSP (skipping for example ext_manifest section)
|
||||
*/
|
||||
struct sof_firmware {
|
||||
const struct firmware *fw;
|
||||
u32 payload_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* SOF DSP HW abstraction operations.
|
||||
* Used to abstract DSP HW architecture and any IO busses between host CPU
|
||||
@ -487,6 +498,9 @@ struct snd_sof_dev {
|
||||
spinlock_t ipc_lock; /* lock for IPC users */
|
||||
spinlock_t hw_lock; /* lock for HW IO access */
|
||||
|
||||
/* Main, Base firmware image */
|
||||
struct sof_firmware basefw;
|
||||
|
||||
/*
|
||||
* ASoC components. plat_drv fields are set dynamically so
|
||||
* can't use const
|
||||
|
Loading…
Reference in New Issue
Block a user