summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2013-11-11 15:49:34 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2013-12-03 20:05:13 -0800
commit66c8ea1b606bffd20d6520e958859a76b8be86df (patch)
treef019e61852812d786cf91436b5df57e1d9cf4f1e
parent3f2221cc49a7d8084a78e2b8ae9110d8f9d39fbc (diff)
arm: tegra: use ARM's DEN0028 v0.9 and PSCI specs to define SMCs
Use SIP Service calls (0x82000000x) and Standard Service calls (0x8400000x) from the DEN0028 spec. PSCI says that we need to use 0x8400000x in r0 for any power management features i.e. cpu idle/hotplug/on/off followed by the actual cpu state (LP2/LP1/LP0) in r1. This translates to Std service calls space mentioned in the DEN0028 spec. The SIP service calls can be used by silicon partners for their CPU specific settings. We use this SMC space for L2 settings and to set the CPU reset vector. SMCs that are interrupted return a special status code to the NS world. Look for that status and send a restart SMC (value = 60 << 24) when received. Also removed save/restore of r4-r12 as we rely on the secure OS to do this for us. Change-Id: I6fae83cc96d29c23305177df770fa07f7970c383 Signed-off-by: Scott Long <scottl@nvidia.com> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/329998
-rw-r--r--arch/arm/mach-tegra/common.c4
-rw-r--r--arch/arm/mach-tegra/cpuidle-t11x.c2
-rw-r--r--arch/arm/mach-tegra/pm.c6
-rw-r--r--arch/arm/mach-tegra/reset.c2
-rw-r--r--arch/arm/mach-tegra/sleep.S23
5 files changed, 19 insertions, 18 deletions
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 5347059ac55d..9e81d557b0e3 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -603,9 +603,9 @@ static void tegra_cache_smc(bool enable, u32 arg)
local_irq_save(flags);
l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1;
if (enable && !l2x0_enabled)
- tegra_generic_smc(0xFFFFF100, 0x00000001, arg);
+ tegra_generic_smc(0x82000002, 0x00000001, arg);
else if (!enable && l2x0_enabled)
- tegra_generic_smc(0xFFFFF100, 0x00000002, arg);
+ tegra_generic_smc(0x82000002, 0x00000002, arg);
local_irq_restore(flags);
if (need_affinity_switch && can_switch_affinity) {
diff --git a/arch/arm/mach-tegra/cpuidle-t11x.c b/arch/arm/mach-tegra/cpuidle-t11x.c
index 1b8e639b6ab4..e14595e33643 100644
--- a/arch/arm/mach-tegra/cpuidle-t11x.c
+++ b/arch/arm/mach-tegra/cpuidle-t11x.c
@@ -441,7 +441,7 @@ static bool tegra_cpu_core_power_down(struct cpuidle_device *dev,
#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
if ((cpu == 0) || (cpu == 4)) {
- tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE7,
+ tegra_generic_smc(0x84000001, ((1 << 16) | 5),
(TEGRA_RESET_HANDLER_BASE +
tegra_cpu_reset_handler_offset));
}
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index d077ea22c5a9..91d201fc099e 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -708,12 +708,12 @@ static void tegra_sleep_core(enum tegra_suspend_mode mode,
if (mode == TEGRA_SUSPEND_LP0) {
trace_smc_sleep_core(NVSEC_SMC_START);
- tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE3,
+ tegra_generic_smc(0x84000001, ((1 << 16) | (1 << 24) | 1),
virt_to_phys(tegra_resume));
} else {
trace_smc_sleep_core(NVSEC_SMC_START);
- tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE6,
+ tegra_generic_smc(0x84000001, ((1 << 16) | 2),
(TEGRA_RESET_HANDLER_BASE +
tegra_cpu_reset_handler_offset));
}
@@ -740,7 +740,7 @@ static inline void tegra_stop_mc_clk(unsigned long v2p)
__pa(&tegra_resume_timestamps_end));
trace_smc_sleep_core(NVSEC_SMC_START);
- tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE5,
+ tegra_generic_smc(0x84000001, ((1 << 16) | 3),
(TEGRA_RESET_HANDLER_BASE +
tegra_cpu_reset_handler_offset));
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index e6be374fe60a..fbec87eec053 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -51,7 +51,7 @@ static void tegra_cpu_reset_handler_enable(void)
tegra_cpu_reset_handler_size);
#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL)
- tegra_generic_smc(0xFFFFF200,
+ tegra_generic_smc(0x82000001,
TEGRA_RESET_HANDLER_BASE + tegra_cpu_reset_handler_offset, 0);
#else
/* NOTE: This must be the one and only write to the EVP CPU reset
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index 5e4b1473329f..b4827a16cf05 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -209,8 +209,8 @@ ENDPROC(tegra_flush_l1_cache)
ENTRY(tegra_sleep_cpu_finish)
mov r4, r0
#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL)
- ldr r0, =0xFFFFFFFC
- ldr r1, =0xFFFFFFE4
+ ldr r0, =0x84000001
+ ldr r1, =((1 << 16) | 4)
ldr r2, =TEGRA_RESET_HANDLER_BASE
bl tegra_generic_smc
#else
@@ -350,17 +350,18 @@ ENDPROC(tegra_cpu_pllp)
* the specified parameters.
*/
ENTRY(tegra_generic_smc)
- adr r3, __tegra_smc_stack
- stmia r3, {r4-r12, lr}
mov r3, #0
- mov r4, #0
dsb
smc #0
- adr r3, __tegra_smc_stack
- ldmia r3, {r4-r12, pc}
+restart:
+ ldr r3, =0xFFFFFFFD
+ cmp r0, r3
+ bne done
+ mov r0, #(60 << 24)
+ dsb
+ smc #0
+ b restart
+done:
+ mov pc, lr
ENDPROC(tegra_generic_smc)
- .type __tegra_smc_stack, %object
-__tegra_smc_stack:
- .long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- .size __tegra_smc_stack, . - __tegra_smc_stack
#endif