// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Copyright (c) 2010-2011 NVIDIA Corporation
 *  NVIDIA Corporation <www.nvidia.com>
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <i2c.h>
#include <log.h>
#include <asm/io.h>
#include <clk.h>
#include <reset.h>
#ifndef CONFIG_TEGRA186
#include <asm/arch/clock.h>
#include <asm/arch/funcmux.h>
#endif
#include <asm/arch/gpio.h>
#include <asm/arch-tegra/tegra_i2c.h>
#include <linux/delay.h>
#include <linux/err.h>

enum i2c_type {
	TYPE_114,
	TYPE_STD,
	TYPE_DVC,
};

/* Information about i2c controller */
struct i2c_bus {
	int			id;
	struct reset_ctl	reset_ctl;
	struct clk		clk;
	int			speed;
	int			pinmux_config;
	struct i2c_control	*control;
	struct i2c_ctlr		*regs;
	enum i2c_type		type;
	int			inited;	/* bus is inited */
};

static void set_packet_mode(struct i2c_bus *i2c_bus)
{
	u32 config;

	config = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK;

	if (i2c_bus->type == TYPE_DVC) {
		struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;

		writel(config, &dvc->cnfg);
	} else {
		writel(config, &i2c_bus->regs->cnfg);
		/*
		 * program I2C_SL_CNFG.NEWSL to ENABLE. This fixes probe
		 * issues, i.e., some slaves may be wrongly detected.
		 */
		setbits_le32(&i2c_bus->regs->sl_cnfg, I2C_SL_CNFG_NEWSL_MASK);
	}
}

static void i2c_reset_controller(struct i2c_bus *i2c_bus)
{
	/* Reset I2C controller. */
	reset_assert(&i2c_bus->reset_ctl);
	udelay(1);
	reset_deassert(&i2c_bus->reset_ctl);
	udelay(1);

	/* re-program config register to packet mode */
	set_packet_mode(i2c_bus);
}

static int i2c_init_clock(struct i2c_bus *i2c_bus, unsigned rate)
{
	int ret;

	ret = reset_assert(&i2c_bus->reset_ctl);
	if (ret)
		return ret;
	ret = clk_enable(&i2c_bus->clk);
	if (ret)
		return ret;
	ret = clk_set_rate(&i2c_bus->clk, rate);
	if (IS_ERR_VALUE(ret))
		return ret;
	ret = reset_deassert(&i2c_bus->reset_ctl);
	if (ret)
		return ret;

	return 0;
}

static void i2c_init_controller(struct i2c_bus *i2c_bus)
{
	if (!i2c_bus->speed)
		return;
	debug("%s: speed=%d\n", __func__, i2c_bus->speed);
	/*
	 * Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8
	 * here, in section 23.3.1, but in fact we seem to need a factor of
	 * 16 to get the right frequency.
	 */
	i2c_init_clock(i2c_bus, i2c_bus->speed * 2 * 8);

	if (i2c_bus->type == TYPE_114) {
		/*
		 * T114 I2C went to a single clock source for standard/fast and
		 * HS clock speeds. The new clock rate setting calculation is:
		 *  SCL = CLK_SOURCE.I2C /
		 *   (CLK_MULT_STD_FAST_MODE * (I2C_CLK_DIV_STD_FAST_MODE+1) *
		 *   I2C FREQUENCY DIVISOR) as per the T114 TRM (sec 30.3.1).
		 *
		 * NOTE: We do this here, after the initial clock/pll start,
		 * because if we read the clk_div reg before the controller
		 * is running, we hang, and we need it for the new calc.
		 */
		int clk_div_stdfst_mode = readl(&i2c_bus->regs->clk_div) >> 16;
		unsigned rate = CLK_MULT_STD_FAST_MODE *
				(clk_div_stdfst_mode + 1) * i2c_bus->speed * 2;
		debug("%s: CLK_DIV_STD_FAST_MODE setting = %d\n", __func__,
			clk_div_stdfst_mode);

		i2c_init_clock(i2c_bus, rate);
	}

	/* Reset I2C controller. */
	i2c_reset_controller(i2c_bus);

	/* Configure I2C controller. */
	if (i2c_bus->type == TYPE_DVC) {	/* only for DVC I2C */
		struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;

		setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK);
	}

#ifndef CONFIG_TEGRA186
	funcmux_select(i2c_bus->clk.id, i2c_bus->pinmux_config);
#endif
}

static void send_packet_headers(
	struct i2c_bus *i2c_bus,
	struct i2c_trans_info *trans,
	u32 packet_id,
	bool end_with_repeated_start)
{
	u32 data;

	/* prepare header1: Header size = 0 Protocol = I2C, pktType = 0 */
	data = PROTOCOL_TYPE_I2C << PKT_HDR1_PROTOCOL_SHIFT;
	data |= packet_id << PKT_HDR1_PKT_ID_SHIFT;
	data |= i2c_bus->id << PKT_HDR1_CTLR_ID_SHIFT;
	writel(data, &i2c_bus->control->tx_fifo);
	debug("pkt header 1 sent (0x%x)\n", data);

	/* prepare header2 */
	data = (trans->num_bytes - 1) << PKT_HDR2_PAYLOAD_SIZE_SHIFT;
	writel(data, &i2c_bus->control->tx_fifo);
	debug("pkt header 2 sent (0x%x)\n", data);

	/* prepare IO specific header: configure the slave address */
	data = trans->address << PKT_HDR3_SLAVE_ADDR_SHIFT;

	/* Enable Read if it is not a write transaction */
	if (!(trans->flags & I2C_IS_WRITE))
		data |= PKT_HDR3_READ_MODE_MASK;
	if (end_with_repeated_start)
		data |= PKT_HDR3_REPEAT_START_MASK;

	/* Write I2C specific header */
	writel(data, &i2c_bus->control->tx_fifo);
	debug("pkt header 3 sent (0x%x)\n", data);
}

static int wait_for_tx_fifo_empty(struct i2c_control *control)
{
	u32 count;
	int timeout_us = I2C_TIMEOUT_USEC;

	while (timeout_us >= 0) {
		count = (readl(&control->fifo_status) & TX_FIFO_EMPTY_CNT_MASK)
				>> TX_FIFO_EMPTY_CNT_SHIFT;
		if (count == I2C_FIFO_DEPTH)
			return 1;
		udelay(10);
		timeout_us -= 10;
	}

	return 0;
}

static int wait_for_rx_fifo_notempty(struct i2c_control *control)
{
	u32 count;
	int timeout_us = I2C_TIMEOUT_USEC;

	while (timeout_us >= 0) {
		count = (readl(&control->fifo_status) & TX_FIFO_FULL_CNT_MASK)
				>> TX_FIFO_FULL_CNT_SHIFT;
		if (count)
			return 1;
		udelay(10);
		timeout_us -= 10;
	}

	return 0;
}

static int wait_for_transfer_complete(struct i2c_control *control)
{
	int int_status;
	int timeout_us = I2C_TIMEOUT_USEC;

	while (timeout_us >= 0) {
		int_status = readl(&control->int_status);
		if (int_status & I2C_INT_NO_ACK_MASK)
			return -int_status;
		if (int_status & I2C_INT_ARBITRATION_LOST_MASK)
			return -int_status;
		if (int_status & I2C_INT_XFER_COMPLETE_MASK)
			return 0;

		udelay(10);
		timeout_us -= 10;
	}

	return -1;
}

static int send_recv_packets(struct i2c_bus *i2c_bus,
			     struct i2c_trans_info *trans)
{
	struct i2c_control *control = i2c_bus->control;
	u32 int_status;
	u32 words;
	u8 *dptr;
	u32 local;
	uchar last_bytes;
	int error = 0;
	int is_write = trans->flags & I2C_IS_WRITE;

	/* clear status from previous transaction, XFER_COMPLETE, NOACK, etc. */
	int_status = readl(&control->int_status);
	writel(int_status, &control->int_status);

	send_packet_headers(i2c_bus, trans, 1,
			    trans->flags & I2C_USE_REPEATED_START);

	words = DIV_ROUND_UP(trans->num_bytes, 4);
	last_bytes = trans->num_bytes & 3;
	dptr = trans->buf;

	while (words) {
		u32 *wptr = (u32 *)dptr;

		if (is_write) {
			/* deal with word alignment */
			if ((words == 1) && last_bytes) {
				local = 0;
				memcpy(&local, dptr, last_bytes);
			} else if ((unsigned long)dptr & 3) {
				memcpy(&local, dptr, sizeof(u32));
			} else {
				local = *wptr;
			}
			writel(local, &control->tx_fifo);
			debug("pkt data sent (0x%x)\n", local);
			if (!wait_for_tx_fifo_empty(control)) {
				error = -1;
				goto exit;
			}
		} else {
			if (!wait_for_rx_fifo_notempty(control)) {
				error = -1;
				goto exit;
			}
			/*
			 * for the last word, we read into our local buffer,
			 * in case that caller did not provide enough buffer.
			 */
			local = readl(&control->rx_fifo);
			if ((words == 1) && last_bytes)
				memcpy(dptr, (char *)&local, last_bytes);
			else if ((unsigned long)dptr & 3)
				memcpy(dptr, &local, sizeof(u32));
			else
				*wptr = local;
			debug("pkt data received (0x%x)\n", local);
		}
		words--;
		dptr += sizeof(u32);
	}

	if (wait_for_transfer_complete(control)) {
		error = -1;
		goto exit;
	}
	return 0;
exit:
	/* error, reset the controller. */
	i2c_reset_controller(i2c_bus);

	return error;
}

static int tegra_i2c_write_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data,
				u32 len, bool end_with_repeated_start)
{
	int error;
	struct i2c_trans_info trans_info;

	trans_info.address = addr;
	trans_info.buf = data;
	trans_info.flags = I2C_IS_WRITE;
	if (end_with_repeated_start)
		trans_info.flags |= I2C_USE_REPEATED_START;
	trans_info.num_bytes = len;
	trans_info.is_10bit_address = 0;

	error = send_recv_packets(i2c_bus, &trans_info);
	if (error)
		debug("tegra_i2c_write_data: Error (%d) !!!\n", error);

	return error;
}

static int tegra_i2c_read_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data,
			       u32 len)
{
	int error;
	struct i2c_trans_info trans_info;

	trans_info.address = addr | 1;
	trans_info.buf = data;
	trans_info.flags = 0;
	trans_info.num_bytes = len;
	trans_info.is_10bit_address = 0;

	error = send_recv_packets(i2c_bus, &trans_info);
	if (error)
		debug("tegra_i2c_read_data: Error (%d) !!!\n", error);

	return error;
}

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

	i2c_bus->speed = speed;
	i2c_init_controller(i2c_bus);

	return 0;
}

static int tegra_i2c_probe(struct udevice *dev)
{
	struct i2c_bus *i2c_bus = dev_get_priv(dev);
	int ret;
	bool is_dvc;

	i2c_bus->id = dev_seq(dev);
	i2c_bus->type = dev_get_driver_data(dev);
	i2c_bus->regs = (struct i2c_ctlr *)dev_read_addr(dev);
	if ((ulong)i2c_bus->regs == FDT_ADDR_T_NONE) {
		debug("%s: Cannot get regs address\n", __func__);
		return -EINVAL;
	}

	ret = reset_get_by_name(dev, "i2c", &i2c_bus->reset_ctl);
	if (ret) {
		pr_err("reset_get_by_name() failed: %d\n", ret);
		return ret;
	}
	ret = clk_get_by_name(dev, "div-clk", &i2c_bus->clk);
	if (ret) {
		pr_err("clk_get_by_name() failed: %d\n", ret);
		return ret;
	}

#ifndef CONFIG_TEGRA186
	/*
	 * We don't have a binding for pinmux yet. Leave it out for now. So
	 * far no one needs anything other than the default.
	 */
	i2c_bus->pinmux_config = FUNCMUX_DEFAULT;

	/*
	 * We can't specify the pinmux config in the fdt, so I2C2 will not
	 * work on Seaboard. It normally has no devices on it anyway.
	 * You could add in this little hack if you need to use it.
	 * The correct solution is a pinmux binding in the fdt.
	 *
	 *	if (i2c_bus->clk.id == PERIPH_ID_I2C2)
	 *		i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA;
	 */
#endif

	is_dvc = dev_get_driver_data(dev) == TYPE_DVC;
	if (is_dvc) {
		i2c_bus->control =
			&((struct dvc_ctlr *)i2c_bus->regs)->control;
	} else {
		i2c_bus->control = &i2c_bus->regs->control;
	}
	i2c_init_controller(i2c_bus);
	debug("%s: controller bus %d at %p, speed %d: ",
	      is_dvc ? "dvc" : "i2c", dev_seq(dev), i2c_bus->regs,
	      i2c_bus->speed);

	return 0;
}

/* i2c write version without the register address */
static int i2c_write_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer,
			  int len, bool end_with_repeated_start)
{
	int rc;

	debug("i2c_write_data: chip=0x%x, len=0x%x\n", chip, len);
	debug("write_data: ");
	/* use rc for counter */
	for (rc = 0; rc < len; ++rc)
		debug(" 0x%02x", buffer[rc]);
	debug("\n");

	/* Shift 7-bit address over for lower-level i2c functions */
	rc = tegra_i2c_write_data(i2c_bus, chip << 1, buffer, len,
				  end_with_repeated_start);
	if (rc)
		debug("i2c_write_data(): rc=%d\n", rc);

	return rc;
}

/* i2c read version without the register address */
static int i2c_read_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer,
			 int len)
{
	int rc;

	debug("inside i2c_read_data():\n");
	/* Shift 7-bit address over for lower-level i2c functions */
	rc = tegra_i2c_read_data(i2c_bus, chip << 1, buffer, len);
	if (rc) {
		debug("i2c_read_data(): rc=%d\n", rc);
		return rc;
	}

	debug("i2c_read_data: ");
	/* reuse rc for counter*/
	for (rc = 0; rc < len; ++rc)
		debug(" 0x%02x", buffer[rc]);
	debug("\n");

	return 0;
}

/* Probe to see if a chip is present. */
static int tegra_i2c_probe_chip(struct udevice *bus, uint chip_addr,
				uint chip_flags)
{
	struct i2c_bus *i2c_bus = dev_get_priv(bus);
	int rc;
	u8 reg;

	/* Shift 7-bit address over for lower-level i2c functions */
	rc = tegra_i2c_write_data(i2c_bus, chip_addr << 1, &reg, sizeof(reg),
				  false);

	return rc;
}

static int tegra_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
			  int nmsgs)
{
	struct i2c_bus *i2c_bus = dev_get_priv(bus);
	int ret;

	debug("i2c_xfer: %d messages\n", nmsgs);
	for (; nmsgs > 0; nmsgs--, msg++) {
		bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);

		debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
		if (msg->flags & I2C_M_RD) {
			ret = i2c_read_data(i2c_bus, msg->addr, msg->buf,
					    msg->len);
		} else {
			ret = i2c_write_data(i2c_bus, msg->addr, msg->buf,
					     msg->len, next_is_read);
		}
		if (ret) {
			debug("i2c_write: error sending\n");
			return -EREMOTEIO;
		}
	}

	return 0;
}

int tegra_i2c_get_dvc_bus(struct udevice **busp)
{
	return uclass_first_device_drvdata(UCLASS_I2C, TYPE_DVC, busp);
}

static const struct dm_i2c_ops tegra_i2c_ops = {
	.xfer		= tegra_i2c_xfer,
	.probe_chip	= tegra_i2c_probe_chip,
	.set_bus_speed	= tegra_i2c_set_bus_speed,
};

static const struct udevice_id tegra_i2c_ids[] = {
	{ .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 },
	{ .compatible = "nvidia,tegra124-i2c", .data = TYPE_114 },
	{ .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD },
	{ .compatible = "nvidia,tegra20-i2c-dvc", .data = TYPE_DVC },
	{ }
};

U_BOOT_DRIVER(i2c_tegra) = {
	.name	= "i2c_tegra",
	.id	= UCLASS_I2C,
	.of_match = tegra_i2c_ids,
	.probe	= tegra_i2c_probe,
	.priv_auto	= sizeof(struct i2c_bus),
	.ops	= &tegra_i2c_ops,
};
