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 */
thread_system_off_handler(unsigned long a0 __unused,unsigned long a1 __unused)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
get_pm_hint(unsigned long a0)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 */
thread_cpu_resume_handler(unsigned long a0,unsigned long a1 __unused)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 */
thread_cpu_suspend_handler(unsigned long a0,unsigned long a1 __unused)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