/*
 * Copyright (C) 2018 Marvell International Ltd.
 * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
 *
 * SPDX-License-Identifier:     BSD-3-Clause
 * https://spdx.org/licenses
 */

/*
 * This driver is for Mentor Graphics Inventra MI2CV IP core, which is used
 * for Marvell and Allwinner SoCs in ATF.
 */

#include <debug.h>
#include <delay_timer.h>
#include <errno.h>
#include <mentor/mi2cv.h>
#include <mmio.h>

#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
#define DEBUG_I2C
#endif

#define I2C_TIMEOUT_VALUE		0x500
#define I2C_MAX_RETRY_CNT		1000
#define I2C_CMD_WRITE			0x0
#define I2C_CMD_READ			0x1

#define I2C_DATA_ADDR_7BIT_OFFS		0x1
#define I2C_DATA_ADDR_7BIT_MASK		(0xFF << I2C_DATA_ADDR_7BIT_OFFS)

#define I2C_CONTROL_ACK			0x00000004
#define I2C_CONTROL_IFLG		0x00000008
#define I2C_CONTROL_STOP		0x00000010
#define I2C_CONTROL_START		0x00000020
#define I2C_CONTROL_TWSIEN		0x00000040
#define I2C_CONTROL_INTEN		0x00000080

#define I2C_STATUS_START			0x08
#define I2C_STATUS_REPEATED_START		0x10
#define I2C_STATUS_ADDR_W_ACK			0x18
#define I2C_STATUS_DATA_W_ACK			0x28
#define I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER	0x38
#define I2C_STATUS_ADDR_R_ACK			0x40
#define I2C_STATUS_DATA_R_ACK			0x50
#define I2C_STATUS_DATA_R_NAK			0x58
#define I2C_STATUS_LOST_ARB_GENERAL_CALL	0x78
#define I2C_STATUS_IDLE				0xF8

#define I2C_UNSTUCK_TRIGGER			0x1
#define I2C_UNSTUCK_ONGOING			0x2
#define I2C_UNSTUCK_ERROR			0x4

static struct mentor_i2c_regs *base;

static int mentor_i2c_lost_arbitration(uint32_t *status)
{
	*status = mmio_read_32((uintptr_t)&base->status);
	if ((*status == I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER) ||
	    (*status == I2C_STATUS_LOST_ARB_GENERAL_CALL))
		return -EAGAIN;

	return 0;
}

static void mentor_i2c_interrupt_clear(void)
{
	uint32_t reg;

	reg = mmio_read_32((uintptr_t)&base->control);
#ifndef I2C_INTERRUPT_CLEAR_INVERTED
	reg &= ~(I2C_CONTROL_IFLG);
#else
	reg |= I2C_CONTROL_IFLG;
#endif
	mmio_write_32((uintptr_t)&base->control, reg);
	/* Wait for 1 us for the clear to take effect */
	udelay(1);
}

static int mentor_i2c_interrupt_get(void)
{
	uint32_t reg;

	/* get the interrupt flag bit */
	reg = mmio_read_32((uintptr_t)&base->control);
	reg &= I2C_CONTROL_IFLG;
	return reg && I2C_CONTROL_IFLG;
}

static int mentor_i2c_wait_interrupt(void)
{
	uint32_t timeout = 0;

	while (!mentor_i2c_interrupt_get() && (timeout++ < I2C_TIMEOUT_VALUE))
		;
	if (timeout >= I2C_TIMEOUT_VALUE)
		return -ETIMEDOUT;

	return 0;
}

static int mentor_i2c_start_bit_set(void)
{
	int is_int_flag = 0;
	uint32_t status;

	if (mentor_i2c_interrupt_get())
		is_int_flag = 1;

	/* set start bit */
	mmio_write_32((uintptr_t)&base->control,
		      mmio_read_32((uintptr_t)&base->control) |
		      I2C_CONTROL_START);

	/* in case that the int flag was set before i.e. repeated start bit */
	if (is_int_flag) {
		VERBOSE("%s: repeated start Bit\n", __func__);
		mentor_i2c_interrupt_clear();
	}

	if (mentor_i2c_wait_interrupt()) {
		ERROR("Start clear bit timeout\n");
		return -ETIMEDOUT;
	}

	/* check that start bit went down */
	if ((mmio_read_32((uintptr_t)&base->control) &
	    I2C_CONTROL_START) != 0) {
		ERROR("Start bit didn't went down\n");
		return -EPERM;
	}

	/* check the status */
	if (mentor_i2c_lost_arbitration(&status)) {
		ERROR("%s - %d: Lost arbitration, got status %x\n",
		      __func__, __LINE__, status);
		return -EAGAIN;
	}
	if ((status != I2C_STATUS_START) &&
	    (status != I2C_STATUS_REPEATED_START)) {
		ERROR("Got status %x after enable start bit.\n", status);
		return -EPERM;
	}

	return 0;
}

static int mentor_i2c_stop_bit_set(void)
{
	int timeout;
	uint32_t status;

	/* Generate stop bit */
	mmio_write_32((uintptr_t)&base->control,
		      mmio_read_32((uintptr_t)&base->control) |
		      I2C_CONTROL_STOP);
	mentor_i2c_interrupt_clear();

	timeout = 0;
	/* Read control register, check the control stop bit */
	while ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) &&
	       (timeout++ < I2C_TIMEOUT_VALUE))
		;
	if (timeout >= I2C_TIMEOUT_VALUE) {
		ERROR("Stop bit didn't went down\n");
		return -ETIMEDOUT;
	}

	/* check that stop bit went down */
	if ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) != 0) {
		ERROR("Stop bit didn't went down\n");
		return -EPERM;
	}

	/* check the status */
	if (mentor_i2c_lost_arbitration(&status)) {
		ERROR("%s - %d: Lost arbitration, got status %x\n",
		      __func__, __LINE__, status);
		return -EAGAIN;
	}
	if (status != I2C_STATUS_IDLE) {
		ERROR("Got status %x after enable stop bit.\n", status);
		return -EPERM;
	}

	return 0;
}

static int mentor_i2c_address_set(uint8_t chain, int command)
{
	uint32_t reg, status;

	reg = (chain << I2C_DATA_ADDR_7BIT_OFFS) & I2C_DATA_ADDR_7BIT_MASK;
	reg |= command;
	mmio_write_32((uintptr_t)&base->data, reg);
	udelay(1);

	mentor_i2c_interrupt_clear();

	if (mentor_i2c_wait_interrupt()) {
		ERROR("Start clear bit timeout\n");
		return -ETIMEDOUT;
	}

	/* check the status */
	if (mentor_i2c_lost_arbitration(&status)) {
		ERROR("%s - %d: Lost arbitration, got status %x\n",
		      __func__, __LINE__, status);
		return -EAGAIN;
	}
	if (((status != I2C_STATUS_ADDR_R_ACK) && (command == I2C_CMD_READ)) ||
	   ((status != I2C_STATUS_ADDR_W_ACK) && (command == I2C_CMD_WRITE))) {
		/* only in debug, since in boot we try to read the SPD
		 * of both DRAM, and we don't want error messages in cas
		 * DIMM doesn't exist.
		 */
		INFO("%s: ERROR - status %x addr in %s mode.\n", __func__,
		     status, (command == I2C_CMD_WRITE) ? "Write" : "Read");
		return -EPERM;
	}

	return 0;
}

/*
 * The I2C module contains a clock divider to generate the SCL clock.
 * This function calculates and sets the <N> and <M> fields in the I2C Baud
 * Rate Register (t=01) to obtain given 'requested_speed'.
 * The requested_speed will be equal to:
 * CONFIG_SYS_TCLK / (10 * (M + 1) * (2 << N))
 * Where M is the value represented by bits[6:3] and N is the value represented
 * by bits[2:0] of "I2C Baud Rate Register".
 * Therefore max M which can be set is 16 (2^4) and max N is 8 (2^3). So the
 * lowest possible baudrate is:
 * CONFIG_SYS_TCLK/(10 * (16 +1) * (2 << 8), which equals to:
 * CONFIG_SYS_TCLK/87040. Assuming that CONFIG_SYS_TCLK=250MHz, the lowest
 * possible frequency is ~2,872KHz.
 */
static unsigned int mentor_i2c_bus_speed_set(unsigned int requested_speed)
{
	unsigned int n, m, freq, margin, min_margin = 0xffffffff;
	unsigned int actual_n = 0, actual_m = 0;
	int val;

	/* Calculate N and M for the TWSI clock baud rate */
	for (n = 0; n < 8; n++) {
		for (m = 0; m < 16; m++) {
			freq = CONFIG_SYS_TCLK / (10 * (m + 1) * (2 << n));
			val = requested_speed - freq;
			margin = (val > 0) ? val : -val;

			if ((freq <= requested_speed) &&
			    (margin < min_margin)) {
				min_margin = margin;
				actual_n = n;
				actual_m = m;
			}
		}
	}
	VERBOSE("%s: actual_n = %u, actual_m = %u\n",
		__func__, actual_n, actual_m);
	/* Set the baud rate */
	mmio_write_32((uintptr_t)&base->baudrate, (actual_m << 3) | actual_n);

	return 0;
}

#ifdef DEBUG_I2C
static int mentor_i2c_probe(uint8_t chip)
{
	int ret = 0;

	ret = mentor_i2c_start_bit_set();
	if (ret != 0) {
		mentor_i2c_stop_bit_set();
		ERROR("%s - %d: %s", __func__, __LINE__,
		      "mentor_i2c_start_bit_set failed\n");
		return -EPERM;
	}

	ret = mentor_i2c_address_set(chip, I2C_CMD_WRITE);
	if (ret != 0) {
		mentor_i2c_stop_bit_set();
		ERROR("%s - %d: %s", __func__, __LINE__,
		      "mentor_i2c_address_set failed\n");
		return -EPERM;
	}

	mentor_i2c_stop_bit_set();

	VERBOSE("%s: successful I2C probe\n", __func__);

	return ret;
}
#endif

/* regular i2c transaction */
static int mentor_i2c_data_receive(uint8_t *p_block, uint32_t block_size)
{
	uint32_t reg, status, block_size_read = block_size;

	/* Wait for cause interrupt */
	if (mentor_i2c_wait_interrupt()) {
		ERROR("Start clear bit timeout\n");
		return -ETIMEDOUT;
	}
	while (block_size_read) {
		if (block_size_read == 1) {
			reg = mmio_read_32((uintptr_t)&base->control);
			reg &= ~(I2C_CONTROL_ACK);
			mmio_write_32((uintptr_t)&base->control, reg);
		}
		mentor_i2c_interrupt_clear();

		if (mentor_i2c_wait_interrupt()) {
			ERROR("Start clear bit timeout\n");
			return -ETIMEDOUT;
		}
		/* check the status */
		if (mentor_i2c_lost_arbitration(&status)) {
			ERROR("%s - %d: Lost arbitration, got status %x\n",
			      __func__, __LINE__, status);
			return -EAGAIN;
		}
		if ((status != I2C_STATUS_DATA_R_ACK) &&
		    (block_size_read != 1)) {
			ERROR("Status %x in read transaction\n", status);
			return -EPERM;
		}
		if ((status != I2C_STATUS_DATA_R_NAK) &&
		    (block_size_read == 1)) {
			ERROR("Status %x in Rd Terminate\n", status);
			return -EPERM;
		}

		/* read the data */
		*p_block = (uint8_t) mmio_read_32((uintptr_t)&base->data);
		VERBOSE("%s: place %d read %x\n", __func__,
			block_size - block_size_read, *p_block);
		p_block++;
		block_size_read--;
	}

	return 0;
}

static int mentor_i2c_data_transmit(uint8_t *p_block, uint32_t block_size)
{
	uint32_t status, block_size_write = block_size;

	if (mentor_i2c_wait_interrupt()) {
		ERROR("Start clear bit timeout\n");
		return -ETIMEDOUT;
	}

	while (block_size_write) {
		/* write the data */
		mmio_write_32((uintptr_t)&base->data, (uint32_t) *p_block);
		VERBOSE("%s: index = %d, data = %x\n", __func__,
			block_size - block_size_write, *p_block);
		p_block++;
		block_size_write--;

		mentor_i2c_interrupt_clear();

		if (mentor_i2c_wait_interrupt()) {
			ERROR("Start clear bit timeout\n");
			return -ETIMEDOUT;
		}

		/* check the status */
		if (mentor_i2c_lost_arbitration(&status)) {
			ERROR("%s - %d: Lost arbitration, got status %x\n",
			      __func__, __LINE__, status);
			return -EAGAIN;
		}
		if (status != I2C_STATUS_DATA_W_ACK) {
			ERROR("Status %x in write transaction\n", status);
			return -EPERM;
		}
	}

	return 0;
}

static int mentor_i2c_target_offset_set(uint8_t chip, uint32_t addr, int alen)
{
	uint8_t off_block[2];
	uint32_t off_size;

	if (alen == 2) { /* 2-byte addresses support */
		off_block[0] = (addr >> 8) & 0xff;
		off_block[1] = addr & 0xff;
		off_size = 2;
	} else { /* 1-byte addresses support */
		off_block[0] = addr & 0xff;
		off_size = 1;
	}
	VERBOSE("%s: off_size = %x addr1 = %x addr2 = %x\n", __func__,
		off_size, off_block[0], off_block[1]);
	return mentor_i2c_data_transmit(off_block, off_size);
}

#ifdef I2C_CAN_UNSTUCK
static int mentor_i2c_unstuck(int ret)
{
	uint32_t v;

	if (ret != -ETIMEDOUT)
		return ret;
	VERBOSE("Trying to \"unstuck i2c\"... ");
	i2c_init(base);
	mmio_write_32((uintptr_t)&base->unstuck, I2C_UNSTUCK_TRIGGER);
	do {
		v = mmio_read_32((uintptr_t)&base->unstuck);
	} while (v & I2C_UNSTUCK_ONGOING);

	if (v & I2C_UNSTUCK_ERROR) {
		VERBOSE("failed - soft reset i2c\n");
		ret = -EPERM;
	} else {
		VERBOSE("ok\n");
		i2c_init(base);
		ret = -EAGAIN;
	}
	return ret;
}
#else
static int mentor_i2c_unstuck(int ret)
{
	VERBOSE("Cannot \"unstuck i2c\" - soft reset i2c\n");
	return -EPERM;
}
#endif

/*
 * API Functions
 */
void i2c_init(void *i2c_base)
{
	/* For I2C speed and slave address, now we do not set them since
	 * we just provide the working speed and slave address otherwhere
	 * for i2c_init
	 */
	base = (struct mentor_i2c_regs *)i2c_base;

	/* Reset the I2C logic */
	mmio_write_32((uintptr_t)&base->soft_reset, 0);

	udelay(200);

	mentor_i2c_bus_speed_set(CONFIG_SYS_I2C_SPEED);

	/* Enable the I2C and slave */
	mmio_write_32((uintptr_t)&base->control,
		      I2C_CONTROL_TWSIEN | I2C_CONTROL_ACK);

	/* set the I2C slave address */
	mmio_write_32((uintptr_t)&base->xtnd_slave_addr, 0);
	mmio_write_32((uintptr_t)&base->slave_address, CONFIG_SYS_I2C_SLAVE);

	/* unmask I2C interrupt */
	mmio_write_32((uintptr_t)&base->control,
		      mmio_read_32((uintptr_t)&base->control) |
		      I2C_CONTROL_INTEN);

	udelay(10);
}

/*
 * i2c_read: - Read multiple bytes from an i2c device
 *
 * The higher level routines take into account that this function is only
 * called with len < page length of the device (see configuration file)
 *
 * @chip:	address of the chip which is to be read
 * @addr:	i2c data address within the chip
 * @alen:	length of the i2c data address (1..2 bytes)
 * @buffer:	where to write the data
 * @len:	how much byte do we want to read
 * @return:	0 in case of success
 */
int i2c_read(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
{
	int ret = 0;
	uint32_t counter = 0;

#ifdef DEBUG_I2C
	mentor_i2c_probe(chip);
#endif

	do {
		if (ret != -EAGAIN && ret) {
			ERROR("i2c transaction failed, after %d retries\n",
			      counter);
			mentor_i2c_stop_bit_set();
			return ret;
		}

		/* wait for 1 us for the interrupt clear to take effect */
		if (counter > 0)
			udelay(1);
		counter++;

		ret = mentor_i2c_start_bit_set();
		if (ret) {
			ret = mentor_i2c_unstuck(ret);
			continue;
		}

		/* if EEPROM device */
		if (alen != 0) {
			ret = mentor_i2c_address_set(chip, I2C_CMD_WRITE);
			if (ret)
				continue;

			ret = mentor_i2c_target_offset_set(chip, addr, alen);
			if (ret)
				continue;
			ret = mentor_i2c_start_bit_set();
			if (ret)
				continue;
		}

		ret =  mentor_i2c_address_set(chip, I2C_CMD_READ);
		if (ret)
			continue;

		ret = mentor_i2c_data_receive(buffer, len);
		if (ret)
			continue;

		ret =  mentor_i2c_stop_bit_set();
	} while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT));

	if (counter == I2C_MAX_RETRY_CNT) {
		ERROR("I2C transactions failed, got EAGAIN %d times\n",
		      I2C_MAX_RETRY_CNT);
		ret = -EPERM;
	}
	mmio_write_32((uintptr_t)&base->control,
		      mmio_read_32((uintptr_t)&base->control) |
		      I2C_CONTROL_ACK);

	udelay(1);
	return ret;
}

/*
 * i2c_write: -  Write multiple bytes to an i2c device
 *
 * The higher level routines take into account that this function is only
 * called with len < page length of the device (see configuration file)
 *
 * @chip:	address of the chip which is to be written
 * @addr:	i2c data address within the chip
 * @alen:	length of the i2c data address (1..2 bytes)
 * @buffer:	where to find the data to be written
 * @len:	how much byte do we want to read
 * @return:	0 in case of success
 */
int i2c_write(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
{
	int ret = 0;
	uint32_t counter = 0;

	do {
		if (ret != -EAGAIN && ret) {
			ERROR("i2c transaction failed\n");
			mentor_i2c_stop_bit_set();
			return ret;
		}
		/* wait for 1 us for the interrupt clear to take effect */
		if (counter > 0)
			udelay(1);
		counter++;

		ret = mentor_i2c_start_bit_set();
		if (ret) {
			ret = mentor_i2c_unstuck(ret);
			continue;
		}

		ret = mentor_i2c_address_set(chip, I2C_CMD_WRITE);
		if (ret)
			continue;

		/* if EEPROM device */
		if (alen != 0) {
			ret = mentor_i2c_target_offset_set(chip, addr, alen);
			if (ret)
				continue;
		}

		ret = mentor_i2c_data_transmit(buffer, len);
		if (ret)
			continue;

		ret = mentor_i2c_stop_bit_set();
	} while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT));

	if (counter == I2C_MAX_RETRY_CNT) {
		ERROR("I2C transactions failed, got EAGAIN %d times\n",
		      I2C_MAX_RETRY_CNT);
		ret = -EPERM;
	}

	udelay(1);
	return ret;
}
