blob: 953e5f72a0ec586a7649fea93504670683f1d1b4 [file] [log] [blame]
Sandrine Bailleux01b916b2014-07-17 16:06:39 +01001/*
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>
Juan Castillo33132e62014-10-20 12:29:58 +010033#include <arm_gic.h>
Vikram Kanigiri4991ecd2015-02-26 15:25:58 +000034#include <cci.h>
Juan Castilloefafbc82014-08-12 08:42:28 +010035#include <debug.h>
Sandrine Bailleux01b916b2014-07-17 16:06:39 +010036#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 ******************************************************************************/
48static 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 ******************************************************************************/
65static 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/*******************************************************************************
Soby Mathew539dced2014-10-02 16:56:51 +010088 * Juno handler called to check the validity of the power state parameter.
89 ******************************************************************************/
90int32_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/*******************************************************************************
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100113 * Juno handler called when an affinity instance is about to be turned on. The
114 * level and mpidr determine the affinity instance.
115 ******************************************************************************/
Achin Guptafef4fdb2014-08-18 14:40:27 +0100116int32_t juno_affinst_on(uint64_t mpidr,
117 uint64_t sec_entrypoint,
Achin Guptafef4fdb2014-08-18 14:40:27 +0100118 uint32_t afflvl,
119 uint32_t state)
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100120{
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 ******************************************************************************/
Soby Mathew539dced2014-10-02 16:56:51 +0100146void juno_affinst_on_finish(uint32_t afflvl, uint32_t state)
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100147{
Soby Mathewe146f4c2014-09-26 15:08:52 +0100148 unsigned long mpidr;
149
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100150 /* Determine if any platform actions need to be executed. */
151 if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
Soby Mathew539dced2014-10-02 16:56:51 +0100152 return;
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100153
Soby Mathewe146f4c2014-09-26 15:08:52 +0100154 /* Get the mpidr for this cpu */
155 mpidr = read_mpidr_el1();
156
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100157 /*
158 * Perform the common cluster specific operations i.e enable coherency
159 * if this cluster was off.
160 */
161 if (afflvl != MPIDR_AFFLVL0)
Vikram Kanigiri4991ecd2015-02-26 15:25:58 +0000162 cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100163
164 /* Enable the gic cpu interface */
Juan Castillo33132e62014-10-20 12:29:58 +0100165 arm_gic_cpuif_setup();
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100166
167 /* Juno todo: Is this setup only needed after a cold boot? */
Juan Castillo33132e62014-10-20 12:29:58 +0100168 arm_gic_pcpu_distif_setup();
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100169
170 /* Clear the mailbox for this cpu. */
171 juno_program_mailbox(mpidr, 0);
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100172}
173
174/*******************************************************************************
Achin Guptafef4fdb2014-08-18 14:40:27 +0100175 * Common function called while turning a cpu off or suspending it. It is called
176 * from juno_off() or juno_suspend() when these functions in turn are called for
177 * the highest affinity level which will be powered down. It performs the
178 * actions common to the OFF and SUSPEND calls.
179 ******************************************************************************/
Soby Mathew539dced2014-10-02 16:56:51 +0100180static void juno_power_down_common(uint32_t afflvl)
Achin Guptafef4fdb2014-08-18 14:40:27 +0100181{
182 uint32_t cluster_state = scpi_power_on;
183
184 /* Prevent interrupts from spuriously waking up this cpu */
Juan Castillo33132e62014-10-20 12:29:58 +0100185 arm_gic_cpuif_deactivate();
Achin Guptafef4fdb2014-08-18 14:40:27 +0100186
187 /* Cluster is to be turned off, so disable coherency */
188 if (afflvl > MPIDR_AFFLVL0) {
Vikram Kanigiri4991ecd2015-02-26 15:25:58 +0000189 cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
Achin Guptafef4fdb2014-08-18 14:40:27 +0100190 cluster_state = scpi_power_off;
191 }
192
193 /*
194 * Ask the SCP to power down the appropriate components depending upon
195 * their state.
196 */
197 scpi_set_css_power_state(read_mpidr_el1(),
198 scpi_power_off,
199 cluster_state,
200 scpi_power_on);
Achin Guptafef4fdb2014-08-18 14:40:27 +0100201}
202
203/*******************************************************************************
204 * Handler called when an affinity instance is about to be turned off. The
205 * level and mpidr determine the affinity instance. The 'state' arg. allows the
206 * platform to decide whether the cluster is being turned off and take
207 * appropriate actions.
208 *
209 * CAUTION: There is no guarantee that caches will remain turned on across calls
210 * to this function as each affinity level is dealt with. So do not write & read
211 * global variables across calls. It will be wise to do flush a write to the
212 * global to prevent unpredictable results.
213 ******************************************************************************/
Soby Mathew539dced2014-10-02 16:56:51 +0100214static void juno_affinst_off(uint32_t afflvl, uint32_t state)
Achin Guptafef4fdb2014-08-18 14:40:27 +0100215{
216 /* Determine if any platform actions need to be executed */
217 if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
Soby Mathew539dced2014-10-02 16:56:51 +0100218 return;
Achin Guptafef4fdb2014-08-18 14:40:27 +0100219
Soby Mathew539dced2014-10-02 16:56:51 +0100220 juno_power_down_common(afflvl);
Achin Guptafef4fdb2014-08-18 14:40:27 +0100221}
222
223/*******************************************************************************
224 * Handler called when an affinity instance is about to be suspended. The
225 * level and mpidr determine the affinity instance. The 'state' arg. allows the
226 * platform to decide whether the cluster is being turned off and take apt
227 * actions. The 'sec_entrypoint' determines the address in BL3-1 from where
228 * execution should resume.
229 *
230 * CAUTION: There is no guarantee that caches will remain turned on across calls
231 * to this function as each affinity level is dealt with. So do not write & read
232 * global variables across calls. It will be wise to do flush a write to the
233 * global to prevent unpredictable results.
234 ******************************************************************************/
Soby Mathew539dced2014-10-02 16:56:51 +0100235static void juno_affinst_suspend(uint64_t sec_entrypoint,
Achin Guptafef4fdb2014-08-18 14:40:27 +0100236 uint32_t afflvl,
237 uint32_t state)
238{
239 /* Determine if any platform actions need to be executed */
240 if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
Soby Mathew539dced2014-10-02 16:56:51 +0100241 return;
Achin Guptafef4fdb2014-08-18 14:40:27 +0100242
243 /*
244 * Setup mailbox with address for CPU entrypoint when it next powers up.
245 */
Soby Mathewe146f4c2014-09-26 15:08:52 +0100246 juno_program_mailbox(read_mpidr_el1(), sec_entrypoint);
Achin Guptafef4fdb2014-08-18 14:40:27 +0100247
Soby Mathew539dced2014-10-02 16:56:51 +0100248 juno_power_down_common(afflvl);
Achin Guptafef4fdb2014-08-18 14:40:27 +0100249}
250
251/*******************************************************************************
252 * Juno handler called when an affinity instance has just been powered on after
253 * having been suspended earlier. The level and mpidr determine the affinity
254 * instance.
255 * TODO: At the moment we reuse the on finisher and reinitialize the secure
256 * context. Need to implement a separate suspend finisher.
257 ******************************************************************************/
Soby Mathew539dced2014-10-02 16:56:51 +0100258static void juno_affinst_suspend_finish(uint32_t afflvl,
Achin Guptafef4fdb2014-08-18 14:40:27 +0100259 uint32_t state)
260{
Soby Mathew539dced2014-10-02 16:56:51 +0100261 juno_affinst_on_finish(afflvl, state);
Achin Guptafef4fdb2014-08-18 14:40:27 +0100262}
263
264/*******************************************************************************
Juan Castilloefafbc82014-08-12 08:42:28 +0100265 * Juno handlers to shutdown/reboot the system
266 ******************************************************************************/
267static void __dead2 juno_system_off(void)
268{
269 uint32_t response;
270
271 /* Send the power down request to the SCP */
272 response = scpi_sys_power_state(scpi_system_shutdown);
273
274 if (response != SCP_OK) {
275 ERROR("Juno System Off: SCP error %u.\n", response);
276 panic();
277 }
278 wfi();
279 ERROR("Juno System Off: operation not handled.\n");
280 panic();
281}
282
283static void __dead2 juno_system_reset(void)
284{
285 uint32_t response;
286
287 /* Send the system reset request to the SCP */
288 response = scpi_sys_power_state(scpi_system_reboot);
289
290 if (response != SCP_OK) {
291 ERROR("Juno System Reset: SCP error %u.\n", response);
292 panic();
293 }
294 wfi();
295 ERROR("Juno System Reset: operation not handled.\n");
296 panic();
297}
298
299/*******************************************************************************
Vikram Kanigirifc680452014-07-01 15:34:11 +0100300 * Handler called when an affinity instance is about to enter standby.
301 ******************************************************************************/
Soby Mathew539dced2014-10-02 16:56:51 +0100302void juno_affinst_standby(unsigned int power_state)
Vikram Kanigirifc680452014-07-01 15:34:11 +0100303{
Vikram Kanigirifc680452014-07-01 15:34:11 +0100304 unsigned int scr;
305
Vikram Kanigirifc680452014-07-01 15:34:11 +0100306 scr = read_scr_el3();
307 /* Enable PhysicalIRQ bit for NS world to wake the CPU */
308 write_scr_el3(scr | SCR_IRQ_BIT);
309 isb();
310 dsb();
311 wfi();
312
313 /*
314 * Restore SCR to the original value, synchronisation of scr_el3 is
315 * done by eret while el3_exit to save some execution cycles.
316 */
317 write_scr_el3(scr);
Vikram Kanigirifc680452014-07-01 15:34:11 +0100318}
319
320/*******************************************************************************
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100321 * Export the platform handlers to enable psci to invoke them
322 ******************************************************************************/
323static const plat_pm_ops_t juno_ops = {
Achin Guptafef4fdb2014-08-18 14:40:27 +0100324 .affinst_on = juno_affinst_on,
325 .affinst_on_finish = juno_affinst_on_finish,
326 .affinst_off = juno_affinst_off,
Vikram Kanigirifc680452014-07-01 15:34:11 +0100327 .affinst_standby = juno_affinst_standby,
Achin Guptafef4fdb2014-08-18 14:40:27 +0100328 .affinst_suspend = juno_affinst_suspend,
Juan Castilloefafbc82014-08-12 08:42:28 +0100329 .affinst_suspend_finish = juno_affinst_suspend_finish,
330 .system_off = juno_system_off,
Soby Mathew539dced2014-10-02 16:56:51 +0100331 .system_reset = juno_system_reset,
332 .validate_power_state = juno_validate_power_state
Sandrine Bailleux01b916b2014-07-17 16:06:39 +0100333};
334
335/*******************************************************************************
336 * Export the platform specific power ops.
337 ******************************************************************************/
338int32_t platform_setup_pm(const plat_pm_ops_t **plat_ops)
339{
340 *plat_ops = &juno_ops;
341 return 0;
342}