From ab89c94f146b72ab6354a5f9595ef327be9eda6c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 27 Jul 2021 17:02:39 -0500 Subject: [PATCH 1/3] Revert "trace: add _log_nodict() and enable DMA trace for Zephyr" This reverts commit 57ee04f2d9312968a8e11fd916195bbacd667180. Signed-off-by: Pierre-Louis Bossart --- src/include/sof/trace/trace.h | 25 +------------------------ src/trace/trace.c | 5 ----- zephyr/include/sof/trace/trace.h | 20 +++++++++++++++----- 3 files changed, 16 insertions(+), 34 deletions(-) diff --git a/src/include/sof/trace/trace.h b/src/include/sof/trace/trace.h index 155964698c56..b874fafc8b2f 100644 --- a/src/include/sof/trace/trace.h +++ b/src/include/sof/trace/trace.h @@ -205,14 +205,7 @@ void mtrace_event(const char *complete_packet, uint32_t length); } #ifdef CONFIG_TRACEM /* Send everything to shared memory too */ -# ifdef __ZEPHYR__ -/* We don't use Zephyr's dictionary yet so there's not enough space for - * DEBUG messages - */ -# define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_INFO -# else -# define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_DEBUG -# endif +# define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_DEBUG #else /* copy only ERRORS */ # define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_ERROR #endif /* CONFIG_TRACEM */ @@ -275,23 +268,7 @@ do { \ ); \ _log_sofdict(log_func, atomic, &log_entry, ctx, lvl, id_1, id_2, \ META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), ##__VA_ARGS__); \ - _log_nodict(atomic, META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), \ - lvl, format, ##__VA_ARGS__); \ -} while (0) - -#ifdef __ZEPHYR__ -/* Just like XTOS, only the most urgent messages go to limited - * shared memory. - */ -#define _log_nodict(atomic, arg_count, lvl, format, ...) \ -do { \ - if ((lvl) <= MTRACE_DUPLICATION_LEVEL) \ - printk("%llu " format "\n", platform_timer_get(NULL), \ - ##__VA_ARGS__); \ } while (0) -#else -#define _log_nodict(atomic, n_args, lvl, format, ...) -#endif #endif /* CONFIG_LIBRARY */ diff --git a/src/trace/trace.c b/src/trace/trace.c index f311d6021950..4cdb11cd9843 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -92,7 +92,6 @@ static void put_header(void *dst, const struct sof_uuid_entry *uid, } -#ifndef __ZEPHYR__ /** Ring buffer for the mailbox trace */ void mtrace_event(const char *data, uint32_t length) { @@ -111,7 +110,6 @@ void mtrace_event(const char *data, uint32_t length) dcache_writeback_region(t + trace->pos, length); trace->pos += length; } -#endif /* __ZEPHYR__ */ #if CONFIG_TRACE_FILTERING_VERBOSITY /** @@ -550,14 +548,11 @@ void _log_sofdict(log_func_t sofdict_logf, bool atomic, const void *log_entry, { va_list ap; -#ifndef __ZEPHYR__ /* for Zephyr see _log_nodict() in trace.h */ if (lvl <= MTRACE_DUPLICATION_LEVEL) { va_start(ap, arg_count); mtrace_dict_entry_vl(atomic, (uint32_t)log_entry, arg_count, ap); va_end(ap); } -#endif - va_start(ap, arg_count); sofdict_logf(atomic, log_entry, ctx, lvl, id_1, id_2, arg_count, ap); va_end(ap); diff --git a/zephyr/include/sof/trace/trace.h b/zephyr/include/sof/trace/trace.h index 64888cff22d6..7d24708c8845 100644 --- a/zephyr/include/sof/trace/trace.h +++ b/zephyr/include/sof/trace/trace.h @@ -25,10 +25,10 @@ struct timer; uint64_t platform_timer_get(struct timer *timer); /* - * Override SOF mtrace_printf() macro for now to support Zephyr's shared - * memory logger. Note the DMA trace can be copied to the shared memory - * too thanks to CONFIG_TRACEM. + * Override SOF dictionary macros for now and let Zephyr take care of + * the physical log IO. */ +#undef _log_message #undef mtrace_printf #if USE_PRINTK @@ -38,8 +38,18 @@ uint64_t platform_timer_get(struct timer *timer); printk("%llu: " format "\n", platform_timer_get(NULL), \ ##__VA_ARGS__); \ } while (0) -#else -#error "TODO: Z_LOG()" +#define _log_message(log_func, atomic, level, comp_class, ctx, id1, id2, format, ...) \ + do { \ + if ((level) <= SOF_ZEPHYR_TRACE_LEVEL) \ + printk("%llu: " format "\n", platform_timer_get(NULL), \ + ##__VA_ARGS__); \ + } while (0) +#else /* not tested */ +#define _log_message(log_func, atomic, level, comp_class, ctx, id1, id2, format, ...) \ + do { \ + Z_LOG(level, "%u: " format, (uint32_t)platform_timer_get(NULL), \ + ##__VA_ARGS__); \ + } while (0) #endif #endif /* __INCLUDE_TRACE__ */ From 9a8dc9a1776514a6539ecd88c91fd5491a9ceed9 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 27 Jul 2021 17:02:48 -0500 Subject: [PATCH 2/3] Revert "trace: move CONFIG_TRACEM implementation up a couple levels" This reverts commit 0def9056300a4b23d909ba0b36256087af91d2fe. Signed-off-by: Pierre-Louis Bossart --- src/include/sof/trace/trace.h | 28 +++---------- src/trace/trace.c | 72 +++++++++++++++++----------------- test/cmocka/src/common_mocks.c | 10 +---- 3 files changed, 43 insertions(+), 67 deletions(-) diff --git a/src/include/sof/trace/trace.h b/src/include/sof/trace/trace.h index b874fafc8b2f..1d759a6bb95c 100644 --- a/src/include/sof/trace/trace.h +++ b/src/include/sof/trace/trace.h @@ -97,9 +97,6 @@ struct trace_filter { #if CONFIG_TRACE -#include -#include /* LOG_LEVEL_... */ - /* * trace_event macro definition * @@ -147,13 +144,10 @@ void trace_off(void); void trace_init(struct sof *sof); /* All tracing macros in this file end up calling these functions in the end. */ -typedef void (*log_func_t)(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx, - uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list args); - void trace_log_filtered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx, - uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list args); + uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, ...); void trace_log_unfiltered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx, - uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list args); + uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, ...); struct sof_ipc_trace_filter_elem *trace_filter_fill(struct sof_ipc_trace_filter_elem *elem, struct sof_ipc_trace_filter_elem *end, struct trace_filter *filter); @@ -204,17 +198,6 @@ void mtrace_event(const char *complete_packet, uint32_t length); format \ } -#ifdef CONFIG_TRACEM /* Send everything to shared memory too */ -# define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_DEBUG -#else /* copy only ERRORS */ -# define MTRACE_DUPLICATION_LEVEL LOG_LEVEL_ERROR -#endif /* CONFIG_TRACEM */ - -/* This function is _not_ passed the format string to save space */ -void _log_sofdict(log_func_t sofdict_logf, bool atomic, const void *log_entry, - const struct tr_ctx *ctx, const uint32_t lvl, - uint32_t id_1, uint32_t id_2, int arg_count, ...); - /* _log_message() */ #ifdef CONFIG_LIBRARY @@ -254,8 +237,7 @@ _thrown_from_macro_BASE_LOG_in_trace_h /** _log_message is where the memory-saving dictionary magic described * above happens: the "format" string argument is moved to a special - * linker section and replaced by a &log_entry pointer to it. This must - * be a macro for the source location to be meaningful. + * linker section and replaced by a &log_entry pointer to it. */ #define _log_message(log_func, atomic, lvl, comp_class, ctx, id_1, id_2, format, ...) \ do { \ @@ -266,8 +248,8 @@ do { \ META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), \ BASE_LOG_ASSERT_FAIL_MSG \ ); \ - _log_sofdict(log_func, atomic, &log_entry, ctx, lvl, id_1, id_2, \ - META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), ##__VA_ARGS__); \ + log_func(atomic, &log_entry, ctx, lvl, id_1, id_2, \ + META_COUNT_VARAGS_BEFORE_COMPILE(__VA_ARGS__), ##__VA_ARGS__); \ } while (0) #endif /* CONFIG_LIBRARY */ diff --git a/src/trace/trace.c b/src/trace/trace.c index 4cdb11cd9843..f31fb3a1c3e8 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -222,15 +222,21 @@ static bool trace_filter_flood(uint32_t log_level, uint32_t entry, uint64_t mess /** Implementation shared and invoked by both adaptive filtering and * not. Serializes events into trace messages and passes them to - * dtrace_event() + * dtrace_event() or to mtrace_event() or to both depending on the log + * lvl and the Kconfiguration. */ -static void dma_trace_log(bool send_atomic, uint32_t log_entry, const struct tr_ctx *ctx, - uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list vargs) +static void vatrace_log(bool send_atomic, uint32_t log_entry, const struct tr_ctx *ctx, + uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list vargs) { uint32_t data[MESSAGE_SIZE_DWORDS(_TRACE_EVENT_MAX_ARGUMENT_COUNT)]; const int message_size = MESSAGE_SIZE(arg_count); int i; +#if CONFIG_TRACEM + unsigned long flags; + struct trace *trace = trace_get(); +#endif /* CONFIG TRACEM */ + /* fill log content. arg_count is in the dictionary. */ put_header(data, ctx->uuid_p, id_1, id_2, log_entry, platform_safe_get_time(timer_get())); @@ -244,25 +250,42 @@ static void dma_trace_log(bool send_atomic, uint32_t log_entry, const struct tr_ else dtrace_event((const char *)data, message_size); +#if CONFIG_TRACEM + /* send event by mail box too. */ + if (send_atomic) { + mtrace_event((const char *)data, MESSAGE_SIZE(arg_count)); + } else { + spin_lock_irq(&trace->lock, flags); + mtrace_event((const char *)data, MESSAGE_SIZE(arg_count)); + spin_unlock_irq(&trace->lock, flags); + } +#else + /* send event by mail box if level is LOG_LEVEL_CRITICAL. */ + if (lvl == LOG_LEVEL_CRITICAL) + mtrace_event((const char *)data, MESSAGE_SIZE(arg_count)); +#endif /* CONFIG_TRACEM */ } void trace_log_unfiltered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx, - uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list vl) + uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, ...) { struct trace *trace = trace_get(); + va_list vl; if (!trace->enable) { return; } - dma_trace_log(send_atomic, (uint32_t)log_entry, ctx, lvl, id_1, id_2, arg_count, vl); + va_start(vl, arg_count); + vatrace_log(send_atomic, (uint32_t)log_entry, ctx, lvl, id_1, id_2, arg_count, vl); + va_end(vl); } void trace_log_filtered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx, - uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, va_list vl) + uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, ...) { struct trace *trace = trace_get(); - + va_list vl; #if CONFIG_TRACE_FILTERING_ADAPTIVE uint64_t current_ts; #endif /* CONFIG_TRACE_FILTERING_ADAPTIVE */ @@ -287,7 +310,9 @@ void trace_log_filtered(bool send_atomic, const void *log_entry, const struct tr } #endif /* CONFIG_TRACE_FILTERING_ADAPTIVE */ - dma_trace_log(send_atomic, (uint32_t)log_entry, ctx, lvl, id_1, id_2, arg_count, vl); + va_start(vl, arg_count); + vatrace_log(send_atomic, (uint32_t)log_entry, ctx, lvl, id_1, id_2, arg_count, vl); + va_end(vl); } struct sof_ipc_trace_filter_elem *trace_filter_fill(struct sof_ipc_trace_filter_elem *elem, @@ -507,9 +532,9 @@ void trace_init(struct sof *sof) dma_trace_init_early(sof); } -static void mtrace_dict_entry_vl(bool atomic_context, uint32_t dict_entry_address, - int n_args, va_list ap) +void mtrace_dict_entry(bool atomic_context, uint32_t dict_entry_address, int n_args, ...) { + va_list ap; int i; char packet[MESSAGE_SIZE(_TRACE_EVENT_MAX_ARGUMENT_COUNT)]; uint32_t *args = (uint32_t *)&packet[MESSAGE_SIZE(0)]; @@ -518,8 +543,10 @@ static void mtrace_dict_entry_vl(bool atomic_context, uint32_t dict_entry_addres put_header(packet, dt_tr.uuid_p, _TRACE_INV_ID, _TRACE_INV_ID, dict_entry_address, tstamp); + va_start(ap, n_args); for (i = 0; i < MIN(n_args, _TRACE_EVENT_MAX_ARGUMENT_COUNT); i++) args[i] = va_arg(ap, uint32_t); + va_end(ap); if (atomic_context) { mtrace_event(packet, MESSAGE_SIZE(n_args)); @@ -532,28 +559,3 @@ static void mtrace_dict_entry_vl(bool atomic_context, uint32_t dict_entry_addres spin_unlock_irq(&trace->lock, saved_flags); } } - -void mtrace_dict_entry(bool atomic_context, uint32_t dict_entry_address, int n_args, ...) -{ - va_list ap; - - va_start(ap, n_args); - mtrace_dict_entry_vl(atomic_context, dict_entry_address, n_args, ap); - va_end(ap); -} - -void _log_sofdict(log_func_t sofdict_logf, bool atomic, const void *log_entry, - const struct tr_ctx *ctx, const uint32_t lvl, - uint32_t id_1, uint32_t id_2, int arg_count, ...) -{ - va_list ap; - - if (lvl <= MTRACE_DUPLICATION_LEVEL) { - va_start(ap, arg_count); - mtrace_dict_entry_vl(atomic, (uint32_t)log_entry, arg_count, ap); - va_end(ap); - } - va_start(ap, arg_count); - sofdict_logf(atomic, log_entry, ctx, lvl, id_1, id_2, arg_count, ap); - va_end(ap); -} diff --git a/test/cmocka/src/common_mocks.c b/test/cmocka/src/common_mocks.c index ddabdad353d6..e362f4b953bd 100644 --- a/test/cmocka/src/common_mocks.c +++ b/test/cmocka/src/common_mocks.c @@ -102,8 +102,7 @@ void WEAK __panic(uint32_t p, char *filename, uint32_t linenum) #if CONFIG_TRACE void WEAK trace_log_filtered(bool send_atomic, const void *log_entry, const struct tr_ctx *ctx, - uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, - va_list args) + uint32_t lvl, uint32_t id_1, uint32_t id_2, int arg_count, ...) { (void) send_atomic; (void) log_entry; @@ -112,13 +111,6 @@ void WEAK trace_log_filtered(bool send_atomic, const void *log_entry, const stru (void) id_1; (void) id_2; (void) arg_count; - (void) args; -} - -void WEAK _log_sofdict(log_func_t sofdict_logf, bool atomic, const void *log_entry, - const struct tr_ctx *ctx, const uint32_t lvl, - uint32_t id_1, uint32_t id_2, int arg_count, ...) -{ } void WEAK trace_flush_dma_to_mbox(void) From a6ed9535358789d821a975b6cac57db223391906 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 30 Jul 2021 12:17:44 -0500 Subject: [PATCH 3/3] Revert "pipeline: trigger START from the task context" This reverts commit 9a7a5ce17dcb339e3fd667c8f12dd50db13afe31. Signed-off-by: Pierre-Louis Bossart --- src/audio/pipeline/pipeline-graph.c | 1 - src/audio/pipeline/pipeline-schedule.c | 74 ++++---------- src/audio/pipeline/pipeline-stream.c | 134 +++---------------------- src/audio/pipeline/pipeline-xrun.c | 2 +- src/drivers/intel/cavs/ipc.c | 7 +- src/include/sof/audio/pipeline.h | 20 +--- src/include/sof/ipc/common.h | 7 -- src/ipc/ipc-common.c | 9 -- src/ipc/ipc3/handler.c | 15 +-- 9 files changed, 41 insertions(+), 228 deletions(-) diff --git a/src/audio/pipeline/pipeline-graph.c b/src/audio/pipeline/pipeline-graph.c index d013fd2a59fd..f4e907c271cc 100644 --- a/src/audio/pipeline/pipeline-graph.c +++ b/src/audio/pipeline/pipeline-graph.c @@ -127,7 +127,6 @@ struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t p->priority = priority; p->pipeline_id = pipeline_id; p->status = COMP_STATE_INIT; - p->trigger.cmd = -EINVAL; ret = memcpy_s(&p->tctx, sizeof(struct tr_ctx), &pipe_tr, sizeof(struct tr_ctx)); assert(!ret); diff --git a/src/audio/pipeline/pipeline-schedule.c b/src/audio/pipeline/pipeline-schedule.c index ce536e366ae1..ceb146ae0b66 100644 --- a/src/audio/pipeline/pipeline-schedule.c +++ b/src/audio/pipeline/pipeline-schedule.c @@ -55,44 +55,12 @@ static enum task_state pipeline_task(void *arg) return SOF_TASK_STATE_COMPLETED; } - if (p->trigger.cmd >= 0) { - /* First pipeline task run for either START or RELEASE */ - struct sof_ipc_reply reply = { - .hdr.cmd = SOF_IPC_GLB_REPLY, - .hdr.size = sizeof(reply), - }; - - err = pipeline_trigger_run(p, p->trigger.host, p->trigger.cmd); - p->trigger.cmd = -EINVAL; - - if (err < 0) { - pipe_err(p, "pipeline_task(): failed to trigger components: %d", err); - reply.error = err; - err = SOF_TASK_STATE_COMPLETED; - } else if (err == PPL_STATUS_PATH_STOP) { - pipe_warn(p, "pipeline_task(): stopping for xrun"); - err = SOF_TASK_STATE_COMPLETED; - } else { - p->status = COMP_STATE_ACTIVE; - err = SOF_TASK_STATE_RESCHEDULE; - } - - ipc_msg_reply(&reply); - - return err; - } - - /* - * The first execution of the pipeline task above has triggered all - * pipeline components. Subsequent iterations actually perform data - * copying below. - */ err = pipeline_copy(p); if (err < 0) { /* try to recover */ err = pipeline_xrun_recover(p); if (err < 0) { - pipe_err(p, "pipeline_task(): xrun recovery failed! pipeline is stopped."); + pipe_err(p, "pipeline_task(): xrun recover failed! pipeline will be stopped!"); /* failed - host will stop this pipeline */ return SOF_TASK_STATE_COMPLETED; } @@ -139,11 +107,9 @@ int pipeline_schedule_config(struct pipeline *p, uint32_t sched_id, return 0; } -/* trigger connected pipelines: either immediately or schedule them */ void pipeline_schedule_triggered(struct pipeline_walk_context *ctx, int cmd) { - struct pipeline_data *ppl_data = ctx->comp_data; struct list_item *tlist; struct pipeline *p; uint32_t flags; @@ -155,31 +121,25 @@ void pipeline_schedule_triggered(struct pipeline_walk_context *ctx, */ irq_local_disable(flags); - switch (cmd) { - case COMP_TRIGGER_PAUSE: - case COMP_TRIGGER_STOP: - list_for_item(tlist, &ctx->pipelines) { - p = container_of(tlist, struct pipeline, list); + list_for_item(tlist, &ctx->pipelines) { + p = container_of(tlist, struct pipeline, list); + + switch (cmd) { + case COMP_TRIGGER_PAUSE: + case COMP_TRIGGER_STOP: pipeline_schedule_cancel(p); p->status = COMP_STATE_PAUSED; - } - break; - case COMP_TRIGGER_RELEASE: - case COMP_TRIGGER_START: - list_for_item(tlist, &ctx->pipelines) { - p = container_of(tlist, struct pipeline, list); - if (pipeline_is_timer_driven(p)) { - /* Use the first of connected pipelines to trigger */ - if (cmd >= 0) { - p->trigger.cmd = cmd; - p->trigger.host = ppl_data->start; - cmd = -EINVAL; - } - } else { - p->xrun_bytes = 0; - p->status = COMP_STATE_ACTIVE; - } + break; + case COMP_TRIGGER_RELEASE: + case COMP_TRIGGER_START: pipeline_schedule_copy(p, 0); + p->xrun_bytes = 0; + p->status = COMP_STATE_ACTIVE; + break; + case COMP_TRIGGER_SUSPEND: + case COMP_TRIGGER_RESUME: + default: + break; } } diff --git a/src/audio/pipeline/pipeline-stream.c b/src/audio/pipeline/pipeline-stream.c index 8350036012dc..0277bf751ea3 100644 --- a/src/audio/pipeline/pipeline-stream.c +++ b/src/audio/pipeline/pipeline-stream.c @@ -59,40 +59,21 @@ pipeline_should_report_enodata_on_trigger(struct comp_dev *rsrc, return false; } -/* Runs in IPC or in pipeline task context */ static int pipeline_comp_trigger(struct comp_dev *current, struct comp_buffer *calling_buf, struct pipeline_walk_context *ctx, int dir) { struct pipeline_data *ppl_data = ctx->comp_data; bool is_single_ppl = comp_is_single_pipeline(current, ppl_data->start); - bool is_same_sched, async; + bool is_same_sched = + pipeline_is_same_sched_comp(current->pipeline, + ppl_data->start->pipeline); int err; pipe_dbg(current->pipeline, "pipeline_comp_trigger(), current->comp.id = %u, dir = %u", dev_comp_id(current), dir); - switch (ppl_data->cmd) { - case COMP_TRIGGER_PAUSE: - case COMP_TRIGGER_STOP: - /* - * PAUSE and STOP are triggered in IPC context, not from the - * pipeline task - */ - async = true; - break; - case COMP_TRIGGER_RELEASE: - case COMP_TRIGGER_START: - async = !pipeline_is_timer_driven(current->pipeline); - break; - default: - return -EINVAL; - } - - is_same_sched = pipeline_is_same_sched_comp(current->pipeline, - ppl_data->start->pipeline); - /* trigger should propagate to the connected pipelines, * which need to be scheduled together */ @@ -111,12 +92,7 @@ static int pipeline_comp_trigger(struct comp_dev *current, if (err < 0 || err == PPL_STATUS_PATH_STOP) return err; - /* - * Add scheduling components to the list. This is only needed for the - * stopping flow. - */ - if (async) - pipeline_comp_trigger_sched_comp(current->pipeline, current, ctx); + pipeline_comp_trigger_sched_comp(current->pipeline, current, ctx); return pipeline_for_each_comp(current, ctx, dir); } @@ -196,87 +172,10 @@ int pipeline_copy(struct pipeline *p) return ret; } -/* only collect scheduling components */ -static int pipeline_comp_list(struct comp_dev *current, - struct comp_buffer *calling_buf, - struct pipeline_walk_context *ctx, int dir) -{ - struct pipeline_data *ppl_data = ctx->comp_data; - bool is_single_ppl = comp_is_single_pipeline(current, ppl_data->start); - bool is_same_sched = pipeline_is_same_sched_comp(current->pipeline, - ppl_data->start->pipeline); - - if (!is_single_ppl && !is_same_sched) { - pipe_dbg(current->pipeline, - "pipeline_comp_list(), current is from another pipeline"); - return 0; - } - - /* Add scheduling components to the list */ - pipeline_comp_trigger_sched_comp(current->pipeline, current, ctx); - - return pipeline_for_each_comp(current, ctx, dir); -} - -/* build a list of connected pipelines' scheduling components and trigger them */ -static int pipeline_trigger_list(struct pipeline *p, struct comp_dev *host, int cmd) -{ - struct pipeline_data data = { - .start = host, - .cmd = cmd, - }; - struct pipeline_walk_context walk_ctx = { - .comp_func = pipeline_comp_list, - .comp_data = &data, - .skip_incomplete = true, - }; - int ret; - - list_init(&walk_ctx.pipelines); - - ret = walk_ctx.comp_func(host, NULL, &walk_ctx, host->direction); - if (ret < 0) - pipe_err(p, "pipeline_trigger_list(): ret = %d, host->comp.id = %u, cmd = %d", - ret, dev_comp_id(host), cmd); - else - pipeline_schedule_triggered(&walk_ctx, cmd); - - return ret; -} - -/* trigger pipeline in IPC context */ +/* trigger pipeline */ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd) { - int ret; - - pipe_info(p, "pipe trigger cmd %d", cmd); - - switch (cmd) { - case COMP_TRIGGER_PAUSE: - case COMP_TRIGGER_STOP: - /* Execute immediately */ - ret = pipeline_trigger_run(p, host, cmd); - return ret == PPL_STATUS_PATH_STOP ? 0 : ret; - case COMP_TRIGGER_RELEASE: - case COMP_TRIGGER_START: - /* Add all connected pipelines to the list and schedule them all */ - ret = pipeline_trigger_list(p, host, cmd); - if (ret < 0) - return ret; - /* IPC response will be sent from the task */ - return 1; - } - - return 0; -} - -/* actually execute pipeline trigger, including components: either in IPC or in task context */ -int pipeline_trigger_run(struct pipeline *p, struct comp_dev *host, int cmd) -{ - struct pipeline_data data = { - .start = host, - .cmd = cmd, - }; + struct pipeline_data data; struct pipeline_walk_context walk_ctx = { .comp_func = pipeline_comp_trigger, .comp_data = &data, @@ -284,7 +183,7 @@ int pipeline_trigger_run(struct pipeline *p, struct comp_dev *host, int cmd) }; int ret; - pipe_dbg(p, "execute trigger cmd %d on pipe %u", cmd, p->pipeline_id); + pipe_info(p, "pipe trigger cmd %d", cmd); list_init(&walk_ctx.pipelines); @@ -294,23 +193,20 @@ int pipeline_trigger_run(struct pipeline *p, struct comp_dev *host, int cmd) if (ret < 0) { pipe_err(p, "xrun handle: ret = %d", ret); return ret; - } - - if (ret == PPL_STATUS_PATH_STOP) + } else if (ret == PPL_STATUS_PATH_STOP) /* no further action needed*/ - return pipeline_is_timer_driven(p); + return 0; } + data.start = host; + data.cmd = cmd; + ret = walk_ctx.comp_func(host, NULL, &walk_ctx, host->direction); - if (ret < 0) - pipe_err(p, "pipeline_trigger_run(): ret = %d, host->comp.id = %u, cmd = %d", + if (ret < 0) { + pipe_err(p, "pipeline_trigger(): ret = %d, host->comp.id = %u, cmd = %d", ret, dev_comp_id(host), cmd); + } - /* - * When called from the pipeline task, pipeline_comp_trigger() will not - * add pipelines to the list, so pipeline_schedule_triggered() will have - * no effect. - */ pipeline_schedule_triggered(&walk_ctx, cmd); return ret; diff --git a/src/audio/pipeline/pipeline-xrun.c b/src/audio/pipeline/pipeline-xrun.c index 04b85f3abfab..1f22fbb93b51 100644 --- a/src/audio/pipeline/pipeline-xrun.c +++ b/src/audio/pipeline/pipeline-xrun.c @@ -153,7 +153,7 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, return; /* notify all pipeline comps we are in XRUN, and stop copying */ - ret = pipeline_trigger_run(p, p->source_comp, COMP_TRIGGER_XRUN); + ret = pipeline_trigger(p, p->source_comp, COMP_TRIGGER_XRUN); if (ret < 0) pipe_err(p, "pipeline_xrun(): Pipelines notification about XRUN failed, ret = %d", ret); diff --git a/src/drivers/intel/cavs/ipc.c b/src/drivers/intel/cavs/ipc.c index a272ebb8e46b..67528d6748b4 100644 --- a/src/drivers/intel/cavs/ipc.c +++ b/src/drivers/intel/cavs/ipc.c @@ -201,13 +201,10 @@ enum task_state ipc_platform_do_cmd(void *data) void ipc_platform_complete_cmd(void *data) { struct ipc *ipc = data; - uint32_t flags; - if (!cpu_is_me(ipc->core) || ipc->delayed_response) + if (!cpu_is_me(ipc->core)) return; - spin_lock_irq(&ipc->lock, flags); - /* write 1 to clear busy, and trigger interrupt to host*/ #if CAVS_VERSION == CAVS_VERSION_1_5 ipc_write(IPC_DIPCT, ipc_read(IPC_DIPCT) | IPC_DIPCT_BUSY); @@ -232,8 +229,6 @@ void ipc_platform_complete_cmd(void *data) } #endif - - spin_unlock_irq(&ipc->lock, flags); } int ipc_platform_send_msg(struct ipc_msg *msg) diff --git a/src/include/sof/audio/pipeline.h b/src/include/sof/audio/pipeline.h index a23b9f7bf61d..bc3f5fc0e411 100644 --- a/src/include/sof/audio/pipeline.h +++ b/src/include/sof/audio/pipeline.h @@ -73,10 +73,6 @@ struct pipeline { /* position update */ uint32_t posn_offset; /* position update array offset*/ struct ipc_msg *msg; - struct { - int cmd; - struct comp_dev *host; - } trigger; }; struct pipeline_walk_context { @@ -222,22 +218,14 @@ int pipeline_prepare(struct pipeline *p, struct comp_dev *cd); */ /** - * \brief Trigger pipeline - IPC context + * \brief Trigger pipeline - atomic * \param[in] p pipeline. - * \param[in] host Host DMA component. + * \param[in] host_cd Host DMA component. * \param[in] cmd Pipeline trigger command. * \return 0 on success. */ -int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd); - -/** - * \brief Trigger pipeline - either IPC or pipeline task context - * \param[in] p pipeline. - * \param[in] host Host DMA component. - * \param[in] cmd Pipeline trigger command. - * \return 0 on success. - */ -int pipeline_trigger_run(struct pipeline *p, struct comp_dev *host, int cmd); +/* */ +int pipeline_trigger(struct pipeline *p, struct comp_dev *host_cd, int cmd); /** * \brief Copy data along a pipeline. diff --git a/src/include/sof/ipc/common.h b/src/include/sof/ipc/common.h index 79cf8de4c8e5..a53010a02f69 100644 --- a/src/include/sof/ipc/common.h +++ b/src/include/sof/ipc/common.h @@ -68,7 +68,6 @@ struct ipc { struct list_item msg_list; /* queue of messages to be sent */ bool is_notification_pending; /* notification is being sent to host */ - bool delayed_response; /* response will be sent from a different context */ unsigned int core; /* core, processing the IPC */ struct list_item comp_list; /* list of component devices */ @@ -197,10 +196,4 @@ void ipc_cmd(ipc_cmd_hdr *hdr); */ int ipc_process_on_core(uint32_t core, bool blocking); -/** - * \brief reply to an IPC message. - * @param[in] reply pointer to the reply structure. - */ -void ipc_msg_reply(struct sof_ipc_reply *reply); - #endif /* __SOF_DRIVERS_IPC_H__ */ diff --git a/src/ipc/ipc-common.c b/src/ipc/ipc-common.c index 9c341636de90..f88412558a37 100644 --- a/src/ipc/ipc-common.c +++ b/src/ipc/ipc-common.c @@ -220,15 +220,6 @@ void ipc_msg_send(struct ipc_msg *msg, void *data, bool high_priority) spin_unlock_irq(&ipc->lock, flags); } -void ipc_msg_reply(struct sof_ipc_reply *reply) -{ - struct ipc *ipc = ipc_get(); - - ipc->delayed_response = false; - mailbox_hostbox_write(0, reply, reply->hdr.size); - ipc_platform_complete_cmd(ipc); -} - void ipc_schedule_process(struct ipc *ipc) { schedule_task(&ipc->ipc_task, 0, IPC_PERIOD_USEC); diff --git a/src/ipc/ipc3/handler.c b/src/ipc/ipc3/handler.c index cf01a1e9a6a9..eb00efe70033 100644 --- a/src/ipc/ipc3/handler.c +++ b/src/ipc/ipc3/handler.c @@ -438,18 +438,11 @@ static int ipc_stream_trigger(uint32_t header) } /* trigger the component */ - if (pipeline_is_timer_driven(pcm_dev->cd->pipeline)) { - ret = pipeline_trigger(pcm_dev->cd->pipeline, pcm_dev->cd, cmd); - if (ret > 0) - ipc->delayed_response = true; - } else { - ret = pipeline_trigger_run(pcm_dev->cd->pipeline, pcm_dev->cd, cmd); - } - - if (ret < 0) + ret = pipeline_trigger(pcm_dev->cd->pipeline, pcm_dev->cd, cmd); + if (ret < 0) { tr_err(&ipc_tr, "ipc: comp %d trigger 0x%x failed %d", stream.comp_id, ipc_command, ret); - + } return ret; } @@ -1517,8 +1510,6 @@ void ipc_cmd(ipc_cmd_hdr *_hdr) /* A new IPC from the host, delivered to the primary core */ ipc->core = PLATFORM_PRIMARY_CORE_ID; - ipc->delayed_response = false; - type = iGS(hdr->cmd); switch (type) {