blob: 348f8efff9f2585e2ad3700df0ce01f1a0c63301 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <assert.h>
9#include <mmio.h>
10#include <plat_topology.h>
11#include <platform_def.h>
12#include <stddef.h>
13#include <tftf_lib.h>
14
15/* FVP Power controller based defines */
16#define PWRC_BASE 0x1c100000
17#define PSYSR_OFF 0x10
18#define PSYSR_INVALID 0xffffffff
19
20static const struct {
21 unsigned int cluster_id;
22 unsigned int cpu_id;
23} fvp_base_aemv8a_aemv8a_cores[] = {
24 /* Cluster 0 */
25 { 0, 0 },
26 { 0, 1 },
27 { 0, 2 },
28 { 0, 3 },
29 /* Cluster 1 */
30 { 1, 0 },
31 { 1, 1 },
32 { 1, 2 },
33 { 1, 3 },
34 /* Cluster 2 */
35 { 2, 0 },
36 { 2, 1 },
37 { 2, 2 },
38 { 2, 3 },
39 /* Cluster 3 */
40 { 3, 0 },
41 { 3, 1 },
42 { 3, 2 },
43 { 3, 3 },
44};
45
46/*
47 * The FVP power domain tree descriptor. We always construct a topology
48 * with the maximum number of cluster nodes possible for FVP. During
49 * TFTF initialization, the actual number of nodes present on the model
50 * will be queried dynamically using `tftf_plat_get_mpidr()`.
51 * The FVP power domain tree does not have a single system level power domain
52 * i.e. a single root node. The first entry in the power domain descriptor
53 * specifies the number of power domains at the highest power level which
54 * is equal to FVP_CLUSTER_COUNT.
55 */
56static const unsigned char fvp_power_domain_tree_desc[] = {
57 /* Number of system nodes */
58 1,
59 /* Number of cluster nodes */
60 FVP_CLUSTER_COUNT,
61 /* Number of children for the first node */
62 FVP_MAX_CPUS_PER_CLUSTER,
63 /* Number of children for the second node */
64 FVP_MAX_CPUS_PER_CLUSTER,
65 /* Number of children for the third node */
66 FVP_MAX_CPUS_PER_CLUSTER,
67 /* Number of children for the fourth node */
68 FVP_MAX_CPUS_PER_CLUSTER
69};
70
71const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void)
72{
73 return fvp_power_domain_tree_desc;
74}
75
76static unsigned int fvp_pwrc_read_psysr(unsigned long mpidr)
77{
78 unsigned int rc;
79 mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr);
80 rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
81 return rc;
82}
83
84uint64_t tftf_plat_get_mpidr(unsigned int core_pos)
85{
86 unsigned int mpid;
87
88 assert(core_pos < PLATFORM_CORE_COUNT);
89
90 mpid = make_mpid(
91 fvp_base_aemv8a_aemv8a_cores[core_pos].cluster_id,
92 fvp_base_aemv8a_aemv8a_cores[core_pos].cpu_id);
93
94 if (fvp_pwrc_read_psysr(mpid) != PSYSR_INVALID)
95 return mpid;
96
97 return INVALID_MPID;
98}