1*a2847172SGrzegorz Jaszczyk /* 2*a2847172SGrzegorz Jaszczyk * Copyright (C) 2018 Marvell International Ltd. 3*a2847172SGrzegorz Jaszczyk * 4*a2847172SGrzegorz Jaszczyk * SPDX-License-Identifier: BSD-3-Clause 5*a2847172SGrzegorz Jaszczyk * https://spdx.org/licenses 6*a2847172SGrzegorz Jaszczyk */ 7*a2847172SGrzegorz Jaszczyk 8*a2847172SGrzegorz Jaszczyk #include <plat_marvell.h> 9*a2847172SGrzegorz Jaszczyk 10*a2847172SGrzegorz Jaszczyk /* The power domain tree descriptor */ 11*a2847172SGrzegorz Jaszczyk unsigned char marvell_power_domain_tree_desc[PLAT_MARVELL_CLUSTER_COUNT + 1]; 12*a2847172SGrzegorz Jaszczyk 13*a2847172SGrzegorz Jaszczyk /***************************************************************************** 14*a2847172SGrzegorz Jaszczyk * This function dynamically constructs the topology according to 15*a2847172SGrzegorz Jaszczyk * PLAT_MARVELL_CLUSTER_COUNT and returns it. 16*a2847172SGrzegorz Jaszczyk ***************************************************************************** 17*a2847172SGrzegorz Jaszczyk */ 18*a2847172SGrzegorz Jaszczyk const unsigned char *plat_get_power_domain_tree_desc(void) 19*a2847172SGrzegorz Jaszczyk { 20*a2847172SGrzegorz Jaszczyk int i; 21*a2847172SGrzegorz Jaszczyk 22*a2847172SGrzegorz Jaszczyk /* 23*a2847172SGrzegorz Jaszczyk * The power domain tree does not have a single system level power 24*a2847172SGrzegorz Jaszczyk * domain i.e. a single root node. The first entry in the power domain 25*a2847172SGrzegorz Jaszczyk * descriptor specifies the number of power domains at the highest power 26*a2847172SGrzegorz Jaszczyk * level. 27*a2847172SGrzegorz Jaszczyk * For Marvell Platform this is the number of cluster power domains. 28*a2847172SGrzegorz Jaszczyk */ 29*a2847172SGrzegorz Jaszczyk marvell_power_domain_tree_desc[0] = PLAT_MARVELL_CLUSTER_COUNT; 30*a2847172SGrzegorz Jaszczyk 31*a2847172SGrzegorz Jaszczyk for (i = 0; i < PLAT_MARVELL_CLUSTER_COUNT; i++) 32*a2847172SGrzegorz Jaszczyk marvell_power_domain_tree_desc[i + 1] = 33*a2847172SGrzegorz Jaszczyk PLAT_MARVELL_CLUSTER_CORE_COUNT; 34*a2847172SGrzegorz Jaszczyk 35*a2847172SGrzegorz Jaszczyk return marvell_power_domain_tree_desc; 36*a2847172SGrzegorz Jaszczyk } 37*a2847172SGrzegorz Jaszczyk 38*a2847172SGrzegorz Jaszczyk /***************************************************************************** 39*a2847172SGrzegorz Jaszczyk * This function validates an MPIDR by checking whether it falls within the 40*a2847172SGrzegorz Jaszczyk * acceptable bounds. An error code (-1) is returned if an incorrect mpidr 41*a2847172SGrzegorz Jaszczyk * is passed. 42*a2847172SGrzegorz Jaszczyk ***************************************************************************** 43*a2847172SGrzegorz Jaszczyk */ 44*a2847172SGrzegorz Jaszczyk int marvell_check_mpidr(u_register_t mpidr) 45*a2847172SGrzegorz Jaszczyk { 46*a2847172SGrzegorz Jaszczyk unsigned int nb_id, cluster_id, cpu_id; 47*a2847172SGrzegorz Jaszczyk 48*a2847172SGrzegorz Jaszczyk mpidr &= MPIDR_AFFINITY_MASK; 49*a2847172SGrzegorz Jaszczyk 50*a2847172SGrzegorz Jaszczyk if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK | 51*a2847172SGrzegorz Jaszczyk MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)) 52*a2847172SGrzegorz Jaszczyk return -1; 53*a2847172SGrzegorz Jaszczyk 54*a2847172SGrzegorz Jaszczyk /* Get north bridge ID */ 55*a2847172SGrzegorz Jaszczyk nb_id = MPIDR_AFFLVL3_VAL(mpidr); 56*a2847172SGrzegorz Jaszczyk cluster_id = MPIDR_AFFLVL1_VAL(mpidr); 57*a2847172SGrzegorz Jaszczyk cpu_id = MPIDR_AFFLVL0_VAL(mpidr); 58*a2847172SGrzegorz Jaszczyk 59*a2847172SGrzegorz Jaszczyk if (nb_id >= PLAT_MARVELL_CLUSTER_COUNT) 60*a2847172SGrzegorz Jaszczyk return -1; 61*a2847172SGrzegorz Jaszczyk 62*a2847172SGrzegorz Jaszczyk if (cluster_id >= PLAT_MARVELL_CLUSTER_COUNT) 63*a2847172SGrzegorz Jaszczyk return -1; 64*a2847172SGrzegorz Jaszczyk 65*a2847172SGrzegorz Jaszczyk if (cpu_id >= PLAT_MARVELL_CLUSTER_CORE_COUNT) 66*a2847172SGrzegorz Jaszczyk return -1; 67*a2847172SGrzegorz Jaszczyk 68*a2847172SGrzegorz Jaszczyk return 0; 69*a2847172SGrzegorz Jaszczyk } 70*a2847172SGrzegorz Jaszczyk 71*a2847172SGrzegorz Jaszczyk /***************************************************************************** 72*a2847172SGrzegorz Jaszczyk * This function implements a part of the critical interface between the PSCI 73*a2847172SGrzegorz Jaszczyk * generic layer and the platform that allows the former to query the platform 74*a2847172SGrzegorz Jaszczyk * to convert an MPIDR to a unique linear index. An error code (-1) is returned 75*a2847172SGrzegorz Jaszczyk * in case the MPIDR is invalid. 76*a2847172SGrzegorz Jaszczyk ***************************************************************************** 77*a2847172SGrzegorz Jaszczyk */ 78*a2847172SGrzegorz Jaszczyk int plat_core_pos_by_mpidr(u_register_t mpidr) 79*a2847172SGrzegorz Jaszczyk { 80*a2847172SGrzegorz Jaszczyk if (marvell_check_mpidr(mpidr) == -1) 81*a2847172SGrzegorz Jaszczyk return -1; 82*a2847172SGrzegorz Jaszczyk 83*a2847172SGrzegorz Jaszczyk return plat_marvell_calc_core_pos(mpidr); 84*a2847172SGrzegorz Jaszczyk } 85