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
34ENTRY(lowlevel_init)
35	mov	x29, lr			/* Save LR */
36
37#ifndef CONFIG_ARMV8_MULTIENTRY
38	/*
39	 * For single-entry systems the lowlevel init is very simple.
40	 */
41	ldr	x0, =GICD_BASE
42	bl	gic_init_secure
43
44#else /* CONFIG_ARMV8_MULTIENTRY is set */
45
46#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
47	branch_if_slave x0, 1f
48	ldr	x0, =GICD_BASE
49	bl	gic_init_secure
501:
51#if defined(CONFIG_GICV3)
52	ldr	x0, =GICR_BASE
53	bl	gic_init_secure_percpu
54#elif defined(CONFIG_GICV2)
55	ldr	x0, =GICD_BASE
56	ldr	x1, =GICC_BASE
57	bl	gic_init_secure_percpu
58#endif
59#endif
60
61	branch_if_master x0, x1, 2f
62
63	/*
64	 * Slave should wait for master clearing spin table.
65	 * This sync prevent salves observing incorrect
66	 * value of spin table and jumping to wrong place.
67	 */
68#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
69#ifdef CONFIG_GICV2
70	ldr	x0, =GICC_BASE
71#endif
72	bl	gic_wait_for_interrupt
73#endif
74
75	/*
76	 * All slaves will enter EL2 and optionally EL1.
77	 */
78	adr	x4, lowlevel_in_el2
79	ldr	x5, =ES_TO_AARCH64
80	bl	armv8_switch_to_el2
81
82lowlevel_in_el2:
83#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
84	adr	x4, lowlevel_in_el1
85	ldr	x5, =ES_TO_AARCH64
86	bl	armv8_switch_to_el1
87
88lowlevel_in_el1:
89#endif
90#endif /* CONFIG_ARMV8_MULTIENTRY */
91
92	bl      s_init
93
942:
95	mov	lr, x29			/* Restore LR */
96	ret
97ENDPROC(lowlevel_init)
98