summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-12-26 11:00:13 -0800
committerOlof Johansson <olof@lixom.net>2013-12-26 11:01:11 -0800
commit51b052b0d31666e64cb97d3c620c0baff4792d91 (patch)
treeccdc40870bcc30d703ec891904d1bfd1f3e53c30 /arch/arm/mach-tegra
parent4ac63adc4f29f92a019b54eb02425357cf6c2967 (diff)
parentf47d41acfd65919c669921674444caa471723c87 (diff)
downloadlinux-51b052b0d31666e64cb97d3c620c0baff4792d91.tar.gz
linux-51b052b0d31666e64cb97d3c620c0baff4792d91.tar.bz2
linux-51b052b0d31666e64cb97d3c620c0baff4792d91.zip
Merge tag 'tegra-for-3.14-trusted-foundations' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers
From Stephen Warren: ARM: tegra: Trusted Foundations firmware support Add support for the Trusted Foundations secure-mode firmware, as found on NVIDIA SHIELD. This allows Linux to run in non-secure mode on this board; all previous Tegra support has assumed the kernel is running in secure mode. (The base TF support has been discussed back and forth a lot; for now the most logical place for it seems to be under arch/arm, so we're adding it here. We can move it out to a common location in the future if needed). * tag 'tegra-for-3.14-trusted-foundations' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: ARM: tegra: support Trusted Foundations by default ARM: tegra: set CPU reset handler using firmware ARM: tegra: split setting of CPU reset handler ARM: tegra: add support for Trusted Foundations of: add Trusted Foundations bindings documentation of: add vendor prefix for Trusted Logic Mobility ARM: add basic support for Trusted Foundations Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/Kconfig1
-rw-r--r--arch/arm/mach-tegra/reset.c40
-rw-r--r--arch/arm/mach-tegra/tegra.c2
3 files changed, 32 insertions, 11 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 09e740f58b27..00b85fd9285d 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -2,6 +2,7 @@ config ARCH_TEGRA
bool "NVIDIA Tegra" if ARCH_MULTI_V7
select ARCH_HAS_CPUFREQ
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
select ARM_GIC
select CLKSRC_MMIO
select CLKSRC_OF
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 568f5bbf979d..146fe8e0ae7c 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -21,6 +21,7 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
+#include <asm/firmware.h>
#include "iomap.h"
#include "irammap.h"
@@ -33,26 +34,18 @@
static bool is_enabled;
-static void __init tegra_cpu_reset_handler_enable(void)
+static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
{
- void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
void __iomem *evp_cpu_reset =
IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
u32 reg;
- BUG_ON(is_enabled);
- BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
-
- memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
- tegra_cpu_reset_handler_size);
-
/*
* NOTE: This must be the one and only write to the EVP CPU reset
* vector in the entire system.
*/
- writel(TEGRA_IRAM_RESET_BASE + tegra_cpu_reset_handler_offset,
- evp_cpu_reset);
+ writel(reset_address, evp_cpu_reset);
wmb();
reg = readl(evp_cpu_reset);
@@ -66,8 +59,33 @@ static void __init tegra_cpu_reset_handler_enable(void)
writel(reg, sb_ctrl);
wmb();
}
+}
+
+static void __init tegra_cpu_reset_handler_enable(void)
+{
+ void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
+ const u32 reset_address = TEGRA_IRAM_RESET_BASE +
+ tegra_cpu_reset_handler_offset;
+ int err;
+
+ BUG_ON(is_enabled);
+ BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
- is_enabled = true;
+ memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
+ tegra_cpu_reset_handler_size);
+
+ err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
+ switch (err) {
+ case -ENOSYS:
+ tegra_cpu_reset_handler_set(reset_address);
+ /* pass-through */
+ case 0:
+ is_enabled = true;
+ break;
+ default:
+ pr_crit("Cannot set CPU reset handler: %d\n", err);
+ BUG();
+ }
}
void __init tegra_cpu_reset_handler_init(void)
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 73368176c6e8..09a1f8d98ca2 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -40,6 +40,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/setup.h>
+#include <asm/trusted_foundations.h>
#include "apbio.h"
#include "board.h"
@@ -90,6 +91,7 @@ static void __init tegra_init_cache(void)
static void __init tegra_init_early(void)
{
+ of_register_trusted_foundations();
tegra_apb_io_init();
tegra_init_fuse();
tegra_cpu_reset_handler_init();