/* * Initialise the CPU possible map early - this describes the CPUs * which may be present or become present in the system. */ static void __init omap4_smp_init_cpus(void) { unsigned int i = 0, ncores = 1, cpu_id; /* Use ARM cpuid check here, as SoC detection will not work so early */ cpu_id = read_cpuid_id() & CPU_MASK; if (cpu_id == CPU_CORTEX_A9) { /* * Currently we can't call ioremap here because * SoC detection won't work until after init_early. */ scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base()); BUG_ON(!scu_base); ncores = scu_get_core_count(scu_base); } else if (cpu_id == CPU_CORTEX_A15) { ncores = OMAP5_CORE_COUNT; } /* sanity check */ if (ncores > nr_cpu_ids) { pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", ncores, nr_cpu_ids); ncores = nr_cpu_ids; } for (i = 0; i < ncores; i++) set_cpu_possible(i, true); }
static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) { /* Always mark the boot CPU (CPU0) as initialized. */ cpumask_set_cpu(0, &tegra_cpu_init_mask); if (scu_a9_has_base()) scu_enable(IO_ADDRESS(scu_a9_get_base())); }
static int __init am43xx_map_scu(void) { scu_base = ioremap(scu_a9_get_base(), SZ_256); if (!scu_base) return -ENOMEM; return 0; }
static void __init hisi_enable_scu_a9(void) { unsigned long base = 0; void __iomem *scu_base = NULL; if (scu_a9_has_base()) { base = scu_a9_get_base(); scu_base = ioremap(base, SZ_4K); if (!scu_base) { pr_err("ioremap(scu_base) failed\n"); return; } scu_enable(scu_base); iounmap(scu_base); } }
/* * Enable the Cortex A9 Snoop Control Unit * * By the time this is called we already know there are multiple * cores present. We assume we're running on a Cortex A9 processor, * so any trouble getting the base address register or getting the * SCU base is a problem. * * Return 0 if successful or an error code otherwise. */ static int __init scu_a9_enable(void) { unsigned long config_base; void __iomem *scu_base; unsigned int i, ncores; if (!scu_a9_has_base()) { pr_err("no configuration base address register!\n"); return -ENXIO; } /* Config base address register value is zero for uniprocessor */ config_base = scu_a9_get_base(); if (!config_base) { pr_err("hardware reports only one core\n"); return -ENOENT; } scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE); if (!scu_base) { pr_err("failed to remap config base (%lu/%u) for SCU\n", config_base, CORTEX_A9_SCU_SIZE); return -ENOMEM; } scu_enable(scu_base); ncores = scu_base ? scu_get_core_count(scu_base) : 1; if (ncores > nr_cpu_ids) { pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", ncores, nr_cpu_ids); ncores = nr_cpu_ids; } /* The BCM63138 SoC has two Cortex-A9 CPUs, CPU0 features a complete * and fully functional VFP unit that can be used, but CPU1 does not. * Since we will not be able to trap kernel-mode NEON to force * migration to CPU0, just do not advertise VFP support at all. * * This will make vfp_init bail out and do not attempt to use VFP at * all, for kernel-mode NEON, we do not want to introduce any * conditionals in hot-paths, so we just restrict the system to UP. */ #ifdef CONFIG_VFP if (ncores > 1) { pr_warn("SMP: secondary CPUs lack VFP unit, disabling VFP\n"); vfp_disable(); #ifdef CONFIG_KERNEL_MODE_NEON WARN(1, "SMP: kernel-mode NEON enabled, restricting to UP\n"); ncores = 1; #endif } #endif for (i = 0; i < ncores; i++) set_cpu_possible(i, true); iounmap(scu_base); /* That's the last we'll need of this */ return 0; }