blob: a40ff6f505c0dfe12093559ba92df7fd904cf751 [file] [log] [blame]
Konstantin Porotchkinf69ec582018-06-07 18:31:14 +03001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8#include <plat_marvell.h>
9
10/* The power domain tree descriptor */
11unsigned char marvell_power_domain_tree_desc[PLAT_MARVELL_CLUSTER_COUNT + 1];
12
13/*****************************************************************************
14 * This function dynamically constructs the topology according to
15 * PLAT_MARVELL_CLUSTER_COUNT and returns it.
16 *****************************************************************************
17 */
18const unsigned char *plat_get_power_domain_tree_desc(void)
19{
20 int i;
21
22 /*
23 * The power domain tree does not have a single system level power
24 * domain i.e. a single root node. The first entry in the power domain
25 * descriptor specifies the number of power domains at the highest power
26 * level.
27 * For Marvell Platform this is the number of cluster power domains.
28 */
29 marvell_power_domain_tree_desc[0] = PLAT_MARVELL_CLUSTER_COUNT;
30
31 for (i = 0; i < PLAT_MARVELL_CLUSTER_COUNT; i++)
32 marvell_power_domain_tree_desc[i + 1] =
33 PLAT_MARVELL_CLUSTER_CORE_COUNT;
34
35 return marvell_power_domain_tree_desc;
36}
37
38/*****************************************************************************
39 * This function validates an MPIDR by checking whether it falls within the
40 * acceptable bounds. An error code (-1) is returned if an incorrect mpidr
41 * is passed.
42 *****************************************************************************
43 */
44int marvell_check_mpidr(u_register_t mpidr)
45{
46 unsigned int nb_id, cluster_id, cpu_id;
47
48 mpidr &= MPIDR_AFFINITY_MASK;
49
50 if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK |
51 MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT))
52 return -1;
53
54 /* Get north bridge ID */
55 nb_id = MPIDR_AFFLVL3_VAL(mpidr);
56 cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
57 cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
58
59 if (nb_id >= PLAT_MARVELL_CLUSTER_COUNT)
60 return -1;
61
62 if (cluster_id >= PLAT_MARVELL_CLUSTER_COUNT)
63 return -1;
64
65 if (cpu_id >= PLAT_MARVELL_CLUSTER_CORE_COUNT)
66 return -1;
67
68 return 0;
69}
70
71/*****************************************************************************
72 * This function implements a part of the critical interface between the PSCI
73 * generic layer and the platform that allows the former to query the platform
74 * to convert an MPIDR to a unique linear index. An error code (-1) is returned
75 * in case the MPIDR is invalid.
76 *****************************************************************************
77 */
78int plat_core_pos_by_mpidr(u_register_t mpidr)
79{
80 if (marvell_check_mpidr(mpidr) == -1)
81 return -1;
82
83 return plat_marvell_calc_core_pos(mpidr);
84}