/*
 * Copyright (C) 2018 Marvell International Ltd.
 *
 * SPDX-License-Identifier:     BSD-3-Clause
 * https://spdx.org/licenses
 */

/* This driver provides I2C support for Marvell A8K and compatible SoCs */

#include <a8k_i2c.h>
#include <debug.h>
#include <delay_timer.h>
#include <errno.h>
#include <mmio.h>
#include <mvebu_def.h>

#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
#define DEBUG_I2C
#endif

#define CONFIG_SYS_TCLK			250000000
#define CONFIG_SYS_I2C_SPEED		100000
#define CONFIG_SYS_I2C_SLAVE		0x0
#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
struct  marvell_i2c_regs {
	uint32_t slave_address;
	uint32_t data;
	uint32_t control;
	union {
		uint32_t status;	/* when reading */
		uint32_t baudrate;	/* when writing */
	} u;
	uint32_t xtnd_slave_addr;
	uint32_t reserved[2];
	uint32_t soft_reset;
	uint8_t  reserved2[0xa0 - 0x20];
	uint32_t unstuck;
};

static struct marvell_i2c_regs *base;

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

	return 0;
}

static void marvell_i2c_interrupt_clear(void)
{
	uint32_t reg;

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

static int marvell_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 marvell_i2c_wait_interrupt(void)
{
	uint32_t timeout = 0;

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

	return 0;
}

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

	if (marvell_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__);
		marvell_i2c_interrupt_clear();
	}

	if (marvell_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 (marvell_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 marvell_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);
	marvell_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 (marvell_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 marvell_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);

	marvell_i2c_interrupt_clear();

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

	/* check the status */
	if (marvell_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 marvell_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->u.baudrate, (actual_m << 3) | actual_n);

	return 0;
}

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

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

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

	marvell_i2c_stop_bit_set();

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

	return ret;
}
#endif

/* regular i2c transaction */
static int marvell_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 (marvell_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);
		}
		marvell_i2c_interrupt_clear();

		if (marvell_i2c_wait_interrupt()) {
			ERROR("Start clear bit timeout\n");
			return -ETIMEDOUT;
		}
		/* check the status */
		if (marvell_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 marvell_i2c_data_transmit(uint8_t *p_block, uint32_t block_size)
{
	uint32_t status, block_size_write = block_size;

	if (marvell_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--;

		marvell_i2c_interrupt_clear();

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

		/* check the status */
		if (marvell_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 marvell_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 marvell_i2c_data_transmit(off_block, off_size);
}

static int marvell_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;
}

/*
 * 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 in plat_def.h
	 * for i2c_init
	 */
	base = (struct marvell_i2c_regs *)i2c_base;

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

	udelay(200);

	marvell_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
	marvell_i2c_probe(chip);
#endif

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

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

		ret = marvell_i2c_start_bit_set();
		if (ret) {
			ret = marvell_i2c_unstuck(ret);
			continue;
		}

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

			ret = marvell_i2c_target_offset_set(chip, addr, alen);
			if (ret)
				continue;
			ret = marvell_i2c_start_bit_set();
			if (ret)
				continue;
		}

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

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

		ret =  marvell_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");
			marvell_i2c_stop_bit_set();
			return ret;
		}
		/* wait for 1 us for the interrupt clear to take effect */
		if (counter > 0)
			udelay(1);
		counter++;

		ret = marvell_i2c_start_bit_set();
		if (ret) {
			ret = marvell_i2c_unstuck(ret);
			continue;
		}

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

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

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

		ret = marvell_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;
}
