Commit 8d7c1a57 authored by Mark Brown's avatar Mark Brown

ASoC: SOF: Intel/ipc4: Do not reset BE DAI pipeline

Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>:

Do not reset pipelines during the stop/suspend triggers in the BE DAI
ops as the BE DAI pipeline needs to be left in the PAUSED state. It should
only be reset during hw_free. This simplification is already done for
the FE pipelines and the DAI trigger only toggles the states between
PAUSED and RUNNING.
parents 3959cd3d 225f37b5
...@@ -120,6 +120,26 @@ static struct hdac_ext_stream *hda_get_hext_stream(struct snd_sof_dev *sdev, ...@@ -120,6 +120,26 @@ static struct hdac_ext_stream *hda_get_hext_stream(struct snd_sof_dev *sdev,
return snd_soc_dai_get_dma_data(cpu_dai, substream); return snd_soc_dai_get_dma_data(cpu_dai, substream);
} }
static struct hdac_ext_stream *hda_ipc4_get_hext_stream(struct snd_sof_dev *sdev,
struct snd_soc_dai *cpu_dai,
struct snd_pcm_substream *substream)
{
struct snd_sof_widget *pipe_widget;
struct sof_ipc4_pipeline *pipeline;
struct snd_sof_widget *swidget;
struct snd_soc_dapm_widget *w;
w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
swidget = w->dobj.private;
pipe_widget = swidget->spipe->pipe_widget;
pipeline = pipe_widget->private;
/* mark pipeline so that it can be skipped during FE trigger */
pipeline->skip_during_fe_trigger = true;
return snd_soc_dai_get_dma_data(cpu_dai, substream);
}
static struct hdac_ext_stream *hda_assign_hext_stream(struct snd_sof_dev *sdev, static struct hdac_ext_stream *hda_assign_hext_stream(struct snd_sof_dev *sdev,
struct snd_soc_dai *cpu_dai, struct snd_soc_dai *cpu_dai,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
...@@ -158,6 +178,7 @@ static void hda_reset_hext_stream(struct snd_sof_dev *sdev, struct hdac_ext_stre ...@@ -158,6 +178,7 @@ static void hda_reset_hext_stream(struct snd_sof_dev *sdev, struct hdac_ext_stre
static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
struct snd_pcm_substream *substream, int cmd) struct snd_pcm_substream *substream, int cmd)
{ {
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct snd_sof_widget *pipe_widget; struct snd_sof_widget *pipe_widget;
struct sof_ipc4_pipeline *pipeline; struct sof_ipc4_pipeline *pipeline;
struct snd_sof_widget *swidget; struct snd_sof_widget *swidget;
...@@ -169,6 +190,8 @@ static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cp ...@@ -169,6 +190,8 @@ static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cp
pipe_widget = swidget->spipe->pipe_widget; pipe_widget = swidget->spipe->pipe_widget;
pipeline = pipe_widget->private; pipeline = pipe_widget->private;
mutex_lock(&ipc4_data->pipeline_state_mutex);
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
...@@ -179,7 +202,7 @@ static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cp ...@@ -179,7 +202,7 @@ static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cp
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_PAUSED); SOF_IPC4_PIPE_PAUSED);
if (ret < 0) if (ret < 0)
return ret; goto out;
pipeline->state = SOF_IPC4_PIPE_PAUSED; pipeline->state = SOF_IPC4_PIPE_PAUSED;
break; break;
...@@ -187,7 +210,8 @@ static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cp ...@@ -187,7 +210,8 @@ static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cp
dev_err(sdev->dev, "unknown trigger command %d\n", cmd); dev_err(sdev->dev, "unknown trigger command %d\n", cmd);
return -EINVAL; return -EINVAL;
} }
out:
mutex_unlock(&ipc4_data->pipeline_state_mutex);
return 0; return 0;
} }
...@@ -217,57 +241,66 @@ static int hda_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, ...@@ -217,57 +241,66 @@ static int hda_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
static int hda_ipc4_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, static int hda_ipc4_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
struct snd_pcm_substream *substream, int cmd) struct snd_pcm_substream *substream, int cmd)
{ {
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct snd_sof_widget *pipe_widget; struct snd_sof_widget *pipe_widget;
struct sof_ipc4_pipeline *pipeline; struct sof_ipc4_pipeline *pipeline;
struct snd_sof_widget *swidget; struct snd_sof_widget *swidget;
struct snd_soc_dapm_widget *w; struct snd_soc_dapm_widget *w;
int ret; int ret = 0;
w = snd_soc_dai_get_widget(cpu_dai, substream->stream); w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
swidget = w->dobj.private; swidget = w->dobj.private;
pipe_widget = swidget->spipe->pipe_widget; pipe_widget = swidget->spipe->pipe_widget;
pipeline = pipe_widget->private; pipeline = pipe_widget->private;
mutex_lock(&ipc4_data->pipeline_state_mutex);
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (pipeline->state != SOF_IPC4_PIPE_PAUSED) { if (pipeline->state != SOF_IPC4_PIPE_PAUSED) {
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_PAUSED); SOF_IPC4_PIPE_PAUSED);
if (ret < 0) if (ret < 0)
return ret; goto out;
pipeline->state = SOF_IPC4_PIPE_PAUSED; pipeline->state = SOF_IPC4_PIPE_PAUSED;
} }
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_RUNNING); SOF_IPC4_PIPE_RUNNING);
if (ret < 0) if (ret < 0)
return ret; goto out;
pipeline->state = SOF_IPC4_PIPE_RUNNING; pipeline->state = SOF_IPC4_PIPE_RUNNING;
swidget->spipe->started_count++;
break; break;
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_STOP:
{
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_RESET); SOF_IPC4_PIPE_RUNNING);
if (ret < 0) if (ret < 0)
return ret; goto out;
pipeline->state = SOF_IPC4_PIPE_RUNNING;
pipeline->state = SOF_IPC4_PIPE_RESET; break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
/*
* STOP/SUSPEND trigger is invoked only once when all users of this pipeline have
* been stopped. So, clear the started_count so that the pipeline can be reset
*/
swidget->spipe->started_count = 0;
break; break;
}
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
break; break;
default: default:
dev_err(sdev->dev, "unknown trigger command %d\n", cmd); dev_err(sdev->dev, "unknown trigger command %d\n", cmd);
return -EINVAL; ret = -EINVAL;
break;
} }
out:
return 0; mutex_unlock(&ipc4_data->pipeline_state_mutex);
return ret;
} }
static const struct hda_dai_widget_dma_ops hda_ipc4_dma_ops = { static const struct hda_dai_widget_dma_ops hda_ipc4_dma_ops = {
.get_hext_stream = hda_get_hext_stream, .get_hext_stream = hda_ipc4_get_hext_stream,
.assign_hext_stream = hda_assign_hext_stream, .assign_hext_stream = hda_assign_hext_stream,
.release_hext_stream = hda_release_hext_stream, .release_hext_stream = hda_release_hext_stream,
.setup_hext_stream = hda_setup_hext_stream, .setup_hext_stream = hda_setup_hext_stream,
......
...@@ -69,7 +69,7 @@ sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state, ...@@ -69,7 +69,7 @@ sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state,
struct snd_sof_widget *pipe_widget = spipe->pipe_widget; struct snd_sof_widget *pipe_widget = spipe->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private; struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
if (pipeline->skip_during_fe_trigger) if (pipeline->skip_during_fe_trigger && state != SOF_IPC4_PIPE_RESET)
return; return;
switch (state) { switch (state) {
...@@ -108,7 +108,7 @@ sof_ipc4_update_pipeline_state(struct snd_sof_dev *sdev, int state, int cmd, ...@@ -108,7 +108,7 @@ sof_ipc4_update_pipeline_state(struct snd_sof_dev *sdev, int state, int cmd,
struct sof_ipc4_pipeline *pipeline = pipe_widget->private; struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
int i; int i;
if (pipeline->skip_during_fe_trigger) if (pipeline->skip_during_fe_trigger && state != SOF_IPC4_PIPE_RESET)
return; return;
/* set state for pipeline if it was just triggered */ /* set state for pipeline if it was just triggered */
......
...@@ -2500,7 +2500,6 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget * ...@@ -2500,7 +2500,6 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
} }
gtw_attr = ipc4_copier->gtw_attr; gtw_attr = ipc4_copier->gtw_attr;
gtw_attr->lp_buffer_alloc = pipeline->lp_mode; gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
pipeline->skip_during_fe_trigger = true;
fallthrough; fallthrough;
case SOF_DAI_INTEL_ALH: case SOF_DAI_INTEL_ALH:
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment