diff --git a/soc/adi/max32/CMakeLists.txt b/soc/adi/max32/CMakeLists.txt index b398dcd8d8f..0d22dfc71b3 100644 --- a/soc/adi/max32/CMakeLists.txt +++ b/soc/adi/max32/CMakeLists.txt @@ -5,6 +5,7 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_include_directories(common) zephyr_sources(soc.c) +zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_linker_sources_ifdef(CONFIG_SOC_FLASH_MAX32 SECTIONS flash.ld) if(CONFIG_SOC_MAX78000 OR CONFIG_SOC_MAX78002) zephyr_linker_sources(SECTIONS max7800x.ld) diff --git a/soc/adi/max32/Kconfig b/soc/adi/max32/Kconfig index 5750ddb609a..7f5e4324733 100644 --- a/soc/adi/max32/Kconfig +++ b/soc/adi/max32/Kconfig @@ -26,6 +26,7 @@ config SOC_FAMILY_MAX32_M4 select CPU_CORTEX_M_HAS_SYSTICK select CPU_HAS_ARM_MPU select CPU_HAS_FPU + select HAS_PM config SOC_MAX32655_M4 select MAX32_HAS_SECONDARY_RV32 diff --git a/soc/adi/max32/power.c b/soc/adi/max32/power.c new file mode 100644 index 00000000000..f82b3335228 --- /dev/null +++ b/soc/adi/max32/power.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include +#include + +#include +#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL +LOG_MODULE_REGISTER(soc); + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + /* Set PRIMASK */ + __disable_irq(); + /* Set BASEPRI to 0 */ + irq_unlock(0); + + switch (state) { + case PM_STATE_RUNTIME_IDLE: + LOG_DBG("entering PM state runtime idle"); + Wrap_MXC_LP_EnterLowPowerMode(); + break; + case PM_STATE_SUSPEND_TO_IDLE: + LOG_DBG("entering PM state suspend to idle"); + Wrap_MXC_LP_EnterMicroPowerMode(); + break; + case PM_STATE_STANDBY: + LOG_DBG("entering PM state standby"); + Wrap_MXC_LP_EnterStandbyMode(); + break; + case PM_STATE_SOFT_OFF: + LOG_DBG("entering PM state powerdown"); + Wrap_MXC_LP_EnterPowerDownMode(); + /*Code not reach here */ + default: + LOG_DBG("Unsupported power state %u", state); + return; + } + LOG_DBG("wakeup from sleep mode"); +} + +/* Handle SOC specific activity after Low Power Mode Exit */ +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + /* Set run mode config after wakeup */ + switch (state) { + case PM_STATE_RUNTIME_IDLE: + LOG_DBG("exited PM state runtime idle"); + break; + case PM_STATE_SUSPEND_TO_IDLE: + LOG_DBG("exited PM state suspend to idle"); + break; + case PM_STATE_STANDBY: + /* For this state wait a little until RTC register being ready + * otherwise seems previous RTC value being read + */ + k_busy_wait(100); + LOG_DBG("exited PM state standby"); + break; + default: + break; + } + + /* Clear PRIMASK after wakeup */ + __enable_irq(); +}