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