xref: /linux/arch/arm/mach-mmp/platsmp.c (revision c95baf12f5077419db01313ab61c2aac007d40cd)
1*d093bc03SLubomir Rintel // SPDX-License-Identifier: GPL-2.0-or-later
2*d093bc03SLubomir Rintel /*
3*d093bc03SLubomir Rintel  * Copyright (C) 2019 Lubomir Rintel <lkundrak@v3.sk>
4*d093bc03SLubomir Rintel  */
5*d093bc03SLubomir Rintel #include <linux/io.h>
6*d093bc03SLubomir Rintel #include <asm/smp_scu.h>
7*d093bc03SLubomir Rintel #include <asm/smp.h>
8*d093bc03SLubomir Rintel #include "addr-map.h"
9*d093bc03SLubomir Rintel 
10*d093bc03SLubomir Rintel #define SW_BRANCH_VIRT_ADDR	CIU_REG(0x24)
11*d093bc03SLubomir Rintel 
mmp3_boot_secondary(unsigned int cpu,struct task_struct * idle)12*d093bc03SLubomir Rintel static int mmp3_boot_secondary(unsigned int cpu, struct task_struct *idle)
13*d093bc03SLubomir Rintel {
14*d093bc03SLubomir Rintel 	/*
15*d093bc03SLubomir Rintel 	 * Apparently, the boot ROM on the second core spins on this
16*d093bc03SLubomir Rintel 	 * register becoming non-zero and then jumps to the address written
17*d093bc03SLubomir Rintel 	 * there. No IPIs involved.
18*d093bc03SLubomir Rintel 	 */
19*d093bc03SLubomir Rintel 	__raw_writel(__pa_symbol(secondary_startup), SW_BRANCH_VIRT_ADDR);
20*d093bc03SLubomir Rintel 	return 0;
21*d093bc03SLubomir Rintel }
22*d093bc03SLubomir Rintel 
mmp3_smp_prepare_cpus(unsigned int max_cpus)23*d093bc03SLubomir Rintel static void mmp3_smp_prepare_cpus(unsigned int max_cpus)
24*d093bc03SLubomir Rintel {
25*d093bc03SLubomir Rintel 	scu_enable(SCU_VIRT_BASE);
26*d093bc03SLubomir Rintel }
27*d093bc03SLubomir Rintel 
28*d093bc03SLubomir Rintel static const struct smp_operations mmp3_smp_ops __initconst = {
29*d093bc03SLubomir Rintel 	.smp_prepare_cpus	= mmp3_smp_prepare_cpus,
30*d093bc03SLubomir Rintel 	.smp_boot_secondary	= mmp3_boot_secondary,
31*d093bc03SLubomir Rintel };
32*d093bc03SLubomir Rintel CPU_METHOD_OF_DECLARE(mmp3_smp, "marvell,mmp3-smp", &mmp3_smp_ops);
33