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