1 /* 2 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <platform_def.h> 11 12 #include <arch_helpers.h> 13 #include <common/debug.h> 14 #include <drivers/arm/gic_common.h> 15 #include <drivers/arm/gicv2.h> 16 #include <drivers/st/stm32mp1_clk.h> 17 #include <drivers/st/stm32mp1_rcc.h> 18 #include <dt-bindings/clock/stm32mp1-clks.h> 19 #include <lib/mmio.h> 20 #include <lib/psci/psci.h> 21 #include <plat/common/platform.h> 22 23 #include <boot_api.h> 24 #include <stm32mp1_private.h> 25 26 static uintptr_t stm32_sec_entrypoint; 27 static uint32_t cntfrq_core0; 28 29 /******************************************************************************* 30 * STM32MP1 handler called when a CPU is about to enter standby. 31 * call by core 1 to enter in wfi 32 ******************************************************************************/ 33 static void stm32_cpu_standby(plat_local_state_t cpu_state) 34 { 35 uint32_t interrupt = GIC_SPURIOUS_INTERRUPT; 36 37 assert(cpu_state == ARM_LOCAL_STATE_RET); 38 39 /* 40 * Enter standby state 41 * dsb is good practice before using wfi to enter low power states 42 */ 43 isb(); 44 dsb(); 45 while (interrupt == GIC_SPURIOUS_INTERRUPT) { 46 wfi(); 47 48 /* Acknoledge IT */ 49 interrupt = gicv2_acknowledge_interrupt(); 50 /* If Interrupt == 1022 it will be acknowledged by non secure */ 51 if ((interrupt != PENDING_G1_INTID) && 52 (interrupt != GIC_SPURIOUS_INTERRUPT)) { 53 gicv2_end_of_interrupt(interrupt); 54 } 55 } 56 } 57 58 /******************************************************************************* 59 * STM32MP1 handler called when a power domain is about to be turned on. The 60 * mpidr determines the CPU to be turned on. 61 * call by core 0 to activate core 1 62 ******************************************************************************/ 63 static int stm32_pwr_domain_on(u_register_t mpidr) 64 { 65 unsigned long current_cpu_mpidr = read_mpidr_el1(); 66 uint32_t tamp_clk_off = 0; 67 uint32_t bkpr_core1_addr = 68 tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); 69 uint32_t bkpr_core1_magic = 70 tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); 71 72 if (mpidr == current_cpu_mpidr) { 73 return PSCI_E_INVALID_PARAMS; 74 } 75 76 if ((stm32_sec_entrypoint < STM32MP1_SRAM_BASE) || 77 (stm32_sec_entrypoint > (STM32MP1_SRAM_BASE + 78 (STM32MP1_SRAM_SIZE - 1)))) { 79 return PSCI_E_INVALID_ADDRESS; 80 } 81 82 if (!stm32mp1_clk_is_enabled(RTCAPB)) { 83 tamp_clk_off = 1; 84 if (stm32mp1_clk_enable(RTCAPB) != 0) { 85 panic(); 86 } 87 } 88 89 cntfrq_core0 = read_cntfrq_el0(); 90 91 /* Write entrypoint in backup RAM register */ 92 mmio_write_32(bkpr_core1_addr, stm32_sec_entrypoint); 93 94 /* Write magic number in backup register */ 95 mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER); 96 97 if (tamp_clk_off != 0U) { 98 if (stm32mp1_clk_disable(RTCAPB) != 0) { 99 panic(); 100 } 101 } 102 103 /* Generate an IT to core 1 */ 104 gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP1_SECONDARY_CPU); 105 106 return PSCI_E_SUCCESS; 107 } 108 109 /******************************************************************************* 110 * STM32MP1 handler called when a power domain is about to be turned off. The 111 * target_state encodes the power state that each level should transition to. 112 ******************************************************************************/ 113 static void stm32_pwr_domain_off(const psci_power_state_t *target_state) 114 { 115 /* Nothing to do */ 116 } 117 118 /******************************************************************************* 119 * STM32MP1 handler called when a power domain is about to be suspended. The 120 * target_state encodes the power state that each level should transition to. 121 ******************************************************************************/ 122 static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state) 123 { 124 /* Nothing to do, power domain is not disabled */ 125 } 126 127 /******************************************************************************* 128 * STM32MP1 handler called when a power domain has just been powered on after 129 * being turned off earlier. The target_state encodes the low power state that 130 * each level has woken up from. 131 * call by core 1 just after wake up 132 ******************************************************************************/ 133 static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state) 134 { 135 stm32mp1_gic_pcpu_init(); 136 137 write_cntfrq_el0(cntfrq_core0); 138 } 139 140 /******************************************************************************* 141 * STM32MP1 handler called when a power domain has just been powered on after 142 * having been suspended earlier. The target_state encodes the low power state 143 * that each level has woken up from. 144 ******************************************************************************/ 145 static void stm32_pwr_domain_suspend_finish(const psci_power_state_t 146 *target_state) 147 { 148 /* Nothing to do, power domain is not disabled */ 149 } 150 151 static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t 152 *target_state) 153 { 154 ERROR("stm32mpu1 Power Down WFI: operation not handled.\n"); 155 panic(); 156 } 157 158 static void __dead2 stm32_system_off(void) 159 { 160 ERROR("stm32mpu1 System Off: operation not handled.\n"); 161 panic(); 162 } 163 164 static void __dead2 stm32_system_reset(void) 165 { 166 mmio_setbits_32(RCC_BASE + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPSYSRST); 167 168 /* Loop in case system reset is not immediately caught */ 169 for ( ; ; ) { 170 ; 171 } 172 } 173 174 static int stm32_validate_power_state(unsigned int power_state, 175 psci_power_state_t *req_state) 176 { 177 int pstate = psci_get_pstate_type(power_state); 178 179 if (pstate != 0) { 180 return PSCI_E_INVALID_PARAMS; 181 } 182 183 if (psci_get_pstate_pwrlvl(power_state)) { 184 return PSCI_E_INVALID_PARAMS; 185 } 186 187 if (psci_get_pstate_id(power_state)) { 188 return PSCI_E_INVALID_PARAMS; 189 } 190 191 req_state->pwr_domain_state[0] = ARM_LOCAL_STATE_RET; 192 req_state->pwr_domain_state[1] = ARM_LOCAL_STATE_RUN; 193 194 return PSCI_E_SUCCESS; 195 } 196 197 static int stm32_validate_ns_entrypoint(uintptr_t entrypoint) 198 { 199 /* The non-secure entry point must be in DDR */ 200 if (entrypoint < STM32MP1_DDR_BASE) { 201 return PSCI_E_INVALID_ADDRESS; 202 } 203 204 return PSCI_E_SUCCESS; 205 } 206 207 static int stm32_node_hw_state(u_register_t target_cpu, 208 unsigned int power_level) 209 { 210 /* 211 * The format of 'power_level' is implementation-defined, but 0 must 212 * mean a CPU. Only allow level 0. 213 */ 214 if (power_level != MPIDR_AFFLVL0) { 215 return PSCI_E_INVALID_PARAMS; 216 } 217 218 /* 219 * From psci view the CPU 0 is always ON, 220 * CPU 1 can be SUSPEND or RUNNING. 221 * Therefore do not manage POWER OFF state and always return HW_ON. 222 */ 223 224 return (int)HW_ON; 225 } 226 227 /******************************************************************************* 228 * Export the platform handlers. The ARM Standard platform layer will take care 229 * of registering the handlers with PSCI. 230 ******************************************************************************/ 231 static const plat_psci_ops_t stm32_psci_ops = { 232 .cpu_standby = stm32_cpu_standby, 233 .pwr_domain_on = stm32_pwr_domain_on, 234 .pwr_domain_off = stm32_pwr_domain_off, 235 .pwr_domain_suspend = stm32_pwr_domain_suspend, 236 .pwr_domain_on_finish = stm32_pwr_domain_on_finish, 237 .pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish, 238 .pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi, 239 .system_off = stm32_system_off, 240 .system_reset = stm32_system_reset, 241 .validate_power_state = stm32_validate_power_state, 242 .validate_ns_entrypoint = stm32_validate_ns_entrypoint, 243 .get_node_hw_state = stm32_node_hw_state 244 }; 245 246 /******************************************************************************* 247 * Export the platform specific power ops. 248 ******************************************************************************/ 249 int plat_setup_psci_ops(uintptr_t sec_entrypoint, 250 const plat_psci_ops_t **psci_ops) 251 { 252 stm32_sec_entrypoint = sec_entrypoint; 253 *psci_ops = &stm32_psci_ops; 254 255 return 0; 256 } 257