xref: /rk3399_ARM-atf/plat/arm/board/arm_fpga/fpga_topology.c (revision 0a0a7a9ac82cb79af91f098cedc69cc67bca3978)
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;
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 	mpidr &= MPIDR_AFFINITY_MASK;
40 	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
41 		return -1;
42 	}
43 
44 	if (mpidr & MPIDR_MT_MASK) {
45 		thread_id = MPIDR_AFFLVL0_VAL(mpidr);
46 	} else {
47 		thread_id = 0;
48 	}
49 
50 	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
51 	cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
52 
53 	if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) {
54 		return -1;
55 	} else if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) {
56 		return -1;
57 	} else if (thread_id >= FPGA_MAX_PE_PER_CPU) {
58 		return -1;
59 	}
60 
61 	/*
62 	 * The image running on the FPGA may or may not implement multithreading,
63 	 * and it shouldn't be assumed this is consistent across all CPUs.
64 	 * This ensures that any passed mpidr values reflect the status of the
65 	 * primary CPU's MT bit.
66 	 */
67 	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
68 
69 	/* Calculate the correct core, catering for multi-threaded images */
70 	return (int) plat_fpga_calc_core_pos(mpidr);
71 }
72