msm: smp: cold and warm boot support for 4 cpus
Add support for cold and warm booting of the third and fourth cpus in a quad-core processor via scm. Change-Id: Ib83a993e77092f0e4dc75f336fc38efea7a4c76d Signed-off-by: Joel King <joelking@codeaurora.org>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -56,12 +57,14 @@ static void __cpuinit release_secondary(unsigned int cpu)
|
||||
|
||||
/* KraitMP or ScorpionMP ? */
|
||||
if ((read_cpuid_id() & 0xFF0) >> 4 != 0x2D) {
|
||||
base_ptr = ioremap_nocache(0x02098000, SZ_4K);
|
||||
base_ptr = ioremap_nocache(0x02088000 + (cpu * 0x10000), SZ_4K);
|
||||
if (base_ptr) {
|
||||
if (machine_is_msm8960_sim() ||
|
||||
machine_is_msm8960_rumi3()) {
|
||||
writel_relaxed(0x10, base_ptr+0x04);
|
||||
writel_relaxed(0x80, base_ptr+0x04);
|
||||
} else if (machine_is_apq8064_sim()) {
|
||||
writel_relaxed(0xf0000, base_ptr+0x04);
|
||||
} else if (get_core_count() == 2) {
|
||||
writel_relaxed(0x109, base_ptr+0x04);
|
||||
writel_relaxed(0x101, base_ptr+0x04);
|
||||
@@ -95,6 +98,12 @@ static void __cpuinit release_secondary(unsigned int cpu)
|
||||
}
|
||||
|
||||
DEFINE_PER_CPU(int, cold_boot_done);
|
||||
static int cold_boot_flags[] = {
|
||||
0,
|
||||
SCM_FLAG_COLDBOOT_CPU1,
|
||||
SCM_FLAG_COLDBOOT_CPU2,
|
||||
SCM_FLAG_COLDBOOT_CPU3,
|
||||
};
|
||||
|
||||
/* Executed by primary CPU, brings other CPUs out of reset. Called at boot
|
||||
as well as when a CPU is coming out of shutdown induced by echo 0 >
|
||||
@@ -104,16 +113,22 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
int cnt = 0;
|
||||
int ret;
|
||||
int flag = 0;
|
||||
|
||||
pr_debug("Starting secondary CPU %d\n", cpu);
|
||||
|
||||
/* Set preset_lpj to avoid subsequent lpj recalculations */
|
||||
preset_lpj = loops_per_jiffy;
|
||||
|
||||
if (cpu > 0 && cpu < ARRAY_SIZE(cold_boot_flags))
|
||||
flag = cold_boot_flags[cpu];
|
||||
else
|
||||
__WARN();
|
||||
|
||||
if (per_cpu(cold_boot_done, cpu) == false) {
|
||||
ret = scm_set_boot_addr((void *)
|
||||
virt_to_phys(msm_secondary_startup),
|
||||
SCM_FLAG_COLDBOOT_CPU1);
|
||||
flag);
|
||||
if (ret == 0)
|
||||
release_secondary(cpu);
|
||||
else
|
||||
|
||||
@@ -36,6 +36,9 @@ static int __init msm_pm_tz_boot_init(void)
|
||||
flag = SCM_FLAG_WARMBOOT_CPU0;
|
||||
else if (num_possible_cpus() == 2)
|
||||
flag = SCM_FLAG_WARMBOOT_CPU0 | SCM_FLAG_WARMBOOT_CPU1;
|
||||
else if (num_possible_cpus() == 4)
|
||||
flag = SCM_FLAG_WARMBOOT_CPU0 | SCM_FLAG_WARMBOOT_CPU1 |
|
||||
SCM_FLAG_WARMBOOT_CPU2 | SCM_FLAG_WARMBOOT_CPU3;
|
||||
else
|
||||
__WARN();
|
||||
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
#ifndef __MACH_SCM_BOOT_H
|
||||
#define __MACH_SCM_BOOT_H
|
||||
|
||||
#define SCM_BOOT_ADDR 0x1
|
||||
#define SCM_FLAG_COLDBOOT_CPU1 0x1
|
||||
#define SCM_FLAG_WARMBOOT_CPU1 0x2
|
||||
#define SCM_FLAG_WARMBOOT_CPU0 0x4
|
||||
#define SCM_BOOT_ADDR 0x1
|
||||
#define SCM_FLAG_COLDBOOT_CPU1 0x01
|
||||
#define SCM_FLAG_COLDBOOT_CPU2 0x08
|
||||
#define SCM_FLAG_COLDBOOT_CPU3 0x20
|
||||
#define SCM_FLAG_WARMBOOT_CPU1 0x02
|
||||
#define SCM_FLAG_WARMBOOT_CPU0 0x04
|
||||
#define SCM_FLAG_WARMBOOT_CPU2 0x10
|
||||
#define SCM_FLAG_WARMBOOT_CPU3 0x40
|
||||
|
||||
int scm_set_boot_addr(void *addr, int flags);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user