1 /* 2 * Copyright (c) 2021 STMicroelectronics. 3 * Copyright (c) 2021 G-Technologies Sdn. Bhd. 4 * Copyright (c) 2022 Worldcoin Foundation. 5 * 6 * SPDX-License-Identifier: Apache-2.0 7 */ 8 #include <zephyr/init.h> 9 #include <zephyr/kernel.h> 10 #include <zephyr/logging/log.h> 11 #include <zephyr/pm/pm.h> 12 #include <soc.h> 13 14 #include <clock_control/clock_stm32_ll_common.h> 15 #include <stm32g4xx_ll_bus.h> 16 #include <stm32g4xx_ll_cortex.h> 17 #include <stm32g4xx_ll_pwr.h> 18 #include <stm32g4xx_ll_system.h> 19 #include <stm32g4xx_ll_utils.h> 20 LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); 21 22 /* Invoke Low Power/System Off specific Tasks */ pm_state_set(enum pm_state state,uint8_t substate_id)23void pm_state_set(enum pm_state state, uint8_t substate_id) 24 { 25 if (state != PM_STATE_SUSPEND_TO_IDLE) { 26 LOG_DBG("Unsupported power state %u", state); 27 return; 28 } 29 30 switch (substate_id) { 31 case 1: /* this corresponds to the STOP0 mode: */ 32 /* enter STOP0 mode */ 33 LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0); 34 LL_LPM_EnableDeepSleep(); 35 /* enter SLEEP mode : WFE or WFI */ 36 k_cpu_idle(); 37 break; 38 case 2: /* this corresponds to the STOP1 mode: */ 39 /* enter STOP1 mode */ 40 LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); 41 LL_LPM_EnableDeepSleep(); 42 /* enter SLEEP mode : WFE or WFI */ 43 k_cpu_idle(); 44 break; 45 default: 46 LOG_DBG("Unsupported power state substate-id %u", substate_id); 47 break; 48 } 49 } 50 51 /* Handle SOC specific activity after Low Power Mode Exit */ pm_state_exit_post_ops(enum pm_state state,uint8_t substate_id)52void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) 53 { 54 if (state != PM_STATE_SUSPEND_TO_IDLE) { 55 LOG_DBG("Unsupported power substate %u", state); 56 } else { 57 switch (substate_id) { 58 case 1: /* STOP0 */ 59 __fallthrough; 60 case 2: /* STOP1 */ 61 LL_LPM_DisableSleepOnExit(); 62 /* Clear SLEEPDEEP bit */ 63 LL_LPM_EnableSleep(); 64 break; 65 default: 66 LOG_DBG("Unsupported power substate-id %u", substate_id); 67 break; 68 } 69 /* need to restore the clock */ 70 stm32_clock_control_init(NULL); 71 } 72 73 /* 74 * System is now in active mode. 75 * Reenable interrupts which were disabled 76 * when OS started idling code. 77 */ 78 irq_unlock(0); 79 } 80 81 /* Initialize STM32 Power */ stm32_power_init(void)82void stm32_power_init(void) 83 { 84 85 /* enable Power clock */ 86 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); 87 } 88