* [PATCH v3 1/8] ARM: trusted_foundations: Implement L2 cache initialization callback
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 2/8] ARM: trusted_foundations: Make prepare_idle call to take mode argument Dmitry Osipenko
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
Implement L2 cache initialization firmware callback that should be invoked
early in boot in order to setup the required outer cache driver callbacks.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/firmware/trusted_foundations.c | 46 +++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
index 689e6565abfc..3bf61a5933b9 100644
--- a/arch/arm/firmware/trusted_foundations.c
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -18,8 +18,15 @@
#include <linux/init.h>
#include <linux/of.h>
#include <asm/firmware.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/outercache.h>
#include <asm/trusted_foundations.h>
+#define TF_CACHE_MAINT 0xfffff100
+
+#define TF_CACHE_ENABLE 1
+#define TF_CACHE_DISABLE 2
+
#define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
#define TF_CPU_PM 0xfffffffc
@@ -67,9 +74,48 @@ static int tf_prepare_idle(void)
return 0;
}
+#ifdef CONFIG_CACHE_L2X0
+static void tf_cache_write_sec(unsigned long val, unsigned int reg)
+{
+ static u32 l2x0_way_mask = 0xff;
+ static u32 l2x0_aux_ctrl = 0;
+
+ switch (reg) {
+ case L2X0_AUX_CTRL:
+ l2x0_aux_ctrl = val;
+
+ if (l2x0_aux_ctrl & BIT(16))
+ l2x0_way_mask = 0xffff;
+ break;
+
+ case L2X0_CTRL:
+ if (val == L2X0_CTRL_EN)
+ tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_ENABLE,
+ l2x0_aux_ctrl);
+ else
+ tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_DISABLE,
+ l2x0_way_mask);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int tf_init_cache(void)
+{
+ outer_cache.write_sec = tf_cache_write_sec;
+
+ return 0;
+}
+#endif /* CONFIG_CACHE_L2X0 */
+
static const struct firmware_ops trusted_foundations_ops = {
.set_cpu_boot_addr = tf_set_cpu_boot_addr,
.prepare_idle = tf_prepare_idle,
+#ifdef CONFIG_CACHE_L2X0
+ .l2x0_init = tf_init_cache,
+#endif
};
void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 2/8] ARM: trusted_foundations: Make prepare_idle call to take mode argument
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 1/8] ARM: trusted_foundations: Implement L2 cache initialization callback Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 3/8] ARM: trusted_foundations: Provide information about whether firmware is registered Dmitry Osipenko
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
The Trusted Foundations firmware call varies depending on the required
suspend-mode. Make the firmware API to take the mode argument in order
to expose all of the modes to firmware user.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/firmware/trusted_foundations.c | 29 ++++++++++++++++++++--
arch/arm/include/asm/firmware.h | 2 +-
arch/arm/include/asm/trusted_foundations.h | 6 +++++
arch/arm/mach-tegra/cpuidle-tegra114.c | 3 ++-
4 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
index 3bf61a5933b9..c496f4cc49cb 100644
--- a/arch/arm/firmware/trusted_foundations.c
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -67,9 +67,34 @@ static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
return 0;
}
-static int tf_prepare_idle(void)
+static int tf_prepare_idle(unsigned long mode)
{
- tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2, cpu_boot_addr);
+ switch (mode) {
+ case TF_PM_MODE_LP0:
+ tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S3, cpu_boot_addr);
+ break;
+
+ case TF_PM_MODE_LP1:
+ tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S2, cpu_boot_addr);
+ break;
+
+ case TF_PM_MODE_LP1_NO_MC_CLK:
+ tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S2_NO_MC_CLK,
+ cpu_boot_addr);
+ break;
+
+ case TF_PM_MODE_LP2:
+ tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1, cpu_boot_addr);
+ break;
+
+ case TF_PM_MODE_LP2_NOFLUSH_L2:
+ tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2,
+ cpu_boot_addr);
+ break;
+
+ default:
+ return -EINVAL;
+ }
return 0;
}
diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h
index 34c1d96ef46d..6698272bbcbf 100644
--- a/arch/arm/include/asm/firmware.h
+++ b/arch/arm/include/asm/firmware.h
@@ -24,7 +24,7 @@ struct firmware_ops {
/*
* Inform the firmware we intend to enter CPU idle mode
*/
- int (*prepare_idle)(void);
+ int (*prepare_idle)(unsigned long mode);
/*
* Enters CPU idle mode
*/
diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h
index 00748350cf72..cdd48ab7d191 100644
--- a/arch/arm/include/asm/trusted_foundations.h
+++ b/arch/arm/include/asm/trusted_foundations.h
@@ -32,6 +32,12 @@
#include <linux/cpu.h>
#include <linux/smp.h>
+#define TF_PM_MODE_LP0 0
+#define TF_PM_MODE_LP1 1
+#define TF_PM_MODE_LP1_NO_MC_CLK 2
+#define TF_PM_MODE_LP2 3
+#define TF_PM_MODE_LP2_NOFLUSH_L2 4
+
struct trusted_foundations_platform_data {
unsigned int version_major;
unsigned int version_minor;
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index e3fbcfedf845..3b9af4766cdf 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -24,6 +24,7 @@
#include <asm/cpuidle.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>
+#include <asm/trusted_foundations.h>
#include <asm/psci.h>
#include "cpuidle.h"
@@ -46,7 +47,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
tegra_set_cpu_in_lp2();
cpu_pm_enter();
- call_firmware_op(prepare_idle);
+ call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
/* Do suspend by ourselves if the firmware does not implement it */
if (call_firmware_op(do_idle, 0) == -ENOSYS)
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 3/8] ARM: trusted_foundations: Provide information about whether firmware is registered
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 1/8] ARM: trusted_foundations: Implement L2 cache initialization callback Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 2/8] ARM: trusted_foundations: Make prepare_idle call to take mode argument Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 4/8] ARM: tegra: Setup L2 cache using Trusted Foundations firmware Dmitry Osipenko
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
Add a helper that provides information about whether Trusted Foundations
firmware operations have been registered.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/firmware/trusted_foundations.c | 5 +++++
arch/arm/include/asm/trusted_foundations.h | 7 +++++++
2 files changed, 12 insertions(+)
diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
index c496f4cc49cb..d795ed83a3cd 100644
--- a/arch/arm/firmware/trusted_foundations.c
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -172,3 +172,8 @@ void of_register_trusted_foundations(void)
panic("Trusted Foundation: missing version-minor property\n");
register_trusted_foundations(&pdata);
}
+
+bool trusted_foundations_registered(void)
+{
+ return firmware_ops == &trusted_foundations_ops;
+}
diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h
index cdd48ab7d191..3f23fa493db6 100644
--- a/arch/arm/include/asm/trusted_foundations.h
+++ b/arch/arm/include/asm/trusted_foundations.h
@@ -31,6 +31,7 @@
#include <linux/of.h>
#include <linux/cpu.h>
#include <linux/smp.h>
+#include <linux/types.h>
#define TF_PM_MODE_LP0 0
#define TF_PM_MODE_LP1 1
@@ -47,6 +48,7 @@ struct trusted_foundations_platform_data {
void register_trusted_foundations(struct trusted_foundations_platform_data *pd);
void of_register_trusted_foundations(void);
+bool trusted_foundations_registered(void);
#else /* CONFIG_TRUSTED_FOUNDATIONS */
@@ -74,6 +76,11 @@ static inline void of_register_trusted_foundations(void)
if (of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations"))
register_trusted_foundations(NULL);
}
+
+static inline bool trusted_foundations_registered(void)
+{
+ return false;
+}
#endif /* CONFIG_TRUSTED_FOUNDATIONS */
#endif
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 4/8] ARM: tegra: Setup L2 cache using Trusted Foundations firmware
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (2 preceding siblings ...)
2018-08-30 18:04 ` [PATCH v3 3/8] ARM: trusted_foundations: Provide information about whether firmware is registered Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 5/8] ARM: tegra: Don't apply CPU erratas in insecure mode Dmitry Osipenko
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
On Tegra30 L2 cache should be initialized using firmware call if CPU is
running in insecure mode. Initialize L2 cache and setup the outer-cache
callbacks in early boot using the firmware API.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/tegra.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index f9587be48235..67d8ae60ac67 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -38,6 +38,7 @@
#include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h>
+#include <asm/firmware.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
@@ -70,9 +71,18 @@ u32 tegra_uart_config[3] = {
0,
};
+static void __init tegra_trusted_foundations_l2x0_cache_init(void)
+{
+ if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
+ IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) &&
+ of_machine_is_compatible("nvidia,tegra30"))
+ call_firmware_op(l2x0_init);
+}
+
static void __init tegra_init_early(void)
{
of_register_trusted_foundations();
+ tegra_trusted_foundations_l2x0_cache_init();
tegra_cpu_reset_handler_init();
}
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 5/8] ARM: tegra: Don't apply CPU erratas in insecure mode
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (3 preceding siblings ...)
2018-08-30 18:04 ` [PATCH v3 4/8] ARM: tegra: Setup L2 cache using Trusted Foundations firmware Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 6/8] ARM: tegra: Always boot CPU in ARM-mode Dmitry Osipenko
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
CPU isn't allowed to touch secure registers while running under secure
monitor. Hence skip applying of CPU erratas in the reset handler if
Trusted Foundations firmware presents.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/reset-handler.S | 24 ++++++++++++------------
arch/arm/mach-tegra/reset.c | 3 +++
arch/arm/mach-tegra/reset.h | 9 +++++++--
arch/arm/mach-tegra/sleep-tegra20.S | 4 ++++
4 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 805f306fa6f7..a9f13230da2f 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -29,8 +29,6 @@
#define PMC_SCRATCH41 0x140
-#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
-
#ifdef CONFIG_PM_SLEEP
/*
* tegra_resume
@@ -121,6 +119,12 @@ ENTRY(__tegra_cpu_reset_handler)
cpsid aif, 0x13 @ SVC mode, interrupts disabled
tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
+
+ adr r12, __tegra_cpu_reset_handler_data
+ ldr r5, [r12, #RESET_DATA(TF_PRESENT)]
+ cmp r5, #0
+ bne after_errata
+
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
t20_check:
cmp r6, #TEGRA20
@@ -155,7 +159,6 @@ after_errata:
and r10, r10, #0x3 @ R10 = CPU number
mov r11, #1
mov r11, r11, lsl r10 @ R11 = CPU mask
- adr r12, __tegra_cpu_reset_handler_data
#ifdef CONFIG_SMP
/* Does the OS know about this CPU? */
@@ -169,10 +172,9 @@ after_errata:
cmp r6, #TEGRA20
bne 1f
/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
- mov32 r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
mov r0, #CPU_NOT_RESETTABLE
cmp r10, #0
- strneb r0, [r5, #__tegra20_cpu1_resettable_status_offset]
+ strneb r0, [r12, #RESET_DATA(RESETTABLE_STATUS)]
1:
#endif
@@ -277,14 +279,12 @@ ENDPROC(__tegra_cpu_reset_handler)
.align L1_CACHE_SHIFT
.type __tegra_cpu_reset_handler_data, %object
.globl __tegra_cpu_reset_handler_data
+ .globl __tegra_cpu_reset_handler_data_offset
+ .equ __tegra_cpu_reset_handler_data_offset, \
+ . - __tegra_cpu_reset_handler_start
__tegra_cpu_reset_handler_data:
- .rept TEGRA_RESET_DATA_SIZE
- .long 0
+ .rept TEGRA_RESET_DATA_SIZE
+ .long 0
.endr
- .globl __tegra20_cpu1_resettable_status_offset
- .equ __tegra20_cpu1_resettable_status_offset, \
- . - __tegra_cpu_reset_handler_start
- .byte 0
.align L1_CACHE_SHIFT
-
ENTRY(__tegra_cpu_reset_handler_end)
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index dc558892753c..b02ae7699842 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -24,6 +24,7 @@
#include <asm/cacheflush.h>
#include <asm/firmware.h>
#include <asm/hardware/cache-l2x0.h>
+#include <asm/trusted_foundations.h>
#include "iomap.h"
#include "irammap.h"
@@ -89,6 +90,8 @@ static void __init tegra_cpu_reset_handler_enable(void)
void __init tegra_cpu_reset_handler_init(void)
{
+ __tegra_cpu_reset_handler_data[TEGRA_RESET_TF_PRESENT] =
+ trusted_foundations_registered();
#ifdef CONFIG_SMP
__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
index 9c479c7925b8..db0e6b3097ab 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -25,7 +25,11 @@
#define TEGRA_RESET_STARTUP_SECONDARY 3
#define TEGRA_RESET_STARTUP_LP2 4
#define TEGRA_RESET_STARTUP_LP1 5
-#define TEGRA_RESET_DATA_SIZE 6
+#define TEGRA_RESET_RESETTABLE_STATUS 6
+#define TEGRA_RESET_TF_PRESENT 7
+#define TEGRA_RESET_DATA_SIZE 8
+
+#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
#ifndef __ASSEMBLY__
@@ -49,7 +53,8 @@ void __tegra_cpu_reset_handler_end(void);
(u32)__tegra_cpu_reset_handler_start)))
#define tegra20_cpu1_resettable_status \
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
- (u32)__tegra20_cpu1_resettable_status_offset))
+ ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_RESETTABLE_STATUS] - \
+ (u32)__tegra_cpu_reset_handler_start)))
#endif
#define tegra_cpu_reset_handler_offset \
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index 5c8e638ee51a..11f423e4a263 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -28,6 +28,7 @@
#include <asm/cache.h>
#include "irammap.h"
+#include "reset.h"
#include "sleep.h"
#define EMC_CFG 0xc
@@ -54,6 +55,9 @@
#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
+#define __tegra20_cpu1_resettable_status_offset \
+ (__tegra_cpu_reset_handler_data_offset + RESET_DATA(RESETTABLE_STATUS))
+
.macro pll_enable, rd, r_car_base, pll_base
ldr \rd, [\r_car_base, #\pll_base]
tst \rd, #(1 << 30)
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 6/8] ARM: tegra: Always boot CPU in ARM-mode
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (4 preceding siblings ...)
2018-08-30 18:04 ` [PATCH v3 5/8] ARM: tegra: Don't apply CPU erratas in insecure mode Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 7/8] ARM: tegra: Support L2 cache maintenance done via firmware Dmitry Osipenko
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
CPU always jumps into reset handler in ARM-mode from the Trusted
Foundations firmware, hence let's make CPU to always jump into kernel
in ARM-mode regardless of the firmware presence to support. This is
required to make Thumb-2 kernel working with the Trusted Foundations
firmware on Tegra30.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/reset-handler.S | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index a9f13230da2f..555c652f5a07 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -20,6 +20,7 @@
#include <soc/tegra/flowctrl.h>
#include <soc/tegra/fuse.h>
+#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/cache.h>
@@ -112,10 +113,20 @@ ENTRY(__tegra_cpu_reset_handler_start)
* NOTE: This code is copied to IRAM. All code and data accesses
* must be position-independent.
*/
-
+ .arm
.align L1_CACHE_SHIFT
ENTRY(__tegra_cpu_reset_handler)
+ /*
+ * Tegra30 ignores first bit of the reset vector and always jumps
+ * into kernel in .ARM mode from the firmware, hence force the mode
+ * switch if kernel is compiled in Thumb-2.
+ */
+ THUMB( badr r0, 1f )
+ THUMB( bx r0 )
+ THUMB( .thumb )
+ THUMB( 1: )
+
cpsid aif, 0x13 @ SVC mode, interrupts disabled
tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
@@ -215,7 +226,7 @@ __no_cpu0_chk:
ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
cmp lr, #0
bleq __die @ no secondary startup handler
- bx lr
+ ret lr
#endif
/*
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 7/8] ARM: tegra: Support L2 cache maintenance done via firmware
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (5 preceding siblings ...)
2018-08-30 18:04 ` [PATCH v3 6/8] ARM: tegra: Always boot CPU in ARM-mode Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-08-30 18:04 ` [PATCH v3 8/8] ARM: tegra: Add firmware calls required for suspend-resume Dmitry Osipenko
2018-10-15 12:34 ` [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
Trusted Foundations firmware require MMU to be enabled for L2 cache
maintenance on Tegra30, hence perform the maintenance early-late on
suspend-resume respectively.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/pm.c | 36 +++++++++++++++++++++++++++++
arch/arm/mach-tegra/reset-handler.S | 8 ++-----
arch/arm/mach-tegra/sleep.S | 4 ++++
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 1ad5719779b0..66c8cd63dd86 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -38,6 +38,7 @@
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <asm/tlbflush.h>
+#include <asm/trusted_foundations.h>
#include "iomap.h"
#include "pm.h"
@@ -195,8 +196,27 @@ void tegra_idle_lp2_last(void)
cpu_cluster_pm_enter();
suspend_cpu_complex();
+ /*
+ * L2 cache disabling using kernel API only allowed when all
+ * secondary CPU's are offline. Cache have to be disabled early
+ * if cache maintenance is done via Trusted Foundations firmware.
+ * Note that CPUIDLE won't ever enter powergate on Tegra30 if any
+ * of secondary CPU's is online and this is the LP2 codepath only
+ * for Tegra20/30.
+ */
+ if (trusted_foundations_registered())
+ outer_disable();
+
cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
+ /*
+ * Resume L2 cache if it wasn't re-enabled early during resume,
+ * which is the case for Tegra30 that has to re-enable the cache
+ * via firmware call. In other cases cache is already enabled and
+ * hence re-enabling is a no-op.
+ */
+ outer_resume();
+
restore_cpu_complex();
cpu_cluster_pm_exit();
}
@@ -340,8 +360,24 @@ static int tegra_suspend_enter(suspend_state_t state)
break;
}
+ /*
+ * Cache have to be disabled early if cache maintenance is done
+ * via Trusted Foundations firmware. Otherwise this is a no-op,
+ * like on Tegra114+.
+ */
+ if (trusted_foundations_registered())
+ outer_disable();
+
cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, tegra_sleep_func);
+ /*
+ * Resume L2 cache if it wasn't re-enabled early during resume,
+ * which is the case for Tegra30 that has to re-enable the cache
+ * via firmware call. In other cases cache is already enabled and
+ * hence re-enabling is a no-op.
+ */
+ outer_resume();
+
switch (mode) {
case TEGRA_SUSPEND_LP1:
tegra_suspend_exit_lp1();
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 555c652f5a07..4973ea053bd7 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -69,7 +69,7 @@ ENTRY(tegra_resume)
mov32 r9, 0xc09
cmp r8, r9
- bne end_ca9_scu_l2_resume
+ bne end_ca9_scu_resume
#ifdef CONFIG_HAVE_ARM_SCU
/* enable SCU */
mov32 r0, TEGRA_ARM_PERIF_BASE
@@ -78,11 +78,7 @@ ENTRY(tegra_resume)
str r1, [r0]
#endif
-#ifdef CONFIG_CACHE_L2X0
- /* L2 cache resume & re-enable */
- bl l2c310_early_resume
-#endif
-end_ca9_scu_l2_resume:
+end_ca9_scu_resume:
mov32 r9, 0xc0f
cmp r8, r9
bleq tegra_init_l2_for_a15
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index 5e3496753df1..b96126fe5dc5 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -132,8 +132,12 @@ ENTRY(tegra_shut_off_mmu)
#ifdef CONFIG_CACHE_L2X0
/* Disable L2 cache */
check_cpu_part_num 0xc09, r9, r10
+ retne r0
+
movweq r2, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000)
movteq r2, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000)
+ ldr r3, [r2, #L2X0_CTRL]
+ cmp r3, #1
moveq r3, #0
streq r3, [r2, #L2X0_CTRL]
#endif
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 8/8] ARM: tegra: Add firmware calls required for suspend-resume
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (6 preceding siblings ...)
2018-08-30 18:04 ` [PATCH v3 7/8] ARM: tegra: Support L2 cache maintenance done via firmware Dmitry Osipenko
@ 2018-08-30 18:04 ` Dmitry Osipenko
2018-10-15 12:34 ` [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-08-30 18:04 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
In order to resume CPU from suspend via trusted Foundations firmware,
the LP1/LP2 boot vectors shall be specified using the firmware calls.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/pm.c | 7 ++++++
arch/arm/mach-tegra/reset-handler.S | 33 +++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 66c8cd63dd86..12341ffabb99 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -33,6 +33,7 @@
#include <soc/tegra/pmc.h>
#include <asm/cacheflush.h>
+#include <asm/firmware.h>
#include <asm/idmap.h>
#include <asm/proc-fns.h>
#include <asm/smp_plat.h>
@@ -150,6 +151,10 @@ bool tegra_set_cpu_in_lp2(void)
tegra20_cpu_set_resettable_soon();
spin_unlock(&tegra_lp2_lock);
+
+ if (last_cpu)
+ call_firmware_op(prepare_idle, TF_PM_MODE_LP2);
+
return last_cpu;
}
@@ -316,6 +321,8 @@ static void tegra_suspend_enter_lp1(void)
tegra_lp1_iram.start_addr, iram_save_size);
*((u32 *)tegra_cpu_lp1_mask) = 1;
+
+ call_firmware_op(prepare_idle, TF_PM_MODE_LP1);
}
static void tegra_suspend_exit_lp1(void)
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 4973ea053bd7..0e208b2e246e 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -69,7 +69,7 @@ ENTRY(tegra_resume)
mov32 r9, 0xc09
cmp r8, r9
- bne end_ca9_scu_resume
+ bne end_ca9_scu_l2_resume
#ifdef CONFIG_HAVE_ARM_SCU
/* enable SCU */
mov32 r0, TEGRA_ARM_PERIF_BASE
@@ -77,14 +77,43 @@ ENTRY(tegra_resume)
orr r1, r1, #1
str r1, [r0]
#endif
+ bl tegra_resume_trusted_foundations
-end_ca9_scu_resume:
+#ifdef CONFIG_CACHE_L2X0
+ /* L2 cache resume & re-enable */
+ bleq l2c310_early_resume @ No, resume cache early
+#endif
+end_ca9_scu_l2_resume:
mov32 r9, 0xc0f
cmp r8, r9
bleq tegra_init_l2_for_a15
b cpu_resume
ENDPROC(tegra_resume)
+
+/*
+ * tegra_resume_trusted_foundations
+ *
+ * Trusted Foundations firmware initialization.
+ *
+ * Doesn't return if firmware presents.
+ * Corrupted registers: r1, r2
+ */
+ENTRY(tegra_resume_trusted_foundations)
+ /* Check whether Trusted Foundations firmware presents. */
+ mov32 r2, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
+ ldr r1, =__tegra_cpu_reset_handler_data_offset + \
+ RESET_DATA(TF_PRESENT)
+ ldr r1, [r2, r1]
+ cmp r1, #0
+ reteq lr
+
+ .arch_extension sec
+ /* First call after suspend wakes firmware. No arguments required. */
+ smc #0
+
+ b cpu_resume
+ENDPROC(tegra_resume_trusted_foundations)
#endif
.align L1_CACHE_SHIFT
--
2.18.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30
2018-08-30 18:04 [PATCH v3 0/8] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (7 preceding siblings ...)
2018-08-30 18:04 ` [PATCH v3 8/8] ARM: tegra: Add firmware calls required for suspend-resume Dmitry Osipenko
@ 2018-10-15 12:34 ` Dmitry Osipenko
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Osipenko @ 2018-10-15 12:34 UTC (permalink / raw)
To: Thierry Reding, Jonathan Hunter, Russell King
Cc: linux-arm-kernel, linux-tegra, linux-kernel
On 8/30/18 9:04 PM, Dmitry Osipenko wrote:
> Hello,
>
> All consumer-grade Tegra30 devices, like Nexus 7 tablet; Ouya console and
> others, use Trusted Foundations firmware that doesn't allow CPU to access
> secure registers directly from the Linux kernel, these accesses shall be
> done via the firmware calls. This patch-series adds a full-featured support
> of the Trusted Foundations firmware that opens the door for supporting of
> various Tegra30-based devices in the upstream Linux kernel.
>
> Changelog:
>
> v3: - Implemented suspend-resume support.
>
> - Reworked arm/firmware/trusted_foundations.c a tad. Now cache
> is getting properly initialized, cache enabling / disabling is
> supported.
>
> v2:
> - The "Don't apply CPU erratas in insecure mode" patch got some
> cleanup, in particular resolved the messiness in
> __tegra_cpu_reset_handler_data.
>
> - Added a comment to tf_cache_write_sec(), justifying the warning
> message.
>
> Dmitry Osipenko (8):
> ARM: trusted_foundations: Implement L2 cache initialization callback
> ARM: trusted_foundations: Make prepare_idle call to take mode argument
> ARM: trusted_foundations: Provide information about whether firmware
> is registered
> ARM: tegra: Setup L2 cache using Trusted Foundations firmware
> ARM: tegra: Don't apply CPU erratas in insecure mode
> ARM: tegra: Always boot CPU in ARM-mode
> ARM: tegra: Support L2 cache maintenance done via firmware
> ARM: tegra: Add firmware calls required for suspend-resume
>
> arch/arm/firmware/trusted_foundations.c | 80 +++++++++++++++++++++-
> arch/arm/include/asm/firmware.h | 2 +-
> arch/arm/include/asm/trusted_foundations.h | 13 ++++
> arch/arm/mach-tegra/cpuidle-tegra114.c | 3 +-
> arch/arm/mach-tegra/pm.c | 43 ++++++++++++
> arch/arm/mach-tegra/reset-handler.S | 66 ++++++++++++++----
> arch/arm/mach-tegra/reset.c | 3 +
> arch/arm/mach-tegra/reset.h | 9 ++-
> arch/arm/mach-tegra/sleep-tegra20.S | 4 ++
> arch/arm/mach-tegra/sleep.S | 4 ++
> arch/arm/mach-tegra/tegra.c | 10 +++
> 11 files changed, 216 insertions(+), 21 deletions(-)
>
ping
^ permalink raw reply [flat|nested] 10+ messages in thread