Merge "feat(fvp): add cpu power control" into integration
diff --git a/include/drivers/arm/fvp/fvp_cpu_pwr.h b/include/drivers/arm/fvp/fvp_cpu_pwr.h
new file mode 100644
index 0000000..488be18
--- /dev/null
+++ b/include/drivers/arm/fvp/fvp_cpu_pwr.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_CPU_PWR_H
+#define FVP_CPU_PWR_H
+
+#ifndef __ASSEMBLER__
+#include <stdbool.h>
+#include <stdint.h>
+
+#if __aarch64__
+bool check_cpupwrctrl_el1_is_available(void);
+#endif /* __aarch64__ */
+#endif /* __ASSEMBLER__ */
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* FVP_CPU_PWR_H */
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 8efc238..46fb44a 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -6,9 +6,10 @@
#include <arch.h>
#include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
#include <drivers/arm/gicv2.h>
#include <drivers/arm/gicv3.h>
-#include <drivers/arm/fvp/fvp_pwrc.h>
#include <platform_def.h>
.globl plat_secondary_cold_boot_setup
@@ -29,6 +30,21 @@
*/
func plat_secondary_cold_boot_setup
#ifndef EL3_PAYLOAD_BASE
+
+ /* --------------------------------------------
+ * Check if core supports powering down, if it
+ * supports power down then set core power down
+ * bit before requesting for the cores to be
+ * powered off from base power controller.
+ * ---------------------------------------------
+ */
+ bl check_cpupwrctrl_el1_is_available
+ cbz x0, base_power_off
+
+ mrs x1, CPUPWRCTLR_EL1
+ orr x1, x1, #CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ msr CPUPWRCTLR_EL1, x1
+
/* ---------------------------------------------
* Power down this cpu.
* TODO: Do we need to worry about powering the
@@ -37,6 +53,7 @@
* loader zeroes out the zi section.
* ---------------------------------------------
*/
+base_power_off:
mrs x0, mpidr_el1
mov_imm x1, PWRC_BASE
str w0, [x1, #PPOFFR_OFF]
diff --git a/plat/arm/board/fvp/fvp_cpu_pwr.c b/plat/arm/board/fvp/fvp_cpu_pwr.c
new file mode 100644
index 0000000..f2771c2
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_cpu_pwr.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if __aarch64__
+
+#include <aem_generic.h>
+#include <arch_helpers.h>
+#include <cortex_a35.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <cortex_a73.h>
+#include <cortex_a78_ae.h>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <lib/utils_def.h>
+#include <neoverse_e1.h>
+
+bool check_cpupwrctrl_el1_is_available(void)
+{
+ /* Poupulate list of CPU midr that doesn't support CPUPWRCTL_EL1 */
+ const unsigned int midr_no_cpupwrctl[] = {
+ BASE_AEM_MIDR,
+ CORTEX_A35_MIDR,
+ CORTEX_A53_MIDR,
+ CORTEX_A57_MIDR,
+ CORTEX_A72_MIDR,
+ CORTEX_A73_MIDR,
+ CORTEX_A78_AE_MIDR,
+ NEOVERSE_E1_MIDR
+ };
+ unsigned int midr = (unsigned int)read_midr();
+
+ for (unsigned int i = 0U; i < ARRAY_SIZE(midr_no_cpupwrctl); i++) {
+ if (midr_no_cpupwrctl[i] == midr) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#endif /* __arch64__ */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 033eb7c..af2b78d 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -222,6 +222,7 @@
lib/semihosting/${ARCH}/semihosting_call.S \
plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
plat/arm/board/fvp/fvp_bl1_setup.c \
+ plat/arm/board/fvp/fvp_cpu_pwr.c \
plat/arm/board/fvp/fvp_err.c \
plat/arm/board/fvp/fvp_io_storage.c \
plat/arm/board/fvp/fvp_topology.c \
@@ -252,7 +253,8 @@
endif
ifeq (${ENABLE_RME},1)
-BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S
+BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S \
+ plat/arm/board/fvp/fvp_cpu_pwr.c
BL31_SOURCES += plat/arm/board/fvp/fvp_plat_attest_token.c \
plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -264,6 +266,7 @@
ifeq (${RESET_TO_BL2},1)
BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
+ plat/arm/board/fvp/fvp_cpu_pwr.c \
plat/arm/board/fvp/fvp_bl2_el3_setup.c \
${FVP_CPU_LIBS} \
${FVP_INTERCONNECT_SOURCES}
@@ -290,6 +293,7 @@
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \
+ plat/arm/board/fvp/fvp_cpu_pwr.c \
plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_CPU_LIBS} \
${FVP_GIC_SOURCES} \