From 4db629fe3155f8dfa944d04f47faf1c3c18a6067 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Wed, 20 Mar 2024 10:27:30 +0100 Subject: [PATCH] ipc4: Ensure pipeline component directions are synchronized This patch addresses an issue where audio output could be silent due to the direction property of pipeline components not being set. The problem manifests when the pipeline is initialized in the sequence: Init -> Reset -> Pause -> Ready In this scenario, the direction property may remain unset, leading to incorrect pipeline behavior. In flow of transitions: Init -> Pause -> Ready, this issue does not occur because the firmware attempts to set the directions in pipe components during the transition from Init to Pause. This step is skipped if Pause is done after Reset, which is the scenario that this patch addresses. The added code ensures that if the source component's direction is unset but the sink's direction is set, or vice versa, the direction is copied from the set component to the unset one. This synchronization of the direction property guarantees that the pipeline's data flow is correctly established. This synchronization of the direction property guarantees that the pipeline's data flow is correctly established, allowing the `pipeline_for_each_comp` function to traverse and process all components as intended, thus resolving the silent audio output problem. Signed-off-by: Tomasz Leman --- src/ipc/ipc4/handler.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index e54b886434bb..171ffd6a79ad 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -251,6 +251,28 @@ static struct ipc_comp_dev *pipeline_get_host_dev(struct ipc_comp_dev *ppl_icd) struct ipc *ipc = ipc_get(); int host_id; + /* If the source component's direction is not set but the sink's direction is, + * this block will copy the direction from the sink to the source component and + * mark the source's direction as set. + */ + if (!ppl_icd->pipeline->source_comp->direction_set && + ppl_icd->pipeline->sink_comp->direction_set) { + ppl_icd->pipeline->source_comp->direction = + ppl_icd->pipeline->sink_comp->direction; + ppl_icd->pipeline->source_comp->direction_set = true; + } + + /* If the sink component's direction is not set but the source's direction is, + * this block will copy the direction from the source to the sink component and + * mark the sink's direction as set. + */ + if (!ppl_icd->pipeline->sink_comp->direction_set && + ppl_icd->pipeline->source_comp->direction_set) { + ppl_icd->pipeline->sink_comp->direction = + ppl_icd->pipeline->source_comp->direction; + ppl_icd->pipeline->sink_comp->direction_set = true; + } + if (ppl_icd->pipeline->source_comp->direction == SOF_IPC_STREAM_PLAYBACK) host_id = ppl_icd->pipeline->source_comp->ipc_config.id; else