Skip to content

Commit a1deb74

Browse files
iganakovkv2019i
authored andcommitted
copier: dai: use HD-A dai to configure soundwire on LNL
Since LNL soundwire uses HD-A DMA to transfer data. Add LNL specific configuration to select HD-A 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 21bcf73 commit a1deb74

File tree

3 files changed

+134
-43
lines changed

3 files changed

+134
-43
lines changed

src/audio/copier/copier_dai.c

Lines changed: 102 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,96 @@ 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+
uint8_t *dma_config;
78+
size_t alh_cfg_size, dma_config_length;
79+
int i, dai_num, ret;
80+
81+
if (!cd->config.gtw_cfg.config_length) {
82+
comp_err(mod->dev, "No gateway config found in blob!");
83+
return -EINVAL;
84+
}
85+
86+
switch (dai->type) {
87+
case SOF_DAI_INTEL_HDA:
88+
/* We use DAI_INTEL_HDA for ACE 2.0 platforms */
89+
alh_cfg_size = get_alh_config_size(alh_blob);
90+
dma_config = (uint8_t *)gtw_cfg_data + alh_cfg_size;
91+
dma_config_length = (cd->config.gtw_cfg.config_length << 2) - alh_cfg_size;
92+
93+
/* Here we check node_id if we need to use FW aggregation,
94+
* in other words do we need to create multiple dai or not
95+
*/
96+
if (!is_multi_gateway(node_id)) {
97+
/* Find DMA config in blob and retrieve stream_id */
98+
ret = ipc4_find_dma_config_multiple(dai, dma_config, dma_config_length,
99+
alh_blob->alh_cfg.mapping[0].alh_id, 0);
100+
if (ret != 0) {
101+
comp_err(mod->dev, "No sndw dma_config found in blob!");
102+
return -EINVAL;
103+
}
104+
dai_index[0] = dai->host_dma_config[0]->stream_id;
105+
return 0;
106+
}
107+
108+
dai_num = alh_blob->alh_cfg.count;
109+
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
110+
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
111+
return -EINVAL;
112+
}
113+
114+
for (i = 0; i < dai_num; i++) {
115+
ret = ipc4_find_dma_config_multiple(dai, dma_config,
116+
dma_config_length,
117+
alh_blob->alh_cfg.mapping[i].alh_id, i);
118+
if (ret != 0) {
119+
comp_err(mod->dev, "No sndw dma_config found in blob!");
120+
return -EINVAL;
121+
}
122+
123+
/* To process data on SoundWire interface HD-A DMA is used so it seems
124+
* logical to me to use stream tag as a dai_index instead of PDI.
125+
*/
126+
dai_index[i] = dai->host_dma_config[i]->stream_id;
127+
}
128+
129+
*dai_count = dai_num;
130+
break;
131+
case SOF_DAI_INTEL_ALH:
132+
/* Use DAI_INTEL_ALH for ACE 1.0 and older */
133+
if (!is_multi_gateway(node_id)) {
134+
dai_index[0] = IPC4_ALH_DAI_INDEX(node_id.f.v_index);
135+
return 0;
136+
}
137+
138+
dai_num = alh_blob->alh_cfg.count;
139+
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
140+
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
141+
return -EINVAL;
142+
}
143+
144+
for (i = 0; i < dai_num; i++)
145+
dai_index[i] = IPC4_ALH_DAI_INDEX(alh_blob->alh_cfg.mapping[i].alh_id);
146+
147+
*dai_count = dai_num;
148+
break;
149+
default:
150+
comp_err(mod->dev, "Invalid dai type selected: %d", dai->type);
151+
return -EINVAL;
152+
}
153+
154+
return 0;
155+
}
156+
67157
static int copier_dai_init(struct comp_dev *dev,
68158
struct comp_ipc_config *config,
69159
const struct ipc4_copier_module_cfg *copier,
@@ -100,7 +190,8 @@ static int copier_dai_init(struct comp_dev *dev,
100190
}
101191

102192
/* save the channel map and count for ALH multi-gateway */
103-
if (type == ipc4_gtw_alh && is_multi_gateway(copier->gtw_cfg.node_id)) {
193+
if ((type == ipc4_gtw_alh || type == ipc4_gtw_link) &&
194+
is_multi_gateway(copier->gtw_cfg.node_id)) {
104195
ret = copier_set_alh_multi_gtw_channel_map(dev, copier, index);
105196
if (ret < 0)
106197
return ret;
@@ -182,50 +273,19 @@ int copier_dai_create(struct comp_dev *dev, struct copier_data *cd,
182273
break;
183274
case ipc4_alh_link_output_class:
184275
case ipc4_alh_link_input_class:
276+
#if defined(CONFIG_ACE_VERSION_2_0)
277+
dai.type = SOF_DAI_INTEL_HDA;
278+
dai.is_config_blob = true;
279+
type = ipc4_gtw_link;
280+
#else
185281
dai.type = SOF_DAI_INTEL_ALH;
186282
dai.is_config_blob = true;
187283
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-
284+
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
285+
ret = copier_alh_assign_dai_index(dev, cd->gtw_cfg, node_id,
286+
&dai, dai_index, &dai_count);
287+
if (ret)
288+
return ret;
229289
break;
230290
case ipc4_dmic_link_input_class:
231291
dai.type = SOF_DAI_INTEL_DMIC;
@@ -425,7 +485,6 @@ int copier_dai_params(struct copier_data *cd, struct comp_dev *dev,
425485
cd->converter[IPC4_COPIER_GATEWAY_PIN];
426486
return ret;
427487
}
428-
429488
/* For ALH multi-gateway case, params->channels is a total multiplexed
430489
* number of channels. Demultiplexed number of channels for each individual
431490
* 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: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <stdbool.h>
2727
#include <stddef.h>
2828
#include <stdint.h>
29+
#include <sof/audio/module_adapter/module/generic.h>
2930

3031
#include "../audio/copier/copier.h"
3132
#include "../audio/copier/dai_copier.h"
@@ -84,6 +85,29 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void
8485
#endif
8586
break;
8687
case SOF_DAI_INTEL_HDA:
88+
#if defined(CONFIG_ACE_VERSION_2_0)
89+
if (copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_output_class ||
90+
copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_input_class) {
91+
struct processing_module *mod = comp_get_drvdata(dev);
92+
struct copier_data *cd = module_get_private_data(mod);
93+
94+
if (!cd->gtw_cfg) {
95+
comp_err(dev, "No gateway config found!");
96+
return DMA_CHAN_INVALID;
97+
}
98+
99+
channel = DMA_CHAN_INVALID;
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) */
87111
channel = copier_cfg->gtw_cfg.node_id.f.v_index;
88112
break;
89113
case SOF_DAI_INTEL_ALH:

0 commit comments

Comments
 (0)