aboutsummaryrefslogtreecommitdiff
path: root/plat/ti/k3
diff options
context:
space:
mode:
authorAndrew F. Davis <afd@ti.com>2019-02-11 14:18:53 -0600
committerAndrew F. Davis <afd@ti.com>2019-02-11 16:13:30 -0600
commite9152c13c541572f81b449320a0e89f16d98f534 (patch)
tree823340b34f5874ed29cdb2afe2ebc270019b0a86 /plat/ti/k3
parent60d23323a78d8c3cb0c1758df5e85b0cd22fe3ac (diff)
downloadtrusted-firmware-a-e9152c13c541572f81b449320a0e89f16d98f534.tar.gz
ti: k3: drivers: ti_sci: Add non-blocking TI-SCI messages
Most TI-SCI functions request an ACK and wait until it is received. For some power sequence tasks we cannot wait but instead queue messages asynchronously. Three messages have been identified that will need to be used in this way. Add non-waiting versions of these functions. Signed-off-by: Andrew F. Davis <afd@ti.com>
Diffstat (limited to 'plat/ti/k3')
-rw-r--r--plat/ti/k3/common/drivers/ti_sci/ti_sci.c182
-rw-r--r--plat/ti/k3/common/drivers/ti_sci/ti_sci.h16
2 files changed, 198 insertions, 0 deletions
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 0f0905bb07..0f0a6f0c32 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -402,6 +402,53 @@ int ti_sci_device_put(uint32_t id)
}
/**
+ * ti_sci_device_put_no_wait() - Release a device without requesting or waiting
+ * for a response.
+ *
+ * @id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_put_no_wait(uint32_t id)
+{
+ struct ti_sci_msg_req_set_device_state req;
+ struct ti_sci_msg_hdr *hdr;
+ struct k3_sec_proxy_msg tx_message;
+ int ret;
+
+ /* Ensure we have sane transfer size */
+ if (sizeof(req) > info.desc.max_msg_size)
+ return -ERANGE;
+
+ hdr = (struct ti_sci_msg_hdr *)&req;
+ hdr->seq = info.seq;
+ hdr->type = TI_SCI_MSG_SET_DEVICE_STATE;
+ hdr->host = info.desc.host_id;
+ /* Setup with NORESPONSE flag to keep response queue clean */
+ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+
+ req.id = id;
+ req.state = MSG_DEVICE_SW_STATE_AUTO_OFF;
+
+ tx_message.buf = (uint8_t *)&req;
+ tx_message.len = sizeof(req);
+
+ /* Send message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
+ if (ret) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* Return without waiting for response */
+ return 0;
+}
+
+/**
* ti_sci_device_is_valid() - Is the device valid
*
* @id: Device Identifier
@@ -1337,6 +1384,55 @@ int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set,
}
/**
+ * ti_sci_proc_set_boot_ctrl_no_wait() - Set the processor boot control flags
+ * without requesting or waiting for a
+ * response.
+ *
+ * @proc_id: Processor ID this request is for
+ * @control_flags_set: Control flags to be set
+ * @control_flags_clear: Control flags to be cleared
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_set_boot_ctrl_no_wait(uint8_t proc_id,
+ uint32_t control_flags_set,
+ uint32_t control_flags_clear)
+{
+ struct ti_sci_msg_req_set_proc_boot_ctrl req;
+ struct ti_sci_msg_hdr *hdr;
+ struct k3_sec_proxy_msg tx_message;
+ int ret;
+
+ /* Ensure we have sane transfer size */
+ if (sizeof(req) > info.desc.max_msg_size)
+ return -ERANGE;
+
+ hdr = (struct ti_sci_msg_hdr *)&req;
+ hdr->seq = info.seq;
+ hdr->type = TISCI_MSG_SET_PROC_BOOT_CTRL;
+ hdr->host = info.desc.host_id;
+ /* Setup with NORESPONSE flag to keep response queue clean */
+ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+
+ req.processor_id = proc_id;
+ req.control_flags_set = control_flags_set;
+ req.control_flags_clear = control_flags_clear;
+
+ tx_message.buf = (uint8_t *)&req;
+ tx_message.len = sizeof(req);
+
+ /* Send message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
+ if (ret) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* Return without waiting for response */
+ return 0;
+}
+
+/**
* ti_sci_proc_auth_boot_image() - Authenticate and load image and then set the
* processor configuration flags
*
@@ -1499,6 +1595,92 @@ int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
}
/**
+ * ti_sci_proc_wait_boot_status_no_wait() - Wait for a processor boot status
+ * without requesting or waiting for
+ * a response.
+ *
+ * @proc_id: Processor ID this request is for
+ * @num_wait_iterations Total number of iterations we will check before
+ * we will timeout and give up
+ * @num_match_iterations How many iterations should we have continued
+ * status to account for status bits glitching.
+ * This is to make sure that match occurs for
+ * consecutive checks. This implies that the
+ * worst case should consider that the stable
+ * time should at the worst be num_wait_iterations
+ * num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us Specifies how long to wait (in micro seconds)
+ * between each status checks. This is the minimum
+ * duration, and overhead of register reads and
+ * checks are on top of this and can vary based on
+ * varied conditions.
+ * @delay_before_iterations_us Specifies how long to wait (in micro seconds)
+ * before the very first check in the first
+ * iteration of status check loop. This is the
+ * minimum duration, and overhead of register
+ * reads and checks are.
+ * @status_flags_1_set_all_wait If non-zero, Specifies that all bits of the
+ * status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait If non-zero, Specifies that at least one of the
+ * bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait If non-zero, Specifies that all bits of the
+ * status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait If non-zero, Specifies that at least one of the
+ * bits matching this field requested MUST be 0.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id,
+ uint8_t num_wait_iterations,
+ uint8_t num_match_iterations,
+ uint8_t delay_per_iteration_us,
+ uint8_t delay_before_iterations_us,
+ uint32_t status_flags_1_set_all_wait,
+ uint32_t status_flags_1_set_any_wait,
+ uint32_t status_flags_1_clr_all_wait,
+ uint32_t status_flags_1_clr_any_wait)
+{
+ struct ti_sci_msg_req_wait_proc_boot_status req;
+ struct ti_sci_msg_hdr *hdr;
+ struct k3_sec_proxy_msg tx_message;
+ int ret;
+
+ /* Ensure we have sane transfer size */
+ if (sizeof(req) > info.desc.max_msg_size)
+ return -ERANGE;
+
+ hdr = (struct ti_sci_msg_hdr *)&req;
+ hdr->seq = info.seq;
+ hdr->type = TISCI_MSG_WAIT_PROC_BOOT_STATUS;
+ hdr->host = info.desc.host_id;
+ /* Setup with NORESPONSE flag to keep response queue clean */
+ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+
+ req.processor_id = proc_id;
+ req.num_wait_iterations = num_wait_iterations;
+ req.num_match_iterations = num_match_iterations;
+ req.delay_per_iteration_us = delay_per_iteration_us;
+ req.delay_before_iterations_us = delay_before_iterations_us;
+ req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
+ req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
+ req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
+ req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
+
+ tx_message.buf = (uint8_t *)&req;
+ tx_message.len = sizeof(req);
+
+ /* Send message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
+ if (ret) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* Return without waiting for response */
+ return 0;
+}
+
+/**
* ti_sci_proc_shutdown() - Shutdown Processor without waiting for ACKs
*
* @proc_id: Processor ID this request is for
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 7eb9f6de3c..a179c13210 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -21,6 +21,7 @@
* - ti_sci_device_idle - Command to idle a device managed by TISCI
* - ti_sci_device_idle_exclusive - exclusively idle a device
* - ti_sci_device_put - command to release a device managed by TISCI
+ * - ti_sci_device_put_no_wait - release a device without waiting for response
* - ti_sci_device_is_valid - Is the device valid
* - ti_sci_device_get_clcnt - Get context loss counter
* @count: Pointer to Context Loss counter to populate
@@ -53,6 +54,7 @@ int ti_sci_device_get_exclusive(uint32_t id);
int ti_sci_device_idle(uint32_t id);
int ti_sci_device_idle_exclusive(uint32_t id);
int ti_sci_device_put(uint32_t id);
+int ti_sci_device_put_no_wait(uint32_t id);
int ti_sci_device_is_valid(uint32_t id);
int ti_sci_device_get_clcnt(uint32_t id, uint32_t *count);
int ti_sci_device_is_idle(uint32_t id, bool *r_state);
@@ -158,11 +160,13 @@ int ti_sci_core_reboot(void);
* - ti_sci_proc_set_boot_ctrl - Command to set the processor boot control flags
* @control_flags_set: Control flags to be set
* @control_flags_clear: Control flags to be cleared
+ * - ti_sci_proc_set_boot_ctrl_no_wait - Same as above without waiting for response
* - ti_sci_proc_auth_boot_image - Command to authenticate and load the image
* and then set the processor configuration flags.
* @cert_addr: Memory address at which payload image certificate is located.
* - ti_sci_proc_get_boot_status - Command to get the processor boot status
* - ti_sci_proc_wait_boot_status - Command to wait for a processor boot status
+ * - ti_sci_proc_wait_boot_status_no_wait - Same as above without waiting for response
*
* NOTE: for all these functions, the following are generic in nature:
* @proc_id: Processor ID
@@ -176,6 +180,9 @@ int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector,
uint32_t config_flags_clear);
int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set,
uint32_t control_flags_clear);
+int ti_sci_proc_set_boot_ctrl_no_wait(uint8_t proc_id,
+ uint32_t control_flags_set,
+ uint32_t control_flags_clear);
int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr);
int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
uint32_t *cfg_flags,
@@ -189,6 +196,15 @@ 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_wait_boot_status_no_wait(uint8_t proc_id,
+ uint8_t num_wait_iterations,
+ uint8_t num_match_iterations,
+ uint8_t delay_per_iteration_us,
+ uint8_t delay_before_iterations_us,
+ uint32_t status_flags_1_set_all_wait,
+ 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);
/**