]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
Provide a hint to power controller for DSU cluster power down
authorMadhukar Pappireddy <madhukar.pappireddy@arm.com>
Wed, 30 Oct 2019 19:24:39 +0000 (14:24 -0500)
committerMadhukar Pappireddy <madhukar.pappireddy@arm.com>
Wed, 15 Apr 2020 15:10:24 +0000 (10:10 -0500)
By writing 0 to CLUSTERPWRDN DSU register bit 0, we send an
advisory to the power controller that cluster power is not required
when all cores are powered down.

The AArch32 CLUSTERPWRDN register is architecturally mapped to the
AArch64 CLUSTERPWRDN_EL1 register

Change-Id: Ie6e67c1c7d811fa25c51e2e405ca7f59bd20c81b
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
include/arch/aarch32/arch.h
include/arch/aarch32/arch_helpers.h
include/arch/aarch64/arch.h
include/arch/aarch64/arch_helpers.h
plat/arm/board/fvp/fvp_pm.c
plat/arm/css/common/css_pm.c

index 8492b3ea4b673f1a4b93f9b0a02f5f2e518f4c48..a11d55e08e8b200e3af4b8d87de1f31e33887046 100644 (file)
 #define AMEVTYPER1E    p15, 0, c13, c15, 6
 #define AMEVTYPER1F    p15, 0, c13, c15, 7
 
+/*******************************************************************************
+ * Definitions for DynamicIQ Shared Unit registers
+ ******************************************************************************/
+#define CLUSTERPWRDN   p15, 0, c15, c3, 6
+
+/* CLUSTERPWRDN register definitions */
+#define DSU_CLUSTER_PWR_OFF    0
+#define DSU_CLUSTER_PWR_ON     1
+#define DSU_CLUSTER_PWR_MASK   U(1)
+
 #endif /* ARCH_H */
index a90b2a54cfb30dc24daf126bf942fd0e6b323ea1..eed56e219220bab8f4f0c06ba4c72079a3ce43c4 100644 (file)
@@ -336,6 +336,11 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCIMVAC)
 DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
 #endif
 
+/*
+ * DynamIQ Shared Unit power management
+ */
+DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN)
+
 /* Previously defined accessor functions with incomplete register names  */
 #define dsb()                  dsbsy()
 #define dmb()                  dmbsy()
index 19dd8c5e38470c61dd111b2ca40ea534196bc0bd..e45a594c56f9d7510cdd430933d729efa366a3b5 100644 (file)
 #define RGSR_EL1               S3_0_C1_C0_5
 #define GCR_EL1                        S3_0_C1_C0_6
 
+/*******************************************************************************
+ * Definitions for DynamicIQ Shared Unit registers
+ ******************************************************************************/
+#define CLUSTERPWRDN_EL1       S3_0_c15_c3_6
+
+/* CLUSTERPWRDN_EL1 register definitions */
+#define DSU_CLUSTER_PWR_OFF    0
+#define DSU_CLUSTER_PWR_ON     1
+#define DSU_CLUSTER_PWR_MASK   U(1)
+
 #endif /* ARCH_H */
index 669a1403c4b0945b8b338fe770b649503e67b763..9cd1ae51535e2bba9112e57b284b6188c6edbb88 100644 (file)
@@ -520,6 +520,9 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1)
 
+/* DynamIQ Shared Unit power management */
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
+
 #define IS_IN_EL(x) \
        (GET_EL(read_CurrentEl()) == MODE_EL##x)
 
@@ -582,4 +585,7 @@ static inline uint64_t el_implemented(unsigned int el)
 #define read_cpacr()           read_cpacr_el1()
 #define write_cpacr(_v)                write_cpacr_el1(_v)
 
+#define read_clusterpwrdn()    read_clusterpwrdn_el1()
+#define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v)
+
 #endif /* ARCH_HELPERS_H */
index c47d837796767fee1b460686f91afedcd12fbd15..333d89288a6b99f62bc794367fbfd2bd8c7a0735 100644 (file)
@@ -64,6 +64,25 @@ static void fvp_cluster_pwrdwn_common(void)
        /* Disable coherency if this cluster is to be turned off */
        fvp_interconnect_disable();
 
+#if HW_ASSISTED_COHERENCY
+       uint32_t reg;
+
+       /*
+        * If we have determined this core to be the last man standing and we
+        * intend to power down the cluster proactively, we provide a hint to
+        * the power controller that cluster power is not required when all
+        * cores are powered down.
+        * Note that this is only an advisory to power controller and is supported
+        * by SoCs with DynamIQ Shared Units only.
+        */
+       reg = read_clusterpwrdn();
+
+       /* Clear and set bit 0 : Cluster power not required */
+       reg &= ~DSU_CLUSTER_PWR_MASK;
+       reg |= DSU_CLUSTER_PWR_OFF;
+       write_clusterpwrdn(reg);
+#endif
+
        /* Program the power controller to turn the cluster off */
        fvp_pwrc_write_pcoffr(mpidr);
 }
index af69c6fb46d5c3b0a20fe45ae4f0f02dd5576b2c..8e74526346cc409dc46d6e01ea47ba77f4af5b5c 100644 (file)
@@ -124,8 +124,28 @@ static void css_power_down_common(const psci_power_state_t *target_state)
        plat_arm_gic_cpuif_disable();
 
        /* Cluster is to be turned off, so disable coherency */
-       if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+       if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
                plat_arm_interconnect_exit_coherency();
+
+#if HW_ASSISTED_COHERENCY
+               uint32_t reg;
+
+               /*
+                * If we have determined this core to be the last man standing and we
+                * intend to power down the cluster proactively, we provide a hint to
+                * the power controller that cluster power is not required when all
+                * cores are powered down.
+                * Note that this is only an advisory to power controller and is supported
+                * by SoCs with DynamIQ Shared Units only.
+                */
+               reg = read_clusterpwrdn();
+
+               /* Clear and set bit 0 : Cluster power not required */
+               reg &= ~DSU_CLUSTER_PWR_MASK;
+               reg |= DSU_CLUSTER_PWR_OFF;
+               write_clusterpwrdn(reg);
+#endif
+       }
 }
 
 /*******************************************************************************