Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0f23919
ASoC: SOF: loader: Set complete state before post_fw_run op
ranj063 Jun 25, 2022
127aa3c
ASoC: SOF: Introduce container struct for SOF firmware
ujfalusi Aug 16, 2022
74324a7
ASoC: SOF: amd: Use the basefw firmware container directly
ujfalusi Aug 16, 2022
3a7fd4b
ASoC: SOF: Intel: hda-loader: Use the basefw firmware container directly
ujfalusi Aug 16, 2022
a1e313a
ASoC: SOF: Intel: hda-loader-skl: Use the basefw firmware container d…
ujfalusi Aug 19, 2022
7e69eec
ASoC: SOF: Drop the firmware and fw_offset from snd_sof_pdata
ujfalusi Aug 16, 2022
178afa6
ASoC: SOF: ipc: ops: Add support for optional init and exit callbacks
ujfalusi Aug 16, 2022
dfa03d6
ASoC: SOF: ipc4-loader: Save the maximum number of libraries supported
ujfalusi Aug 15, 2022
1946837
ASoC: SOF: ipc4: Convert the firmware handling (loader) to library co…
ujfalusi Aug 16, 2022
323bbed
ASoC: SOF: IPC4: Add helper for looking up module by UUID
ujfalusi Aug 17, 2022
8892d18
ASoC: SOF: Add path definition for external firmware libraries
ujfalusi Aug 17, 2022
ff9aedc
ASoC: SOF: Intel: Set the default firmware library path for IPC4
ujfalusi Aug 17, 2022
571f447
ASoC: SOF: ipc4: Define platform dependent library loading callback
ujfalusi Aug 18, 2022
3825848
ASoC: SOF: Intel: hda: Add flag to indicate that the firmware is IMR …
ujfalusi Aug 17, 2022
37e2ab0
ASoC: SOF: Intel: Add ipc4 library loading implementation
ujfalusi Aug 18, 2022
b193fb2
ASoC: SOF: loader: Add support for IPC dependent post firmware boot ops
ujfalusi Aug 19, 2022
4966d36
ASoC: SOF: ipc4: Stop using the query_fw_configuration fw_loader ops
ujfalusi Aug 19, 2022
2a5ce69
ASoC: SOF: loader: Remove the query_fw_configuration ops
ujfalusi Aug 19, 2022
210555c
ASoC: SOF: ipc4-loader: Support for loading external libraries
ujfalusi Aug 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions include/sound/sof.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,11 @@ enum sof_ipc_type {
* SOF Platform data.
*/
struct snd_sof_pdata {
const struct firmware *fw;
const char *name;
const char *platform;

struct device *dev;

/* indicate how many first bytes shouldn't be loaded into DSP memory. */
size_t fw_offset;

/*
* notification callback used if the hardware initialization
* can take time or is handled in a workqueue. This callback
Expand All @@ -86,6 +82,9 @@ struct snd_sof_pdata {
const char *tplg_filename_prefix;
const char *tplg_filename;

/* loadable external libraries available under this directory */
const char *fw_lib_prefix;

/* machine */
struct platform_device *pdev_mach;
const struct snd_soc_acpi_mach *machine;
Expand Down Expand Up @@ -131,8 +130,9 @@ struct sof_dev_desc {
unsigned int ipc_supported_mask;
enum sof_ipc_type ipc_default;

/* defaults paths for firmware and topology files */
/* defaults paths for firmware, library and topology files */
const char *default_fw_path[SOF_IPC_TYPE_COUNT];
const char *default_lib_path[SOF_IPC_TYPE_COUNT];
const char *default_tplg_path[SOF_IPC_TYPE_COUNT];

/* default firmware name */
Expand Down
4 changes: 4 additions & 0 deletions include/sound/sof/ipc4/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ enum sof_ipc4_pipeline_state {
#define SOF_IPC4_GLB_PIPE_STATE_MASK GENMASK(15, 0)
#define SOF_IPC4_GLB_PIPE_STATE(x) ((x) << SOF_IPC4_GLB_PIPE_STATE_SHIFT)

/* load library ipc msg */
#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT 16
#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(x) ((x) << SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT)

enum sof_ipc4_channel_config {
/* one channel only. */
SOF_IPC4_CHANNEL_CONFIG_MONO,
Expand Down
6 changes: 2 additions & 4 deletions sound/soc/sof/amd/acp-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ EXPORT_SYMBOL_NS(acp_dsp_block_read, SND_SOC_SOF_AMD_COMMON);
int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
u32 offset, void *src, size_t size)
{
struct snd_sof_pdata *plat_data = sdev->pdata;
struct pci_dev *pci = to_pci_dev(sdev->dev);
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
struct acp_dev_data *adata;
Expand All @@ -61,7 +60,7 @@ int acp_dsp_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_t
switch (blk_type) {
case SOF_FW_BLK_TYPE_IRAM:
if (!adata->bin_buf) {
size_fw = plat_data->fw->size;
size_fw = sdev->basefw.fw->size;
page_count = PAGE_ALIGN(size_fw) >> PAGE_SHIFT;
dma_size = page_count * ACP_PAGE_SIZE;
adata->bin_buf = dma_alloc_coherent(&pci->dev, dma_size,
Expand Down Expand Up @@ -152,7 +151,6 @@ static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev
int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
{
struct pci_dev *pci = to_pci_dev(sdev->dev);
struct snd_sof_pdata *plat_data = sdev->pdata;
struct acp_dev_data *adata;
unsigned int src_addr, size_fw;
u32 page_count, dma_size;
Expand Down Expand Up @@ -186,7 +184,7 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
dev_err(sdev->dev, "acp dma transfer status: %d\n", ret);

/* Free memory once DMA is complete */
dma_size = (PAGE_ALIGN(plat_data->fw->size) >> PAGE_SHIFT) * ACP_PAGE_SIZE;
dma_size = (PAGE_ALIGN(sdev->basefw.fw->size) >> PAGE_SHIFT) * ACP_PAGE_SIZE;
dma_free_coherent(&pci->dev, dma_size, adata->bin_buf, adata->sha_dma_addr);
dma_free_coherent(&pci->dev, ACP_DEFAULT_DRAM_LENGTH, adata->data_buf, adata->dma_addr);
adata->bin_buf = NULL;
Expand Down
3 changes: 3 additions & 0 deletions sound/soc/sof/intel/apl.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev)

ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_1_5;

/* External library loading support */
ipc4_data->load_library = hda_dsp_ipc4_load_library;

/* doorbell */
sof_apl_ops.irq_thread = hda_dsp_ipc4_irq_thread;

Expand Down
3 changes: 3 additions & 0 deletions sound/soc/sof/intel/cnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,9 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev)

ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_1_8;

/* External library loading support */
ipc4_data->load_library = hda_dsp_ipc4_load_library;

/* doorbell */
sof_cnl_ops.irq_thread = cnl_ipc4_irq_thread;

Expand Down
7 changes: 3 additions & 4 deletions sound/soc/sof/intel/hda-loader-skl.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,14 +494,13 @@ static int cl_copy_fw_skl(struct snd_sof_dev *sdev,
struct snd_dma_buffer *dmab)

{
struct snd_sof_pdata *plat_data = sdev->pdata;
const struct firmware *fw = plat_data->fw;
const struct firmware *fw = sdev->basefw.fw;
struct firmware stripped_firmware;
unsigned int bufsize = HDA_SKL_CLDMA_MAX_BUFFER_SIZE;
int ret;

stripped_firmware.data = plat_data->fw->data + plat_data->fw_offset;
stripped_firmware.size = plat_data->fw->size - plat_data->fw_offset;
stripped_firmware.data = fw->data + sdev->basefw.payload_offset;
stripped_firmware.size = fw->size - sdev->basefw.payload_offset;

dev_dbg(sdev->dev, "firmware size: %#zx buffer size %#x\n", fw->size, bufsize);

Expand Down
83 changes: 76 additions & 7 deletions sound/soc/sof/intel/hda-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#include <sound/hdaudio_ext.h>
#include <sound/hda_register.h>
#include <sound/sof.h>
#include <sound/sof/ipc4/header.h>
#include "ext_manifest.h"
#include "../ipc4-priv.h"
#include "../ops.h"
#include "../sof-priv.h"
#include "hda.h"
Expand Down Expand Up @@ -318,7 +320,6 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream

int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *plat_data = sdev->pdata;
struct hdac_ext_stream *iccmax_stream;
struct hdac_bus *bus = sof_to_bus(sdev);
struct firmware stripped_firmware;
Expand All @@ -329,12 +330,12 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev)
/* save the original LTRP guardband value */
original_gb = snd_hdac_chip_readb(bus, VS_LTRP) & HDA_VS_INTEL_LTRP_GB_MASK;

if (plat_data->fw->size <= plat_data->fw_offset) {
if (sdev->basefw.fw->size <= sdev->basefw.payload_offset) {
dev_err(sdev->dev, "error: firmware size must be greater than firmware offset\n");
return -EINVAL;
}

stripped_firmware.size = plat_data->fw->size - plat_data->fw_offset;
stripped_firmware.size = sdev->basefw.fw->size - sdev->basefw.payload_offset;

/* prepare capture stream for ICCMAX */
iccmax_stream = hda_cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT, stripped_firmware.size,
Expand Down Expand Up @@ -397,21 +398,25 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n");
hda->boot_iteration = 0;
ret = hda_dsp_boot_imr(sdev);
if (!ret)
if (!ret) {
hda->booted_from_imr = true;
return 0;
}

dev_warn(sdev->dev, "IMR restore failed, trying to cold boot\n");
}

hda->booted_from_imr = false;

chip_info = desc->chip_info;

if (plat_data->fw->size <= plat_data->fw_offset) {
if (sdev->basefw.fw->size <= sdev->basefw.payload_offset) {
dev_err(sdev->dev, "error: firmware size must be greater than firmware offset\n");
return -EINVAL;
}

stripped_firmware.data = plat_data->fw->data + plat_data->fw_offset;
stripped_firmware.size = plat_data->fw->size - plat_data->fw_offset;
stripped_firmware.data = sdev->basefw.fw->data + sdev->basefw.payload_offset;
stripped_firmware.size = sdev->basefw.fw->size - sdev->basefw.payload_offset;

/* init for booting wait */
init_waitqueue_head(&sdev->boot_wait);
Expand Down Expand Up @@ -515,6 +520,70 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
return ret;
}

int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev,
struct sof_ipc4_fw_library *fw_lib, bool reload)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct hdac_ext_stream *hext_stream;
struct firmware stripped_firmware;
struct sof_ipc4_msg msg = {};
struct snd_dma_buffer dmab;
int ret, ret1;

/* IMR booting will restore the libraries as well, skip the loading */
if (reload && hda->booted_from_imr)
return 0;

/* the fw_lib has been verified during loading, we can trust the validity here */
stripped_firmware.data = fw_lib->sof_fw.fw->data + fw_lib->sof_fw.payload_offset;
stripped_firmware.size = fw_lib->sof_fw.fw->size - fw_lib->sof_fw.payload_offset;

/* prepare DMA for code loader stream */
hext_stream = hda_cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT,
stripped_firmware.size,
&dmab, SNDRV_PCM_STREAM_PLAYBACK);
if (IS_ERR(hext_stream)) {
dev_err(sdev->dev, "%s: DMA prepare failed\n", __func__);
return PTR_ERR(hext_stream);
}

memcpy(dmab.area, stripped_firmware.data, stripped_firmware.size);

msg.primary = hext_stream->hstream.stream_tag - 1;
msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_LOAD_LIBRARY);
msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
msg.primary |= SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(fw_lib->id);

ret = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_START);
if (ret < 0) {
dev_err(sdev->dev, "%s: DMA trigger start failed\n", __func__);
goto cleanup;
}

ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0);

ret1 = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_STOP);
if (ret1 < 0) {
dev_err(sdev->dev, "%s: DMA trigger stop failed\n", __func__);
if (!ret)
ret = ret1;
}

cleanup:
/* clean up even in case of error and return the first error */
ret1 = hda_cl_cleanup(sdev, &dmab, hext_stream);
if (ret1 < 0) {
dev_err(sdev->dev, "%s: Code loader DSP cleanup failed\n", __func__);

/* set return value to indicate cleanup failure */
if (!ret)
ret = ret1;
}

return ret;
}

/* pre fw run operations */
int hda_dsp_pre_fw_run(struct snd_sof_dev *sdev)
{
Expand Down
4 changes: 4 additions & 0 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ enum sof_hda_D0_substate {
struct sof_intel_hda_dev {
bool imrboot_supported;
bool skip_imr_boot;
bool booted_from_imr;

int boot_iteration;

Expand Down Expand Up @@ -857,4 +858,7 @@ int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
void hda_ipc4_dump(struct snd_sof_dev *sdev);
extern struct sdw_intel_ops sdw_callback;

struct sof_ipc4_fw_library;
int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev,
struct sof_ipc4_fw_library *fw_lib, bool reload);
#endif
3 changes: 3 additions & 0 deletions sound/soc/sof/intel/icl.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev)

ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_2;

/* External library loading support */
ipc4_data->load_library = hda_dsp_ipc4_load_library;

/* doorbell */
sof_icl_ops.irq_thread = cnl_ipc4_irq_thread;

Expand Down
3 changes: 3 additions & 0 deletions sound/soc/sof/intel/mtl.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,9 @@ int sof_mtl_ops_init(struct snd_sof_dev *sdev)

ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_2;

/* External library loading support */
ipc4_data->load_library = hda_dsp_ipc4_load_library;

/* set DAI ops */
hda_set_dai_drv_ops(sdev, &sof_mtl_ops);

Expand Down
6 changes: 6 additions & 0 deletions sound/soc/sof/intel/pci-apl.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ static const struct sof_dev_desc bxt_desc = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/apl",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/avs-lib/apl",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
Expand Down Expand Up @@ -61,6 +64,9 @@ static const struct sof_dev_desc glk_desc = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/glk",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/avs-lib/glk",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
Expand Down
9 changes: 9 additions & 0 deletions sound/soc/sof/intel/pci-cnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ static const struct sof_dev_desc cnl_desc = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/cnl",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/avs-lib/cnl",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
Expand Down Expand Up @@ -62,6 +65,9 @@ static const struct sof_dev_desc cfl_desc = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/cnl",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/avs-lib/cnl",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
Expand Down Expand Up @@ -91,6 +97,9 @@ static const struct sof_dev_desc cml_desc = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/cnl",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/avs-lib/cnl",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
Expand Down
6 changes: 6 additions & 0 deletions sound/soc/sof/intel/pci-icl.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ static const struct sof_dev_desc icl_desc = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/icl",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/avs-lib/icl",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
Expand Down Expand Up @@ -62,6 +65,9 @@ static const struct sof_dev_desc jsl_desc = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/jsl",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/avs-lib/jsl",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
Expand Down
3 changes: 3 additions & 0 deletions sound/soc/sof/intel/pci-mtl.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ static const struct sof_dev_desc mtl_desc = {
.default_fw_path = {
[SOF_INTEL_IPC4] = "intel/sof-ipc4/mtl",
},
.default_lib_path = {
[SOF_INTEL_IPC4] = "intel/sof-ipc4-lib/mtl",
},
.default_tplg_path = {
[SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
},
Expand Down
Loading