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