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.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -56,12 +57,14 @@ static void __cpuinit release_secondary(unsigned int cpu)
|
|||||||
|
|
||||||
/* KraitMP or ScorpionMP ? */
|
/* KraitMP or ScorpionMP ? */
|
||||||
if ((read_cpuid_id() & 0xFF0) >> 4 != 0x2D) {
|
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 (base_ptr) {
|
||||||
if (machine_is_msm8960_sim() ||
|
if (machine_is_msm8960_sim() ||
|
||||||
machine_is_msm8960_rumi3()) {
|
machine_is_msm8960_rumi3()) {
|
||||||
writel_relaxed(0x10, base_ptr+0x04);
|
writel_relaxed(0x10, base_ptr+0x04);
|
||||||
writel_relaxed(0x80, 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) {
|
} else if (get_core_count() == 2) {
|
||||||
writel_relaxed(0x109, base_ptr+0x04);
|
writel_relaxed(0x109, base_ptr+0x04);
|
||||||
writel_relaxed(0x101, 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);
|
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
|
/* 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 >
|
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 cnt = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
int flag = 0;
|
||||||
|
|
||||||
pr_debug("Starting secondary CPU %d\n", cpu);
|
pr_debug("Starting secondary CPU %d\n", cpu);
|
||||||
|
|
||||||
/* Set preset_lpj to avoid subsequent lpj recalculations */
|
/* Set preset_lpj to avoid subsequent lpj recalculations */
|
||||||
preset_lpj = loops_per_jiffy;
|
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) {
|
if (per_cpu(cold_boot_done, cpu) == false) {
|
||||||
ret = scm_set_boot_addr((void *)
|
ret = scm_set_boot_addr((void *)
|
||||||
virt_to_phys(msm_secondary_startup),
|
virt_to_phys(msm_secondary_startup),
|
||||||
SCM_FLAG_COLDBOOT_CPU1);
|
flag);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
release_secondary(cpu);
|
release_secondary(cpu);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ static int __init msm_pm_tz_boot_init(void)
|
|||||||
flag = SCM_FLAG_WARMBOOT_CPU0;
|
flag = SCM_FLAG_WARMBOOT_CPU0;
|
||||||
else if (num_possible_cpus() == 2)
|
else if (num_possible_cpus() == 2)
|
||||||
flag = SCM_FLAG_WARMBOOT_CPU0 | SCM_FLAG_WARMBOOT_CPU1;
|
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
|
else
|
||||||
__WARN();
|
__WARN();
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,14 @@
|
|||||||
#ifndef __MACH_SCM_BOOT_H
|
#ifndef __MACH_SCM_BOOT_H
|
||||||
#define __MACH_SCM_BOOT_H
|
#define __MACH_SCM_BOOT_H
|
||||||
|
|
||||||
#define SCM_BOOT_ADDR 0x1
|
#define SCM_BOOT_ADDR 0x1
|
||||||
#define SCM_FLAG_COLDBOOT_CPU1 0x1
|
#define SCM_FLAG_COLDBOOT_CPU1 0x01
|
||||||
#define SCM_FLAG_WARMBOOT_CPU1 0x2
|
#define SCM_FLAG_COLDBOOT_CPU2 0x08
|
||||||
#define SCM_FLAG_WARMBOOT_CPU0 0x4
|
#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);
|
int scm_set_boot_addr(void *addr, int flags);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user