summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/omap-headsmp.S
blob: 7d0db77ab8cbf84914fa70d3aa6787c679ef9e05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Secondary CPU startup routine source file.
 *
 * Copyright (C) 2009-2014 Texas Instruments, Inc.
 *
 * Author:
 *      Santosh Shilimkar <santosh.shilimkar@ti.com>
 *
 * Interface functions needed for the SMP. This file is based on arm
 * realview smp platform.
 * Copyright (c) 2003 ARM Limited.
 */

#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>

#include "omap44xx.h"

/* Physical address needed since MMU not enabled yet on secondary core */
#define AUX_CORE_BOOT0_PA			0x48281800
#define API_HYP_ENTRY				0x102

ENTRY(omap_secondary_startup)
#ifdef CONFIG_SMP
	b	secondary_startup
#else
/* Should never get here */
again:	wfi
	b	again
#endif
#ENDPROC(omap_secondary_startup)

/*
 * OMAP5 specific entry point for secondary CPU to jump from ROM
 * code.  This routine also provides a holding flag into which
 * secondary core is held until we're ready for it to initialise.
 * The primary core will update this flag using a hardware
 * register AuxCoreBoot0.
 */
ENTRY(omap5_secondary_startup)
wait:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
	ldr	r0, [r2]
	mov	r0, r0, lsr #5
	mrc	p15, 0, r4, c0, c0, 5
	and	r4, r4, #0x0f
	cmp	r0, r4
	bne	wait
	b	omap_secondary_startup
ENDPROC(omap5_secondary_startup)
/*
 * Same as omap5_secondary_startup except we call into the ROM to
 * enable HYP mode first.  This is called instead of
 * omap5_secondary_startup if the primary CPU was put into HYP mode by
 * the boot loader.
 */
ENTRY(omap5_secondary_hyp_startup)
wait_2:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
	ldr	r0, [r2]
	mov	r0, r0, lsr #5
	mrc	p15, 0, r4, c0, c0, 5
	and	r4, r4, #0x0f
	cmp	r0, r4
	bne	wait_2
	ldr	r12, =API_HYP_ENTRY
	badr	r0, hyp_boot
	smc	#0
hyp_boot:
	b	omap_secondary_startup
ENDPROC(omap5_secondary_hyp_startup)
/*
 * OMAP4 specific entry point for secondary CPU to jump from ROM
 * code.  This routine also provides a holding flag into which
 * secondary core is held until we're ready for it to initialise.
 * The primary core will update this flag using a hardware
 * register AuxCoreBoot0.
 */
ENTRY(omap4_secondary_startup)
hold:	ldr	r12,=0x103
	dsb
	smc	#0			@ read from AuxCoreBoot0
	mov	r0, r0, lsr #9
	mrc	p15, 0, r4, c0, c0, 5
	and	r4, r4, #0x0f
	cmp	r0, r4
	bne	hold

	/*
	 * we've been released from the wait loop,secondary_stack
	 * should now contain the SVC stack for this core
	 */
	b	omap_secondary_startup
ENDPROC(omap4_secondary_startup)

ENTRY(omap4460_secondary_startup)
hold_2:	ldr	r12,=0x103
	dsb
	smc	#0			@ read from AuxCoreBoot0
	mov	r0, r0, lsr #9
	mrc	p15, 0, r4, c0, c0, 5
	and	r4, r4, #0x0f
	cmp	r0, r4
	bne	hold_2

	/*
	 * GIC distributor control register has changed between
	 * CortexA9 r1pX and r2pX. The Control Register secure
	 * banked version is now composed of 2 bits:
	 * bit 0 == Secure Enable
	 * bit 1 == Non-Secure Enable
	 * The Non-Secure banked register has not changed
	 * Because the ROM Code is based on the r1pX GIC, the CPU1
	 * GIC restoration will cause a problem to CPU0 Non-Secure SW.
	 * The workaround must be:
	 * 1) Before doing the CPU1 wakeup, CPU0 must disable
	 * the GIC distributor
	 * 2) CPU1 must re-enable the GIC distributor on
	 * it's wakeup path.
	 */
	ldr	r1, =OMAP44XX_GIC_DIST_BASE
	ldr	r0, [r1]
	orr	r0, #1
	str	r0, [r1]

	/*
	 * we've been released from the wait loop,secondary_stack
	 * should now contain the SVC stack for this core
	 */
	b	omap_secondary_startup
ENDPROC(omap4460_secondary_startup)