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