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