* [PATCH v6 1/7] ARM: trusted_foundations: Implement L2 cache initialization callback
2019-02-22 19:34 [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
@ 2019-02-22 19:34 ` Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 2/7] ARM: trusted_foundations: Make prepare_idle call to take mode argument Dmitry Osipenko
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-22 19:34 UTC (permalink / raw)
To: Russell King, Thierry Reding, Jonathan Hunter, Robert Yang,
Michał Mirosław
Cc: linux-tegra, linux-kernel, linux-arm-kernel
Implement L2 cache initialization firmware callback that should be
invoked early during boot in order to set up the required outer cache
driver's callbacks.
Partially based on work done by Michał Mirosław [1].
[1] https://www.spinics.net/lists/arm-kernel/msg594765.html
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.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 2/7] ARM: trusted_foundations: Make prepare_idle call to take mode argument
2019-02-22 19:34 [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 1/7] ARM: trusted_foundations: Implement L2 cache initialization callback Dmitry Osipenko
@ 2019-02-22 19:34 ` Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 3/7] ARM: trusted_foundations: Provide information about whether firmware is registered Dmitry Osipenko
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-22 19:34 UTC (permalink / raw)
To: Russell King, Thierry Reding, Jonathan Hunter, Robert Yang,
Michał Mirosław
Cc: linux-tegra, linux-kernel, linux-arm-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.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 3/7] ARM: trusted_foundations: Provide information about whether firmware is registered
2019-02-22 19:34 [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 1/7] ARM: trusted_foundations: Implement L2 cache initialization callback Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 2/7] ARM: trusted_foundations: Make prepare_idle call to take mode argument Dmitry Osipenko
@ 2019-02-22 19:34 ` Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 4/7] ARM: tegra: Set up L2 cache using Trusted Foundations firmware Dmitry Osipenko
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-22 19:34 UTC (permalink / raw)
To: Russell King, Thierry Reding, Jonathan Hunter, Robert Yang,
Michał Mirosław
Cc: linux-tegra, linux-kernel, linux-arm-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.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 4/7] ARM: tegra: Set up L2 cache using Trusted Foundations firmware
2019-02-22 19:34 [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (2 preceding siblings ...)
2019-02-22 19:34 ` [PATCH v6 3/7] ARM: trusted_foundations: Provide information about whether firmware is registered Dmitry Osipenko
@ 2019-02-22 19:34 ` Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 5/7] ARM: tegra: Don't apply CPU erratas in insecure mode Dmitry Osipenko
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-22 19:34 UTC (permalink / raw)
To: Russell King, Thierry Reding, Jonathan Hunter, Robert Yang,
Michał Mirosław
Cc: linux-tegra, linux-kernel, linux-arm-kernel
On Tegra30 L2 cache should be initialized using firmware call if CPU
is running in insecure mode. Set up the required outer-cache write_sec()
callback early during boot using the firmware API, it is always a NO-OP
on T114+ and is NO-OP on T20/30 if Trusted Foundations firmware node
isn't present in device-tree.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/tegra.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index f9587be48235..1e89cfefbf68 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>
@@ -74,6 +75,7 @@ static void __init tegra_init_early(void)
{
of_register_trusted_foundations();
tegra_cpu_reset_handler_init();
+ call_firmware_op(l2x0_init);
}
static void __init tegra_dt_init_irq(void)
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 5/7] ARM: tegra: Don't apply CPU erratas in insecure mode
2019-02-22 19:34 [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (3 preceding siblings ...)
2019-02-22 19:34 ` [PATCH v6 4/7] ARM: tegra: Set up L2 cache using Trusted Foundations firmware Dmitry Osipenko
@ 2019-02-22 19:34 ` Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 6/7] ARM: tegra: Always boot CPU in ARM-mode Dmitry Osipenko
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-22 19:34 UTC (permalink / raw)
To: Russell King, Thierry Reding, Jonathan Hunter, Robert Yang,
Michał Mirosław
Cc: linux-tegra, linux-kernel, linux-arm-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.
Partially based on work done by Michał Mirosław [1].
[1] https://www.spinics.net/lists/arm-kernel/msg594768.html
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/reset-handler.S | 23 ++++++++++++-----------
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(+), 13 deletions(-)
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 805f306fa6f7..6bea95d165fa 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,13 @@ 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 dedeebfccc55..50d51d3465f6 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
@@ -53,6 +54,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.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 6/7] ARM: tegra: Always boot CPU in ARM-mode
2019-02-22 19:34 [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (4 preceding siblings ...)
2019-02-22 19:34 ` [PATCH v6 5/7] ARM: tegra: Don't apply CPU erratas in insecure mode Dmitry Osipenko
@ 2019-02-22 19:34 ` Dmitry Osipenko
2019-02-22 19:34 ` [PATCH v6 7/7] ARM: tegra: Add firmware calls required for suspend-resume on Tegra30 Dmitry Osipenko
[not found] ` <20190225040232.GA2242@qmqm.qmqm.pl>
7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-22 19:34 UTC (permalink / raw)
To: Russell King, Thierry Reding, Jonathan Hunter, Robert Yang,
Michał Mirosław
Cc: linux-tegra, linux-kernel, linux-arm-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. 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 | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 6bea95d165fa..3bf202819534 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -113,6 +113,7 @@ ENTRY(__tegra_cpu_reset_handler_start)
* must be position-independent.
*/
+ .arm
.align L1_CACHE_SHIFT
ENTRY(__tegra_cpu_reset_handler)
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v6 7/7] ARM: tegra: Add firmware calls required for suspend-resume on Tegra30
2019-02-22 19:34 [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30 Dmitry Osipenko
` (5 preceding siblings ...)
2019-02-22 19:34 ` [PATCH v6 6/7] ARM: tegra: Always boot CPU in ARM-mode Dmitry Osipenko
@ 2019-02-22 19:34 ` Dmitry Osipenko
[not found] ` <20190225040232.GA2242@qmqm.qmqm.pl>
7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-22 19:34 UTC (permalink / raw)
To: Russell King, Thierry Reding, Jonathan Hunter, Robert Yang,
Michał Mirosław
Cc: linux-tegra, linux-kernel, linux-arm-kernel
In order to suspend-resume CPU with Trusted Foundations firmware being
present on Tegra30, the LP1/LP2 boot vectors and CPU caches need to be
set up using the firmware calls and then suspend code shall avoid
re-disabling parts that were disabled by the firmware.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
arch/arm/mach-tegra/pm.c | 49 +++++++++++++++++++++++++++++
arch/arm/mach-tegra/reset-handler.S | 26 +++++++++++++++
arch/arm/mach-tegra/sleep.S | 14 ++++++---
3 files changed, 84 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 1ad5719779b0..f209f59e0daf 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -33,11 +33,13 @@
#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>
#include <asm/suspend.h>
#include <asm/tlbflush.h>
+#include <asm/trusted_foundations.h>
#include "iomap.h"
#include "pm.h"
@@ -159,6 +161,28 @@ int tegra_cpu_do_idle(void)
static int tegra_sleep_cpu(unsigned long v2p)
{
+ /*
+ * L2 cache disabling using kernel API only allowed when all
+ * secondary CPU's are offline. Cache have to be disabled with
+ * MMU-on 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-idle
+ * code-path only for Tegra20/30.
+ */
+ if (trusted_foundations_registered())
+ outer_disable();
+
+ /*
+ * Note that besides of setting up CPU reset vector this firmware
+ * call may also do the following, depending on the FW version:
+ * 1) Disable L2. But this doesn't matter since we already
+ * disabled the L2.
+ * 2) Disable D-cache. This need to be taken into account in
+ * particular by the tegra_disable_clean_inv_dcache() which
+ * shall avoid the re-disable.
+ */
+ call_firmware_op(prepare_idle, TF_PM_MODE_LP2);
+
setup_mm_for_reboot();
tegra_sleep_cpu_finish(v2p);
@@ -197,6 +221,14 @@ void tegra_idle_lp2_last(void)
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. This is always a no-op on Tegra114+.
+ */
+ outer_resume();
+
restore_cpu_complex();
cpu_cluster_pm_exit();
}
@@ -215,6 +247,15 @@ enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
static int tegra_sleep_core(unsigned long v2p)
{
+ /*
+ * Cache have to be disabled with MMU-on if cache maintenance is done
+ * via Trusted Foundations firmware. This is a no-op on Tegra114+.
+ */
+ if (trusted_foundations_registered())
+ outer_disable();
+
+ call_firmware_op(prepare_idle, TF_PM_MODE_LP1);
+
setup_mm_for_reboot();
tegra_sleep_core_finish(v2p);
@@ -342,6 +383,14 @@ static int tegra_suspend_enter(suspend_state_t state)
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 3bf202819534..19a609046547 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>
@@ -76,6 +77,7 @@ ENTRY(tegra_resume)
orr r1, r1, #1
str r1, [r0]
#endif
+ bl tegra_resume_trusted_foundations
#ifdef CONFIG_CACHE_L2X0
/* L2 cache resume & re-enable */
@@ -88,6 +90,30 @@ end_ca9_scu_l2_resume:
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
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index 5e3496753df1..53863d59521b 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -49,8 +49,9 @@ ENTRY(tegra_disable_clean_inv_dcache)
/* Disable the D-cache */
mrc p15, 0, r2, c1, c0, 0
+ tst r2, #CR_C @ see tegra_sleep_cpu()
bic r2, r2, #CR_C
- mcr p15, 0, r2, c1, c0, 0
+ mcrne p15, 0, r2, c1, c0, 0
isb
/* Flush the D-cache */
@@ -132,10 +133,13 @@ ENTRY(tegra_shut_off_mmu)
#ifdef CONFIG_CACHE_L2X0
/* Disable L2 cache */
check_cpu_part_num 0xc09, r9, r10
- movweq r2, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000)
- movteq r2, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000)
- moveq r3, #0
- streq r3, [r2, #L2X0_CTRL]
+ retne r0
+
+ mov32 r2, TEGRA_ARM_PERIF_BASE + 0x3000
+ ldr r3, [r2, #L2X0_CTRL]
+ mov r9, #0
+ tst r3, #1 @ see tegra_sleep_cpu()
+ strne r9, [r2, #L2X0_CTRL]
#endif
ret r0
ENDPROC(tegra_shut_off_mmu)
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 11+ messages in thread
[parent not found: <20190225040232.GA2242@qmqm.qmqm.pl>]
* Re: [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30
[not found] ` <20190225040232.GA2242@qmqm.qmqm.pl>
@ 2019-02-25 5:21 ` Dmitry Osipenko
2019-02-25 16:58 ` Robert Yang
0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-25 5:21 UTC (permalink / raw)
To: Michał Mirosław, Robert Yang
Cc: linux-kernel, Russell King, Thierry Reding, linux-tegra,
Jonathan Hunter, linux-arm-kernel
В Mon, 25 Feb 2019 05:02:33 +0100
Michał Mirosław <mirq-linux@rere.qmqm.pl> пишет:
> On Fri, Feb 22, 2019 at 10:34:19PM +0300, Dmitry Osipenko wrote:
> > Hello,
> >
> > This patchset adds support for the Trusted Foundations firmware on
> > NVIDIA Tegra30. Pretty much all of Tegra30 consumer devices have
> > that firmware and upstream kernel can't boot on those devices
> > without the firmware support.
>
> Hi Dmitry
>
> I've applied and tested this patchset on my TF300T. Boots and
> suspends/wakes using 'rtcwake -m mem -s 1 -d /dev/rtc1' as the test.
> dmesg attached.
>
> The exact tree used:
> git://rere.qmqm.pl/linux tf300t
>
> Feel free to add my Tested-by and Signed-off-by on the patches where
> apropriate, and thanks for your work!
Awesome, thank you very much!
Robert, could you please confirm that v6 works for you too?
I'll probably make a v7 with an extra minor clean up and then will add
all the appropriate tags to the patches.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30
2019-02-25 5:21 ` [PATCH v6 0/7] Support Trusted Foundations firmware " Dmitry Osipenko
@ 2019-02-25 16:58 ` Robert Yang
2019-02-25 17:55 ` Dmitry Osipenko
0 siblings, 1 reply; 11+ messages in thread
From: Robert Yang @ 2019-02-25 16:58 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: linux-kernel, Russell King, Michał Mirosław,
Thierry Reding, linux-tegra, Jonathan Hunter, linux-arm-kernel
On Mon, Feb 25, 2019 at 08:21:55AM +0300, Dmitry Osipenko wrote:
> В Mon, 25 Feb 2019 05:02:33 +0100
> Michał Mirosław <mirq-linux@rere.qmqm.pl> пишет:
>
> > On Fri, Feb 22, 2019 at 10:34:19PM +0300, Dmitry Osipenko wrote:
> > > Hello,
> > >
> > > This patchset adds support for the Trusted Foundations firmware on
> > > NVIDIA Tegra30. Pretty much all of Tegra30 consumer devices have
> > > that firmware and upstream kernel can't boot on those devices
> > > without the firmware support.
> >
> > Hi Dmitry
> >
> > I've applied and tested this patchset on my TF300T. Boots and
> > suspends/wakes using 'rtcwake -m mem -s 1 -d /dev/rtc1' as the test.
> > dmesg attached.
> >
> > The exact tree used:
> > git://rere.qmqm.pl/linux tf300t
> >
> > Feel free to add my Tested-by and Signed-off-by on the patches where
> > apropriate, and thanks for your work!
>
> Awesome, thank you very much!
>
> Robert, could you please confirm that v6 works for you too?
>
Yes, v6 works on Ouya.
LP1/LP2 suspend tested with 'rtcwake -m mem -s 5'
cpuidle LP2 tested with 'echo 0 | tee /sys/devices/system/cpu/cpu[1-3]/online'
Tested with CONFIG_SMP disabled too.
You can add my Tested-by to this patch set.
> I'll probably make a v7 with an extra minor clean up and then will add
> all the appropriate tags to the patches.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v6 0/7] Support Trusted Foundations firmware on Tegra30
2019-02-25 16:58 ` Robert Yang
@ 2019-02-25 17:55 ` Dmitry Osipenko
0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Osipenko @ 2019-02-25 17:55 UTC (permalink / raw)
To: Robert Yang
Cc: linux-kernel, Russell King, Michał Mirosław,
Thierry Reding, linux-tegra, Jonathan Hunter, linux-arm-kernel
25.02.2019 19:58, Robert Yang пишет:
> On Mon, Feb 25, 2019 at 08:21:55AM +0300, Dmitry Osipenko wrote:
>> В Mon, 25 Feb 2019 05:02:33 +0100
>> Michał Mirosław <mirq-linux@rere.qmqm.pl> пишет:
>>
>>> On Fri, Feb 22, 2019 at 10:34:19PM +0300, Dmitry Osipenko wrote:
>>>> Hello,
>>>>
>>>> This patchset adds support for the Trusted Foundations firmware on
>>>> NVIDIA Tegra30. Pretty much all of Tegra30 consumer devices have
>>>> that firmware and upstream kernel can't boot on those devices
>>>> without the firmware support.
>>>
>>> Hi Dmitry
>>>
>>> I've applied and tested this patchset on my TF300T. Boots and
>>> suspends/wakes using 'rtcwake -m mem -s 1 -d /dev/rtc1' as the test.
>>> dmesg attached.
>>>
>>> The exact tree used:
>>> git://rere.qmqm.pl/linux tf300t
>>>
>>> Feel free to add my Tested-by and Signed-off-by on the patches where
>>> apropriate, and thanks for your work!
>>
>> Awesome, thank you very much!
>>
>> Robert, could you please confirm that v6 works for you too?
>>
>
> Yes, v6 works on Ouya.
>
> LP1/LP2 suspend tested with 'rtcwake -m mem -s 5'
> cpuidle LP2 tested with 'echo 0 | tee /sys/devices/system/cpu/cpu[1-3]/online'
> Tested with CONFIG_SMP disabled too.
>
> You can add my Tested-by to this patch set.
Great, thank you!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread