-
Notifications
You must be signed in to change notification settings - Fork 140
ASoC: SOF: Intel: sort pipeline based on priority #4593
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,10 +62,37 @@ int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 instance_id, u32 s | |
| } | ||
| EXPORT_SYMBOL(sof_ipc4_set_pipeline_state); | ||
|
|
||
| static void sof_ipc4_add_pipeline_by_priority(struct ipc4_pipeline_set_state_data *trigger_list, | ||
| struct snd_sof_widget *pipe_widget, | ||
| s8 *pipe_priority, bool ascend) | ||
RanderWang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
RanderWang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| struct sof_ipc4_pipeline *pipeline = pipe_widget->private; | ||
| int i, j; | ||
|
|
||
| for (i = 0; i < trigger_list->count; i++) { | ||
| /* add pipeline from low priority to high */ | ||
| if (ascend && pipeline->priority < pipe_priority[i]) | ||
| break; | ||
| /* add pipeline from high priority to low */ | ||
| else if (!ascend && pipeline->priority > pipe_priority[i]) | ||
RanderWang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| break; | ||
| } | ||
|
|
||
| for (j = trigger_list->count - 1; j >= i; j--) { | ||
| trigger_list->pipeline_instance_ids[j + 1] = trigger_list->pipeline_instance_ids[j]; | ||
| pipe_priority[j + 1] = pipe_priority[j]; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i had the same suspicion when I looked at the code. But the array size is pipeline_list->count not trigger_list->count. So I think it is safe here
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the end we are not going to put all pipelines in the trigger list? Right, when we add the last pipeline the |
||
| } | ||
|
|
||
| trigger_list->pipeline_instance_ids[i] = pipe_widget->instance_id; | ||
| trigger_list->count++; | ||
| pipe_priority[i] = pipeline->priority; | ||
| } | ||
|
|
||
| static void | ||
| sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state, | ||
| struct snd_sof_pipeline *spipe, | ||
| struct ipc4_pipeline_set_state_data *trigger_list) | ||
| struct ipc4_pipeline_set_state_data *trigger_list, | ||
| s8 *pipe_priority) | ||
| { | ||
| struct snd_sof_widget *pipe_widget = spipe->pipe_widget; | ||
| struct sof_ipc4_pipeline *pipeline = pipe_widget->private; | ||
|
|
@@ -80,20 +107,20 @@ sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state, | |
| * for the first time | ||
| */ | ||
| if (spipe->started_count == spipe->paused_count) | ||
| trigger_list->pipeline_instance_ids[trigger_list->count++] = | ||
| pipe_widget->instance_id; | ||
| sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority, | ||
| false); | ||
| break; | ||
| case SOF_IPC4_PIPE_RESET: | ||
| /* RESET if the pipeline is neither running nor paused */ | ||
| if (!spipe->started_count && !spipe->paused_count) | ||
| trigger_list->pipeline_instance_ids[trigger_list->count++] = | ||
| pipe_widget->instance_id; | ||
| sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority, | ||
| true); | ||
| break; | ||
| case SOF_IPC4_PIPE_PAUSED: | ||
| /* Pause the pipeline only when its started_count is 1 more than paused_count */ | ||
| if (spipe->paused_count == (spipe->started_count - 1)) | ||
| trigger_list->pipeline_instance_ids[trigger_list->count++] = | ||
| pipe_widget->instance_id; | ||
| sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority, | ||
| true); | ||
|
||
| break; | ||
| default: | ||
| break; | ||
|
|
@@ -288,6 +315,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, | |
| struct sof_ipc4_pipeline *pipeline; | ||
| struct snd_sof_pipeline *spipe; | ||
| struct snd_sof_pcm *spcm; | ||
| u8 *pipe_priority; | ||
RanderWang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| int ret; | ||
| int i; | ||
|
|
||
|
|
@@ -320,6 +348,12 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, | |
| if (!trigger_list) | ||
| return -ENOMEM; | ||
|
|
||
| pipe_priority = kzalloc(pipeline_list->count, GFP_KERNEL); | ||
| if (!pipe_priority) { | ||
| kfree(trigger_list); | ||
| return -ENOMEM; | ||
RanderWang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| mutex_lock(&ipc4_data->pipeline_state_mutex); | ||
|
|
||
| /* | ||
|
|
@@ -334,12 +368,14 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, | |
| if (state == SOF_IPC4_PIPE_RUNNING || state == SOF_IPC4_PIPE_RESET) | ||
| for (i = pipeline_list->count - 1; i >= 0; i--) { | ||
| spipe = pipeline_list->pipelines[i]; | ||
| sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list); | ||
| sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list, | ||
| pipe_priority); | ||
| } | ||
| else | ||
| for (i = 0; i < pipeline_list->count; i++) { | ||
| spipe = pipeline_list->pipelines[i]; | ||
| sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list); | ||
| sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list, | ||
| pipe_priority); | ||
| } | ||
|
|
||
| /* return if all pipelines are in the requested state already */ | ||
|
|
@@ -389,6 +425,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, | |
| free: | ||
| mutex_unlock(&ipc4_data->pipeline_state_mutex); | ||
| kfree(trigger_list); | ||
| kfree(pipe_priority); | ||
| return ret; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RanderWang I had a though about this second patch. Instead of sorting the pipelines based on priority in the kernel while ending the IPC, can we handle this in the FW? When the pipeline is set up, the FW is already aware of the priority. We can use that information in the firmware to trigger in decreasing order of priorities, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(1) We can do it in FW, but we need some search operation to find the priority in FW. As you know, host X86 is much faster than dsp core. (5GHZ vs 400MHZ , DDR4800 vs DDR400).
(2) According to above discussing, we should fully align with REF implementation which does it in driver and it should be good for REF FW also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verified working fine with randomly start/stop spk playback and DMIC0 RTC AEC.