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