platsmp.c (1877B)
1// SPDX-License-Identifier: GPL-2.0 2// Copyright (c) 2018 Nuvoton Technology corporation. 3// Copyright 2018 Google, Inc. 4 5#define pr_fmt(fmt) "nuvoton,npcm7xx-smp: " fmt 6 7#include <linux/delay.h> 8#include <linux/device.h> 9#include <linux/smp.h> 10#include <linux/io.h> 11#include <linux/of.h> 12#include <linux/of_device.h> 13#include <linux/of_platform.h> 14#include <linux/of_address.h> 15#include <asm/cacheflush.h> 16#include <asm/smp.h> 17#include <asm/smp_plat.h> 18#include <asm/smp_scu.h> 19 20#define NPCM7XX_SCRPAD_REG 0x13c 21 22extern void npcm7xx_secondary_startup(void); 23 24static int npcm7xx_smp_boot_secondary(unsigned int cpu, 25 struct task_struct *idle) 26{ 27 struct device_node *gcr_np; 28 void __iomem *gcr_base; 29 int ret = 0; 30 31 gcr_np = of_find_compatible_node(NULL, NULL, "nuvoton,npcm750-gcr"); 32 if (!gcr_np) { 33 pr_err("no gcr device node\n"); 34 ret = -ENODEV; 35 goto out; 36 } 37 gcr_base = of_iomap(gcr_np, 0); 38 if (!gcr_base) { 39 pr_err("could not iomap gcr"); 40 ret = -ENOMEM; 41 goto out; 42 } 43 44 /* give boot ROM kernel start address. */ 45 iowrite32(__pa_symbol(npcm7xx_secondary_startup), gcr_base + 46 NPCM7XX_SCRPAD_REG); 47 /* make sure the previous write is seen by all observers. */ 48 dsb_sev(); 49 50 iounmap(gcr_base); 51out: 52 return ret; 53} 54 55static void __init npcm7xx_smp_prepare_cpus(unsigned int max_cpus) 56{ 57 struct device_node *scu_np; 58 void __iomem *scu_base; 59 60 scu_np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); 61 if (!scu_np) { 62 pr_err("no scu device node\n"); 63 return; 64 } 65 scu_base = of_iomap(scu_np, 0); 66 if (!scu_base) { 67 pr_err("could not iomap scu"); 68 return; 69 } 70 71 scu_enable(scu_base); 72 73 iounmap(scu_base); 74} 75 76static struct smp_operations npcm7xx_smp_ops __initdata = { 77 .smp_prepare_cpus = npcm7xx_smp_prepare_cpus, 78 .smp_boot_secondary = npcm7xx_smp_boot_secondary, 79}; 80 81CPU_METHOD_OF_DECLARE(npcm7xx_smp, "nuvoton,npcm750-smp", &npcm7xx_smp_ops);