Juno: Implement PSCI SYSTEM_OFF and SYSTEM_RESET APIs

This patch adds the Juno platform specific handlers for PSCI
SYSTEM_OFF and SYSTEM_RESET operations.

Change-Id: Ie389adead533ec2314af44d721b4d0f306147c7d
This commit is contained in:
Juan Castillo 2014-08-12 08:42:28 +01:00 committed by Soby Mathew
parent edfda10a6b
commit efafbc898e
3 changed files with 61 additions and 1 deletions

View File

@ -30,6 +30,7 @@
#include <assert.h>
#include <arch_helpers.h>
#include <debug.h>
#include <cci400.h>
#include <errno.h>
#include <platform.h>
@ -238,6 +239,41 @@ static int32_t juno_affinst_suspend_finish(uint64_t mpidr,
return juno_affinst_on_finish(mpidr, afflvl, state);
}
/*******************************************************************************
* Juno handlers to shutdown/reboot the system
******************************************************************************/
static void __dead2 juno_system_off(void)
{
uint32_t response;
/* Send the power down request to the SCP */
response = scpi_sys_power_state(scpi_system_shutdown);
if (response != SCP_OK) {
ERROR("Juno System Off: SCP error %u.\n", response);
panic();
}
wfi();
ERROR("Juno System Off: operation not handled.\n");
panic();
}
static void __dead2 juno_system_reset(void)
{
uint32_t response;
/* Send the system reset request to the SCP */
response = scpi_sys_power_state(scpi_system_reboot);
if (response != SCP_OK) {
ERROR("Juno System Reset: SCP error %u.\n", response);
panic();
}
wfi();
ERROR("Juno System Reset: operation not handled.\n");
panic();
}
/*******************************************************************************
* Export the platform handlers to enable psci to invoke them
******************************************************************************/
@ -246,7 +282,9 @@ static const plat_pm_ops_t juno_ops = {
.affinst_on_finish = juno_affinst_on_finish,
.affinst_off = juno_affinst_off,
.affinst_suspend = juno_affinst_suspend,
.affinst_suspend_finish = juno_affinst_suspend_finish
.affinst_suspend_finish = juno_affinst_suspend_finish,
.system_off = juno_system_off,
.system_reset = juno_system_reset
};
/*******************************************************************************

View File

@ -124,3 +124,17 @@ void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
state |= css_state << 16;
scpi_secure_send32(SCPI_CMD_SET_CSS_POWER_STATE, state);
}
uint32_t scpi_sys_power_state(scpi_system_state_t system_state)
{
uint32_t *response;
size_t size;
uint8_t state = system_state & 0xff;
/* Send the command */
*(__typeof__(state) *)scpi_secure_message_start() = state;
scpi_secure_message_send(SCPI_CMD_SYS_POWER_STATE, sizeof(state));
scpi_secure_message_receive((void *)&response, &size);
scpi_secure_message_end();
return *response;
}

View File

@ -59,6 +59,7 @@ typedef uint32_t scpi_status_t;
typedef enum {
SCPI_CMD_SCP_READY = 0x01,
SCPI_CMD_SET_CSS_POWER_STATE = 0x04,
SCPI_CMD_SYS_POWER_STATE = 0x08
} scpi_command_t;
typedef enum {
@ -67,8 +68,15 @@ typedef enum {
scpi_power_off = 3,
} scpi_power_state_t;
typedef enum {
scpi_system_shutdown = 0,
scpi_system_reboot = 1,
scpi_system_reset = 2
} scpi_system_state_t;
extern int scpi_wait_ready(void);
extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
scpi_power_state_t cluster_state, scpi_power_state_t css_state);
uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
#endif /* __SCPI_H__ */