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 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 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 49 void __noreturn psci_system_off(void) 50 { 51 if (!atmel_shdwc_available()) 52 panic(); 53 54 atmel_shdwc_shutdown(); 55 } 56 57 void __noreturn psci_system_reset(void) 58 { 59 if (!atmel_rstc_available()) 60 panic(); 61 62 atmel_rstc_reset(); 63 } 64 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 90 uint32_t psci_version(void) 91 { 92 return PSCI_VERSION_1_0; 93 } 94