// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2016, Google Inc
 *
 * (C) Copyright 2002
 * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
 */

#include <dm.h>
#include <i2c.h>
#include <log.h>
#include <asm/arch/clk.h>
#include <asm/arch/cpu.h>
#include <asm/arch/pinmux.h>
#include <asm/global_data.h>
#include <linux/delay.h>
#include "s3c24x0_i2c.h"

DECLARE_GLOBAL_DATA_PTR;

/* HSI2C-specific register description */

/* I2C_CTL Register bits */
#define HSI2C_FUNC_MODE_I2C		(1u << 0)
#define HSI2C_MASTER			(1u << 3)
#define HSI2C_RXCHON			(1u << 6)	/* Write/Send */
#define HSI2C_TXCHON			(1u << 7)	/* Read/Receive */
#define HSI2C_SW_RST			(1u << 31)

/* I2C_FIFO_CTL Register bits */
#define HSI2C_RXFIFO_EN			(1u << 0)
#define HSI2C_TXFIFO_EN			(1u << 1)
#define HSI2C_TXFIFO_TRIGGER_LEVEL	(0x20 << 16)
#define HSI2C_RXFIFO_TRIGGER_LEVEL	(0x20 << 4)

/* I2C_TRAILING_CTL Register bits */
#define HSI2C_TRAILING_COUNT		(0xff)

/* I2C_INT_EN Register bits */
#define HSI2C_TX_UNDERRUN_EN		(1u << 2)
#define HSI2C_TX_OVERRUN_EN		(1u << 3)
#define HSI2C_RX_UNDERRUN_EN		(1u << 4)
#define HSI2C_RX_OVERRUN_EN		(1u << 5)
#define HSI2C_INT_TRAILING_EN		(1u << 6)
#define HSI2C_INT_I2C_EN		(1u << 9)

#define HSI2C_INT_ERROR_MASK	(HSI2C_TX_UNDERRUN_EN |\
				 HSI2C_TX_OVERRUN_EN  |\
				 HSI2C_RX_UNDERRUN_EN |\
				 HSI2C_RX_OVERRUN_EN  |\
				 HSI2C_INT_TRAILING_EN)

/* I2C_CONF Register bits */
#define HSI2C_AUTO_MODE			(1u << 31)
#define HSI2C_10BIT_ADDR_MODE		(1u << 30)
#define HSI2C_HS_MODE			(1u << 29)

/* I2C_AUTO_CONF Register bits */
#define HSI2C_READ_WRITE		(1u << 16)
#define HSI2C_STOP_AFTER_TRANS		(1u << 17)
#define HSI2C_MASTER_RUN		(1u << 31)

/* I2C_TIMEOUT Register bits */
#define HSI2C_TIMEOUT_EN		(1u << 31)

/* I2C_TRANS_STATUS register bits */
#define HSI2C_MASTER_BUSY		(1u << 17)
#define HSI2C_SLAVE_BUSY		(1u << 16)
#define HSI2C_TIMEOUT_AUTO		(1u << 4)
#define HSI2C_NO_DEV			(1u << 3)
#define HSI2C_NO_DEV_ACK		(1u << 2)
#define HSI2C_TRANS_ABORT		(1u << 1)
#define HSI2C_TRANS_SUCCESS		(1u << 0)
#define HSI2C_TRANS_ERROR_MASK	(HSI2C_TIMEOUT_AUTO |\
				 HSI2C_NO_DEV | HSI2C_NO_DEV_ACK |\
				 HSI2C_TRANS_ABORT)
#define HSI2C_TRANS_FINISHED_MASK (HSI2C_TRANS_ERROR_MASK | HSI2C_TRANS_SUCCESS)


/* I2C_FIFO_STAT Register bits */
#define HSI2C_RX_FIFO_EMPTY		(1u << 24)
#define HSI2C_RX_FIFO_FULL		(1u << 23)
#define HSI2C_TX_FIFO_EMPTY		(1u << 8)
#define HSI2C_TX_FIFO_FULL		(1u << 7)
#define HSI2C_RX_FIFO_LEVEL(x)		(((x) >> 16) & 0x7f)
#define HSI2C_TX_FIFO_LEVEL(x)		((x) & 0x7f)

#define HSI2C_SLV_ADDR_MAS(x)		((x & 0x3ff) << 10)

#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */

/*
 * Wait for transfer completion.
 *
 * This function reads the interrupt status register waiting for the INT_I2C
 * bit to be set, which indicates copletion of a transaction.
 *
 * @param i2c: pointer to the appropriate register bank
 *
 * @return: I2C_OK in case of successful completion, I2C_NOK_TIMEOUT in case
 *          the status bits do not get set in time, or an approrpiate error
 *          value in case of transfer errors.
 */
static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c)
{
	int i = HSI2C_TIMEOUT_US;

	while (i-- > 0) {
		u32 int_status = readl(&i2c->usi_int_stat);

		if (int_status & HSI2C_INT_I2C_EN) {
			u32 trans_status = readl(&i2c->usi_trans_status);

			/* Deassert pending interrupt. */
			writel(int_status, &i2c->usi_int_stat);

			if (trans_status & HSI2C_NO_DEV_ACK) {
				debug("%s: no ACK from device\n", __func__);
				return I2C_NACK;
			}
			if (trans_status & HSI2C_NO_DEV) {
				debug("%s: no device\n", __func__);
				return I2C_NOK;
			}
			if (trans_status & HSI2C_TRANS_ABORT) {
				debug("%s: arbitration lost\n", __func__);
				return I2C_NOK_LA;
			}
			if (trans_status & HSI2C_TIMEOUT_AUTO) {
				debug("%s: device timed out\n", __func__);
				return I2C_NOK_TOUT;
			}
			return I2C_OK;
		}
		udelay(1);
	}
	debug("%s: transaction timeout!\n", __func__);
	return I2C_NOK_TOUT;
}

static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)
{
	struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
	ulong clkin;
	unsigned int op_clk = i2c_bus->clock_frequency;
	unsigned int i = 0, utemp0 = 0, utemp1 = 0;
	unsigned int t_ftl_cycle;

#if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
	clkin = get_i2c_clk();
#else
	clkin = get_PCLK();
#endif
	/* FPCLK / FI2C =
	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
	 * uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
	 * uTemp1 = (TSCLK_L + TSCLK_H + 2)
	 * uTemp2 = TSCLK_L + TSCLK_H
	 */
	t_ftl_cycle = (readl(&hsregs->usi_conf) >> 16) & 0x7;
	utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle;

	/* CLK_DIV max is 256 */
	for (i = 0; i < 256; i++) {
		utemp1 = utemp0 / (i + 1);
		if ((utemp1 < 512) && (utemp1 > 4)) {
			i2c_bus->clk_cycle = utemp1 - 2;
			i2c_bus->clk_div = i;
			return 0;
		}
	}
	return -EINVAL;
}

static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus)
{
	struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
	unsigned int t_sr_release;
	unsigned int n_clkdiv;
	unsigned int t_start_su, t_start_hd;
	unsigned int t_stop_su;
	unsigned int t_data_su, t_data_hd;
	unsigned int t_scl_l, t_scl_h;
	u32 i2c_timing_s1;
	u32 i2c_timing_s2;
	u32 i2c_timing_s3;
	u32 i2c_timing_sla;

	n_clkdiv = i2c_bus->clk_div;
	t_scl_l = i2c_bus->clk_cycle / 2;
	t_scl_h = i2c_bus->clk_cycle / 2;
	t_start_su = t_scl_l;
	t_start_hd = t_scl_l;
	t_stop_su = t_scl_l;
	t_data_su = t_scl_l / 2;
	t_data_hd = t_scl_l / 2;
	t_sr_release = i2c_bus->clk_cycle;

	i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8;
	i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0;
	i2c_timing_s3 = n_clkdiv << 16 | t_sr_release << 0;
	i2c_timing_sla = t_data_hd << 0;

	writel(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl);

	/* Clear to enable Timeout */
	clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0);

	/* set AUTO mode */
	writel(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf);

	/* Enable completion conditions' reporting. */
	writel(HSI2C_INT_I2C_EN, &hsregs->usi_int_en);

	/* Enable FIFOs */
	writel(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl);

	/* Currently operating in Fast speed mode. */
	writel(i2c_timing_s1, &hsregs->usi_timing_fs1);
	writel(i2c_timing_s2, &hsregs->usi_timing_fs2);
	writel(i2c_timing_s3, &hsregs->usi_timing_fs3);
	writel(i2c_timing_sla, &hsregs->usi_timing_sla);
}

/* SW reset for the high speed bus */
static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus)
{
	struct exynos5_hsi2c *i2c = i2c_bus->hsregs;
	u32 i2c_ctl;

	/* Set and clear the bit for reset */
	i2c_ctl = readl(&i2c->usi_ctl);
	i2c_ctl |= HSI2C_SW_RST;
	writel(i2c_ctl, &i2c->usi_ctl);

	i2c_ctl = readl(&i2c->usi_ctl);
	i2c_ctl &= ~HSI2C_SW_RST;
	writel(i2c_ctl, &i2c->usi_ctl);

	/* Initialize the configure registers */
	hsi2c_ch_init(i2c_bus);
}

/*
 * Poll the appropriate bit of the fifo status register until the interface is
 * ready to process the next byte or timeout expires.
 *
 * In addition to the FIFO status register this function also polls the
 * interrupt status register to be able to detect unexpected transaction
 * completion.
 *
 * When FIFO is ready to process the next byte, this function returns I2C_OK.
 * If in course of polling the INT_I2C assertion is detected, the function
 * returns I2C_NOK. If timeout happens before any of the above conditions is
 * met - the function returns I2C_NOK_TOUT;

 * @param i2c: pointer to the appropriate i2c register bank.
 * @param rx_transfer: set to True if the receive transaction is in progress.
 * @return: as described above.
 */
static unsigned hsi2c_poll_fifo(struct exynos5_hsi2c *i2c, bool rx_transfer)
{
	u32 fifo_bit = rx_transfer ? HSI2C_RX_FIFO_EMPTY : HSI2C_TX_FIFO_FULL;
	int i = HSI2C_TIMEOUT_US;

	while (readl(&i2c->usi_fifo_stat) & fifo_bit) {
		if (readl(&i2c->usi_int_stat) & HSI2C_INT_I2C_EN) {
			/*
			 * There is a chance that assertion of
			 * HSI2C_INT_I2C_EN and deassertion of
			 * HSI2C_RX_FIFO_EMPTY happen simultaneously. Let's
			 * give FIFO status priority and check it one more
			 * time before reporting interrupt. The interrupt will
			 * be reported next time this function is called.
			 */
			if (rx_transfer &&
			    !(readl(&i2c->usi_fifo_stat) & fifo_bit))
				break;
			return I2C_NOK;
		}
		if (!i--) {
			debug("%s: FIFO polling timeout!\n", __func__);
			return I2C_NOK_TOUT;
		}
		udelay(1);
	}
	return I2C_OK;
}

/*
 * Preapre hsi2c transaction, either read or write.
 *
 * Set up transfer as described in section 27.5.1.2 'I2C Channel Auto Mode' of
 * the 5420 UM.
 *
 * @param i2c: pointer to the appropriate i2c register bank.
 * @param chip: slave address on the i2c bus (with read/write bit exlcuded)
 * @param len: number of bytes expected to be sent or received
 * @param rx_transfer: set to true for receive transactions
 * @param: issue_stop: set to true if i2c stop condition should be generated
 *         after this transaction.
 * @return: I2C_NOK_TOUT in case the bus remained busy for HSI2C_TIMEOUT_US,
 *          I2C_OK otherwise.
 */
static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c,
				     u8 chip,
				     u16 len,
				     bool rx_transfer,
				     bool issue_stop)
{
	u32 conf;

	conf = len | HSI2C_MASTER_RUN;

	if (issue_stop)
		conf |= HSI2C_STOP_AFTER_TRANS;

	/* Clear to enable Timeout */
	writel(readl(&i2c->usi_timeout) & ~HSI2C_TIMEOUT_EN, &i2c->usi_timeout);

	/* Set slave address */
	writel(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr);

	if (rx_transfer) {
		/* i2c master, read transaction */
		writel((HSI2C_RXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
		       &i2c->usi_ctl);

		/* read up to len bytes, stop after transaction is finished */
		writel(conf | HSI2C_READ_WRITE, &i2c->usi_auto_conf);
	} else {
		/* i2c master, write transaction */
		writel((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
		       &i2c->usi_ctl);

		/* write up to len bytes, stop after transaction is finished */
		writel(conf, &i2c->usi_auto_conf);
	}

	/* Reset all pending interrupt status bits we care about, if any */
	writel(HSI2C_INT_I2C_EN, &i2c->usi_int_stat);

	return I2C_OK;
}

/*
 * Wait while i2c bus is settling down (mostly stop gets completed).
 */
static int hsi2c_wait_while_busy(struct exynos5_hsi2c *i2c)
{
	int i = HSI2C_TIMEOUT_US;

	while (readl(&i2c->usi_trans_status) & HSI2C_MASTER_BUSY) {
		if (!i--) {
			debug("%s: bus busy\n", __func__);
			return I2C_NOK_TOUT;
		}
		udelay(1);
	}
	return I2C_OK;
}

static int hsi2c_write(struct exynos5_hsi2c *i2c,
		       unsigned char chip,
		       unsigned char addr[],
		       unsigned char alen,
		       unsigned char data[],
		       unsigned short len,
		       bool issue_stop)
{
	int i, rv = 0;

	if (!(len + alen)) {
		/* Writes of zero length not supported in auto mode. */
		debug("%s: zero length writes not supported\n", __func__);
		return I2C_NOK;
	}

	rv = hsi2c_prepare_transaction
		(i2c, chip, len + alen, false, issue_stop);
	if (rv != I2C_OK)
		return rv;

	/* Move address, if any, and the data, if any, into the FIFO. */
	for (i = 0; i < alen; i++) {
		rv = hsi2c_poll_fifo(i2c, false);
		if (rv != I2C_OK) {
			debug("%s: address write failed\n", __func__);
			goto write_error;
		}
		writel(addr[i], &i2c->usi_txdata);
	}

	for (i = 0; i < len; i++) {
		rv = hsi2c_poll_fifo(i2c, false);
		if (rv != I2C_OK) {
			debug("%s: data write failed\n", __func__);
			goto write_error;
		}
		writel(data[i], &i2c->usi_txdata);
	}

	rv = hsi2c_wait_for_trx(i2c);

 write_error:
	if (issue_stop) {
		int tmp_ret = hsi2c_wait_while_busy(i2c);
		if (rv == I2C_OK)
			rv = tmp_ret;
	}

	writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
	return rv;
}

static int hsi2c_read(struct exynos5_hsi2c *i2c,
		      unsigned char chip,
		      unsigned char addr[],
		      unsigned char alen,
		      unsigned char data[],
		      unsigned short len)
{
	int i, rv, tmp_ret;
	bool drop_data = false;

	if (!len) {
		/* Reads of zero length not supported in auto mode. */
		debug("%s: zero length read adjusted\n", __func__);
		drop_data = true;
		len = 1;
	}

	if (alen) {
		/* Internal register adress needs to be written first. */
		rv = hsi2c_write(i2c, chip, addr, alen, NULL, 0, false);
		if (rv != I2C_OK)
			return rv;
	}

	rv = hsi2c_prepare_transaction(i2c, chip, len, true, true);

	if (rv != I2C_OK)
		return rv;

	for (i = 0; i < len; i++) {
		rv = hsi2c_poll_fifo(i2c, true);
		if (rv != I2C_OK)
			goto read_err;
		if (drop_data)
			continue;
		data[i] = readl(&i2c->usi_rxdata);
	}

	rv = hsi2c_wait_for_trx(i2c);

 read_err:
	tmp_ret = hsi2c_wait_while_busy(i2c);
	if (rv == I2C_OK)
		rv = tmp_ret;

	writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
	return rv;
}

static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
			      int nmsgs)
{
	struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
	struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
	int ret;

	for (; nmsgs > 0; nmsgs--, msg++) {
		if (msg->flags & I2C_M_RD) {
			ret = hsi2c_read(hsregs, msg->addr, 0, 0, msg->buf,
					 msg->len);
		} else {
			ret = hsi2c_write(hsregs, msg->addr, 0, 0, msg->buf,
					  msg->len, true);
		}
		if (ret) {
			exynos5_i2c_reset(i2c_bus);
			return -EREMOTEIO;
		}
	}

	return 0;
}

static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
{
	struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);

	i2c_bus->clock_frequency = speed;

	if (hsi2c_get_clk_details(i2c_bus))
		return -EFAULT;
	hsi2c_ch_init(i2c_bus);

	return 0;
}

static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags)
{
	struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
	uchar buf[1];
	int ret;

	buf[0] = 0;

	/*
	 * What is needed is to send the chip address and verify that the
	 * address was <ACK>ed (i.e. there was a chip at that address which
	 * drove the data line low).
	 */
	ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buf, 1);

	return ret != I2C_OK;
}

static int s3c_i2c_of_to_plat(struct udevice *dev)
{
	const void *blob = gd->fdt_blob;
	struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
	int node;

	node = dev_of_offset(dev);

	i2c_bus->hsregs = dev_read_addr_ptr(dev);

	i2c_bus->id = pinmux_decode_periph_id(blob, node);

	i2c_bus->clock_frequency =
		dev_read_u32_default(dev, "clock-frequency",
				     I2C_SPEED_STANDARD_RATE);
	i2c_bus->node = node;
	i2c_bus->bus_num = dev_seq(dev);

	exynos_pinmux_config(i2c_bus->id, PINMUX_FLAG_HS_MODE);

	i2c_bus->active = true;

	return 0;
}

static const struct dm_i2c_ops exynos_hs_i2c_ops = {
	.xfer		= exynos_hs_i2c_xfer,
	.probe_chip	= s3c24x0_i2c_probe,
	.set_bus_speed	= s3c24x0_i2c_set_bus_speed,
};

static const struct udevice_id exynos_hs_i2c_ids[] = {
	{ .compatible = "samsung,exynos5-hsi2c" },
	{ }
};

U_BOOT_DRIVER(hs_i2c) = {
	.name	= "i2c_s3c_hs",
	.id	= UCLASS_I2C,
	.of_match = exynos_hs_i2c_ids,
	.of_to_plat = s3c_i2c_of_to_plat,
	.priv_auto	= sizeof(struct s3c24x0_i2c_bus),
	.ops	= &exynos_hs_i2c_ops,
};
