xref: /rk3399_ARM-atf/lib/psci/aarch32/psci_helpers.S (revision 5dd9dbb5bfe64b1eb2e78648f3a2e900678ef433)
1727e5238SSoby Mathew/*
2727e5238SSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3727e5238SSoby Mathew *
4727e5238SSoby Mathew * Redistribution and use in source and binary forms, with or without
5727e5238SSoby Mathew * modification, are permitted provided that the following conditions are met:
6727e5238SSoby Mathew *
7727e5238SSoby Mathew * Redistributions of source code must retain the above copyright notice, this
8727e5238SSoby Mathew * list of conditions and the following disclaimer.
9727e5238SSoby Mathew *
10727e5238SSoby Mathew * Redistributions in binary form must reproduce the above copyright notice,
11727e5238SSoby Mathew * this list of conditions and the following disclaimer in the documentation
12727e5238SSoby Mathew * and/or other materials provided with the distribution.
13727e5238SSoby Mathew *
14727e5238SSoby Mathew * Neither the name of ARM nor the names of its contributors may be used
15727e5238SSoby Mathew * to endorse or promote products derived from this software without specific
16727e5238SSoby Mathew * prior written permission.
17727e5238SSoby Mathew *
18727e5238SSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19727e5238SSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20727e5238SSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21727e5238SSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22727e5238SSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23727e5238SSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24727e5238SSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25727e5238SSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26727e5238SSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27727e5238SSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28727e5238SSoby Mathew * POSSIBILITY OF SUCH DAMAGE.
29727e5238SSoby Mathew */
30727e5238SSoby Mathew
31727e5238SSoby Mathew#include <asm_macros.S>
32727e5238SSoby Mathew#include <platform_def.h>
33727e5238SSoby Mathew#include <psci.h>
34727e5238SSoby Mathew
35727e5238SSoby Mathew	.globl	psci_do_pwrdown_cache_maintenance
36727e5238SSoby Mathew	.globl	psci_do_pwrup_cache_maintenance
37727e5238SSoby Mathew	.globl	psci_power_down_wfi
38727e5238SSoby Mathew
39727e5238SSoby Mathew/* -----------------------------------------------------------------------
40727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
41727e5238SSoby Mathew *
42727e5238SSoby Mathew * This function performs cache maintenance for the specified power
43727e5238SSoby Mathew * level. The levels of cache affected are determined by the power
44727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results
45727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
46727e5238SSoby Mathew * for a higher power level.
47727e5238SSoby Mathew *
48727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly
49727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory
50727e5238SSoby Mathew * attributes after the data cache is disabled.
51727e5238SSoby Mathew * -----------------------------------------------------------------------
52727e5238SSoby Mathew */
53727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance
54727e5238SSoby Mathew	push	{r4, lr}
55727e5238SSoby Mathew
56727e5238SSoby Mathew	/* ----------------------------------------------
57727e5238SSoby Mathew	 * Turn OFF cache and do stack maintenance
58727e5238SSoby Mathew	 * prior to cpu operations . This sequence is
59727e5238SSoby Mathew	 * different from AArch64 because in AArch32 the
60727e5238SSoby Mathew	 * assembler routines for cpu operations utilize
61727e5238SSoby Mathew	 * the stack whereas in AArch64 it doesn't.
62727e5238SSoby Mathew	 * ----------------------------------------------
63727e5238SSoby Mathew	 */
64727e5238SSoby Mathew	mov	r4, r0
65727e5238SSoby Mathew	bl	do_stack_maintenance
66727e5238SSoby Mathew
67727e5238SSoby Mathew	/* ---------------------------------------------
68*5dd9dbb5SJeenu Viswambharan	 * Invoke CPU-specifc power down operations for
69*5dd9dbb5SJeenu Viswambharan	 * the appropriate level
70727e5238SSoby Mathew	 * ---------------------------------------------
71727e5238SSoby Mathew	 */
72*5dd9dbb5SJeenu Viswambharan	mov	r0, r4
73727e5238SSoby Mathew	pop	{r4, lr}
74*5dd9dbb5SJeenu Viswambharan	b	prepare_cpu_pwr_dwn
75727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance
76727e5238SSoby Mathew
77727e5238SSoby Mathew
78727e5238SSoby Mathew/* -----------------------------------------------------------------------
79727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void);
80727e5238SSoby Mathew *
81727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up.
82727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning
83727e5238SSoby Mathew * on the data cache.
84727e5238SSoby Mathew * -----------------------------------------------------------------------
85727e5238SSoby Mathew */
86727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance
879f3ee61cSSoby Mathew	/* r12 is pushed to meet the 8 byte stack alignment requirement */
889f3ee61cSSoby Mathew	push	{r12, lr}
89727e5238SSoby Mathew
90727e5238SSoby Mathew	/* ---------------------------------------------
91727e5238SSoby Mathew	 * Ensure any inflight stack writes have made it
92727e5238SSoby Mathew	 * to main memory.
93727e5238SSoby Mathew	 * ---------------------------------------------
94727e5238SSoby Mathew	 */
95727e5238SSoby Mathew	dmb	st
96727e5238SSoby Mathew
97727e5238SSoby Mathew	/* ---------------------------------------------
98727e5238SSoby Mathew	 * Calculate and store the size of the used
99727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
100727e5238SSoby Mathew	 * stack base address in r0.
101727e5238SSoby Mathew	 * ---------------------------------------------
102727e5238SSoby Mathew	 */
103727e5238SSoby Mathew	bl	plat_get_my_stack
104727e5238SSoby Mathew	mov	r1, sp
105727e5238SSoby Mathew	sub	r1, r0, r1
106727e5238SSoby Mathew	mov	r0, sp
107727e5238SSoby Mathew	bl	inv_dcache_range
108727e5238SSoby Mathew
109727e5238SSoby Mathew	/* ---------------------------------------------
110727e5238SSoby Mathew	 * Enable the data cache.
111727e5238SSoby Mathew	 * ---------------------------------------------
112727e5238SSoby Mathew	 */
113727e5238SSoby Mathew	ldcopr	r0, SCTLR
114727e5238SSoby Mathew	orr	r0, r0, #SCTLR_C_BIT
115727e5238SSoby Mathew	stcopr	r0, SCTLR
116727e5238SSoby Mathew	isb
117727e5238SSoby Mathew
1189f3ee61cSSoby Mathew	pop	{r12, pc}
119727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance
120727e5238SSoby Mathew
121727e5238SSoby Mathew	/* ---------------------------------------------
122727e5238SSoby Mathew	 * void do_stack_maintenance(void)
123727e5238SSoby Mathew	 * Do stack maintenance by flushing the used
124727e5238SSoby Mathew	 * stack to the main memory and invalidating the
125727e5238SSoby Mathew	 * remainder.
126727e5238SSoby Mathew	 * ---------------------------------------------
127727e5238SSoby Mathew	 */
128727e5238SSoby Mathewfunc do_stack_maintenance
129727e5238SSoby Mathew	push	{r4, lr}
130727e5238SSoby Mathew	bl	plat_get_my_stack
131727e5238SSoby Mathew
132727e5238SSoby Mathew	/* Turn off the D-cache */
133727e5238SSoby Mathew	ldcopr	r1, SCTLR
134727e5238SSoby Mathew	bic	r1, #SCTLR_C_BIT
135727e5238SSoby Mathew	stcopr	r1, SCTLR
136727e5238SSoby Mathew	isb
137727e5238SSoby Mathew
138727e5238SSoby Mathew	/* ---------------------------------------------
139727e5238SSoby Mathew	 * Calculate and store the size of the used
140727e5238SSoby Mathew	 * stack memory in r1.
141727e5238SSoby Mathew	 * ---------------------------------------------
142727e5238SSoby Mathew	 */
143727e5238SSoby Mathew	mov	r4, r0
144727e5238SSoby Mathew	mov	r1, sp
145727e5238SSoby Mathew	sub	r1, r0, r1
146727e5238SSoby Mathew	mov	r0, sp
147727e5238SSoby Mathew	bl	flush_dcache_range
148727e5238SSoby Mathew
149727e5238SSoby Mathew	/* ---------------------------------------------
150727e5238SSoby Mathew	 * Calculate and store the size of the unused
151727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
152727e5238SSoby Mathew	 * stack base address in r0.
153727e5238SSoby Mathew	 * ---------------------------------------------
154727e5238SSoby Mathew	 */
155727e5238SSoby Mathew	sub	r0, r4, #PLATFORM_STACK_SIZE
156727e5238SSoby Mathew	sub	r1, sp, r0
157727e5238SSoby Mathew	bl	inv_dcache_range
158727e5238SSoby Mathew
159727e5238SSoby Mathew	pop	{r4, pc}
160727e5238SSoby Mathewendfunc do_stack_maintenance
161727e5238SSoby Mathew
162727e5238SSoby Mathew/* -----------------------------------------------------------------------
163727e5238SSoby Mathew * This function is called to indicate to the power controller that it
164727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will
165727e5238SSoby Mathew * be released from reset upon power up.
166727e5238SSoby Mathew * -----------------------------------------------------------------------
167727e5238SSoby Mathew */
168727e5238SSoby Mathewfunc psci_power_down_wfi
169727e5238SSoby Mathew	dsb	sy		// ensure write buffer empty
170727e5238SSoby Mathew	wfi
171a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
172727e5238SSoby Mathewendfunc psci_power_down_wfi
173