xref: /rk3399_ARM-atf/plat/arm/board/arm_fpga/fpga_topology.c (revision 53baf7f049d250bb96f59050fcff657455241cad)
1 /*
2  * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch_helpers.h>
8 
9 #include "fpga_private.h"
10 #include <platform_def.h>
11 
12 static unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2];
13 
14 const unsigned char *plat_get_power_domain_tree_desc(void)
15 {
16 	int i;
17 	/*
18 	* The highest level is the system level. The next level is constituted
19 	* by clusters and then cores in clusters.
20 	*
21 	* This description of the power domain topology is aligned with the CPU
22 	* indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos()
23 	* APIs.
24 	*/
25 	fpga_power_domain_tree_desc[0] = 1;
26 	fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT;
27 
28 	for (i = 0; i < FPGA_MAX_CLUSTER_COUNT; i++) {
29 		fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU;
30 	}
31 
32 	return fpga_power_domain_tree_desc;
33 }
34 
35 int plat_core_pos_by_mpidr(u_register_t mpidr)
36 {
37 	unsigned int cluster_id, cpu_id, thread_id;
38 
39 	/*
40 	 * The image running on the FPGA may or may not implement
41 	 * multithreading, and it shouldn't be assumed this is consistent
42 	 * across all CPUs.
43 	 * This ensures that any passed mpidr values reflect the status of the
44 	 * primary CPU's MT bit.
45 	 */
46 	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
47 	mpidr &= MPID_MASK;
48 
49 	if (mpidr & MPIDR_MT_MASK) {
50 		thread_id = MPIDR_AFFLVL0_VAL(mpidr);
51 		cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
52 		cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
53 	} else {
54 		thread_id = 0;
55 		cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
56 		cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
57 	}
58 
59 	if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) {
60 		return -1;
61 	}
62 
63 	if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) {
64 		return -1;
65 	}
66 
67 	if (thread_id >= FPGA_MAX_PE_PER_CPU) {
68 		return -1;
69 	}
70 
71 	/* Calculate the correct core, catering for multi-threaded images */
72 	return (int) plat_fpga_calc_core_pos(mpidr);
73 }
74