plat/arm/fvp: populate pwr domain descriptor dynamically

The motivation behind this patch and following patches is to extract
information about the platform in runtime rather than depending on
compile time macros such as FVP_CLUSTER_COUNT. This partially enables
us to use a single binary for a family of platforms which all have
similar hardware capabilities but differ in configurations.

we populate the data structure describing the power domain hierarchy
of the platform dynamically by querying the number of clusters and cpus
using fconf getter APIs. Compile time macro such as FVP_CLUSTER_COUNT
is still needed as it determines the size of related data structures.

Note that the cpu-map node in HW_CONFIG dts represents a logical
hierarchy of power domains of CPU. However, in reality, the power
domains may not have been physically built in such hierarchy.

Change-Id: Ibcbb5ca7b2c969f8ad03ab2eab289725245af7a9
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
This commit is contained in:
Madhukar Pappireddy 2020-02-21 14:01:44 -06:00
parent 4682461ded
commit 6138ffbc12
1 changed files with 36 additions and 10 deletions

View File

@ -1,18 +1,21 @@
/*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
#include <assert.h>
#include <arch.h>
#include <drivers/arm/fvp/fvp_pwrc.h>
#include <fconf_hw_config_getter.h>
#include <lib/cassert.h>
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
/* The FVP power domain tree descriptor */
static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2];
@ -21,24 +24,47 @@ CASSERT(((FVP_CLUSTER_COUNT > 0) && (FVP_CLUSTER_COUNT <= 256)),
assert_invalid_fvp_cluster_count);
/*******************************************************************************
* This function dynamically constructs the topology according to
* FVP_CLUSTER_COUNT and returns it.
* This function dynamically constructs the topology according to cpu-map node
* in HW_CONFIG dtb and returns it.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
int i;
unsigned int i;
uint32_t cluster_count, cpus_per_cluster;
/*
* fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
* BL2_AT_EL3 systems.
*/
#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3
cluster_count = FVP_CLUSTER_COUNT;
cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
#else
cluster_count = FCONF_GET_PROPERTY(hw_config, topology, plat_cluster_count);
cpus_per_cluster = FCONF_GET_PROPERTY(hw_config, topology, cluster_cpu_count);
/* Several FVP Models use the same blanket dts. Ex: FVP_Base_Cortex-A65x4
* and FVP_Base_Cortex-A65AEx8 both use same dts but have different number of
* CPUs in the cluster, as reflected by build flags FVP_MAX_CPUS_PER_CLUSTER.
* Take the minimum of two to ensure PSCI functions do not exceed the size of
* the PSCI data structures allocated at build time.
*/
cpus_per_cluster = MIN(cpus_per_cluster,
(uint32_t)(FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU));
#endif
assert(cluster_count > 0U);
assert(cpus_per_cluster > 0U);
/*
* The highest level is the system level. The next level is constituted
* by clusters and then cores in clusters.
*/
fvp_power_domain_tree_desc[0] = 1;
fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT;
for (i = 0; i < FVP_CLUSTER_COUNT; i++)
fvp_power_domain_tree_desc[i + 2] =
FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
fvp_power_domain_tree_desc[1] = (unsigned char)cluster_count;
for (i = 0; i < cluster_count; i++)
fvp_power_domain_tree_desc[i + 2] = (unsigned char)cpus_per_cluster;
return fvp_power_domain_tree_desc;
}