1 /* 2 * Copyright (c) 2013, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <assert.h> 32 #include <arch_helpers.h> 33 #include <arm_gic.h> 34 #include <debug.h> 35 #include <cci400.h> 36 #include <errno.h> 37 #include <platform.h> 38 #include <platform_def.h> 39 #include <psci.h> 40 #include "juno_def.h" 41 #include "juno_private.h" 42 #include "scpi.h" 43 44 /******************************************************************************* 45 * Private Juno function to program the mailbox for a cpu before it is released 46 * from reset. 47 ******************************************************************************/ 48 static void juno_program_mailbox(uint64_t mpidr, uint64_t address) 49 { 50 uint64_t linear_id; 51 uint64_t mbox; 52 53 linear_id = platform_get_core_pos(mpidr); 54 mbox = TRUSTED_MAILBOXES_BASE + (linear_id << TRUSTED_MAILBOX_SHIFT); 55 *((uint64_t *) mbox) = address; 56 flush_dcache_range(mbox, sizeof(mbox)); 57 } 58 59 /******************************************************************************* 60 * Private Juno function which is used to determine if any platform actions 61 * should be performed for the specified affinity instance given its 62 * state. Nothing needs to be done if the 'state' is not off or if this is not 63 * the highest affinity level which will enter the 'state'. 64 ******************************************************************************/ 65 static int32_t juno_do_plat_actions(uint32_t afflvl, uint32_t state) 66 { 67 uint32_t max_phys_off_afflvl; 68 69 assert(afflvl <= MPIDR_AFFLVL1); 70 71 if (state != PSCI_STATE_OFF) 72 return -EAGAIN; 73 74 /* 75 * Find the highest affinity level which will be suspended and postpone 76 * all the platform specific actions until that level is hit. 77 */ 78 max_phys_off_afflvl = psci_get_max_phys_off_afflvl(); 79 assert(max_phys_off_afflvl != PSCI_INVALID_DATA); 80 assert(psci_get_suspend_afflvl() >= max_phys_off_afflvl); 81 if (afflvl != max_phys_off_afflvl) 82 return -EAGAIN; 83 84 return 0; 85 } 86 87 /******************************************************************************* 88 * Juno handler called to check the validity of the power state parameter. 89 ******************************************************************************/ 90 int32_t juno_validate_power_state(unsigned int power_state) 91 { 92 /* Sanity check the requested state */ 93 if (psci_get_pstate_type(power_state) == PSTATE_TYPE_STANDBY) { 94 /* 95 * It's possible to enter standby only on affinity level 0 i.e. 96 * a cpu on the Juno. Ignore any other affinity level. 97 */ 98 if (psci_get_pstate_afflvl(power_state) != MPIDR_AFFLVL0) 99 return PSCI_E_INVALID_PARAMS; 100 } 101 102 /* 103 * We expect the 'state id' to be zero. 104 */ 105 if (psci_get_pstate_id(power_state)) 106 return PSCI_E_INVALID_PARAMS; 107 108 return PSCI_E_SUCCESS; 109 } 110 111 112 /******************************************************************************* 113 * Juno handler called when an affinity instance is about to be turned on. The 114 * level and mpidr determine the affinity instance. 115 ******************************************************************************/ 116 int32_t juno_affinst_on(uint64_t mpidr, 117 uint64_t sec_entrypoint, 118 uint32_t afflvl, 119 uint32_t state) 120 { 121 /* 122 * SCP takes care of powering up higher affinity levels so we 123 * only need to care about level 0 124 */ 125 if (afflvl != MPIDR_AFFLVL0) 126 return PSCI_E_SUCCESS; 127 128 /* 129 * Setup mailbox with address for CPU entrypoint when it next powers up 130 */ 131 juno_program_mailbox(mpidr, sec_entrypoint); 132 133 scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on, 134 scpi_power_on); 135 136 return PSCI_E_SUCCESS; 137 } 138 139 /******************************************************************************* 140 * Juno handler called when an affinity instance has just been powered on after 141 * being turned off earlier. The level and mpidr determine the affinity 142 * instance. The 'state' arg. allows the platform to decide whether the cluster 143 * was turned off prior to wakeup and do what's necessary to setup it up 144 * correctly. 145 ******************************************************************************/ 146 void juno_affinst_on_finish(uint32_t afflvl, uint32_t state) 147 { 148 unsigned long mpidr; 149 150 /* Determine if any platform actions need to be executed. */ 151 if (juno_do_plat_actions(afflvl, state) == -EAGAIN) 152 return; 153 154 /* Get the mpidr for this cpu */ 155 mpidr = read_mpidr_el1(); 156 157 /* 158 * Perform the common cluster specific operations i.e enable coherency 159 * if this cluster was off. 160 */ 161 if (afflvl != MPIDR_AFFLVL0) 162 cci_enable_cluster_coherency(mpidr); 163 164 165 /* Enable the gic cpu interface */ 166 arm_gic_cpuif_setup(); 167 168 /* Juno todo: Is this setup only needed after a cold boot? */ 169 arm_gic_pcpu_distif_setup(); 170 171 /* Clear the mailbox for this cpu. */ 172 juno_program_mailbox(mpidr, 0); 173 } 174 175 /******************************************************************************* 176 * Common function called while turning a cpu off or suspending it. It is called 177 * from juno_off() or juno_suspend() when these functions in turn are called for 178 * the highest affinity level which will be powered down. It performs the 179 * actions common to the OFF and SUSPEND calls. 180 ******************************************************************************/ 181 static void juno_power_down_common(uint32_t afflvl) 182 { 183 uint32_t cluster_state = scpi_power_on; 184 185 /* Prevent interrupts from spuriously waking up this cpu */ 186 arm_gic_cpuif_deactivate(); 187 188 /* Cluster is to be turned off, so disable coherency */ 189 if (afflvl > MPIDR_AFFLVL0) { 190 cci_disable_cluster_coherency(read_mpidr_el1()); 191 cluster_state = scpi_power_off; 192 } 193 194 /* 195 * Ask the SCP to power down the appropriate components depending upon 196 * their state. 197 */ 198 scpi_set_css_power_state(read_mpidr_el1(), 199 scpi_power_off, 200 cluster_state, 201 scpi_power_on); 202 } 203 204 /******************************************************************************* 205 * Handler called when an affinity instance is about to be turned off. The 206 * level and mpidr determine the affinity instance. The 'state' arg. allows the 207 * platform to decide whether the cluster is being turned off and take 208 * appropriate actions. 209 * 210 * CAUTION: There is no guarantee that caches will remain turned on across calls 211 * to this function as each affinity level is dealt with. So do not write & read 212 * global variables across calls. It will be wise to do flush a write to the 213 * global to prevent unpredictable results. 214 ******************************************************************************/ 215 static void juno_affinst_off(uint32_t afflvl, uint32_t state) 216 { 217 /* Determine if any platform actions need to be executed */ 218 if (juno_do_plat_actions(afflvl, state) == -EAGAIN) 219 return; 220 221 juno_power_down_common(afflvl); 222 } 223 224 /******************************************************************************* 225 * Handler called when an affinity instance is about to be suspended. The 226 * level and mpidr determine the affinity instance. The 'state' arg. allows the 227 * platform to decide whether the cluster is being turned off and take apt 228 * actions. The 'sec_entrypoint' determines the address in BL3-1 from where 229 * execution should resume. 230 * 231 * CAUTION: There is no guarantee that caches will remain turned on across calls 232 * to this function as each affinity level is dealt with. So do not write & read 233 * global variables across calls. It will be wise to do flush a write to the 234 * global to prevent unpredictable results. 235 ******************************************************************************/ 236 static void juno_affinst_suspend(uint64_t sec_entrypoint, 237 uint32_t afflvl, 238 uint32_t state) 239 { 240 /* Determine if any platform actions need to be executed */ 241 if (juno_do_plat_actions(afflvl, state) == -EAGAIN) 242 return; 243 244 /* 245 * Setup mailbox with address for CPU entrypoint when it next powers up. 246 */ 247 juno_program_mailbox(read_mpidr_el1(), sec_entrypoint); 248 249 juno_power_down_common(afflvl); 250 } 251 252 /******************************************************************************* 253 * Juno handler called when an affinity instance has just been powered on after 254 * having been suspended earlier. The level and mpidr determine the affinity 255 * instance. 256 * TODO: At the moment we reuse the on finisher and reinitialize the secure 257 * context. Need to implement a separate suspend finisher. 258 ******************************************************************************/ 259 static void juno_affinst_suspend_finish(uint32_t afflvl, 260 uint32_t state) 261 { 262 juno_affinst_on_finish(afflvl, state); 263 } 264 265 /******************************************************************************* 266 * Juno handlers to shutdown/reboot the system 267 ******************************************************************************/ 268 static void __dead2 juno_system_off(void) 269 { 270 uint32_t response; 271 272 /* Send the power down request to the SCP */ 273 response = scpi_sys_power_state(scpi_system_shutdown); 274 275 if (response != SCP_OK) { 276 ERROR("Juno System Off: SCP error %u.\n", response); 277 panic(); 278 } 279 wfi(); 280 ERROR("Juno System Off: operation not handled.\n"); 281 panic(); 282 } 283 284 static void __dead2 juno_system_reset(void) 285 { 286 uint32_t response; 287 288 /* Send the system reset request to the SCP */ 289 response = scpi_sys_power_state(scpi_system_reboot); 290 291 if (response != SCP_OK) { 292 ERROR("Juno System Reset: SCP error %u.\n", response); 293 panic(); 294 } 295 wfi(); 296 ERROR("Juno System Reset: operation not handled.\n"); 297 panic(); 298 } 299 300 /******************************************************************************* 301 * Handler called when an affinity instance is about to enter standby. 302 ******************************************************************************/ 303 void juno_affinst_standby(unsigned int power_state) 304 { 305 unsigned int scr; 306 307 scr = read_scr_el3(); 308 /* Enable PhysicalIRQ bit for NS world to wake the CPU */ 309 write_scr_el3(scr | SCR_IRQ_BIT); 310 isb(); 311 dsb(); 312 wfi(); 313 314 /* 315 * Restore SCR to the original value, synchronisation of scr_el3 is 316 * done by eret while el3_exit to save some execution cycles. 317 */ 318 write_scr_el3(scr); 319 } 320 321 /******************************************************************************* 322 * Export the platform handlers to enable psci to invoke them 323 ******************************************************************************/ 324 static const plat_pm_ops_t juno_ops = { 325 .affinst_on = juno_affinst_on, 326 .affinst_on_finish = juno_affinst_on_finish, 327 .affinst_off = juno_affinst_off, 328 .affinst_standby = juno_affinst_standby, 329 .affinst_suspend = juno_affinst_suspend, 330 .affinst_suspend_finish = juno_affinst_suspend_finish, 331 .system_off = juno_system_off, 332 .system_reset = juno_system_reset, 333 .validate_power_state = juno_validate_power_state 334 }; 335 336 /******************************************************************************* 337 * Export the platform specific power ops. 338 ******************************************************************************/ 339 int32_t platform_setup_pm(const plat_pm_ops_t **plat_ops) 340 { 341 *plat_ops = &juno_ops; 342 return 0; 343 } 344