diff options
| -rw-r--r-- | include/plat/arm/css/common/css_def.h | 10 | ||||
| -rw-r--r-- | include/plat/arm/css/common/css_pm.h | 1 | ||||
| -rw-r--r-- | plat/arm/board/juno/juno_pm.c | 5 | ||||
| -rw-r--r-- | plat/arm/css/common/css_pm.c | 40 | 
4 files changed, 53 insertions, 3 deletions
| diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 636daf29..173de1b4 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -148,5 +148,15 @@  /* Trusted mailbox base address common to all CSS */  #define PLAT_ARM_TRUSTED_MAILBOX_BASE	ARM_TRUSTED_SRAM_BASE +/* + * Parsing of CPU and Cluster states, as returned by 'Get CSS Power State' SCP + * command + */ +#define CSS_CLUSTER_PWR_STATE_ON	0 +#define CSS_CLUSTER_PWR_STATE_OFF	3 + +#define CSS_CPU_PWR_STATE_ON		1 +#define CSS_CPU_PWR_STATE_OFF		0 +#define CSS_CPU_PWR_STATE(state, n)	(((state) >> (n)) & 1)  #endif /* __CSS_DEF_H__ */ diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h index ea6a5d25..4a6ca816 100644 --- a/include/plat/arm/css/common/css_pm.h +++ b/include/plat/arm/css/common/css_pm.h @@ -45,5 +45,6 @@ void __dead2 css_system_off(void);  void __dead2 css_system_reset(void);  void css_cpu_standby(plat_local_state_t cpu_state);  void css_get_sys_suspend_power_state(psci_power_state_t *req_state); +int css_node_hw_state(u_register_t mpidr, unsigned int power_level);  #endif /* __CSS_PM_H__ */ diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c index cbf994a4..c355d94d 100644 --- a/plat/arm/board/juno/juno_pm.c +++ b/plat/arm/board/juno/juno_pm.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.   *   * Redistribution and use in source and binary forms, with or without   * modification, are permitted provided that the following conditions are met: @@ -88,5 +88,6 @@ const plat_psci_ops_t plat_arm_psci_pm_ops = {  	.validate_power_state		= juno_validate_power_state,  	.validate_ns_entrypoint		= arm_validate_ns_entrypoint,  	.get_sys_suspend_power_state	= css_get_sys_suspend_power_state, -	.translate_power_state_by_mpidr = juno_translate_power_state_by_mpidr +	.translate_power_state_by_mpidr = juno_translate_power_state_by_mpidr, +	.get_node_hw_state		= css_node_hw_state  }; diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index 801d9375..7607f617 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -299,6 +299,43 @@ void css_get_sys_suspend_power_state(psci_power_state_t *req_state)  }  /******************************************************************************* + * Handler to query CPU/cluster power states from SCP + ******************************************************************************/ +int css_node_hw_state(u_register_t mpidr, unsigned int power_level) +{ +	int rc, element; +	unsigned int cpu_state, cluster_state; + +	/* +	 * The format of 'power_level' is implementation-defined, but 0 must +	 * mean a CPU. We also allow 1 to denote the cluster +	 */ +	if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1) +		return PSCI_E_INVALID_PARAMS; + +	/* Query SCP */ +	rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state); +	if (rc != 0) +		return PSCI_E_INVALID_PARAMS; + +	/* Map power states of CPU and cluster to expected PSCI return codes */ +	if (power_level == ARM_PWR_LVL0) { +		/* +		 * The CPU state returned by SCP is an 8-bit bit mask +		 * corresponding to each CPU in the cluster +		 */ +		element = mpidr & MPIDR_AFFLVL_MASK; +		return CSS_CPU_PWR_STATE(cpu_state, element) == +			CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF; +	} else { +		assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON || +				cluster_state == CSS_CLUSTER_PWR_STATE_OFF); +		return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON : +			HW_OFF; +	} +} + +/*******************************************************************************   * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard   * platform will take care of registering the handlers with PSCI.   ******************************************************************************/ @@ -312,5 +349,6 @@ const plat_psci_ops_t plat_arm_psci_pm_ops = {  	.system_off		= css_system_off,  	.system_reset		= css_system_reset,  	.validate_power_state	= arm_validate_power_state, -	.validate_ns_entrypoint = arm_validate_ns_entrypoint +	.validate_ns_entrypoint = arm_validate_ns_entrypoint, +	.get_node_hw_state	= css_node_hw_state  }; | 
