Merge pull request #435 from sandrine-bailleux/sb/juno-r2
Changes to platform reset handler for Juno r2
diff --git a/include/lib/cpus/aarch64/cortex_a72.h b/include/lib/cpus/aarch64/cortex_a72.h
index bb32f9b..fa10ca9 100644
--- a/include/lib/cpus/aarch64/cortex_a72.h
+++ b/include/lib/cpus/aarch64/cortex_a72.h
@@ -62,6 +62,7 @@
#define L2CTLR_TAG_RAM_LATENCY_SHIFT 6
#define L2_DATA_RAM_LATENCY_3_CYCLES 0x2
+#define L2_TAG_RAM_LATENCY_2_CYCLES 0x1
#define L2_TAG_RAM_LATENCY_3_CYCLES 0x2
#endif /* __CORTEX_A72_H__ */
diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S
index 263a980..1931535 100644
--- a/plat/arm/board/juno/aarch64/juno_helpers.S
+++ b/plat/arm/board/juno/aarch64/juno_helpers.S
@@ -31,7 +31,9 @@
#include <arch.h>
#include <asm_macros.S>
#include <bl_common.h>
+#include <cortex_a53.h>
#include <cortex_a57.h>
+#include <cortex_a72.h>
#include <v2m_def.h>
#include "../juno_def.h"
@@ -39,52 +41,99 @@
.globl plat_reset_handler
.globl plat_arm_calc_core_pos
+#define JUNO_REVISION(rev) REV_JUNO_R##rev
+#define JUNO_HANDLER(rev) plat_reset_handler_juno_r##rev
+#define JUMP_TO_HANDLER_IF_JUNO_R(revision) \
+ jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision)
+
/* --------------------------------------------------------------------
- * void plat_reset_handler(void);
+ * Helper macro to jump to the given handler if the board revision
+ * matches.
+ * Expects the Juno board revision in x0.
+ * --------------------------------------------------------------------
+ */
+ .macro jump_to_handler _revision, _handler
+ cmp x0, #\_revision
+ b.eq \_handler
+ .endm
+
+ /* --------------------------------------------------------------------
+ * Helper macro that reads the part number of the current CPU and jumps
+ * to the given label if it matches the CPU MIDR provided.
+ *
+ * Clobbers x0.
+ * --------------------------------------------------------------------
+ */
+ .macro jump_if_cpu_midr _cpu_midr, _label
+ mrs x0, midr_el1
+ ubfx x0, x0, MIDR_PN_SHIFT, #12
+ cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+ b.eq \_label
+ .endm
+
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R0.
+ *
+ * Juno R0 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
*
- * For Juno r0:
+ * This handler does the following:
* - Implement workaround for defect id 831273 by enabling an event
* stream every 65536 cycles.
* - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
* - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
- *
- * For Juno r1:
- * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
- * Note that:
- * - The default value for the L2 Tag RAM latency for Cortex-A57 is
- * suitable.
- * - Defect #831273 doesn't affect Juno r1.
* --------------------------------------------------------------------
*/
-func plat_reset_handler
+func JUNO_HANDLER(0)
/* --------------------------------------------------------------------
- * Determine whether this code is running on Juno r0 or Juno r1.
- * Keep this information in x2.
+ * Enable the event stream every 65536 cycles
* --------------------------------------------------------------------
*/
- /* Read the V2M SYS_ID register */
- mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID)
- ldr w1, [x0]
- /* Extract board revision from the SYS_ID */
- ubfx x1, x1, #V2M_SYS_ID_REV_SHIFT, #4
- /*
- * On Juno R0: x2 := REV_JUNO_R0 - 1 = 0
- * On Juno R1: x2 := REV_JUNO_R1 - 1 = 1
+ mov x0, #(0xf << EVNTI_SHIFT)
+ orr x0, x0, #EVNTEN_BIT
+ msr CNTKCTL_EL1, x0
+
+ /* --------------------------------------------------------------------
+ * Nothing else to do on Cortex-A53.
+ * --------------------------------------------------------------------
*/
- sub x2, x1, #1
+ jump_if_cpu_midr CORTEX_A53_MIDR, 1f
/* --------------------------------------------------------------------
- * Determine whether this code is executed on a Cortex-A53 or on a
- * Cortex-A57 core.
+ * Cortex-A57 specific settings
* --------------------------------------------------------------------
*/
- mrs x0, midr_el1
- ubfx x1, x0, MIDR_PN_SHIFT, #12
- cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
- b.eq A57
+ mov x0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (L2_TAG_RAM_LATENCY_3_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ msr L2CTLR_EL1, x0
+1:
+ isb
+ ret
+endfunc JUNO_HANDLER(0)
- /* Nothing needs to be done for the Cortex-A53 on Juno r1 */
- cbz x2, apply_831273
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R1.
+ *
+ * Juno R1 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A57 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+ *
+ * Note that:
+ * - The default value for the L2 Tag RAM latency for Cortex-A57 is
+ * suitable.
+ * - Defect #831273 doesn't affect Juno R1.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(1)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A57_MIDR, A57
ret
A57:
@@ -92,30 +141,69 @@
* Cortex-A57 specific settings
* --------------------------------------------------------------------
*/
-
- /* Change the L2 Data RAM latency to 3 cycles */
- mov x0, #L2_DATA_RAM_LATENCY_3_CYCLES
- cbnz x2, apply_l2_ram_latencies
- /* On Juno r0, also change the L2 Tag RAM latency to 3 cycles */
- orr x0, x0, #(L2_TAG_RAM_LATENCY_3_CYCLES << \
- L2CTLR_TAG_RAM_LATENCY_SHIFT)
-apply_l2_ram_latencies:
+ mov x0, #(L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT)
msr L2CTLR_EL1, x0
+ isb
+ ret
+endfunc JUNO_HANDLER(1)
- /* Juno r1 doesn't suffer from defect #831273 */
- cbnz x2, ret
+ /* --------------------------------------------------------------------
+ * Platform reset handler for Juno R2.
+ *
+ * Juno R2 has the following topology:
+ * - Quad core Cortex-A53 processor cluster;
+ * - Dual core Cortex-A72 processor cluster.
+ *
+ * This handler does the following:
+ * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72
+ * - Set the L2 Tag RAM latency to 1 (i.e. 2 cycles) for Cortex-A72
+ *
+ * Note that:
+ * - Defect #831273 doesn't affect Juno R2.
+ * --------------------------------------------------------------------
+ */
+func JUNO_HANDLER(2)
+ /* --------------------------------------------------------------------
+ * Nothing to do on Cortex-A53.
+ * --------------------------------------------------------------------
+ */
+ jump_if_cpu_midr CORTEX_A72_MIDR, A72
+ ret
-apply_831273:
+A72:
/* --------------------------------------------------------------------
- * On Juno r0, enable the event stream every 65536 cycles
+ * Cortex-A72 specific settings
* --------------------------------------------------------------------
*/
- mov x0, #(0xf << EVNTI_SHIFT)
- orr x0, x0, #EVNTEN_BIT
- msr CNTKCTL_EL1, x0
-ret:
+ mov x0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+ (L2_TAG_RAM_LATENCY_2_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ msr L2CTLR_EL1, x0
isb
ret
+endfunc JUNO_HANDLER(2)
+
+ /* --------------------------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the Juno board revision and call the appropriate reset
+ * handler.
+ * --------------------------------------------------------------------
+ */
+func plat_reset_handler
+ /* Read the V2M SYS_ID register */
+ mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID)
+ ldr w1, [x0]
+ /* Extract board revision from the SYS_ID */
+ ubfx x0, x1, #V2M_SYS_ID_REV_SHIFT, #4
+
+ JUMP_TO_HANDLER_IF_JUNO_R(0)
+ JUMP_TO_HANDLER_IF_JUNO_R(1)
+ JUMP_TO_HANDLER_IF_JUNO_R(2)
+
+ /* Board revision is not supported */
+not_supported:
+ b not_supported
+
endfunc plat_reset_handler
/* -----------------------------------------------------
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index 143cf00..1f367f2 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -39,6 +39,7 @@
/* Board revisions */
#define REV_JUNO_R0 0x1 /* Rev B */
#define REV_JUNO_R1 0x2 /* Rev C */
+#define REV_JUNO_R2 0x3 /* Rev D */
/* Bypass offset from start of NOR flash */
#define BL1_ROM_BYPASS_OFFSET 0x03EC0000