[coreboot-gerrit] New patch to review for coreboot: 0f47a53 arm64: implement CPU power down sequence as per A57/A53/A72 TRM

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Apr 24 11:12:54 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9980

-gerrit

commit 0f47a53b543ca595c33d45762315c683f1eefe06
Author: Joseph Lo <josephl at nvidia.com>
Date:   Wed Apr 15 10:09:50 2015 +0800

    arm64: implement CPU power down sequence as per A57/A53/A72 TRM
    
    Implement the individual core powerdown sequence as per
    Cortex-A57/A53/A72 TRM.
    
    Based-on-the-work-by:
    Varun Wadekar <vwadekar at nvidia.com>
    
    BRANCH=none
    BUG=none
    TEST=boot on smaug/foster, verify the cpu_on/off is ok as well
    
    Change-Id: I4719fcbe86b35f9b448d274e1732da5fc75346b0
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: b6bdcc12150820dfad28cef3af3d8220847c5d74
    Original-Change-Id: I65abab8cda55cfe7a0c424f3175677ed5e3c2a1c
    Original-Signed-off-by: Joseph Lo <josephl at nvidia.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/265827
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/arch/arm64/cpu-stubs.c              |  6 +++
 src/arch/arm64/cpu/Kconfig              |  5 ++
 src/arch/arm64/cpu/cortex_a57.S         | 95 +++++++++++++++++++++++++++++++++
 src/arch/arm64/cpu/cortex_a57.h         |  6 +++
 src/arch/arm64/include/armv8/arch/cpu.h | 14 +++++
 5 files changed, 126 insertions(+)

diff --git a/src/arch/arm64/cpu-stubs.c b/src/arch/arm64/cpu-stubs.c
index c7b083e..da76759 100644
--- a/src/arch/arm64/cpu-stubs.c
+++ b/src/arch/arm64/cpu-stubs.c
@@ -18,8 +18,14 @@
  */
 
 void arm64_cpu_early_setup(void);
+void cortex_a57_cpu_power_down(int l2_flush);
 
 void __attribute__((weak)) arm64_cpu_early_setup(void)
 {
 	/* Default empty implementation */
 }
+
+void __attribute__((weak)) cortex_a57_cpu_power_down(int l2_flush)
+{
+	/* Default empty implementation */
+}
diff --git a/src/arch/arm64/cpu/Kconfig b/src/arch/arm64/cpu/Kconfig
index fadd48a..20304be 100644
--- a/src/arch/arm64/cpu/Kconfig
+++ b/src/arch/arm64/cpu/Kconfig
@@ -21,3 +21,8 @@ config ARCH_ARM64_CPU_CORTEX_A57
 	bool
 	default n
 	depends on ARCH_ARM64
+
+config ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT
+	bool
+	default n
+	depends on ARCH_ARM64 && ARCH_ARM64_CPU_CORTEX_A57
diff --git a/src/arch/arm64/cpu/cortex_a57.S b/src/arch/arm64/cpu/cortex_a57.S
index 5039d1c..ae05175 100644
--- a/src/arch/arm64/cpu/cortex_a57.S
+++ b/src/arch/arm64/cpu/cortex_a57.S
@@ -18,6 +18,7 @@
  */
 
 #include <arch/asm.h>
+#include <arch/cache_helpers.h>
 #include "cortex_a57.h"
 
 ENTRY(arm64_cpu_early_setup)
@@ -27,3 +28,97 @@ ENTRY(arm64_cpu_early_setup)
 	isb
 	ret
 ENDPROC(arm64_cpu_early_setup)
+
+/*
+ * CPU power down sequence as per A57/A53/A72 TRM
+ *
+ * x0 - L2 flush by HW(0) or SW(1), if system/HW driven L2 flush is supported
+ *
+ */
+#if IS_ENABLED(CONFIG_ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT)
+ENTRY(cortex_a57_cpu_power_down)
+	/* Store L2 cache flush request */
+	mov	x13, x0
+
+	/* 1. Stop allocations to our data cache */
+	mrs	x0, sctlr_el1
+	bic	x0, x0, #1 << 2		// clear SCTLR.C
+	msr	sctlr_el1, x0
+	isb
+
+	mrs	x0, sctlr_el3
+	bic	x0, x0, #1 << 2		// clear SCTLR.C
+	msr	sctlr_el3, x0
+	isb
+
+	mrs	x0, midr_el1
+	ubfx	x0, x0, #4, #12
+	cmp	x0, #CORTEX_A53_PN
+	b.eq	a53
+
+	/* 2. Disable L2 prefetch */
+	mrs	x0, CPUECTLR_EL1	// CPUECTLR_EL1
+	/* CPUECTLR[38], disable table walk descriptor access L2 prefetch */
+	orr	x0, x0, #1 << 38
+	/*
+	 * CPUECTLR[36:35] L2 instruction fetch prefetch distance
+	 * 0 => disable instruction prefetch
+	 */
+	bic	x0, x0, #3 << 35
+	/*
+	 * CPUECTLR[33:32] L2 load/store prefetch distance
+	 * 0 => disable instruction prefetch
+	 */
+	bic	x0, x0, #3 << 32
+	msr	CPUECTLR_EL1, x0
+
+	/* 3. ISB to ensure ectlr write is complete */
+	isb
+
+	/* 4. DSB to ensure prior prefetches are complete */
+	dsb	sy
+
+a53:
+	/* 5. Clean and invalidate L1 and L2 if X13 == 1 */
+	mov	x0, #DCCISW
+	cmp	x13, #1
+	bne	1f
+	bl	flush_dcache_all
+	b	2f
+1:
+	bl	flush_dcache_louis
+2:
+
+	/* 6. Leave coherency, clear SMPEN */
+	mrs	x0, CPUECTLR_EL1
+	bic	x0, x0, #(1 << SMPEN_SHIFT)
+	msr	CPUECTLR_EL1, x0
+
+	/* 7. Set the DBGOSDLR.DLK, Double lock control bit */
+	mrs	x0, osdlr_el1
+	orr	x0, x0, #OSDLR_DBL_LOCK_BIT
+	msr	osdlr_el1, x0
+
+	/*
+	 * 9. Execute an ISB instruction to ensure that all of the
+	 * System register changes from the previous steps have
+	 * been committed.
+	 */
+	isb
+
+	/*
+	 * 10. Execute a DSB instruction to ensure that all
+	 * instruction cache, TLB, and branch predictor
+	 * maintenance operations issued by any processor in the
+	 * multiprocessor before the SMPEN bit was cleared have
+	 * completed.
+	 */
+	dsb	sy
+
+	/* 11. wfi */
+3:	wfi
+
+	/* we never return here */
+	b	3b
+ENDPROC(cortex_a57_cpu_power_down)
+#endif
diff --git a/src/arch/arm64/cpu/cortex_a57.h b/src/arch/arm64/cpu/cortex_a57.h
index 9e66f4d..9e12e8b 100644
--- a/src/arch/arm64/cpu/cortex_a57.h
+++ b/src/arch/arm64/cpu/cortex_a57.h
@@ -23,4 +23,10 @@
 #define CPUECTLR_EL1	S3_1_c15_c2_1
 #define SMPEN_SHIFT	6
 
+/* Cortex MIDR[15:4] PN */
+#define CORTEX_A53_PN	0xd03
+
+/* Double lock control bit */
+#define OSDLR_DBL_LOCK_BIT	1
+
 #endif /* __ARCH_ARM64_CORTEX_A57_H__ */
diff --git a/src/arch/arm64/include/armv8/arch/cpu.h b/src/arch/arm64/include/armv8/arch/cpu.h
index 14635e3..4e15209 100644
--- a/src/arch/arm64/include/armv8/arch/cpu.h
+++ b/src/arch/arm64/include/armv8/arch/cpu.h
@@ -187,4 +187,18 @@ void arm64_cpu_startup_resume(void);
  */
 void arm64_arch_timer_init(void);
 
+/*
+ * The cortex_a57_cpu_power_down sequence as per A57/A53/A72 TRM.
+ * L2 flush by HW(0) or SW(1), if system/HW driven L2 flush is supported.
+ */
+#define NO_L2_FLUSH 0
+#define L2_FLUSH_HW 0
+#define L2_FLUSH_SW 1
+
+#if IS_ENABLED(CONFIG_ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT)
+void cortex_a57_cpu_power_down(int l2_flush);
+#else
+static inline void cortex_a57_cpu_power_down(int l2_flush) {}
+#endif
+
 #endif /* __ARCH_CPU_H__ */



More information about the coreboot-gerrit mailing list