xref: /optee_os/core/arch/arm/plat-stm32mp2/stm32mp_pm.c (revision 5d5d7d0b1c038a6836be9f0b38585f5aa6a4dd01)
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