Skip to content

Commit

Permalink
copier: dai: use HDA dai to configure soundwire on LNL
Browse files Browse the repository at this point in the history
Since LNL soundwire uses HDA DMA to transfer data add LNL specific
configuration to select HDA DMA in case of soundwire audio interface.
Refactor copier dai code for sndw/alh node id type.

Add support for sndw link aggregation mode for LNL platform based on
DMA config being sent during Copier Init Instance IPC.

Signed-off-by: Ievgen Ganakov <ievgen.ganakov@intel.com>
  • Loading branch information
iganakov committed Oct 31, 2023
1 parent 01f03d2 commit b31b017
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 43 deletions.
127 changes: 84 additions & 43 deletions src/audio/copier/copier_dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,78 @@ static int copier_set_alh_multi_gtw_channel_map(struct comp_dev *dev,
return 0;
}

static int copier_alh_assign_dai_index(struct comp_dev *dev,
void *gtw_cfg_data,
union ipc4_connector_node_id node_id,
struct ipc_config_dai *dai,
int *dai_index,
int *dai_count)
{
struct processing_module *mod = comp_get_drvdata(dev);
struct copier_data *cd = module_get_private_data(mod);
const struct sof_alh_configuration_blob *alh_blob = gtw_cfg_data;
int ret, i, dai_num;

if (!cd->config.gtw_cfg.config_length) {
comp_err(mod->dev, "No gateway config found in blob!");
return -EINVAL;
}

#if defined(CONFIG_ACE_VERSION_2_0)
size_t alh_cfg_size = get_alh_config_size(alh_blob);
uint8_t *dma_config = (uint8_t *)gtw_cfg_data + alh_cfg_size;
size_t dma_config_length = (cd->config.gtw_cfg.config_length << 2) - alh_cfg_size;
uint32_t dma_ch_id;

if (!is_multi_gateway(node_id)) {
ret = ipc4_find_dma_config_multiple(dai, dma_config, dma_config_length,
alh_blob->alh_cfg.mapping[0].alh_id);
if (ret != 0) {
comp_err(mod->dev, "No sndw dma_config found in blob!");
return -EINVAL;
}
dai_index[0] = dai->host_dma_config[0]->stream_id;

return ret;
}

dai_num = alh_blob->alh_cfg.count;
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
return -EINVAL;
}
for (i = 0; i < dai_num; i++) {
ret = ipc4_find_dma_config_multiple(dai, dma_config,
dma_config_length,
alh_blob->alh_cfg.mapping[i].alh_id);
if (ret != 0) {
comp_err(mod->dev, "No sndw dma_config found in blob!");
return -EINVAL;
}
dai_index[i] = dai->host_dma_config[i]->stream_id;
}
*dai_count = dai_num;

#else /* defined(CONFIG_ACE_VERSION_2_0) */
if (!is_multi_gateway(node_id)) {
dai_index[0] = IPC4_ALH_DAI_INDEX(node_id.f.v_index);
return 0;
}

dai_num = alh_blob->alh_cfg.count;
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
return -EINVAL;
}

for (i = 0; i < dai_num; i++)
dai_index[i] = IPC4_ALH_DAI_INDEX(alh_blob->alh_cfg.mapping[i].alh_id);

*dai_count = dai_num;
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
return 0;
}

static int copier_dai_init(struct comp_dev *dev,
struct comp_ipc_config *config,
const struct ipc4_copier_module_cfg *copier,
Expand Down Expand Up @@ -100,7 +172,8 @@ static int copier_dai_init(struct comp_dev *dev,
}

/* save the channel map and count for ALH multi-gateway */
if (type == ipc4_gtw_alh && is_multi_gateway(copier->gtw_cfg.node_id)) {
if ((type == ipc4_gtw_alh || type == ipc4_gtw_link)
&& is_multi_gateway(copier->gtw_cfg.node_id)) {
ret = copier_set_alh_multi_gtw_channel_map(dev, copier, index);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -182,50 +255,19 @@ int copier_dai_create(struct comp_dev *dev, struct copier_data *cd,
break;
case ipc4_alh_link_output_class:
case ipc4_alh_link_input_class:
#if defined(CONFIG_ACE_VERSION_2_0)
dai.type = SOF_DAI_INTEL_HDA;
dai.is_config_blob = true;
type = ipc4_gtw_link;
#else
dai.type = SOF_DAI_INTEL_ALH;
dai.is_config_blob = true;
type = ipc4_gtw_alh;

/* copier
* {
* gtw_cfg
* {
* gtw_node_id;
* config_length;
* config_data
* {
* count;
* {
* node_id; \\ normal gtw id
* mask;
* } mapping[MAX_ALH_COUNT];
* }
* }
* }
*/
/* get gtw node id in config data */
if (is_multi_gateway(node_id)) {
if (copier->gtw_cfg.config_length) {
const struct sof_alh_configuration_blob *alh_blob =
(const struct sof_alh_configuration_blob *)
copier->gtw_cfg.config_data;

dai_count = alh_blob->alh_cfg.count;
if (dai_count > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_count < 0) {
comp_err(dev, "Invalid dai_count: %d", dai_count);
return -EINVAL;
}
for (i = 0; i < dai_count; i++)
dai_index[i] =
IPC4_ALH_DAI_INDEX(alh_blob->alh_cfg.mapping[i].alh_id);
} else {
comp_err(dev, "No ipc4_alh_multi_gtw_cfg found in blob!");
return -EINVAL;
}
} else {
dai_index[dai_count - 1] = IPC4_ALH_DAI_INDEX(node_id.f.v_index);
}

#endif /* defined(CONFIG_ACE_VERSION_2_0) */
ret = copier_alh_assign_dai_index(dev, cd->gtw_cfg, node_id,
&dai, dai_index, &dai_count);
if (ret)
return ret;
break;
case ipc4_dmic_link_input_class:
dai.type = SOF_DAI_INTEL_DMIC;
Expand Down Expand Up @@ -426,7 +468,6 @@ int copier_dai_params(struct copier_data *cd, struct comp_dev *dev,
cd->converter[IPC4_COPIER_GATEWAY_PIN];
return ret;
}

/* For ALH multi-gateway case, params->channels is a total multiplexed
* number of channels. Demultiplexed number of channels for each individual
* gateway comes in blob's struct ipc4_alh_multi_gtw_cfg.
Expand Down
8 changes: 8 additions & 0 deletions src/include/ipc4/alh.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,12 @@ struct sof_alh_configuration_blob {
struct ipc4_alh_multi_gtw_cfg alh_cfg;
} __attribute__((packed, aligned(4)));

static inline size_t
get_alh_config_size(const struct sof_alh_configuration_blob *alh_blob)
{
return sizeof(alh_blob->gtw_attributes) +
sizeof(alh_blob->alh_cfg.count) +
sizeof(alh_blob->alh_cfg.mapping[0]) * alh_blob->alh_cfg.count;
}

#endif
25 changes: 25 additions & 0 deletions src/ipc/ipc4/dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <sof/audio/module_adapter/module/generic.h>

LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);

Expand Down Expand Up @@ -83,6 +84,30 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void
#endif
break;
case SOF_DAI_INTEL_HDA:
#if defined(CONFIG_ACE_VERSION_2_0)
if (copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_output_class ||
copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_input_class) {
struct processing_module *mod = comp_get_drvdata(dev);
struct copier_data *cd = module_get_private_data(mod);

channel = DMA_CHAN_INVALID;

if (!cd->gtw_cfg) {
comp_err(dev, "No gateway config found!");
return channel;
}

const struct sof_alh_configuration_blob *alh_blob = cd->gtw_cfg;

for (int i = 0; i < alh_blob->alh_cfg.count; i++) {
if (dai->host_dma_config[i]->stream_id == dai->dai_index) {
channel = dai->host_dma_config[i]->dma_channel_id;
break;
}
}
break;
}
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
channel = copier_cfg->gtw_cfg.node_id.f.v_index;
break;
case SOF_DAI_INTEL_ALH:
Expand Down

0 comments on commit b31b017

Please sign in to comment.