1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021, Microchip
4 */
5
6 #include <drivers/atmel_rstc.h>
7 #include <drivers/atmel_shdwc.h>
8 #include <drivers/pm/sam/atmel_pm.h>
9 #include <kernel/panic.h>
10 #include <sm/psci.h>
11 #include <sm/std_smc.h>
12 #include <stdint.h>
13 #include <trace.h>
14
psci_system_suspend(uintptr_t entry,uint32_t context_id __unused,struct sm_nsec_ctx * nsec)15 int psci_system_suspend(uintptr_t entry, uint32_t context_id __unused,
16 struct sm_nsec_ctx *nsec)
17 {
18 if (!atmel_pm_suspend_available())
19 return PSCI_RET_NOT_SUPPORTED;
20
21 if (atmel_pm_suspend(entry, nsec))
22 return PSCI_RET_INTERNAL_FAILURE;
23
24 return PSCI_RET_SUCCESS;
25 }
26
psci_cpu_suspend(uint32_t power_state,uintptr_t entry __unused,uint32_t context_id __unused,struct sm_nsec_ctx * nsec __unused)27 int psci_cpu_suspend(uint32_t power_state,
28 uintptr_t entry __unused, uint32_t context_id __unused,
29 struct sm_nsec_ctx *nsec __unused)
30 {
31 uint32_t type = 0;
32
33 if (atmel_pm_suspend_available())
34 return PSCI_RET_NOT_SUPPORTED;
35
36 type = (power_state & PSCI_POWER_STATE_TYPE_MASK) >>
37 PSCI_POWER_STATE_TYPE_SHIFT;
38
39 if (type != PSCI_POWER_STATE_TYPE_STANDBY) {
40 DMSG("Power state %x not supported", type);
41 return PSCI_RET_INVALID_PARAMETERS;
42 }
43
44 atmel_pm_cpu_idle();
45
46 return PSCI_RET_SUCCESS;
47 }
48
psci_system_off(void)49 void __noreturn psci_system_off(void)
50 {
51 if (!atmel_shdwc_available())
52 panic();
53
54 atmel_shdwc_shutdown();
55 }
56
psci_system_reset(void)57 void __noreturn psci_system_reset(void)
58 {
59 if (!atmel_rstc_available())
60 panic();
61
62 atmel_rstc_reset();
63 }
64
psci_features(uint32_t psci_fid)65 int psci_features(uint32_t psci_fid)
66 {
67 switch (psci_fid) {
68 case ARM_SMCCC_VERSION:
69 case PSCI_PSCI_FEATURES:
70 case PSCI_VERSION:
71 return PSCI_RET_SUCCESS;
72 case PSCI_SYSTEM_RESET:
73 if (atmel_rstc_available())
74 return PSCI_RET_SUCCESS;
75 return PSCI_RET_NOT_SUPPORTED;
76 case PSCI_SYSTEM_OFF:
77 if (atmel_shdwc_available())
78 return PSCI_RET_SUCCESS;
79 return PSCI_RET_NOT_SUPPORTED;
80 case PSCI_CPU_SUSPEND:
81 case PSCI_SYSTEM_SUSPEND:
82 if (atmel_pm_suspend_available())
83 return PSCI_RET_SUCCESS;
84 return PSCI_RET_NOT_SUPPORTED;
85 default:
86 return PSCI_RET_NOT_SUPPORTED;
87 }
88 }
89
psci_version(void)90 uint32_t psci_version(void)
91 {
92 return PSCI_VERSION_1_0;
93 }
94