xref: /OK3568_Linux_fs/kernel/arch/arm/mach-omap2/omap-headsmp.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun/*
3*4882a593Smuzhiyun * Secondary CPU startup routine source file.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2009-2014 Texas Instruments, Inc.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Author:
8*4882a593Smuzhiyun *      Santosh Shilimkar <santosh.shilimkar@ti.com>
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Interface functions needed for the SMP. This file is based on arm
11*4882a593Smuzhiyun * realview smp platform.
12*4882a593Smuzhiyun * Copyright (c) 2003 ARM Limited.
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun#include <linux/linkage.h>
16*4882a593Smuzhiyun#include <linux/init.h>
17*4882a593Smuzhiyun#include <asm/assembler.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun#include "omap44xx.h"
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun/* Physical address needed since MMU not enabled yet on secondary core */
22*4882a593Smuzhiyun#define AUX_CORE_BOOT0_PA			0x48281800
23*4882a593Smuzhiyun#define API_HYP_ENTRY				0x102
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunENTRY(omap_secondary_startup)
26*4882a593Smuzhiyun#ifdef CONFIG_SMP
27*4882a593Smuzhiyun	b	secondary_startup
28*4882a593Smuzhiyun#else
29*4882a593Smuzhiyun/* Should never get here */
30*4882a593Smuzhiyunagain:	wfi
31*4882a593Smuzhiyun	b	again
32*4882a593Smuzhiyun#endif
33*4882a593Smuzhiyun#ENDPROC(omap_secondary_startup)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun/*
36*4882a593Smuzhiyun * OMAP5 specific entry point for secondary CPU to jump from ROM
37*4882a593Smuzhiyun * code.  This routine also provides a holding flag into which
38*4882a593Smuzhiyun * secondary core is held until we're ready for it to initialise.
39*4882a593Smuzhiyun * The primary core will update this flag using a hardware
40*4882a593Smuzhiyun * register AuxCoreBoot0.
41*4882a593Smuzhiyun */
42*4882a593SmuzhiyunENTRY(omap5_secondary_startup)
43*4882a593Smuzhiyunwait:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
44*4882a593Smuzhiyun	ldr	r0, [r2]
45*4882a593Smuzhiyun	mov	r0, r0, lsr #5
46*4882a593Smuzhiyun	mrc	p15, 0, r4, c0, c0, 5
47*4882a593Smuzhiyun	and	r4, r4, #0x0f
48*4882a593Smuzhiyun	cmp	r0, r4
49*4882a593Smuzhiyun	bne	wait
50*4882a593Smuzhiyun	b	omap_secondary_startup
51*4882a593SmuzhiyunENDPROC(omap5_secondary_startup)
52*4882a593Smuzhiyun/*
53*4882a593Smuzhiyun * Same as omap5_secondary_startup except we call into the ROM to
54*4882a593Smuzhiyun * enable HYP mode first.  This is called instead of
55*4882a593Smuzhiyun * omap5_secondary_startup if the primary CPU was put into HYP mode by
56*4882a593Smuzhiyun * the boot loader.
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun	.arch armv7-a
59*4882a593Smuzhiyun	.arch_extension sec
60*4882a593SmuzhiyunENTRY(omap5_secondary_hyp_startup)
61*4882a593Smuzhiyunwait_2:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
62*4882a593Smuzhiyun	ldr	r0, [r2]
63*4882a593Smuzhiyun	mov	r0, r0, lsr #5
64*4882a593Smuzhiyun	mrc	p15, 0, r4, c0, c0, 5
65*4882a593Smuzhiyun	and	r4, r4, #0x0f
66*4882a593Smuzhiyun	cmp	r0, r4
67*4882a593Smuzhiyun	bne	wait_2
68*4882a593Smuzhiyun	ldr	r12, =API_HYP_ENTRY
69*4882a593Smuzhiyun	badr	r0, hyp_boot
70*4882a593Smuzhiyun	smc	#0
71*4882a593Smuzhiyunhyp_boot:
72*4882a593Smuzhiyun	b	omap_secondary_startup
73*4882a593SmuzhiyunENDPROC(omap5_secondary_hyp_startup)
74*4882a593Smuzhiyun/*
75*4882a593Smuzhiyun * OMAP4 specific entry point for secondary CPU to jump from ROM
76*4882a593Smuzhiyun * code.  This routine also provides a holding flag into which
77*4882a593Smuzhiyun * secondary core is held until we're ready for it to initialise.
78*4882a593Smuzhiyun * The primary core will update this flag using a hardware
79*4882a593Smuzhiyun * register AuxCoreBoot0.
80*4882a593Smuzhiyun */
81*4882a593SmuzhiyunENTRY(omap4_secondary_startup)
82*4882a593Smuzhiyunhold:	ldr	r12,=0x103
83*4882a593Smuzhiyun	dsb
84*4882a593Smuzhiyun	smc	#0			@ read from AuxCoreBoot0
85*4882a593Smuzhiyun	mov	r0, r0, lsr #9
86*4882a593Smuzhiyun	mrc	p15, 0, r4, c0, c0, 5
87*4882a593Smuzhiyun	and	r4, r4, #0x0f
88*4882a593Smuzhiyun	cmp	r0, r4
89*4882a593Smuzhiyun	bne	hold
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun	/*
92*4882a593Smuzhiyun	 * we've been released from the wait loop,secondary_stack
93*4882a593Smuzhiyun	 * should now contain the SVC stack for this core
94*4882a593Smuzhiyun	 */
95*4882a593Smuzhiyun	b	omap_secondary_startup
96*4882a593SmuzhiyunENDPROC(omap4_secondary_startup)
97*4882a593Smuzhiyun
98*4882a593SmuzhiyunENTRY(omap4460_secondary_startup)
99*4882a593Smuzhiyunhold_2:	ldr	r12,=0x103
100*4882a593Smuzhiyun	dsb
101*4882a593Smuzhiyun	smc	#0			@ read from AuxCoreBoot0
102*4882a593Smuzhiyun	mov	r0, r0, lsr #9
103*4882a593Smuzhiyun	mrc	p15, 0, r4, c0, c0, 5
104*4882a593Smuzhiyun	and	r4, r4, #0x0f
105*4882a593Smuzhiyun	cmp	r0, r4
106*4882a593Smuzhiyun	bne	hold_2
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun	/*
109*4882a593Smuzhiyun	 * GIC distributor control register has changed between
110*4882a593Smuzhiyun	 * CortexA9 r1pX and r2pX. The Control Register secure
111*4882a593Smuzhiyun	 * banked version is now composed of 2 bits:
112*4882a593Smuzhiyun	 * bit 0 == Secure Enable
113*4882a593Smuzhiyun	 * bit 1 == Non-Secure Enable
114*4882a593Smuzhiyun	 * The Non-Secure banked register has not changed
115*4882a593Smuzhiyun	 * Because the ROM Code is based on the r1pX GIC, the CPU1
116*4882a593Smuzhiyun	 * GIC restoration will cause a problem to CPU0 Non-Secure SW.
117*4882a593Smuzhiyun	 * The workaround must be:
118*4882a593Smuzhiyun	 * 1) Before doing the CPU1 wakeup, CPU0 must disable
119*4882a593Smuzhiyun	 * the GIC distributor
120*4882a593Smuzhiyun	 * 2) CPU1 must re-enable the GIC distributor on
121*4882a593Smuzhiyun	 * it's wakeup path.
122*4882a593Smuzhiyun	 */
123*4882a593Smuzhiyun	ldr	r1, =OMAP44XX_GIC_DIST_BASE
124*4882a593Smuzhiyun	ldr	r0, [r1]
125*4882a593Smuzhiyun	orr	r0, #1
126*4882a593Smuzhiyun	str	r0, [r1]
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun	/*
129*4882a593Smuzhiyun	 * we've been released from the wait loop,secondary_stack
130*4882a593Smuzhiyun	 * should now contain the SVC stack for this core
131*4882a593Smuzhiyun	 */
132*4882a593Smuzhiyun	b	omap_secondary_startup
133*4882a593SmuzhiyunENDPROC(omap4460_secondary_startup)
134