// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
 *
 * Driver for STMicroelectronics Serial peripheral interface (SPI)
 */
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <reset.h>
#include <spi.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>

#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/bitfield.h>
#include <linux/iopoll.h>

/* STM32 SPI registers */
#define STM32_SPI_CR1		0x00
#define STM32_SPI_CR2		0x04
#define STM32_SPI_CFG1		0x08
#define STM32_SPI_CFG2		0x0C
#define STM32_SPI_SR		0x14
#define STM32_SPI_IFCR		0x18
#define STM32_SPI_TXDR		0x20
#define STM32_SPI_RXDR		0x30
#define STM32_SPI_I2SCFGR	0x50

/* STM32_SPI_CR1 bit fields */
#define SPI_CR1_SPE		BIT(0)
#define SPI_CR1_MASRX		BIT(8)
#define SPI_CR1_CSTART		BIT(9)
#define SPI_CR1_CSUSP		BIT(10)
#define SPI_CR1_HDDIR		BIT(11)
#define SPI_CR1_SSI		BIT(12)

/* STM32_SPI_CR2 bit fields */
#define SPI_CR2_TSIZE		GENMASK(15, 0)

/* STM32_SPI_CFG1 bit fields */
#define SPI_CFG1_DSIZE		GENMASK(4, 0)
#define SPI_CFG1_DSIZE_MIN	3
#define SPI_CFG1_FTHLV_SHIFT	5
#define SPI_CFG1_FTHLV		GENMASK(8, 5)
#define SPI_CFG1_MBR_SHIFT	28
#define SPI_CFG1_MBR		GENMASK(30, 28)
#define SPI_CFG1_MBR_MIN	0
#define SPI_CFG1_MBR_MAX	FIELD_GET(SPI_CFG1_MBR, SPI_CFG1_MBR)

/* STM32_SPI_CFG2 bit fields */
#define SPI_CFG2_COMM_SHIFT	17
#define SPI_CFG2_COMM		GENMASK(18, 17)
#define SPI_CFG2_MASTER		BIT(22)
#define SPI_CFG2_LSBFRST	BIT(23)
#define SPI_CFG2_CPHA		BIT(24)
#define SPI_CFG2_CPOL		BIT(25)
#define SPI_CFG2_SSM		BIT(26)
#define SPI_CFG2_AFCNTR		BIT(31)

/* STM32_SPI_SR bit fields */
#define SPI_SR_RXP		BIT(0)
#define SPI_SR_TXP		BIT(1)
#define SPI_SR_EOT		BIT(3)
#define SPI_SR_TXTF		BIT(4)
#define SPI_SR_OVR		BIT(6)
#define SPI_SR_SUSP		BIT(11)
#define SPI_SR_RXPLVL_SHIFT	13
#define SPI_SR_RXPLVL		GENMASK(14, 13)
#define SPI_SR_RXWNE		BIT(15)

/* STM32_SPI_IFCR bit fields */
#define SPI_IFCR_ALL		GENMASK(11, 3)

/* STM32_SPI_I2SCFGR bit fields */
#define SPI_I2SCFGR_I2SMOD	BIT(0)

#define MAX_CS_COUNT	4

/* SPI Master Baud Rate min/max divisor */
#define STM32_MBR_DIV_MIN	(2 << SPI_CFG1_MBR_MIN)
#define STM32_MBR_DIV_MAX	(2 << SPI_CFG1_MBR_MAX)

#define STM32_SPI_TIMEOUT_US	100000

/* SPI Communication mode */
#define SPI_FULL_DUPLEX		0
#define SPI_SIMPLEX_TX		1
#define SPI_SIMPLEX_RX		2
#define SPI_HALF_DUPLEX		3

struct stm32_spi_priv {
	void __iomem *base;
	struct clk clk;
	struct reset_ctl rst_ctl;
	struct gpio_desc cs_gpios[MAX_CS_COUNT];
	ulong bus_clk_rate;
	unsigned int fifo_size;
	unsigned int cur_bpw;
	unsigned int cur_hz;
	unsigned int cur_xferlen; /* current transfer length in bytes */
	unsigned int tx_len;	  /* number of data to be written in bytes */
	unsigned int rx_len;	  /* number of data to be read in bytes */
	const void *tx_buf;	  /* data to be written, or NULL */
	void *rx_buf;		  /* data to be read, or NULL */
	u32 cur_mode;
	bool cs_high;
};

static void stm32_spi_write_txfifo(struct stm32_spi_priv *priv)
{
	while ((priv->tx_len > 0) &&
	       (readl(priv->base + STM32_SPI_SR) & SPI_SR_TXP)) {
		u32 offs = priv->cur_xferlen - priv->tx_len;

		if (priv->tx_len >= sizeof(u32) &&
		    IS_ALIGNED((uintptr_t)(priv->tx_buf + offs), sizeof(u32))) {
			const u32 *tx_buf32 = (const u32 *)(priv->tx_buf + offs);

			writel(*tx_buf32, priv->base + STM32_SPI_TXDR);
			priv->tx_len -= sizeof(u32);
		} else if (priv->tx_len >= sizeof(u16) &&
			   IS_ALIGNED((uintptr_t)(priv->tx_buf + offs), sizeof(u16))) {
			const u16 *tx_buf16 = (const u16 *)(priv->tx_buf + offs);

			writew(*tx_buf16, priv->base + STM32_SPI_TXDR);
			priv->tx_len -= sizeof(u16);
		} else {
			const u8 *tx_buf8 = (const u8 *)(priv->tx_buf + offs);

			writeb(*tx_buf8, priv->base + STM32_SPI_TXDR);
			priv->tx_len -= sizeof(u8);
		}
	}

	debug("%s: %d bytes left\n", __func__, priv->tx_len);
}

static void stm32_spi_read_rxfifo(struct stm32_spi_priv *priv)
{
	u32 sr = readl(priv->base + STM32_SPI_SR);
	u32 rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT;

	while ((priv->rx_len > 0) &&
	       ((sr & SPI_SR_RXP) ||
	       ((sr & SPI_SR_EOT) && ((sr & SPI_SR_RXWNE) || (rxplvl > 0))))) {
		u32 offs = priv->cur_xferlen - priv->rx_len;

		if (IS_ALIGNED((uintptr_t)(priv->rx_buf + offs), sizeof(u32)) &&
		    (priv->rx_len >= sizeof(u32) || (sr & SPI_SR_RXWNE))) {
			u32 *rx_buf32 = (u32 *)(priv->rx_buf + offs);

			*rx_buf32 = readl(priv->base + STM32_SPI_RXDR);
			priv->rx_len -= sizeof(u32);
		} else if (IS_ALIGNED((uintptr_t)(priv->rx_buf + offs), sizeof(u16)) &&
			   (priv->rx_len >= sizeof(u16) ||
			    (!(sr & SPI_SR_RXWNE) &&
			    (rxplvl >= 2 || priv->cur_bpw > 8)))) {
			u16 *rx_buf16 = (u16 *)(priv->rx_buf + offs);

			*rx_buf16 = readw(priv->base + STM32_SPI_RXDR);
			priv->rx_len -= sizeof(u16);
		} else {
			u8 *rx_buf8 = (u8 *)(priv->rx_buf + offs);

			*rx_buf8 = readb(priv->base + STM32_SPI_RXDR);
			priv->rx_len -= sizeof(u8);
		}

		sr = readl(priv->base + STM32_SPI_SR);
		rxplvl = (sr & SPI_SR_RXPLVL) >> SPI_SR_RXPLVL_SHIFT;
	}

	debug("%s: %d bytes left\n", __func__, priv->rx_len);
}

static int stm32_spi_enable(struct stm32_spi_priv *priv)
{
	debug("%s\n", __func__);

	/* Enable the SPI hardware */
	setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE);

	return 0;
}

static int stm32_spi_disable(struct stm32_spi_priv *priv)
{
	debug("%s\n", __func__);

	/* Disable the SPI hardware */
	clrbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_SPE);

	return 0;
}

static int stm32_spi_claim_bus(struct udevice *slave)
{
	struct udevice *bus = dev_get_parent(slave);
	struct stm32_spi_priv *priv = dev_get_priv(bus);

	debug("%s\n", __func__);

	/* Enable the SPI hardware */
	return stm32_spi_enable(priv);
}

static int stm32_spi_release_bus(struct udevice *slave)
{
	struct udevice *bus = dev_get_parent(slave);
	struct stm32_spi_priv *priv = dev_get_priv(bus);

	debug("%s\n", __func__);

	/* Disable the SPI hardware */
	return stm32_spi_disable(priv);
}

static void stm32_spi_stopxfer(struct udevice *dev)
{
	struct stm32_spi_priv *priv = dev_get_priv(dev);
	u32 cr1, sr;
	int ret;

	debug("%s\n", __func__);

	cr1 = readl(priv->base + STM32_SPI_CR1);

	if (!(cr1 & SPI_CR1_SPE))
		return;

	/* Wait on EOT or suspend the flow */
	ret = readl_poll_timeout(priv->base + STM32_SPI_SR, sr,
				 !(sr & SPI_SR_EOT), 100000);
	if (ret < 0) {
		if (cr1 & SPI_CR1_CSTART) {
			writel(cr1 | SPI_CR1_CSUSP, priv->base + STM32_SPI_CR1);
			if (readl_poll_timeout(priv->base + STM32_SPI_SR,
					       sr, !(sr & SPI_SR_SUSP),
					       100000) < 0)
				dev_err(dev, "Suspend request timeout\n");
		}
	}

	/* clear status flags */
	setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL);
}

static int stm32_spi_set_cs(struct udevice *dev, unsigned int cs, bool enable)
{
	struct stm32_spi_priv *priv = dev_get_priv(dev);

	debug("%s: cs=%d enable=%d\n", __func__, cs, enable);

	if (cs >= MAX_CS_COUNT)
		return -ENODEV;

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

	if (priv->cs_high)
		enable = !enable;

	return dm_gpio_set_value(&priv->cs_gpios[cs], enable ? 1 : 0);
}

static int stm32_spi_set_mode(struct udevice *bus, uint mode)
{
	struct stm32_spi_priv *priv = dev_get_priv(bus);
	u32 cfg2_clrb = 0, cfg2_setb = 0;

	debug("%s: mode=%d\n", __func__, mode);

	if (mode & SPI_CPOL)
		cfg2_setb |= SPI_CFG2_CPOL;
	else
		cfg2_clrb |= SPI_CFG2_CPOL;

	if (mode & SPI_CPHA)
		cfg2_setb |= SPI_CFG2_CPHA;
	else
		cfg2_clrb |= SPI_CFG2_CPHA;

	if (mode & SPI_LSB_FIRST)
		cfg2_setb |= SPI_CFG2_LSBFRST;
	else
		cfg2_clrb |= SPI_CFG2_LSBFRST;

	if (cfg2_clrb || cfg2_setb)
		clrsetbits_le32(priv->base + STM32_SPI_CFG2,
				cfg2_clrb, cfg2_setb);

	if (mode & SPI_CS_HIGH)
		priv->cs_high = true;
	else
		priv->cs_high = false;
	return 0;
}

static int stm32_spi_set_fthlv(struct udevice *dev, u32 xfer_len)
{
	struct stm32_spi_priv *priv = dev_get_priv(dev);
	u32 fthlv, half_fifo;

	/* data packet should not exceed 1/2 of fifo space */
	half_fifo = (priv->fifo_size / 2);

	/* data_packet should not exceed transfer length */
	fthlv = (half_fifo > xfer_len) ? xfer_len : half_fifo;

	/* align packet size with data registers access */
	fthlv -= (fthlv % 4);

	if (!fthlv)
		fthlv = 1;
	clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_FTHLV,
			(fthlv - 1) << SPI_CFG1_FTHLV_SHIFT);

	return 0;
}

static int stm32_spi_set_speed(struct udevice *bus, uint hz)
{
	struct stm32_spi_priv *priv = dev_get_priv(bus);
	u32 mbrdiv;
	long div;

	debug("%s: hz=%d\n", __func__, hz);

	if (priv->cur_hz == hz)
		return 0;

	div = DIV_ROUND_UP(priv->bus_clk_rate, hz);

	if (div < STM32_MBR_DIV_MIN ||
	    div > STM32_MBR_DIV_MAX)
		return -EINVAL;

	/* Determine the first power of 2 greater than or equal to div */
	if (div & (div - 1))
		mbrdiv = fls(div);
	else
		mbrdiv = fls(div) - 1;

	if (!mbrdiv)
		return -EINVAL;

	clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_MBR,
			(mbrdiv - 1) << SPI_CFG1_MBR_SHIFT);

	priv->cur_hz = hz;

	return 0;
}

static int stm32_spi_xfer(struct udevice *slave, unsigned int bitlen,
			  const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev_get_parent(slave);
	struct dm_spi_slave_plat *slave_plat;
	struct stm32_spi_priv *priv = dev_get_priv(bus);
	u32 sr;
	u32 ifcr = 0;
	u32 xferlen;
	u32 mode;
	int xfer_status = 0;

	xferlen = bitlen / 8;

	if (xferlen <= SPI_CR2_TSIZE)
		writel(xferlen, priv->base + STM32_SPI_CR2);
	else
		return -EMSGSIZE;

	priv->tx_buf = dout;
	priv->rx_buf = din;
	priv->tx_len = priv->tx_buf ? bitlen / 8 : 0;
	priv->rx_len = priv->rx_buf ? bitlen / 8 : 0;

	mode = SPI_FULL_DUPLEX;
	if (!priv->tx_buf)
		mode = SPI_SIMPLEX_RX;
	else if (!priv->rx_buf)
		mode = SPI_SIMPLEX_TX;

	if (priv->cur_xferlen != xferlen || priv->cur_mode != mode) {
		priv->cur_mode = mode;
		priv->cur_xferlen = xferlen;

		/* Disable the SPI hardware to unlock CFG1/CFG2 registers */
		stm32_spi_disable(priv);

		clrsetbits_le32(priv->base + STM32_SPI_CFG2, SPI_CFG2_COMM,
				mode << SPI_CFG2_COMM_SHIFT);

		stm32_spi_set_fthlv(bus, xferlen);

		/* Enable the SPI hardware */
		stm32_spi_enable(priv);
	}

	debug("%s: priv->tx_len=%d priv->rx_len=%d\n", __func__,
	      priv->tx_len, priv->rx_len);

	slave_plat = dev_get_parent_plat(slave);
	if (flags & SPI_XFER_BEGIN)
		stm32_spi_set_cs(bus, slave_plat->cs, false);

	/* Be sure to have data in fifo before starting data transfer */
	if (priv->tx_buf)
		stm32_spi_write_txfifo(priv);

	setbits_le32(priv->base + STM32_SPI_CR1, SPI_CR1_CSTART);

	while (1) {
		sr = readl(priv->base + STM32_SPI_SR);

		if (sr & SPI_SR_OVR) {
			dev_err(bus, "Overrun: RX data lost\n");
			xfer_status = -EIO;
			break;
		}

		if (sr & SPI_SR_SUSP) {
			dev_warn(bus, "System too slow is limiting data throughput\n");

			if (priv->rx_buf && priv->rx_len > 0)
				stm32_spi_read_rxfifo(priv);

			ifcr |= SPI_SR_SUSP;
		}

		if (sr & SPI_SR_TXTF)
			ifcr |= SPI_SR_TXTF;

		if (sr & SPI_SR_TXP)
			if (priv->tx_buf && priv->tx_len > 0)
				stm32_spi_write_txfifo(priv);

		if (sr & SPI_SR_RXP)
			if (priv->rx_buf && priv->rx_len > 0)
				stm32_spi_read_rxfifo(priv);

		if (sr & SPI_SR_EOT) {
			if (priv->rx_buf && priv->rx_len > 0)
				stm32_spi_read_rxfifo(priv);
			break;
		}

		writel(ifcr, priv->base + STM32_SPI_IFCR);
	}

	/* clear status flags */
	setbits_le32(priv->base + STM32_SPI_IFCR, SPI_IFCR_ALL);
	stm32_spi_stopxfer(bus);

	if (flags & SPI_XFER_END)
		stm32_spi_set_cs(bus, slave_plat->cs, true);

	return xfer_status;
}

static int stm32_spi_get_fifo_size(struct udevice *dev)
{
	struct stm32_spi_priv *priv = dev_get_priv(dev);
	u32 count = 0;

	stm32_spi_enable(priv);

	while (readl(priv->base + STM32_SPI_SR) & SPI_SR_TXP)
		writeb(++count, priv->base + STM32_SPI_TXDR);

	stm32_spi_disable(priv);

	debug("%s %d x 8-bit fifo size\n", __func__, count);

	return count;
}

static int stm32_spi_probe(struct udevice *dev)
{
	struct stm32_spi_priv *priv = dev_get_priv(dev);
	unsigned long clk_rate;
	int ret;
	unsigned int i;

	priv->base = dev_remap_addr(dev);
	if (!priv->base)
		return -EINVAL;

	/* enable clock */
	ret = clk_get_by_index(dev, 0, &priv->clk);
	if (ret < 0)
		return ret;

	ret = clk_enable(&priv->clk);
	if (ret < 0)
		return ret;

	clk_rate = clk_get_rate(&priv->clk);
	if (!clk_rate) {
		ret = -EINVAL;
		goto clk_err;
	}

	priv->bus_clk_rate = clk_rate;

	/* perform reset */
	ret = reset_get_by_index(dev, 0, &priv->rst_ctl);
	if (ret < 0)
		goto clk_err;

	reset_assert(&priv->rst_ctl);
	udelay(2);
	reset_deassert(&priv->rst_ctl);

	ret = gpio_request_list_by_name(dev, "cs-gpios", priv->cs_gpios,
					ARRAY_SIZE(priv->cs_gpios), 0);
	if (ret < 0) {
		pr_err("Can't get %s cs gpios: %d", dev->name, ret);
		goto reset_err;
	}

	priv->fifo_size = stm32_spi_get_fifo_size(dev);

	priv->cur_mode = SPI_FULL_DUPLEX;
	priv->cur_xferlen = 0;
	priv->cur_bpw = SPI_DEFAULT_WORDLEN;
	clrsetbits_le32(priv->base + STM32_SPI_CFG1, SPI_CFG1_DSIZE,
			priv->cur_bpw - 1);

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

		dm_gpio_set_dir_flags(&priv->cs_gpios[i],
				      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
	}

	/* Ensure I2SMOD bit is kept cleared */
	clrbits_le32(priv->base + STM32_SPI_I2SCFGR, SPI_I2SCFGR_I2SMOD);

	/*
	 * - SS input value high
	 * - transmitter half duplex direction
	 * - automatic communication suspend when RX-Fifo is full
	 */
	setbits_le32(priv->base + STM32_SPI_CR1,
		     SPI_CR1_SSI | SPI_CR1_HDDIR | SPI_CR1_MASRX);

	/*
	 * - Set the master mode (default Motorola mode)
	 * - Consider 1 master/n slaves configuration and
	 *   SS input value is determined by the SSI bit
	 * - keep control of all associated GPIOs
	 */
	setbits_le32(priv->base + STM32_SPI_CFG2,
		     SPI_CFG2_MASTER | SPI_CFG2_SSM | SPI_CFG2_AFCNTR);

	return 0;

reset_err:
	reset_free(&priv->rst_ctl);

clk_err:
	clk_disable(&priv->clk);
	clk_free(&priv->clk);

	return ret;
};

static int stm32_spi_remove(struct udevice *dev)
{
	struct stm32_spi_priv *priv = dev_get_priv(dev);
	int ret;

	stm32_spi_stopxfer(dev);
	stm32_spi_disable(priv);

	ret = reset_assert(&priv->rst_ctl);
	if (ret < 0)
		return ret;

	reset_free(&priv->rst_ctl);

	ret = clk_disable(&priv->clk);
	if (ret < 0)
		return ret;

	clk_free(&priv->clk);

	return ret;
};

static const struct dm_spi_ops stm32_spi_ops = {
	.claim_bus	= stm32_spi_claim_bus,
	.release_bus	= stm32_spi_release_bus,
	.set_mode	= stm32_spi_set_mode,
	.set_speed	= stm32_spi_set_speed,
	.xfer		= stm32_spi_xfer,
};

static const struct udevice_id stm32_spi_ids[] = {
	{ .compatible = "st,stm32h7-spi", },
	{ }
};

U_BOOT_DRIVER(stm32_spi) = {
	.name			= "stm32_spi",
	.id			= UCLASS_SPI,
	.of_match		= stm32_spi_ids,
	.ops			= &stm32_spi_ops,
	.priv_auto	= sizeof(struct stm32_spi_priv),
	.probe			= stm32_spi_probe,
	.remove			= stm32_spi_remove,
};
