summaryrefslogtreecommitdiff
path: root/include/bl31
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2015-04-08 17:42:06 +0100
committerAchin Gupta <achin.gupta@arm.com>2015-08-13 16:28:26 +0100
commit82dcc039812fafb912c9a7e582ffa3fcc1db2d71 (patch)
tree96e1b7585923170c20a547cdedbab1777d9d0abf /include/bl31
parent12d0d00d1e4714fc59c4abbe1d8a2a3ae8a84f56 (diff)
PSCI: Introduce new platform interface to describe topology
This patch removes the assumption in the current PSCI implementation that MPIDR based affinity levels map directly to levels in a power domain tree. This enables PSCI generic code to support complex power domain topologies as envisaged by PSCIv1.0 specification. The platform interface for querying the power domain topology has been changed such that: 1. The generic PSCI code does not generate MPIDRs and use them to query the platform about the number of power domains at a particular power level. The platform now provides a description of the power domain tree on the SoC through a data structure. The existing platform APIs to provide the same information have been removed. 2. The linear indices returned by plat_core_pos_by_mpidr() and plat_my_core_pos() are used to retrieve core power domain nodes from the power domain tree. Power domains above the core level are accessed using a 'parent' field in the tree node descriptors. The platform describes the power domain tree in an array of 'unsigned char's. The first entry in the array specifies the number of power domains at the highest power level implemented in the system. Each susbsequent entry corresponds to a power domain and contains the number of power domains that are its direct children. This array is exported to the generic PSCI implementation via the new `plat_get_power_domain_tree_desc()` platform API. The PSCI generic code uses this array to populate its internal power domain tree using the Breadth First Search like algorithm. The tree is split into two arrays: 1. An array that contains all the core power domain nodes 2. An array that contains all the other power domain nodes A separate array for core nodes allows certain core specific optimisations to be implemented e.g. remove the bakery lock, re-use per-cpu data framework for storing some information. Entries in the core power domain array are allocated such that the array index of the domain is equal to the linear index returned by plat_core_pos_by_mpidr() and plat_my_core_pos() for the MPIDR corresponding to that domain. This relationship is key to be able to use an MPIDR to find the corresponding core power domain node, traverse to higher power domain nodes and index into arrays that contain core specific information. An introductory document has been added to briefly describe the new interface. Change-Id: I4b444719e8e927ba391cae48a23558308447da13
Diffstat (limited to 'include/bl31')
-rw-r--r--include/bl31/services/psci1.0/psci.h31
1 files changed, 20 insertions, 11 deletions
diff --git a/include/bl31/services/psci1.0/psci.h b/include/bl31/services/psci1.0/psci.h
index d00796c5..c31562c0 100644
--- a/include/bl31/services/psci1.0/psci.h
+++ b/include/bl31/services/psci1.0/psci.h
@@ -43,6 +43,19 @@
#define PSCI_NUM_PWR_DOMAINS (2 * PLATFORM_CORE_COUNT)
#endif
+#define PSCI_NUM_NON_CPU_PWR_DOMAINS (PSCI_NUM_PWR_DOMAINS - \
+ PLATFORM_CORE_COUNT)
+
+/* This is the power level corresponding to a CPU */
+#define PSCI_CPU_PWR_LVL 0
+
+/*
+ * The maximum power level supported by PSCI. Since PSCI CPU_SUSPEND
+ * uses the old power_state parameter format which has 2 bits to specify the
+ * power level, this constant is defined to be 3.
+ */
+#define PSCI_MAX_PWR_LVL 3
+
/*******************************************************************************
* Defines for runtime services func ids
******************************************************************************/
@@ -137,16 +150,11 @@
#define PSCI_E_NOT_PRESENT -7
#define PSCI_E_DISABLED -8
+#define PSCI_INVALID_MPIDR ~(0ULL)
+
/*******************************************************************************
- * PSCI power domain state related constants. A power domain instance could
- * be present or absent physically to cater for asymmetric topologies. If
- * present then it could be in one of the 4 further defined states.
+ * PSCI power domain state related constants.
******************************************************************************/
-#define PSCI_STATE_SHIFT 1
-#define PSCI_STATE_MASK 0xff
-
-#define PSCI_PWR_DOMAIN_ABSENT 0x0
-#define PSCI_PWR_DOMAIN_PRESENT 0x1
#define PSCI_STATE_ON 0x0
#define PSCI_STATE_OFF 0x1
#define PSCI_STATE_ON_PENDING 0x2
@@ -170,9 +178,10 @@
* this information will not reside on a cache line shared with another cpu.
******************************************************************************/
typedef struct psci_cpu_data {
- uint32_t power_state;
+ uint32_t power_state; /* The power state from CPU_SUSPEND */
+ unsigned char psci_state; /* The state of this CPU as seen by PSCI */
#if !USE_COHERENT_MEM
- bakery_info_t pcpu_bakery_info[PSCI_NUM_PWR_DOMAINS];
+ bakery_info_t pcpu_bakery_info[PSCI_NUM_NON_CPU_PWR_DOMAINS];
#endif
} psci_cpu_data_t;
@@ -230,7 +239,7 @@ void __dead2 psci_power_down_wfi(void);
void psci_cpu_on_finish_entry(void);
void psci_cpu_suspend_finish_entry(void);
void psci_register_spd_pm_hook(const spd_pm_ops_t *);
-int psci_get_suspend_stateid_by_mpidr(unsigned long);
+int psci_get_suspend_stateid_by_idx(unsigned long);
int psci_get_suspend_stateid(void);
int psci_get_suspend_pwrlvl(void);