From 33baa1e33c9e31cce3965ca13289b282eb22178d Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 11 Feb 2019 12:55:25 -0600 Subject: [PATCH 1/6] ti: k3: drivers: ti_sci: Internalize raw get/set state functions The raw get and set state functions for both devices and clocks are only meant for use internal to the TI-SCI driver, the same functionality is available from the other API that call into these. Remove them from the external interface and make them static scope to the driver. Signed-off-by: Andrew F. Davis --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 7 ++++--- plat/ti/k3/common/drivers/ti_sci/ti_sci.h | 21 --------------------- 2 files changed, 4 insertions(+), 24 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 4a33d3449..00382f02f 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -236,7 +236,7 @@ static inline bool ti_sci_is_response_ack(void *r) * * Return: 0 if all goes well, else appropriate error message */ -int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state) +static int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state) { struct ti_sci_msg_req_set_device_state req; struct ti_sci_msg_hdr resp; @@ -280,8 +280,9 @@ int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state) * * Return: 0 if all goes well, else appropriate error message */ -int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, uint32_t *resets, - uint8_t *p_state, uint8_t *c_state) +static int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, + uint32_t *resets, uint8_t *p_state, + uint8_t *c_state) { struct ti_sci_msg_req_get_device_state req; struct ti_sci_msg_resp_get_device_state resp; 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 d07ee61df..1288a6655 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h @@ -16,14 +16,6 @@ /** * Device control operations * - * - ti_sci_device_set_state - Set device state helper - * @flags: flags to setup for the device - * @state: State to move the device to - * - ti_sci_device_get_state - Get device state helper - * @clcnt: Pointer to Context Loss Count - * @resets: pointer to resets - * @p_state: pointer to p_state - * @c_state: pointer to c_state * - ti_sci_device_get - command to request for device managed by TISCI * - ti_sci_device_idle - Command to idle a device managed by TISCI * - ti_sci_device_put - command to release a device managed by TISCI @@ -54,9 +46,6 @@ * usage count by balancing get_device with put_device. No refcounting is * managed by driver for that purpose. */ -int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state); -int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, uint32_t *resets, - uint8_t *p_state, uint8_t *c_state); int ti_sci_device_get(uint32_t id); int ti_sci_device_idle(uint32_t id); int ti_sci_device_put(uint32_t id); @@ -72,12 +61,6 @@ int ti_sci_device_get_resets(uint32_t id, uint32_t *reset_state); /** * Clock control operations * - * - ti_sci_clock_set_state - Set clock state helper - * @flags: Header flags as needed - * @state: State to request for the clock. - * - ti_sci_clock_get_state - Get clock state helper - * @programmed_state: State requested for clock to move to - * @current_state: State that the clock is currently in * - ti_sci_clock_get - Get control of a clock from TI SCI * @needs_ssc: 'true' iff Spread Spectrum clock is desired * @can_change_freq: 'true' iff frequency change is desired @@ -123,10 +106,6 @@ int ti_sci_device_get_resets(uint32_t id, uint32_t *reset_state); * usage count by balancing get_clock with put_clock. No refcounting is * managed by driver for that purpose. */ -int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id, - uint32_t flags, uint8_t state); -int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id, - uint8_t *programmed_state, uint8_t *current_state); int ti_sci_clock_get(uint32_t dev_id, uint8_t clk_id, bool needs_ssc, bool can_change_freq, bool enable_input_term); From b3ca8aabbd585f668cc187ba2001b42dd606b272 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 11 Feb 2019 12:58:32 -0600 Subject: [PATCH 2/6] ti: k3: drivers: ti_sci: Add exclusive device accessors When a device is requested with TI-SCI its control can be made exclusive to the requesting host. This was currently the default but is not what is needed most of the time. Add _exclusive versions of the request functions and remove the exclusive flag from the default version. Signed-off-by: Andrew F. Davis --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 44 +++++++++++++++++++++-- plat/ti/k3/common/drivers/ti_sci/ti_sci.h | 4 +++ 2 files changed, 46 insertions(+), 2 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 00382f02f..a4e28d1da 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -334,11 +334,30 @@ static int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, * usage count by balancing get_device with put_device. No refcounting is * managed by driver for that purpose. * - * NOTE: The request is for exclusive access for the processor. - * * Return: 0 if all goes well, else appropriate error message */ int ti_sci_device_get(uint32_t id) +{ + return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_ON); +} + +/** + * ti_sci_device_get_exclusive() - Exclusive request for device managed by TISCI + * + * @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. + * + * NOTE: This _exclusive version of the get API is for exclusive access to the + * device. Any other host in the system will fail to get this device after this + * call until exclusive access is released with device_put or a non-exclusive + * set call. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_get_exclusive(uint32_t id) { return ti_sci_device_set_state(id, MSG_FLAG_DEVICE_EXCLUSIVE, @@ -357,6 +376,27 @@ int ti_sci_device_get(uint32_t id) * Return: 0 if all goes well, else appropriate error message */ int ti_sci_device_idle(uint32_t id) +{ + return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_RETENTION); +} + +/** + * ti_sci_device_idle_exclusive() - Exclusive idle a device managed by TISCI + * + * @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. + * + * NOTE: This _exclusive version of the idle API is for exclusive access to + * the device. Any other host in the system will fail to get this device after + * this call until exclusive access is released with device_put or a + * non-exclusive set call. + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_device_idle_exclusive(uint32_t id) { return ti_sci_device_set_state(id, MSG_FLAG_DEVICE_EXCLUSIVE, 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 1288a6655..7eb9f6de3 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h @@ -17,7 +17,9 @@ * Device control operations * * - ti_sci_device_get - command to request for device managed by TISCI + * - ti_sci_device_get_exclusive - exclusively request a device * - 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_is_valid - Is the device valid * - ti_sci_device_get_clcnt - Get context loss counter @@ -47,7 +49,9 @@ * managed by driver for that purpose. */ int ti_sci_device_get(uint32_t id); +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_is_valid(uint32_t id); int ti_sci_device_get_clcnt(uint32_t id, uint32_t *count); From 60d23323a78d8c3cb0c1758df5e85b0cd22fe3ac Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 11 Feb 2019 13:44:31 -0600 Subject: [PATCH 3/6] ti: k3: drivers: ti_sci: Request and check for ACK by default Currently almost all TI-SCI messages request and check for an ACK from the system firmware. Move this into a common place to remove the same from each function. Signed-off-by: Andrew F. Davis --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 136 ++++------------------ 1 file changed, 23 insertions(+), 113 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 a4e28d1da..0f0905bb0 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -95,7 +95,7 @@ static int ti_sci_setup_one_xfer(uint16_t msg_type, uint32_t msg_flags, hdr->seq = info.seq; hdr->type = msg_type; hdr->host = info.desc.host_id; - hdr->flags = msg_flags; + hdr->flags = msg_flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED; xfer->tx_message.buf = tx_buf; xfer->tx_message.len = tx_message_size; @@ -143,6 +143,9 @@ static inline int ti_sci_get_response(struct ti_sci_xfer *xfer, return -EINVAL; } + if (!(hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK)) + return -ENODEV; + return 0; } @@ -213,20 +216,6 @@ int ti_sci_get_revision(struct ti_sci_msg_resp_version *rev_info) return 0; } -/** - * ti_sci_is_response_ack() - Generic ACK/NACK message check - * - * @r: pointer to response buffer - * - * Return: true if the response was an ACK, else returns false - */ -static inline bool ti_sci_is_response_ack(void *r) -{ - struct ti_sci_msg_hdr *hdr = r; - - return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; -} - /** * ti_sci_device_set_state() - Set device state * @@ -244,8 +233,7 @@ static int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE, - flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE, flags, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -263,9 +251,6 @@ static int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -310,9 +295,6 @@ static int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - if (clcnt) *clcnt = resp.context_loss_count; if (resets) @@ -573,8 +555,7 @@ int ti_sci_device_set_resets(uint32_t id, uint32_t reset_state) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_RESETS, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_RESETS, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -592,9 +573,6 @@ int ti_sci_device_set_resets(uint32_t id, uint32_t reset_state) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -632,8 +610,7 @@ int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_STATE, - flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_STATE, flags, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -652,9 +629,6 @@ int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -683,8 +657,7 @@ int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id, if (!programmed_state && !current_state) return -EINVAL; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_STATE, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_STATE, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -702,9 +675,6 @@ int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - if (programmed_state) *programmed_state = resp.programmed_state; if (current_state) @@ -889,8 +859,7 @@ int ti_sci_clock_set_parent(uint32_t dev_id, uint8_t clk_id, uint8_t parent_id) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_PARENT, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_PARENT, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -909,9 +878,6 @@ int ti_sci_clock_set_parent(uint32_t dev_id, uint8_t clk_id, uint8_t parent_id) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -934,8 +900,7 @@ int ti_sci_clock_get_parent(uint32_t dev_id, uint8_t clk_id, uint8_t *parent_id) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_PARENT, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_PARENT, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -953,9 +918,6 @@ int ti_sci_clock_get_parent(uint32_t dev_id, uint8_t clk_id, uint8_t *parent_id) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - *parent_id = resp.parent_id; return 0; @@ -981,8 +943,7 @@ int ti_sci_clock_get_num_parents(uint32_t dev_id, uint8_t clk_id, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1000,9 +961,6 @@ int ti_sci_clock_get_num_parents(uint32_t dev_id, uint8_t clk_id, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - *num_parents = resp.num_parents; return 0; @@ -1037,8 +995,7 @@ int ti_sci_clock_get_match_freq(uint32_t dev_id, uint8_t clk_id, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_CLOCK_FREQ, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_CLOCK_FREQ, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1059,9 +1016,6 @@ int ti_sci_clock_get_match_freq(uint32_t dev_id, uint8_t clk_id, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - *match_freq = resp.freq_hz; return 0; @@ -1094,8 +1048,7 @@ int ti_sci_clock_set_freq(uint32_t dev_id, uint8_t clk_id, uint64_t min_freq, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_FREQ, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_FREQ, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1115,9 +1068,6 @@ int ti_sci_clock_set_freq(uint32_t dev_id, uint8_t clk_id, uint64_t min_freq, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1140,8 +1090,7 @@ int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_FREQ, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_FREQ, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1159,9 +1108,6 @@ int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - *freq = resp.freq_hz; return 0; @@ -1180,8 +1126,7 @@ int ti_sci_core_reboot(void) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SYS_RESET, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SYS_RESET, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1196,9 +1141,6 @@ int ti_sci_core_reboot(void) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1217,8 +1159,7 @@ int ti_sci_proc_request(uint8_t proc_id) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_REQUEST, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_REQUEST, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1235,9 +1176,6 @@ int ti_sci_proc_request(uint8_t proc_id) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1256,8 +1194,7 @@ int ti_sci_proc_release(uint8_t proc_id) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_RELEASE, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_RELEASE, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1274,9 +1211,6 @@ int ti_sci_proc_release(uint8_t proc_id) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1297,8 +1231,7 @@ int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_HANDOVER, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_HANDOVER, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1316,9 +1249,6 @@ int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1341,8 +1271,7 @@ int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CONFIG, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CONFIG, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1364,9 +1293,6 @@ int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1388,8 +1314,7 @@ int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1408,9 +1333,6 @@ int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1431,8 +1353,7 @@ int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr) struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMIAGE, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMIAGE, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1452,9 +1373,6 @@ int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr) return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } @@ -1476,8 +1394,7 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_GET_PROC_BOOT_STATUS, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_GET_PROC_BOOT_STATUS, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1494,9 +1411,6 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - *bv = (resp.bootvector_low & TISCI_ADDR_LOW_MASK) | (((uint64_t)resp.bootvector_high << TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); @@ -1556,8 +1470,7 @@ int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations, struct ti_sci_xfer xfer; int ret; - ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS, 0, &req, sizeof(req), &resp, sizeof(resp), &xfer); @@ -1582,9 +1495,6 @@ int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations, return ret; } - if (!ti_sci_is_response_ack(&resp)) - return -ENODEV; - return 0; } From e9152c13c541572f81b449320a0e89f16d98f534 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 11 Feb 2019 14:18:53 -0600 Subject: [PATCH 4/6] 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 --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 182 ++++++++++++++++++++++ plat/ti/k3/common/drivers/ti_sci/ti_sci.h | 16 ++ 2 files changed, 198 insertions(+) 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 0f0905bb0..0f0a6f0c3 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -401,6 +401,53 @@ int ti_sci_device_put(uint32_t id) return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_AUTO_OFF); } +/** + * 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 * @@ -1336,6 +1383,55 @@ int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set, return 0; } +/** + * 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 @@ -1498,6 +1594,92 @@ int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations, return 0; } +/** + * 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 * 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 7eb9f6de3..a179c1321 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); /** From a9ae424ed5a17819bf10f7e88d4c0b4ca5ac096c Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 11 Feb 2019 14:37:58 -0600 Subject: [PATCH 5/6] ti: k3: drivers: ti_sci: Use non-blocking TI-SCI messages for power down Now that we have non-blocking TI-SCI functions we can initiate the shutdown sequence from the PSCI handler without needing the ti_sci_proc_shutdown helper function, which is removed. This gives us the greater control and flexibility that will be needed when cluster power down sequences are added. Signed-off-by: Andrew F. Davis --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 82 ----------------------- plat/ti/k3/common/drivers/ti_sci/ti_sci.h | 1 - plat/ti/k3/common/k3_psci.c | 20 +++++- 3 files changed, 18 insertions(+), 85 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 0f0a6f0c3..df0b794f8 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -1680,88 +1680,6 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id, 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 a179c1321..c7b09b30d 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h @@ -205,7 +205,6 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id, 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 diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c index 235e6396b..afe465e56 100644 --- a/plat/ti/k3/common/k3_psci.c +++ b/plat/ti/k3/common/k3_psci.c @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -90,9 +91,24 @@ void k3_pwr_domain_off(const psci_power_state_t *target_state) proc = PLAT_PROC_START_ID + core_id; device = PLAT_PROC_DEVICE_START_ID + core_id; - ret = ti_sci_proc_shutdown(proc, device); + /* Start by sending wait for WFI command */ + ret = ti_sci_proc_wait_boot_status_no_wait(proc, + /* + * Wait maximum time to give us the best chance to get + * to WFI before this command timeouts + */ + UINT8_MAX, 100, UINT8_MAX, UINT8_MAX, + /* Wait for WFI */ + PROC_BOOT_STATUS_FLAG_ARMV8_WFI, 0, 0, 0); if (ret) { - ERROR("Request to stop core failed: %d\n", ret); + ERROR("Sending wait for WFI failed (%d)\n", ret); + return; + } + + /* Now queue up the core shutdown request */ + ret = ti_sci_device_put_no_wait(device); + if (ret) { + ERROR("Sending core shutdown message failed (%d)\n", ret); return; } } From 34b3eb14c85122ec822c06e6b8f404ee30bd984c Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 11 Feb 2019 14:44:46 -0600 Subject: [PATCH 6/6] ti: k3: common: Do not release processor control on startup ATF should be the only host needing to control a processor that it has started. ATF will need this control to stop the core later. Do not relinquish control of a core after starting the core. Signed-off-by: Andrew F. Davis --- plat/ti/k3/common/k3_psci.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c index afe465e56..f66f12a3d 100644 --- a/plat/ti/k3/common/k3_psci.c +++ b/plat/ti/k3/common/k3_psci.c @@ -71,12 +71,6 @@ static int k3_pwr_domain_on(u_register_t mpidr) return PSCI_E_INTERN_FAIL; } - ret = ti_sci_proc_release(proc); - if (ret) { - /* this is not fatal */ - WARN("Could not release processor control: %d\n", ret); - } - return PSCI_E_SUCCESS; }