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 ******************************************************************************/
juno_program_mailbox(uint64_t mpidr,uint64_t address)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 ******************************************************************************/
juno_do_plat_actions(uint32_t afflvl,uint32_t state)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 ******************************************************************************/
juno_validate_power_state(unsigned int power_state)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 ******************************************************************************/
juno_affinst_on(uint64_t mpidr,uint64_t sec_entrypoint,uint32_t afflvl,uint32_t state)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 ******************************************************************************/
juno_affinst_on_finish(uint32_t afflvl,uint32_t state)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 ******************************************************************************/
juno_power_down_common(uint32_t afflvl)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 ******************************************************************************/
juno_affinst_off(uint32_t afflvl,uint32_t state)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 ******************************************************************************/
juno_affinst_suspend(uint64_t sec_entrypoint,uint32_t afflvl,uint32_t state)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 ******************************************************************************/
juno_affinst_suspend_finish(uint32_t afflvl,uint32_t state)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 ******************************************************************************/
juno_system_off(void)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
juno_system_reset(void)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 ******************************************************************************/
juno_affinst_standby(unsigned int power_state)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 ******************************************************************************/
platform_setup_pm(const plat_pm_ops_t ** plat_ops)339 int32_t platform_setup_pm(const plat_pm_ops_t **plat_ops)
340 {
341 *plat_ops = &juno_ops;
342 return 0;
343 }
344