aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/sof/ipc4-topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/ipc4-topology.c')
-rw-r--r--sound/soc/sof/ipc4-topology.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index db64e0cb8663..a4e1a70b607d 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -559,7 +559,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
strcmp(w->widget->sname, swidget->widget->sname))
continue;
- blob->alh_cfg.count++;
+ blob->alh_cfg.device_count++;
}
ipc4_copier->copier_config = (uint32_t *)blob;
@@ -1225,7 +1225,7 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
unsigned int group_id;
blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
- if (blob->alh_cfg.count > 1) {
+ if (blob->alh_cfg.device_count > 1) {
group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) -
ALH_MULTI_GTW_BASE;
ida_free(&alh_group_ida, group_id);
@@ -1383,6 +1383,8 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
struct snd_sof_dai *dai;
struct snd_mask *fmt;
int out_sample_valid_bits;
+ u32 gtw_cfg_config_length;
+ u32 dma_config_tlv_size = 0;
void **ipc_config_data;
int *ipc_config_size;
u32 **data;
@@ -1609,7 +1611,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
ch_map >>= 4;
}
- step = ch_count / blob->alh_cfg.count;
+ step = ch_count / blob->alh_cfg.device_count;
mask = GENMASK(step - 1, 0);
/*
* Set each gtw_cfg.node_id to blob->alh_cfg.mapping[]
@@ -1624,7 +1626,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
dai = w->private;
alh_copier = (struct sof_ipc4_copier *)dai->private;
alh_data = &alh_copier->data;
- blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id;
+ blob->alh_cfg.mapping[i].device = alh_data->gtw_cfg.node_id;
/*
* Set the same channel mask for playback as the audio data is
* duplicated for all speakers. For capture, split the channels
@@ -1643,7 +1645,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
i++;
}
- if (blob->alh_cfg.count > 1) {
+ if (blob->alh_cfg.device_count > 1) {
int group_id;
group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1,
@@ -1699,7 +1701,27 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
ipc_config_data = &ipc4_copier->ipc_config_data;
/* config_length is DWORD based */
- ipc_size = sizeof(*copier_data) + copier_data->gtw_cfg.config_length * 4;
+ gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4;
+ ipc_size = sizeof(*copier_data) + gtw_cfg_config_length;
+
+ if (ipc4_copier->dma_config_tlv.type == SOF_IPC4_GTW_DMA_CONFIG_ID &&
+ ipc4_copier->dma_config_tlv.length) {
+ dma_config_tlv_size = sizeof(ipc4_copier->dma_config_tlv) +
+ ipc4_copier->dma_config_tlv.dma_config.dma_priv_config_size;
+
+ /* paranoia check on TLV size/length */
+ if (dma_config_tlv_size != ipc4_copier->dma_config_tlv.length +
+ sizeof(uint32_t) * 2) {
+ dev_err(sdev->dev, "Invalid configuration, TLV size %d length %d\n",
+ dma_config_tlv_size, ipc4_copier->dma_config_tlv.length);
+ return -EINVAL;
+ }
+
+ ipc_size += dma_config_tlv_size;
+
+ /* we also need to increase the size at the gtw level */
+ copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4;
+ }
dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size);
@@ -1711,9 +1733,15 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
/* copy IPC data */
memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data));
- if (copier_data->gtw_cfg.config_length)
+ if (gtw_cfg_config_length)
memcpy(*ipc_config_data + sizeof(*copier_data),
- *data, copier_data->gtw_cfg.config_length * 4);
+ *data, gtw_cfg_config_length);
+
+ /* add DMA Config TLV, if configured */
+ if (dma_config_tlv_size)
+ memcpy(*ipc_config_data + sizeof(*copier_data) +
+ gtw_cfg_config_length,
+ &ipc4_copier->dma_config_tlv, dma_config_tlv_size);
/* update pipeline memory usage */
sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config);