1/*
2 * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <aem_generic.h>
7#include <arch.h>
8#include <asm_macros.S>
9#include <cpu_macros.S>
10
11func aem_generic_core_pwr_dwn
12	/* ---------------------------------------------
13	 * Disable the Data Cache.
14	 * ---------------------------------------------
15	 */
16	mrs	x1, sctlr_el3
17	bic	x1, x1, #SCTLR_C_BIT
18	msr	sctlr_el3, x1
19	isb
20
21	/* ---------------------------------------------
22	 * AEM model supports L3 caches in which case L2
23	 * will be private per core caches and flush
24	 * from L1 to L2 is not sufficient.
25	 * ---------------------------------------------
26	 */
27	mrs	x1, clidr_el1
28
29	/* ---------------------------------------------
30	 * Check if L3 cache is implemented.
31	 * ---------------------------------------------
32	 */
33	tst	x1, ((1 << CLIDR_FIELD_WIDTH) - 1) << CTYPE_SHIFT(3)
34
35	/* ---------------------------------------------
36	 * There is no L3 cache, flush L1 to L2 only.
37	 * ---------------------------------------------
38	 */
39	mov	x0, #DCCISW
40	b.eq	dcsw_op_level1
41
42	mov	x18, x30
43
44	/* ---------------------------------------------
45	 * Flush L1 cache to L2.
46	 * ---------------------------------------------
47	 */
48	bl	dcsw_op_level1
49	mov	x30, x18
50
51	/* ---------------------------------------------
52	 * Flush L2 cache to L3.
53	 * ---------------------------------------------
54	 */
55	mov	x0, #DCCISW
56	b	dcsw_op_level2
57endfunc aem_generic_core_pwr_dwn
58
59func aem_generic_cluster_pwr_dwn
60	/* ---------------------------------------------
61	 * Disable the Data Cache.
62	 * ---------------------------------------------
63	 */
64	mrs	x1, sctlr_el3
65	bic	x1, x1, #SCTLR_C_BIT
66	msr	sctlr_el3, x1
67	isb
68
69	/* ---------------------------------------------
70	 * Flush all caches to PoC.
71	 * ---------------------------------------------
72	 */
73	mov	x0, #DCCISW
74	b	dcsw_op_all
75endfunc aem_generic_cluster_pwr_dwn
76
77#if REPORT_ERRATA
78/*
79 * Errata printing function for AEM. Must follow AAPCS.
80 */
81func aem_generic_errata_report
82	ret
83endfunc aem_generic_errata_report
84#endif
85
86	/* ---------------------------------------------
87	 * This function provides cpu specific
88	 * register information for crash reporting.
89	 * It needs to return with x6 pointing to
90	 * a list of register names in ascii and
91	 * x8 - x15 having values of registers to be
92	 * reported.
93	 * ---------------------------------------------
94	 */
95.section .rodata.aem_generic_regs, "aS"
96aem_generic_regs:  /* The ascii list of register names to be reported */
97	.asciz	"" /* no registers to report */
98
99func aem_generic_cpu_reg_dump
100	adr	x6, aem_generic_regs
101	ret
102endfunc aem_generic_cpu_reg_dump
103
104
105/* cpu_ops for Base AEM FVP */
106declare_cpu_ops aem_generic, BASE_AEM_MIDR, CPU_NO_RESET_FUNC, \
107	aem_generic_core_pwr_dwn, \
108	aem_generic_cluster_pwr_dwn
109
110/* cpu_ops for Foundation FVP */
111declare_cpu_ops aem_generic, FOUNDATION_AEM_MIDR, CPU_NO_RESET_FUNC, \
112	aem_generic_core_pwr_dwn, \
113	aem_generic_cluster_pwr_dwn
114