From 89ea53c705000b5b96eb873940560f2ed634ed97 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 4 May 2018 19:06:13 +0000 Subject: [PATCH] ti: k3: drivers: ti_sci: Add support for Processor control TI-SCI message protocol provides support for controlling of various physical cores available in the SoC. In order to control which host is capable of controlling a physical processor core, there is a processor access control list that needs to be populated as part of the board configuration data. Introduce support for the set of TI-SCI message protocol APIs that provide us with this capability of controlling physical cores. Signed-off-by: Andrew F. Davis Reviewed-by: Andreas Dannenberg --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 305 ++++++++++++++++++++++ plat/ti/k3/common/drivers/ti_sci/ti_sci.h | 37 +++ 2 files changed, 342 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 f5d2ce18..7ba0267d 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -1152,6 +1152,311 @@ int ti_sci_core_reboot(void) return 0; } +/** + * ti_sci_proc_request() - Request a physical processor control + * + * @proc_id: Processor ID this request is for + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_request(uint8_t proc_id) +{ + struct ti_sci_msg_req_proc_request req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_REQUEST, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_release() - Release a physical processor control + * + * @proc_id: Processor ID this request is for + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_release(uint8_t proc_id) +{ + struct ti_sci_msg_req_proc_release req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_RELEASE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_handover() - Handover a physical processor control to a host in + * the processor's access control list. + * + * @proc_id: Processor ID this request is for + * @host_id: Host ID to get the control of the processor + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id) +{ + struct ti_sci_msg_req_proc_handover req; + struct ti_sci_msg_hdr resp; + + struct ti_sci_xfer xfer; + int ret; + + ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_HANDOVER, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.host_id = host_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_set_boot_cfg() - Set the processor boot configuration flags + * + * @proc_id: Processor ID this request is for + * @config_flags_set: Configuration flags to be set + * @config_flags_clear: Configuration flags to be cleared + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector, + uint32_t config_flags_set, + uint32_t config_flags_clear) +{ + struct ti_sci_msg_req_set_proc_boot_config req; + struct ti_sci_msg_hdr resp; + + 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, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK; + req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >> + TISCI_ADDR_HIGH_SHIFT; + req.config_flags_set = config_flags_set; + req.config_flags_clear = config_flags_clear; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_set_boot_ctrl() - Set the processor boot control flags + * + * @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(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 resp; + + 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, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.control_flags_set = control_flags_set; + req.control_flags_clear = control_flags_clear; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_auth_boot_image() - Authenticate and load image and then set the + * processor configuration flags + * + * @proc_id: Processor ID this request is for + * @cert_addr: Memory address at which payload image certificate is located + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr) +{ + struct ti_sci_msg_req_proc_auth_boot_image req; + struct ti_sci_msg_hdr resp; + + 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, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK; + req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >> + TISCI_ADDR_HIGH_SHIFT; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + return ret; + } + + if (!ti_sci_is_response_ack(&resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_proc_get_boot_status() - Get the processor boot status + * + * @proc_id: Processor ID this request is for + * + * Return: 0 if all goes well, else appropriate error message + */ +int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv, + uint32_t *cfg_flags, + uint32_t *ctrl_flags, + uint32_t *sts_flags) +{ + struct ti_sci_msg_req_get_proc_boot_status req; + struct ti_sci_msg_resp_get_proc_boot_status resp; + + 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, + &req, sizeof(req), + &resp, sizeof(resp), + &xfer); + if (ret) { + ERROR("Message alloc failed (%d)\n", ret); + return ret; + } + + req.processor_id = proc_id; + + ret = ti_sci_do_xfer(&xfer); + if (ret) { + ERROR("Transfer send failed (%d)\n", ret); + 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); + *cfg_flags = resp.config_flags; + *ctrl_flags = resp.control_flags; + *sts_flags = resp.status_flags; + + 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 df0c13ec..e40ad6bc 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h @@ -161,6 +161,43 @@ int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq); */ int ti_sci_core_reboot(void); +/** + * Processor control operations + * + * - ti_sci_proc_request - Command to request a physical processor control + * - ti_sci_proc_release - Command to release a physical processor control + * - ti_sci_proc_handover - Command to handover a physical processor control to + * a host in the processor's access control list. + * @host_id: Host ID to get the control of the processor + * - ti_sci_proc_set_boot_cfg - Command to set the processor boot configuration flags + * @config_flags_set: Configuration flags to be set + * @config_flags_clear: Configuration flags to be cleared. + * - 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_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 + * + * NOTE: for all these functions, the following are generic in nature: + * @proc_id: Processor ID + * Returns 0 for successful request, else returns corresponding error message. + */ +int ti_sci_proc_request(uint8_t proc_id); +int ti_sci_proc_release(uint8_t proc_id); +int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id); +int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector, + uint32_t config_flags_set, + 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_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, + uint32_t *ctrl_flags, + uint32_t *sts_flags); + /** * ti_sci_init() - Basic initialization * -- 2.30.2