diff options
author | Olof Johansson <olof@lixom.net> | 2013-12-26 11:00:13 -0800 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-12-26 11:01:11 -0800 |
commit | 51b052b0d31666e64cb97d3c620c0baff4792d91 (patch) | |
tree | ccdc40870bcc30d703ec891904d1bfd1f3e53c30 /arch/arm/mach-tegra | |
parent | 4ac63adc4f29f92a019b54eb02425357cf6c2967 (diff) | |
parent | f47d41acfd65919c669921674444caa471723c87 (diff) | |
download | linux-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/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/reset.c | 40 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra.c | 2 |
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(); |