xref: /rk3399_ARM-atf/lib/psci/aarch32/psci_helpers.S (revision 727e5238fa3e9220d6a2718fab3b1df22af1dc61)
1*727e5238SSoby Mathew/*
2*727e5238SSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3*727e5238SSoby Mathew *
4*727e5238SSoby Mathew * Redistribution and use in source and binary forms, with or without
5*727e5238SSoby Mathew * modification, are permitted provided that the following conditions are met:
6*727e5238SSoby Mathew *
7*727e5238SSoby Mathew * Redistributions of source code must retain the above copyright notice, this
8*727e5238SSoby Mathew * list of conditions and the following disclaimer.
9*727e5238SSoby Mathew *
10*727e5238SSoby Mathew * Redistributions in binary form must reproduce the above copyright notice,
11*727e5238SSoby Mathew * this list of conditions and the following disclaimer in the documentation
12*727e5238SSoby Mathew * and/or other materials provided with the distribution.
13*727e5238SSoby Mathew *
14*727e5238SSoby Mathew * Neither the name of ARM nor the names of its contributors may be used
15*727e5238SSoby Mathew * to endorse or promote products derived from this software without specific
16*727e5238SSoby Mathew * prior written permission.
17*727e5238SSoby Mathew *
18*727e5238SSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*727e5238SSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*727e5238SSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*727e5238SSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22*727e5238SSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*727e5238SSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*727e5238SSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*727e5238SSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*727e5238SSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*727e5238SSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*727e5238SSoby Mathew * POSSIBILITY OF SUCH DAMAGE.
29*727e5238SSoby Mathew */
30*727e5238SSoby Mathew
31*727e5238SSoby Mathew#include <asm_macros.S>
32*727e5238SSoby Mathew#include <platform_def.h>
33*727e5238SSoby Mathew#include <psci.h>
34*727e5238SSoby Mathew
35*727e5238SSoby Mathew	.globl	psci_do_pwrdown_cache_maintenance
36*727e5238SSoby Mathew	.globl	psci_do_pwrup_cache_maintenance
37*727e5238SSoby Mathew	.globl	psci_power_down_wfi
38*727e5238SSoby Mathew
39*727e5238SSoby Mathew/* -----------------------------------------------------------------------
40*727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
41*727e5238SSoby Mathew *
42*727e5238SSoby Mathew * This function performs cache maintenance for the specified power
43*727e5238SSoby Mathew * level. The levels of cache affected are determined by the power
44*727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results
45*727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
46*727e5238SSoby Mathew * for a higher power level.
47*727e5238SSoby Mathew *
48*727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly
49*727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory
50*727e5238SSoby Mathew * attributes after the data cache is disabled.
51*727e5238SSoby Mathew * -----------------------------------------------------------------------
52*727e5238SSoby Mathew */
53*727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance
54*727e5238SSoby Mathew	push	{r4, lr}
55*727e5238SSoby Mathew
56*727e5238SSoby Mathew	/* ----------------------------------------------
57*727e5238SSoby Mathew	 * Turn OFF cache and do stack maintenance
58*727e5238SSoby Mathew	 * prior to cpu operations . This sequence is
59*727e5238SSoby Mathew	 * different from AArch64 because in AArch32 the
60*727e5238SSoby Mathew	 * assembler routines for cpu operations utilize
61*727e5238SSoby Mathew	 * the stack whereas in AArch64 it doesn't.
62*727e5238SSoby Mathew	 * ----------------------------------------------
63*727e5238SSoby Mathew	 */
64*727e5238SSoby Mathew	mov	r4, r0
65*727e5238SSoby Mathew	bl	do_stack_maintenance
66*727e5238SSoby Mathew
67*727e5238SSoby Mathew	/* ---------------------------------------------
68*727e5238SSoby Mathew	 * Determine how many levels of cache will be
69*727e5238SSoby Mathew	 * subject to cache maintenance. Power level
70*727e5238SSoby Mathew	 * 0 implies that only the cpu is being powered
71*727e5238SSoby Mathew	 * down. Only the L1 data cache needs to be
72*727e5238SSoby Mathew	 * flushed to the PoU in this case. For a higher
73*727e5238SSoby Mathew	 * power level we are assuming that a flush
74*727e5238SSoby Mathew	 * of L1 data and L2 unified cache is enough.
75*727e5238SSoby Mathew	 * This information should be provided by the
76*727e5238SSoby Mathew	 * platform.
77*727e5238SSoby Mathew	 * ---------------------------------------------
78*727e5238SSoby Mathew	 */
79*727e5238SSoby Mathew	cmp	r4, #PSCI_CPU_PWR_LVL
80*727e5238SSoby Mathew	pop	{r4,lr}
81*727e5238SSoby Mathew
82*727e5238SSoby Mathew	beq	prepare_core_pwr_dwn
83*727e5238SSoby Mathew	b	prepare_cluster_pwr_dwn
84*727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance
85*727e5238SSoby Mathew
86*727e5238SSoby Mathew
87*727e5238SSoby Mathew/* -----------------------------------------------------------------------
88*727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void);
89*727e5238SSoby Mathew *
90*727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up.
91*727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning
92*727e5238SSoby Mathew * on the data cache.
93*727e5238SSoby Mathew * -----------------------------------------------------------------------
94*727e5238SSoby Mathew */
95*727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance
96*727e5238SSoby Mathew	push	{lr}
97*727e5238SSoby Mathew
98*727e5238SSoby Mathew	/* ---------------------------------------------
99*727e5238SSoby Mathew	 * Ensure any inflight stack writes have made it
100*727e5238SSoby Mathew	 * to main memory.
101*727e5238SSoby Mathew	 * ---------------------------------------------
102*727e5238SSoby Mathew	 */
103*727e5238SSoby Mathew	dmb	st
104*727e5238SSoby Mathew
105*727e5238SSoby Mathew	/* ---------------------------------------------
106*727e5238SSoby Mathew	 * Calculate and store the size of the used
107*727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
108*727e5238SSoby Mathew	 * stack base address in r0.
109*727e5238SSoby Mathew	 * ---------------------------------------------
110*727e5238SSoby Mathew	 */
111*727e5238SSoby Mathew	bl	plat_get_my_stack
112*727e5238SSoby Mathew	mov	r1, sp
113*727e5238SSoby Mathew	sub	r1, r0, r1
114*727e5238SSoby Mathew	mov	r0, sp
115*727e5238SSoby Mathew	bl	inv_dcache_range
116*727e5238SSoby Mathew
117*727e5238SSoby Mathew	/* ---------------------------------------------
118*727e5238SSoby Mathew	 * Enable the data cache.
119*727e5238SSoby Mathew	 * ---------------------------------------------
120*727e5238SSoby Mathew	 */
121*727e5238SSoby Mathew	ldcopr	r0, SCTLR
122*727e5238SSoby Mathew	orr	r0, r0, #SCTLR_C_BIT
123*727e5238SSoby Mathew	stcopr	r0, SCTLR
124*727e5238SSoby Mathew	isb
125*727e5238SSoby Mathew
126*727e5238SSoby Mathew	pop	{pc}
127*727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance
128*727e5238SSoby Mathew
129*727e5238SSoby Mathew	/* ---------------------------------------------
130*727e5238SSoby Mathew	 * void do_stack_maintenance(void)
131*727e5238SSoby Mathew	 * Do stack maintenance by flushing the used
132*727e5238SSoby Mathew	 * stack to the main memory and invalidating the
133*727e5238SSoby Mathew	 * remainder.
134*727e5238SSoby Mathew	 * ---------------------------------------------
135*727e5238SSoby Mathew	 */
136*727e5238SSoby Mathewfunc do_stack_maintenance
137*727e5238SSoby Mathew	push	{r4, lr}
138*727e5238SSoby Mathew	bl	plat_get_my_stack
139*727e5238SSoby Mathew
140*727e5238SSoby Mathew	/* Turn off the D-cache */
141*727e5238SSoby Mathew	ldcopr	r1, SCTLR
142*727e5238SSoby Mathew	bic	r1, #SCTLR_C_BIT
143*727e5238SSoby Mathew	stcopr	r1, SCTLR
144*727e5238SSoby Mathew	isb
145*727e5238SSoby Mathew
146*727e5238SSoby Mathew	/* ---------------------------------------------
147*727e5238SSoby Mathew	 * Calculate and store the size of the used
148*727e5238SSoby Mathew	 * stack memory in r1.
149*727e5238SSoby Mathew	 * ---------------------------------------------
150*727e5238SSoby Mathew	 */
151*727e5238SSoby Mathew	mov	r4, r0
152*727e5238SSoby Mathew	mov	r1, sp
153*727e5238SSoby Mathew	sub	r1, r0, r1
154*727e5238SSoby Mathew	mov	r0, sp
155*727e5238SSoby Mathew	bl	flush_dcache_range
156*727e5238SSoby Mathew
157*727e5238SSoby Mathew	/* ---------------------------------------------
158*727e5238SSoby Mathew	 * Calculate and store the size of the unused
159*727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
160*727e5238SSoby Mathew	 * stack base address in r0.
161*727e5238SSoby Mathew	 * ---------------------------------------------
162*727e5238SSoby Mathew	 */
163*727e5238SSoby Mathew	sub	r0, r4, #PLATFORM_STACK_SIZE
164*727e5238SSoby Mathew	sub	r1, sp, r0
165*727e5238SSoby Mathew	bl	inv_dcache_range
166*727e5238SSoby Mathew
167*727e5238SSoby Mathew	pop	{r4, pc}
168*727e5238SSoby Mathewendfunc do_stack_maintenance
169*727e5238SSoby Mathew
170*727e5238SSoby Mathew/* -----------------------------------------------------------------------
171*727e5238SSoby Mathew * This function is called to indicate to the power controller that it
172*727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will
173*727e5238SSoby Mathew * be released from reset upon power up.
174*727e5238SSoby Mathew * -----------------------------------------------------------------------
175*727e5238SSoby Mathew */
176*727e5238SSoby Mathewfunc psci_power_down_wfi
177*727e5238SSoby Mathew	dsb	sy		// ensure write buffer empty
178*727e5238SSoby Mathew	wfi
179*727e5238SSoby Mathew	bl	plat_panic_handler
180*727e5238SSoby Mathewendfunc psci_power_down_wfi
181