Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 // Copyright (C) ASPEED Technology Inc.
0003 // Copyright IBM Corp.
0004 
0005 #include <linux/of_address.h>
0006 #include <linux/io.h>
0007 #include <linux/of.h>
0008 #include <linux/smp.h>
0009 
0010 #define BOOT_ADDR   0x00
0011 #define BOOT_SIG    0x04
0012 
0013 static struct device_node *secboot_node;
0014 
0015 static int aspeed_g6_boot_secondary(unsigned int cpu, struct task_struct *idle)
0016 {
0017     void __iomem *base;
0018 
0019     base = of_iomap(secboot_node, 0);
0020     if (!base) {
0021         pr_err("could not map the secondary boot base!");
0022         return -ENODEV;
0023     }
0024 
0025     writel_relaxed(0, base + BOOT_ADDR);
0026     writel_relaxed(__pa_symbol(secondary_startup_arm), base + BOOT_ADDR);
0027     writel_relaxed((0xABBAAB00 | (cpu & 0xff)), base + BOOT_SIG);
0028 
0029     dsb_sev();
0030 
0031     iounmap(base);
0032 
0033     return 0;
0034 }
0035 
0036 static void __init aspeed_g6_smp_prepare_cpus(unsigned int max_cpus)
0037 {
0038     void __iomem *base;
0039 
0040     secboot_node = of_find_compatible_node(NULL, NULL, "aspeed,ast2600-smpmem");
0041     if (!secboot_node) {
0042         pr_err("secboot device node found!!\n");
0043         return;
0044     }
0045 
0046     base = of_iomap(secboot_node, 0);
0047     if (!base) {
0048         pr_err("could not map the secondary boot base!");
0049         return;
0050     }
0051     __raw_writel(0xBADABABA, base + BOOT_SIG);
0052 
0053     iounmap(base);
0054 }
0055 
0056 static const struct smp_operations aspeed_smp_ops __initconst = {
0057     .smp_prepare_cpus   = aspeed_g6_smp_prepare_cpus,
0058     .smp_boot_secondary = aspeed_g6_boot_secondary,
0059 };
0060 
0061 CPU_METHOD_OF_DECLARE(aspeed_smp, "aspeed,ast2600-smp", &aspeed_smp_ops);