// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2017 - Beniamino Galvani <b.galvani@gmail.com>
 */
#include <common.h>
#include <asm/arch/i2c.h>
#include <asm/io.h>
#include <dm.h>
#include <i2c.h>

#define I2C_TIMEOUT_MS		100

/* Control register fields */
#define REG_CTRL_START		BIT(0)
#define REG_CTRL_ACK_IGNORE	BIT(1)
#define REG_CTRL_STATUS		BIT(2)
#define REG_CTRL_ERROR		BIT(3)
#define REG_CTRL_CLKDIV_SHIFT	12
#define REG_CTRL_CLKDIV_MASK	GENMASK(21, 12)
#define REG_CTRL_CLKDIVEXT_SHIFT 28
#define REG_CTRL_CLKDIVEXT_MASK	GENMASK(29, 28)

enum {
	TOKEN_END = 0,
	TOKEN_START,
	TOKEN_SLAVE_ADDR_WRITE,
	TOKEN_SLAVE_ADDR_READ,
	TOKEN_DATA,
	TOKEN_DATA_LAST,
	TOKEN_STOP,
};

struct i2c_regs {
	u32 ctrl;
	u32 slave_addr;
	u32 tok_list0;
	u32 tok_list1;
	u32 tok_wdata0;
	u32 tok_wdata1;
	u32 tok_rdata0;
	u32 tok_rdata1;
};

struct meson_i2c {
	struct i2c_regs *regs;
	struct i2c_msg *msg;	/* Current I2C message */
	bool last;		/* Whether the message is the last */
	uint count;		/* Number of bytes in the current transfer */
	uint pos;		/* Position of current transfer in message */
	u32 tokens[2];		/* Sequence of tokens to be written */
	uint num_tokens;	/* Number of tokens to be written */
};

static void meson_i2c_reset_tokens(struct meson_i2c *i2c)
{
	i2c->tokens[0] = 0;
	i2c->tokens[1] = 0;
	i2c->num_tokens = 0;
}

static void meson_i2c_add_token(struct meson_i2c *i2c, int token)
{
	if (i2c->num_tokens < 8)
		i2c->tokens[0] |= (token & 0xf) << (i2c->num_tokens * 4);
	else
		i2c->tokens[1] |= (token & 0xf) << ((i2c->num_tokens % 8) * 4);

	i2c->num_tokens++;
}

/*
 * Retrieve data for the current transfer (which can be at most 8
 * bytes) from the device internal buffer.
 */
static void meson_i2c_get_data(struct meson_i2c *i2c, u8 *buf, int len)
{
	u32 rdata0, rdata1;
	int i;

	rdata0 = readl(&i2c->regs->tok_rdata0);
	rdata1 = readl(&i2c->regs->tok_rdata1);

	debug("meson i2c: read data %08x %08x len %d\n", rdata0, rdata1, len);

	for (i = 0; i < min(4, len); i++)
		*buf++ = (rdata0 >> i * 8) & 0xff;

	for (i = 4; i < min(8, len); i++)
		*buf++ = (rdata1 >> (i - 4) * 8) & 0xff;
}

/*
 * Write data for the current transfer (which can be at most 8 bytes)
 * to the device internal buffer.
 */
static void meson_i2c_put_data(struct meson_i2c *i2c, u8 *buf, int len)
{
	u32 wdata0 = 0, wdata1 = 0;
	int i;

	for (i = 0; i < min(4, len); i++)
		wdata0 |= *buf++ << (i * 8);

	for (i = 4; i < min(8, len); i++)
		wdata1 |= *buf++ << ((i - 4) * 8);

	writel(wdata0, &i2c->regs->tok_wdata0);
	writel(wdata1, &i2c->regs->tok_wdata1);

	debug("meson i2c: write data %08x %08x len %d\n", wdata0, wdata1, len);
}

/*
 * Prepare the next transfer: pick the next 8 bytes in the remaining
 * part of message and write tokens and data (if needed) to the
 * device.
 */
static void meson_i2c_prepare_xfer(struct meson_i2c *i2c)
{
	bool write = !(i2c->msg->flags & I2C_M_RD);
	int i;

	i2c->count = min(i2c->msg->len - i2c->pos, 8u);

	for (i = 0; i + 1 < i2c->count; i++)
		meson_i2c_add_token(i2c, TOKEN_DATA);

	if (i2c->count) {
		if (write || i2c->pos + i2c->count < i2c->msg->len)
			meson_i2c_add_token(i2c, TOKEN_DATA);
		else
			meson_i2c_add_token(i2c, TOKEN_DATA_LAST);
	}

	if (write)
		meson_i2c_put_data(i2c, i2c->msg->buf + i2c->pos, i2c->count);

	if (i2c->last && i2c->pos + i2c->count >= i2c->msg->len)
		meson_i2c_add_token(i2c, TOKEN_STOP);

	writel(i2c->tokens[0], &i2c->regs->tok_list0);
	writel(i2c->tokens[1], &i2c->regs->tok_list1);
}

static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg)
{
	int token;

	token = (msg->flags & I2C_M_RD) ? TOKEN_SLAVE_ADDR_READ :
		TOKEN_SLAVE_ADDR_WRITE;

	writel(msg->addr << 1, &i2c->regs->slave_addr);
	meson_i2c_add_token(i2c, TOKEN_START);
	meson_i2c_add_token(i2c, token);
}

static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg,
			      int last)
{
	ulong start;

	debug("meson i2c: %s addr %u len %u\n",
	      (msg->flags & I2C_M_RD) ? "read" : "write",
	      msg->addr, msg->len);

	i2c->msg = msg;
	i2c->last = last;
	i2c->pos = 0;
	i2c->count = 0;

	meson_i2c_reset_tokens(i2c);
	meson_i2c_do_start(i2c, msg);

	do {
		meson_i2c_prepare_xfer(i2c);

		/* start the transfer */
		setbits_le32(&i2c->regs->ctrl, REG_CTRL_START);
		start = get_timer(0);
		while (readl(&i2c->regs->ctrl) & REG_CTRL_STATUS) {
			if (get_timer(start) > I2C_TIMEOUT_MS) {
				clrbits_le32(&i2c->regs->ctrl, REG_CTRL_START);
				debug("meson i2c: timeout\n");
				return -ETIMEDOUT;
			}
			udelay(1);
		}
		meson_i2c_reset_tokens(i2c);
		clrbits_le32(&i2c->regs->ctrl, REG_CTRL_START);

		if (readl(&i2c->regs->ctrl) & REG_CTRL_ERROR) {
			debug("meson i2c: error\n");
			return -EREMOTEIO;
		}

		if ((msg->flags & I2C_M_RD) && i2c->count) {
			meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos,
					   i2c->count);
		}
		i2c->pos += i2c->count;
	} while (i2c->pos < msg->len);

	return 0;
}

static int meson_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
			  int nmsgs)
{
	struct meson_i2c *i2c = dev_get_priv(bus);
	int i, ret = 0;

	for (i = 0; i < nmsgs; i++) {
		ret = meson_i2c_xfer_msg(i2c, msg + i, i == nmsgs - 1);
		if (ret)
			return ret;
	}

	return 0;
}

static int meson_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
{
	struct meson_i2c *i2c = dev_get_priv(bus);
	unsigned int clk_rate = MESON_I2C_CLK_RATE;
	unsigned int div;

	div = DIV_ROUND_UP(clk_rate, speed * 4);

	/* clock divider has 12 bits */
	if (div >= (1 << 12)) {
		debug("meson i2c: requested bus frequency too low\n");
		div = (1 << 12) - 1;
	}

	clrsetbits_le32(&i2c->regs->ctrl, REG_CTRL_CLKDIV_MASK,
			(div & GENMASK(9, 0)) << REG_CTRL_CLKDIV_SHIFT);

	clrsetbits_le32(&i2c->regs->ctrl, REG_CTRL_CLKDIVEXT_MASK,
			(div >> 10) << REG_CTRL_CLKDIVEXT_SHIFT);

	debug("meson i2c: set clk %u, src %u, div %u\n", speed, clk_rate, div);

	return 0;
}

static int meson_i2c_probe(struct udevice *bus)
{
	struct meson_i2c *i2c = dev_get_priv(bus);

	i2c->regs = dev_read_addr_ptr(bus);
	clrbits_le32(&i2c->regs->ctrl, REG_CTRL_START);

	return 0;
}

static const struct dm_i2c_ops meson_i2c_ops = {
	.xfer          = meson_i2c_xfer,
	.set_bus_speed = meson_i2c_set_bus_speed,
};

static const struct udevice_id meson_i2c_ids[] = {
	{ .compatible = "amlogic,meson6-i2c" },
	{ .compatible = "amlogic,meson-gx-i2c" },
	{ .compatible = "amlogic,meson-gxbb-i2c" },
	{ }
};

U_BOOT_DRIVER(i2c_meson) = {
	.name = "i2c_meson",
	.id   = UCLASS_I2C,
	.of_match = meson_i2c_ids,
	.probe = meson_i2c_probe,
	.priv_auto_alloc_size = sizeof(struct meson_i2c),
	.ops = &meson_i2c_ops,
};
