xref: /rk3399_ARM-atf/plat/arm/board/arm_fpga/fpga_topology.c (revision 7ee4db6e4720ebb45a7c20da06c06091ee95c298)
1536d906aSOliver Swede /*
2536d906aSOliver Swede  * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
3536d906aSOliver Swede  *
4536d906aSOliver Swede  * SPDX-License-Identifier: BSD-3-Clause
5536d906aSOliver Swede  */
6536d906aSOliver Swede 
7536d906aSOliver Swede #include <arch_helpers.h>
8536d906aSOliver Swede 
9536d906aSOliver Swede #include "fpga_private.h"
10536d906aSOliver Swede #include <platform_def.h>
11536d906aSOliver Swede 
12*7ee4db6eSOliver Swede static unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2];
13*7ee4db6eSOliver Swede 
14536d906aSOliver Swede const unsigned char *plat_get_power_domain_tree_desc(void)
15536d906aSOliver Swede {
16*7ee4db6eSOliver Swede 	int i;
17*7ee4db6eSOliver Swede 	/*
18*7ee4db6eSOliver Swede 	* The highest level is the system level. The next level is constituted
19*7ee4db6eSOliver Swede 	* by clusters and then cores in clusters.
20*7ee4db6eSOliver Swede 	*
21*7ee4db6eSOliver Swede 	* This description of the power domain topology is aligned with the CPU
22*7ee4db6eSOliver Swede 	* indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos()
23*7ee4db6eSOliver Swede 	* APIs.
24*7ee4db6eSOliver Swede 	*/
25*7ee4db6eSOliver Swede 	fpga_power_domain_tree_desc[0] = 1;
26*7ee4db6eSOliver Swede 	fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT;
27*7ee4db6eSOliver Swede 
28*7ee4db6eSOliver Swede 	for (i = 0; i < FPGA_MAX_CLUSTER_COUNT; i++) {
29*7ee4db6eSOliver Swede 		fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER;
30*7ee4db6eSOliver Swede 	}
31*7ee4db6eSOliver Swede 
32*7ee4db6eSOliver Swede 	return fpga_power_domain_tree_desc;
33536d906aSOliver Swede }
34536d906aSOliver Swede 
35536d906aSOliver Swede int plat_core_pos_by_mpidr(u_register_t mpidr)
36536d906aSOliver Swede {
37*7ee4db6eSOliver Swede 	unsigned int cluster_id, cpu_id, thread_id;
38*7ee4db6eSOliver Swede 
39*7ee4db6eSOliver Swede 	mpidr &= MPIDR_AFFINITY_MASK;
40*7ee4db6eSOliver Swede 	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
41*7ee4db6eSOliver Swede 		return -1;
42*7ee4db6eSOliver Swede 	}
43*7ee4db6eSOliver Swede 
44*7ee4db6eSOliver Swede 	if (mpidr & MPIDR_MT_MASK) {
45*7ee4db6eSOliver Swede 		thread_id = MPIDR_AFFLVL0_VAL(mpidr);
46*7ee4db6eSOliver Swede 	} else {
47*7ee4db6eSOliver Swede 		thread_id = 0;
48*7ee4db6eSOliver Swede 	}
49*7ee4db6eSOliver Swede 
50*7ee4db6eSOliver Swede 	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
51*7ee4db6eSOliver Swede 	cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
52*7ee4db6eSOliver Swede 
53*7ee4db6eSOliver Swede 	if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) {
54*7ee4db6eSOliver Swede 		return -1;
55*7ee4db6eSOliver Swede 	} else if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) {
56*7ee4db6eSOliver Swede 		return -1;
57*7ee4db6eSOliver Swede 	} else if (thread_id >= FPGA_MAX_PE_PER_CPU) {
58*7ee4db6eSOliver Swede 		return -1;
59*7ee4db6eSOliver Swede 	}
60*7ee4db6eSOliver Swede 
61536d906aSOliver Swede 	/*
62*7ee4db6eSOliver Swede 	 * The image running on the FPGA may or may not implement multithreading,
63*7ee4db6eSOliver Swede 	 * and it shouldn't be assumed this is consistent across all CPUs.
64*7ee4db6eSOliver Swede 	 * This ensures that any passed mpidr values reflect the status of the
65*7ee4db6eSOliver Swede 	 * primary CPU's MT bit.
66536d906aSOliver Swede 	 */
67*7ee4db6eSOliver Swede 	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
68*7ee4db6eSOliver Swede 
69*7ee4db6eSOliver Swede 	/* Calculate the correct core, catering for multi-threaded images */
70536d906aSOliver Swede 	return (int) plat_fpga_calc_core_pos(mpidr);
71536d906aSOliver Swede }
72