/*
 * (C) Copyright 2017 Whitebox Systems / Northend Systems B.V.
 * S.J.R. van Schaik <stephan@whiteboxsystems.nl>
 * M.B.W. Wajer <merlijn@whiteboxsystems.nl>
 *
 * (C) Copyright 2017 Olimex Ltd..
 * Stefan Mavrodiev <stefan@olimex.com>
 *
 * Based on linux spi driver. Original copyright follows:
 * linux/drivers/spi/spi-sun4i.c
 *
 * Copyright (C) 2012 - 2014 Allwinner Tech
 * Pan Nan <pannan@allwinnertech.com>
 *
 * Copyright (C) 2014 Maxime Ripard
 * Maxime Ripard <maxime.ripard@free-electrons.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <log.h>
#include <spi.h>
#include <errno.h>
#include <fdt_support.h>
#include <reset.h>
#include <wait_bit.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>

#include <asm/bitops.h>
#include <asm/gpio.h>
#include <asm/io.h>

#include <linux/iopoll.h>

DECLARE_GLOBAL_DATA_PTR;

/* sun4i spi registers */
#define SUN4I_RXDATA_REG		0x00
#define SUN4I_TXDATA_REG		0x04
#define SUN4I_CTL_REG			0x08
#define SUN4I_CLK_CTL_REG		0x1c
#define SUN4I_BURST_CNT_REG		0x20
#define SUN4I_XMIT_CNT_REG		0x24
#define SUN4I_FIFO_STA_REG		0x28

/* sun6i spi registers */
#define SUN6I_GBL_CTL_REG		0x04
#define SUN6I_TFR_CTL_REG		0x08
#define SUN6I_FIFO_CTL_REG		0x18
#define SUN6I_FIFO_STA_REG		0x1c
#define SUN6I_CLK_CTL_REG		0x24
#define SUN6I_BURST_CNT_REG		0x30
#define SUN6I_XMIT_CNT_REG		0x34
#define SUN6I_BURST_CTL_REG		0x38
#define SUN6I_TXDATA_REG		0x200
#define SUN6I_RXDATA_REG		0x300

/* sun spi bits */
#define SUN4I_CTL_ENABLE		BIT(0)
#define SUN4I_CTL_MASTER		BIT(1)
#define SUN4I_CLK_CTL_CDR2_MASK		0xff
#define SUN4I_CLK_CTL_CDR2(div)		((div) & SUN4I_CLK_CTL_CDR2_MASK)
#define SUN4I_CLK_CTL_CDR1_MASK		0xf
#define SUN4I_CLK_CTL_CDR1(div)		(((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
#define SUN4I_CLK_CTL_DRS		BIT(12)
#define SUN4I_MAX_XFER_SIZE		0xffffff
#define SUN4I_BURST_CNT(cnt)		((cnt) & SUN4I_MAX_XFER_SIZE)
#define SUN4I_XMIT_CNT(cnt)		((cnt) & SUN4I_MAX_XFER_SIZE)
#define SUN4I_FIFO_STA_RF_CNT_BITS	0

#define SUN4I_SPI_MAX_RATE		24000000
#define SUN4I_SPI_MIN_RATE		3000
#define SUN4I_SPI_DEFAULT_RATE		1000000
#define SUN4I_SPI_TIMEOUT_US		1000000

#define SPI_REG(priv, reg)		((priv)->base + \
					(priv)->variant->regs[reg])
#define SPI_BIT(priv, bit)		((priv)->variant->bits[bit])
#define SPI_CS(priv, cs)		(((cs) << SPI_BIT(priv, SPI_TCR_CS_SEL)) & \
					SPI_BIT(priv, SPI_TCR_CS_MASK))

/* sun spi register set */
enum sun4i_spi_regs {
	SPI_GCR,
	SPI_TCR,
	SPI_FCR,
	SPI_FSR,
	SPI_CCR,
	SPI_BC,
	SPI_TC,
	SPI_BCTL,
	SPI_TXD,
	SPI_RXD,
};

/* sun spi register bits */
enum sun4i_spi_bits {
	SPI_GCR_TP,
	SPI_GCR_SRST,
	SPI_TCR_CPHA,
	SPI_TCR_CPOL,
	SPI_TCR_CS_ACTIVE_LOW,
	SPI_TCR_CS_SEL,
	SPI_TCR_CS_MASK,
	SPI_TCR_XCH,
	SPI_TCR_CS_MANUAL,
	SPI_TCR_CS_LEVEL,
	SPI_FCR_TF_RST,
	SPI_FCR_RF_RST,
	SPI_FSR_RF_CNT_MASK,
};

struct sun4i_spi_variant {
	const unsigned long *regs;
	const u32 *bits;
	u32 fifo_depth;
	bool has_soft_reset;
	bool has_burst_ctl;
};

struct sun4i_spi_platdata {
	struct sun4i_spi_variant *variant;
	u32 base;
	u32 max_hz;
};

struct sun4i_spi_priv {
	struct sun4i_spi_variant *variant;
	struct clk clk_ahb, clk_mod;
	struct reset_ctl reset;
	u32 base;
	u32 freq;
	u32 mode;

	const u8 *tx_buf;
	u8 *rx_buf;
};

static inline void sun4i_spi_drain_fifo(struct sun4i_spi_priv *priv, int len)
{
	u8 byte;

	while (len--) {
		byte = readb(SPI_REG(priv, SPI_RXD));
		if (priv->rx_buf)
			*priv->rx_buf++ = byte;
	}
}

static inline void sun4i_spi_fill_fifo(struct sun4i_spi_priv *priv, int len)
{
	u8 byte;

	while (len--) {
		byte = priv->tx_buf ? *priv->tx_buf++ : 0;
		writeb(byte, SPI_REG(priv, SPI_TXD));
	}
}

static void sun4i_spi_set_cs(struct udevice *bus, u8 cs, bool enable)
{
	struct sun4i_spi_priv *priv = dev_get_priv(bus);
	u32 reg;

	reg = readl(SPI_REG(priv, SPI_TCR));

	reg &= ~SPI_BIT(priv, SPI_TCR_CS_MASK);
	reg |= SPI_CS(priv, cs);

	if (enable)
		reg &= ~SPI_BIT(priv, SPI_TCR_CS_LEVEL);
	else
		reg |= SPI_BIT(priv, SPI_TCR_CS_LEVEL);

	writel(reg, SPI_REG(priv, SPI_TCR));
}

static int sun4i_spi_parse_pins(struct udevice *dev)
{
	const void *fdt = gd->fdt_blob;
	const char *pin_name;
	const fdt32_t *list;
	u32 phandle;
	int drive, pull = 0, pin, i;
	int offset;
	int size;

	list = fdt_getprop(fdt, dev_of_offset(dev), "pinctrl-0", &size);
	if (!list) {
		printf("WARNING: sun4i_spi: cannot find pinctrl-0 node\n");
		return -EINVAL;
	}

	while (size) {
		phandle = fdt32_to_cpu(*list++);
		size -= sizeof(*list);

		offset = fdt_node_offset_by_phandle(fdt, phandle);
		if (offset < 0)
			return offset;

		drive = fdt_getprop_u32_default_node(fdt, offset, 0,
						     "drive-strength", 0);
		if (drive) {
			if (drive <= 10)
				drive = 0;
			else if (drive <= 20)
				drive = 1;
			else if (drive <= 30)
				drive = 2;
			else
				drive = 3;
		} else {
			drive = fdt_getprop_u32_default_node(fdt, offset, 0,
							     "allwinner,drive",
							      0);
			drive = min(drive, 3);
		}

		if (fdt_get_property(fdt, offset, "bias-disable", NULL))
			pull = 0;
		else if (fdt_get_property(fdt, offset, "bias-pull-up", NULL))
			pull = 1;
		else if (fdt_get_property(fdt, offset, "bias-pull-down", NULL))
			pull = 2;
		else
			pull = fdt_getprop_u32_default_node(fdt, offset, 0,
							    "allwinner,pull",
							     0);
		pull = min(pull, 2);

		for (i = 0; ; i++) {
			pin_name = fdt_stringlist_get(fdt, offset,
						      "pins", i, NULL);
			if (!pin_name) {
				pin_name = fdt_stringlist_get(fdt, offset,
							      "allwinner,pins",
							       i, NULL);
				if (!pin_name)
					break;
			}

			pin = name_to_gpio(pin_name);
			if (pin < 0)
				break;

			if (IS_ENABLED(CONFIG_MACH_SUN50I))
				sunxi_gpio_set_cfgpin(pin, SUN50I_GPC_SPI0);
			else
				sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SPI0);
			sunxi_gpio_set_drv(pin, drive);
			sunxi_gpio_set_pull(pin, pull);
		}
	}
	return 0;
}

static inline int sun4i_spi_set_clock(struct udevice *dev, bool enable)
{
	struct sun4i_spi_priv *priv = dev_get_priv(dev);
	int ret;

	if (!enable) {
		clk_disable(&priv->clk_ahb);
		clk_disable(&priv->clk_mod);
		if (reset_valid(&priv->reset))
			reset_assert(&priv->reset);
		return 0;
	}

	ret = clk_enable(&priv->clk_ahb);
	if (ret) {
		dev_err(dev, "failed to enable ahb clock (ret=%d)\n", ret);
		return ret;
	}

	ret = clk_enable(&priv->clk_mod);
	if (ret) {
		dev_err(dev, "failed to enable mod clock (ret=%d)\n", ret);
		goto err_ahb;
	}

	if (reset_valid(&priv->reset)) {
		ret = reset_deassert(&priv->reset);
		if (ret) {
			dev_err(dev, "failed to deassert reset\n");
			goto err_mod;
		}
	}

	return 0;

err_mod:
	clk_disable(&priv->clk_mod);
err_ahb:
	clk_disable(&priv->clk_ahb);
	return ret;
}

static int sun4i_spi_claim_bus(struct udevice *dev)
{
	struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);
	int ret;

	ret = sun4i_spi_set_clock(dev->parent, true);
	if (ret)
		return ret;

	setbits_le32(SPI_REG(priv, SPI_GCR), SUN4I_CTL_ENABLE |
		     SUN4I_CTL_MASTER | SPI_BIT(priv, SPI_GCR_TP));

	if (priv->variant->has_soft_reset)
		setbits_le32(SPI_REG(priv, SPI_GCR),
			     SPI_BIT(priv, SPI_GCR_SRST));

	setbits_le32(SPI_REG(priv, SPI_TCR), SPI_BIT(priv, SPI_TCR_CS_MANUAL) |
		     SPI_BIT(priv, SPI_TCR_CS_ACTIVE_LOW));

	return 0;
}

static int sun4i_spi_release_bus(struct udevice *dev)
{
	struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);

	clrbits_le32(SPI_REG(priv, SPI_GCR), SUN4I_CTL_ENABLE);

	sun4i_spi_set_clock(dev->parent, false);

	return 0;
}

static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
			  const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct sun4i_spi_priv *priv = dev_get_priv(bus);
	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);

	u32 len = bitlen / 8;
	u32 rx_fifocnt;
	u8 nbytes;
	int ret;

	priv->tx_buf = dout;
	priv->rx_buf = din;

	if (bitlen % 8) {
		debug("%s: non byte-aligned SPI transfer.\n", __func__);
		return -ENAVAIL;
	}

	if (flags & SPI_XFER_BEGIN)
		sun4i_spi_set_cs(bus, slave_plat->cs, true);

	/* Reset FIFOs */
	setbits_le32(SPI_REG(priv, SPI_FCR), SPI_BIT(priv, SPI_FCR_RF_RST) |
		     SPI_BIT(priv, SPI_FCR_TF_RST));

	while (len) {
		/* Setup the transfer now... */
		nbytes = min(len, (priv->variant->fifo_depth - 1));

		/* Setup the counters */
		writel(SUN4I_BURST_CNT(nbytes), SPI_REG(priv, SPI_BC));
		writel(SUN4I_XMIT_CNT(nbytes), SPI_REG(priv, SPI_TC));

		if (priv->variant->has_burst_ctl)
			writel(SUN4I_BURST_CNT(nbytes),
			       SPI_REG(priv, SPI_BCTL));

		/* Fill the TX FIFO */
		sun4i_spi_fill_fifo(priv, nbytes);

		/* Start the transfer */
		setbits_le32(SPI_REG(priv, SPI_TCR),
			     SPI_BIT(priv, SPI_TCR_XCH));

		/* Wait till RX FIFO to be empty */
		ret = readl_poll_timeout(SPI_REG(priv, SPI_FSR),
					 rx_fifocnt,
					 (((rx_fifocnt &
					 SPI_BIT(priv, SPI_FSR_RF_CNT_MASK)) >>
					 SUN4I_FIFO_STA_RF_CNT_BITS) >= nbytes),
					 SUN4I_SPI_TIMEOUT_US);
		if (ret < 0) {
			printf("ERROR: sun4i_spi: Timeout transferring data\n");
			sun4i_spi_set_cs(bus, slave_plat->cs, false);
			return ret;
		}

		/* Drain the RX FIFO */
		sun4i_spi_drain_fifo(priv, nbytes);

		len -= nbytes;
	}

	if (flags & SPI_XFER_END)
		sun4i_spi_set_cs(bus, slave_plat->cs, false);

	return 0;
}

static int sun4i_spi_set_speed(struct udevice *dev, uint speed)
{
	struct sun4i_spi_platdata *plat = dev_get_platdata(dev);
	struct sun4i_spi_priv *priv = dev_get_priv(dev);
	unsigned int div;
	u32 reg;

	if (speed > plat->max_hz)
		speed = plat->max_hz;

	if (speed < SUN4I_SPI_MIN_RATE)
		speed = SUN4I_SPI_MIN_RATE;
	/*
	 * Setup clock divider.
	 *
	 * We have two choices there. Either we can use the clock
	 * divide rate 1, which is calculated thanks to this formula:
	 * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1))
	 * Or we can use CDR2, which is calculated with the formula:
	 * SPI_CLK = MOD_CLK / (2 * (cdr + 1))
	 * Whether we use the former or the latter is set through the
	 * DRS bit.
	 *
	 * First try CDR2, and if we can't reach the expected
	 * frequency, fall back to CDR1.
	 */

	div = SUN4I_SPI_MAX_RATE / (2 * speed);
	reg = readl(SPI_REG(priv, SPI_CCR));

	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
		if (div > 0)
			div--;

		reg &= ~(SUN4I_CLK_CTL_CDR2_MASK | SUN4I_CLK_CTL_DRS);
		reg |= SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
	} else {
		div = __ilog2(SUN4I_SPI_MAX_RATE) - __ilog2(speed);
		reg &= ~((SUN4I_CLK_CTL_CDR1_MASK << 8) | SUN4I_CLK_CTL_DRS);
		reg |= SUN4I_CLK_CTL_CDR1(div);
	}

	priv->freq = speed;
	writel(reg, SPI_REG(priv, SPI_CCR));

	return 0;
}

static int sun4i_spi_set_mode(struct udevice *dev, uint mode)
{
	struct sun4i_spi_priv *priv = dev_get_priv(dev);
	u32 reg;

	reg = readl(SPI_REG(priv, SPI_TCR));
	reg &= ~(SPI_BIT(priv, SPI_TCR_CPOL) | SPI_BIT(priv, SPI_TCR_CPHA));

	if (mode & SPI_CPOL)
		reg |= SPI_BIT(priv, SPI_TCR_CPOL);

	if (mode & SPI_CPHA)
		reg |= SPI_BIT(priv, SPI_TCR_CPHA);

	priv->mode = mode;
	writel(reg, SPI_REG(priv, SPI_TCR));

	return 0;
}

static const struct dm_spi_ops sun4i_spi_ops = {
	.claim_bus		= sun4i_spi_claim_bus,
	.release_bus		= sun4i_spi_release_bus,
	.xfer			= sun4i_spi_xfer,
	.set_speed		= sun4i_spi_set_speed,
	.set_mode		= sun4i_spi_set_mode,
};

static int sun4i_spi_probe(struct udevice *bus)
{
	struct sun4i_spi_platdata *plat = dev_get_platdata(bus);
	struct sun4i_spi_priv *priv = dev_get_priv(bus);
	int ret;

	ret = clk_get_by_name(bus, "ahb", &priv->clk_ahb);
	if (ret) {
		dev_err(dev, "failed to get ahb clock\n");
		return ret;
	}

	ret = clk_get_by_name(bus, "mod", &priv->clk_mod);
	if (ret) {
		dev_err(dev, "failed to get mod clock\n");
		return ret;
	}

	ret = reset_get_by_index(bus, 0, &priv->reset);
	if (ret && ret != -ENOENT) {
		dev_err(dev, "failed to get reset\n");
		return ret;
	}

	sun4i_spi_parse_pins(bus);

	priv->variant = plat->variant;
	priv->base = plat->base;
	priv->freq = plat->max_hz;

	return 0;
}

static int sun4i_spi_ofdata_to_platdata(struct udevice *bus)
{
	struct sun4i_spi_platdata *plat = dev_get_platdata(bus);
	int node = dev_of_offset(bus);

	plat->base = devfdt_get_addr(bus);
	plat->variant = (struct sun4i_spi_variant *)dev_get_driver_data(bus);
	plat->max_hz = fdtdec_get_int(gd->fdt_blob, node,
				      "spi-max-frequency",
				      SUN4I_SPI_DEFAULT_RATE);

	if (plat->max_hz > SUN4I_SPI_MAX_RATE)
		plat->max_hz = SUN4I_SPI_MAX_RATE;

	return 0;
}

static const unsigned long sun4i_spi_regs[] = {
	[SPI_GCR]		= SUN4I_CTL_REG,
	[SPI_TCR]		= SUN4I_CTL_REG,
	[SPI_FCR]		= SUN4I_CTL_REG,
	[SPI_FSR]		= SUN4I_FIFO_STA_REG,
	[SPI_CCR]		= SUN4I_CLK_CTL_REG,
	[SPI_BC]		= SUN4I_BURST_CNT_REG,
	[SPI_TC]		= SUN4I_XMIT_CNT_REG,
	[SPI_TXD]		= SUN4I_TXDATA_REG,
	[SPI_RXD]		= SUN4I_RXDATA_REG,
};

static const u32 sun4i_spi_bits[] = {
	[SPI_GCR_TP]		= BIT(18),
	[SPI_TCR_CPHA]		= BIT(2),
	[SPI_TCR_CPOL]		= BIT(3),
	[SPI_TCR_CS_ACTIVE_LOW] = BIT(4),
	[SPI_TCR_XCH]		= BIT(10),
	[SPI_TCR_CS_SEL]	= 12,
	[SPI_TCR_CS_MASK]	= 0x3000,
	[SPI_TCR_CS_MANUAL]	= BIT(16),
	[SPI_TCR_CS_LEVEL]	= BIT(17),
	[SPI_FCR_TF_RST]	= BIT(8),
	[SPI_FCR_RF_RST]	= BIT(9),
	[SPI_FSR_RF_CNT_MASK]	= GENMASK(6, 0),
};

static const unsigned long sun6i_spi_regs[] = {
	[SPI_GCR]		= SUN6I_GBL_CTL_REG,
	[SPI_TCR]		= SUN6I_TFR_CTL_REG,
	[SPI_FCR]		= SUN6I_FIFO_CTL_REG,
	[SPI_FSR]		= SUN6I_FIFO_STA_REG,
	[SPI_CCR]		= SUN6I_CLK_CTL_REG,
	[SPI_BC]		= SUN6I_BURST_CNT_REG,
	[SPI_TC]		= SUN6I_XMIT_CNT_REG,
	[SPI_BCTL]		= SUN6I_BURST_CTL_REG,
	[SPI_TXD]		= SUN6I_TXDATA_REG,
	[SPI_RXD]		= SUN6I_RXDATA_REG,
};

static const u32 sun6i_spi_bits[] = {
	[SPI_GCR_TP]		= BIT(7),
	[SPI_GCR_SRST]		= BIT(31),
	[SPI_TCR_CPHA]		= BIT(0),
	[SPI_TCR_CPOL]		= BIT(1),
	[SPI_TCR_CS_ACTIVE_LOW] = BIT(2),
	[SPI_TCR_CS_SEL]	= 4,
	[SPI_TCR_CS_MASK]	= 0x30,
	[SPI_TCR_CS_MANUAL]	= BIT(6),
	[SPI_TCR_CS_LEVEL]	= BIT(7),
	[SPI_TCR_XCH]		= BIT(31),
	[SPI_FCR_RF_RST]	= BIT(15),
	[SPI_FCR_TF_RST]	= BIT(31),
	[SPI_FSR_RF_CNT_MASK]	= GENMASK(7, 0),
};

static const struct sun4i_spi_variant sun4i_a10_spi_variant = {
	.regs			= sun4i_spi_regs,
	.bits			= sun4i_spi_bits,
	.fifo_depth		= 64,
};

static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
	.regs			= sun6i_spi_regs,
	.bits			= sun6i_spi_bits,
	.fifo_depth		= 128,
	.has_soft_reset		= true,
	.has_burst_ctl		= true,
};

static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
	.regs			= sun6i_spi_regs,
	.bits			= sun6i_spi_bits,
	.fifo_depth		= 64,
	.has_soft_reset		= true,
	.has_burst_ctl		= true,
};

static const struct udevice_id sun4i_spi_ids[] = {
	{
	  .compatible = "allwinner,sun4i-a10-spi",
	  .data = (ulong)&sun4i_a10_spi_variant,
	},
	{
	  .compatible = "allwinner,sun6i-a31-spi",
	  .data = (ulong)&sun6i_a31_spi_variant,
	},
	{
	  .compatible = "allwinner,sun8i-h3-spi",
	  .data = (ulong)&sun8i_h3_spi_variant,
	},
	{ /* sentinel */ }
};

U_BOOT_DRIVER(sun4i_spi) = {
	.name	= "sun4i_spi",
	.id	= UCLASS_SPI,
	.of_match	= sun4i_spi_ids,
	.ops	= &sun4i_spi_ops,
	.ofdata_to_platdata	= sun4i_spi_ofdata_to_platdata,
	.platdata_auto_alloc_size	= sizeof(struct sun4i_spi_platdata),
	.priv_auto_alloc_size	= sizeof(struct sun4i_spi_priv),
	.probe	= sun4i_spi_probe,
};
