xref: /rk3399_ARM-atf/lib/psci/aarch32/psci_helpers.S (revision 9f3ee61c904e4b6d2038086718c5ec4237d544a8)
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	/* ---------------------------------------------
68727e5238SSoby Mathew	 * Determine how many levels of cache will be
69727e5238SSoby Mathew	 * subject to cache maintenance. Power level
70727e5238SSoby Mathew	 * 0 implies that only the cpu is being powered
71727e5238SSoby Mathew	 * down. Only the L1 data cache needs to be
72727e5238SSoby Mathew	 * flushed to the PoU in this case. For a higher
73727e5238SSoby Mathew	 * power level we are assuming that a flush
74727e5238SSoby Mathew	 * of L1 data and L2 unified cache is enough.
75727e5238SSoby Mathew	 * This information should be provided by the
76727e5238SSoby Mathew	 * platform.
77727e5238SSoby Mathew	 * ---------------------------------------------
78727e5238SSoby Mathew	 */
79727e5238SSoby Mathew	cmp	r4, #PSCI_CPU_PWR_LVL
80727e5238SSoby Mathew	pop	{r4,lr}
81727e5238SSoby Mathew
82727e5238SSoby Mathew	beq	prepare_core_pwr_dwn
83727e5238SSoby Mathew	b	prepare_cluster_pwr_dwn
84727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance
85727e5238SSoby Mathew
86727e5238SSoby Mathew
87727e5238SSoby Mathew/* -----------------------------------------------------------------------
88727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void);
89727e5238SSoby Mathew *
90727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up.
91727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning
92727e5238SSoby Mathew * on the data cache.
93727e5238SSoby Mathew * -----------------------------------------------------------------------
94727e5238SSoby Mathew */
95727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance
96*9f3ee61cSSoby Mathew	/* r12 is pushed to meet the 8 byte stack alignment requirement */
97*9f3ee61cSSoby Mathew	push	{r12, lr}
98727e5238SSoby Mathew
99727e5238SSoby Mathew	/* ---------------------------------------------
100727e5238SSoby Mathew	 * Ensure any inflight stack writes have made it
101727e5238SSoby Mathew	 * to main memory.
102727e5238SSoby Mathew	 * ---------------------------------------------
103727e5238SSoby Mathew	 */
104727e5238SSoby Mathew	dmb	st
105727e5238SSoby Mathew
106727e5238SSoby Mathew	/* ---------------------------------------------
107727e5238SSoby Mathew	 * Calculate and store the size of the used
108727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
109727e5238SSoby Mathew	 * stack base address in r0.
110727e5238SSoby Mathew	 * ---------------------------------------------
111727e5238SSoby Mathew	 */
112727e5238SSoby Mathew	bl	plat_get_my_stack
113727e5238SSoby Mathew	mov	r1, sp
114727e5238SSoby Mathew	sub	r1, r0, r1
115727e5238SSoby Mathew	mov	r0, sp
116727e5238SSoby Mathew	bl	inv_dcache_range
117727e5238SSoby Mathew
118727e5238SSoby Mathew	/* ---------------------------------------------
119727e5238SSoby Mathew	 * Enable the data cache.
120727e5238SSoby Mathew	 * ---------------------------------------------
121727e5238SSoby Mathew	 */
122727e5238SSoby Mathew	ldcopr	r0, SCTLR
123727e5238SSoby Mathew	orr	r0, r0, #SCTLR_C_BIT
124727e5238SSoby Mathew	stcopr	r0, SCTLR
125727e5238SSoby Mathew	isb
126727e5238SSoby Mathew
127*9f3ee61cSSoby Mathew	pop	{r12, pc}
128727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance
129727e5238SSoby Mathew
130727e5238SSoby Mathew	/* ---------------------------------------------
131727e5238SSoby Mathew	 * void do_stack_maintenance(void)
132727e5238SSoby Mathew	 * Do stack maintenance by flushing the used
133727e5238SSoby Mathew	 * stack to the main memory and invalidating the
134727e5238SSoby Mathew	 * remainder.
135727e5238SSoby Mathew	 * ---------------------------------------------
136727e5238SSoby Mathew	 */
137727e5238SSoby Mathewfunc do_stack_maintenance
138727e5238SSoby Mathew	push	{r4, lr}
139727e5238SSoby Mathew	bl	plat_get_my_stack
140727e5238SSoby Mathew
141727e5238SSoby Mathew	/* Turn off the D-cache */
142727e5238SSoby Mathew	ldcopr	r1, SCTLR
143727e5238SSoby Mathew	bic	r1, #SCTLR_C_BIT
144727e5238SSoby Mathew	stcopr	r1, SCTLR
145727e5238SSoby Mathew	isb
146727e5238SSoby Mathew
147727e5238SSoby Mathew	/* ---------------------------------------------
148727e5238SSoby Mathew	 * Calculate and store the size of the used
149727e5238SSoby Mathew	 * stack memory in r1.
150727e5238SSoby Mathew	 * ---------------------------------------------
151727e5238SSoby Mathew	 */
152727e5238SSoby Mathew	mov	r4, r0
153727e5238SSoby Mathew	mov	r1, sp
154727e5238SSoby Mathew	sub	r1, r0, r1
155727e5238SSoby Mathew	mov	r0, sp
156727e5238SSoby Mathew	bl	flush_dcache_range
157727e5238SSoby Mathew
158727e5238SSoby Mathew	/* ---------------------------------------------
159727e5238SSoby Mathew	 * Calculate and store the size of the unused
160727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
161727e5238SSoby Mathew	 * stack base address in r0.
162727e5238SSoby Mathew	 * ---------------------------------------------
163727e5238SSoby Mathew	 */
164727e5238SSoby Mathew	sub	r0, r4, #PLATFORM_STACK_SIZE
165727e5238SSoby Mathew	sub	r1, sp, r0
166727e5238SSoby Mathew	bl	inv_dcache_range
167727e5238SSoby Mathew
168727e5238SSoby Mathew	pop	{r4, pc}
169727e5238SSoby Mathewendfunc do_stack_maintenance
170727e5238SSoby Mathew
171727e5238SSoby Mathew/* -----------------------------------------------------------------------
172727e5238SSoby Mathew * This function is called to indicate to the power controller that it
173727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will
174727e5238SSoby Mathew * be released from reset upon power up.
175727e5238SSoby Mathew * -----------------------------------------------------------------------
176727e5238SSoby Mathew */
177727e5238SSoby Mathewfunc psci_power_down_wfi
178727e5238SSoby Mathew	dsb	sy		// ensure write buffer empty
179727e5238SSoby Mathew	wfi
180727e5238SSoby Mathew	bl	plat_panic_handler
181727e5238SSoby Mathewendfunc psci_power_down_wfi
182