[PATCH 0/3] ASoC: SOF: ipc4/Intel: Implement split fw library loading
Hi,
This series implements support for split library loading to comply with the HDA DMA programming sequence recommendation, which is: 1. DSP side DMA programming and GEN bit set to 1 2. host side DMA programming and RUN bit set to 1
The SOF support for library loading is based on this sequence, backwards compatibility with older reference firmware is supported (where only the LOAD_LIBRARY message is supported).
Regards, Peter --- Peter Ujfalusi (3): ASoC: SOF: Intel: hda: Add definition for SDxFIFOS.FIFOS mask ASoC: SOF: ipc4: Add new message type: SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE ASoC: SOF: Intel: hda-loader: Add support for split library loading
include/sound/sof/ipc4/header.h | 15 +++++++++--- sound/soc/sof/intel/hda-loader.c | 42 ++++++++++++++++++++++++++++++-- sound/soc/sof/intel/hda-stream.c | 2 +- sound/soc/sof/intel/hda.h | 3 +++ sound/soc/sof/ipc4.c | 1 + 5 files changed, 56 insertions(+), 7 deletions(-)
The FIFOS (FIFO Size) field is in bit 0-15 of the register. Use the defined mask instead of a magic number for the FIFOS value masking in hda_dsp_stream_hw_params().
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Chao Song chao.song@linux.intel.com --- sound/soc/sof/intel/hda-stream.c | 2 +- sound/soc/sof/intel/hda.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 0b0087abcc50..65e9242365be 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -668,7 +668,7 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, sd_offset + SOF_HDA_ADSP_REG_SD_FIFOSIZE); - hstream->fifo_size &= 0xffff; + hstream->fifo_size &= SOF_HDA_SD_FIFOSIZE_FIFOS_MASK; hstream->fifo_size += 1; } else { hstream->fifo_size = 0; diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 5c517ec57d4a..2b228c63905b 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -135,6 +135,9 @@ #define SOF_HDA_ADSP_REG_SD_BDLPU 0x1C #define SOF_HDA_ADSP_SD_ENTRY_SIZE 0x20
+/* SDxFIFOS FIFOS */ +#define SOF_HDA_SD_FIFOSIZE_FIFOS_MASK GENMASK(15, 0) + /* CL: Software Position Based FIFO Capability Registers */ #define SOF_DSP_REG_CL_SPBFIFO \ (SOF_HDA_ADSP_LOADER_BASE + 0x20)
On Intel platforms there is a strict order requirement for the DMA programming: DSP side configures the buffer and sets the GEN bit Host side sets the RUN bit.
In order to follow this flow, a new global message type has been added to prepare the DSP side of the DMA:
host sends LOAD_LIBRARY_PREPARE with the dma_id DSP side sets its buffer and sets the GEN bit Host sets the RUN bit Host sends LOAD_LIBRARY with dma_id and lib_id DSP receives the library data.
It is up to the platform code to use the new prepare stage message and how to handle the reply to it from the firmware, which can indicate that the message type is not supported/handled. In this case the kernel should proceed to the LOAD_LIBRARY stage assuming a single stage library loading:
host sends LOAD_LIBRARY_PREPARE with the dma_id DSP replies that the message type is not supported/handled Host acknowledges the return code and sets the RUN bit Host sends LOAD_LIBRARY with dma_id and lib_id DSP receives the library data.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Chao Song chao.song@linux.intel.com --- include/sound/sof/ipc4/header.h | 15 +++++++++++---- sound/soc/sof/ipc4.c | 1 + 2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h index 78568abe2673..c58f00ef054a 100644 --- a/include/sound/sof/ipc4/header.h +++ b/include/sound/sof/ipc4/header.h @@ -106,12 +106,19 @@ enum sof_ipc4_global_msg { SOF_IPC4_GLB_SAVE_PIPELINE, SOF_IPC4_GLB_RESTORE_PIPELINE,
- /* Loads library (using Code Load or HD/A Host Output DMA) */ + /* + * library loading + * + * Loads library (using Code Load or HD/A Host Output DMA) + */ SOF_IPC4_GLB_LOAD_LIBRARY, + /* + * Prepare the host DMA channel for library loading, must be followed by + * a SOF_IPC4_GLB_LOAD_LIBRARY message as the library loading step + */ + SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE,
- /* 25: RESERVED - do not use */ - - SOF_IPC4_GLB_INTERNAL_MESSAGE = 26, + SOF_IPC4_GLB_INTERNAL_MESSAGE,
/* Notification (FW to SW driver) */ SOF_IPC4_GLB_NOTIFICATION, diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index 24e9c29f3579..e14924048eb5 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -157,6 +157,7 @@ static const char * const ipc4_dbg_glb_msg_type[] = { DBG_IPC4_MSG_TYPE_ENTRY(GLB_SAVE_PIPELINE), DBG_IPC4_MSG_TYPE_ENTRY(GLB_RESTORE_PIPELINE), DBG_IPC4_MSG_TYPE_ENTRY(GLB_LOAD_LIBRARY), + DBG_IPC4_MSG_TYPE_ENTRY(GLB_LOAD_LIBRARY_PREPARE), DBG_IPC4_MSG_TYPE_ENTRY(GLB_INTERNAL_MESSAGE), DBG_IPC4_MSG_TYPE_ENTRY(GLB_NOTIFICATION), };
There is a certain sequence needs to be followed when configuring the HDA DMA in host and DSP. The firmware provides a way to handle this two stage sequencing by splitting the library loading into two stage: 1st stage: LOAD_LIBRARY_PREPARE message the lib_id is 0, used to configure the DMA on DSP side 2nd stage: LOAD_LIBRARY message both dma_id and lib_id is valid, used for the actual transfer of the library
In case a firmware without support for this two stage loading is used then the second stage message will trigger the loading and the first stage will return with error, which is ignored by the kernel.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Chao Song chao.song@linux.intel.com --- sound/soc/sof/intel/hda-loader.c | 42 ++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 50ce6b190002..1e2669a8088d 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -545,11 +545,40 @@ int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev,
memcpy(dmab.area, stripped_firmware.data, stripped_firmware.size);
+ /* + * 1st stage: SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE + * Message includes the dma_id to be prepared for the library loading. + * If the firmware does not have support for the message, we will + * receive -EOPNOTSUPP. In this case we will use single step library + * loading and proceed to send the LOAD_LIBRARY message. + */ 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_TYPE_SET(SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE); 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 = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); + if (!ret) { + int sd_offset = SOF_STREAM_SD_OFFSET(&hext_stream->hstream); + unsigned int status; + + /* + * Make sure that the FIFOS value is not 0 in SDxFIFOS register + * which indicates that the firmware set the GEN bit and we can + * continue to start the DMA + */ + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR, + sd_offset + SOF_HDA_ADSP_REG_SD_FIFOSIZE, + status, + status & SOF_HDA_SD_FIFOSIZE_FIFOS_MASK, + HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_BASEFW_TIMEOUT_US); + + if (ret < 0) + dev_warn(sdev->dev, + "%s: timeout waiting for FIFOS\n", __func__); + } else if (ret != -EOPNOTSUPP) { + goto cleanup; + }
ret = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_START); if (ret < 0) { @@ -557,8 +586,17 @@ int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev, goto cleanup; }
+ /* + * 2nd stage: LOAD_LIBRARY + * Message includes the dma_id and the lib_id, the dma_id must be + * identical to the one sent via LOAD_LIBRARY_PREPARE + */ + msg.primary &= ~SOF_IPC4_MSG_TYPE_MASK; + msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_LOAD_LIBRARY); + msg.primary |= SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(fw_lib->id); ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
+ /* Stop the DMA channel */ ret1 = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_STOP); if (ret1 < 0) { dev_err(sdev->dev, "%s: DMA trigger stop failed\n", __func__);
On 15/09/2023 14:39, Peter Ujfalusi wrote:
Hi,
This series implements support for split library loading to comply with the HDA DMA programming sequence recommendation, which is:
- DSP side DMA programming and GEN bit set to 1
- host side DMA programming and RUN bit set to 1
The SOF support for library loading is based on this sequence, backwards compatibility with older reference firmware is supported (where only the LOAD_LIBRARY message is supported).
Regards, Peter
Peter Ujfalusi (3): ASoC: SOF: Intel: hda: Add definition for SDxFIFOS.FIFOS mask ASoC: SOF: ipc4: Add new message type: SOF_IPC4_GLB_LOAD_LIBRARY_PREPARE ASoC: SOF: Intel: hda-loader: Add support for split library loading
There is something off with my scripts, one patch is missing, send the series again with the four patch, please ignore this set.
include/sound/sof/ipc4/header.h | 15 +++++++++--- sound/soc/sof/intel/hda-loader.c | 42 ++++++++++++++++++++++++++++++-- sound/soc/sof/intel/hda-stream.c | 2 +- sound/soc/sof/intel/hda.h | 3 +++ sound/soc/sof/ipc4.c | 1 + 5 files changed, 56 insertions(+), 7 deletions(-)
participants (1)
-
Peter Ujfalusi