Merge "feat(ti): implement DM_MANAGED suspend" into integration

This commit is contained in:
Madhukar Pappireddy 2024-11-01 05:20:32 +01:00 committed by TrustedFirmware Code Review
commit 58b25570c9
4 changed files with 94 additions and 2 deletions

View file

@ -1740,3 +1740,41 @@ int ti_sci_enter_sleep(uint8_t proc_id,
return 0;
}
/**
* ti_sci_lpm_get_next_sys_mode() - Get next LPM system mode
*
* @next_mode: pointer to a variable that will store the next mode
*
* Return: 0 if all goes well, else appropriate error message
*/
int ti_sci_lpm_get_next_sys_mode(uint8_t *next_mode)
{
struct ti_sci_msg_req_lpm_get_next_sys_mode req;
struct ti_sci_msg_resp_lpm_get_next_sys_mode resp;
struct ti_sci_xfer xfer;
int ret;
if (next_mode == NULL) {
return -EINVAL;
}
ret = ti_sci_setup_one_xfer(TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE, 0,
&req, sizeof(req),
&resp, sizeof(resp),
&xfer);
if (ret != 0) {
ERROR("Message alloc failed (%d)\n", ret);
return ret;
}
ret = ti_sci_do_xfer(&xfer);
if (ret != 0) {
ERROR("Transfer send failed (%d)\n", ret);
return ret;
}
*next_mode = resp.mode;
return 0;
}

View file

@ -252,6 +252,11 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id,
* @mode: Low power mode to enter.
* @core_resume_addr: Address that core should be resumed from
* after low power transition.
* - ti_sci_lpm_get_next_sys_mode - Get next LPM system mode
*
* @next_mode: pointer to a variable that will store the next mode
*
* Return: 0 if all goes well, else appropriate error message
*
* NOTE: for all these functions, the following are generic in nature:
* Returns 0 for successful request, else returns corresponding error message.
@ -259,5 +264,6 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id,
int ti_sci_enter_sleep(uint8_t proc_id,
uint8_t mode,
uint64_t core_resume_addr);
int ti_sci_lpm_get_next_sys_mode(uint8_t *next_mode);
#endif /* TI_SCI_H */

View file

@ -31,6 +31,7 @@
/* Low Power Mode Requests */
#define TI_SCI_MSG_ENTER_SLEEP 0x0301
#define TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE 0x030d
/* Clock requests */
#define TI_SCI_MSG_SET_CLOCK_STATE 0x0100
@ -133,6 +134,7 @@ struct ti_sci_msg_req_reboot {
* MSG_FLAG_CAPS_LPM_MCU_ONLY: MCU only LPM
* MSG_FLAG_CAPS_LPM_STANDBY: Standby LPM
* MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM
* MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM
*
* Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
* providing currently available SOC/firmware capabilities. SoC that don't
@ -145,6 +147,7 @@ struct ti_sci_msg_resp_query_fw_caps {
#define MSG_FLAG_CAPS_LPM_MCU_ONLY TI_SCI_MSG_FLAG(2)
#define MSG_FLAG_CAPS_LPM_STANDBY TI_SCI_MSG_FLAG(3)
#define MSG_FLAG_CAPS_LPM_PARTIAL_IO TI_SCI_MSG_FLAG(4)
#define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5)
uint64_t fw_caps;
} __packed;
@ -764,10 +767,35 @@ struct ti_sci_msg_req_wait_proc_boot_status {
*/
struct ti_sci_msg_req_enter_sleep {
struct ti_sci_msg_hdr hdr;
#define MSG_VALUE_SLEEP_MODE_DEEP_SLEEP 0x0
uint8_t mode;
uint8_t processor_id;
uint32_t core_resume_lo;
uint32_t core_resume_hi;
} __packed;
/**
* struct ti_sci_msg_req_lpm_get_next_sys_mode - Request for TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE.
*
* @hdr Generic Header
*
* This message is used to enquire DM for selected system wide low power mode.
*/
struct ti_sci_msg_req_lpm_get_next_sys_mode {
struct ti_sci_msg_hdr hdr;
} __packed;
/**
* struct ti_sci_msg_resp_lpm_get_next_sys_mode - Response for TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE.
*
* @hdr Generic Header
* @mode The selected system wide low power mode.
*
* Note: If the mode selection is not yet locked, this API returns "not selected" mode.
*/
struct ti_sci_msg_resp_lpm_get_next_sys_mode {
struct ti_sci_msg_hdr hdr;
uint8_t mode;
} __packed;
#endif /* TI_SCI_PROTOCOL_H */

View file

@ -234,7 +234,7 @@ static int k3_validate_power_state(unsigned int power_state,
return PSCI_E_SUCCESS;
}
static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
static void k3_pwr_domain_suspend_to_mode(const psci_power_state_t *target_state, uint8_t mode)
{
unsigned int core, proc_id;
@ -247,7 +247,25 @@ static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
k3_pwr_domain_off(target_state);
ti_sci_enter_sleep(proc_id, 0, k3_sec_entrypoint);
ti_sci_enter_sleep(proc_id, mode, k3_sec_entrypoint);
}
static void k3_pwr_domain_suspend_dm_managed(const psci_power_state_t *target_state)
{
uint8_t mode = MSG_VALUE_SLEEP_MODE_DEEP_SLEEP;
int ret;
ret = ti_sci_lpm_get_next_sys_mode(&mode);
if (ret != 0) {
ERROR("Failed to fetch next system mode\n");
}
k3_pwr_domain_suspend_to_mode(target_state, mode);
}
static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
{
k3_pwr_domain_suspend_to_mode(target_state, MSG_VALUE_SLEEP_MODE_DEEP_SLEEP);
}
static void k3_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
@ -301,6 +319,8 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
k3_plat_psci_ops.pwr_domain_suspend = NULL;
k3_plat_psci_ops.pwr_domain_suspend_finish = NULL;
k3_plat_psci_ops.get_sys_suspend_power_state = NULL;
} else if (fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
k3_plat_psci_ops.pwr_domain_suspend = k3_pwr_domain_suspend_dm_managed;
}
*psci_ops = &k3_plat_psci_ops;