diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c index f6d71a0a4..81488a155 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -1539,6 +1539,88 @@ int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations, return 0; } +/** + * ti_sci_proc_shutdown() - Shutdown Processor without waiting for ACKs + * + * @proc_id: Processor ID this request is for + * @dev_id: Device identifier this request is for + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id) +{ + struct ti_sci_msg_req_wait_proc_boot_status wait_req; + struct ti_sci_msg_req_set_device_state set_req; + /* + * We will not be waiting for this response, but declare one anyway + * to pass to the setup function so the checks will still pass + */ + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + /* Start by sending wait command */ + + /* Setup with NORESPONSE flag to keep response queue clean */ + ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS, + TI_SCI_FLAG_REQ_GENERIC_NORESPONSE, + &wait_req, sizeof(wait_req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + wait_req.processor_id = proc_id; + /* + * Wait maximum time to give us the best chance to get + * to WFI before this command timeouts + */ + wait_req.delay_before_iterations_us = UINT8_MAX; + wait_req.num_wait_iterations = UINT8_MAX; + wait_req.delay_per_iteration_us = UINT8_MAX; /* TODO: optimize time */ + wait_req.num_match_iterations = 2; + wait_req.status_flags_1_set_all_wait = 0; + /* Wait for either WFE or WFI */ + wait_req.status_flags_1_set_any_wait = PROC_BOOT_STATUS_FLAG_ARMV8_WFE | + PROC_BOOT_STATUS_FLAG_ARMV8_WFI; + wait_req.status_flags_1_clr_all_wait = 0; + wait_req.status_flags_1_clr_any_wait = 0; + + /* Send wait message */ + ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message); + if (ret) { + ERROR("Message sending failed (%d)\n", ret); + return ret; + } + + /* Now queue up the shutdown request */ + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE, + TI_SCI_FLAG_REQ_GENERIC_NORESPONSE, + &set_req, sizeof(set_req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + set_req.id = dev_id; + set_req.state = MSG_DEVICE_SW_STATE_AUTO_OFF; + + /* Send shutdown message */ + ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message); + if (ret) { + ERROR("Message sending failed (%d)\n", ret); + return ret; + } + + /* Return without waiting for responses */ + return 0; +} + /** * ti_sci_init() - Basic initialization * diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h index 91f864573..d07ee61df 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h @@ -206,6 +206,7 @@ int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations, uint32_t status_flags_1_set_any_wait, uint32_t status_flags_1_clr_all_wait, uint32_t status_flags_1_clr_any_wait); +int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id); /** * ti_sci_init() - Basic initialization