[7/9] ARM: tegra: enable cache via TF

Message ID 6a164b2270a3e996c083e94bf5b1e27028c1135e.1500510157.git.mirq-linux@rere.qmqm.pl
State New
Headers show

Commit Message

Michał Mirosław July 20, 2017, 12:29 a.m.
Cache enable needs to go via firmware call with TF running.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 arch/arm/mach-tegra/reset-handler.S | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

Comments

Dmitry Osipenko Dec. 19, 2017, 7:07 p.m. | #1
On 20.07.2017 03:29, Michał Mirosław wrote:
> Cache enable needs to go via firmware call with TF running.
> 
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---

Perhaps we can unify secure and non-secure modes. The code below works on both
secure-t30 and nonsecure-t20, all CPU's booted and working fine.

The "ARM: enable secure platform-only erratas" patch isn't needed in this case.


diff --git a/arch/arm/mach-tegra/reset-handler.S
b/arch/arm/mach-tegra/reset-handler.S
index 805f306fa6f7..9a92bbf8b5b0 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -80,6 +80,28 @@ ENTRY(tegra_resume)
 #endif

 #ifdef CONFIG_CACHE_L2X0
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+	adr	r3, __tegra_cpu_reset_handler_data
+	ldr	r0, [r3, #RESET_DATA(TF_PRESENT)]
+	cmp	r0, #0
+	beq	ca9_scu_l2_resume
+
+	adr	r3, __tegra_smc_stack
+	stmia	r3, {r4-r12, sp, lr}
+
+	mov	r0, #3	// local wake
+	mov	r3, #0
+	mov	r4, #0
+	dsb
+	.arch_extension	sec
+	smc	#0
+
+	adr	r3, __tegra_smc_stack
+	ldmia	r3, {r4-r12, sp, pc}
+
+	b	end_ca9_scu_l2_resume
+ca9_scu_l2_resume:
+#endif
 	/* L2 cache resume & re-enable */
 	bl	l2c310_early_resume
 #endif
@@ -92,6 +114,16 @@ end_ca9_scu_l2_resume:
 ENDPROC(tegra_resume)
 #endif

+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+	.align L1_CACHE_SHIFT
+	.type __tegra_smc_stack, %object
+__tegra_smc_stack:
+	.rept 11
+	.long 0
+	.endr
+	.size __tegra_smc_stack, . - __tegra_smc_stack
+#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+
 	.align L1_CACHE_SHIFT
 ENTRY(__tegra_cpu_reset_handler_start)

@@ -121,6 +153,12 @@ ENTRY(__tegra_cpu_reset_handler)
 	cpsid	aif, 0x13			@ SVC mode, interrupts disabled

 	tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
+
+	adr	r5, __tegra_cpu_reset_handler_data
+	ldr	r0, [r5, #RESET_DATA(TF_PRESENT)]
+	cmp	r0, #0
+	bne	after_errata
+
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 t20_check:
 	cmp	r6, #TEGRA20
@@ -285,6 +323,10 @@ __tegra_cpu_reset_handler_data:
 	.equ	__tegra20_cpu1_resettable_status_offset, \
 					. - __tegra_cpu_reset_handler_start
 	.byte	0
+	.align	4
+	.globl	__tegra_tf_present
+	.equ	__tegra_tf_present, . - __tegra_cpu_reset_handler_start
+	.long	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..9b6558a69308 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -18,6 +18,7 @@
 #include <linux/cpumask.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/of.h>

 #include <soc/tegra/fuse.h>

@@ -89,6 +90,15 @@ static void __init tegra_cpu_reset_handler_enable(void)

 void __init tegra_cpu_reset_handler_init(void)
 {
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations");
+	if (np) {
+		__tegra_cpu_reset_handler_data[TEGRA_RESET_TF_PRESENT] = true;
+		of_node_put(np);
+	}
+#endif

 #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..0d9ddc022ece 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -25,7 +25,9 @@
 #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

 #ifndef __ASSEMBLY__
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Russell King - ARM Linux Dec. 19, 2017, 11:21 p.m. | #2
On Thu, Jul 20, 2017 at 02:29:25AM +0200, Michał Mirosław wrote:
> diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
> index 805f306fa6f7..aae7f5961563 100644
> --- a/arch/arm/mach-tegra/reset-handler.S
> +++ b/arch/arm/mach-tegra/reset-handler.S
> @@ -78,8 +78,20 @@ ENTRY(tegra_resume)
>  	orr	r1, r1, #1
>  	str	r1, [r0]
>  #endif
> +#ifdef CONFIG_TRUSTED_FOUNDATIONS
> +	adr	r3, __tegra_smc_stack
> +	stmia	r3, {r4-r12, sp, lr}
>  
> -#ifdef CONFIG_CACHE_L2X0
> +	mov	r0, #3	// local wake
> +	mov	r3, #0
> +	mov	r4, #0
> +	dsb
> +	.arch_extension	sec
> +	smc	#0
> +
> +	adr	r3, __tegra_smc_stack
> +	ldmia	r3, {r4-r12, sp, pc}

You don't want to jump to the 'lr' value previously stacked here.  I
also wonder whether you need all this stacking, or whether you're
just doing it because you don't know whether its necessary.  From
what I can see, the only register that this code cares about is r8,
although it would be wise to place a comment in the code if the smc
call corrupts the other registers.

Patch

diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 805f306fa6f7..aae7f5961563 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -78,8 +78,20 @@  ENTRY(tegra_resume)
 	orr	r1, r1, #1
 	str	r1, [r0]
 #endif
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+	adr	r3, __tegra_smc_stack
+	stmia	r3, {r4-r12, sp, lr}
 
-#ifdef CONFIG_CACHE_L2X0
+	mov	r0, #3	// local wake
+	mov	r3, #0
+	mov	r4, #0
+	dsb
+	.arch_extension	sec
+	smc	#0
+
+	adr	r3, __tegra_smc_stack
+	ldmia	r3, {r4-r12, sp, pc}
+#elif defined(CONFIG_CACHE_L2X0)
 	/* L2 cache resume & re-enable */
 	bl	l2c310_early_resume
 #endif
@@ -92,6 +104,16 @@  end_ca9_scu_l2_resume:
 ENDPROC(tegra_resume)
 #endif
 
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+	.align L1_CACHE_SHIFT
+	.type __tegra_smc_stack, %object
+__tegra_smc_stack:
+	.rept 11
+	.long 0
+	.endr
+	.size __tegra_smc_stack, . - __tegra_smc_stack
+#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+
 	.align L1_CACHE_SHIFT
 ENTRY(__tegra_cpu_reset_handler_start)