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> 8*727bbf68SJavier Almansa Sobrino #include <common/debug.h> 9*727bbf68SJavier Almansa Sobrino #include <lib/spinlock.h> 10536d906aSOliver Swede 11536d906aSOliver Swede #include "fpga_private.h" 12*727bbf68SJavier Almansa Sobrino #include <plat/common/platform.h> 13536d906aSOliver Swede #include <platform_def.h> 14536d906aSOliver Swede 15*727bbf68SJavier Almansa Sobrino unsigned char fpga_power_domain_tree_desc[FPGA_MAX_CLUSTER_COUNT + 2]; 16*727bbf68SJavier Almansa Sobrino unsigned char fpga_valid_mpids[PLATFORM_CORE_COUNT]; 177ee4db6eSOliver Swede plat_get_power_domain_tree_desc(void)18536d906aSOliver Swedeconst unsigned char *plat_get_power_domain_tree_desc(void) 19536d906aSOliver Swede { 20*727bbf68SJavier Almansa Sobrino unsigned int i; 21*727bbf68SJavier Almansa Sobrino 227ee4db6eSOliver Swede /* 237ee4db6eSOliver Swede * The highest level is the system level. The next level is constituted 247ee4db6eSOliver Swede * by clusters and then cores in clusters. 257ee4db6eSOliver Swede * 267ee4db6eSOliver Swede * This description of the power domain topology is aligned with the CPU 277ee4db6eSOliver Swede * indices returned by the plat_core_pos_by_mpidr() and plat_my_core_pos() 287ee4db6eSOliver Swede * APIs. 29*727bbf68SJavier Almansa Sobrino * 30*727bbf68SJavier Almansa Sobrino * A description of the topology tree can be found at 31*727bbf68SJavier Almansa Sobrino * https://trustedfirmware-a.readthedocs.io/en/latest/design/psci-pd-tree.html#design 327ee4db6eSOliver Swede */ 33*727bbf68SJavier Almansa Sobrino 34*727bbf68SJavier Almansa Sobrino if (fpga_power_domain_tree_desc[0] == 0U) { 35*727bbf68SJavier Almansa Sobrino /* 36*727bbf68SJavier Almansa Sobrino * As fpga_power_domain_tree_desc[0] == 0, assume that the 37*727bbf68SJavier Almansa Sobrino * Power Domain Topology Tree has not been initialized, so 38*727bbf68SJavier Almansa Sobrino * perform the initialization here. 39*727bbf68SJavier Almansa Sobrino */ 40*727bbf68SJavier Almansa Sobrino 41*727bbf68SJavier Almansa Sobrino fpga_power_domain_tree_desc[0] = 1U; 427ee4db6eSOliver Swede fpga_power_domain_tree_desc[1] = FPGA_MAX_CLUSTER_COUNT; 437ee4db6eSOliver Swede 44*727bbf68SJavier Almansa Sobrino for (i = 0U; i < FPGA_MAX_CLUSTER_COUNT; i++) { 45*727bbf68SJavier Almansa Sobrino fpga_power_domain_tree_desc[2 + i] = 46*727bbf68SJavier Almansa Sobrino (FPGA_MAX_CPUS_PER_CLUSTER * 47*727bbf68SJavier Almansa Sobrino FPGA_MAX_PE_PER_CPU); 48*727bbf68SJavier Almansa Sobrino } 497ee4db6eSOliver Swede } 507ee4db6eSOliver Swede 517ee4db6eSOliver Swede return fpga_power_domain_tree_desc; 52536d906aSOliver Swede } 53536d906aSOliver Swede plat_core_pos_by_mpidr(u_register_t mpidr)54536d906aSOliver Swedeint plat_core_pos_by_mpidr(u_register_t mpidr) 55536d906aSOliver Swede { 56*727bbf68SJavier Almansa Sobrino unsigned int core_pos; 577ee4db6eSOliver Swede 58*727bbf68SJavier Almansa Sobrino mpidr &= (MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT)); 597ee4db6eSOliver Swede mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK); 6053baf7f0SAndre Przywara 61*727bbf68SJavier Almansa Sobrino if ((MPIDR_AFFLVL2_VAL(mpidr) >= FPGA_MAX_CLUSTER_COUNT) || 62*727bbf68SJavier Almansa Sobrino (MPIDR_AFFLVL1_VAL(mpidr) >= FPGA_MAX_CPUS_PER_CLUSTER) || 63*727bbf68SJavier Almansa Sobrino (MPIDR_AFFLVL0_VAL(mpidr) >= FPGA_MAX_PE_PER_CPU)) { 64*727bbf68SJavier Almansa Sobrino ERROR ("Invalid mpidr: 0x%08x\n", (uint32_t)mpidr); 65*727bbf68SJavier Almansa Sobrino panic(); 6653baf7f0SAndre Przywara } 6753baf7f0SAndre Przywara 68*727bbf68SJavier Almansa Sobrino /* Calculate the core position, based on the maximum topology. */ 69*727bbf68SJavier Almansa Sobrino core_pos = plat_fpga_calc_core_pos(mpidr); 70*727bbf68SJavier Almansa Sobrino 71*727bbf68SJavier Almansa Sobrino /* Check whether this core is actually present. */ 72*727bbf68SJavier Almansa Sobrino if (fpga_valid_mpids[core_pos] != VALID_MPID) { 7353baf7f0SAndre Przywara return -1; 7453baf7f0SAndre Przywara } 7553baf7f0SAndre Przywara 76*727bbf68SJavier Almansa Sobrino return core_pos; 77536d906aSOliver Swede } 78