1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2020 Cortina-Access
4 *
5 */
6
7
8#include <asm-offsets.h>
9#include <config.h>
10#include <linux/linkage.h>
11#include <asm/macro.h>
12#include <asm/armv8/mmu.h>
13
14	.globl lowlevel_init
15lowlevel_init:
16	mov	x29, lr			/* Save LR */
17
18#if defined(CONFIG_SOC_CA7774)
19	/* Enable SMPEN in CPUECTLR */
20	mrs     x0, s3_1_c15_c2_1
21	tst     x0, #0x40
22        b.ne    skip_smp_setup
23	orr     x0, x0, #0x40
24	msr     s3_1_c15_c2_1, x0
25skip_smp_setup:
26#endif
27
28#if defined(CONFIG_SOC_CA8277B)
29	/* Enable CPU Timer */
30	ldr x0, =CONFIG_SYS_TIMER_BASE
31	mov x1, #1
32	str w1, [x0]
33#endif
34
35#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
36	branch_if_slave x0, 1f
37#ifndef CONFIG_TARGET_VENUS
38	ldr	x0, =GICD_BASE
39	bl	gic_init_secure
40#endif
411:
42#if defined(CONFIG_GICV3)
43	ldr	x0, =GICR_BASE
44	bl	gic_init_secure_percpu
45#elif defined(CONFIG_GICV2)
46	ldr	x0, =GICD_BASE
47	ldr	x1, =GICC_BASE
48	bl	gic_init_secure_percpu
49#endif
50#endif
51
52#ifdef CONFIG_ARMV8_MULTIENTRY
53	branch_if_master x0, x1, 2f
54
55	/*
56	 * Slave should wait for master clearing spin table.
57	 * This sync prevent salves observing incorrect
58	 * value of spin table and jumping to wrong place.
59	 */
60#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
61#ifdef CONFIG_GICV2
62	ldr	x0, =GICC_BASE
63#endif
64	bl	gic_wait_for_interrupt
65#endif
66
67	/*
68	 * All slaves will enter EL2 and optionally EL1.
69	 */
70	adr	x4, lowlevel_in_el2
71	ldr	x5, =ES_TO_AARCH64
72	bl	armv8_switch_to_el2
73
74lowlevel_in_el2:
75#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
76	adr	x4, lowlevel_in_el1
77	ldr	x5, =ES_TO_AARCH64
78	bl	armv8_switch_to_el1
79
80lowlevel_in_el1:
81#endif
82
83#endif /* CONFIG_ARMV8_MULTIENTRY */
84
852:
86	mov	lr, x29			/* Restore LR */
87	ret
88