Skip to content

Commit

Permalink
ASoC: SOF: Intel: hda: Always clean up link DMA during stop
Browse files Browse the repository at this point in the history
This is required to reset the DMA read/write pointers when the stream is
prepared and restarted after a call to snd_pcm_drain()/snd_pcm_drop().
Modify the prepare callback for Soundwire DAIs for ACE2x to send the
stream number again during prepare without touching the SHM registers.

Link: https://github.com/thesofproject/sof/issues/9502
Signed-off-by: Ranjani Sridharan <[email protected]>
  • Loading branch information
ranj063 committed Oct 2, 2024
1 parent 8cc1a16 commit 03f5352
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 23 deletions.
19 changes: 6 additions & 13 deletions drivers/soundwire/intel_ace2x.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,12 @@ static int intel_hw_params(struct snd_pcm_substream *substream,
static int intel_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_cdns_dai_runtime *dai_runtime;
struct snd_pcm_hw_params *hw_params;
int ch, dir;
int ret = 0;

dai_runtime = cdns->dai_runtime_array[dai->id];
if (!dai_runtime) {
Expand All @@ -396,12 +397,8 @@ static int intel_prepare(struct snd_pcm_substream *substream,
return -EIO;
}

hw_params = &rtd->dpcm[substream->stream].hw_params;
if (dai_runtime->suspended) {
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_pcm_hw_params *hw_params;

hw_params = &rtd->dpcm[substream->stream].hw_params;

dai_runtime->suspended = false;

/*
Expand All @@ -422,15 +419,11 @@ static int intel_prepare(struct snd_pcm_substream *substream,
/* the SHIM will be configured in the callback functions */

sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi);

/* Inform DSP about PDI stream number */
ret = intel_params_stream(sdw, substream, dai,
hw_params,
sdw->instance,
dai_runtime->pdi->intel_alh_id);
}

return ret;
/* Inform DSP about PDI stream number */
return intel_params_stream(sdw, substream, dai, hw_params, sdw->instance,
dai_runtime->pdi->intel_alh_id);
}

static int
Expand Down
4 changes: 0 additions & 4 deletions sound/soc/sof/intel/hda-dai-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@ static const struct hda_dai_widget_dma_ops sdw_ipc4_chain_dma_ops = {
static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
struct snd_pcm_substream *substream, int cmd)
{
struct hdac_ext_stream *hext_stream = hda_get_hext_stream(sdev, cpu_dai, substream);
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);

switch (cmd) {
Expand All @@ -527,9 +526,6 @@ static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *c
if (ret < 0)
return ret;

if (cmd == SNDRV_PCM_TRIGGER_STOP)
return hda_link_dma_cleanup(substream, hext_stream, cpu_dai);

break;
}
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
Expand Down
30 changes: 26 additions & 4 deletions sound/soc/sof/intel/hda-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i
}

switch (cmd) {
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
ret = hda_link_dma_cleanup(substream, hext_stream, dai);
if (ret < 0) {
Expand Down Expand Up @@ -370,14 +371,18 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream,
return -EINVAL;
}

sdev = widget_to_sdev(w);
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
if (hext_stream && hext_stream->link_prepared)
return 0;

/* use HDaudio stream handling */
ret = hda_dai_hw_params_data(substream, params, cpu_dai, data, flags);
if (ret < 0) {
dev_err(cpu_dai->dev, "%s: hda_dai_hw_params_data failed: %d\n", __func__, ret);
return ret;
}

sdev = widget_to_sdev(w);
if (sdev->dspless_mode_selected)
return 0;

Expand Down Expand Up @@ -482,6 +487,26 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
int ret;
int i;

ops = hda_dai_get_ops(substream, cpu_dai);
if (!ops) {
dev_err(cpu_dai->dev, "DAI widget ops not set\n");
return -EINVAL;
}

sdev = widget_to_sdev(w);
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
if (hext_stream && hext_stream->link_prepared)
return 0;

/* reset the PCMSyCM registers */
ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id,
0, 0, substream->stream);
if (ret < 0) {
dev_err(cpu_dai->dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d\n",
__func__, ret);
return ret;
}

data.dai_index = (link_id << 8) | cpu_dai->id;
data.dai_node_id = intel_alh_id;
ret = non_hda_dai_hw_params_data(substream, params, cpu_dai, &data, flags);
Expand All @@ -490,10 +515,7 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
return ret;
}

ops = hda_dai_get_ops(substream, cpu_dai);
sdev = widget_to_sdev(w);
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);

if (!hext_stream)
return -ENODEV;

Expand Down
15 changes: 13 additions & 2 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -3250,9 +3250,20 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
* group_id during copier's ipc_prepare op.
*/
if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
struct sof_ipc4_alh_configuration_blob *blob;

blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
ipc4_copier->dai_index = data->dai_node_id;
copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_node_id);

/*
* no need to set the node_id for aggregated DAI's. These will be assigned
* a group_id during widget ipc_prepare
*/
if (blob->alh_cfg.device_count == 1) {
copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
copier_data->gtw_cfg.node_id |=
SOF_IPC4_NODE_INDEX(data->dai_node_id);
}
}

break;
Expand Down

0 comments on commit 03f5352

Please sign in to comment.