ARM: tegra: Trusted Foundations work for 3.15

This pull request contains a number of cleanups and enhancements for the
 Trusted Foundations firmware used on production Tegra SoCs. The changes
 allow kernels without TF support to run on HW that uses TF, albeit with
 reduced functionality, and also fix the cpuidle feature.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.14 (GNU/Linux)
 
 iQIcBAABAgAGBQJTGilTAAoJEMzrak5tbycx1sYQAJ+G3LcFyATZ90urnAoEUXHA
 vr6EODBGemPheNQ1vqY15M03nAigwIqfchfPYRZ87f6iE5Q1SueOd70/zEKnHYvg
 3gk9dob0/MjqiwBzLzIMNk3OtSm2t0M4niYAUup2QhwVXjEOQD8hgR5K6scU33Fd
 pG98Bh0RhJbIKjms6X+ZMzIZ/gQrtiCFJynf02FgM7rBtGZOBc9sCXytbybIRHUb
 0781i3AXKPE1aR1PRKab1j6rFcVmnkEPNEAc1gLJzJRPXYgruMMEXbQm7uWgn8dB
 bz19rBnhcnexItv/WslUMzhsJ3IVKBS3h9KSV6pnNB+/0MnUyG0A+O9oBslrlsVj
 v0dRQRe0cSRyXC21CWzWhdK1fZFWCu2MilRVNUm/Nh3UZ8n80wvKJNPe0pBvNQSC
 I0Q7x379G03K2/RngHQQgF43B6vxRvGaOKMHxXrJyBLNrYZ74vSszpvLIr0qxh5Z
 NkKKenrJpLIdn6DCLRTqKDbs4fdQgDbX0lDE3iJqNj27/+OZYiEoY7KpQyeDm/HR
 VxqSsOc1HYqbAtpBEYzMFcqWE77wvOuc/PAK1QHiYplU4oI4eGL9UUdmGIe+NnG8
 TAp1p3cHiMF1hBD7bdgHsRCFdz5GcA/59WGgqljayQvt85ktkc/aCxBxu4PIw4nS
 Z71RAeVrPr5J7ZuP1KPU
 =B/hn
 -----END PGP SIGNATURE-----

Merge tag 'tegra-for-3.15-tf' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/soc

Merge "ARM: tegra: Trusted Foundations work for 3.15" from Stephen Warren:

This pull request contains a number of cleanups and enhancements for the
Trusted Foundations firmware used on production Tegra SoCs. The changes
allow kernels without TF support to run on HW that uses TF, albeit with
reduced functionality, and also fix the cpuidle feature.

* tag 'tegra-for-3.15-tf' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  ARM: tegra: cpuidle: use firmware for power down
  ARM: trusted_foundations: implement prepare_idle()
  ARM: firmware: add prepare_idle() operation
  ARM: firmware: enable Trusted Foundations by default
  ARM: trusted_foundations: fallback when TF support is missing
  ARM: trusted_foundations: fix vendor prefix typos

Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson 2014-03-20 14:35:13 -07:00
Родитель 6df5132aee 338f2aadca
Коммит 5d4089a4ad
5 изменённых файлов: 40 добавлений и 7 удалений

Просмотреть файл

@ -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
@ -20,7 +21,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.

Просмотреть файл

@ -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)

Просмотреть файл

@ -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
*/

Просмотреть файл

@ -30,6 +30,8 @@
#include <linux/printk.h>
#include <linux/bug.h>
#include <linux/of.h>
#include <linux/cpu.h>
#include <linux/smp.h>
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)
@ -59,7 +64,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 */

Просмотреть файл

@ -19,6 +19,7 @@
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/clockchips.h>
#include <asm/firmware.h>
#include <asm/cpuidle.h>
#include <asm/suspend.h>
@ -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);