From: Chee Hong Ang <chee.hong....@intel.com> Refactor the FPGA recpnfiguration driver to call the ATF's PSCI runtime services as it no longer handles the Secure Device Manager (SDM) mailbox communication and FPGA reconfiguration logic.
Signed-off-by: Chee Hong Ang <chee.hong....@intel.com> --- drivers/fpga/stratix10.c | 261 +++++++++++------------------------------------ 1 file changed, 59 insertions(+), 202 deletions(-) diff --git a/drivers/fpga/stratix10.c b/drivers/fpga/stratix10.c index d8e3250..44a427d 100644 --- a/drivers/fpga/stratix10.c +++ b/drivers/fpga/stratix10.c @@ -2,92 +2,16 @@ /* * Copyright (C) 2018 Intel Corporation <www.intel.com> */ - #include <common.h> #include <altera.h> -#include <asm/arch/mailbox_s10.h> +#include <asm/arch/misc.h> +#include <linux/intel-smc.h> + +#define BITSTREAM_CHUNK_SIZE 0xFFFF0 #define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS 60000 #define RECONFIG_STATUS_INTERVAL_DELAY_US 1000000 - -static const struct mbox_cfgstat_state { - int err_no; - const char *error_name; -} mbox_cfgstat_state[] = { - {MBOX_CFGSTAT_STATE_IDLE, "FPGA in idle mode."}, - {MBOX_CFGSTAT_STATE_CONFIG, "FPGA in config mode."}, - {MBOX_CFGSTAT_STATE_FAILACK, "Acknowledgment failed!"}, - {MBOX_CFGSTAT_STATE_ERROR_INVALID, "Invalid bitstream!"}, - {MBOX_CFGSTAT_STATE_ERROR_CORRUPT, "Corrupted bitstream!"}, - {MBOX_CFGSTAT_STATE_ERROR_AUTH, "Authentication failed!"}, - {MBOX_CFGSTAT_STATE_ERROR_CORE_IO, "I/O error!"}, - {MBOX_CFGSTAT_STATE_ERROR_HARDWARE, "Hardware error!"}, - {MBOX_CFGSTAT_STATE_ERROR_FAKE, "Fake error!"}, - {MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO, "Error in boot info!"}, - {MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR, "Error in QSPI!"}, - {MBOX_RESP_ERROR, "Mailbox general error!"}, - {-ETIMEDOUT, "I/O timeout error"}, - {-1, "Unknown error!"} -}; - -#define MBOX_CFGSTAT_MAX ARRAY_SIZE(mbox_cfgstat_state) - -static const char *mbox_cfgstat_to_str(int err) -{ - int i; - - for (i = 0; i < MBOX_CFGSTAT_MAX - 1; i++) { - if (mbox_cfgstat_state[i].err_no == err) - return mbox_cfgstat_state[i].error_name; - } - - return mbox_cfgstat_state[MBOX_CFGSTAT_MAX - 1].error_name; -} - -/* - * Add the ongoing transaction's command ID into pending list and return - * the command ID for next transfer. - */ -static u8 add_transfer(u32 *xfer_pending_list, size_t list_size, u8 id) -{ - int i; - - for (i = 0; i < list_size; i++) { - if (xfer_pending_list[i]) - continue; - xfer_pending_list[i] = id; - debug("ID(%d) added to transaction pending list\n", id); - /* - * Increment command ID for next transaction. - * Valid command ID (4 bits) is from 1 to 15. - */ - id = (id % 15) + 1; - break; - } - - return id; -} - -/* - * Check whether response ID match the command ID in the transfer - * pending list. If a match is found in the transfer pending list, - * it clears the transfer pending list and return the matched - * command ID. - */ -static int get_and_clr_transfer(u32 *xfer_pending_list, size_t list_size, - u8 id) -{ - int i; - - for (i = 0; i < list_size; i++) { - if (id != xfer_pending_list[i]) - continue; - xfer_pending_list[i] = 0; - return id; - } - - return 0; -} +#define RECONFIG_STATUS_POLL_RETRY_MAX 100 /* * Polling the FPGA configuration status. @@ -99,11 +23,13 @@ static int reconfig_status_polling_resp(void) unsigned long start = get_timer(0); while (1) { - ret = mbox_get_fpga_config_status(MBOX_RECONFIG_STATUS); + ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, NULL, 0, + NULL, 0); + if (!ret) return 0; /* configuration success */ - if (ret != MBOX_CFGSTAT_STATE_CONFIG) + if (ret != INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY) return ret; if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS) @@ -116,125 +42,59 @@ static int reconfig_status_polling_resp(void) return -ETIMEDOUT; } -static u32 get_resp_hdr(u32 *r_index, u32 *w_index, u32 *resp_count, - u32 *resp_buf, u32 buf_size, u32 client_id) -{ - u32 buf[MBOX_RESP_BUFFER_SIZE]; - u32 mbox_hdr; - u32 resp_len; - u32 hdr_len; - u32 i; - - if (*resp_count < buf_size) { - u32 rcv_len_max = buf_size - *resp_count; - - if (rcv_len_max > MBOX_RESP_BUFFER_SIZE) - rcv_len_max = MBOX_RESP_BUFFER_SIZE; - resp_len = mbox_rcv_resp(buf, rcv_len_max); - - for (i = 0; i < resp_len; i++) { - resp_buf[(*w_index)++] = buf[i]; - *w_index %= buf_size; - (*resp_count)++; - } - } - - /* No response in buffer */ - if (*resp_count == 0) - return 0; - - mbox_hdr = resp_buf[*r_index]; - - hdr_len = MBOX_RESP_LEN_GET(mbox_hdr); - - /* Insufficient header length to return a mailbox header */ - if ((*resp_count - 1) < hdr_len) - return 0; - - *r_index += (hdr_len + 1); - *r_index %= buf_size; - *resp_count -= (hdr_len + 1); - - /* Make sure response belongs to us */ - if (MBOX_RESP_CLIENT_GET(mbox_hdr) != client_id) - return 0; - - return mbox_hdr; -} - -/* Send bit stream data to SDM via RECONFIG_DATA mailbox command */ -static int send_reconfig_data(const void *rbf_data, size_t rbf_size, - u32 xfer_max, u32 buf_size_max) +static int send_bistream(const void *rbf_data, size_t rbf_size) { - u32 response_buffer[MBOX_RESP_BUFFER_SIZE]; - u32 xfer_pending[MBOX_RESP_BUFFER_SIZE]; - u32 resp_rindex = 0; - u32 resp_windex = 0; - u32 resp_count = 0; + int i; + u64 res_buf[3]; + u64 args[2]; u32 xfer_count = 0; - int resp_err = 0; - u8 cmd_id = 1; - u32 args[3]; - int ret; - - debug("SDM xfer_max = %d\n", xfer_max); - debug("SDM buf_size_max = %x\n\n", buf_size_max); - - memset(xfer_pending, 0, sizeof(xfer_pending)); + int ret, wr_ret = 0, retry = 0; + size_t buf_size = (rbf_size > BITSTREAM_CHUNK_SIZE) ? + BITSTREAM_CHUNK_SIZE : rbf_size; while (rbf_size || xfer_count) { - if (!resp_err && rbf_size && xfer_count < xfer_max) { - args[0] = MBOX_ARG_DESC_COUNT(1); - args[1] = (u64)rbf_data; - if (rbf_size >= buf_size_max) { - args[2] = buf_size_max; - rbf_size -= buf_size_max; - rbf_data += buf_size_max; - } else { - args[2] = (u64)rbf_size; - rbf_size = 0; - } + if (!wr_ret && rbf_size) { + args[0] = (u64)rbf_data; + args[1] = buf_size; + wr_ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_WRITE, + args, 2, NULL, 0); - resp_err = mbox_send_cmd_only(cmd_id, MBOX_RECONFIG_DATA, - MBOX_CMD_INDIRECT, 3, args); - if (!resp_err) { - xfer_count++; - cmd_id = add_transfer(xfer_pending, - MBOX_RESP_BUFFER_SIZE, - cmd_id); - } - puts("."); - } else { - u32 resp_hdr = get_resp_hdr(&resp_rindex, &resp_windex, - &resp_count, - response_buffer, - MBOX_RESP_BUFFER_SIZE, - MBOX_CLIENT_ID_UBOOT); + debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n", + wr_ret, rbf_data, buf_size); - /* - * If no valid response header found or - * non-zero length from RECONFIG_DATA - */ - if (!resp_hdr || MBOX_RESP_LEN_GET(resp_hdr)) + if (wr_ret == INTEL_SIP_SMC_FPGA_CONFIG_STATUS_REJECTED) continue; - /* Check for response's status */ - if (!resp_err) { - resp_err = MBOX_RESP_ERR_GET(resp_hdr); - debug("Response error code: %08x\n", resp_err); - } + rbf_size -= buf_size; + rbf_data += buf_size; - ret = get_and_clr_transfer(xfer_pending, - MBOX_RESP_BUFFER_SIZE, - MBOX_RESP_ID_GET(resp_hdr)); - if (ret) { - /* Claim and reuse the ID */ - cmd_id = (u8)ret; - xfer_count--; - } + if (buf_size >= rbf_size) + buf_size = rbf_size; - if (resp_err && !xfer_count) - return resp_err; + xfer_count++; + puts("."); + } else { + ret = invoke_smc( + INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE, + NULL, 0, res_buf, 3); + if (!ret) { + for (i = 0; i < 3; i++) { + if (!res_buf[i]) + break; + xfer_count--; + wr_ret = 0; + retry = 0; + } + } else if (ret != + INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY) + return ret; + else if (!xfer_count) + return INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR; + + if (++retry >= RECONFIG_STATUS_POLL_RETRY_MAX) + return -ETIMEDOUT; + + udelay(20000); } } @@ -248,21 +108,19 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size, int stratix10_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) { int ret; - u32 resp_len = 2; - u32 resp_buf[2]; - debug("Sending MBOX_RECONFIG...\n"); - ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RECONFIG, MBOX_CMD_DIRECT, 0, - NULL, 0, &resp_len, resp_buf); + debug("Invoking FPGA_CONFIG_START...\n"); + + ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_START, NULL, 0, NULL, 0); + if (ret) { puts("Failure in RECONFIG mailbox command!\n"); return ret; } - ret = send_reconfig_data(rbf_data, rbf_size, resp_buf[0], resp_buf[1]); + ret = send_bistream(rbf_data, rbf_size); if (ret) { - printf("RECONFIG_DATA error: %08x, %s\n", ret, - mbox_cfgstat_to_str(ret)); + printf("Error sending bitstream!\n"); return ret; } @@ -272,8 +130,7 @@ int stratix10_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) debug("Polling with MBOX_RECONFIG_STATUS...\n"); ret = reconfig_status_polling_resp(); if (ret) { - printf("RECONFIG_STATUS Error: %08x, %s\n", ret, - mbox_cfgstat_to_str(ret)); + printf("FPGA reconfiguration failed!"); return ret; } -- 2.7.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot