/*
 * Atmel I2C driver.
 *
 * (C) Copyright 2016 Songjun Wu <songjun.wu@atmel.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <asm/io.h>
#include <common.h>
#include <clk_client.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <i2c.h>
#include <linux/bitops.h>
#include <mach/clk.h>

#include "at91_i2c.h"

DECLARE_GLOBAL_DATA_PTR;

#define I2C_TIMEOUT_MS	100

static int at91_wait_for_xfer(struct at91_i2c_bus *bus, u32 status)
{
	struct at91_i2c_regs *reg = bus->regs;
	ulong start_time = get_timer(0);
	u32 sr;

	bus->status = 0;

	do {
		sr = readl(&reg->sr);
		bus->status |= sr;

		if (sr & TWI_SR_NACK)
			return -EREMOTEIO;
		else if (sr & status)
			return 0;
	} while (get_timer(start_time) < I2C_TIMEOUT_MS);

	return -ETIMEDOUT;
}

static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg)
{
	struct at91_i2c_regs *reg = bus->regs;
	bool is_read = msg->flags & I2C_M_RD;
	u32 i;
	int ret = 0;

	readl(&reg->sr);
	if (is_read) {
		writel(TWI_CR_START, &reg->cr);

		for (i = 0; !ret && i < (msg->len - 1); i++) {
			ret = at91_wait_for_xfer(bus, TWI_SR_RXRDY);
			msg->buf[i] = readl(&reg->rhr);
		}

		if (ret)
			goto error;

		writel(TWI_CR_STOP, &reg->cr);

		ret = at91_wait_for_xfer(bus, TWI_SR_RXRDY);
		if (ret)
			goto error;

		msg->buf[i] = readl(&reg->rhr);

	} else {
		writel(msg->buf[0], &reg->thr);
		for (i = 1; !ret && (i < msg->len); i++) {
			writel(msg->buf[i], &reg->thr);
			ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY);
		}

		if (ret)
			goto error;

		writel(TWI_CR_STOP, &reg->cr);
	}

	if (!ret)
		ret = at91_wait_for_xfer(bus, TWI_SR_TXCOMP);

	if (ret)
		goto error;

	if (bus->status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_LOCK)) {
		ret = -EIO;
		goto error;
	}

	return 0;

error:
	if (bus->status & TWI_SR_LOCK)
		writel(TWI_CR_LOCKCLR, &reg->cr);

	return ret;
}

static int at91_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
{
	struct at91_i2c_bus *bus = dev_get_priv(dev);
	struct at91_i2c_regs *reg = bus->regs;
	struct i2c_msg *m_start = msg;
	bool is_read;
	u32 int_addr_flag = 0;
	int ret = 0;

	if (nmsgs == 2) {
		int internal_address = 0;
		int i;

		/* 1st msg is put into the internal address, start with 2nd */
		m_start = &msg[1];

		/* the max length of internal address is 3 bytes */
		if (msg->len > 3)
			return -EFAULT;

		for (i = 0; i < msg->len; ++i) {
			const unsigned addr = msg->buf[msg->len - 1 - i];

			internal_address |= addr << (8 * i);
			int_addr_flag += TWI_MMR_IADRSZ_1;
		}

		writel(internal_address, &reg->iadr);
	}

	is_read = m_start->flags & I2C_M_RD;

	writel((m_start->addr << 16) | int_addr_flag |
	       (is_read ? TWI_MMR_MREAD : 0), &reg->mmr);

	ret = at91_i2c_xfer_msg(bus, m_start);

	return ret;
}

/*
 * Calculate symmetric clock as stated in datasheet:
 * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset))
 */
static void at91_calc_i2c_clock(struct udevice *dev, int i2c_clk)
{
	struct at91_i2c_bus *bus = dev_get_priv(dev);
	const struct at91_i2c_pdata *pdata = bus->pdata;
	int offset = pdata->clk_offset;
	int max_ckdiv = pdata->clk_max_div;
	int ckdiv, cdiv, div;
	unsigned long src_rate;

	src_rate = bus->bus_clk_rate;

	div = max(0, (int)DIV_ROUND_UP(src_rate, 2 * i2c_clk) - offset);
	ckdiv = fls(div >> 8);
	cdiv = div >> ckdiv;

	if (ckdiv > max_ckdiv) {
		ckdiv = max_ckdiv;
		cdiv = 255;
	}

	bus->speed = DIV_ROUND_UP(src_rate,
				  (cdiv * (1 << ckdiv) + offset) * 2);

	bus->cwgr_val = (ckdiv << 16) | (cdiv << 8) | cdiv;
}

static int at91_i2c_enable_clk(struct udevice *dev)
{
	struct at91_i2c_bus *bus = dev_get_priv(dev);
	struct udevice *dev_clk;
	struct clk clk;
	ulong clk_rate;
	int periph;
	int ret;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret)
		return -EINVAL;

	periph = fdtdec_get_uint(gd->fdt_blob, clk.dev->of_offset, "reg", -1);
	if (periph < 0)
		return -EINVAL;

	dev_clk = dev_get_parent(clk.dev);
	ret = clk_request(dev_clk, &clk);
	if (ret)
		return ret;

	clk.id = periph;
	ret = clk_enable(&clk);
	if (ret)
		return ret;

	ret = clk_get_by_index(dev_clk, 0, &clk);
	if (ret)
		return ret;

	clk_rate = clk_get_rate(&clk);
	if (!clk_rate)
		return -ENODEV;

	bus->bus_clk_rate = clk_rate;

	clk_free(&clk);

	return 0;
}

static int at91_i2c_probe(struct udevice *dev, uint chip, uint chip_flags)
{
	struct at91_i2c_bus *bus = dev_get_priv(dev);
	struct at91_i2c_regs *reg = bus->regs;
	int ret;

	ret = at91_i2c_enable_clk(dev);
	if (ret)
		return ret;

	writel(TWI_CR_SWRST, &reg->cr);

	at91_calc_i2c_clock(dev, bus->clock_frequency);

	writel(bus->cwgr_val, &reg->cwgr);
	writel(TWI_CR_MSEN, &reg->cr);
	writel(TWI_CR_SVDIS, &reg->cr);

	return 0;
}

static int at91_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
{
	struct at91_i2c_bus *bus = dev_get_priv(dev);

	at91_calc_i2c_clock(dev, speed);

	writel(bus->cwgr_val, &bus->regs->cwgr);

	return 0;
}

int at91_i2c_get_bus_speed(struct udevice *dev)
{
	struct at91_i2c_bus *bus = dev_get_priv(dev);

	return bus->speed;
}

static int at91_i2c_ofdata_to_platdata(struct udevice *dev)
{
	const void *blob = gd->fdt_blob;
	struct at91_i2c_bus *bus = dev_get_priv(dev);
	int node = dev->of_offset;

	bus->regs = (struct at91_i2c_regs *)dev_get_addr(dev);
	bus->pdata = (struct at91_i2c_pdata *)dev_get_driver_data(dev);
	bus->clock_frequency = fdtdec_get_int(blob, node,
					      "clock-frequency", 100000);

	return 0;
}

static const struct dm_i2c_ops at91_i2c_ops = {
	.xfer		= at91_i2c_xfer,
	.probe_chip	= at91_i2c_probe,
	.set_bus_speed	= at91_i2c_set_bus_speed,
	.get_bus_speed	= at91_i2c_get_bus_speed,
};

static const struct at91_i2c_pdata at91rm9200_config = {
	.clk_max_div = 5,
	.clk_offset = 3,
};

static const struct at91_i2c_pdata at91sam9261_config = {
	.clk_max_div = 5,
	.clk_offset = 4,
};

static const struct at91_i2c_pdata at91sam9260_config = {
	.clk_max_div = 7,
	.clk_offset = 4,
};

static const struct at91_i2c_pdata at91sam9g20_config = {
	.clk_max_div = 7,
	.clk_offset = 4,
};

static const struct at91_i2c_pdata at91sam9g10_config = {
	.clk_max_div = 7,
	.clk_offset = 4,
};

static const struct at91_i2c_pdata at91sam9x5_config = {
	.clk_max_div = 7,
	.clk_offset = 4,
};

static const struct at91_i2c_pdata sama5d4_config = {
	.clk_max_div = 7,
	.clk_offset = 4,
};

static const struct at91_i2c_pdata sama5d2_config = {
	.clk_max_div = 7,
	.clk_offset = 3,
};

static const struct udevice_id at91_i2c_ids[] = {
{ .compatible = "atmel,at91rm9200-i2c", .data = (long)&at91rm9200_config },
{ .compatible = "atmel,at91sam9260-i2c", .data = (long)&at91sam9260_config },
{ .compatible = "atmel,at91sam9261-i2c", .data = (long)&at91sam9261_config },
{ .compatible = "atmel,at91sam9g20-i2c", .data = (long)&at91sam9g20_config },
{ .compatible = "atmel,at91sam9g10-i2c", .data = (long)&at91sam9g10_config },
{ .compatible = "atmel,at91sam9x5-i2c", .data = (long)&at91sam9x5_config },
{ .compatible = "atmel,sama5d4-i2c", .data = (long)&sama5d4_config },
{ .compatible = "atmel,sama5d2-i2c", .data = (long)&sama5d2_config },
{ }
};

U_BOOT_DRIVER(i2c_at91) = {
	.name	= "i2c_at91",
	.id	= UCLASS_I2C,
	.of_match = at91_i2c_ids,
	.ofdata_to_platdata = at91_i2c_ofdata_to_platdata,
	.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
	.priv_auto_alloc_size = sizeof(struct at91_i2c_bus),
	.ops	= &at91_i2c_ops,
};
