blob: 47338cfca95103ea83f88ac6b12111d770b77132 [file] [log] [blame]
Sandrine Bailleux798140d2014-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 Castillob3286c02014-10-20 12:29:58 +010033#include <arm_gic.h>
Juan Castillo75ed3562014-08-12 08:42:28 +010034#include <debug.h>
Sandrine Bailleux798140d2014-07-17 16:06:39 +010035#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 ******************************************************************************/
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 Mathew74e52a72014-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 Bailleux798140d2014-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 Gupta89b70cd2014-08-18 14:40:27 +0100116int32_t juno_affinst_on(uint64_t mpidr,
117 uint64_t sec_entrypoint,
Achin Gupta89b70cd2014-08-18 14:40:27 +0100118 uint32_t afflvl,
119 uint32_t state)
Sandrine Bailleux798140d2014-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 Mathew74e52a72014-10-02 16:56:51 +0100146void juno_affinst_on_finish(uint32_t afflvl, uint32_t state)
Sandrine Bailleux798140d2014-07-17 16:06:39 +0100147{
Soby Mathewffb4ab12014-09-26 15:08:52 +0100148 unsigned long mpidr;
149
Sandrine Bailleux798140d2014-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 Mathew74e52a72014-10-02 16:56:51 +0100152 return;
Sandrine Bailleux798140d2014-07-17 16:06:39 +0100153
Soby Mathewffb4ab12014-09-26 15:08:52 +0100154 /* Get the mpidr for this cpu */
155 mpidr = read_mpidr_el1();
156
Sandrine Bailleux798140d2014-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)
162 cci_enable_cluster_coherency(mpidr);
163
164
165 /* Enable the gic cpu interface */
Juan Castillob3286c02014-10-20 12:29:58 +0100166 arm_gic_cpuif_setup();
Sandrine Bailleux798140d2014-07-17 16:06:39 +0100167
168 /* Juno todo: Is this setup only needed after a cold boot? */
Juan Castillob3286c02014-10-20 12:29:58 +0100169 arm_gic_pcpu_distif_setup();
Sandrine Bailleux798140d2014-07-17 16:06:39 +0100170
171 /* Clear the mailbox for this cpu. */
172 juno_program_mailbox(mpidr, 0);
Sandrine Bailleux798140d2014-07-17 16:06:39 +0100173}
174
175/*******************************************************************************
Achin Gupta89b70cd2014-08-18 14:40:27 +0100176 * 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 ******************************************************************************/
Soby Mathew74e52a72014-10-02 16:56:51 +0100181static void juno_power_down_common(uint32_t afflvl)
Achin Gupta89b70cd2014-08-18 14:40:27 +0100182{
183 uint32_t cluster_state = scpi_power_on;
184
185 /* Prevent interrupts from spuriously waking up this cpu */
Juan Castillob3286c02014-10-20 12:29:58 +0100186 arm_gic_cpuif_deactivate();
Achin Gupta89b70cd2014-08-18 14:40:27 +0100187
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);
Achin Gupta89b70cd2014-08-18 14:40:27 +0100202}
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 ******************************************************************************/
Soby Mathew74e52a72014-10-02 16:56:51 +0100215static void juno_affinst_off(uint32_t afflvl, uint32_t state)
Achin Gupta89b70cd2014-08-18 14:40:27 +0100216{
217 /* Determine if any platform actions need to be executed */
218 if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
Soby Mathew74e52a72014-10-02 16:56:51 +0100219 return;
Achin Gupta89b70cd2014-08-18 14:40:27 +0100220
Soby Mathew74e52a72014-10-02 16:56:51 +0100221 juno_power_down_common(afflvl);
Achin Gupta89b70cd2014-08-18 14:40:27 +0100222}
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 ******************************************************************************/
Soby Mathew74e52a72014-10-02 16:56:51 +0100236static void juno_affinst_suspend(uint64_t sec_entrypoint,
Achin Gupta89b70cd2014-08-18 14:40:27 +0100237 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)
Soby Mathew74e52a72014-10-02 16:56:51 +0100242 return;
Achin Gupta89b70cd2014-08-18 14:40:27 +0100243
244 /*
245 * Setup mailbox with address for CPU entrypoint when it next powers up.
246 */
Soby Mathewffb4ab12014-09-26 15:08:52 +0100247 juno_program_mailbox(read_mpidr_el1(), sec_entrypoint);
Achin Gupta89b70cd2014-08-18 14:40:27 +0100248
Soby Mathew74e52a72014-10-02 16:56:51 +0100249 juno_power_down_common(afflvl);
Achin Gupta89b70cd2014-08-18 14:40:27 +0100250}
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 ******************************************************************************/
Soby Mathew74e52a72014-10-02 16:56:51 +0100259static void juno_affinst_suspend_finish(uint32_t afflvl,
Achin Gupta89b70cd2014-08-18 14:40:27 +0100260 uint32_t state)
261{
Soby Mathew74e52a72014-10-02 16:56:51 +0100262 juno_affinst_on_finish(afflvl, state);
Achin Gupta89b70cd2014-08-18 14:40:27 +0100263}
264
265/*******************************************************************************
Juan Castillo75ed3562014-08-12 08:42:28 +0100266 * Juno handlers to shutdown/reboot the system
267 ******************************************************************************/
268static 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
284static 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/*******************************************************************************
Vikram Kanigiri58a185e2014-07-01 15:34:11 +0100301 * Handler called when an affinity instance is about to enter standby.
302 ******************************************************************************/
Soby Mathew74e52a72014-10-02 16:56:51 +0100303void juno_affinst_standby(unsigned int power_state)
Vikram Kanigiri58a185e2014-07-01 15:34:11 +0100304{
Vikram Kanigiri58a185e2014-07-01 15:34:11 +0100305 unsigned int scr;
306
Vikram Kanigiri58a185e2014-07-01 15:34:11 +0100307 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);
Vikram Kanigiri58a185e2014-07-01 15:34:11 +0100319}
320
321/*******************************************************************************
Sandrine Bailleux798140d2014-07-17 16:06:39 +0100322 * Export the platform handlers to enable psci to invoke them
323 ******************************************************************************/
324static const plat_pm_ops_t juno_ops = {
Achin Gupta89b70cd2014-08-18 14:40:27 +0100325 .affinst_on = juno_affinst_on,
326 .affinst_on_finish = juno_affinst_on_finish,
327 .affinst_off = juno_affinst_off,
Vikram Kanigiri58a185e2014-07-01 15:34:11 +0100328 .affinst_standby = juno_affinst_standby,
Achin Gupta89b70cd2014-08-18 14:40:27 +0100329 .affinst_suspend = juno_affinst_suspend,
Juan Castillo75ed3562014-08-12 08:42:28 +0100330 .affinst_suspend_finish = juno_affinst_suspend_finish,
331 .system_off = juno_system_off,
Soby Mathew74e52a72014-10-02 16:56:51 +0100332 .system_reset = juno_system_reset,
333 .validate_power_state = juno_validate_power_state
Sandrine Bailleux798140d2014-07-17 16:06:39 +0100334};
335
336/*******************************************************************************
337 * Export the platform specific power ops.
338 ******************************************************************************/
339int32_t platform_setup_pm(const plat_pm_ops_t **plat_ops)
340{
341 *plat_ops = &juno_ops;
342 return 0;
343}