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

ASoC: SOF: ipc4: Take priority into cosideration when

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

Add pipeline priority support for IPC4: Add support for parsing pipeline
priorities from the topology. This will be used to break the tie between
pipelines to set the trigger order when multiple pipelines are triggered
simultaneously.

+48 -12
+46 -9
sound/soc/sof/ipc4-pcm.c
··· 62 62 } 63 63 EXPORT_SYMBOL(sof_ipc4_set_pipeline_state); 64 64 65 + static void sof_ipc4_add_pipeline_by_priority(struct ipc4_pipeline_set_state_data *trigger_list, 66 + struct snd_sof_widget *pipe_widget, 67 + s8 *pipe_priority, bool ascend) 68 + { 69 + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 70 + int i, j; 71 + 72 + for (i = 0; i < trigger_list->count; i++) { 73 + /* add pipeline from low priority to high */ 74 + if (ascend && pipeline->priority < pipe_priority[i]) 75 + break; 76 + /* add pipeline from high priority to low */ 77 + else if (!ascend && pipeline->priority > pipe_priority[i]) 78 + break; 79 + } 80 + 81 + for (j = trigger_list->count - 1; j >= i; j--) { 82 + trigger_list->pipeline_instance_ids[j + 1] = trigger_list->pipeline_instance_ids[j]; 83 + pipe_priority[j + 1] = pipe_priority[j]; 84 + } 85 + 86 + trigger_list->pipeline_instance_ids[i] = pipe_widget->instance_id; 87 + trigger_list->count++; 88 + pipe_priority[i] = pipeline->priority; 89 + } 90 + 65 91 static void 66 92 sof_ipc4_add_pipeline_to_trigger_list(struct snd_sof_dev *sdev, int state, 67 93 struct snd_sof_pipeline *spipe, 68 - struct ipc4_pipeline_set_state_data *trigger_list) 94 + struct ipc4_pipeline_set_state_data *trigger_list, 95 + s8 *pipe_priority) 69 96 { 70 97 struct snd_sof_widget *pipe_widget = spipe->pipe_widget; 71 98 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; ··· 107 80 * for the first time 108 81 */ 109 82 if (spipe->started_count == spipe->paused_count) 110 - trigger_list->pipeline_instance_ids[trigger_list->count++] = 111 - pipe_widget->instance_id; 83 + sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority, 84 + false); 112 85 break; 113 86 case SOF_IPC4_PIPE_RESET: 114 87 /* RESET if the pipeline is neither running nor paused */ 115 88 if (!spipe->started_count && !spipe->paused_count) 116 - trigger_list->pipeline_instance_ids[trigger_list->count++] = 117 - pipe_widget->instance_id; 89 + sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority, 90 + true); 118 91 break; 119 92 case SOF_IPC4_PIPE_PAUSED: 120 93 /* Pause the pipeline only when its started_count is 1 more than paused_count */ 121 94 if (spipe->paused_count == (spipe->started_count - 1)) 122 - trigger_list->pipeline_instance_ids[trigger_list->count++] = 123 - pipe_widget->instance_id; 95 + sof_ipc4_add_pipeline_by_priority(trigger_list, pipe_widget, pipe_priority, 96 + true); 124 97 break; 125 98 default: 126 99 break; ··· 315 288 struct sof_ipc4_pipeline *pipeline; 316 289 struct snd_sof_pipeline *spipe; 317 290 struct snd_sof_pcm *spcm; 291 + u8 *pipe_priority; 318 292 int ret; 319 293 int i; 320 294 ··· 348 320 if (!trigger_list) 349 321 return -ENOMEM; 350 322 323 + pipe_priority = kzalloc(pipeline_list->count, GFP_KERNEL); 324 + if (!pipe_priority) { 325 + kfree(trigger_list); 326 + return -ENOMEM; 327 + } 328 + 351 329 mutex_lock(&ipc4_data->pipeline_state_mutex); 352 330 353 331 /* ··· 368 334 if (state == SOF_IPC4_PIPE_RUNNING || state == SOF_IPC4_PIPE_RESET) 369 335 for (i = pipeline_list->count - 1; i >= 0; i--) { 370 336 spipe = pipeline_list->pipelines[i]; 371 - sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list); 337 + sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list, 338 + pipe_priority); 372 339 } 373 340 else 374 341 for (i = 0; i < pipeline_list->count; i++) { 375 342 spipe = pipeline_list->pipelines[i]; 376 - sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list); 343 + sof_ipc4_add_pipeline_to_trigger_list(sdev, state, spipe, trigger_list, 344 + pipe_priority); 377 345 } 378 346 379 347 /* return if all pipelines are in the requested state already */ ··· 425 389 free: 426 390 mutex_unlock(&ipc4_data->pipeline_state_mutex); 427 391 kfree(trigger_list); 392 + kfree(pipe_priority); 428 393 return ret; 429 394 } 430 395
+2 -3
sound/soc/sof/ipc4-topology.c
··· 44 44 offsetof(struct sof_ipc4_pipeline, use_chain_dma)}, 45 45 {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 46 46 offsetof(struct sof_ipc4_pipeline, core_id)}, 47 + {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 48 + offsetof(struct sof_ipc4_pipeline, priority)}, 47 49 }; 48 50 49 51 static const struct sof_topology_token pipeline_tokens[] = { ··· 684 682 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); 685 683 goto err; 686 684 } 687 - 688 - /* TODO: Get priority from topology */ 689 - pipeline->priority = 0; 690 685 691 686 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", 692 687 swidget->widget->name, swidget->pipeline_id,