// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2008, Guennadi Liakhovetski <lg@denx.de>
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <spi.h>
#include <asm/global_data.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
#include <asm/mach-imx/spi.h>

DECLARE_GLOBAL_DATA_PTR;

/* MX35 and older is CSPI */
#if defined(CONFIG_MX31)
#define MXC_CSPI
struct cspi_regs {
	u32 rxdata;
	u32 txdata;
	u32 ctrl;
	u32 intr;
	u32 dma;
	u32 stat;
	u32 period;
	u32 test;
};

#define MXC_CSPICTRL_EN			BIT(0)
#define MXC_CSPICTRL_MODE		BIT(1)
#define MXC_CSPICTRL_XCH		BIT(2)
#define MXC_CSPICTRL_SMC		BIT(3)
#define MXC_CSPICTRL_POL		BIT(4)
#define MXC_CSPICTRL_PHA		BIT(5)
#define MXC_CSPICTRL_SSCTL		BIT(6)
#define MXC_CSPICTRL_SSPOL		BIT(7)
#define MXC_CSPICTRL_DATARATE(x)	(((x) & 0x7) << 16)
#define MXC_CSPICTRL_RXOVF		BIT(6)
#define MXC_CSPIPERIOD_32KHZ		BIT(15)
#define MAX_SPI_BYTES			4
#define MXC_CSPICTRL_CHIPSELECT(x)	(((x) & 0x3) << 24)
#define MXC_CSPICTRL_BITCOUNT(x)	(((x) & 0x1f) << 8)
#define MXC_CSPICTRL_TC			BIT(8)
#define MXC_CSPICTRL_MAXBITS		0x1f

#else	/* MX51 and newer is ECSPI */
#define MXC_ECSPI
struct cspi_regs {
	u32 rxdata;
	u32 txdata;
	u32 ctrl;
	u32 cfg;
	u32 intr;
	u32 dma;
	u32 stat;
	u32 period;
};

#define MXC_CSPICTRL_EN			BIT(0)
#define MXC_CSPICTRL_MODE		BIT(1)
#define MXC_CSPICTRL_XCH		BIT(2)
#define MXC_CSPICTRL_MODE_MASK		(0xf << 4)
#define MXC_CSPICTRL_CHIPSELECT(x)	(((x) & 0x3) << 12)
#define MXC_CSPICTRL_BITCOUNT(x)	(((x) & 0xfff) << 20)
#define MXC_CSPICTRL_PREDIV(x)		(((x) & 0xF) << 12)
#define MXC_CSPICTRL_POSTDIV(x)		(((x) & 0xF) << 8)
#define MXC_CSPICTRL_SELCHAN(x)		(((x) & 0x3) << 18)
#define MXC_CSPICTRL_MAXBITS		0xfff
#define MXC_CSPICTRL_TC			BIT(7)
#define MXC_CSPICTRL_RXOVF		BIT(6)
#define MXC_CSPIPERIOD_32KHZ		BIT(15)
#define MAX_SPI_BYTES			32

/* Bit position inside CTRL register to be associated with SS */
#define MXC_CSPICTRL_CHAN	18

/* Bit position inside CON register to be associated with SS */
#define MXC_CSPICON_PHA		0  /* SCLK phase control */
#define MXC_CSPICON_POL		4  /* SCLK polarity */
#define MXC_CSPICON_SSPOL	12 /* SS polarity */
#define MXC_CSPICON_CTL		20 /* inactive state of SCLK */
#endif

__weak int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
	return -1;
}

#define OUT	MXC_GPIO_DIRECTION_OUT

#define reg_read readl
#define reg_write(a, v) writel(v, a)

#if !defined(CFG_SYS_SPI_MXC_WAIT)
#define CFG_SYS_SPI_MXC_WAIT		(CONFIG_SYS_HZ/100)	/* 10 ms */
#endif

#define MAX_CS_COUNT	4

struct mxc_spi_slave {
	struct spi_slave slave;
	unsigned long	base;
	u32		ctrl_reg;
#if defined(MXC_ECSPI)
	u32		cfg_reg;
#endif
	int		gpio;
	int		ss_pol;
	unsigned int	max_hz;
	unsigned int	mode;
	struct gpio_desc ss;
	struct gpio_desc cs_gpios[MAX_CS_COUNT];
	struct udevice *dev;
};

static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave)
{
	return container_of(slave, struct mxc_spi_slave, slave);
}

static void mxc_spi_cs_activate(struct mxc_spi_slave *mxcs)
{
#if CONFIG_IS_ENABLED(DM_SPI)
	struct udevice *dev = mxcs->dev;
	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);

	u32 cs = slave_plat->cs;

	if (!dm_gpio_is_valid(&mxcs->cs_gpios[cs]))
		return;

	dm_gpio_set_value(&mxcs->cs_gpios[cs], 1);
#else
	if (mxcs->gpio > 0)
		gpio_set_value(mxcs->gpio, mxcs->ss_pol);
#endif
}

static void mxc_spi_cs_deactivate(struct mxc_spi_slave *mxcs)
{
#if CONFIG_IS_ENABLED(DM_SPI)
	struct udevice *dev = mxcs->dev;
	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);

	u32 cs = slave_plat->cs;

	if (!dm_gpio_is_valid(&mxcs->cs_gpios[cs]))
		return;

	dm_gpio_set_value(&mxcs->cs_gpios[cs], 0);
#else
	if (mxcs->gpio > 0)
		gpio_set_value(mxcs->gpio, !(mxcs->ss_pol));
#endif
}

u32 get_cspi_div(u32 div)
{
	int i;

	for (i = 0; i < 8; i++) {
		if (div <= (4 << i))
			return i;
	}
	return i;
}

#ifdef MXC_CSPI
static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs)
{
	unsigned int ctrl_reg;
	u32 clk_src;
	u32 div;
	unsigned int max_hz = mxcs->max_hz;
	unsigned int mode = mxcs->mode;

	clk_src = mxc_get_clock(MXC_CSPI_CLK);

	div = DIV_ROUND_UP(clk_src, max_hz);
	div = get_cspi_div(div);

	debug("clk %d Hz, div %d, real clk %d Hz\n",
		max_hz, div, clk_src / (4 << div));

	ctrl_reg = MXC_CSPICTRL_CHIPSELECT(cs) |
		MXC_CSPICTRL_BITCOUNT(MXC_CSPICTRL_MAXBITS) |
		MXC_CSPICTRL_DATARATE(div) |
		MXC_CSPICTRL_EN |
		MXC_CSPICTRL_MODE;

	if (mode & SPI_CPHA)
		ctrl_reg |= MXC_CSPICTRL_PHA;
	if (mode & SPI_CPOL)
		ctrl_reg |= MXC_CSPICTRL_POL;
	if (mode & SPI_CS_HIGH)
		ctrl_reg |= MXC_CSPICTRL_SSPOL;
	mxcs->ctrl_reg = ctrl_reg;

	return 0;
}
#endif

#ifdef MXC_ECSPI
static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs)
{
	u32 clk_src = mxc_get_clock(MXC_CSPI_CLK);
	s32 reg_ctrl, reg_config;
	u32 ss_pol = 0, sclkpol = 0, sclkpha = 0, sclkctl = 0;
	u32 pre_div = 0, post_div = 0;
	struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
	unsigned int max_hz = mxcs->max_hz;
	unsigned int mode = mxcs->mode;

	/*
	 * Reset SPI and set all CSs to master mode, if toggling
	 * between slave and master mode we might see a glitch
	 * on the clock line
	 */
	reg_ctrl = MXC_CSPICTRL_MODE_MASK;
	reg_write(&regs->ctrl, reg_ctrl);
	reg_ctrl |=  MXC_CSPICTRL_EN;
	reg_write(&regs->ctrl, reg_ctrl);

	if (clk_src > max_hz) {
		pre_div = (clk_src - 1) / max_hz;
		/* fls(1) = 1, fls(0x80000000) = 32, fls(16) = 5 */
		post_div = fls(pre_div);
		if (post_div > 4) {
			post_div -= 4;
			if (post_div >= 16) {
				printf("Error: no divider for the freq: %d\n",
					max_hz);
				return -1;
			}
			pre_div >>= post_div;
		} else {
			post_div = 0;
		}
	}

	debug("pre_div = %d, post_div=%d\n", pre_div, post_div);
	reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_SELCHAN(3)) |
		MXC_CSPICTRL_SELCHAN(cs);
	reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_PREDIV(0x0F)) |
		MXC_CSPICTRL_PREDIV(pre_div);
	reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_POSTDIV(0x0F)) |
		MXC_CSPICTRL_POSTDIV(post_div);

	if (mode & SPI_CS_HIGH)
		ss_pol = 1;

	if (mode & SPI_CPOL) {
		sclkpol = 1;
		sclkctl = 1;
	}

	if (mode & SPI_CPHA)
		sclkpha = 1;

	reg_config = reg_read(&regs->cfg);

	/*
	 * Configuration register setup
	 * The MX51 supports different setup for each SS
	 */
	reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_SSPOL))) |
		(ss_pol << (cs + MXC_CSPICON_SSPOL));
	reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_POL))) |
		(sclkpol << (cs + MXC_CSPICON_POL));
	reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_CTL))) |
		(sclkctl << (cs + MXC_CSPICON_CTL));
	reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_PHA))) |
		(sclkpha << (cs + MXC_CSPICON_PHA));

	debug("reg_ctrl = 0x%x\n", reg_ctrl);
	reg_write(&regs->ctrl, reg_ctrl);
	debug("reg_config = 0x%x\n", reg_config);
	reg_write(&regs->cfg, reg_config);

	/* save config register and control register */
	mxcs->ctrl_reg = reg_ctrl;
	mxcs->cfg_reg = reg_config;

	/* clear interrupt reg */
	reg_write(&regs->intr, 0);
	reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);

	return 0;
}
#endif

int spi_xchg_single(struct mxc_spi_slave *mxcs, unsigned int bitlen,
	const u8 *dout, u8 *din, unsigned long flags)
{
	int nbytes = DIV_ROUND_UP(bitlen, 8);
	u32 data, cnt, i;
	struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
	u32 ts;
	int status;

	debug("%s: bitlen %d dout 0x%lx din 0x%lx\n",
		__func__, bitlen, (ulong)dout, (ulong)din);

	mxcs->ctrl_reg = (mxcs->ctrl_reg &
		~MXC_CSPICTRL_BITCOUNT(MXC_CSPICTRL_MAXBITS)) |
		MXC_CSPICTRL_BITCOUNT(bitlen - 1);

	reg_write(&regs->ctrl, mxcs->ctrl_reg | MXC_CSPICTRL_EN);
#ifdef MXC_ECSPI
	reg_write(&regs->cfg, mxcs->cfg_reg);
#endif

	/* Clear interrupt register */
	reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);

	/*
	 * The SPI controller works only with words,
	 * check if less than a word is sent.
	 * Access to the FIFO is only 32 bit
	 */
	if (bitlen % 32) {
		data = 0;
		cnt = (bitlen % 32) / 8;
		if (dout) {
			for (i = 0; i < cnt; i++) {
				data = (data << 8) | (*dout++ & 0xFF);
			}
		}
		debug("Sending SPI 0x%x\n", data);

		reg_write(&regs->txdata, data);
		nbytes -= cnt;
	}

	data = 0;

	while (nbytes > 0) {
		data = 0;
		if (dout) {
			/* Buffer is not 32-bit aligned */
			if ((unsigned long)dout & 0x03) {
				data = 0;
				for (i = 0; i < 4; i++)
					data = (data << 8) | (*dout++ & 0xFF);
			} else {
				data = *(u32 *)dout;
				data = cpu_to_be32(data);
				dout += 4;
			}
		}
		debug("Sending SPI 0x%x\n", data);
		reg_write(&regs->txdata, data);
		nbytes -= 4;
	}

	/* FIFO is written, now starts the transfer setting the XCH bit */
	reg_write(&regs->ctrl, mxcs->ctrl_reg |
		MXC_CSPICTRL_EN | MXC_CSPICTRL_XCH);

	ts = get_timer(0);
	status = reg_read(&regs->stat);
	/* Wait until the TC (Transfer completed) bit is set */
	while ((status & MXC_CSPICTRL_TC) == 0) {
		if (get_timer(ts) > CFG_SYS_SPI_MXC_WAIT) {
			printf("spi_xchg_single: Timeout!\n");
			return -1;
		}
		status = reg_read(&regs->stat);
	}

	/* Transfer completed, clear any pending request */
	reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);

	nbytes = DIV_ROUND_UP(bitlen, 8);

	if (bitlen % 32) {
		data = reg_read(&regs->rxdata);
		cnt = (bitlen % 32) / 8;
		data = cpu_to_be32(data) >> ((sizeof(data) - cnt) * 8);
		debug("SPI Rx unaligned: 0x%x\n", data);
		if (din) {
			memcpy(din, &data, cnt);
			din += cnt;
		}
		nbytes -= cnt;
	}

	while (nbytes > 0) {
		u32 tmp;
		tmp = reg_read(&regs->rxdata);
		data = cpu_to_be32(tmp);
		debug("SPI Rx: 0x%x 0x%x\n", tmp, data);
		cnt = min_t(u32, nbytes, sizeof(data));
		if (din) {
			memcpy(din, &data, cnt);
			din += cnt;
		}
		nbytes -= cnt;
	}

	return 0;

}

static int mxc_spi_xfer_internal(struct mxc_spi_slave *mxcs,
				 unsigned int bitlen, const void *dout,
				 void *din, unsigned long flags)
{
	int n_bytes = DIV_ROUND_UP(bitlen, 8);
	int n_bits;
	int ret;
	u32 blk_size;
	u8 *p_outbuf = (u8 *)dout;
	u8 *p_inbuf = (u8 *)din;

	if (!mxcs)
		return -EINVAL;

	if (flags & SPI_XFER_BEGIN)
		mxc_spi_cs_activate(mxcs);

	while (n_bytes > 0) {
		if (n_bytes < MAX_SPI_BYTES)
			blk_size = n_bytes;
		else
			blk_size = MAX_SPI_BYTES;

		n_bits = blk_size * 8;

		ret = spi_xchg_single(mxcs, n_bits, p_outbuf, p_inbuf, 0);

		if (ret)
			return ret;
		if (dout)
			p_outbuf += blk_size;
		if (din)
			p_inbuf += blk_size;
		n_bytes -= blk_size;
	}

	if (flags & SPI_XFER_END) {
		mxc_spi_cs_deactivate(mxcs);
	}

	return 0;
}

static int mxc_spi_claim_bus_internal(struct mxc_spi_slave *mxcs, int cs)
{
	struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
	int ret;

	reg_write(&regs->rxdata, 1);
	udelay(1);
	ret = spi_cfg_mxc(mxcs, cs);
	if (ret) {
		printf("mxc_spi: cannot setup SPI controller\n");
		return ret;
	}
	reg_write(&regs->period, MXC_CSPIPERIOD_32KHZ);
	reg_write(&regs->intr, 0);

	return 0;
}

#if !CONFIG_IS_ENABLED(DM_SPI)
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
		void *din, unsigned long flags)
{
	struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);

	return mxc_spi_xfer_internal(mxcs, bitlen, dout, din, flags);
}

/*
 * Some SPI devices require active chip-select over multiple
 * transactions, we achieve this using a GPIO. Still, the SPI
 * controller has to be configured to use one of its own chipselects.
 * To use this feature you have to implement board_spi_cs_gpio() to assign
 * a gpio value for each cs (-1 if cs doesn't need to use gpio).
 * You must use some unused on this SPI controller cs between 0 and 3.
 */
static int setup_cs_gpio(struct mxc_spi_slave *mxcs,
			 unsigned int bus, unsigned int cs)
{
	int ret;

	mxcs->gpio = board_spi_cs_gpio(bus, cs);
	if (mxcs->gpio == -1)
		return 0;

	gpio_request(mxcs->gpio, "spi-cs");
	ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
	if (ret) {
		printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
		return -EINVAL;
	}

	return 0;
}

static unsigned long spi_bases[] = {
	MXC_SPI_BASE_ADDRESSES
};

struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
			unsigned int max_hz, unsigned int mode)
{
	struct mxc_spi_slave *mxcs;
	int ret;

	if (bus >= ARRAY_SIZE(spi_bases))
		return NULL;

	if (max_hz == 0) {
		printf("Error: desired clock is 0\n");
		return NULL;
	}

	mxcs = spi_alloc_slave(struct mxc_spi_slave, bus, cs);
	if (!mxcs) {
		puts("mxc_spi: SPI Slave not allocated !\n");
		return NULL;
	}

	mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;

	ret = setup_cs_gpio(mxcs, bus, cs);
	if (ret < 0) {
		free(mxcs);
		return NULL;
	}

	mxcs->base = spi_bases[bus];
	mxcs->max_hz = max_hz;
	mxcs->mode = mode;

	return &mxcs->slave;
}

void spi_free_slave(struct spi_slave *slave)
{
	struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);

	free(mxcs);
}

int spi_claim_bus(struct spi_slave *slave)
{
	struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);

	return mxc_spi_claim_bus_internal(mxcs, slave->cs);
}

void spi_release_bus(struct spi_slave *slave)
{
	/* TODO: Shut the controller down */
}
#else

static int mxc_spi_probe(struct udevice *bus)
{
	struct mxc_spi_slave *mxcs = dev_get_plat(bus);
	int ret;
	int i;

	ret = gpio_request_list_by_name(bus, "cs-gpios", mxcs->cs_gpios,
					ARRAY_SIZE(mxcs->cs_gpios), 0);
	if (ret < 0) {
		pr_err("Can't get %s gpios! Error: %d", bus->name, ret);
		return ret;
	}

	for (i = 0; i < ARRAY_SIZE(mxcs->cs_gpios); i++) {
		if (!dm_gpio_is_valid(&mxcs->cs_gpios[i]))
			continue;

		ret = dm_gpio_set_dir_flags(&mxcs->cs_gpios[i],
					    GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
		if (ret) {
			dev_err(bus, "Setting cs %d error\n", i);
			return ret;
		}
	}

	mxcs->base = dev_read_addr(bus);
	if (mxcs->base == FDT_ADDR_T_NONE)
		return -ENODEV;

#if CONFIG_IS_ENABLED(CLK)
	struct clk clk;
	ret = clk_get_by_index(bus, 0, &clk);
	if (ret)
		return ret;

	clk_enable(&clk);

	mxcs->max_hz = clk_get_rate(&clk);
#else
	int node = dev_of_offset(bus);
	const void *blob = gd->fdt_blob;
	mxcs->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
				      20000000);
#endif

	return 0;
}

static int mxc_spi_xfer(struct udevice *dev, unsigned int bitlen,
		const void *dout, void *din, unsigned long flags)
{
	struct mxc_spi_slave *mxcs = dev_get_plat(dev->parent);


	return mxc_spi_xfer_internal(mxcs, bitlen, dout, din, flags);
}

static int mxc_spi_claim_bus(struct udevice *dev)
{
	struct mxc_spi_slave *mxcs = dev_get_plat(dev->parent);
	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);

	mxcs->dev = dev;

	return mxc_spi_claim_bus_internal(mxcs, slave_plat->cs);
}

static int mxc_spi_release_bus(struct udevice *dev)
{
	return 0;
}

static int mxc_spi_set_speed(struct udevice *bus, uint speed)
{
	struct mxc_spi_slave *mxcs = dev_get_plat(bus);

	mxcs->max_hz = speed;

	return 0;
}

static int mxc_spi_set_mode(struct udevice *bus, uint mode)
{
	struct mxc_spi_slave *mxcs = dev_get_plat(bus);

	mxcs->mode = mode;
	mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;

	return 0;
}

static const struct dm_spi_ops mxc_spi_ops = {
	.claim_bus	= mxc_spi_claim_bus,
	.release_bus	= mxc_spi_release_bus,
	.xfer		= mxc_spi_xfer,
	.set_speed	= mxc_spi_set_speed,
	.set_mode	= mxc_spi_set_mode,
};

static const struct udevice_id mxc_spi_ids[] = {
	{ .compatible = "fsl,imx51-ecspi" },
	{ }
};

U_BOOT_DRIVER(mxc_spi) = {
	.name	= "mxc_spi",
	.id	= UCLASS_SPI,
	.of_match = mxc_spi_ids,
	.ops	= &mxc_spi_ops,
	.plat_auto	= sizeof(struct mxc_spi_slave),
	.probe	= mxc_spi_probe,
};
#endif
