1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * SMP support for R-Mobile / SH-Mobile - r8a7779 portion 4 * 5 * Copyright (C) 2011 Renesas Solutions Corp. 6 * Copyright (C) 2011 Magnus Damm 7 */ 8 #include <linux/kernel.h> 9 #include <linux/init.h> 10 #include <linux/smp.h> 11 #include <linux/spinlock.h> 12 #include <linux/io.h> 13 #include <linux/delay.h> 14 #include <linux/soc/renesas/rcar-sysc.h> 15 16 #include <asm/cacheflush.h> 17 #include <asm/smp_plat.h> 18 #include <asm/smp_scu.h> 19 20 #include "common.h" 21 #include "r8a7779.h" 22 23 #define HPBREG_BASE 0xfe700000 24 #define AVECR 0x0040 /* ARM Reset Vector Address Register */ 25 26 #define R8A7779_SCU_BASE 0xf0000000 27 28 static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) 29 { 30 int ret = -EIO; 31 32 cpu = cpu_logical_map(cpu); 33 if (cpu) 34 ret = rcar_sysc_power_up_cpu(cpu); 35 36 return ret; 37 } 38 39 static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) 40 { 41 void __iomem *base; 42 43 if (!request_mem_region(0, SZ_4K, "Boot Area")) { 44 pr_err("Failed to request boot area\n"); 45 return; 46 } 47 48 base = ioremap(HPBREG_BASE, 0x1000); 49 50 /* Map the reset vector (in headsmp-scu.S, headsmp.S) */ 51 writel(__pa(shmobile_boot_vector), base + AVECR); 52 53 /* setup r8a7779 specific SCU bits */ 54 shmobile_smp_scu_prepare_cpus(R8A7779_SCU_BASE, max_cpus); 55 56 iounmap(base); 57 } 58 59 #ifdef CONFIG_HOTPLUG_CPU 60 static int r8a7779_platform_cpu_kill(unsigned int cpu) 61 { 62 int ret = -EIO; 63 64 cpu = cpu_logical_map(cpu); 65 if (cpu) 66 ret = rcar_sysc_power_down_cpu(cpu); 67 68 return ret ? ret : 1; 69 } 70 71 static int r8a7779_cpu_kill(unsigned int cpu) 72 { 73 if (shmobile_smp_scu_cpu_kill(cpu)) 74 return r8a7779_platform_cpu_kill(cpu); 75 76 return 0; 77 } 78 #endif /* CONFIG_HOTPLUG_CPU */ 79 80 const struct smp_operations r8a7779_smp_ops __initconst = { 81 .smp_prepare_cpus = r8a7779_smp_prepare_cpus, 82 .smp_boot_secondary = r8a7779_boot_secondary, 83 #ifdef CONFIG_HOTPLUG_CPU 84 .cpu_die = shmobile_smp_scu_cpu_die, 85 .cpu_kill = r8a7779_cpu_kill, 86 #endif 87 }; 88