diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c index 942ef01cc..39550858a 100644 --- a/plat/xilinx/versal/plat_psci.c +++ b/plat/xilinx/versal/plat_psci.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "pm_api_sys.h" #include "pm_client.h" @@ -114,6 +115,34 @@ void versal_pwr_domain_on_finish(const psci_power_state_t *target_state) plat_versal_gic_cpuif_enable(); } +/** + * versal_system_off() - This function sends the system off request + * to firmware. This function does not return. + */ +static void __dead2 versal_system_off(void) +{ + /* Send the power down request to the PMC */ + pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN, + pm_get_shutdown_scope()); + + while (1) + wfi(); +} + +/** + * versal_system_reset() - This function sends the reset request + * to firmware for the system to reset. This function does not return. + */ +static void __dead2 versal_system_reset(void) +{ + /* Send the system reset request to the PMC */ + pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET, + pm_get_shutdown_scope()); + + while (1) + wfi(); +} + /** * versal_pwr_domain_off() - This function performs actions to turn off core * @@ -190,6 +219,8 @@ static const struct plat_psci_ops versal_nopmc_psci_ops = { .pwr_domain_on_finish = versal_pwr_domain_on_finish, .pwr_domain_suspend = versal_pwr_domain_suspend, .pwr_domain_suspend_finish = versal_pwr_domain_suspend_finish, + .system_off = versal_system_off, + .system_reset = versal_system_reset, .validate_power_state = versal_validate_power_state, .get_sys_suspend_power_state = versal_get_sys_suspend_power_state, }; diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index 5f3e30fff..99897ba9d 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -21,6 +21,19 @@ #define LIBPM_MODULE_ID 0x2 #define LOADER_MODULE_ID 0x7 +/* default shutdown/reboot scope is system(2) */ +static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM; + +/** + * pm_get_shutdown_scope() - Get the currently set shutdown scope + * + * @return Shutdown scope value + */ +unsigned int pm_get_shutdown_scope(void) +{ + return pm_shutdown_scope; +} + /** * Assigning of argument values into array elements. */ @@ -625,7 +638,7 @@ enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack) /** * pm_system_shutdown() - PM call to request a system shutdown or restart - * @type Shutdown or restart? 0=shutdown, 1=restart + * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system * * @return Returns status, either success or error+reason @@ -634,6 +647,12 @@ enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype) { uint32_t payload[PAYLOAD_ARG_CNT]; + if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) { + /* Setting scope for subsequent PSCI reboot or shutdown */ + pm_shutdown_scope = subtype; + return PM_RET_SUCCESS; + } + /* Send request to the PMC */ PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_SYSTEM_SHUTDOWN, type, subtype); diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h index 16722e72b..b1ad3f276 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.h +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -63,4 +63,6 @@ enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id, uint32_t arg1, uint32_t arg2, uint32_t *value); enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t *data); +unsigned int pm_get_shutdown_scope(void); + #endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h index f090db538..626fa3916 100644 --- a/plat/xilinx/versal/pm_service/pm_defs.h +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -77,6 +77,15 @@ /* Fractional data portion for PLL */ #define PM_PLL_PARAM_DATA 2 +/* System shutdown macros */ +#define XPM_SHUTDOWN_TYPE_SHUTDOWN 0U +#define XPM_SHUTDOWN_TYPE_RESET 1U +#define XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY 2U + +#define XPM_SHUTDOWN_SUBTYPE_RST_SUBSYSTEM 0U +#define XPM_SHUTDOWN_SUBTYPE_RST_PS_ONLY 1U +#define XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM 2U + /********************************************************************* * Enum definitions ********************************************************************/