// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018 Intel Corporation <www.intel.com>
 */

#include <common.h>
#include <altera.h>
#include <log.h>
#include <asm/arch/mailbox_s10.h>
#include <linux/delay.h>

#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;
}

/*
 * Polling the FPGA configuration status.
 * Return 0 for success, non-zero for error.
 */
static int reconfig_status_polling_resp(void)
{
	int ret;
	unsigned long start = get_timer(0);

	while (1) {
		ret = mbox_get_fpga_config_status(MBOX_RECONFIG_STATUS);
		if (!ret)
			return 0;	/* configuration success */

		if (ret != MBOX_CFGSTAT_STATE_CONFIG)
			return ret;

		if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS)
			break;	/* time out */

		puts(".");
		udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
	}

	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)
{
	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;
	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));

	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;
			}

			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);

			/*
			 * If no valid response header found or
			 * non-zero length from RECONFIG_DATA
			 */
			if (!resp_hdr || MBOX_RESP_LEN_GET(resp_hdr))
				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);
			}

			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 (resp_err && !xfer_count)
				return resp_err;
		}
	}

	return 0;
}

/*
 * This is the interface used by FPGA driver.
 * Return 0 for success, non-zero for error.
 */
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);
	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]);
	if (ret) {
		printf("RECONFIG_DATA error: %08x, %s\n", ret,
		       mbox_cfgstat_to_str(ret));
		return ret;
	}

	/* Make sure we don't send MBOX_RECONFIG_STATUS too fast */
	udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);

	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));
		return ret;
	}

	puts("FPGA reconfiguration OK!\n");

	return ret;
}
