Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

+53 -21
+51 -18
sound/soc/sof/intel/hda-dai-ops.c
··· 120 120 return snd_soc_dai_get_dma_data(cpu_dai, substream); 121 121 } 122 122 123 + static struct hdac_ext_stream *hda_ipc4_get_hext_stream(struct snd_sof_dev *sdev, 124 + struct snd_soc_dai *cpu_dai, 125 + struct snd_pcm_substream *substream) 126 + { 127 + struct snd_sof_widget *pipe_widget; 128 + struct sof_ipc4_pipeline *pipeline; 129 + struct snd_sof_widget *swidget; 130 + struct snd_soc_dapm_widget *w; 131 + 132 + w = snd_soc_dai_get_widget(cpu_dai, substream->stream); 133 + swidget = w->dobj.private; 134 + pipe_widget = swidget->spipe->pipe_widget; 135 + pipeline = pipe_widget->private; 136 + 137 + /* mark pipeline so that it can be skipped during FE trigger */ 138 + pipeline->skip_during_fe_trigger = true; 139 + 140 + return snd_soc_dai_get_dma_data(cpu_dai, substream); 141 + } 142 + 123 143 static struct hdac_ext_stream *hda_assign_hext_stream(struct snd_sof_dev *sdev, 124 144 struct snd_soc_dai *cpu_dai, 125 145 struct snd_pcm_substream *substream) ··· 178 158 static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, 179 159 struct snd_pcm_substream *substream, int cmd) 180 160 { 161 + struct sof_ipc4_fw_data *ipc4_data = sdev->private; 181 162 struct snd_sof_widget *pipe_widget; 182 163 struct sof_ipc4_pipeline *pipeline; 183 164 struct snd_sof_widget *swidget; ··· 190 169 pipe_widget = swidget->spipe->pipe_widget; 191 170 pipeline = pipe_widget->private; 192 171 172 + mutex_lock(&ipc4_data->pipeline_state_mutex); 173 + 193 174 switch (cmd) { 194 175 case SNDRV_PCM_TRIGGER_START: 195 176 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ··· 202 179 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 203 180 SOF_IPC4_PIPE_PAUSED); 204 181 if (ret < 0) 205 - return ret; 182 + goto out; 206 183 207 184 pipeline->state = SOF_IPC4_PIPE_PAUSED; 208 185 break; ··· 210 187 dev_err(sdev->dev, "unknown trigger command %d\n", cmd); 211 188 return -EINVAL; 212 189 } 213 - 190 + out: 191 + mutex_unlock(&ipc4_data->pipeline_state_mutex); 214 192 return 0; 215 193 } 216 194 ··· 241 217 static int hda_ipc4_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, 242 218 struct snd_pcm_substream *substream, int cmd) 243 219 { 220 + struct sof_ipc4_fw_data *ipc4_data = sdev->private; 244 221 struct snd_sof_widget *pipe_widget; 245 222 struct sof_ipc4_pipeline *pipeline; 246 223 struct snd_sof_widget *swidget; 247 224 struct snd_soc_dapm_widget *w; 248 - int ret; 225 + int ret = 0; 249 226 250 227 w = snd_soc_dai_get_widget(cpu_dai, substream->stream); 251 228 swidget = w->dobj.private; 252 229 pipe_widget = swidget->spipe->pipe_widget; 253 230 pipeline = pipe_widget->private; 254 231 232 + mutex_lock(&ipc4_data->pipeline_state_mutex); 233 + 255 234 switch (cmd) { 256 235 case SNDRV_PCM_TRIGGER_START: 257 - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 258 236 if (pipeline->state != SOF_IPC4_PIPE_PAUSED) { 259 237 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 260 238 SOF_IPC4_PIPE_PAUSED); 261 239 if (ret < 0) 262 - return ret; 240 + goto out; 263 241 pipeline->state = SOF_IPC4_PIPE_PAUSED; 264 242 } 265 243 266 244 ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 267 245 SOF_IPC4_PIPE_RUNNING); 268 246 if (ret < 0) 269 - return ret; 247 + goto out; 248 + pipeline->state = SOF_IPC4_PIPE_RUNNING; 249 + swidget->spipe->started_count++; 250 + break; 251 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 252 + ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 253 + SOF_IPC4_PIPE_RUNNING); 254 + if (ret < 0) 255 + goto out; 270 256 pipeline->state = SOF_IPC4_PIPE_RUNNING; 271 257 break; 272 258 case SNDRV_PCM_TRIGGER_SUSPEND: 273 259 case SNDRV_PCM_TRIGGER_STOP: 274 - { 275 - ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id, 276 - SOF_IPC4_PIPE_RESET); 277 - if (ret < 0) 278 - return ret; 279 - 280 - pipeline->state = SOF_IPC4_PIPE_RESET; 260 + /* 261 + * STOP/SUSPEND trigger is invoked only once when all users of this pipeline have 262 + * been stopped. So, clear the started_count so that the pipeline can be reset 263 + */ 264 + swidget->spipe->started_count = 0; 281 265 break; 282 - } 283 266 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 284 267 break; 285 268 default: 286 269 dev_err(sdev->dev, "unknown trigger command %d\n", cmd); 287 - return -EINVAL; 270 + ret = -EINVAL; 271 + break; 288 272 } 289 - 290 - return 0; 273 + out: 274 + mutex_unlock(&ipc4_data->pipeline_state_mutex); 275 + return ret; 291 276 } 292 277 293 278 static const struct hda_dai_widget_dma_ops hda_ipc4_dma_ops = { 294 - .get_hext_stream = hda_get_hext_stream, 279 + .get_hext_stream = hda_ipc4_get_hext_stream, 295 280 .assign_hext_stream = hda_assign_hext_stream, 296 281 .release_hext_stream = hda_release_hext_stream, 297 282 .setup_hext_stream = hda_setup_hext_stream,
+2 -2
sound/soc/sof/ipc4-pcm.c
··· 69 69 struct snd_sof_widget *pipe_widget = spipe->pipe_widget; 70 70 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 71 71 72 - if (pipeline->skip_during_fe_trigger) 72 + if (pipeline->skip_during_fe_trigger && state != SOF_IPC4_PIPE_RESET) 73 73 return; 74 74 75 75 switch (state) { ··· 108 108 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 109 109 int i; 110 110 111 - if (pipeline->skip_during_fe_trigger) 111 + if (pipeline->skip_during_fe_trigger && state != SOF_IPC4_PIPE_RESET) 112 112 return; 113 113 114 114 /* set state for pipeline if it was just triggered */
-1
sound/soc/sof/ipc4-topology.c
··· 2500 2500 } 2501 2501 gtw_attr = ipc4_copier->gtw_attr; 2502 2502 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; 2503 - pipeline->skip_during_fe_trigger = true; 2504 2503 fallthrough; 2505 2504 case SOF_DAI_INTEL_ALH: 2506 2505 /*