feat(fvp): add cpu power control
Most newer CPU's have DSU and CPU power control core-off bit which
means before turning off CPUs from base power controller we need to
turn individual cores off from CPU Power control.
However there are certain older CPU's that don't have DSU and
don't support CPUPWRCTRL_EL1, so populate them as a list
and ignore setting core-off bit for those older CPU's as all newer
CPU's have them.
Note: unfortunately there is no mechanism to identify if a DSU is
present and CPUPWRCTRL_EL1 is supported through any CPU control
registers and CPUPWRCTRL_EL1 is supported only for ARM64 platforms
and not available in ARM32 platforms.
Change-Id: Iba6c3c8db60dbeb177cead7ebc65df8265860da7
Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
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]