162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * SMP support for R-Mobile / SH-Mobile 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2010 Magnus Damm 662306a36Sopenharmony_ci * Copyright (C) 2010 Takashi Yoshii 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Based on vexpress, Copyright (c) 2003 ARM Limited, All Rights Reserved 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci#include <linux/init.h> 1162306a36Sopenharmony_ci#include <linux/linkage.h> 1262306a36Sopenharmony_ci#include <linux/threads.h> 1362306a36Sopenharmony_ci#include <asm/assembler.h> 1462306a36Sopenharmony_ci#include <asm/page.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define SCTLR_MMU 0x01 1762306a36Sopenharmony_ci#define BOOTROM_ADDRESS 0xE6340000 1862306a36Sopenharmony_ci#define RWTCSRA_ADDRESS 0xE6020004 1962306a36Sopenharmony_ci#define RWTCSRA_WOVF 0x10 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * Reset vector for secondary CPUs. 2362306a36Sopenharmony_ci * This will be mapped at address 0 by SBAR register. 2462306a36Sopenharmony_ci * We need _long_ jump to the physical address. 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci .arm 2762306a36Sopenharmony_ci .align 12 2862306a36Sopenharmony_ciENTRY(shmobile_boot_vector) 2962306a36Sopenharmony_ci ldr r1, 1f 3062306a36Sopenharmony_ci bx r1 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ciENDPROC(shmobile_boot_vector) 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci .align 2 3562306a36Sopenharmony_ci .globl shmobile_boot_fn 3662306a36Sopenharmony_cishmobile_boot_fn: 3762306a36Sopenharmony_ci1: .space 4 3862306a36Sopenharmony_ci .globl shmobile_boot_size 3962306a36Sopenharmony_cishmobile_boot_size: 4062306a36Sopenharmony_ci .long . - shmobile_boot_vector 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#ifdef CONFIG_ARCH_RCAR_GEN2 4362306a36Sopenharmony_ci/* 4462306a36Sopenharmony_ci * Reset vector for R-Car Gen2 and RZ/G1 secondary CPUs. 4562306a36Sopenharmony_ci * This will be mapped at address 0 by SBAR register. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ciENTRY(shmobile_boot_vector_gen2) 4862306a36Sopenharmony_ci mrc p15, 0, r0, c0, c0, 5 @ r0 = MPIDR 4962306a36Sopenharmony_ci ldr r1, shmobile_boot_cpu_gen2 5062306a36Sopenharmony_ci cmp r0, r1 5162306a36Sopenharmony_ci bne shmobile_smp_continue_gen2 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR 5462306a36Sopenharmony_ci and r0, r1, #SCTLR_MMU 5562306a36Sopenharmony_ci cmp r0, #SCTLR_MMU 5662306a36Sopenharmony_ci beq shmobile_smp_continue_gen2 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci ldr r0, rwtcsra 5962306a36Sopenharmony_ci mov r1, #0 6062306a36Sopenharmony_ci ldrb r1, [r0] 6162306a36Sopenharmony_ci and r0, r1, #RWTCSRA_WOVF 6262306a36Sopenharmony_ci cmp r0, #RWTCSRA_WOVF 6362306a36Sopenharmony_ci bne shmobile_smp_continue_gen2 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci ldr r0, bootrom 6662306a36Sopenharmony_ci bx r0 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cishmobile_smp_continue_gen2: 6962306a36Sopenharmony_ci ldr r1, shmobile_boot_fn_gen2 7062306a36Sopenharmony_ci bx r1 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciENDPROC(shmobile_boot_vector_gen2) 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci .align 4 7562306a36Sopenharmony_cirwtcsra: 7662306a36Sopenharmony_ci .word RWTCSRA_ADDRESS 7762306a36Sopenharmony_cibootrom: 7862306a36Sopenharmony_ci .word BOOTROM_ADDRESS 7962306a36Sopenharmony_ci .globl shmobile_boot_cpu_gen2 8062306a36Sopenharmony_cishmobile_boot_cpu_gen2: 8162306a36Sopenharmony_ci .word 0x00000000 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci .align 2 8462306a36Sopenharmony_ci .globl shmobile_boot_fn_gen2 8562306a36Sopenharmony_cishmobile_boot_fn_gen2: 8662306a36Sopenharmony_ci .space 4 8762306a36Sopenharmony_ci .globl shmobile_boot_size_gen2 8862306a36Sopenharmony_cishmobile_boot_size_gen2: 8962306a36Sopenharmony_ci .long . - shmobile_boot_vector_gen2 9062306a36Sopenharmony_ci#endif /* CONFIG_ARCH_RCAR_GEN2 */ 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/* 9362306a36Sopenharmony_ci * Per-CPU SMP boot function/argument selection code based on MPIDR 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ciENTRY(shmobile_smp_boot) 9762306a36Sopenharmony_ci mrc p15, 0, r1, c0, c0, 5 @ r1 = MPIDR 9862306a36Sopenharmony_ci and r0, r1, #0xffffff @ MPIDR_HWID_BITMASK 9962306a36Sopenharmony_ci @ r0 = cpu_logical_map() value 10062306a36Sopenharmony_ci mov r1, #0 @ r1 = CPU index 10162306a36Sopenharmony_ci adr r2, 1f 10262306a36Sopenharmony_ci ldmia r2, {r5, r6, r7} 10362306a36Sopenharmony_ci add r5, r5, r2 @ array of per-cpu mpidr values 10462306a36Sopenharmony_ci add r6, r6, r2 @ array of per-cpu functions 10562306a36Sopenharmony_ci add r7, r7, r2 @ array of per-cpu arguments 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cishmobile_smp_boot_find_mpidr: 10862306a36Sopenharmony_ci ldr r8, [r5, r1, lsl #2] 10962306a36Sopenharmony_ci cmp r8, r0 11062306a36Sopenharmony_ci bne shmobile_smp_boot_next 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci ldr r9, [r6, r1, lsl #2] 11362306a36Sopenharmony_ci cmp r9, #0 11462306a36Sopenharmony_ci bne shmobile_smp_boot_found 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cishmobile_smp_boot_next: 11762306a36Sopenharmony_ci add r1, r1, #1 11862306a36Sopenharmony_ci cmp r1, #NR_CPUS 11962306a36Sopenharmony_ci blo shmobile_smp_boot_find_mpidr 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci b shmobile_smp_sleep 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cishmobile_smp_boot_found: 12462306a36Sopenharmony_ci ldr r0, [r7, r1, lsl #2] 12562306a36Sopenharmony_ci ret r9 12662306a36Sopenharmony_ciENDPROC(shmobile_smp_boot) 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciENTRY(shmobile_smp_sleep) 12962306a36Sopenharmony_ci wfi 13062306a36Sopenharmony_ci b shmobile_smp_boot 13162306a36Sopenharmony_ciENDPROC(shmobile_smp_sleep) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci .align 2 13462306a36Sopenharmony_ci1: .long shmobile_smp_mpidr - . 13562306a36Sopenharmony_ci .long shmobile_smp_fn - 1b 13662306a36Sopenharmony_ci .long shmobile_smp_arg - 1b 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci .bss 13962306a36Sopenharmony_ci .globl shmobile_smp_mpidr 14062306a36Sopenharmony_cishmobile_smp_mpidr: 14162306a36Sopenharmony_ci .space NR_CPUS * 4 14262306a36Sopenharmony_ci .globl shmobile_smp_fn 14362306a36Sopenharmony_cishmobile_smp_fn: 14462306a36Sopenharmony_ci .space NR_CPUS * 4 14562306a36Sopenharmony_ci .globl shmobile_smp_arg 14662306a36Sopenharmony_cishmobile_smp_arg: 14762306a36Sopenharmony_ci .space NR_CPUS * 4 148