/* SPDX-License-Identifier: BSD-3-Clause */

#include <device/mmio.h>
#include <console/console.h>
#include <delay.h>
#include <timer.h>
#include <soc/iomap.h>
#include <soc/qup.h>

#define TIMEOUT_CNT	100

#define QUP_ADDR(id, reg)	(blsp_qup_base(id) + (reg))

#define QUP_DEBUG	0

#define QUPDBG		BIOS_ERR, "\t-> "

#if QUP_DEBUG
#define qup_write32(a, v) do {				\
	write32(a, v);					\
	printk(QUPDBG "%s(%d): write32(%p, 0x%x)\n",	\
			__func__, __LINE__, a, v);	\
} while (0)
#else
#define qup_write32	write32
#endif

static qup_return_t qup_i2c_master_status(blsp_qup_id_t id)
{
	uint32_t reg_val = read32(QUP_ADDR(id, QUP_I2C_MASTER_STATUS));

	if (read32(QUP_ADDR(id, QUP_ERROR_FLAGS)))
		return QUP_ERR_XFER_FAIL;

#if QUP_DEBUG
	printk(QUPDBG "%s: 0x%x\n", __func__, reg_val);
#endif

	if (reg_val & QUP_I2C_INVALID_READ_ADDR)
		return QUP_ERR_I2C_INVALID_SLAVE_ADDR;
	if (reg_val & QUP_I2C_FAILED_MASK)
		return QUP_ERR_I2C_FAILED;
	if (reg_val & QUP_I2C_ARB_LOST)
		return QUP_ERR_I2C_ARB_LOST;
	if (reg_val & QUP_I2C_BUS_ERROR)
		return QUP_ERR_I2C_BUS_ERROR;
	if (reg_val & QUP_I2C_INVALID_WRITE)
		return QUP_ERR_I2C_INVALID_WRITE;
	if (reg_val & QUP_I2C_PACKET_NACK)
		return QUP_ERR_I2C_NACK;
	if (reg_val & QUP_I2C_INVALID_TAG)
		return QUP_ERR_I2C_INVALID_TAG;

	return QUP_SUCCESS;
}

static int check_bit_state(uint32_t *reg, int wait_for)
{
	unsigned int count = TIMEOUT_CNT;

	while ((read32(reg) & (QUP_STATE_VALID_MASK | QUP_STATE_MASK)) !=
			(QUP_STATE_VALID | wait_for)) {
		if (count == 0)
			return QUP_ERR_TIMEOUT;
		count--;
	}

	return QUP_SUCCESS;
}

/*
 * Check whether GSBIn_QUP State is valid
 */
static qup_return_t qup_wait_for_state(blsp_qup_id_t id, unsigned int wait_for)
{
	return check_bit_state(QUP_ADDR(id, QUP_STATE), wait_for);
}

qup_return_t qup_reset_i2c_master_status(blsp_qup_id_t id)
{
	/*
	 * The I2C_STATUS is a status register.
	 * Writing any value clears the status bits.
	 */
	qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_STATUS), 0);
	return QUP_SUCCESS;
}

static qup_return_t qup_reset_master_status(blsp_qup_id_t id)
{
	qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS), 0x3C);
	qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS_EN), 0x3C);
	qup_reset_i2c_master_status(id);
	return QUP_SUCCESS;
}

static qup_return_t qup_fifo_wait_for(blsp_qup_id_t id, uint32_t status,
				      struct stopwatch *timeout)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;

	while (!(read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status)) {
		ret = qup_i2c_master_status(id);
		if (ret)
			return ret;
		if (stopwatch_expired(timeout))
			return QUP_ERR_TIMEOUT;
	}

	return QUP_SUCCESS;
}

static qup_return_t qup_fifo_wait_while(blsp_qup_id_t id, uint32_t status,
					struct stopwatch *timeout)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;

	while (read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status) {
		ret = qup_i2c_master_status(id);
		if (ret)
			return ret;
		if (stopwatch_expired(timeout))
			return QUP_ERR_TIMEOUT;
	}

	return QUP_SUCCESS;
}

static inline uint32_t qup_i2c_create_output_tag(int stop, u8 data)
{
	uint32_t tag;

	if (stop)
		tag = QUP_I2C_STOP_SEQ | QUP_I2C_DATA(data);
	else
		tag = QUP_I2C_DATA_SEQ | QUP_I2C_DATA(data);

	return tag;
}

static inline qup_return_t qup_i2c_write_fifo_flush(blsp_qup_id_t id,
						    struct stopwatch *timeout)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;

	qup_write32(QUP_ADDR(id, QUP_OPERATIONAL), OUTPUT_SERVICE_FLAG);

	mdelay(4);	/* TPM seems to need this */

	ret = qup_fifo_wait_while(id, OUTPUT_FIFO_NOT_EMPTY, timeout);
	if (ret)
		return ret;

	ret = qup_i2c_master_status(id);

	if (ret)
		printk(BIOS_DEBUG, "%s: error\n", __func__);

	return ret;
}

static qup_return_t qup_i2c_write_fifo(blsp_qup_id_t id, qup_data_t *p_tx_obj,
				       uint8_t stop_seq)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;
	uint8_t addr = p_tx_obj->p.iic.addr;
	uint8_t *data_ptr = p_tx_obj->p.iic.data;
	unsigned int data_len = p_tx_obj->p.iic.data_len;
	unsigned int idx = 0;
	uint32_t tag, *fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO);
	struct stopwatch timeout;

	qup_reset_master_status(id);

	qup_write32(QUP_ADDR(id, QUP_MX_OUTPUT_COUNT), data_len + 1);

	qup_set_state(id, QUP_STATE_RUN);

	/*
	 * Since UNPACK enable is set in io mode register, populate 2 tags
	 * for each fifo register.
	 *
	 * Create the first tag as follows, with the start tag and first byte
	 * of the data to be written
	 *	+--------+--------+--------+--------+
	 *	| STOP / |  data  | START  | ADDR   |
	 *	|DATA tag|  byte  |  tag   | << 1   |
	 *	+--------+--------+--------+--------+
	 * rest will be created in the following while loop.
	 */
	tag = qup_i2c_create_output_tag(data_len == 1 && stop_seq,
					data_ptr[idx]);
	tag = ((tag << 16) & 0xffff0000) |
			(QUP_I2C_START_SEQ | QUP_I2C_ADDR(addr));
	data_len--;
	idx++;

	qup_write32(fifo, tag);

	stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
	while (data_len) {

		tag = qup_i2c_create_output_tag(data_len == 1 && stop_seq,
						data_ptr[idx]);
		data_len--;
		idx++;

		if (data_len) {
			tag |= qup_i2c_create_output_tag(
						data_len == 1 && stop_seq,
						data_ptr[idx]) << 16;
			data_len--;
			idx++;
		}

		qup_write32(fifo, tag);

		ret = qup_i2c_write_fifo_flush(id, &timeout);

		if (ret) {
			printk(QUPDBG "%s: error\n", __func__);
			return ret;
		}
	}

	ret = qup_i2c_write_fifo_flush(id, &timeout);

	qup_set_state(id, QUP_STATE_RESET);

	return ret;
}

static qup_return_t qup_i2c_write(blsp_qup_id_t id, uint8_t mode,
				  qup_data_t *p_tx_obj, uint8_t stop_seq)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;

	switch (mode) {
	case QUP_MODE_FIFO:
	case QUP_MODE_BLOCK:
		ret = qup_i2c_write_fifo(id, p_tx_obj, stop_seq);
		break;
	default:
		ret = QUP_ERR_UNSUPPORTED;
	}

	if (ret) {
		qup_set_state(id, QUP_STATE_RESET);
		printk(QUPDBG "%s() failed (%d)\n", __func__, ret);
	}

	return ret;
}

static int qup_i2c_parse_tag(uint32_t data, uint8_t *data_ptr, uint32_t len)
{
	int i, idx = 0;
	int max = (len > 2) ? 2 : len;

	for (i = 0; i < max; i++) {
		switch (QUP_I2C_MI_TAG(data)) {
		case QUP_I2C_MIDATA_SEQ:
			data_ptr[idx] = QUP_I2C_DATA(data);
			idx++;
			break;
		case QUP_I2C_MISTOP_SEQ:
			data_ptr[idx] = QUP_I2C_DATA(data);
			idx++;
			return idx;
		default:
			printk(QUPDBG "%s: Unexpected tag (0x%x)\n", __func__,
				QUP_I2C_MI_TAG(data));
			return -1;
		}

		data = (data >> 16);
	}

	return idx;
}

static qup_return_t qup_i2c_read_fifo(blsp_qup_id_t id, qup_data_t *p_tx_obj)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;
	uint8_t addr = p_tx_obj->p.iic.addr;
	uint8_t *data_ptr = p_tx_obj->p.iic.data;
	unsigned int data_len = p_tx_obj->p.iic.data_len;
	unsigned int idx = 0;
	uint32_t *fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO);
	struct stopwatch timeout;

	qup_reset_master_status(id);

	qup_write32(QUP_ADDR(id, QUP_IO_MODES),
		QUP_UNPACK_EN | QUP_PACK_EN |
			  ((QUP_MODE_BLOCK & QUP_MODE_MASK) <<
					QUP_OUTPUT_MODE_SHFT) |
			  ((QUP_MODE_BLOCK & QUP_MODE_MASK) <<
					QUP_INPUT_MODE_SHFT));

	qup_write32(QUP_ADDR(id, QUP_MX_INPUT_COUNT), data_len);

	qup_set_state(id, QUP_STATE_RUN);

	qup_write32(fifo, (QUP_I2C_START_SEQ |
				  (QUP_I2C_ADDR(addr) | QUP_I2C_SLAVE_READ)) |
				((QUP_I2C_RECV_SEQ | data_len) << 16));

	stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
	ret = qup_i2c_write_fifo_flush(id, &timeout);
	if (ret) {
		printk(QUPDBG "%s: OUTPUT_FIFO_NOT_EMPTY\n", __func__);
		return ret;
	}

	ret = qup_fifo_wait_for(id, INPUT_SERVICE_FLAG, &timeout);
	if (ret) {
		printk(QUPDBG "%s: INPUT_SERVICE_FLAG\n", __func__);
		return ret;
	}

	fifo = QUP_ADDR(id, QUP_INPUT_FIFO);

	while (data_len) {
		uint32_t data;
		int count;

		data = read32(fifo);
		mdelay(1);

		count = qup_i2c_parse_tag(data, data_ptr + idx, data_len);

		if (count < 0) {
			printk(QUPDBG "%s: Cannot parse tag 0x%x\n",
						__func__, data);
			qup_set_state(id, QUP_STATE_PAUSE);

			return QUP_ERR_I2C_INVALID_TAG;
		}

		idx += count;
		data_len -= count;

		qup_write32(QUP_ADDR(id, QUP_OPERATIONAL), INPUT_SERVICE_FLAG);
	}

	p_tx_obj->p.iic.data_len = idx;

	qup_write32(QUP_ADDR(id, QUP_MX_READ_COUNT), 0);

	qup_set_state(id, QUP_STATE_RESET);

	return QUP_SUCCESS;
}

static qup_return_t qup_i2c_read(blsp_qup_id_t id, uint8_t mode,
				 qup_data_t *p_tx_obj)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;

	qup_set_state(id, QUP_STATE_RESET);

	switch (mode) {
	case QUP_MODE_FIFO:
	case QUP_MODE_BLOCK:
		ret = qup_i2c_read_fifo(id, p_tx_obj);
		break;
	default:
		ret = QUP_ERR_UNSUPPORTED;
	}

	if (ret) {
		qup_set_state(id, QUP_STATE_RESET);
		printk(QUPDBG "%s() failed (%d)\n", __func__, ret);
	}

	return ret;
}

qup_return_t qup_init(blsp_qup_id_t id, const qup_config_t *config_ptr)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;
	uint32_t reg_val;

	/* Reset the QUP core.*/
	qup_write32(QUP_ADDR(id, QUP_SW_RESET), 0x1);

	/* Wait till the reset takes effect */
	ret = qup_wait_for_state(id, QUP_STATE_RESET);
	if (ret)
		goto bailout;

	/* Reset the config */
	qup_write32(QUP_ADDR(id, QUP_CONFIG), 0);

	/* Program the config register */
	/* Set N value */
	reg_val = 0x0F;
	/* Set protocol */
	switch (config_ptr->protocol) {
	case QUP_MINICORE_I2C_MASTER:
		reg_val |= ((config_ptr->protocol &
				QUP_MINI_CORE_PROTO_MASK) <<
				QUP_MINI_CORE_PROTO_SHFT);
		break;
	default:
		ret = QUP_ERR_UNSUPPORTED;
		goto bailout;
	}
	reg_val |= QUP_APP_CLK_ON_EN | QUP_CORE_CLK_ON_EN;
	qup_write32(QUP_ADDR(id, QUP_CONFIG), reg_val);

	/* Choose version 1 tag */
	qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CONFIG), 0);

	/* Reset i2c clk cntl register */
	qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CLK_CTL), 0);

	/* Set QUP IO Mode */
	switch (config_ptr->mode) {
	case QUP_MODE_FIFO:
	case QUP_MODE_BLOCK:
		reg_val = QUP_UNPACK_EN | QUP_PACK_EN |
			  ((config_ptr->mode & QUP_MODE_MASK) <<
					QUP_OUTPUT_MODE_SHFT) |
			  ((config_ptr->mode & QUP_MODE_MASK) <<
					QUP_INPUT_MODE_SHFT);
		break;
	default:
		ret = QUP_ERR_UNSUPPORTED;
		goto bailout;
	}
	qup_write32(QUP_ADDR(id, QUP_IO_MODES), reg_val);

	/*Set i2c clk cntl*/
	reg_val = (QUP_DIVIDER_MIN_VAL << QUP_HS_DIVIDER_SHFT);
	reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency)
			/ 2) - QUP_DIVIDER_MIN_VAL) &
				QUP_FS_DIVIDER_MASK);
	qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CLK_CTL), reg_val);

	qup_set_state(id, QUP_STATE_RESET);
bailout:
	if (ret)
		printk(QUPDBG "failed to init qup (%d)\n", ret);

	return ret;
}

qup_return_t qup_set_state(blsp_qup_id_t id, uint32_t state)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;
	unsigned int curr_state = read32(QUP_ADDR(id, QUP_STATE));

	if (state <= QUP_STATE_PAUSE && (curr_state & QUP_STATE_VALID_MASK)) {
		/*
		* For PAUSE_STATE to RESET_STATE transition,
		* two writes of  10[binary]) are required for the
		* transition to complete.
		*/
		if (QUP_STATE_PAUSE == curr_state && QUP_STATE_RESET == state) {
			qup_write32(QUP_ADDR(id, QUP_STATE), 0x2);
			qup_write32(QUP_ADDR(id, QUP_STATE), 0x2);
		} else {
			qup_write32(QUP_ADDR(id, QUP_STATE), state);
		}
		ret = qup_wait_for_state(id, state);
	}

	return ret;
}

static qup_return_t qup_i2c_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj,
				      uint8_t stop_seq)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;
	uint8_t mode = (read32(QUP_ADDR(id, QUP_IO_MODES)) >>
			QUP_OUTPUT_MODE_SHFT) & QUP_MODE_MASK;

	ret = qup_i2c_write(id, mode, p_tx_obj, stop_seq);
	if (QUP_DEBUG) {
		int i;

		printk(BIOS_DEBUG, "i2c tx bus %d device %2.2x:",
		       id, p_tx_obj->p.iic.addr);
		for (i = 0; i < p_tx_obj->p.iic.data_len; i++)
			printk(BIOS_DEBUG, " %2.2x", p_tx_obj->p.iic.data[i]);
		printk(BIOS_DEBUG, "\n");
	}

	return ret;
}

qup_return_t qup_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj,
			   uint8_t stop_seq)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;

	if (p_tx_obj->protocol == ((read32(QUP_ADDR(id, QUP_CONFIG)) >>
			QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
		switch (p_tx_obj->protocol) {
		case QUP_MINICORE_I2C_MASTER:
			ret = qup_i2c_send_data(id, p_tx_obj, stop_seq);
			break;
		default:
			ret = QUP_ERR_UNSUPPORTED;
		}
	}

	return ret;
}

static qup_return_t qup_i2c_recv_data(blsp_qup_id_t id, qup_data_t *p_rx_obj)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;
	uint8_t mode = (read32(QUP_ADDR(id, QUP_IO_MODES)) >>
			QUP_INPUT_MODE_SHFT) & QUP_MODE_MASK;

	ret = qup_i2c_read(id, mode, p_rx_obj);
	if (QUP_DEBUG) {
		int i;

		printk(BIOS_DEBUG, "i2c rxed on bus %d device %2.2x:",
		       id, p_rx_obj->p.iic.addr);
		for (i = 0; i < p_rx_obj->p.iic.data_len; i++)
			printk(BIOS_DEBUG, " %2.2x", p_rx_obj->p.iic.data[i]);
		printk(BIOS_DEBUG, "\n");
	}

	return ret;
}

qup_return_t qup_recv_data(blsp_qup_id_t id, qup_data_t *p_rx_obj)
{
	qup_return_t ret = QUP_ERR_UNDEFINED;

	if (p_rx_obj->protocol == ((read32(QUP_ADDR(id, QUP_CONFIG)) >>
			QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
		switch (p_rx_obj->protocol) {
		case QUP_MINICORE_I2C_MASTER:
			ret = qup_i2c_recv_data(id, p_rx_obj);
			break;
		default:
			ret = QUP_ERR_UNSUPPORTED;
		}
	}

	return ret;
}
