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