From efafbc898e101a48bb3cb635514d7ee30b4c7f41 Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Tue, 12 Aug 2014 08:42:28 +0100 Subject: 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 --- plat/juno/plat_pm.c | 40 +++++++++++++++++++++++++++++++++++++++- plat/juno/scpi.c | 14 ++++++++++++++ plat/juno/scpi.h | 8 ++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) (limited to 'plat') diff --git a/plat/juno/plat_pm.c b/plat/juno/plat_pm.c index 27a1227..74ce89f 100644 --- a/plat/juno/plat_pm.c +++ b/plat/juno/plat_pm.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -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 }; /******************************************************************************* diff --git a/plat/juno/scpi.c b/plat/juno/scpi.c index c1677aa..950c00b 100644 --- a/plat/juno/scpi.c +++ b/plat/juno/scpi.c @@ -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; +} diff --git a/plat/juno/scpi.h b/plat/juno/scpi.h index 1112980..8a5ef65 100644 --- a/plat/juno/scpi.h +++ b/plat/juno/scpi.h @@ -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__ */ -- cgit v1.2.3