aboutsummaryrefslogtreecommitdiff
path: root/src/arch/arm64/include
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-10-28 15:38:17 -0500
committerPatrick Georgi <pgeorgi@google.com>2015-04-09 14:40:13 +0200
commitb777f3e3d1cb4265f1a4bf392781b93bd0c37eea (patch)
tree76fb64e2714b8dc9822b25a24d80b17e68890f58 /src/arch/arm64/include
parent7d62ad05fb7e1bc1f38c609709e600c76f6b1d34 (diff)
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.h82
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__ */