From a553b7f536de9cf48cee7db410ff6c9108b67344 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 7 Feb 2014 13:35:01 +0900 Subject: ARM: trusted_foundations: fix vendor prefix typos of_register_trusted_foundations() and the firmware Kconfig used the wrong vendor prefix for Trusted Logic Mobility. Signed-off-by: Alexandre Courbot Acked-by: Olof Johansson Signed-off-by: Stephen Warren --- arch/arm/firmware/Kconfig | 2 +- arch/arm/include/asm/trusted_foundations.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/firmware/Kconfig b/arch/arm/firmware/Kconfig index bb00ccf00d66..bb126594995e 100644 --- a/arch/arm/firmware/Kconfig +++ b/arch/arm/firmware/Kconfig @@ -20,7 +20,7 @@ config TRUSTED_FOUNDATIONS This option allows the kernel to invoke the secure monitor whenever required on devices using Trusted Foundations. See arch/arm/include/asm/trusted_foundations.h or the - tl,trusted-foundations device tree binding documentation for details + tlm,trusted-foundations device tree binding documentation for details on how to use it. Say n if you don't know what this is about. diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h index 3bd36e2c5f2e..997862fd5d77 100644 --- a/arch/arm/include/asm/trusted_foundations.h +++ b/arch/arm/include/asm/trusted_foundations.h @@ -59,7 +59,7 @@ static inline void of_register_trusted_foundations(void) * If we find the target should enable TF but does not support it, * fail as the system won't be able to do much anyway */ - if (of_find_compatible_node(NULL, NULL, "tl,trusted-foundations")) + if (of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations")) register_trusted_foundations(NULL); } #endif /* CONFIG_TRUSTED_FOUNDATIONS */ -- cgit From c3af6d68550c50597be25f29bc1cb742c10c63c0 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 7 Feb 2014 13:35:02 +0900 Subject: ARM: trusted_foundations: fallback when TF support is missing When Trusted Foundations is detected as present on the system, but Trusted Foundations support is not built into the kernel, the kernel used to issue a panic very early during boot, leaving little clue to the user as to what is going wrong. It turns out that even without TF support built-in, the kernel can boot on a TF-enabled system provided that SMP and cpuidle are disabled. This patch does this and continue booting on one CPU, leaving the user with a usable (however degraded) system. Signed-off-by: Alexandre Courbot Acked-by: Olof Johansson Signed-off-by: Stephen Warren --- arch/arm/include/asm/trusted_foundations.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h index 997862fd5d77..b5f7705abcb0 100644 --- a/arch/arm/include/asm/trusted_foundations.h +++ b/arch/arm/include/asm/trusted_foundations.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include struct trusted_foundations_platform_data { unsigned int version_major; @@ -47,10 +49,13 @@ static inline void register_trusted_foundations( struct trusted_foundations_platform_data *pd) { /* - * If we try to register TF, this means the system needs it to continue. - * Its absence if thus a fatal error. + * If the system requires TF and we cannot provide it, continue booting + * but disable features that cannot be provided. */ - panic("No support for Trusted Foundations, stopping...\n"); + pr_err("No support for Trusted Foundations, continuing in degraded mode.\n"); + pr_err("Secondary processors as well as CPU PM will be disabled.\n"); + setup_max_cpus = 0; + cpu_idle_poll_ctrl(true); } static inline void of_register_trusted_foundations(void) -- cgit From 5b154f18086f11096567aad55543af4bc44a0aa0 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 7 Feb 2014 13:35:03 +0900 Subject: ARM: firmware: enable Trusted Foundations by default As discussed previously (https://lkml.org/lkml/2013/11/26/289), enable Trusted Foundation support by default since it already depends on a supporting architecture being selected. Signed-off-by: Alexandre Courbot Acked-by: Olof Johansson Signed-off-by: Stephen Warren --- arch/arm/firmware/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/firmware/Kconfig b/arch/arm/firmware/Kconfig index bb126594995e..ad396af68e47 100644 --- a/arch/arm/firmware/Kconfig +++ b/arch/arm/firmware/Kconfig @@ -11,6 +11,7 @@ menu "Firmware options" config TRUSTED_FOUNDATIONS bool "Trusted Foundations secure monitor support" depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS + default y help Some devices (including most Tegra-based consumer devices on the market) are booted with the Trusted Foundations secure monitor -- cgit From cd42145cd993fa1a7426d63648fc7e3423fb2e1d Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 7 Feb 2014 13:35:04 +0900 Subject: ARM: firmware: add prepare_idle() operation Some firmwares do not put the CPU into idle mode themselves, but still need to be informed that the CPU is about to enter idle mode before this happens. Add a prepare_idle() operation to the firmware_ops structure to handle such cases. Signed-off-by: Alexandre Courbot Acked-by: Olof Johansson Signed-off-by: Stephen Warren --- arch/arm/include/asm/firmware.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h index 15631300c238..2c9f10df7568 100644 --- a/arch/arm/include/asm/firmware.h +++ b/arch/arm/include/asm/firmware.h @@ -21,6 +21,10 @@ * A filled up structure can be registered with register_firmware_ops(). */ struct firmware_ops { + /* + * Inform the firmware we intend to enter CPU idle mode + */ + int (*prepare_idle)(void); /* * Enters CPU idle mode */ -- cgit From b77b6e885c592815f272d70749fb8d391038f97a Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 7 Feb 2014 13:35:05 +0900 Subject: ARM: trusted_foundations: implement prepare_idle() Support the prepare_idle() firmware call, which is necessary to properly support CPU idling. Signed-off-by: Alexandre Courbot Acked-by: Olof Johansson Signed-off-by: Stephen Warren --- arch/arm/firmware/trusted_foundations.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c index ef1e3d8f4af0..3fb1b5a1dce9 100644 --- a/arch/arm/firmware/trusted_foundations.c +++ b/arch/arm/firmware/trusted_foundations.c @@ -22,6 +22,15 @@ #define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200 +#define TF_CPU_PM 0xfffffffc +#define TF_CPU_PM_S3 0xffffffe3 +#define TF_CPU_PM_S2 0xffffffe6 +#define TF_CPU_PM_S2_NO_MC_CLK 0xffffffe5 +#define TF_CPU_PM_S1 0xffffffe4 +#define TF_CPU_PM_S1_NOFLUSH_L2 0xffffffe7 + +static unsigned long cpu_boot_addr; + static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2) { asm volatile( @@ -41,13 +50,22 @@ static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2) static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr) { - tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, boot_addr, 0); + cpu_boot_addr = boot_addr; + tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, cpu_boot_addr, 0); + + return 0; +} + +static int tf_prepare_idle(void) +{ + tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2, cpu_boot_addr); return 0; } static const struct firmware_ops trusted_foundations_ops = { .set_cpu_boot_addr = tf_set_cpu_boot_addr, + .prepare_idle = tf_prepare_idle, }; void register_trusted_foundations(struct trusted_foundations_platform_data *pd) -- cgit From 338f2aadca7ed4e30e5937fdebc3ff72fda210b6 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Wed, 12 Feb 2014 11:43:44 +0900 Subject: ARM: tegra: cpuidle: use firmware for power down Attempt to invoke the prepare_idle() and do_idle() firmware calls to power down a CPU so an underlying firmware gets informed of the idle operation and performs it by itself if designed in such a way. Signed-off-by: Alexandre Courbot Acked-by: Olof Johansson Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/cpuidle-tegra114.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c index e0b87300243d..b5fb7c110c64 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ b/arch/arm/mach-tegra/cpuidle-tegra114.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,11 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev, clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); - cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); + call_firmware_op(prepare_idle); + + /* Do suspend by ourselves if the firmware does not implement it */ + if (call_firmware_op(do_idle) == -ENOSYS) + cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); -- cgit