1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2023-2024, STMicroelectronics 4 */ 5 6 #include <kernel/misc.h> 7 #include <kernel/pm.h> 8 #include <kernel/thread.h> 9 #include <sm/psci.h> 10 #include <stm32mp_pm.h> 11 12 /** 13 * @brief Handler for system off 14 * 15 * @param[in] a0 Unused 16 * @param[in] a1 Unused 17 * 18 * @retval 0 if OK, other value else and TF-A will panic 19 */ 20 unsigned long thread_system_off_handler(unsigned long a0 __unused, 21 unsigned long a1 __unused) 22 { 23 /* 24 * configure targeted mode in PMIC for system OFF, 25 * no need to save context 26 */ 27 uint32_t pm_hint = PM_HINT_CLOCK_STATE | 28 ((PM_MAX_LEVEL << PM_HINT_PLATFORM_STATE_SHIFT) & 29 PM_HINT_PLATFORM_STATE_MASK); 30 31 return pm_change_state(PM_OP_SUSPEND, pm_hint); 32 } 33 34 static uint32_t get_pm_hint(unsigned long a0) 35 { 36 uint32_t pm_hint = 0U; 37 38 /* a0 is the highest power level which was powered down. */ 39 if (a0 < PM_D2_LPLV_LEVEL) 40 pm_hint = PM_HINT_CLOCK_STATE; 41 else 42 pm_hint = PM_HINT_CONTEXT_STATE; 43 44 pm_hint |= ((a0 << PM_HINT_PLATFORM_STATE_SHIFT) & 45 PM_HINT_PLATFORM_STATE_MASK); 46 47 return pm_hint; 48 } 49 50 /** 51 * @brief Handler for cpu resume 52 * 53 * @param[in] a0 Max power level powered down 54 * @param[in] a1 Unused 55 * 56 * @retval 0 if OK, other value else and TF-A will panic 57 */ 58 unsigned long thread_cpu_resume_handler(unsigned long a0, 59 unsigned long a1 __unused) 60 { 61 TEE_Result retstatus = TEE_SUCCESS; 62 63 retstatus = pm_change_state(PM_OP_RESUME, get_pm_hint(a0)); 64 65 /* 66 * Returned value to the TF-A. 67 * If it is not 0, the system will panic 68 */ 69 if (retstatus == TEE_SUCCESS) 70 return 0; 71 else 72 return 1; 73 } 74 75 /** 76 * @brief Handler for cpu suspend 77 * 78 * @param[in] a0 Max power level to power down 79 * @param[in] a1 Unused 80 * 81 * @retval 0 if OK, other value else and TF-A will panic 82 */ 83 unsigned long thread_cpu_suspend_handler(unsigned long a0, 84 unsigned long a1 __unused) 85 { 86 TEE_Result retstatus = TEE_SUCCESS; 87 88 retstatus = pm_change_state(PM_OP_SUSPEND, get_pm_hint(a0)); 89 90 /* 91 * Returned value to the TF-A. 92 * If it is not 0, the system will panic 93 */ 94 if (retstatus == TEE_SUCCESS) 95 return 0; 96 else 97 return 1; 98 } 99