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