xref: /rk3399_ARM-atf/plat/arm/board/arm_fpga/fpga_topology.c (revision 53baf7f049d250bb96f59050fcff657455241cad)
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 
127ee4db6eSOliver Swede static unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2];
137ee4db6eSOliver Swede 
14536d906aSOliver Swede const unsigned char *plat_get_power_domain_tree_desc(void)
15536d906aSOliver Swede {
167ee4db6eSOliver Swede 	int i;
177ee4db6eSOliver Swede 	/*
187ee4db6eSOliver Swede 	* The highest level is the system level. The next level is constituted
197ee4db6eSOliver Swede 	* by clusters and then cores in clusters.
207ee4db6eSOliver Swede 	*
217ee4db6eSOliver Swede 	* This description of the power domain topology is aligned with the CPU
227ee4db6eSOliver Swede 	* indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos()
237ee4db6eSOliver Swede 	* APIs.
247ee4db6eSOliver Swede 	*/
257ee4db6eSOliver Swede 	fpga_power_domain_tree_desc[0] = 1;
267ee4db6eSOliver Swede 	fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT;
277ee4db6eSOliver Swede 
287ee4db6eSOliver Swede 	for (i = 0; i < FPGA_MAX_CLUSTER_COUNT; i++) {
29*53baf7f0SAndre Przywara 		fpga_power_domain_tree_desc[i + 2] = FPGA_MAX_CPUS_PER_CLUSTER * FPGA_MAX_PE_PER_CPU;
307ee4db6eSOliver Swede 	}
317ee4db6eSOliver Swede 
327ee4db6eSOliver 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 {
377ee4db6eSOliver Swede 	unsigned int cluster_id, cpu_id, thread_id;
387ee4db6eSOliver Swede 
39536d906aSOliver Swede 	/*
40*53baf7f0SAndre Przywara 	 * The image running on the FPGA may or may not implement
41*53baf7f0SAndre Przywara 	 * multithreading, and it shouldn't be assumed this is consistent
42*53baf7f0SAndre Przywara 	 * across all CPUs.
437ee4db6eSOliver Swede 	 * This ensures that any passed mpidr values reflect the status of the
447ee4db6eSOliver Swede 	 * primary CPU's MT bit.
45536d906aSOliver Swede 	 */
467ee4db6eSOliver Swede 	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
47*53baf7f0SAndre Przywara 	mpidr &= MPID_MASK;
48*53baf7f0SAndre Przywara 
49*53baf7f0SAndre Przywara 	if (mpidr & MPIDR_MT_MASK) {
50*53baf7f0SAndre Przywara 		thread_id = MPIDR_AFFLVL0_VAL(mpidr);
51*53baf7f0SAndre Przywara 		cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
52*53baf7f0SAndre Przywara 		cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
53*53baf7f0SAndre Przywara 	} else {
54*53baf7f0SAndre Przywara 		thread_id = 0;
55*53baf7f0SAndre Przywara 		cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
56*53baf7f0SAndre Przywara 		cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
57*53baf7f0SAndre Przywara 	}
58*53baf7f0SAndre Przywara 
59*53baf7f0SAndre Przywara 	if (cluster_id >= FPGA_MAX_CLUSTER_COUNT) {
60*53baf7f0SAndre Przywara 		return -1;
61*53baf7f0SAndre Przywara 	}
62*53baf7f0SAndre Przywara 
63*53baf7f0SAndre Przywara 	if (cpu_id >= FPGA_MAX_CPUS_PER_CLUSTER) {
64*53baf7f0SAndre Przywara 		return -1;
65*53baf7f0SAndre Przywara 	}
66*53baf7f0SAndre Przywara 
67*53baf7f0SAndre Przywara 	if (thread_id >= FPGA_MAX_PE_PER_CPU) {
68*53baf7f0SAndre Przywara 		return -1;
69*53baf7f0SAndre Przywara 	}
707ee4db6eSOliver Swede 
717ee4db6eSOliver Swede 	/* Calculate the correct core, catering for multi-threaded images */
72536d906aSOliver Swede 	return (int) plat_fpga_calc_core_pos(mpidr);
73536d906aSOliver Swede }
74