diff options
author | Aaron Durbin <adurbin@chromium.org> | 2014-10-28 15:38:17 -0500 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-04-09 14:40:13 +0200 |
commit | b777f3e3d1cb4265f1a4bf392781b93bd0c37eea (patch) | |
tree | 76fb64e2714b8dc9822b25a24d80b17e68890f58 /src/arch/arm64/include | |
parent | 7d62ad05fb7e1bc1f38c609709e600c76f6b1d34 (diff) | |
download | coreboot-b777f3e3d1cb4265f1a4bf392781b93bd0c37eea.tar.xz |
arm64: psci: add node hierarchy
In order to properly support more arm64 SoCs PSCI needs
to handle the hierarchy of cpus/clusters within the SoC.
The nodes within PSCI are kept in a tree as well as
a depth-first ordered array of same tree. Additionally,
the PSCI states are now maintained in a hierachal manner.
OFF propogates up the tree as long as all siblings are
set to OFF. ON propogates up the tree until a node is
not already set to OFF.
The SoC provides the operations for determining how many
children are at a given affinity level. Lastly, the
secmon startup has been reworked in that all non-BSP CPUs
wait for instructions from the BSP.
BUG=chrome-os-partner:32136
BRANCH=None
TEST=Can still boot into kernel with SMP.
Change-Id: I036fabaf0f1cefa2841264c47e4092c75a2ff4dc
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 721d408cd110e1b56d38789177b740aa0e54ca33
Original-Change-Id: I520a9726e283bee7edcb514cda28ec1eb31b5ea0
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/226480
Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: http://review.coreboot.org/9390
Tested-by: build bot (Jenkins)
Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/arch/arm64/include')
-rw-r--r-- | src/arch/arm64/include/arch/psci.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/arch/arm64/include/arch/psci.h b/src/arch/arm64/include/arch/psci.h index c39f13a088..afa4c4209c 100644 --- a/src/arch/arm64/include/arch/psci.h +++ b/src/arch/arm64/include/arch/psci.h @@ -20,6 +20,8 @@ #ifndef __ARCH_PSCI_H__ #define __ARCH_PSCI_H__ +#include <stdint.h> +#include <arch/cpu.h> #include <arch/smc.h> /* Return Values */ @@ -35,6 +37,85 @@ enum { PSCI_RET_DISABLED = -8, }; +/* Generic PSCI state. */ +enum { + PSCI_STATE_OFF = 0, + PSCI_STATE_ON_PENDING, + PSCI_STATE_ON, +}; + +/* Affinity level support. */ +enum { + PSCI_AFFINITY_LEVEL_0, + PSCI_AFFINITY_LEVEL_1, + PSCI_AFFINITY_LEVEL_2, + PSCI_AFFINITY_LEVEL_3, + PSCI_AFFINITY_ROOT, + PSCI_AFFINITY_LEVEL_HIGHEST = PSCI_AFFINITY_ROOT, +}; + +static inline int psci_level_below(int level) +{ + return level - 1; +} + +struct psci_node; + +struct psci_cpu_state { + struct cpu_info *ci; + void *entry; + void *arg; + /* Ancestor of target to update state in CPU_ON case. */ + struct psci_node *ancestor; +}; + +struct psci_node_group { + size_t num; + struct psci_node *nodes; +}; + +struct psci_node { + uint64_t mpidr; + /* Affinity level of node. */ + int level; + /* Generic power state of this entity. */ + int state; + /* The SoC can stash its own state accounting in here. */ + int soc_state; + /* Parent of curernt entity. */ + struct psci_node *parent; + /* + * CPUs are leaves in the tree. They don't have children. The + * CPU-specific bits of storage can be shared with the children + * storage. + */ + union { + struct psci_node_group children; + struct psci_cpu_state cpu_state; + }; +}; + +static inline struct psci_node *psci_node_parent(const struct psci_node *n) +{ + return n->parent; +} + +static inline int psci_root_node(const struct psci_node *n) +{ + return psci_node_parent(n) == NULL; +} + +struct psci_soc_ops { + /* + * Return number of entities one level below given parent affinitly + * level and mpidr. + */ + size_t (*children_at_level)(int parent_level, uint64_t mpidr); +}; + +/* Each SoC needs to provide the functions in the psci_soc_ops structure. */ +extern struct psci_soc_ops soc_psci_ops; + /* PSCI Functions. */ enum { /* 32-bit System level functions. */ @@ -111,5 +192,6 @@ void psci_init(void); /* Turn on the current CPU within the PSCI subsystem. */ void psci_turn_on_self(void *entry, void *arg); +int psci_turn_off_self(void); #endif /* __ARCH_PSCI_H__ */ |