xref: /openbmc/linux/arch/arm/mach-omap2/omap-headsmp.S (revision 0898782247ae533d1f4e47a06bc5d4870931b284)
1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
2367cd31eSSantosh Shilimkar/*
3367cd31eSSantosh Shilimkar * Secondary CPU startup routine source file.
4367cd31eSSantosh Shilimkar *
5da0159fdSJoel Fernandes * Copyright (C) 2009-2014 Texas Instruments, Inc.
6367cd31eSSantosh Shilimkar *
7367cd31eSSantosh Shilimkar * Author:
8367cd31eSSantosh Shilimkar *      Santosh Shilimkar <santosh.shilimkar@ti.com>
9367cd31eSSantosh Shilimkar *
10367cd31eSSantosh Shilimkar * Interface functions needed for the SMP. This file is based on arm
11367cd31eSSantosh Shilimkar * realview smp platform.
12367cd31eSSantosh Shilimkar * Copyright (c) 2003 ARM Limited.
13367cd31eSSantosh Shilimkar */
14367cd31eSSantosh Shilimkar
15367cd31eSSantosh Shilimkar#include <linux/linkage.h>
16367cd31eSSantosh Shilimkar#include <linux/init.h>
17448c077eSMatthijs van Duin#include <asm/assembler.h>
18367cd31eSSantosh Shilimkar
19ff999b8aSSantosh Shilimkar#include "omap44xx.h"
20ff999b8aSSantosh Shilimkar
21283f708cSSantosh Shilimkar/* Physical address needed since MMU not enabled yet on secondary core */
22283f708cSSantosh Shilimkar#define AUX_CORE_BOOT0_PA			0x48281800
23999f934dSLennart Sorensen#define API_HYP_ENTRY				0x102
24283f708cSSantosh Shilimkar
2544e7475dSTony LindgrenENTRY(omap_secondary_startup)
2644e7475dSTony Lindgren#ifdef CONFIG_SMP
2744e7475dSTony Lindgren	b	secondary_startup
2844e7475dSTony Lindgren#else
2944e7475dSTony Lindgren/* Should never get here */
3044e7475dSTony Lindgrenagain:	wfi
3144e7475dSTony Lindgren	b	again
3244e7475dSTony Lindgren#endif
3344e7475dSTony Lindgren#ENDPROC(omap_secondary_startup)
3444e7475dSTony Lindgren
35283f708cSSantosh Shilimkar/*
36283f708cSSantosh Shilimkar * OMAP5 specific entry point for secondary CPU to jump from ROM
37283f708cSSantosh Shilimkar * code.  This routine also provides a holding flag into which
38283f708cSSantosh Shilimkar * secondary core is held until we're ready for it to initialise.
39283f708cSSantosh Shilimkar * The primary core will update this flag using a hardware
40da0159fdSJoel Fernandes * register AuxCoreBoot0.
41283f708cSSantosh Shilimkar */
42283f708cSSantosh ShilimkarENTRY(omap5_secondary_startup)
43283f708cSSantosh Shilimkarwait:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
44283f708cSSantosh Shilimkar	ldr	r0, [r2]
45283f708cSSantosh Shilimkar	mov	r0, r0, lsr #5
46283f708cSSantosh Shilimkar	mrc	p15, 0, r4, c0, c0, 5
47283f708cSSantosh Shilimkar	and	r4, r4, #0x0f
48283f708cSSantosh Shilimkar	cmp	r0, r4
49283f708cSSantosh Shilimkar	bne	wait
5044e7475dSTony Lindgren	b	omap_secondary_startup
5155fde31cSJoel FernandesENDPROC(omap5_secondary_startup)
52367cd31eSSantosh Shilimkar/*
53999f934dSLennart Sorensen * Same as omap5_secondary_startup except we call into the ROM to
54999f934dSLennart Sorensen * enable HYP mode first.  This is called instead of
55999f934dSLennart Sorensen * omap5_secondary_startup if the primary CPU was put into HYP mode by
56999f934dSLennart Sorensen * the boot loader.
57999f934dSLennart Sorensen */
58*3fe1ee40SStefan Agner	.arch armv7-a
59*3fe1ee40SStefan Agner	.arch_extension sec
60999f934dSLennart SorensenENTRY(omap5_secondary_hyp_startup)
61999f934dSLennart Sorensenwait_2:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
62999f934dSLennart Sorensen	ldr	r0, [r2]
63999f934dSLennart Sorensen	mov	r0, r0, lsr #5
64999f934dSLennart Sorensen	mrc	p15, 0, r4, c0, c0, 5
65999f934dSLennart Sorensen	and	r4, r4, #0x0f
66999f934dSLennart Sorensen	cmp	r0, r4
67999f934dSLennart Sorensen	bne	wait_2
68999f934dSLennart Sorensen	ldr	r12, =API_HYP_ENTRY
69448c077eSMatthijs van Duin	badr	r0, hyp_boot
70999f934dSLennart Sorensen	smc	#0
71999f934dSLennart Sorensenhyp_boot:
7244e7475dSTony Lindgren	b	omap_secondary_startup
73999f934dSLennart SorensenENDPROC(omap5_secondary_hyp_startup)
74999f934dSLennart Sorensen/*
75367cd31eSSantosh Shilimkar * OMAP4 specific entry point for secondary CPU to jump from ROM
76367cd31eSSantosh Shilimkar * code.  This routine also provides a holding flag into which
77367cd31eSSantosh Shilimkar * secondary core is held until we're ready for it to initialise.
78942e2c9eSSantosh Shilimkar * The primary core will update this flag using a hardware
79942e2c9eSSantosh Shilimkar * register AuxCoreBoot0.
80367cd31eSSantosh Shilimkar */
81baf4b7d3SSantosh ShilimkarENTRY(omap4_secondary_startup)
82942e2c9eSSantosh Shilimkarhold:	ldr	r12,=0x103
83942e2c9eSSantosh Shilimkar	dsb
84df571c4aSRichard Woodruff	smc	#0			@ read from AuxCoreBoot0
85942e2c9eSSantosh Shilimkar	mov	r0, r0, lsr #9
86942e2c9eSSantosh Shilimkar	mrc	p15, 0, r4, c0, c0, 5
87942e2c9eSSantosh Shilimkar	and	r4, r4, #0x0f
88942e2c9eSSantosh Shilimkar	cmp	r0, r4
89367cd31eSSantosh Shilimkar	bne	hold
90367cd31eSSantosh Shilimkar
91367cd31eSSantosh Shilimkar	/*
92942e2c9eSSantosh Shilimkar	 * we've been released from the wait loop,secondary_stack
93367cd31eSSantosh Shilimkar	 * should now contain the SVC stack for this core
94367cd31eSSantosh Shilimkar	 */
9544e7475dSTony Lindgren	b	omap_secondary_startup
96baf4b7d3SSantosh ShilimkarENDPROC(omap4_secondary_startup)
97367cd31eSSantosh Shilimkar
98baf4b7d3SSantosh ShilimkarENTRY(omap4460_secondary_startup)
99ff999b8aSSantosh Shilimkarhold_2:	ldr	r12,=0x103
100ff999b8aSSantosh Shilimkar	dsb
101ff999b8aSSantosh Shilimkar	smc	#0			@ read from AuxCoreBoot0
102ff999b8aSSantosh Shilimkar	mov	r0, r0, lsr #9
103ff999b8aSSantosh Shilimkar	mrc	p15, 0, r4, c0, c0, 5
104ff999b8aSSantosh Shilimkar	and	r4, r4, #0x0f
105ff999b8aSSantosh Shilimkar	cmp	r0, r4
106ff999b8aSSantosh Shilimkar	bne	hold_2
107ff999b8aSSantosh Shilimkar
108ff999b8aSSantosh Shilimkar	/*
109ff999b8aSSantosh Shilimkar	 * GIC distributor control register has changed between
110ff999b8aSSantosh Shilimkar	 * CortexA9 r1pX and r2pX. The Control Register secure
111ff999b8aSSantosh Shilimkar	 * banked version is now composed of 2 bits:
112ff999b8aSSantosh Shilimkar	 * bit 0 == Secure Enable
113ff999b8aSSantosh Shilimkar	 * bit 1 == Non-Secure Enable
114ff999b8aSSantosh Shilimkar	 * The Non-Secure banked register has not changed
115ff999b8aSSantosh Shilimkar	 * Because the ROM Code is based on the r1pX GIC, the CPU1
116ff999b8aSSantosh Shilimkar	 * GIC restoration will cause a problem to CPU0 Non-Secure SW.
117ff999b8aSSantosh Shilimkar	 * The workaround must be:
118ff999b8aSSantosh Shilimkar	 * 1) Before doing the CPU1 wakeup, CPU0 must disable
119ff999b8aSSantosh Shilimkar	 * the GIC distributor
120ff999b8aSSantosh Shilimkar	 * 2) CPU1 must re-enable the GIC distributor on
121ff999b8aSSantosh Shilimkar	 * it's wakeup path.
122ff999b8aSSantosh Shilimkar	 */
123ff999b8aSSantosh Shilimkar	ldr	r1, =OMAP44XX_GIC_DIST_BASE
124ff999b8aSSantosh Shilimkar	ldr	r0, [r1]
125ff999b8aSSantosh Shilimkar	orr	r0, #1
126ff999b8aSSantosh Shilimkar	str	r0, [r1]
127ff999b8aSSantosh Shilimkar
128ff999b8aSSantosh Shilimkar	/*
129ff999b8aSSantosh Shilimkar	 * we've been released from the wait loop,secondary_stack
130ff999b8aSSantosh Shilimkar	 * should now contain the SVC stack for this core
131ff999b8aSSantosh Shilimkar	 */
13244e7475dSTony Lindgren	b	omap_secondary_startup
133baf4b7d3SSantosh ShilimkarENDPROC(omap4460_secondary_startup)
134