Skip to content

Commit 3bb6ca5

Browse files
committed
copier: dai: use HDA dai to configure soundwire on LNL
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>
1 parent f208969 commit 3bb6ca5

3 files changed

Lines changed: 117 additions & 43 deletions

File tree

src/audio/copier/copier_dai.c

Lines changed: 84 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,78 @@ static int copier_set_alh_multi_gtw_channel_map(struct comp_dev *dev,
6464
return 0;
6565
}
6666

67+
static int copier_alh_assign_dai_index(struct comp_dev *dev,
68+
void *gtw_cfg_data,
69+
union ipc4_connector_node_id node_id,
70+
struct ipc_config_dai *dai,
71+
int *dai_index,
72+
int *dai_count)
73+
{
74+
struct processing_module *mod = comp_get_drvdata(dev);
75+
struct copier_data *cd = module_get_private_data(mod);
76+
const struct sof_alh_configuration_blob *alh_blob = gtw_cfg_data;
77+
int i, dai_num;
78+
79+
if (!cd->config.gtw_cfg.config_length) {
80+
comp_err(mod->dev, "No gateway config found in blob!");
81+
return -EINVAL;
82+
}
83+
84+
#if defined(CONFIG_ACE_VERSION_2_0)
85+
int ret;
86+
size_t alh_cfg_size = get_alh_config_size(alh_blob);
87+
uint8_t *dma_config = (uint8_t *)gtw_cfg_data + alh_cfg_size;
88+
size_t dma_config_length = (cd->config.gtw_cfg.config_length << 2) - alh_cfg_size;
89+
90+
if (!is_multi_gateway(node_id)) {
91+
ret = ipc4_find_dma_config_multiple(dai, dma_config, dma_config_length,
92+
alh_blob->alh_cfg.mapping[0].alh_id);
93+
if (ret != 0) {
94+
comp_err(mod->dev, "No sndw dma_config found in blob!");
95+
return -EINVAL;
96+
}
97+
dai_index[0] = dai->host_dma_config[0]->stream_id;
98+
99+
return ret;
100+
}
101+
102+
dai_num = alh_blob->alh_cfg.count;
103+
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
104+
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
105+
return -EINVAL;
106+
}
107+
for (i = 0; i < dai_num; i++) {
108+
ret = ipc4_find_dma_config_multiple(dai, dma_config,
109+
dma_config_length,
110+
alh_blob->alh_cfg.mapping[i].alh_id);
111+
if (ret != 0) {
112+
comp_err(mod->dev, "No sndw dma_config found in blob!");
113+
return -EINVAL;
114+
}
115+
dai_index[i] = dai->host_dma_config[i]->stream_id;
116+
}
117+
*dai_count = dai_num;
118+
119+
#else /* defined(CONFIG_ACE_VERSION_2_0) */
120+
if (!is_multi_gateway(node_id)) {
121+
dai_index[0] = IPC4_ALH_DAI_INDEX(node_id.f.v_index);
122+
return 0;
123+
}
124+
125+
dai_num = alh_blob->alh_cfg.count;
126+
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
127+
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
128+
return -EINVAL;
129+
}
130+
131+
for (i = 0; i < dai_num; i++)
132+
dai_index[i] = IPC4_ALH_DAI_INDEX(alh_blob->alh_cfg.mapping[i].alh_id);
133+
134+
*dai_count = dai_num;
135+
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
136+
return 0;
137+
}
138+
67139
static int copier_dai_init(struct comp_dev *dev,
68140
struct comp_ipc_config *config,
69141
const struct ipc4_copier_module_cfg *copier,
@@ -100,7 +172,8 @@ static int copier_dai_init(struct comp_dev *dev,
100172
}
101173

102174
/* save the channel map and count for ALH multi-gateway */
103-
if (type == ipc4_gtw_alh && is_multi_gateway(copier->gtw_cfg.node_id)) {
175+
if ((type == ipc4_gtw_alh || type == ipc4_gtw_link)
176+
&& is_multi_gateway(copier->gtw_cfg.node_id)) {
104177
ret = copier_set_alh_multi_gtw_channel_map(dev, copier, index);
105178
if (ret < 0)
106179
return ret;
@@ -182,50 +255,19 @@ int copier_dai_create(struct comp_dev *dev, struct copier_data *cd,
182255
break;
183256
case ipc4_alh_link_output_class:
184257
case ipc4_alh_link_input_class:
258+
#if defined(CONFIG_ACE_VERSION_2_0)
259+
dai.type = SOF_DAI_INTEL_HDA;
260+
dai.is_config_blob = true;
261+
type = ipc4_gtw_link;
262+
#else
185263
dai.type = SOF_DAI_INTEL_ALH;
186264
dai.is_config_blob = true;
187265
type = ipc4_gtw_alh;
188-
189-
/* copier
190-
* {
191-
* gtw_cfg
192-
* {
193-
* gtw_node_id;
194-
* config_length;
195-
* config_data
196-
* {
197-
* count;
198-
* {
199-
* node_id; \\ normal gtw id
200-
* mask;
201-
* } mapping[MAX_ALH_COUNT];
202-
* }
203-
* }
204-
* }
205-
*/
206-
/* get gtw node id in config data */
207-
if (is_multi_gateway(node_id)) {
208-
if (copier->gtw_cfg.config_length) {
209-
const struct sof_alh_configuration_blob *alh_blob =
210-
(const struct sof_alh_configuration_blob *)
211-
copier->gtw_cfg.config_data;
212-
213-
dai_count = alh_blob->alh_cfg.count;
214-
if (dai_count > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_count < 0) {
215-
comp_err(dev, "Invalid dai_count: %d", dai_count);
216-
return -EINVAL;
217-
}
218-
for (i = 0; i < dai_count; i++)
219-
dai_index[i] =
220-
IPC4_ALH_DAI_INDEX(alh_blob->alh_cfg.mapping[i].alh_id);
221-
} else {
222-
comp_err(dev, "No ipc4_alh_multi_gtw_cfg found in blob!");
223-
return -EINVAL;
224-
}
225-
} else {
226-
dai_index[dai_count - 1] = IPC4_ALH_DAI_INDEX(node_id.f.v_index);
227-
}
228-
266+
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
267+
ret = copier_alh_assign_dai_index(dev, cd->gtw_cfg, node_id,
268+
&dai, dai_index, &dai_count);
269+
if (ret)
270+
return ret;
229271
break;
230272
case ipc4_dmic_link_input_class:
231273
dai.type = SOF_DAI_INTEL_DMIC;
@@ -426,7 +468,6 @@ int copier_dai_params(struct copier_data *cd, struct comp_dev *dev,
426468
cd->converter[IPC4_COPIER_GATEWAY_PIN];
427469
return ret;
428470
}
429-
430471
/* For ALH multi-gateway case, params->channels is a total multiplexed
431472
* number of channels. Demultiplexed number of channels for each individual
432473
* gateway comes in blob's struct ipc4_alh_multi_gtw_cfg.

src/include/ipc4/alh.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,12 @@ struct sof_alh_configuration_blob {
6666
struct ipc4_alh_multi_gtw_cfg alh_cfg;
6767
} __attribute__((packed, aligned(4)));
6868

69+
static inline size_t
70+
get_alh_config_size(const struct sof_alh_configuration_blob *alh_blob)
71+
{
72+
return sizeof(alh_blob->gtw_attributes) +
73+
sizeof(alh_blob->alh_cfg.count) +
74+
sizeof(alh_blob->alh_cfg.mapping[0]) * alh_blob->alh_cfg.count;
75+
}
76+
6977
#endif

src/ipc/ipc4/dai.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <stdbool.h>
2929
#include <stddef.h>
3030
#include <stdint.h>
31+
#include <sof/audio/module_adapter/module/generic.h>
3132

3233
LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
3334

@@ -83,6 +84,30 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void
8384
#endif
8485
break;
8586
case SOF_DAI_INTEL_HDA:
87+
#if defined(CONFIG_ACE_VERSION_2_0)
88+
if (copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_output_class ||
89+
copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_input_class) {
90+
struct processing_module *mod = comp_get_drvdata(dev);
91+
struct copier_data *cd = module_get_private_data(mod);
92+
93+
channel = DMA_CHAN_INVALID;
94+
95+
if (!cd->gtw_cfg) {
96+
comp_err(dev, "No gateway config found!");
97+
return channel;
98+
}
99+
100+
const struct sof_alh_configuration_blob *alh_blob = cd->gtw_cfg;
101+
102+
for (int i = 0; i < alh_blob->alh_cfg.count; i++) {
103+
if (dai->host_dma_config[i]->stream_id == dai->dai_index) {
104+
channel = dai->host_dma_config[i]->dma_channel_id;
105+
break;
106+
}
107+
}
108+
break;
109+
}
110+
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
86111
channel = copier_cfg->gtw_cfg.node_id.f.v_index;
87112
break;
88113
case SOF_DAI_INTEL_ALH:

0 commit comments

Comments
 (0)