ASoC: SOF: Intel: hda-dai: set dma_stream_channel_map device

sof_ipc4_dma_config_tlv{} is required for ACE2.x. The patch follow the
convention to set the dma_stream_channel_map.mapping device as
"link_id << 8 | pdi_id".
And the mapping in sof_ipc4_alh_configuration_blob{} should be the same
as dma_stream_channel_map.mapping in sof_ipc4_dma_config{}.
The purposes of device id is to map DMA tlv.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://msgid.link/r/20240402151828.175002-7-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Bard Liao 2024-04-02 10:18:17 -05:00 committed by Mark Brown
parent 8fa10a2436
commit 17386cb1b4
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0
2 changed files with 47 additions and 2 deletions

View file

@ -346,6 +346,7 @@ static int non_hda_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai) struct snd_soc_dai *cpu_dai)
{ {
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream); struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_ipc4_dma_config_tlv *dma_config_tlv; struct sof_ipc4_dma_config_tlv *dma_config_tlv;
const struct hda_dai_widget_dma_ops *ops; const struct hda_dai_widget_dma_ops *ops;
struct sof_ipc4_dma_config *dma_config; struct sof_ipc4_dma_config *dma_config;
@ -353,6 +354,8 @@ static int non_hda_dai_hw_params(struct snd_pcm_substream *substream,
struct hdac_ext_stream *hext_stream; struct hdac_ext_stream *hext_stream;
struct hdac_stream *hstream; struct hdac_stream *hstream;
struct snd_sof_dev *sdev; struct snd_sof_dev *sdev;
struct snd_soc_dai *dai;
int cpu_dai_id;
int stream_id; int stream_id;
int ret; int ret;
@ -392,7 +395,12 @@ static int non_hda_dai_hw_params(struct snd_pcm_substream *substream,
/* configure TLV */ /* configure TLV */
ipc4_copier = widget_to_copier(w); ipc4_copier = widget_to_copier(w);
dma_config_tlv = &ipc4_copier->dma_config_tlv[0]; for_each_rtd_cpu_dais(rtd, cpu_dai_id, dai) {
if (dai == cpu_dai)
break;
}
dma_config_tlv = &ipc4_copier->dma_config_tlv[cpu_dai_id];
dma_config_tlv->type = SOF_IPC4_GTW_DMA_CONFIG_ID; dma_config_tlv->type = SOF_IPC4_GTW_DMA_CONFIG_ID;
/* dma_config_priv_size is zero */ /* dma_config_priv_size is zero */
dma_config_tlv->length = sizeof(dma_config_tlv->dma_config); dma_config_tlv->length = sizeof(dma_config_tlv->dma_config);
@ -403,7 +411,11 @@ static int non_hda_dai_hw_params(struct snd_pcm_substream *substream,
dma_config->pre_allocated_by_host = 1; dma_config->pre_allocated_by_host = 1;
dma_config->dma_channel_id = stream_id - 1; dma_config->dma_channel_id = stream_id - 1;
dma_config->stream_id = stream_id; dma_config->stream_id = stream_id;
dma_config->dma_stream_channel_map.device_count = 0; /* mapping not used */ /*
* Currently we use a DMA for each device in ALH blob. The device will
* be copied in sof_ipc4_prepare_copier_module.
*/
dma_config->dma_stream_channel_map.device_count = 1;
dma_config->dma_priv_config_size = 0; dma_config->dma_priv_config_size = 0;
skip_tlv: skip_tlv:
@ -440,7 +452,10 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream); struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sof_ipc4_dma_config_tlv *dma_config_tlv;
const struct hda_dai_widget_dma_ops *ops; const struct hda_dai_widget_dma_ops *ops;
struct sof_ipc4_dma_config *dma_config;
struct sof_ipc4_copier *ipc4_copier;
struct hdac_ext_stream *hext_stream; struct hdac_ext_stream *hext_stream;
struct snd_soc_dai *dai; struct snd_soc_dai *dai;
struct snd_sof_dev *sdev; struct snd_sof_dev *sdev;
@ -448,6 +463,7 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
int cpu_dai_id; int cpu_dai_id;
int ch_mask; int ch_mask;
int ret; int ret;
int i;
ret = non_hda_dai_hw_params(substream, params, cpu_dai); ret = non_hda_dai_hw_params(substream, params, cpu_dai);
if (ret < 0) { if (ret < 0) {
@ -489,6 +505,22 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
ipc4_copier = widget_to_copier(w);
dma_config_tlv = &ipc4_copier->dma_config_tlv[cpu_dai_id];
dma_config = &dma_config_tlv->dma_config;
dma_config->dma_stream_channel_map.mapping[0].device = link_id << 8 | cpu_dai->id;
dma_config->dma_stream_channel_map.mapping[0].channel_mask = ch_mask;
/*
* copy the dma_config_tlv to all ipc4_copier in the same link. Because only one copier
* will be handled in sof_ipc4_prepare_copier_module.
*/
for_each_rtd_cpu_dais(rtd, i, dai) {
w = snd_soc_dai_get_widget(dai, substream->stream);
ipc4_copier = widget_to_copier(w);
memcpy(&ipc4_copier->dma_config_tlv[cpu_dai_id], dma_config_tlv,
sizeof(*dma_config_tlv));
}
return 0; return 0;
} }

View file

@ -1672,6 +1672,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
*/ */
if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
struct sof_ipc4_alh_configuration_blob *blob; struct sof_ipc4_alh_configuration_blob *blob;
struct sof_ipc4_dma_config *dma_config;
struct sof_ipc4_copier_data *alh_data; struct sof_ipc4_copier_data *alh_data;
struct sof_ipc4_copier *alh_copier; struct sof_ipc4_copier *alh_copier;
struct snd_sof_widget *w; struct snd_sof_widget *w;
@ -1711,6 +1712,18 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
alh_copier = (struct sof_ipc4_copier *)dai->private; alh_copier = (struct sof_ipc4_copier *)dai->private;
alh_data = &alh_copier->data; alh_data = &alh_copier->data;
blob->alh_cfg.mapping[i].device = alh_data->gtw_cfg.node_id; blob->alh_cfg.mapping[i].device = alh_data->gtw_cfg.node_id;
/*
* The mapping[i] device in ALH blob should be the same as the
* dma_config_tlv[i] mapping device if a dma_config_tlv is present.
* The device id will be used for DMA tlv mapping purposes.
*/
if (ipc4_copier->dma_config_tlv[i].length) {
dma_config = &ipc4_copier->dma_config_tlv[i].dma_config;
blob->alh_cfg.mapping[i].device =
dma_config->dma_stream_channel_map.mapping[0].device;
}
/* /*
* Set the same channel mask for playback as the audio data is * Set the same channel mask for playback as the audio data is
* duplicated for all speakers. For capture, split the channels * duplicated for all speakers. For capture, split the channels