From f95b43339f63c1fef5452031fe1b5c5280608178 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Wed, 16 Aug 2023 08:47:27 +0200 Subject: [PATCH] DP: connect dp_queue to processing DP modules DP component need to work flawlessly on diffrent cores than the main pipeline processing data independently from the modules before and after them in the pipeline To achieve this, a cross core producer-consumer safe dp_queue should be used DP queue can only be connected to modules that use sink/src interface, so DP modules need to use it obligatory. To connect dp_queue into modules chain, double buffering method is used: - in LL task DP module is processed as an LL module, but the copy method is copying data from/to audio_streams to/from dp_queues - the main DP module processing takes place in DP task (in separate Zephyr thread). The tread may be bind to separate core Signed-off-by: Marcin Szkudlinski --- src/audio/component.c | 13 +- src/audio/module_adapter/module_adapter.c | 228 +++++++++++++++++- src/audio/pipeline/pipeline-params.c | 28 +-- src/audio/pipeline/pipeline-schedule.c | 10 +- src/idc/idc.c | 4 +- src/include/sof/audio/component_ext.h | 1 + .../sof/audio/module_adapter/module/generic.h | 20 +- src/include/sof/schedule/dp_schedule.h | 9 +- src/schedule/zephyr_dp_schedule.c | 71 +++--- 9 files changed, 306 insertions(+), 78 deletions(-) diff --git a/src/audio/component.c b/src/audio/component.c index 51e6b4250f9b..57991e9c949d 100644 --- a/src/audio/component.c +++ b/src/audio/component.c @@ -328,9 +328,16 @@ int comp_copy(struct comp_dev *dev) assert(dev->drv->ops.copy); - /* copy only if we are the owner of the LL component */ - if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL && - cpu_is_me(dev->ipc_config.core)) { + /* copy only if we are the owner of component OR this is DP component + * + * DP components (modules) require two stage processing: + * - in first step the pipeline (this) must copy data to/from module DP queues + * - second step will be performed by a thread specific to the DP module + * + * to be removed when pipeline 2.0 is ready + */ + if (cpu_is_me(dev->ipc_config.core) || + dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { #if CONFIG_PERFORMANCE_COUNTERS perf_cnt_init(&dev->pcd); #endif diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 997c76ef9830..0afd54a9b3b0 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -71,7 +73,16 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, dev->ipc_config = *config; dev->drv = drv; - mod = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*mod)); + /* allocate module information. + * for DP shared modules this struct must be accessible from all cores + * Unfortunalely at this point there's no information of components the module + * will be binded to. So we need to allocate shared memory for each DP module + * To be removed when pipeline 2.0 is ready + */ + enum mem_zone zone = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ? + SOF_MEM_ZONE_RUNTIME_SHARED : SOF_MEM_ZONE_RUNTIME; + + mod = rzalloc(zone, 0, SOF_MEM_CAPS_RAM, sizeof(*mod)); if (!mod) { comp_err(dev, "module_adapter_new(), failed to allocate memory for module"); rfree(dev); @@ -161,6 +172,12 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, goto err; } +#if CONFIG_ZEPHYR_DP_SCHEDULER + /* create a task for DP processing */ + if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) + pipeline_comp_dp_task_init(dev); +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ + #if CONFIG_IPC_MAJOR_4 dst->init_data = NULL; #endif @@ -230,6 +247,126 @@ static int module_adapter_sink_src_prepare(struct comp_dev *dev) return ret; } +#if CONFIG_ZEPHYR_DP_SCHEDULER +static int module_adapter_dp_queue_prepare(struct comp_dev *dev) +{ + struct list_item *blist; + struct processing_module *mod = comp_get_drvdata(dev); + int i; + int ret; + struct dp_queue *dp_queue; + int dp_mode = dev->is_shared ? DP_QUEUE_MODE_SHARED : DP_QUEUE_MODE_SIMPLE; + + /* for DP processing we need to create a DP QUEUE for each module input/output + * till pipeline2.0 is ready, DP processing requires double buffering + * + * first, set all parameters by calling "module prepare" with pointers to + * "main" audio_stream buffers + */ + ret = module_adapter_sink_src_prepare(dev); + if (ret) + return ret; + + /* + * second step - create a "shadow" cross-core DpQueue for existing buffers + * and copy stream parameters to shadow buffers + */ + i = 0; + list_for_item(blist, &dev->bsource_list) { + struct comp_buffer *source_buffer; + struct comp_buffer __sparse_cache *source_buffer_c; + + source_buffer = container_of(blist, struct comp_buffer, sink_list); + source_buffer_c = buffer_acquire(source_buffer); + + /* copy IBS & OBS from buffer to be shadowed */ + size_t obs = source_get_min_available( + audio_stream_get_source(&source_buffer_c->stream)); + size_t ibs = sink_get_min_free( + audio_stream_get_sink(&source_buffer_c->stream)); + + /* create a shadow dp queue */ + dp_queue = dp_queue_create(ibs, obs, dp_mode); + + if (!dp_queue) { + buffer_release(source_buffer_c); + goto err; + } + mod->dp_queue_ll_to_dp[i] = dp_queue; + mod->sources[i] = dp_queue_get_source(dp_queue); + + /* copy parameters from audio_stream */ + memcpy_s(dp_queue_get_audio_params(mod->dp_queue_ll_to_dp[i]), + sizeof(struct sof_audio_stream_params), + &source_buffer_c->stream.runtime_stream_params, + sizeof(source_buffer_c->stream.runtime_stream_params)); + + buffer_release(source_buffer_c); + i++; + } + + i = 0; + list_for_item(blist, &dev->bsink_list) { + uint32_t period; + struct comp_buffer *sink_buffer; + struct comp_buffer __sparse_cache *sink_buffer_c; + + sink_buffer = container_of(blist, struct comp_buffer, source_list); + sink_buffer_c = buffer_acquire(sink_buffer); + + /* copy IBS & OBS from buffer to be shadowed */ + size_t obs = source_get_min_available( + audio_stream_get_source(&sink_buffer_c->stream)); + size_t ibs = sink_get_min_free( + audio_stream_get_sink(&sink_buffer_c->stream)); + + /* create a shadow dp queue */ + dp_queue = dp_queue_create(ibs, obs, dp_mode); + + if (!dp_queue) { + buffer_release(sink_buffer_c); + goto err; + } + + mod->dp_queue_dp_to_ll[i] = dp_queue; + mod->sinks[i] = dp_queue_get_sink(dp_queue); + + memcpy_s(dp_queue_get_audio_params(mod->dp_queue_dp_to_ll[i]), + sizeof(struct sof_audio_stream_params), + &sink_buffer_c->stream.runtime_stream_params, + sizeof(sink_buffer_c->stream.runtime_stream_params)); + + buffer_release(sink_buffer_c); + i++; + } + + return 0; + +err: + for (int i = 0; i < mod->num_of_sources; i++) + if (mod->dp_queue_ll_to_dp[i]) { + dp_queue_free(mod->dp_queue_ll_to_dp[i]); + mod->dp_queue_ll_to_dp[i] = NULL; + mod->sources[i] = NULL; + } + mod->num_of_sources = 0; + + for (int i = 0; i < mod->num_of_sinks; i++) + if (mod->dp_queue_dp_to_ll[i]) { + dp_queue_free(mod->dp_queue_dp_to_ll[i]); + mod->dp_queue_dp_to_ll[i] = NULL; + mod->sinks[i] = NULL; + } + mod->num_of_sinks = 0; + return -ENOMEM; +} +#else +static int module_adapter_dp_queue_prepare(struct comp_dev *dev) +{ + return -EINVAL; +} +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ + /* * \brief Prepare the module * \param[in] dev - component device pointer. @@ -254,13 +391,18 @@ int module_adapter_prepare(struct comp_dev *dev) comp_dbg(dev, "module_adapter_prepare() start"); /* Prepare module */ - if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) + if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && + mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + ret = module_adapter_dp_queue_prepare(dev); + else if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && + mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) ret = module_adapter_sink_src_prepare(dev); + else if ((IS_PROCESSING_MODE_RAW_DATA(mod) || IS_PROCESSING_MODE_AUDIO_STREAM(mod)) && mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) - ret = module_prepare(mod, NULL, 0, NULL, 0); + else ret = -EINVAL; @@ -1024,6 +1166,66 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) return ret; } +#if CONFIG_ZEPHYR_DP_SCHEDULER +static int module_adapter_copy_dp_queues(struct comp_dev *dev) +{ + /* + * copy data from component audio streams to dp_queue + * DP module processing itself will take place in DP thread + * This is an adapter, to be removed when pipeline2.0 is ready + */ + struct processing_module *mod = comp_get_drvdata(dev); + int i = 0; + struct list_item *blist; + + list_for_item(blist, &dev->bsource_list) { + /* input - we need to copy data from audio_stream (as source) + * to dp_queue (as sink) + */ + struct comp_buffer *buffer = + container_of(blist, struct comp_buffer, sink_list); + struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(buffer); + struct sof_source *data_src = audio_stream_get_source(&buffer_c->stream); + + struct sof_sink *data_sink = dp_queue_get_sink(mod->dp_queue_ll_to_dp[i]); + uint32_t to_copy = MIN(sink_get_free_size(data_sink), + source_get_data_available(data_src)); + + source_to_sink_copy(data_src, data_sink, true, to_copy); + + buffer_release(buffer_c); + i++; + } + + i = 0; + list_for_item(blist, &dev->bsink_list) { + /* output - we need to copy data from dp_queue (as source) + * to audio_stream (as sink) + */ + struct sof_source *data_src = dp_queue_get_source(mod->dp_queue_dp_to_ll[i]); + struct comp_buffer *buffer = + container_of(blist, struct comp_buffer, source_list); + struct comp_buffer __sparse_cache *buffer_c = buffer_acquire(buffer); + struct sof_sink __sparse_cache *data_sink = + audio_stream_get_sink(&buffer_c->stream); + + uint32_t to_copy = MIN(sink_get_free_size(data_sink), + source_get_data_available(data_src)); + + source_to_sink_copy(data_src, data_sink, true, to_copy); + + buffer_release(buffer_c); + i++; + } + return 0; +} +#else +static int module_adapter_copy_dp_queues(struct comp_dev *dev) +{ + return -ENOTSUP; +} +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ + static int module_adapter_sink_source_copy(struct comp_dev *dev) { struct comp_buffer __sparse_cache *source_buffers_c[PLATFORM_MAX_STREAMS]; @@ -1196,6 +1398,8 @@ int module_adapter_copy(struct comp_dev *dev) comp_dbg(dev, "module_adapter_copy(): start"); struct processing_module *mod = comp_get_drvdata(dev); + if (mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) + return module_adapter_copy_dp_queues(dev); if (IS_PROCESSING_MODE_AUDIO_STREAM(mod)) return module_adapter_audio_stream_type_copy(dev); @@ -1436,6 +1640,24 @@ int module_adapter_reset(struct comp_dev *dev) mod->num_output_buffers = 0; } +#if CONFIG_ZEPHYR_DP_SCHEDULER + if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && + mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + for (int i = 0; i < mod->num_of_sources; i++) { + mod->sources[i] = NULL; + if (mod->dp_queue_ll_to_dp[i]) + dp_queue_free(mod->dp_queue_ll_to_dp[i]); + mod->dp_queue_ll_to_dp[i] = NULL; + } + for (int i = 0; i < mod->num_of_sinks; i++) { + mod->sinks[i] = NULL; + if (mod->dp_queue_dp_to_ll[i]) + dp_queue_free(mod->dp_queue_dp_to_ll[i]); + mod->dp_queue_ll_to_dp[i] = NULL; + } + } + +#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) { diff --git a/src/audio/pipeline/pipeline-params.c b/src/audio/pipeline/pipeline-params.c index 43974e290fb4..732cd46ef3bd 100644 --- a/src/audio/pipeline/pipeline-params.c +++ b/src/audio/pipeline/pipeline-params.c @@ -317,33 +317,9 @@ static int pipeline_comp_prepare(struct comp_dev *current, } } - switch (current->ipc_config.proc_domain) { - case COMP_PROCESSING_DOMAIN_LL: - /* this is a LL scheduled module */ + if (current->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) + /* init a task for LL module, DP task has been created in during init_instance */ err = pipeline_comp_ll_task_init(current->pipeline); - break; - -#if CONFIG_ZEPHYR_DP_SCHEDULER - case COMP_PROCESSING_DOMAIN_DP: - /* this is a DP scheduled module */ - - /* - * workaround - because of some issues with cache, currently we can allow DP - * modules to run on the same core as LL pipeline only. - * to be removed once buffering is fixed - */ - if (current->pipeline->core != current->ipc_config.core) - err = -EINVAL; - else - err = pipeline_comp_dp_task_init(current); - - break; -#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ - - default: - err = -EINVAL; - } - if (err < 0) return err; diff --git a/src/audio/pipeline/pipeline-schedule.c b/src/audio/pipeline/pipeline-schedule.c index a4a7a71da50f..4e7ea69744f9 100644 --- a/src/audio/pipeline/pipeline-schedule.c +++ b/src/audio/pipeline/pipeline-schedule.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -378,15 +379,18 @@ int pipeline_comp_ll_task_init(struct pipeline *p) #if CONFIG_ZEPHYR_DP_SCHEDULER static enum task_state dp_task_run(void *data) { - struct comp_dev *comp = data; + struct processing_module *mod = data; + + module_process_sink_src(mod, mod->sources, mod->num_input_buffers, + mod->sinks, mod->num_output_buffers); - comp->drv->ops.copy(comp); return SOF_TASK_STATE_RESCHEDULE; } int pipeline_comp_dp_task_init(struct comp_dev *comp) { int ret; + struct processing_module *mod = comp_get_drvdata(comp); struct task_ops ops = { .run = dp_task_run, .get_deadline = NULL, @@ -397,7 +401,7 @@ int pipeline_comp_dp_task_init(struct comp_dev *comp) ret = scheduler_dp_task_init(&comp->task, SOF_UUID(dp_task_uuid), &ops, - comp, + mod, comp->ipc_config.core, TASK_DP_STACK_SIZE, ZEPHYR_DP_THREAD_PRIORITY); diff --git a/src/idc/idc.c b/src/idc/idc.c index 70087f097f46..78ddbc5ab2e6 100644 --- a/src/idc/idc.c +++ b/src/idc/idc.c @@ -227,8 +227,8 @@ static int idc_prepare(uint32_t comp_id) dev = ipc_dev->cd; - /* we're running on different core, so allocate our own task */ - if (!dev->task) { + /* we're running LL on different core, so allocate our own task */ + if (!dev->task && dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) { /* allocate task for shared component */ dev->task = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*dev->task)); diff --git a/src/include/sof/audio/component_ext.h b/src/include/sof/audio/component_ext.h index 4aa65bf61fcd..2c51943413c3 100644 --- a/src/include/sof/audio/component_ext.h +++ b/src/include/sof/audio/component_ext.h @@ -55,6 +55,7 @@ static inline void comp_free(struct comp_dev *dev) dev->task) { schedule_task_free(dev->task); rfree(dev->task); + dev->task = NULL; } dev->drv->ops.free(dev); diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 2690ebb74cec..da99313d121b 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -17,6 +17,7 @@ #include #include #include +#include #include "module_interface.h" #if CONFIG_INTEL_MODULES @@ -199,10 +200,21 @@ struct processing_module { struct sof_source *sources[MODULE_MAX_SOURCES]; uint32_t num_of_sources; uint32_t num_of_sinks; - struct input_stream_buffer *input_buffers; - struct output_stream_buffer *output_buffers; - uint32_t num_input_buffers; /**< number of input buffers */ - uint32_t num_output_buffers; /**< number of output buffers */ + + union { + struct { + /* this is used in case of raw data or audio_stream mode */ + struct input_stream_buffer *input_buffers; + struct output_stream_buffer *output_buffers; + uint32_t num_input_buffers; /**< number of inputs */ + uint32_t num_output_buffers; /**< number of outputs */ + }; + struct { + /* this is used in case of DP processing */ + struct dp_queue *dp_queue_ll_to_dp[MODULE_MAX_SOURCES]; + struct dp_queue *dp_queue_dp_to_ll[MODULE_MAX_SOURCES]; + }; + }; struct comp_buffer *source_comp_buffer; /**< single source component buffer */ struct comp_buffer *sink_comp_buffer; /**< single sink compoonent buffer */ diff --git a/src/include/sof/schedule/dp_schedule.h b/src/include/sof/schedule/dp_schedule.h index 81650c563d80..84e60ff71c76 100644 --- a/src/include/sof/schedule/dp_schedule.h +++ b/src/include/sof/schedule/dp_schedule.h @@ -13,6 +13,8 @@ #include #include +struct processing_module; + /** * * DP scheduler is a scheduler that creates a separate preemptible Zephyr thread for each SOF task @@ -49,9 +51,6 @@ * */ -/** \brief tell the scheduler to run the task immediately, even if LL tick is not yet running */ -#define SCHEDULER_DP_RUN_TASK_IMMEDIATELY ((uint64_t)-1) - /** * \brief Init the Data Processing scheduler */ @@ -64,7 +63,7 @@ int scheduler_dp_init(void); * \param[out] task pointer, pointer to allocated task structure will be return * \param[in] uid pointer to UUID of the task * \param[in] ops pointer to task functions - * \param[in] data pointer to the thread private data + * \param[in] processing_module pointer to the module to be run * \param[in] core CPU the thread should run on * \param[in] stack_size size of stack for a zephyr task * \param[in] task_priority priority of the zephyr task @@ -72,7 +71,7 @@ int scheduler_dp_init(void); int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid, const struct task_ops *ops, - void *data, + struct processing_module *mod, uint16_t core, size_t stack_size, uint32_t task_priority); diff --git a/src/schedule/zephyr_dp_schedule.c b/src/schedule/zephyr_dp_schedule.c index a51304e9a6db..ce1cb512b307 100644 --- a/src/schedule/zephyr_dp_schedule.c +++ b/src/schedule/zephyr_dp_schedule.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -34,10 +35,10 @@ struct scheduler_dp_data { struct task_dp_pdata { k_tid_t thread_id; /* zephyr thread ID */ + uint32_t period; /* period the task should be scheduled in us */ k_thread_stack_t __sparse_cache *p_stack; /* pointer to thread stack */ - uint32_t ticks_period; /* period the task should be scheduled in LL ticks */ - uint32_t ticks_to_trigger; /* number of ticks the task should be triggered after */ struct k_sem sem; /* semaphore for task scheduling */ + struct processing_module *mod; /* the module to be scheduled */ }; /* Single CPU-wide lock @@ -62,10 +63,6 @@ static enum task_state scheduler_dp_ll_tick_dummy(void *data) /* * function called after every LL tick - * - * TODO: - * the scheduler should here calculate deadlines of all task and tell Zephyr about them - * Currently there's an assumption that the task is always ready to run */ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void *caller_data) { @@ -81,20 +78,38 @@ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void * lock_key = scheduler_dp_lock(); list_for_item(tlist, &dp_sch->tasks) { curr_task = container_of(tlist, struct task, list); - pdata = curr_task->priv_data; - if (pdata->ticks_to_trigger == 0) { - if (curr_task->state == SOF_TASK_STATE_QUEUED) { - /* set new trigger time, start the thread */ - pdata->ticks_to_trigger = pdata->ticks_period; + /* step 1 - check if the module is ready for processing */ + if (curr_task->state == SOF_TASK_STATE_QUEUED) { + pdata = curr_task->priv_data; + struct processing_module *mod = pdata->mod; + bool mod_ready = true; + + /* check all sink/sources of the component + * check if it has enough data to processing/space to send data + */ + for (int i = 0; i < mod->num_of_sources; i++) { + if (!source_get_is_enough_available(mod->sources[i])) { + mod_ready = false; + break; + } + } + + if (mod_ready) + for (int i = 0; i < mod->num_of_sinks; i++) { + if (!sink_get_is_enough_free(mod->sinks[i])) { + mod_ready = false; + break; + } + } + + if (mod_ready) { + + /* TODO: step 2 - caclulate deadlines */ + /* trigger the task */ curr_task->state = SOF_TASK_STATE_RUNNING; k_sem_give(&pdata->sem); } - } else { - if (curr_task->state == SOF_TASK_STATE_QUEUED || - curr_task->state == SOF_TASK_STATE_RUNNING) - /* decrease num of ticks to re-schedule */ - pdata->ticks_to_trigger--; } } scheduler_dp_unlock(lock_key); @@ -102,6 +117,7 @@ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void * static int scheduler_dp_task_cancel(void *data, struct task *task) { + struct scheduler_dp_data *dp_sch = (struct scheduler_dp_data *)data; unsigned int lock_key; /* this is asyn cancel - mark the task as canceled and remove it from scheduling */ @@ -118,6 +134,7 @@ static int scheduler_dp_task_cancel(void *data, struct task *task) static int scheduler_dp_task_free(void *data, struct task *task) { unsigned int lock_key; + struct scheduler_dp_data *dp_sch = (struct scheduler_dp_data *)data; struct task_dp_pdata *pdata = task->priv_data; /* abort the execution of the thread */ @@ -145,6 +162,7 @@ static void dp_thread_fn(void *p1, void *p2, void *p3) struct task_dp_pdata *task_pdata = task->priv_data; unsigned int lock_key; enum task_state state; + struct scheduler_dp_data *dp_sch = scheduler_get_data(SOF_SCHEDULE_DP); while (1) { /* @@ -212,23 +230,11 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta return -EINVAL; } - /* calculate period and start time in LL ticks */ - pdata->ticks_period = period / LL_TIMER_PERIOD_US; - /* add a task to DP scheduler list */ + task->state = SOF_TASK_STATE_QUEUED; list_item_prepend(&task->list, &dp_sch->tasks); - if (start == SCHEDULER_DP_RUN_TASK_IMMEDIATELY) { - /* trigger the task immediately, don't wait for LL tick */ - pdata->ticks_to_trigger = 0; - task->state = SOF_TASK_STATE_RUNNING; - k_sem_give(&pdata->sem); - } else { - /* wait for tick */ - pdata->ticks_to_trigger = start / LL_TIMER_PERIOD_US; - task->state = SOF_TASK_STATE_QUEUED; - } - + pdata->period = period; scheduler_dp_unlock(lock_key); /* start LL task - run DP tick start and period are irrelevant for LL (that's bad)*/ @@ -272,7 +278,7 @@ int scheduler_dp_init(void) int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid, const struct task_ops *ops, - void *data, + struct processing_module *mod, uint16_t core, size_t stack_size, uint32_t task_priority) @@ -335,7 +341,7 @@ int scheduler_dp_task_init(struct task **task, /* internal SOF task init */ ret = schedule_task_init(&task_memory->task, uid, SOF_SCHEDULE_DP, 0, ops->run, - data, core, 0); + mod, core, 0); if (ret < 0) { tr_err(&dp_tr, "zephyr_dp_task_init(): schedule_task_init failed"); goto err; @@ -354,6 +360,7 @@ int scheduler_dp_task_init(struct task **task, task_memory->task.priv_data = &task_memory->pdata; task_memory->pdata.thread_id = thread_id; task_memory->pdata.p_stack = p_stack; + task_memory->pdata.mod = mod; *task = &task_memory->task; /* start the thread - it will immediately stop at a semaphore */