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