xref: /rk3399_ARM-atf/lib/psci/aarch64/psci_helpers.S (revision cc94e71b3ac5233d5ff6bc0156ded8ff03408c24)
1532ed618SSoby Mathew/*
2*cc94e71bSBoyan Karatotev * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
3532ed618SSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5532ed618SSoby Mathew */
6532ed618SSoby Mathew
7532ed618SSoby Mathew#include <asm_macros.S>
8532ed618SSoby Mathew#include <assert_macros.S>
9db9ee834SBoyan Karatotev#include <cpu_macros.S>
1009d40e0eSAntonio Nino Diaz#include <lib/psci/psci.h>
11532ed618SSoby Mathew#include <platform_def.h>
12532ed618SSoby Mathew
13532ed618SSoby Mathew	.globl	psci_do_pwrdown_cache_maintenance
14532ed618SSoby Mathew	.globl	psci_do_pwrup_cache_maintenance
15cf0b1492SSoby Mathew	.globl	psci_power_down_wfi
16532ed618SSoby Mathew
17532ed618SSoby Mathew/* -----------------------------------------------------------------------
18532ed618SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
19532ed618SSoby Mathew *
20532ed618SSoby Mathew * This function performs cache maintenance for the specified power
21532ed618SSoby Mathew * level. The levels of cache affected are determined by the power
22532ed618SSoby Mathew * level which is passed as the argument i.e. level 0 results
23532ed618SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
24532ed618SSoby Mathew * for a higher power level.
25532ed618SSoby Mathew *
26532ed618SSoby Mathew * Additionally, this function also ensures that stack memory is correctly
27532ed618SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory
28532ed618SSoby Mathew * attributes after the data cache is disabled.
29532ed618SSoby Mathew * -----------------------------------------------------------------------
30532ed618SSoby Mathew */
31532ed618SSoby Mathewfunc psci_do_pwrdown_cache_maintenance
32532ed618SSoby Mathew	stp     x29, x30, [sp,#-16]!
33532ed618SSoby Mathew	stp     x19, x20, [sp,#-16]!
34532ed618SSoby Mathew
35532ed618SSoby Mathew	/* ---------------------------------------------
365dd9dbb5SJeenu Viswambharan	 * Invoke CPU-specific power down operations for
375dd9dbb5SJeenu Viswambharan	 * the appropriate level
38532ed618SSoby Mathew	 * ---------------------------------------------
39532ed618SSoby Mathew	 */
405dd9dbb5SJeenu Viswambharan	bl	prepare_cpu_pwr_dwn
41532ed618SSoby Mathew
42532ed618SSoby Mathew	/* ---------------------------------------------
43532ed618SSoby Mathew	 * Do stack maintenance by flushing the used
44532ed618SSoby Mathew	 * stack to the main memory and invalidating the
45532ed618SSoby Mathew	 * remainder.
46532ed618SSoby Mathew	 * ---------------------------------------------
47532ed618SSoby Mathew	 */
48532ed618SSoby Mathew	bl	plat_get_my_stack
49532ed618SSoby Mathew
50532ed618SSoby Mathew	/* ---------------------------------------------
51532ed618SSoby Mathew	 * Calculate and store the size of the used
52532ed618SSoby Mathew	 * stack memory in x1.
53532ed618SSoby Mathew	 * ---------------------------------------------
54532ed618SSoby Mathew	 */
55532ed618SSoby Mathew	mov	x19, x0
56532ed618SSoby Mathew	mov	x1, sp
57532ed618SSoby Mathew	sub	x1, x0, x1
58532ed618SSoby Mathew	mov	x0, sp
59532ed618SSoby Mathew	bl	flush_dcache_range
60532ed618SSoby Mathew
61532ed618SSoby Mathew	/* ---------------------------------------------
62532ed618SSoby Mathew	 * Calculate and store the size of the unused
63532ed618SSoby Mathew	 * stack memory in x1. Calculate and store the
64532ed618SSoby Mathew	 * stack base address in x0.
65532ed618SSoby Mathew	 * ---------------------------------------------
66532ed618SSoby Mathew	 */
67532ed618SSoby Mathew	sub	x0, x19, #PLATFORM_STACK_SIZE
68532ed618SSoby Mathew	sub	x1, sp, x0
69532ed618SSoby Mathew	bl	inv_dcache_range
70532ed618SSoby Mathew
71532ed618SSoby Mathew	ldp	x19, x20, [sp], #16
72532ed618SSoby Mathew	ldp	x29, x30, [sp], #16
73532ed618SSoby Mathew	ret
74532ed618SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance
75532ed618SSoby Mathew
76532ed618SSoby Mathew
77532ed618SSoby Mathew/* -----------------------------------------------------------------------
78532ed618SSoby Mathew * void psci_do_pwrup_cache_maintenance(void);
79532ed618SSoby Mathew *
80532ed618SSoby Mathew * This function performs cache maintenance after this cpu is powered up.
81532ed618SSoby Mathew * Currently, this involves managing the used stack memory before turning
82532ed618SSoby Mathew * on the data cache.
83532ed618SSoby Mathew * -----------------------------------------------------------------------
84532ed618SSoby Mathew */
85532ed618SSoby Mathewfunc psci_do_pwrup_cache_maintenance
86532ed618SSoby Mathew	stp	x29, x30, [sp,#-16]!
87532ed618SSoby Mathew
88532ed618SSoby Mathew	/* ---------------------------------------------
89532ed618SSoby Mathew	 * Ensure any inflight stack writes have made it
90532ed618SSoby Mathew	 * to main memory.
91532ed618SSoby Mathew	 * ---------------------------------------------
92532ed618SSoby Mathew	 */
93532ed618SSoby Mathew	dmb	st
94532ed618SSoby Mathew
95532ed618SSoby Mathew	/* ---------------------------------------------
96532ed618SSoby Mathew	 * Calculate and store the size of the used
97532ed618SSoby Mathew	 * stack memory in x1. Calculate and store the
98532ed618SSoby Mathew	 * stack base address in x0.
99532ed618SSoby Mathew	 * ---------------------------------------------
100532ed618SSoby Mathew	 */
101532ed618SSoby Mathew	bl	plat_get_my_stack
102532ed618SSoby Mathew	mov	x1, sp
103532ed618SSoby Mathew	sub	x1, x0, x1
104532ed618SSoby Mathew	mov	x0, sp
105532ed618SSoby Mathew	bl	inv_dcache_range
106532ed618SSoby Mathew
107532ed618SSoby Mathew	/* ---------------------------------------------
108532ed618SSoby Mathew	 * Enable the data cache.
109532ed618SSoby Mathew	 * ---------------------------------------------
110532ed618SSoby Mathew	 */
111532ed618SSoby Mathew	mrs	x0, sctlr_el3
112532ed618SSoby Mathew	orr	x0, x0, #SCTLR_C_BIT
113532ed618SSoby Mathew	msr	sctlr_el3, x0
114532ed618SSoby Mathew	isb
115532ed618SSoby Mathew
116532ed618SSoby Mathew	ldp	x29, x30, [sp], #16
117532ed618SSoby Mathew	ret
118532ed618SSoby Mathewendfunc psci_do_pwrup_cache_maintenance
119cf0b1492SSoby Mathew
120cf0b1492SSoby Mathew/* -----------------------------------------------------------------------
121cf0b1492SSoby Mathew * void psci_power_down_wfi(void);
122cf0b1492SSoby Mathew * This function is called to indicate to the power controller that it
123cf0b1492SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will
124cf0b1492SSoby Mathew * be released from reset upon power up.
125cf0b1492SSoby Mathew * -----------------------------------------------------------------------
126cf0b1492SSoby Mathew */
127cf0b1492SSoby Mathewfunc psci_power_down_wfi
128db9ee834SBoyan Karatotev	apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597
129db9ee834SBoyan Karatotev
130cf0b1492SSoby Mathew	dsb	sy		// ensure write buffer empty
131695a48b5SHarrison Mutai1:
132cf0b1492SSoby Mathew	wfi
133695a48b5SHarrison Mutai	b	1b
134*cc94e71bSBoyan Karatotev
135*cc94e71bSBoyan Karatotev	/*
136*cc94e71bSBoyan Karatotev	 * in case the WFI wasn't terminal, we have to undo errata mitigations.
137*cc94e71bSBoyan Karatotev	 * These will be smart enough to handle being called the same way
138*cc94e71bSBoyan Karatotev	 */
139*cc94e71bSBoyan Karatotev	apply_erratum cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219
140*cc94e71bSBoyan Karatotev	apply_erratum cortex_x3,   ERRATUM(2313909), ERRATA_X3_2313909, NO_GET_CPU_REV
141*cc94e71bSBoyan Karatotev	apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639, NO_GET_CPU_REV
142cf0b1492SSoby Mathewendfunc psci_power_down_wfi
143