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