1/*
2 * Copyright 2018-2021 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <asm_macros.S>
9#include <drivers/console.h>
10#include <lib/cpus/aarch64/cortex_a72.h>
11
12#include <platform_def.h>
13
14
15	.globl	plat_crash_console_init
16	.globl	plat_crash_console_putc
17	.globl	plat_crash_console_flush
18	.globl  plat_core_pos
19	.globl  plat_my_core_pos
20	.globl  plat_core_mask
21	.globl  plat_my_core_mask
22	.globl  plat_core_pos_by_mpidr
23	.globl _disable_ldstr_pfetch_A53
24	.globl _disable_ldstr_pfetch_A72
25	.global	_set_smmu_pagesz_64
26
27	/* int plat_crash_console_init(void)
28	 * Function to initialize the crash console
29	 * without a C Runtime to print crash report.
30	 * Clobber list : x0 - x4
31	 */
32
33	/* int plat_crash_console_init(void)
34	 * Use normal console by default. Switch it to crash
35	 * mode so serial consoles become active again.
36	 * NOTE: This default implementation will only work for
37	 * crashes that occur after a normal console (marked
38	 * valid for the crash state) has been registered with
39	 * the console framework. To debug crashes that occur
40	 * earlier, the platform has to override these functions
41	 * with an implementation that initializes a console
42	 * driver with hardcoded parameters. See
43	 * docs/porting-guide.rst for more information.
44	 */
45func plat_crash_console_init
46	mov	x3, x30
47	mov	x0, #CONSOLE_FLAG_CRASH
48	bl	console_switch_state
49	mov	x0, #1
50	ret	x3
51endfunc plat_crash_console_init
52
53	/* void plat_crash_console_putc(int character)
54	 * Output through the normal console by default.
55	 */
56func plat_crash_console_putc
57	b	console_putc
58endfunc plat_crash_console_putc
59
60	/* void plat_crash_console_flush(void)
61	 * Flush normal console by default.
62	 */
63func plat_crash_console_flush
64	b	console_flush
65endfunc plat_crash_console_flush
66
67/* This function implements a part of the critical interface between the psci
68 * generic layer and the platform that allows the former to query the platform
69 * to convert an MPIDR to a unique linear index. An error code (-1) is returned
70 * in case the MPIDR is invalid.
71 */
72func plat_core_pos_by_mpidr
73
74	b	plat_core_pos
75
76endfunc plat_core_pos_by_mpidr
77
78#if (SYMMETRICAL_CLUSTERS)
79/* unsigned int plat_my_core_mask(void)
80 *  generate a mask bit for this core
81 */
82func plat_my_core_mask
83	mrs	x0, MPIDR_EL1
84	b	plat_core_mask
85endfunc plat_my_core_mask
86
87/* unsigned int plat_core_mask(u_register_t mpidr)
88 * generate a lsb-based mask bit for the core specified by mpidr in x0.
89 *
90 * SoC core = ((cluster * cpu_per_cluster) + core)
91 * mask = (1 << SoC core)
92 */
93func plat_core_mask
94	mov	w1, wzr
95	mov	w2, wzr
96
97	/* extract cluster */
98	bfxil	w1, w0, #8, #8
99	/* extract cpu # */
100	bfxil	w2, w0, #0, #8
101
102	mov	w0, wzr
103
104	/* error checking */
105	cmp	w1, #NUMBER_OF_CLUSTERS
106	b.ge	1f
107	cmp	w2, #CORES_PER_CLUSTER
108	b.ge	1f
109
110	mov	w0, #CORES_PER_CLUSTER
111	mul	w1, w1, w0
112	add	w1, w1, w2
113	mov	w2, #0x1
114	lsl	w0, w2, w1
1151:
116	ret
117endfunc plat_core_mask
118
119/*
120 * unsigned int plat_my_core_pos(void)
121 *  generate a linear core number for this core
122 */
123func plat_my_core_pos
124	mrs	x0, MPIDR_EL1
125	b	plat_core_pos
126endfunc plat_my_core_pos
127
128/*
129 * unsigned int plat_core_pos(u_register_t mpidr)
130 * Generate a linear core number for the core specified by mpidr.
131 *
132 * SoC core = ((cluster * cpu_per_cluster) + core)
133 * Returns -1 if mpidr invalid
134 */
135func plat_core_pos
136	mov	w1, wzr
137	mov	w2, wzr
138	bfxil	w1, w0, #8, #8	/* extract cluster */
139	bfxil	w2, w0, #0, #8	/* extract cpu #   */
140
141	mov	w0, #-1
142
143	/* error checking */
144	cmp	w1, #NUMBER_OF_CLUSTERS
145	b.ge	1f
146	cmp	w2, #CORES_PER_CLUSTER
147	b.ge	1f
148
149	mov	w0, #CORES_PER_CLUSTER
150	mul	w1, w1, w0
151	add	w0, w1, w2
1521:
153	ret
154endfunc plat_core_pos
155
156#endif
157
158/* this function disables the load-store prefetch of the calling core
159 * Note: this function is for A72 cores ONLY
160 * in:  none
161 * out: none
162 * uses x0
163 */
164func _disable_ldstr_pfetch_A72
165
166	mrs	x0, CORTEX_A72_CPUACTLR_EL1
167	tst	x0, #CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
168	b.eq	1f
169	b	2f
170
171.align 6
1721:
173	dsb	sy
174	isb
175	orr	x0, x0, #CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
176	msr	CORTEX_A72_CPUACTLR_EL1, x0
177	isb
178
1792:
180	ret
181endfunc _disable_ldstr_pfetch_A72
182
183/*
184 * Function sets the SACR pagesize to 64k
185 */
186func _set_smmu_pagesz_64
187
188	ldr	x1, =NXP_SMMU_ADDR
189	ldr	w0, [x1, #0x10]
190	orr	w0, w0, #1 << 16	/* setting to 64K page */
191	str	w0, [x1, #0x10]
192
193	ret
194endfunc _set_smmu_pagesz_64
195