xref: /rk3399_ARM-atf/lib/psci/aarch32/psci_helpers.S (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
1727e5238SSoby Mathew/*
2727e5238SSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3727e5238SSoby Mathew *
4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5727e5238SSoby Mathew */
6727e5238SSoby Mathew
7727e5238SSoby Mathew#include <asm_macros.S>
8727e5238SSoby Mathew#include <platform_def.h>
9727e5238SSoby Mathew#include <psci.h>
10727e5238SSoby Mathew
11727e5238SSoby Mathew	.globl	psci_do_pwrdown_cache_maintenance
12727e5238SSoby Mathew	.globl	psci_do_pwrup_cache_maintenance
13727e5238SSoby Mathew	.globl	psci_power_down_wfi
14727e5238SSoby Mathew
15727e5238SSoby Mathew/* -----------------------------------------------------------------------
16727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
17727e5238SSoby Mathew *
18727e5238SSoby Mathew * This function performs cache maintenance for the specified power
19727e5238SSoby Mathew * level. The levels of cache affected are determined by the power
20727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results
21727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
22727e5238SSoby Mathew * for a higher power level.
23727e5238SSoby Mathew *
24727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly
25727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory
26727e5238SSoby Mathew * attributes after the data cache is disabled.
27727e5238SSoby Mathew * -----------------------------------------------------------------------
28727e5238SSoby Mathew */
29727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance
30727e5238SSoby Mathew	push	{r4, lr}
31727e5238SSoby Mathew
32727e5238SSoby Mathew	/* ----------------------------------------------
33727e5238SSoby Mathew	 * Turn OFF cache and do stack maintenance
34727e5238SSoby Mathew	 * prior to cpu operations . This sequence is
35727e5238SSoby Mathew	 * different from AArch64 because in AArch32 the
36727e5238SSoby Mathew	 * assembler routines for cpu operations utilize
37727e5238SSoby Mathew	 * the stack whereas in AArch64 it doesn't.
38727e5238SSoby Mathew	 * ----------------------------------------------
39727e5238SSoby Mathew	 */
40727e5238SSoby Mathew	mov	r4, r0
41727e5238SSoby Mathew	bl	do_stack_maintenance
42727e5238SSoby Mathew
43727e5238SSoby Mathew	/* ---------------------------------------------
445dd9dbb5SJeenu Viswambharan	 * Invoke CPU-specifc power down operations for
455dd9dbb5SJeenu Viswambharan	 * the appropriate level
46727e5238SSoby Mathew	 * ---------------------------------------------
47727e5238SSoby Mathew	 */
485dd9dbb5SJeenu Viswambharan	mov	r0, r4
49727e5238SSoby Mathew	pop	{r4, lr}
505dd9dbb5SJeenu Viswambharan	b	prepare_cpu_pwr_dwn
51727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance
52727e5238SSoby Mathew
53727e5238SSoby Mathew
54727e5238SSoby Mathew/* -----------------------------------------------------------------------
55727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void);
56727e5238SSoby Mathew *
57727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up.
58727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning
59727e5238SSoby Mathew * on the data cache.
60727e5238SSoby Mathew * -----------------------------------------------------------------------
61727e5238SSoby Mathew */
62727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance
639f3ee61cSSoby Mathew	/* r12 is pushed to meet the 8 byte stack alignment requirement */
649f3ee61cSSoby Mathew	push	{r12, lr}
65727e5238SSoby Mathew
66727e5238SSoby Mathew	/* ---------------------------------------------
67727e5238SSoby Mathew	 * Ensure any inflight stack writes have made it
68727e5238SSoby Mathew	 * to main memory.
69727e5238SSoby Mathew	 * ---------------------------------------------
70727e5238SSoby Mathew	 */
71727e5238SSoby Mathew	dmb	st
72727e5238SSoby Mathew
73727e5238SSoby Mathew	/* ---------------------------------------------
74727e5238SSoby Mathew	 * Calculate and store the size of the used
75727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
76727e5238SSoby Mathew	 * stack base address in r0.
77727e5238SSoby Mathew	 * ---------------------------------------------
78727e5238SSoby Mathew	 */
79727e5238SSoby Mathew	bl	plat_get_my_stack
80727e5238SSoby Mathew	mov	r1, sp
81727e5238SSoby Mathew	sub	r1, r0, r1
82727e5238SSoby Mathew	mov	r0, sp
83727e5238SSoby Mathew	bl	inv_dcache_range
84727e5238SSoby Mathew
85727e5238SSoby Mathew	/* ---------------------------------------------
86727e5238SSoby Mathew	 * Enable the data cache.
87727e5238SSoby Mathew	 * ---------------------------------------------
88727e5238SSoby Mathew	 */
89727e5238SSoby Mathew	ldcopr	r0, SCTLR
90727e5238SSoby Mathew	orr	r0, r0, #SCTLR_C_BIT
91727e5238SSoby Mathew	stcopr	r0, SCTLR
92727e5238SSoby Mathew	isb
93727e5238SSoby Mathew
949f3ee61cSSoby Mathew	pop	{r12, pc}
95727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance
96727e5238SSoby Mathew
97727e5238SSoby Mathew	/* ---------------------------------------------
98727e5238SSoby Mathew	 * void do_stack_maintenance(void)
99727e5238SSoby Mathew	 * Do stack maintenance by flushing the used
100727e5238SSoby Mathew	 * stack to the main memory and invalidating the
101727e5238SSoby Mathew	 * remainder.
102727e5238SSoby Mathew	 * ---------------------------------------------
103727e5238SSoby Mathew	 */
104727e5238SSoby Mathewfunc do_stack_maintenance
105727e5238SSoby Mathew	push	{r4, lr}
106727e5238SSoby Mathew	bl	plat_get_my_stack
107727e5238SSoby Mathew
108727e5238SSoby Mathew	/* Turn off the D-cache */
109727e5238SSoby Mathew	ldcopr	r1, SCTLR
110727e5238SSoby Mathew	bic	r1, #SCTLR_C_BIT
111727e5238SSoby Mathew	stcopr	r1, SCTLR
112727e5238SSoby Mathew	isb
113727e5238SSoby Mathew
114727e5238SSoby Mathew	/* ---------------------------------------------
115727e5238SSoby Mathew	 * Calculate and store the size of the used
116727e5238SSoby Mathew	 * stack memory in r1.
117727e5238SSoby Mathew	 * ---------------------------------------------
118727e5238SSoby Mathew	 */
119727e5238SSoby Mathew	mov	r4, r0
120727e5238SSoby Mathew	mov	r1, sp
121727e5238SSoby Mathew	sub	r1, r0, r1
122727e5238SSoby Mathew	mov	r0, sp
123727e5238SSoby Mathew	bl	flush_dcache_range
124727e5238SSoby Mathew
125727e5238SSoby Mathew	/* ---------------------------------------------
126727e5238SSoby Mathew	 * Calculate and store the size of the unused
127727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
128727e5238SSoby Mathew	 * stack base address in r0.
129727e5238SSoby Mathew	 * ---------------------------------------------
130727e5238SSoby Mathew	 */
131727e5238SSoby Mathew	sub	r0, r4, #PLATFORM_STACK_SIZE
132727e5238SSoby Mathew	sub	r1, sp, r0
133727e5238SSoby Mathew	bl	inv_dcache_range
134727e5238SSoby Mathew
135727e5238SSoby Mathew	pop	{r4, pc}
136727e5238SSoby Mathewendfunc do_stack_maintenance
137727e5238SSoby Mathew
138727e5238SSoby Mathew/* -----------------------------------------------------------------------
139727e5238SSoby Mathew * This function is called to indicate to the power controller that it
140727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will
141727e5238SSoby Mathew * be released from reset upon power up.
142727e5238SSoby Mathew * -----------------------------------------------------------------------
143727e5238SSoby Mathew */
144727e5238SSoby Mathewfunc psci_power_down_wfi
145727e5238SSoby Mathew	dsb	sy		// ensure write buffer empty
146727e5238SSoby Mathew	wfi
147a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
148727e5238SSoby Mathewendfunc psci_power_down_wfi
149