1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * arch/arm/cpu/armv8/rcar_gen3/lowlevel_init.S
4 *	This file is lowlevel initialize routine.
5 *
6 * (C) Copyright 2015 Renesas Electronics Corporation
7 *
8 * This file is based on the arch/arm/cpu/armv8/start.S
9 *
10 * (C) Copyright 2013
11 * David Feng <fenghua@phytium.com.cn>
12 */
13
14#include <asm-offsets.h>
15#include <config.h>
16#include <linux/linkage.h>
17#include <asm/macro.h>
18
19.align 8
20.globl	rcar_atf_boot_args
21rcar_atf_boot_args:
22	.dword 0
23	.dword 0
24	.dword 0
25	.dword 0
26
27ENTRY(save_boot_params)
28	adr	x8, rcar_atf_boot_args
29	stp	x0, x1, [x8], #16
30	stp	x2, x3, [x8], #16
31	b	save_boot_params_ret
32ENDPROC(save_boot_params)
33
34.pushsection .text.s_init, "ax"
35WEAK(s_init)
36	ret
37ENDPROC(s_init)
38.popsection
39
40ENTRY(lowlevel_init)
41	mov	x29, lr			/* Save LR */
42
43#ifndef CONFIG_ARMV8_MULTIENTRY
44	/*
45	 * For single-entry systems the lowlevel init is very simple.
46	 */
47	ldr	x0, =GICD_BASE
48	bl	gic_init_secure
49
50#else /* CONFIG_ARMV8_MULTIENTRY is set */
51
52#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
53	branch_if_slave x0, 1f
54	ldr	x0, =GICD_BASE
55	bl	gic_init_secure
561:
57#if defined(CONFIG_GICV3)
58	ldr	x0, =GICR_BASE
59	bl	gic_init_secure_percpu
60#elif defined(CONFIG_GICV2)
61	ldr	x0, =GICD_BASE
62	ldr	x1, =GICC_BASE
63	bl	gic_init_secure_percpu
64#endif
65#endif
66
67	branch_if_master x0, x1, 2f
68
69	/*
70	 * Slave should wait for master clearing spin table.
71	 * This sync prevent salves observing incorrect
72	 * value of spin table and jumping to wrong place.
73	 */
74#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
75#ifdef CONFIG_GICV2
76	ldr	x0, =GICC_BASE
77#endif
78	bl	gic_wait_for_interrupt
79#endif
80
81	/*
82	 * All slaves will enter EL2 and optionally EL1.
83	 */
84	adr	x4, lowlevel_in_el2
85	ldr	x5, =ES_TO_AARCH64
86	bl	armv8_switch_to_el2
87
88lowlevel_in_el2:
89#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
90	adr	x4, lowlevel_in_el1
91	ldr	x5, =ES_TO_AARCH64
92	bl	armv8_switch_to_el1
93
94lowlevel_in_el1:
95#endif
96#endif /* CONFIG_ARMV8_MULTIENTRY */
97
98	bl      s_init
99
1002:
101	mov	lr, x29			/* Restore LR */
102	ret
103ENDPROC(lowlevel_init)
104