Skip to content

Commit 0a40e5d

Browse files
ipc4: uaol: add ipc4_find_dma_config_tlv()
This adds yet another function to parse DMA config supplied by the host. Unfortunately, we now have three functions for this purpose. Unlike the existing ipc4_find_dma_config(), ipc4_find_dma_config_tlv() can find multiple DMA configs. For example, a UAOL copier may use two DMA channels: one for the audio USB endpoint and one for the feedback USB endpoint. ipc4_find_dma_config_tlv() can only work when all data in data_buffer is in TLV format; unfortunately, this is not always the case with IPC4 for all gateway types. Therefore, the existing ipc4_find_dma_config() is still needed as it can skip non-TLV blob data at the beginning of data_buffer. The other function, ipc4_find_dma_config_multiple(), works differently: it searches for DMA config for a given ALH stream ID in ALH multi-gateway case. Hence, this third function -- ipc4_find_dma_config_tlv() -- is added to the family :-/. Signed-off-by: Serhiy Katsyuba <serhiy.katsyuba@intel.com>
1 parent db50e84 commit 0a40e5d

3 files changed

Lines changed: 39 additions & 1 deletion

File tree

src/audio/copier/copier_dai.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ __cold int copier_dai_create(struct comp_dev *dev, struct copier_data *cd,
327327
dai.type = SOF_DAI_INTEL_UAOL;
328328
dai.is_config_blob = true;
329329
cd->gtw_type = ipc4_gtw_alh;
330-
ret = ipc4_find_dma_config(&dai, gtw_cfg_data, gtw_cfg_size);
330+
ret = ipc4_find_dma_config_tlv(&dai, gtw_cfg_data, gtw_cfg_size);
331331
if (ret != IPC4_SUCCESS) {
332332
comp_err(dev, "No uaol dma_config found in blob!");
333333
return -EINVAL;

src/include/sof/ipc/topology.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ int ipc4_trigger_chain_dma(struct ipc *ipc, struct ipc4_chain_dma *cdma, bool *d
5656
int ipc4_process_on_core(uint32_t core, bool blocking);
5757
int ipc4_pipeline_complete(struct ipc *ipc, uint32_t comp_id, uint32_t cmd);
5858
int ipc4_find_dma_config(struct ipc_config_dai *dai, uint8_t *data_buffer, uint32_t size);
59+
int ipc4_find_dma_config_tlv(struct ipc_config_dai *dai, uint8_t *data_buffer, size_t size);
5960
int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd);
6061
int ipc4_pipeline_trigger(struct ipc_comp_dev *ppl_icd, uint32_t cmd, bool *delayed);
6162
int ipc4_find_dma_config_multiple(struct ipc_config_dai *dai, uint8_t *data_buffer,

src/ipc/ipc4/helper.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,43 @@ int ipc4_find_dma_config(struct ipc_config_dai *dai, uint8_t *data_buffer, uint3
12991299
return IPC4_SUCCESS;
13001300
}
13011301

1302+
/* Unlike the above ipc4_find_dma_config(), this can find multiple DMA configs.
1303+
* For example, a UAOL copier may use two DMA channels: one for audio and one
1304+
* for clock feedback. This function can only work when all data in data_buffer
1305+
* is in TLV format; however, this is not always the case for all gateway types.
1306+
* Therefore, the above ipc4_find_dma_config() is still used as it can skip non-TLV
1307+
* blob data at the beginning of data_buffer.
1308+
*/
1309+
int ipc4_find_dma_config_tlv(struct ipc_config_dai *dai, uint8_t *data_buffer, size_t size)
1310+
{
1311+
uint8_t *end_addr = data_buffer + size;
1312+
struct sof_tlv *tlvs;
1313+
struct ipc_dma_config *dma_cfg;
1314+
int count = 0;
1315+
1316+
for (tlvs = (struct sof_tlv *)data_buffer; (uint8_t *)tlvs < end_addr;
1317+
tlvs = tlv_next(tlvs)) {
1318+
dma_cfg = tlv_value_ptr_get(tlvs, GTW_DMA_CONFIG_ID);
1319+
if (!dma_cfg)
1320+
continue;
1321+
1322+
if (count >= GTW_DMA_DEVICE_MAX_COUNT) {
1323+
tr_err(&ipc_tr, "Unexpected DMA config count %d, max %d",
1324+
count, GTW_DMA_DEVICE_MAX_COUNT);
1325+
return IPC4_INVALID_REQUEST;
1326+
}
1327+
1328+
dai->host_dma_config[count++] = dma_cfg;
1329+
}
1330+
1331+
if (count == 0) {
1332+
tr_err(&ipc_tr, "No DMA config found");
1333+
return IPC4_INVALID_REQUEST;
1334+
}
1335+
1336+
return IPC4_SUCCESS;
1337+
}
1338+
13021339
int ipc4_find_dma_config_multiple(struct ipc_config_dai *dai, uint8_t *data_buffer,
13031340
uint32_t size, uint32_t device_id, int dma_cfg_idx)
13041341
{

0 commit comments

Comments
 (0)