Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor pipeline management #5262

Open
wants to merge 7 commits into
base: topic/sof-dev
Choose a base branch
from

Conversation

ranj063
Copy link
Collaborator

@ranj063 ranj063 commented Dec 4, 2024

This PR refactors the pipeline management to do the following:

  1. Make sure that BE pipeline widgets/routes are set up and freed during BE DAI ops. A BE pipeline is the one that contains the DAI widget
  2. Pipeline trigger is already split between FE and BE DAI ops except for pipeline reset. This PR also modifies pipeline set/up free to the respective DAI ops i.e BE pipeline in the BE DAI hw_free and the rest of the pipelines in the FE DAI hw_free.
  3. The widget's ipc_prepare op is intentionally left to the handled during the FE DAI hw_params because it requires propagating pipeline_params all the way from the source to the sink widget.

So the overall flow for a normal start/stop would be:

  1. Pipeline widgets are prepared during FE DAI hw_params. This includes all widgets belonging to all pipelines including the BE pipeline as well.
  2. All widgets and routes belonging to BE pipelines are set up during BE DAI prepare.
  3. All widgets and routes belonging to the remaining pipelines are set up during FE DAI prepare.
  4. All widgets and routes belonging to BE pipelines are freed and unprepared during BE DAI hw_free
  5. All widgets and routes belonging to the remaining pipelines are freed and unprepared during FE DAI hw_free

The above flow ensures that the pipelines are unprepared only during hw_free. Since the hw_params do not change because of xruns/suspend, there is no need to unprepare and re-prepare the widgets in these cases. The only critical change would be to make sure that the host DMA and the link DMA are reconfigured before restarting.

In the case of an xrun, the change would be that the BE pipeline would be freed, the link DMA will be reconfigured and the pipelines will be set up again in the prepare following the xrun stop trigger. And the remaining pipelines would be freed, host DMA reconfigured and the pipelines will be set up again in the prepare ioctl following the xrun stop trigger.

The case of a suspend/resume during audio is slightly different from the xrun case: The BE pipeline will be freed during the suspend trigger. The link DMA will be reconfigured and the BE pipeline will be set up again during the BE DAI prepare after resuming. Similarly, for the remaining pipelines, they will be freed during suspend and the host DMA will be reconfigured and pipelines set up during the prepare after resume.

@ranj063 ranj063 force-pushed the fix/pipeline_mgt branch 2 times, most recently from 50da688 to 9883c9b Compare December 4, 2024 18:52
@ranj063
Copy link
Collaborator Author

ranj063 commented Dec 4, 2024

SOFCI TEST

@ranj063 ranj063 force-pushed the fix/pipeline_mgt branch 6 times, most recently from f2569fa to 8818a53 Compare December 6, 2024 01:59
Copy link
Collaborator

@bardliao bardliao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call setup in hw_params and prepare in prepare?

list = spcm->stream[dir].list;
params = &spcm->params[substream->stream];
platform_params = &spcm->platform_params[substream->stream];
ret = sof_widget_list_setup(sdev, spcm, params, platform_params, dir);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As setup and prepare are split, why don't we do setup in sof_pcm_hw_params?

int stream = substream->stream;
int ret;

ret = hda_dai_hw_params(substream, &rtd->dpcm[stream].hw_params, dai);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any specific reason that we always call hw_params in .prepare?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because sometimes we dont have a hw_free like in the case of xruns and we'll need to do everything again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prepare() should be fast. We should call this out in comments - we need to do X,Y out of cycle because Z

drivers/soundwire/intel_ace2x.c Show resolved Hide resolved
@ranj063
Copy link
Collaborator Author

ranj063 commented Dec 6, 2024

Can we call setup in hw_params and prepare in prepare?

No. A widget needs to be prepared before it can be set up. So ipc_prepare needs to be done in hw_params before we do set up in prepare

@ranj063 ranj063 force-pushed the fix/pipeline_mgt branch 2 times, most recently from 0a0cbf9 to dae9464 Compare December 6, 2024 17:31
@ranj063
Copy link
Collaborator Author

ranj063 commented Dec 7, 2024

SOFCI TEST

@ranj063 ranj063 force-pushed the fix/pipeline_mgt branch 2 times, most recently from 0b23916 to c3a3b54 Compare December 7, 2024 19:56
Add a new host_config op in struct sof_ipc_tplg_ops and define it for
IPC4. This will be used to configure the host widget during prepare
after a suspend/resume or after an xrun.

Signed-off-by: Ranjani Sridharan <[email protected]>
In preparation for refacting pipeline management, split the widget
prepare and set up between the hw_params and prepare ioctls. This is
required to ensure that the BE pipeline widgets can be set up during the
BE DAI prepare and the remaining widgets will be set up during the FE
DAI prepare. The widget's ipc_prepare op for all widgets in both the
BE and FE pipelines are handled during the FE DAI hw_params to make sure
that the pipeline params can be propagated all the way from the source
widget to the sink widget.

Signed-off-by: Ranjani Sridharan <[email protected]>
Define 3 new ops in struct hda_dai_widget_dma_ops for setting
up/freeing/unpreparing the BE pipeline and set them for IPC4 version
of the ops. These ops will be used when the pipeline management is
refactored to set up/free widgets, routes and pipelines during BE DAI
prepare or hw_free.

Signed-off-by: Ranjani Sridharan <[email protected]>
This will be used in the BE DAI ops in the following patches.

Signed-off-by: Ranjani Sridharan <[email protected]>
Add and define the prepare op for Intel ACE2.x platforms. For the
moment, the prepare_stream op is exactly the same as the prepare_stream
op.  But it will be modified in the following patch when the pipeline
management is refactored.

Signed-off-by: Ranjani Sridharan <[email protected]>
Invoke the set_up_be_pipeline and free_be_pipeline ops in the BE DAI
prepare and hw_free to ensure that all the widgets and routes belonging
to the BE pipeline are handled in the BE DAI ops. Add a new field in
struct snd_sof_pipeline to identify BE pipelines i.e. those that contain
the DAI widget. Modify the FE ops to make sure that the widgets/routes
belonging to these pipelines are skipped during setup/free/unprepare.

Signed-off-by: Ranjani Sridharan <[email protected]>
Now that all widgets/routes/pipelines are setup, triggered and freed in
the BE DAI ops, we can reuse the be_pipeline flag in struct
snd_sof_pipeline to skip triggering the BE pipelines in the PCM trigger.
So remove the skip_during_fe_trigger flag from struct sof_ipc4_pipeline.

Signed-off-by: Ranjani Sridharan <[email protected]>
@ranj063
Copy link
Collaborator Author

ranj063 commented Dec 8, 2024

SOFCI TEST

@ranj063 ranj063 marked this pull request as ready for review December 8, 2024 02:00
int ret;

/* set up the widget if it belongs to the same pipeline as the DAI widget */
if (swidget->spipe != spipe || !swidget->prepared)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to go through the widgets in the path like hda_dai_unprepare_widgets_in_pipeline() does in the !swidget->prepared case? And same question for hda_dai_free_widgets_in_pipeline().

@bardliao
Copy link
Collaborator

bardliao commented Dec 9, 2024

SOFCI TEST

@ujfalusi
Copy link
Collaborator

ujfalusi commented Dec 9, 2024

@ranj063, this sequence still fails (HDA machine):
terminal 1:
aplay -Dhw:0,0
CTRL+z

terminal 2:
aplay -Dhw:0,3

terminal 1:
fg

[11038.698037] snd_soc_core:dpcm_be_dai_trigger:  Analog Playback and Capture: ASoC: trigger BE Analog Playback and Capture cmd 1
[11038.698057] snd_sof_intel_hda_common:hda_dai_trigger: sof-audio-pci-intel-tgl 0000:00:1f.3: cmd=1 dai Analog CPU DAI direction 0
[11038.698071] snd_sof:sof_ipc4_set_pipeline_state: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc4 set pipeline instance 0 state 3
[11038.698078] snd_sof:sof_ipc4_log_header: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc tx      : 0x13000003|0x0: GLB_SET_PIPELINE_STATE
[11038.698434] snd_sof:sof_ipc4_log_header: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc tx reply: 0x33000000|0x0: GLB_SET_PIPELINE_STATE
[11038.698455] snd_sof:sof_ipc4_log_header: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc tx done : 0x13000003|0x0: GLB_SET_PIPELINE_STATE
[11038.698460] snd_sof:sof_ipc4_set_pipeline_state: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc4 set pipeline instance 0 state 4
[11038.698464] snd_sof:sof_ipc4_log_header: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc tx      : 0x13000004|0x0: GLB_SET_PIPELINE_STATE
[11038.703027] snd_sof:sof_ipc4_log_header: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc tx reply: 0x33000007|0x0: GLB_SET_PIPELINE_STATE
[11038.703031] sof-audio-pci-intel-tgl 0000:00:1f.3: FW reported error: 7 - Unsupported operation requested
[11038.703058] sof-audio-pci-intel-tgl 0000:00:1f.3: ipc error for msg 0x13000004|0x0
[11038.703062] sof-audio-pci-intel-tgl 0000:00:1f.3: ASoC: error at soc_dai_trigger on Analog CPU DAI: -22
[11038.703067]  HDA Analog: ASoC: trigger FE cmd: 1 failed: -22

Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranj063 we you able to see any IP programming delta with debug in the hw_read(), hw_write() ?

int stream = substream->stream;
int ret;

ret = hda_dai_hw_params(substream, &rtd->dpcm[stream].hw_params, dai);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prepare() should be fast. We should call this out in comments - we need to do X,Y out of cycle because Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants