1/*
2 * Copyright (c) 2015-2020, Broadcom
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <assert_macros.S>
10#include <cpu_macros.S>
11#include <cortex_a72.h>
12#include <drivers/ti/uart/uart_16550.h>
13
14#include <platform_def.h>
15
16	.globl	plat_reset_handler
17	.globl	platform_get_entrypoint
18	.globl	plat_secondary_cold_boot_setup
19	.globl	platform_mem_init
20	.globl	platform_check_mpidr
21	.globl	plat_crash_console_init
22	.globl	plat_crash_console_putc
23	.globl	plat_crash_console_flush
24	.globl	plat_disable_acp
25	.globl	plat_is_my_cpu_primary
26	.globl	plat_my_core_pos
27	.globl	platform_is_primary_cpu
28	.globl	plat_brcm_calc_core_pos
29	.globl	plat_get_my_entrypoint
30
31
32	/* ------------------------------------------------------------
33	 * void plat_l2_init(void);
34	 *
35	 * BL1 and BL2 run with one core, one cluster
36	 * This is safe to disable cluster coherency
37	 * to make use of the data cache MMU WB attribute
38	 * for the SRAM.
39	 *
40	 * Set L2 Auxiliary Control Register
41	 * --------------------------------------------------------------------
42	 */
43func plat_l2_init
44	mrs x0, CORTEX_A72_L2ACTLR_EL1
45#if (IMAGE_BL1 || IMAGE_BL2) || defined(USE_SINGLE_CLUSTER)
46	orr x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI
47#else
48	bic x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI
49#endif
50	msr CORTEX_A72_L2ACTLR_EL1, x0
51
52	/* Set L2 Control Register */
53	mrs x0, CORTEX_A72_L2CTLR_EL1
54	mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_MASK << \
55			CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
56			(CORTEX_A72_L2_TAG_RAM_LATENCY_MASK << \
57			CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT) | \
58			(U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \
59			(U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT))
60	bic x0, x0, x1
61	mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << \
62			CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
63			(U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \
64			(U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT))
65	orr x0, x0, x1
66	msr CORTEX_A72_L2CTLR_EL1, x0
67
68	isb
69	ret
70endfunc plat_l2_init
71
72	/* --------------------------------------------------------------------
73	 * void plat_reset_handler(void);
74	 *
75	 * Before adding code in this function, refer to the guidelines in
76	 * docs/firmware-design.md.
77	 *
78	 * --------------------------------------------------------------------
79	 */
80func plat_reset_handler
81	mov	x9, x30
82	bl	plat_l2_init
83	mov	x30, x9
84	ret
85endfunc plat_reset_handler
86
87	/* -----------------------------------------------------
88	 * void platform_get_entrypoint (unsigned int mpid);
89	 *
90	 * Main job of this routine is to distinguish between
91	 * a cold and warm boot.
92	 * On a cold boot the secondaries first wait for the
93	 * platform to be initialized after which they are
94	 * hotplugged in. The primary proceeds to perform the
95	 * platform initialization.
96	 * -----------------------------------------------------
97	 */
98func platform_get_entrypoint
99	/*TBD-STINGRAY*/
100	mov x0, #0
101	ret
102endfunc platform_get_entrypoint
103
104	/* -----------------------------------------------------
105	 * void plat_secondary_cold_boot_setup (void);
106	 *
107	 * This function performs any platform specific actions
108	 * needed for a secondary cpu after a cold reset e.g
109	 * mark the cpu's presence, mechanism to place it in a
110	 * holding pen etc.
111	 * -----------------------------------------------------
112	 */
113func plat_secondary_cold_boot_setup
114	bl	plat_my_core_pos
115	mov_imm	x1, SECONDARY_CPU_SPIN_BASE_ADDR
116	add	x0, x1, x0, LSL #3
117	mov	x1, #0
118	str	x1, [x0]
119
120	/* Wait until the entrypoint gets populated */
121poll_mailbox:
122	ldr	x1, [x0]
123	cbz	x1, 1f
124	br	x1
1251:
126	wfe
127	b	poll_mailbox
128endfunc plat_secondary_cold_boot_setup
129
130
131	/* -----------------------------------------------------
132	 * void platform_mem_init(void);
133	 *
134	 * We don't need to carry out any memory initialization
135	 * on CSS platforms. The Secure RAM is accessible straight away.
136	 * -----------------------------------------------------
137	 */
138func platform_mem_init
139	/*TBD-STINGRAY*/
140	ret
141endfunc platform_mem_init
142
143	/* -----------------------------------------------------
144	 * Placeholder function which should be redefined by
145	 * each platform.
146	 * -----------------------------------------------------
147	 */
148func platform_check_mpidr
149	/*TBD-STINGRAY*/
150	mov	x0, xzr
151	ret
152endfunc platform_check_mpidr
153
154	/* ---------------------------------------------
155	 * int plat_crash_console_init(void)
156	 * Function to initialize the crash console
157	 * without a C Runtime to print crash report.
158	 * Clobber list : x0, x1, x2
159	 * ---------------------------------------------
160	 */
161
162func plat_crash_console_init
163	mov_imm	x0, BRCM_CRASH_CONSOLE_BASE
164	mov_imm	x1, BRCM_CRASH_CONSOLE_REFCLK
165	mov_imm	x2, BRCM_CRASH_CONSOLE_BAUDRATE
166	b	console_16550_core_init
167	ret
168endfunc plat_crash_console_init
169
170	/* ---------------------------------------------
171	 * int plat_crash_console_putc(void)
172	 * Function to print a character on the crash
173	 * console without a C Runtime.
174	 * Clobber list : x1, x2, x3
175	 * ---------------------------------------------
176	 */
177
178func plat_crash_console_putc
179	mov_imm x1, BRCM_CRASH_CONSOLE_BASE
180	b	console_16550_core_putc
181	ret
182endfunc plat_crash_console_putc
183
184	/* ---------------------------------------------
185	 * void plat_crash_console_flush(void)
186	 * Function to flush crash console
187	 * Clobber list : x0, x1
188	 * ---------------------------------------------
189	 */
190func plat_crash_console_flush
191	mov_imm x0, BRCM_CRASH_CONSOLE_BASE
192	b	console_16550_core_flush
193	ret
194endfunc plat_crash_console_flush
195
196	/* -----------------------------------------------------
197	 * Placeholder function which should be redefined by
198	 * each platform. This function is allowed to use
199	 * registers x0 - x17.
200	 * -----------------------------------------------------
201	 */
202
203func plat_disable_acp
204	/*TBD-STINGRAY*/
205	ret
206endfunc plat_disable_acp
207
208	/* -----------------------------------------------------
209	 * unsigned int plat_is_my_cpu_primary (void);
210	 *
211	 * Find out whether the current cpu is the primary
212	 * cpu (applicable only after a cold boot)
213	 * -----------------------------------------------------
214	 */
215func plat_is_my_cpu_primary
216	mrs	x0, mpidr_el1
217	b	platform_is_primary_cpu
218endfunc plat_is_my_cpu_primary
219
220	/* -----------------------------------------------------
221	 *  unsigned int plat_my_core_pos(void)
222	 *  This function uses the plat_brcm_calc_core_pos()
223	 *  definition to get the index of the calling CPU.
224	 * -----------------------------------------------------
225	 */
226func plat_my_core_pos
227	mrs	x0, mpidr_el1
228	b	plat_brcm_calc_core_pos
229endfunc plat_my_core_pos
230
231	/* -----------------------------------------------------
232	 * unsigned int platform_is_primary_cpu (void);
233	 *
234	 * Find out whether the current cpu is the primary
235	 * cpu (applicable only after a cold boot)
236	 * -----------------------------------------------------
237	 */
238func platform_is_primary_cpu
239	mov	x9, x30
240	bl	plat_my_core_pos
241	cmp	x0, #PRIMARY_CPU
242	cset	x0, eq
243	ret	x9
244endfunc platform_is_primary_cpu
245
246	/* -----------------------------------------------------
247	 *  unsigned int plat_brcm_calc_core_pos(uint64_t mpidr)
248	 *  Helper function to calculate the core position.
249	 *  With this function: CorePos = (ClusterId * 4) +
250	 *  				  CoreId
251	 * -----------------------------------------------------
252	 */
253func plat_brcm_calc_core_pos
254	and	x1, x0, #MPIDR_CPU_MASK
255	and	x0, x0, #MPIDR_CLUSTER_MASK
256	add	x0, x1, x0, LSR #7
257	ret
258endfunc plat_brcm_calc_core_pos
259
260func plat_get_my_entrypoint
261	mrs	x0, mpidr_el1
262	b	platform_get_entrypoint
263endfunc plat_get_my_entrypoint
264