diff --git a/src/platform/intel/ace/platform.c b/src/platform/intel/ace/platform.c index 86afbfa80fef..0fbf364931e2 100644 --- a/src/platform/intel/ace/platform.c +++ b/src/platform/intel/ace/platform.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,11 @@ int platform_boot_complete(uint32_t boot_message) return ipc_platform_send_msg(&msg); } +static struct pm_notifier pm_state_notifier = { + .state_entry = NULL, + .state_exit = cpu_notify_state_exit, +}; + /* Runs on the primary core only */ int platform_init(struct sof *sof) { @@ -114,6 +120,9 @@ int platform_init(struct sof *sof) if (ret < 0) return ret; + /* register power states entry / exit notifiers */ + pm_notifier_register(&pm_state_notifier); + /* initialize the host IPC mechanisms */ trace_point(TRACE_BOOT_PLATFORM_IPC); ipc_init(sof); diff --git a/west.yml b/west.yml index beb5ac8d0882..9583cf6f4472 100644 --- a/west.yml +++ b/west.yml @@ -43,7 +43,7 @@ manifest: - name: zephyr repo-path: zephyr - revision: 3e02d48e4ead9978d10ee760c640bf55873f6e95 + revision: aba3b12e311b4779338406fe3e7c4c54f655d0cd remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision diff --git a/zephyr/include/sof/lib/cpu.h b/zephyr/include/sof/lib/cpu.h index 41328ee9ebe4..81a8840742b8 100644 --- a/zephyr/include/sof/lib/cpu.h +++ b/zephyr/include/sof/lib/cpu.h @@ -20,10 +20,16 @@ #include -//#include - #include +#if CONFIG_PM + +#include + +void cpu_notify_state_exit(enum pm_state state); + +#endif /* CONFIG_PM */ + /* let the compiler optimise when in single core mode */ #if CONFIG_MULTICORE && CONFIG_SMP diff --git a/zephyr/lib/cpu.c b/zephyr/lib/cpu.c index 882a7c8baf47..448697bfd6b8 100644 --- a/zephyr/lib/cpu.c +++ b/zephyr/lib/cpu.c @@ -59,12 +59,26 @@ static FUNC_NORETURN void secondary_init(void *arg) #if CONFIG_ZEPHYR_NATIVE_DRIVERS #include #include -#include LOG_MODULE_DECLARE(zephyr, CONFIG_SOF_LOG_LEVEL); extern struct tr_ctx zephyr_tr; +/* notifier called after every power state transition */ +void cpu_notify_state_exit(enum pm_state state) +{ + if (state == PM_STATE_SOFT_OFF) { +#if CONFIG_MULTICORE + if (!cpu_is_primary(arch_proc_id())) { + /* Notifying primary core that secondary core successfully exit the D3 + * state and is back in the Idle thread. + */ + atomic_set(&ready_flag, 1); + } +#endif + } +} + int cpu_enable_core(int id) { /* only called from single core, no RMW lock */ @@ -79,7 +93,13 @@ int cpu_enable_core(int id) return 0; #if ZEPHYR_VERSION(3, 0, 99) <= ZEPHYR_VERSION_CODE - z_init_cpu(id); + /* During kernel initialization, the next pm state is set to ACTIVE. By checking this + * value, we determine if this is the first core boot, if not, we need to skip idle thread + * initialization. By reinitializing the idle thread, we would overwrite the kernel structs + * and the idle thread stack. + */ + if (pm_state_next_get(id)->state == PM_STATE_ACTIVE) + z_init_cpu(id); #endif atomic_clear(&start_flag);