diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c index 942ef01..3955085 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" @@ -115,6 +116,34 @@ } /** + * 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 * * @target_state Targated state @@ -190,6 +219,8 @@ .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 5f3e30f..99897ba 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 @@ /** * 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 @@ { 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 16722e7..b1ad3f2 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 @@ 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 f090db5..626fa39 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 ********************************************************************/