xref: /rk3399_ARM-atf/plat/arm/board/fvp/fvp_topology.c (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
13fc4124cSDan Handley /*
20108047aSSoby Mathew  * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
33fc4124cSDan Handley  *
4*82cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
53fc4124cSDan Handley  */
63fc4124cSDan Handley 
73fc4124cSDan Handley #include <arch.h>
80108047aSSoby Mathew #include <cassert.h>
938dce70fSSoby Mathew #include <plat_arm.h>
103fc4124cSDan Handley #include <platform_def.h>
113fc4124cSDan Handley #include "drivers/pwrc/fvp_pwrc.h"
123fc4124cSDan Handley 
130108047aSSoby Mathew /* The FVP power domain tree descriptor */
140108047aSSoby Mathew unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 1];
150108047aSSoby Mathew 
160108047aSSoby Mathew 
170108047aSSoby Mathew CASSERT(FVP_CLUSTER_COUNT && FVP_CLUSTER_COUNT <= 256, assert_invalid_fvp_cluster_count);
180108047aSSoby Mathew 
190108047aSSoby Mathew /*******************************************************************************
200108047aSSoby Mathew  * This function dynamically constructs the topology according to
210108047aSSoby Mathew  * FVP_CLUSTER_COUNT and returns it.
220108047aSSoby Mathew  ******************************************************************************/
230108047aSSoby Mathew const unsigned char *plat_get_power_domain_tree_desc(void)
240108047aSSoby Mathew {
250108047aSSoby Mathew 	int i;
260108047aSSoby Mathew 
2738dce70fSSoby Mathew 	/*
2838dce70fSSoby Mathew 	 * The FVP power domain tree does not have a single system level power domain
2938dce70fSSoby Mathew 	 * i.e. a single root node. The first entry in the power domain descriptor
3038dce70fSSoby Mathew 	 * specifies the number of power domains at the highest power level. For the FVP
310108047aSSoby Mathew 	 * this is the number of cluster power domains.
3238dce70fSSoby Mathew 	 */
330108047aSSoby Mathew 	fvp_power_domain_tree_desc[0] = FVP_CLUSTER_COUNT;
343fc4124cSDan Handley 
350108047aSSoby Mathew 	for (i = 0; i < FVP_CLUSTER_COUNT; i++)
360108047aSSoby Mathew 		fvp_power_domain_tree_desc[i + 1] = FVP_MAX_CPUS_PER_CLUSTER;
370108047aSSoby Mathew 
380108047aSSoby Mathew 	return fvp_power_domain_tree_desc;
390108047aSSoby Mathew }
400108047aSSoby Mathew 
410108047aSSoby Mathew /*******************************************************************************
420108047aSSoby Mathew  * This function returns the core count within the cluster corresponding to
430108047aSSoby Mathew  * `mpidr`.
440108047aSSoby Mathew  ******************************************************************************/
450108047aSSoby Mathew unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
460108047aSSoby Mathew {
470108047aSSoby Mathew 	return FVP_MAX_CPUS_PER_CLUSTER;
480108047aSSoby Mathew }
493fc4124cSDan Handley 
503fc4124cSDan Handley /*******************************************************************************
513fc4124cSDan Handley  * This function implements a part of the critical interface between the psci
5238dce70fSSoby Mathew  * generic layer and the platform that allows the former to query the platform
5338dce70fSSoby Mathew  * to convert an MPIDR to a unique linear index. An error code (-1) is returned
5438dce70fSSoby Mathew  * in case the MPIDR is invalid.
553fc4124cSDan Handley  ******************************************************************************/
5638dce70fSSoby Mathew int plat_core_pos_by_mpidr(u_register_t mpidr)
573fc4124cSDan Handley {
5838dce70fSSoby Mathew 	if (arm_check_mpidr(mpidr) == -1)
5938dce70fSSoby Mathew 		return -1;
603fc4124cSDan Handley 
6138dce70fSSoby Mathew 	if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID)
6238dce70fSSoby Mathew 		return -1;
633fc4124cSDan Handley 
6438dce70fSSoby Mathew 	return plat_arm_calc_core_pos(mpidr);
653fc4124cSDan Handley }
66