Commit 0412c66a authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #259 from soby-mathew/sm/plat_max_afflvl

Export maximum affinity using PLATFORM_MAX_AFFLVL macro
parents f578d5e1 8c32bc26
...@@ -181,6 +181,17 @@ file is found in [plat/fvp/include/platform_def.h]. ...@@ -181,6 +181,17 @@ file is found in [plat/fvp/include/platform_def.h].
Defines the total number of nodes in the affinity heirarchy at all affinity Defines the total number of nodes in the affinity heirarchy at all affinity
levels used by the platform. levels used by the platform.
* **#define : PLATFORM_MAX_AFFLVL**
Defines the maximum affinity level that the power management operations
should apply to. ARMv8-A has support for 4 affinity levels. It is likely
that hardware will implement fewer affinity levels. This macro allows the
PSCI implementation to consider only those affinity levels in the system
that the platform implements. For example, the Base AEM FVP implements two
clusters with a configurable number of CPUs. It reports the maximum
affinity level as 1, resulting in PSCI power control up to the cluster
level.
* **#define : BL1_RO_BASE** * **#define : BL1_RO_BASE**
Defines the base address in secure ROM where BL1 originally lives. Must be Defines the base address in secure ROM where BL1 originally lives. Must be
...@@ -1131,25 +1142,6 @@ is missing but needs to be accounted for to reach this single CPU in the ...@@ -1131,25 +1142,6 @@ is missing but needs to be accounted for to reach this single CPU in the
topology tree. Hence it is marked as `PSCI_AFF_ABSENT`. topology tree. Hence it is marked as `PSCI_AFF_ABSENT`.
### Function : plat_get_max_afflvl() [mandatory]
Argument : void
Return : int
This function may execute with the MMU and data caches enabled if the platform
port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
called by the primary CPU.
This function is called by the PSCI implementation both during cold and warm
boot, to determine the maximum affinity level that the power management
operations should apply to. ARMv8-A has support for 4 affinity levels. It is
likely that hardware will implement fewer affinity levels. This function allows
the PSCI implementation to consider only those affinity levels in the system
that the platform implements. For example, the Base AEM FVP implements two
clusters with a configurable number of CPUs. It reports the maximum affinity
level as 1, resulting in PSCI power control up to the cluster level.
### Function : platform_setup_pm() [mandatory] ### Function : platform_setup_pm() [mandatory]
Argument : const plat_pm_ops ** Argument : const plat_pm_ops **
......
...@@ -177,7 +177,6 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type); ...@@ -177,7 +177,6 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type);
* Mandatory PSCI functions (BL3-1) * Mandatory PSCI functions (BL3-1)
******************************************************************************/ ******************************************************************************/
int platform_setup_pm(const struct plat_pm_ops **); int platform_setup_pm(const struct plat_pm_ops **);
int plat_get_max_afflvl(void);
unsigned int plat_get_aff_count(unsigned int, unsigned long); unsigned int plat_get_aff_count(unsigned int, unsigned long);
unsigned int plat_get_aff_state(unsigned int, unsigned long); unsigned int plat_get_aff_state(unsigned int, unsigned long);
......
...@@ -176,15 +176,6 @@ unsigned int plat_get_aff_state(unsigned int aff_lvl, ...@@ -176,15 +176,6 @@ unsigned int plat_get_aff_state(unsigned int aff_lvl,
return aff_state; return aff_state;
} }
/*******************************************************************************
* Handy optimization to prevent the psci implementation from traversing through
* affinity levels which are not present while detecting the platform topology.
******************************************************************************/
int plat_get_max_afflvl(void)
{
return MPIDR_AFFLVL1;
}
/******************************************************************************* /*******************************************************************************
* This function populates the FVP specific topology information depending upon * This function populates the FVP specific topology information depending upon
* the FVP flavour its running on. We construct all the mpidrs we can handle * the FVP flavour its running on. We construct all the mpidrs we can handle
......
...@@ -105,6 +105,7 @@ ...@@ -105,6 +105,7 @@
#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 #define PLATFORM_MAX_CPUS_PER_CLUSTER 4
#define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \ #define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT) PLATFORM_CORE_COUNT)
#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1
#define MAX_IO_DEVICES 3 #define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4 #define MAX_IO_HANDLES 4
......
...@@ -92,6 +92,7 @@ ...@@ -92,6 +92,7 @@
#define PLATFORM_CORE_COUNT 6 #define PLATFORM_CORE_COUNT 6
#define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \ #define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT) PLATFORM_CORE_COUNT)
#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1
#define MAX_IO_DEVICES 3 #define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4 #define MAX_IO_HANDLES 4
......
...@@ -157,7 +157,6 @@ void plat_gic_init(void); ...@@ -157,7 +157,6 @@ void plat_gic_init(void);
/* Declarations for plat_topology.c */ /* Declarations for plat_topology.c */
int plat_setup_topology(void); int plat_setup_topology(void);
int plat_get_max_afflvl(void);
unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr); unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr);
unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr); unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr);
......
...@@ -48,11 +48,6 @@ unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr) ...@@ -48,11 +48,6 @@ unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT; return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
} }
int plat_get_max_afflvl()
{
return MPIDR_AFFLVL1;
}
int plat_setup_topology() int plat_setup_topology()
{ {
/* Juno todo: Make topology configurable via SCC */ /* Juno todo: Make topology configurable via SCC */
......
...@@ -61,6 +61,13 @@ __attribute__ ((section("tzfw_coherent_mem"))) ...@@ -61,6 +61,13 @@ __attribute__ ((section("tzfw_coherent_mem")))
******************************************************************************/ ******************************************************************************/
const plat_pm_ops_t *psci_plat_pm_ops; const plat_pm_ops_t *psci_plat_pm_ops;
/*******************************************************************************
* Check that the maximum affinity level supported by the platform makes sense
* ****************************************************************************/
CASSERT(PLATFORM_MAX_AFFLVL <= MPIDR_MAX_AFFLVL && \
PLATFORM_MAX_AFFLVL >= MPIDR_AFFLVL0, \
assert_platform_max_afflvl_check);
/******************************************************************************* /*******************************************************************************
* This function is passed an array of pointers to affinity level nodes in the * This function is passed an array of pointers to affinity level nodes in the
* topology tree for an mpidr. It iterates through the nodes to find the highest * topology tree for an mpidr. It iterates through the nodes to find the highest
...@@ -150,29 +157,15 @@ int get_power_on_target_afflvl() ...@@ -150,29 +157,15 @@ int get_power_on_target_afflvl()
/* /*
* Assume that this cpu was suspended and retrieve its target affinity * Assume that this cpu was suspended and retrieve its target affinity
* level. If it is invalid then it could only have been turned off * level. If it is invalid then it could only have been turned off
* earlier. get_max_afflvl() will return the highest affinity level a * earlier. PLATFORM_MAX_AFFLVL will be the highest affinity level a
* cpu can be turned off to. * cpu can be turned off to.
*/ */
afflvl = psci_get_suspend_afflvl(); afflvl = psci_get_suspend_afflvl();
if (afflvl == PSCI_INVALID_DATA) if (afflvl == PSCI_INVALID_DATA)
afflvl = get_max_afflvl(); afflvl = PLATFORM_MAX_AFFLVL;
return afflvl; return afflvl;
} }
/*******************************************************************************
* Simple routine to retrieve the maximum affinity level supported by the
* platform and check that it makes sense.
******************************************************************************/
int get_max_afflvl(void)
{
int aff_lvl;
aff_lvl = plat_get_max_afflvl();
assert(aff_lvl <= MPIDR_MAX_AFFLVL && aff_lvl >= MPIDR_AFFLVL0);
return aff_lvl;
}
/******************************************************************************* /*******************************************************************************
* Simple routine to set the id of an affinity instance at a given level in the * Simple routine to set the id of an affinity instance at a given level in the
* mpidr. * mpidr.
...@@ -204,7 +197,7 @@ unsigned long mpidr_set_aff_inst(unsigned long mpidr, ...@@ -204,7 +197,7 @@ unsigned long mpidr_set_aff_inst(unsigned long mpidr,
int psci_check_afflvl_range(int start_afflvl, int end_afflvl) int psci_check_afflvl_range(int start_afflvl, int end_afflvl)
{ {
/* Sanity check the parameters passed */ /* Sanity check the parameters passed */
if (end_afflvl > get_max_afflvl()) if (end_afflvl > PLATFORM_MAX_AFFLVL)
return PSCI_E_INVALID_PARAMS; return PSCI_E_INVALID_PARAMS;
if (start_afflvl < MPIDR_AFFLVL0) if (start_afflvl < MPIDR_AFFLVL0)
......
...@@ -78,7 +78,7 @@ int psci_cpu_on(unsigned long target_cpu, ...@@ -78,7 +78,7 @@ int psci_cpu_on(unsigned long target_cpu,
* levels need to be turned on * levels need to be turned on
*/ */
start_afflvl = MPIDR_AFFLVL0; start_afflvl = MPIDR_AFFLVL0;
end_afflvl = get_max_afflvl(); end_afflvl = PLATFORM_MAX_AFFLVL;
rc = psci_afflvl_on(target_cpu, rc = psci_afflvl_on(target_cpu,
&ep, &ep,
start_afflvl, start_afflvl,
...@@ -106,7 +106,7 @@ int psci_cpu_suspend(unsigned int power_state, ...@@ -106,7 +106,7 @@ int psci_cpu_suspend(unsigned int power_state,
/* Sanity check the requested state */ /* Sanity check the requested state */
target_afflvl = psci_get_pstate_afflvl(power_state); target_afflvl = psci_get_pstate_afflvl(power_state);
if (target_afflvl > get_max_afflvl()) if (target_afflvl > PLATFORM_MAX_AFFLVL)
return PSCI_E_INVALID_PARAMS; return PSCI_E_INVALID_PARAMS;
/* Validate the power_state using platform pm_ops */ /* Validate the power_state using platform pm_ops */
...@@ -170,7 +170,7 @@ int psci_cpu_suspend(unsigned int power_state, ...@@ -170,7 +170,7 @@ int psci_cpu_suspend(unsigned int power_state,
int psci_cpu_off(void) int psci_cpu_off(void)
{ {
int rc; int rc;
int target_afflvl = get_max_afflvl(); int target_afflvl = PLATFORM_MAX_AFFLVL;
/* /*
* Traverse from the highest to the lowest affinity level. When the * Traverse from the highest to the lowest affinity level. When the
...@@ -196,7 +196,7 @@ int psci_affinity_info(unsigned long target_affinity, ...@@ -196,7 +196,7 @@ int psci_affinity_info(unsigned long target_affinity,
unsigned int aff_state; unsigned int aff_state;
aff_map_node_t *node; aff_map_node_t *node;
if (lowest_affinity_level > get_max_afflvl()) if (lowest_affinity_level > PLATFORM_MAX_AFFLVL)
return rc; return rc;
node = psci_get_aff_map_node(target_affinity, lowest_affinity_level); node = psci_get_aff_map_node(target_affinity, lowest_affinity_level);
......
...@@ -113,7 +113,6 @@ extern const spd_pm_ops_t *psci_spd_pm; ...@@ -113,7 +113,6 @@ extern const spd_pm_ops_t *psci_spd_pm;
* Function prototypes * Function prototypes
******************************************************************************/ ******************************************************************************/
/* Private exported functions from psci_common.c */ /* Private exported functions from psci_common.c */
int get_max_afflvl(void);
unsigned short psci_get_state(aff_map_node_t *node); unsigned short psci_get_state(aff_map_node_t *node);
unsigned short psci_get_phys_state(aff_map_node_t *node); unsigned short psci_get_phys_state(aff_map_node_t *node);
void psci_set_state(aff_map_node_t *node, unsigned short state); void psci_set_state(aff_map_node_t *node, unsigned short state);
......
...@@ -107,7 +107,7 @@ aff_map_node_t *psci_get_aff_map_node(unsigned long mpidr, int aff_lvl) ...@@ -107,7 +107,7 @@ aff_map_node_t *psci_get_aff_map_node(unsigned long mpidr, int aff_lvl)
{ {
int rc; int rc;
if (aff_lvl > get_max_afflvl()) if (aff_lvl > PLATFORM_MAX_AFFLVL)
return NULL; return NULL;
/* Right shift the mpidr to the required affinity level */ /* Right shift the mpidr to the required affinity level */
...@@ -320,7 +320,7 @@ int32_t psci_setup(void) ...@@ -320,7 +320,7 @@ int32_t psci_setup(void)
psci_plat_pm_ops = NULL; psci_plat_pm_ops = NULL;
/* Find out the maximum affinity level that the platform implements */ /* Find out the maximum affinity level that the platform implements */
max_afflvl = get_max_afflvl(); max_afflvl = PLATFORM_MAX_AFFLVL;
assert(max_afflvl <= MPIDR_MAX_AFFLVL); assert(max_afflvl <= MPIDR_MAX_AFFLVL);
/* /*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment