Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * arch/arm/mach-mediatek/platsmp.c
0004  *
0005  * Copyright (c) 2014 Mediatek Inc.
0006  * Author: Shunli Wang <shunli.wang@mediatek.com>
0007  *         Yingjoe Chen <yingjoe.chen@mediatek.com>
0008  */
0009 #include <linux/io.h>
0010 #include <linux/memblock.h>
0011 #include <linux/of.h>
0012 #include <linux/of_address.h>
0013 #include <linux/string.h>
0014 #include <linux/threads.h>
0015 
0016 #define MTK_MAX_CPU     8
0017 #define MTK_SMP_REG_SIZE    0x1000
0018 
0019 struct mtk_smp_boot_info {
0020     unsigned long smp_base;
0021     unsigned int jump_reg;
0022     unsigned int core_keys[MTK_MAX_CPU - 1];
0023     unsigned int core_regs[MTK_MAX_CPU - 1];
0024 };
0025 
0026 static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = {
0027     0x80002000, 0x3fc,
0028     { 0x534c4131, 0x4c415332, 0x41534c33 },
0029     { 0x3f8, 0x3f8, 0x3f8 },
0030 };
0031 
0032 static const struct mtk_smp_boot_info mtk_mt6589_boot = {
0033     0x10002000, 0x34,
0034     { 0x534c4131, 0x4c415332, 0x41534c33 },
0035     { 0x38, 0x3c, 0x40 },
0036 };
0037 
0038 static const struct mtk_smp_boot_info mtk_mt7623_boot = {
0039     0x10202000, 0x34,
0040     { 0x534c4131, 0x4c415332, 0x41534c33 },
0041     { 0x38, 0x3c, 0x40 },
0042 };
0043 
0044 static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
0045     { .compatible   = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
0046     { .compatible   = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
0047     { .compatible   = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot },
0048     {},
0049 };
0050 
0051 static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
0052     { .compatible   = "mediatek,mt6589", .data = &mtk_mt6589_boot },
0053     { .compatible   = "mediatek,mt7623", .data = &mtk_mt7623_boot },
0054     { .compatible   = "mediatek,mt7629", .data = &mtk_mt7623_boot },
0055     {},
0056 };
0057 
0058 static void __iomem *mtk_smp_base;
0059 static const struct mtk_smp_boot_info *mtk_smp_info;
0060 
0061 static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
0062 {
0063     if (!mtk_smp_base)
0064         return -EINVAL;
0065 
0066     if (!mtk_smp_info->core_keys[cpu-1])
0067         return -EINVAL;
0068 
0069     writel_relaxed(mtk_smp_info->core_keys[cpu-1],
0070         mtk_smp_base + mtk_smp_info->core_regs[cpu-1]);
0071 
0072     arch_send_wakeup_ipi_mask(cpumask_of(cpu));
0073 
0074     return 0;
0075 }
0076 
0077 static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone)
0078 {
0079     int i, num;
0080     const struct of_device_id *infos;
0081 
0082     if (trustzone) {
0083         num = ARRAY_SIZE(mtk_tz_smp_boot_infos);
0084         infos = mtk_tz_smp_boot_infos;
0085     } else {
0086         num = ARRAY_SIZE(mtk_smp_boot_infos);
0087         infos = mtk_smp_boot_infos;
0088     }
0089 
0090     /* Find smp boot info for this SoC */
0091     for (i = 0; i < num; i++) {
0092         if (of_machine_is_compatible(infos[i].compatible)) {
0093             mtk_smp_info = infos[i].data;
0094             break;
0095         }
0096     }
0097 
0098     if (!mtk_smp_info) {
0099         pr_err("%s: Device is not supported\n", __func__);
0100         return;
0101     }
0102 
0103     if (trustzone) {
0104         /* smp_base(trustzone-bootinfo) is reserved by device tree */
0105         mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base);
0106     } else {
0107         mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE);
0108         if (!mtk_smp_base) {
0109             pr_err("%s: Can't remap %lx\n", __func__,
0110                 mtk_smp_info->smp_base);
0111             return;
0112         }
0113     }
0114 
0115     /*
0116      * write the address of slave startup address into the system-wide
0117      * jump register
0118      */
0119     writel_relaxed(__pa_symbol(secondary_startup_arm),
0120             mtk_smp_base + mtk_smp_info->jump_reg);
0121 }
0122 
0123 static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus)
0124 {
0125     __mtk_smp_prepare_cpus(max_cpus, 1);
0126 }
0127 
0128 static void __init mtk_smp_prepare_cpus(unsigned int max_cpus)
0129 {
0130     __mtk_smp_prepare_cpus(max_cpus, 0);
0131 }
0132 
0133 static const struct smp_operations mt81xx_tz_smp_ops __initconst = {
0134     .smp_prepare_cpus = mtk_tz_smp_prepare_cpus,
0135     .smp_boot_secondary = mtk_boot_secondary,
0136 };
0137 CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops);
0138 
0139 static const struct smp_operations mt6589_smp_ops __initconst = {
0140     .smp_prepare_cpus = mtk_smp_prepare_cpus,
0141     .smp_boot_secondary = mtk_boot_secondary,
0142 };
0143 CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);