// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for the Renesas R-Car I2C unit
 *
 * Copyright (C) 2014-19 Wolfram Sang <wsa@sang-engineering.com>
 * Copyright (C) 2011-2019 Renesas Electronics Corporation
 *
 * Copyright (C) 2012-14 Renesas Solutions Corp.
 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 *
 * This file is based on the drivers/i2c/busses/i2c-sh7760.c
 * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
 */
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h>

/* register offsets */
#define ICSCR	0x00	/* slave ctrl */
#define ICMCR	0x04	/* master ctrl */
#define ICSSR	0x08	/* slave status */
#define ICMSR	0x0C	/* master status */
#define ICSIER	0x10	/* slave irq enable */
#define ICMIER	0x14	/* master irq enable */
#define ICCCR	0x18	/* clock dividers */
#define ICSAR	0x1C	/* slave address */
#define ICMAR	0x20	/* master address */
#define ICRXTX	0x24	/* data port */
#define ICCCR2	0x28	/* Clock control 2 */
#define ICMPR	0x2C	/* SCL mask control */
#define ICHPR	0x30	/* SCL HIGH control */
#define ICLPR	0x34	/* SCL LOW control */
#define ICFBSCR	0x38	/* first bit setup cycle (Gen3) */
#define ICDMAER	0x3c	/* DMA enable (Gen3) */

/* ICSCR */
#define SDBS	BIT(3)	/* slave data buffer select */
#define SIE	BIT(2)	/* slave interface enable */
#define GCAE	BIT(1)	/* general call address enable */
#define FNA	BIT(0)	/* forced non acknowledgment */

/* ICMCR */
#define MDBS	BIT(7)	/* non-fifo mode switch */
#define FSCL	BIT(6)	/* override SCL pin */
#define FSDA	BIT(5)	/* override SDA pin */
#define OBPC	BIT(4)	/* override pins */
#define MIE	BIT(3)	/* master if enable */
#define TSBE	BIT(2)
#define FSB	BIT(1)	/* force stop bit */
#define ESG	BIT(0)	/* enable start bit gen */

/* ICSSR (also for ICSIER) */
#define GCAR	BIT(6)	/* general call received */
#define STM	BIT(5)	/* slave transmit mode */
#define SSR	BIT(4)	/* stop received */
#define SDE	BIT(3)	/* slave data empty */
#define SDT	BIT(2)	/* slave data transmitted */
#define SDR	BIT(1)	/* slave data received */
#define SAR	BIT(0)	/* slave addr received */

/* ICMSR (also for ICMIE) */
#define MNR	BIT(6)	/* nack received */
#define MAL	BIT(5)	/* arbitration lost */
#define MST	BIT(4)	/* sent a stop */
#define MDE	BIT(3)
#define MDT	BIT(2)
#define MDR	BIT(1)
#define MAT	BIT(0)	/* slave addr xfer done */

/* ICDMAER */
#define RSDMAE	BIT(3)	/* DMA Slave Received Enable */
#define TSDMAE	BIT(2)	/* DMA Slave Transmitted Enable */
#define RMDMAE	BIT(1)	/* DMA Master Received Enable */
#define TMDMAE	BIT(0)	/* DMA Master Transmitted Enable */

/* ICCCR2 */
#define FMPE	BIT(7)	/* Fast Mode Plus Enable */
#define CDFD	BIT(2)	/* CDF Disable */
#define HLSE	BIT(1)	/* HIGH/LOW Separate Control Enable */
#define SME	BIT(0)	/* SCL Mask Enable */

/* ICFBSCR */
#define TCYC17	0x0f		/* 17*Tcyc delay 1st bit between SDA and SCL */

#define RCAR_MIN_DMA_LEN	8

/* SCL low/high ratio 5:4 to meet all I2C timing specs (incl safety margin) */
#define RCAR_SCLD_RATIO		5
#define RCAR_SCHD_RATIO		4
/*
 * SMD should be smaller than SCLD/SCHD and is always around 20 in the docs.
 * Thus, we simply use 20 which works for low and high speeds.
 */
#define RCAR_DEFAULT_SMD	20

#define RCAR_BUS_PHASE_START	(MDBS | MIE | ESG)
#define RCAR_BUS_PHASE_DATA	(MDBS | MIE)
#define RCAR_BUS_PHASE_STOP	(MDBS | MIE | FSB)

#define RCAR_IRQ_SEND	(MNR | MAL | MST | MAT | MDE)
#define RCAR_IRQ_RECV	(MNR | MAL | MST | MAT | MDR)
#define RCAR_IRQ_STOP	(MST)

#define ID_LAST_MSG		BIT(0)
#define ID_REP_AFTER_RD		BIT(1)
#define ID_DONE			BIT(2)
#define ID_ARBLOST		BIT(3)
#define ID_NACK			BIT(4)
#define ID_EPROTO		BIT(5)
/* persistent flags */
#define ID_P_FMPLUS		BIT(27)
#define ID_P_NOT_ATOMIC		BIT(28)
#define ID_P_HOST_NOTIFY	BIT(29)
#define ID_P_NO_RXDMA		BIT(30) /* HW forbids RXDMA sometimes */
#define ID_P_PM_BLOCKED		BIT(31)
#define ID_P_MASK		GENMASK(31, 27)

enum rcar_i2c_type {
	I2C_RCAR_GEN1,
	I2C_RCAR_GEN2,
	I2C_RCAR_GEN3,
	I2C_RCAR_GEN4,
};

struct rcar_i2c_priv {
	u32 flags;
	void __iomem *io;
	struct i2c_adapter adap;
	struct i2c_msg *msg;
	int msgs_left;
	struct clk *clk;

	wait_queue_head_t wait;

	int pos;
	u32 icccr;
	u16 schd;
	u16 scld;
	u8 smd;
	u8 recovery_icmcr;	/* protected by adapter lock */
	enum rcar_i2c_type devtype;
	struct i2c_client *slave;

	struct resource *res;
	struct dma_chan *dma_tx;
	struct dma_chan *dma_rx;
	struct scatterlist sg;
	enum dma_data_direction dma_direction;

	struct reset_control *rstc;
	int irq;

	struct i2c_client *host_notify_client;
};

#define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent)
#define rcar_i2c_is_recv(p)		((p)->msg->flags & I2C_M_RD)

static void rcar_i2c_write(struct rcar_i2c_priv *priv, int reg, u32 val)
{
	writel(val, priv->io + reg);
}

static u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg)
{
	return readl(priv->io + reg);
}

static void rcar_i2c_clear_irq(struct rcar_i2c_priv *priv, u32 val)
{
	writel(~val & 0x7f, priv->io + ICMSR);
}

static int rcar_i2c_get_scl(struct i2c_adapter *adap)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);

	return !!(rcar_i2c_read(priv, ICMCR) & FSCL);

};

static void rcar_i2c_set_scl(struct i2c_adapter *adap, int val)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);

	if (val)
		priv->recovery_icmcr |= FSCL;
	else
		priv->recovery_icmcr &= ~FSCL;

	rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
};

static void rcar_i2c_set_sda(struct i2c_adapter *adap, int val)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);

	if (val)
		priv->recovery_icmcr |= FSDA;
	else
		priv->recovery_icmcr &= ~FSDA;

	rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
};

static int rcar_i2c_get_bus_free(struct i2c_adapter *adap)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);

	return !(rcar_i2c_read(priv, ICMCR) & FSDA);

};

static struct i2c_bus_recovery_info rcar_i2c_bri = {
	.get_scl = rcar_i2c_get_scl,
	.set_scl = rcar_i2c_set_scl,
	.set_sda = rcar_i2c_set_sda,
	.get_bus_free = rcar_i2c_get_bus_free,
	.recover_bus = i2c_generic_scl_recovery,
};
static void rcar_i2c_init(struct rcar_i2c_priv *priv)
{
	/* reset master mode */
	rcar_i2c_write(priv, ICMIER, 0);
	rcar_i2c_write(priv, ICMCR, MDBS);
	rcar_i2c_write(priv, ICMSR, 0);
	/* start clock */
	if (priv->devtype < I2C_RCAR_GEN3) {
		rcar_i2c_write(priv, ICCCR, priv->icccr);
	} else {
		u32 icccr2 = CDFD | HLSE | SME;

		if (priv->flags & ID_P_FMPLUS)
			icccr2 |= FMPE;

		rcar_i2c_write(priv, ICCCR2, icccr2);
		rcar_i2c_write(priv, ICCCR, priv->icccr);
		rcar_i2c_write(priv, ICMPR, priv->smd);
		rcar_i2c_write(priv, ICHPR, priv->schd);
		rcar_i2c_write(priv, ICLPR, priv->scld);
		rcar_i2c_write(priv, ICFBSCR, TCYC17);
	}
}

static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
{
	int ret;
	u32 val;

	ret = readl_poll_timeout(priv->io + ICMCR, val, !(val & FSDA), 10,
				 priv->adap.timeout);
	if (ret) {
		/* Waiting did not help, try to recover */
		priv->recovery_icmcr = MDBS | OBPC | FSDA | FSCL;
		ret = i2c_recover_bus(&priv->adap);
	}

	return ret;
}

static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
{
	u32 cdf, round, ick, sum, scl, cdf_width;
	unsigned long rate;
	struct device *dev = rcar_i2c_priv_to_dev(priv);
	struct i2c_timings t = {
		.bus_freq_hz		= I2C_MAX_STANDARD_MODE_FREQ,
		.scl_fall_ns		= 35,
		.scl_rise_ns		= 200,
		.scl_int_delay_ns	= 50,
	};

	/* Fall back to previously used values if not supplied */
	i2c_parse_fw_timings(dev, &t, false);
	priv->smd = RCAR_DEFAULT_SMD;

	/*
	 * calculate SCL clock
	 * see
	 *	ICCCR (and ICCCR2 for Gen3+)
	 *
	 * ick	= clkp / (1 + CDF)
	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
	 *
	 * for Gen3+:
	 * SCL	= clkp / (8 + SMD * 2 + SCLD + SCHD +F[(ticf + tr + intd) * clkp])
	 *
	 * ick  : I2C internal clock < 20 MHz
	 * ticf : I2C SCL falling time
	 * tr   : I2C SCL rising  time
	 * intd : LSI internal delay
	 * clkp : peripheral_clk
	 * F[]  : integer up-valuation
	 */
	rate = clk_get_rate(priv->clk);
	cdf = rate / 20000000;
	cdf_width = (priv->devtype == I2C_RCAR_GEN1) ? 2 : 3;
	if (cdf >= 1U << cdf_width)
		goto err_no_val;

	if (t.bus_freq_hz > I2C_MAX_FAST_MODE_FREQ && priv->devtype >= I2C_RCAR_GEN4)
		priv->flags |= ID_P_FMPLUS;
	else
		priv->flags &= ~ID_P_FMPLUS;

	/* On Gen3+, we use cdf only for the filters, not as a SCL divider */
	ick = rate / (priv->devtype < I2C_RCAR_GEN3 ? (cdf + 1) : 1);

	/*
	 * It is impossible to calculate a large scale number on u32. Separate it.
	 *
	 * F[(ticf + tr + intd) * ick] with sum = (ticf + tr + intd)
	 *  = F[sum * ick / 1000000000]
	 *  = F[(ick / 1000000) * sum / 1000]
	 */
	sum = t.scl_fall_ns + t.scl_rise_ns + t.scl_int_delay_ns;
	round = DIV_ROUND_CLOSEST(ick, 1000000);
	round = DIV_ROUND_CLOSEST(round * sum, 1000);

	if (priv->devtype < I2C_RCAR_GEN3) {
		u32 scgd;
		/*
		 * SCL	= ick / (20 + 8 * SCGD + F[(ticf + tr + intd) * ick])
		 * 20 + 8 * SCGD + F[...] = ick / SCL
		 * SCGD = ((ick / SCL) - 20 - F[...]) / 8
		 * Result (= SCL) should be less than bus_speed for hardware safety
		 */
		scgd = DIV_ROUND_UP(ick, t.bus_freq_hz ?: 1);
		scgd = DIV_ROUND_UP(scgd - 20 - round, 8);
		scl = ick / (20 + 8 * scgd + round);

		if (scgd > 0x3f)
			goto err_no_val;

		dev_dbg(dev, "clk %u/%u(%lu), round %u, CDF: %u, SCGD: %u\n",
			scl, t.bus_freq_hz, rate, round, cdf, scgd);

		priv->icccr = scgd << cdf_width | cdf;
	} else {
		u32 x, sum_ratio = RCAR_SCHD_RATIO + RCAR_SCLD_RATIO;
		/*
		 * SCLD/SCHD ratio and SMD default value are explained above
		 * where they are defined. With these definitions, we can compute
		 * x as a base value for the SCLD/SCHD ratio:
		 *
		 * SCL = clkp / (8 + 2 * SMD + SCLD + SCHD + F[(ticf + tr + intd) * clkp])
		 * SCL = clkp / (8 + 2 * SMD + RCAR_SCLD_RATIO * x
		 *		 + RCAR_SCHD_RATIO * x + F[...])
		 *
		 * with: sum_ratio = RCAR_SCLD_RATIO + RCAR_SCHD_RATIO
		 *
		 * SCL = clkp / (8 + 2 * smd + sum_ratio * x + F[...])
		 * 8 + 2 * smd + sum_ratio * x + F[...] = clkp / SCL
		 * x = ((clkp / SCL) - 8 - 2 * smd - F[...]) / sum_ratio
		 */
		x = DIV_ROUND_UP(rate, t.bus_freq_hz ?: 1);
		x = DIV_ROUND_UP(x - 8 - 2 * priv->smd - round, sum_ratio);
		scl = rate / (8 + 2 * priv->smd + sum_ratio * x + round);

		if (x == 0 || x * RCAR_SCLD_RATIO > 0xffff)
			goto err_no_val;

		priv->icccr = cdf;
		priv->schd = RCAR_SCHD_RATIO * x;
		priv->scld = RCAR_SCLD_RATIO * x;
		if (priv->smd >= priv->schd)
			priv->smd = priv->schd - 1;

		dev_dbg(dev, "clk %u/%u(%lu), round %u, CDF: %u SCHD %u SCLD %u SMD %u\n",
			scl, t.bus_freq_hz, rate, round, cdf, priv->schd, priv->scld, priv->smd);
	}

	return 0;

err_no_val:
	dev_err(dev, "it is impossible to calculate best SCL\n");
	return -EINVAL;
}

/*
 * We don't have a test case but the HW engineers say that the write order of
 * ICMSR and ICMCR depends on whether we issue START or REP_START. So, ICMSR
 * handling is outside of this function. First messages clear ICMSR before this
 * function, interrupt handlers clear the relevant bits after this function.
 */
static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
{
	int read = !!rcar_i2c_is_recv(priv);
	bool rep_start = !(priv->flags & ID_REP_AFTER_RD);

	priv->pos = 0;
	priv->flags &= ID_P_MASK;

	if (priv->msgs_left == 1)
		priv->flags |= ID_LAST_MSG;

	rcar_i2c_write(priv, ICMAR, i2c_8bit_addr_from_msg(priv->msg));
	if (priv->flags & ID_P_NOT_ATOMIC)
		rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);

	if (rep_start)
		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
}

static void rcar_i2c_first_msg(struct rcar_i2c_priv *priv,
			       struct i2c_msg *msgs, int num)
{
	priv->msg = msgs;
	priv->msgs_left = num;
	rcar_i2c_write(priv, ICMSR, 0); /* must be before preparing msg */
	rcar_i2c_prepare_msg(priv);
}

static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv)
{
	priv->msg++;
	priv->msgs_left--;
	rcar_i2c_prepare_msg(priv);
	/* ICMSR handling must come afterwards in the irq handler */
}

static void rcar_i2c_cleanup_dma(struct rcar_i2c_priv *priv, bool terminate)
{
	struct dma_chan *chan = priv->dma_direction == DMA_FROM_DEVICE
		? priv->dma_rx : priv->dma_tx;

	/* only allowed from thread context! */
	if (terminate)
		dmaengine_terminate_sync(chan);

	dma_unmap_single(chan->device->dev, sg_dma_address(&priv->sg),
			 sg_dma_len(&priv->sg), priv->dma_direction);

	/* Gen3+ can only do one RXDMA per transfer and we just completed it */
	if (priv->devtype >= I2C_RCAR_GEN3 &&
	    priv->dma_direction == DMA_FROM_DEVICE)
		priv->flags |= ID_P_NO_RXDMA;

	priv->dma_direction = DMA_NONE;

	/* Disable DMA Master Received/Transmitted, must be last! */
	rcar_i2c_write(priv, ICDMAER, 0);
}

static void rcar_i2c_dma_callback(void *data)
{
	struct rcar_i2c_priv *priv = data;

	priv->pos += sg_dma_len(&priv->sg);

	rcar_i2c_cleanup_dma(priv, false);
}

static bool rcar_i2c_dma(struct rcar_i2c_priv *priv)
{
	struct device *dev = rcar_i2c_priv_to_dev(priv);
	struct i2c_msg *msg = priv->msg;
	bool read = msg->flags & I2C_M_RD;
	enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
	struct dma_chan *chan = read ? priv->dma_rx : priv->dma_tx;
	struct dma_async_tx_descriptor *txdesc;
	dma_addr_t dma_addr;
	dma_cookie_t cookie;
	unsigned char *buf;
	int len;

	/* Do various checks to see if DMA is feasible at all */
	if (!(priv->flags & ID_P_NOT_ATOMIC) || IS_ERR(chan) || msg->len < RCAR_MIN_DMA_LEN ||
	    !(msg->flags & I2C_M_DMA_SAFE) || (read && priv->flags & ID_P_NO_RXDMA))
		return false;

	if (read) {
		/*
		 * The last two bytes needs to be fetched using PIO in
		 * order for the STOP phase to work.
		 */
		buf = priv->msg->buf;
		len = priv->msg->len - 2;
	} else {
		/*
		 * First byte in message was sent using PIO.
		 */
		buf = priv->msg->buf + 1;
		len = priv->msg->len - 1;
	}

	dma_addr = dma_map_single(chan->device->dev, buf, len, dir);
	if (dma_mapping_error(chan->device->dev, dma_addr)) {
		dev_dbg(dev, "dma map failed, using PIO\n");
		return false;
	}

	sg_dma_len(&priv->sg) = len;
	sg_dma_address(&priv->sg) = dma_addr;

	priv->dma_direction = dir;

	txdesc = dmaengine_prep_slave_sg(chan, &priv->sg, 1,
					 read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV,
					 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
	if (!txdesc) {
		dev_dbg(dev, "dma prep slave sg failed, using PIO\n");
		rcar_i2c_cleanup_dma(priv, false);
		return false;
	}

	txdesc->callback = rcar_i2c_dma_callback;
	txdesc->callback_param = priv;

	cookie = dmaengine_submit(txdesc);
	if (dma_submit_error(cookie)) {
		dev_dbg(dev, "submitting dma failed, using PIO\n");
		rcar_i2c_cleanup_dma(priv, false);
		return false;
	}

	/* Enable DMA Master Received/Transmitted */
	if (read)
		rcar_i2c_write(priv, ICDMAER, RMDMAE);
	else
		rcar_i2c_write(priv, ICDMAER, TMDMAE);

	dma_async_issue_pending(chan);
	return true;
}

static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
{
	struct i2c_msg *msg = priv->msg;
	u32 irqs_to_clear = MDE;

	/* FIXME: sometimes, unknown interrupt happened. Do nothing */
	if (!(msr & MDE))
		return;

	if (msr & MAT)
		irqs_to_clear |= MAT;

	/* Check if DMA can be enabled and take over */
	if (priv->pos == 1 && rcar_i2c_dma(priv))
		return;

	if (priv->pos < msg->len) {
		/*
		 * Prepare next data to ICRXTX register.
		 * This data will go to _SHIFT_ register.
		 *
		 *    *
		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
		 */
		rcar_i2c_write(priv, ICRXTX, msg->buf[priv->pos]);
		priv->pos++;
	} else {
		/*
		 * The last data was pushed to ICRXTX on _PREV_ empty irq.
		 * It is on _SHIFT_ register, and will sent to I2C bus.
		 *
		 *		  *
		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
		 */

		if (priv->flags & ID_LAST_MSG)
			/*
			 * If current msg is the _LAST_ msg,
			 * prepare stop condition here.
			 * ID_DONE will be set on STOP irq.
			 */
			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
		else
			rcar_i2c_next_msg(priv);
	}

	rcar_i2c_clear_irq(priv, irqs_to_clear);
}

static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
{
	struct i2c_msg *msg = priv->msg;
	bool recv_len_init = priv->pos == 0 && msg->flags & I2C_M_RECV_LEN;
	u32 irqs_to_clear = MDR;

	/* FIXME: sometimes, unknown interrupt happened. Do nothing */
	if (!(msr & MDR))
		return;

	if (msr & MAT) {
		irqs_to_clear |= MAT;
		/*
		 * Address transfer phase finished, but no data at this point.
		 * Try to use DMA to receive data.
		 */
		rcar_i2c_dma(priv);
	} else if (priv->pos < msg->len) {
		/* get received data */
		u8 data = rcar_i2c_read(priv, ICRXTX);

		msg->buf[priv->pos] = data;
		if (recv_len_init) {
			if (data == 0 || data > I2C_SMBUS_BLOCK_MAX) {
				priv->flags |= ID_DONE | ID_EPROTO;
				return;
			}
			msg->len += msg->buf[0];
			/* Enough data for DMA? */
			if (rcar_i2c_dma(priv))
				return;
			/* new length after RECV_LEN now properly initialized */
			recv_len_init = false;
		}
		priv->pos++;
	}

	/*
	 * If next received data is the _LAST_ and we are not waiting for a new
	 * length because of RECV_LEN, then go to a new phase.
	 */
	if (priv->pos + 1 == msg->len && !recv_len_init) {
		if (priv->flags & ID_LAST_MSG) {
			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
		} else {
			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
			priv->flags |= ID_REP_AFTER_RD;
		}
	}

	if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG))
		rcar_i2c_next_msg(priv);

	rcar_i2c_clear_irq(priv, irqs_to_clear);
}

static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
{
	u32 ssr_raw, ssr_filtered;
	u8 value;

	ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff;
	ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER);

	if (!ssr_filtered)
		return false;

	/* address detected */
	if (ssr_filtered & SAR) {
		/* read or write request */
		if (ssr_raw & STM) {
			i2c_slave_event(priv->slave, I2C_SLAVE_READ_REQUESTED, &value);
			rcar_i2c_write(priv, ICRXTX, value);
			rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR);
		} else {
			i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
			rcar_i2c_read(priv, ICRXTX);	/* dummy read */
			rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR);
		}

		/* Clear SSR, too, because of old STOPs to other clients than us */
		rcar_i2c_write(priv, ICSSR, ~(SAR | SSR) & 0xff);
	}

	/* master sent stop */
	if (ssr_filtered & SSR) {
		i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
		rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */
		rcar_i2c_write(priv, ICSIER, SAR);
		rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
	}

	/* master wants to write to us */
	if (ssr_filtered & SDR) {
		int ret;

		value = rcar_i2c_read(priv, ICRXTX);
		ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
		/* Send NACK in case of error */
		rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0));
		rcar_i2c_write(priv, ICSSR, ~SDR & 0xff);
	}

	/* master wants to read from us */
	if (ssr_filtered & SDE) {
		i2c_slave_event(priv->slave, I2C_SLAVE_READ_PROCESSED, &value);
		rcar_i2c_write(priv, ICRXTX, value);
		rcar_i2c_write(priv, ICSSR, ~SDE & 0xff);
	}

	return true;
}

/*
 * This driver has a lock-free design because there are IP cores (at least
 * R-Car Gen2) which have an inherent race condition in their hardware design.
 * There, we need to switch to RCAR_BUS_PHASE_DATA as soon as possible after
 * the interrupt was generated, otherwise an unwanted repeated message gets
 * generated. It turned out that taking a spinlock at the beginning of the ISR
 * was already causing repeated messages. Thus, this driver was converted to
 * the now lockless behaviour. Please keep this in mind when hacking the driver.
 * R-Car Gen3 seems to have this fixed but earlier versions than R-Car Gen2 are
 * likely affected. Therefore, we have different interrupt handler entries.
 */
static irqreturn_t rcar_i2c_irq(int irq, struct rcar_i2c_priv *priv, u32 msr)
{
	if (!msr) {
		if (rcar_i2c_slave_irq(priv))
			return IRQ_HANDLED;

		return IRQ_NONE;
	}

	/* Arbitration lost */
	if (msr & MAL) {
		priv->flags |= ID_DONE | ID_ARBLOST;
		goto out;
	}

	/* Nack */
	if (msr & MNR) {
		/* HW automatically sends STOP after received NACK */
		if (priv->flags & ID_P_NOT_ATOMIC)
			rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP);
		priv->flags |= ID_NACK;
		goto out;
	}

	/* Stop */
	if (msr & MST) {
		priv->msgs_left--; /* The last message also made it */
		priv->flags |= ID_DONE;
		goto out;
	}

	if (rcar_i2c_is_recv(priv))
		rcar_i2c_irq_recv(priv, msr);
	else
		rcar_i2c_irq_send(priv, msr);

out:
	if (priv->flags & ID_DONE) {
		rcar_i2c_write(priv, ICMIER, 0);
		rcar_i2c_write(priv, ICMSR, 0);
		if (priv->flags & ID_P_NOT_ATOMIC)
			wake_up(&priv->wait);
	}

	return IRQ_HANDLED;
}

static irqreturn_t rcar_i2c_gen2_irq(int irq, void *ptr)
{
	struct rcar_i2c_priv *priv = ptr;
	u32 msr;

	/* Clear START or STOP immediately, except for REPSTART after read */
	if (likely(!(priv->flags & ID_REP_AFTER_RD)))
		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);

	/* Only handle interrupts that are currently enabled */
	msr = rcar_i2c_read(priv, ICMSR);
	if (priv->flags & ID_P_NOT_ATOMIC)
		msr &= rcar_i2c_read(priv, ICMIER);

	return rcar_i2c_irq(irq, priv, msr);
}

static irqreturn_t rcar_i2c_gen3_irq(int irq, void *ptr)
{
	struct rcar_i2c_priv *priv = ptr;
	u32 msr;

	/* Only handle interrupts that are currently enabled */
	msr = rcar_i2c_read(priv, ICMSR);
	if (priv->flags & ID_P_NOT_ATOMIC)
		msr &= rcar_i2c_read(priv, ICMIER);

	/*
	 * Clear START or STOP immediately, except for REPSTART after read or
	 * if a spurious interrupt was detected.
	 */
	if (likely(!(priv->flags & ID_REP_AFTER_RD) && msr))
		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);

	return rcar_i2c_irq(irq, priv, msr);
}

static struct dma_chan *rcar_i2c_request_dma_chan(struct device *dev,
					enum dma_transfer_direction dir,
					dma_addr_t port_addr)
{
	struct dma_chan *chan;
	struct dma_slave_config cfg;
	char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx";
	int ret;

	chan = dma_request_chan(dev, chan_name);
	if (IS_ERR(chan)) {
		dev_dbg(dev, "request_channel failed for %s (%ld)\n",
			chan_name, PTR_ERR(chan));
		return chan;
	}

	memset(&cfg, 0, sizeof(cfg));
	cfg.direction = dir;
	if (dir == DMA_MEM_TO_DEV) {
		cfg.dst_addr = port_addr;
		cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
	} else {
		cfg.src_addr = port_addr;
		cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
	}

	ret = dmaengine_slave_config(chan, &cfg);
	if (ret) {
		dev_dbg(dev, "slave_config failed for %s (%d)\n",
			chan_name, ret);
		dma_release_channel(chan);
		return ERR_PTR(ret);
	}

	dev_dbg(dev, "got DMA channel for %s\n", chan_name);
	return chan;
}

static void rcar_i2c_request_dma(struct rcar_i2c_priv *priv,
				 struct i2c_msg *msg)
{
	struct device *dev = rcar_i2c_priv_to_dev(priv);
	bool read;
	struct dma_chan *chan;
	enum dma_transfer_direction dir;

	read = msg->flags & I2C_M_RD;

	chan = read ? priv->dma_rx : priv->dma_tx;
	if (PTR_ERR(chan) != -EPROBE_DEFER)
		return;

	dir = read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
	chan = rcar_i2c_request_dma_chan(dev, dir, priv->res->start + ICRXTX);

	if (read)
		priv->dma_rx = chan;
	else
		priv->dma_tx = chan;
}

static void rcar_i2c_release_dma(struct rcar_i2c_priv *priv)
{
	if (!IS_ERR(priv->dma_tx)) {
		dma_release_channel(priv->dma_tx);
		priv->dma_tx = ERR_PTR(-EPROBE_DEFER);
	}

	if (!IS_ERR(priv->dma_rx)) {
		dma_release_channel(priv->dma_rx);
		priv->dma_rx = ERR_PTR(-EPROBE_DEFER);
	}
}

/* I2C is a special case, we need to poll the status of a reset */
static int rcar_i2c_do_reset(struct rcar_i2c_priv *priv)
{
	int ret;

	ret = reset_control_reset(priv->rstc);
	if (ret)
		return ret;

	return read_poll_timeout_atomic(reset_control_status, ret, ret == 0, 1,
					100, false, priv->rstc);
}

static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
				struct i2c_msg *msgs,
				int num)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
	struct device *dev = rcar_i2c_priv_to_dev(priv);
	int i, ret;
	long time_left;

	priv->flags |= ID_P_NOT_ATOMIC;

	pm_runtime_get_sync(dev);

	/* Check bus state before init otherwise bus busy info will be lost */
	ret = rcar_i2c_bus_barrier(priv);
	if (ret < 0)
		goto out;

	/* Gen3+ needs a reset. That also allows RXDMA once */
	if (priv->devtype >= I2C_RCAR_GEN3) {
		priv->flags &= ~ID_P_NO_RXDMA;
		ret = rcar_i2c_do_reset(priv);
		if (ret)
			goto out;
	}

	rcar_i2c_init(priv);

	for (i = 0; i < num; i++)
		rcar_i2c_request_dma(priv, msgs + i);

	rcar_i2c_first_msg(priv, msgs, num);

	time_left = wait_event_timeout(priv->wait, priv->flags & ID_DONE,
				     num * adap->timeout);

	/* cleanup DMA if it couldn't complete properly due to an error */
	if (priv->dma_direction != DMA_NONE)
		rcar_i2c_cleanup_dma(priv, true);

	if (!time_left) {
		rcar_i2c_init(priv);
		ret = -ETIMEDOUT;
	} else if (priv->flags & ID_NACK) {
		ret = -ENXIO;
	} else if (priv->flags & ID_ARBLOST) {
		ret = -EAGAIN;
	} else if (priv->flags & ID_EPROTO) {
		ret = -EPROTO;
	} else {
		ret = num - priv->msgs_left; /* The number of transfer */
	}
out:
	pm_runtime_put(dev);

	if (ret < 0 && ret != -ENXIO)
		dev_err(dev, "error %d : %x\n", ret, priv->flags);

	return ret;
}

static int rcar_i2c_master_xfer_atomic(struct i2c_adapter *adap,
				struct i2c_msg *msgs,
				int num)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
	struct device *dev = rcar_i2c_priv_to_dev(priv);
	unsigned long j;
	bool time_left;
	int ret;

	priv->flags &= ~ID_P_NOT_ATOMIC;

	pm_runtime_get_sync(dev);

	/* Check bus state before init otherwise bus busy info will be lost */
	ret = rcar_i2c_bus_barrier(priv);
	if (ret < 0)
		goto out;

	rcar_i2c_init(priv);
	rcar_i2c_first_msg(priv, msgs, num);

	j = jiffies + num * adap->timeout;
	do {
		u32 msr = rcar_i2c_read(priv, ICMSR);

		msr &= (rcar_i2c_is_recv(priv) ? RCAR_IRQ_RECV : RCAR_IRQ_SEND) | RCAR_IRQ_STOP;

		if (msr) {
			if (priv->devtype < I2C_RCAR_GEN3)
				rcar_i2c_gen2_irq(0, priv);
			else
				rcar_i2c_gen3_irq(0, priv);
		}

		time_left = time_before_eq(jiffies, j);
	} while (!(priv->flags & ID_DONE) && time_left);

	if (!time_left) {
		rcar_i2c_init(priv);
		ret = -ETIMEDOUT;
	} else if (priv->flags & ID_NACK) {
		ret = -ENXIO;
	} else if (priv->flags & ID_ARBLOST) {
		ret = -EAGAIN;
	} else if (priv->flags & ID_EPROTO) {
		ret = -EPROTO;
	} else {
		ret = num - priv->msgs_left; /* The number of transfer */
	}
out:
	pm_runtime_put(dev);

	if (ret < 0 && ret != -ENXIO)
		dev_err(dev, "error %d : %x\n", ret, priv->flags);

	return ret;
}

static int rcar_reg_slave(struct i2c_client *slave)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(slave->adapter);

	if (priv->slave)
		return -EBUSY;

	if (slave->flags & I2C_CLIENT_TEN)
		return -EAFNOSUPPORT;

	/* Keep device active for slave address detection logic */
	pm_runtime_get_sync(rcar_i2c_priv_to_dev(priv));

	priv->slave = slave;
	rcar_i2c_write(priv, ICSAR, slave->addr);
	rcar_i2c_write(priv, ICSSR, 0);
	rcar_i2c_write(priv, ICSIER, SAR);
	rcar_i2c_write(priv, ICSCR, SIE | SDBS);

	return 0;
}

static int rcar_unreg_slave(struct i2c_client *slave)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(slave->adapter);

	WARN_ON(!priv->slave);

	/* ensure no irq is running before clearing ptr */
	disable_irq(priv->irq);
	rcar_i2c_write(priv, ICSIER, 0);
	rcar_i2c_write(priv, ICSSR, 0);
	enable_irq(priv->irq);
	rcar_i2c_write(priv, ICSCR, SDBS);
	rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */

	priv->slave = NULL;

	pm_runtime_put(rcar_i2c_priv_to_dev(priv));

	return 0;
}

static u32 rcar_i2c_func(struct i2c_adapter *adap)
{
	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);

	/*
	 * This HW can't do:
	 * I2C_SMBUS_QUICK (setting FSB during START didn't work)
	 * I2C_M_NOSTART (automatically sends address after START)
	 * I2C_M_IGNORE_NAK (automatically sends STOP after NAK)
	 */
	u32 func = I2C_FUNC_I2C | I2C_FUNC_SLAVE |
		   (I2C_FUNC_SMBUS_EMUL_ALL & ~I2C_FUNC_SMBUS_QUICK);

	if (priv->flags & ID_P_HOST_NOTIFY)
		func |= I2C_FUNC_SMBUS_HOST_NOTIFY;

	return func;
}

static const struct i2c_algorithm rcar_i2c_algo = {
	.master_xfer	= rcar_i2c_master_xfer,
	.master_xfer_atomic = rcar_i2c_master_xfer_atomic,
	.functionality	= rcar_i2c_func,
	.reg_slave	= rcar_reg_slave,
	.unreg_slave	= rcar_unreg_slave,
};

static const struct i2c_adapter_quirks rcar_i2c_quirks = {
	.flags = I2C_AQ_NO_ZERO_LEN,
};

static const struct of_device_id rcar_i2c_dt_ids[] = {
	{ .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 },
	{ .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 },
	{ .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7791", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7792", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7793", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
	{ .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
	/* S4 has no FM+ bit */
	{ .compatible = "renesas,i2c-r8a779f0", .data = (void *)I2C_RCAR_GEN3 },
	{ .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 },
	{ .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 },
	{ .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 },
	{ .compatible = "renesas,rcar-gen4-i2c", .data = (void *)I2C_RCAR_GEN4 },
	{},
};
MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);

static int rcar_i2c_probe(struct platform_device *pdev)
{
	struct rcar_i2c_priv *priv;
	struct i2c_adapter *adap;
	struct device *dev = &pdev->dev;
	unsigned long irqflags = 0;
	irqreturn_t (*irqhandler)(int irq, void *ptr) = rcar_i2c_gen3_irq;
	int ret;

	/* Otherwise logic will break because some bytes must always use PIO */
	BUILD_BUG_ON_MSG(RCAR_MIN_DMA_LEN < 3, "Invalid min DMA length");

	priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(dev, "cannot get clock\n");
		return PTR_ERR(priv->clk);
	}

	priv->io = devm_platform_get_and_ioremap_resource(pdev, 0, &priv->res);
	if (IS_ERR(priv->io))
		return PTR_ERR(priv->io);

	priv->devtype = (enum rcar_i2c_type)of_device_get_match_data(dev);
	init_waitqueue_head(&priv->wait);

	adap = &priv->adap;
	adap->nr = pdev->id;
	adap->algo = &rcar_i2c_algo;
	adap->class = I2C_CLASS_DEPRECATED;
	adap->retries = 3;
	adap->dev.parent = dev;
	adap->dev.of_node = dev->of_node;
	adap->bus_recovery_info = &rcar_i2c_bri;
	adap->quirks = &rcar_i2c_quirks;
	i2c_set_adapdata(adap, priv);
	strscpy(adap->name, pdev->name, sizeof(adap->name));

	/* Init DMA */
	sg_init_table(&priv->sg, 1);
	priv->dma_direction = DMA_NONE;
	priv->dma_rx = priv->dma_tx = ERR_PTR(-EPROBE_DEFER);

	/* Activate device for clock calculation */
	pm_runtime_enable(dev);
	pm_runtime_get_sync(dev);
	ret = rcar_i2c_clock_calculate(priv);
	if (ret < 0) {
		pm_runtime_put(dev);
		goto out_pm_disable;
	}

	rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */

	if (priv->devtype < I2C_RCAR_GEN3) {
		irqflags |= IRQF_NO_THREAD;
		irqhandler = rcar_i2c_gen2_irq;
	}

	/* Stay always active when multi-master to keep arbitration working */
	if (of_property_read_bool(dev->of_node, "multi-master"))
		priv->flags |= ID_P_PM_BLOCKED;
	else
		pm_runtime_put(dev);

	if (of_property_read_bool(dev->of_node, "smbus"))
		priv->flags |= ID_P_HOST_NOTIFY;

	if (priv->devtype >= I2C_RCAR_GEN3) {
		priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
		if (IS_ERR(priv->rstc)) {
			ret = PTR_ERR(priv->rstc);
			goto out_pm_put;
		}

		ret = reset_control_status(priv->rstc);
		if (ret < 0)
			goto out_pm_put;
	}

	ret = platform_get_irq(pdev, 0);
	if (ret < 0)
		goto out_pm_put;
	priv->irq = ret;
	ret = devm_request_irq(dev, priv->irq, irqhandler, irqflags, dev_name(dev), priv);
	if (ret < 0) {
		dev_err(dev, "cannot get irq %d\n", priv->irq);
		goto out_pm_put;
	}

	platform_set_drvdata(pdev, priv);

	ret = i2c_add_numbered_adapter(adap);
	if (ret < 0)
		goto out_pm_put;

	if (priv->flags & ID_P_HOST_NOTIFY) {
		priv->host_notify_client = i2c_new_slave_host_notify_device(adap);
		if (IS_ERR(priv->host_notify_client)) {
			ret = PTR_ERR(priv->host_notify_client);
			goto out_del_device;
		}
	}

	dev_info(dev, "probed\n");

	return 0;

 out_del_device:
	i2c_del_adapter(&priv->adap);
 out_pm_put:
	if (priv->flags & ID_P_PM_BLOCKED)
		pm_runtime_put(dev);
 out_pm_disable:
	pm_runtime_disable(dev);
	return ret;
}

static void rcar_i2c_remove(struct platform_device *pdev)
{
	struct rcar_i2c_priv *priv = platform_get_drvdata(pdev);
	struct device *dev = &pdev->dev;

	if (priv->host_notify_client)
		i2c_free_slave_host_notify_device(priv->host_notify_client);
	i2c_del_adapter(&priv->adap);
	rcar_i2c_release_dma(priv);
	if (priv->flags & ID_P_PM_BLOCKED)
		pm_runtime_put(dev);
	pm_runtime_disable(dev);
}

static int rcar_i2c_suspend(struct device *dev)
{
	struct rcar_i2c_priv *priv = dev_get_drvdata(dev);

	i2c_mark_adapter_suspended(&priv->adap);
	return 0;
}

static int rcar_i2c_resume(struct device *dev)
{
	struct rcar_i2c_priv *priv = dev_get_drvdata(dev);

	i2c_mark_adapter_resumed(&priv->adap);
	return 0;
}

static const struct dev_pm_ops rcar_i2c_pm_ops = {
	NOIRQ_SYSTEM_SLEEP_PM_OPS(rcar_i2c_suspend, rcar_i2c_resume)
};

static struct platform_driver rcar_i2c_driver = {
	.driver	= {
		.name	= "i2c-rcar",
		.of_match_table = rcar_i2c_dt_ids,
		.pm	= pm_sleep_ptr(&rcar_i2c_pm_ops),
	},
	.probe		= rcar_i2c_probe,
	.remove_new	= rcar_i2c_remove,
};

module_platform_driver(rcar_i2c_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Renesas R-Car I2C bus driver");
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
