// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2016
 *
 * Michael Kurz, <michi.kurz@gmail.com>
 *
 * STM32 QSPI driver
 */

#define LOG_CATEGORY UCLASS_SPI

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <log.h>
#include <reset.h>
#include <spi.h>
#include <spi-mem.h>
#include <watchdog.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/ioport.h>
#include <linux/sizes.h>

struct stm32_qspi_regs {
	u32 cr;		/* 0x00 */
	u32 dcr;	/* 0x04 */
	u32 sr;		/* 0x08 */
	u32 fcr;	/* 0x0C */
	u32 dlr;	/* 0x10 */
	u32 ccr;	/* 0x14 */
	u32 ar;		/* 0x18 */
	u32 abr;	/* 0x1C */
	u32 dr;		/* 0x20 */
	u32 psmkr;	/* 0x24 */
	u32 psmar;	/* 0x28 */
	u32 pir;	/* 0x2C */
	u32 lptr;	/* 0x30 */
};

/*
 * QUADSPI control register
 */
#define STM32_QSPI_CR_EN		BIT(0)
#define STM32_QSPI_CR_ABORT		BIT(1)
#define STM32_QSPI_CR_DMAEN		BIT(2)
#define STM32_QSPI_CR_TCEN		BIT(3)
#define STM32_QSPI_CR_SSHIFT		BIT(4)
#define STM32_QSPI_CR_DFM		BIT(6)
#define STM32_QSPI_CR_FSEL		BIT(7)
#define STM32_QSPI_CR_FTHRES_SHIFT	8
#define STM32_QSPI_CR_TEIE		BIT(16)
#define STM32_QSPI_CR_TCIE		BIT(17)
#define STM32_QSPI_CR_FTIE		BIT(18)
#define STM32_QSPI_CR_SMIE		BIT(19)
#define STM32_QSPI_CR_TOIE		BIT(20)
#define STM32_QSPI_CR_APMS		BIT(22)
#define STM32_QSPI_CR_PMM		BIT(23)
#define STM32_QSPI_CR_PRESCALER_MASK	GENMASK(7, 0)
#define STM32_QSPI_CR_PRESCALER_SHIFT	24

/*
 * QUADSPI device configuration register
 */
#define STM32_QSPI_DCR_CKMODE		BIT(0)
#define STM32_QSPI_DCR_CSHT_MASK	GENMASK(2, 0)
#define STM32_QSPI_DCR_CSHT_SHIFT	8
#define STM32_QSPI_DCR_FSIZE_MASK	GENMASK(4, 0)
#define STM32_QSPI_DCR_FSIZE_SHIFT	16

/*
 * QUADSPI status register
 */
#define STM32_QSPI_SR_TEF		BIT(0)
#define STM32_QSPI_SR_TCF		BIT(1)
#define STM32_QSPI_SR_FTF		BIT(2)
#define STM32_QSPI_SR_SMF		BIT(3)
#define STM32_QSPI_SR_TOF		BIT(4)
#define STM32_QSPI_SR_BUSY		BIT(5)

/*
 * QUADSPI flag clear register
 */
#define STM32_QSPI_FCR_CTEF		BIT(0)
#define STM32_QSPI_FCR_CTCF		BIT(1)
#define STM32_QSPI_FCR_CSMF		BIT(3)
#define STM32_QSPI_FCR_CTOF		BIT(4)

/*
 * QUADSPI communication configuration register
 */
#define STM32_QSPI_CCR_DDRM		BIT(31)
#define STM32_QSPI_CCR_DHHC		BIT(30)
#define STM32_QSPI_CCR_SIOO		BIT(28)
#define STM32_QSPI_CCR_FMODE_SHIFT	26
#define STM32_QSPI_CCR_DMODE_SHIFT	24
#define STM32_QSPI_CCR_DCYC_SHIFT	18
#define STM32_QSPI_CCR_ABSIZE_SHIFT	16
#define STM32_QSPI_CCR_ABMODE_SHIFT	14
#define STM32_QSPI_CCR_ADSIZE_SHIFT	12
#define STM32_QSPI_CCR_ADMODE_SHIFT	10
#define STM32_QSPI_CCR_IMODE_SHIFT	8

#define STM32_QSPI_CCR_IND_WRITE	0
#define STM32_QSPI_CCR_IND_READ		1
#define STM32_QSPI_CCR_MEM_MAP		3

#define STM32_QSPI_MAX_MMAP_SZ		SZ_256M
#define STM32_QSPI_MAX_CHIP		2

#define STM32_QSPI_FIFO_TIMEOUT_US	30000
#define STM32_QSPI_CMD_TIMEOUT_US	1000000
#define STM32_BUSY_TIMEOUT_US		100000
#define STM32_ABT_TIMEOUT_US		100000

struct stm32_qspi_flash {
	u32 cr;
	u32 dcr;
	bool initialized;
};

struct stm32_qspi_priv {
	struct stm32_qspi_regs *regs;
	struct stm32_qspi_flash flash[STM32_QSPI_MAX_CHIP];
	void __iomem *mm_base;
	resource_size_t mm_size;
	ulong clock_rate;
	int cs_used;
};

static int _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv)
{
	u32 sr;
	int ret;

	ret = readl_poll_timeout(&priv->regs->sr, sr,
				 !(sr & STM32_QSPI_SR_BUSY),
				 STM32_BUSY_TIMEOUT_US);
	if (ret)
		log_err("busy timeout (stat:%#x)\n", sr);

	return ret;
}

static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv,
				const struct spi_mem_op *op)
{
	u32 sr;
	int ret = 0;

	ret = readl_poll_timeout(&priv->regs->sr, sr,
				 sr & STM32_QSPI_SR_TCF,
				 STM32_QSPI_CMD_TIMEOUT_US);
	if (ret) {
		log_err("cmd timeout (stat:%#x)\n", sr);
	} else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
		log_err("transfer error (stat:%#x)\n", sr);
		ret = -EIO;
	}

	/* clear flags */
	writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr);

	if (!ret)
		ret = _stm32_qspi_wait_for_not_busy(priv);

	return ret;
}

static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr)
{
	*val = readb(addr);
	schedule();
}

static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr)
{
	writeb(*val, addr);
}

static int _stm32_qspi_poll(struct stm32_qspi_priv *priv,
			    const struct spi_mem_op *op)
{
	void (*fifo)(u8 *val, void __iomem *addr);
	u32 len = op->data.nbytes, sr;
	u8 *buf;
	int ret;

	if (op->data.dir == SPI_MEM_DATA_IN) {
		fifo = _stm32_qspi_read_fifo;
		buf = op->data.buf.in;

	} else {
		fifo = _stm32_qspi_write_fifo;
		buf = (u8 *)op->data.buf.out;
	}

	while (len--) {
		ret = readl_poll_timeout(&priv->regs->sr, sr,
					 sr & STM32_QSPI_SR_FTF,
					 STM32_QSPI_FIFO_TIMEOUT_US);
		if (ret) {
			log_err("fifo timeout (len:%d stat:%#x)\n", len, sr);
			return ret;
		}

		fifo(buf++, &priv->regs->dr);
	}

	return 0;
}

static int stm32_qspi_mm(struct stm32_qspi_priv *priv,
			 const struct spi_mem_op *op)
{
	memcpy_fromio(op->data.buf.in, priv->mm_base + op->addr.val,
		      op->data.nbytes);

	return 0;
}

static int _stm32_qspi_tx(struct stm32_qspi_priv *priv,
			  const struct spi_mem_op *op,
			  u8 mode)
{
	if (!op->data.nbytes)
		return 0;

	if (mode == STM32_QSPI_CCR_MEM_MAP)
		return stm32_qspi_mm(priv, op);

	return _stm32_qspi_poll(priv, op);
}

static int _stm32_qspi_get_mode(u8 buswidth)
{
	if (buswidth == 4)
		return 3;

	return buswidth;
}

static int stm32_qspi_exec_op(struct spi_slave *slave,
			      const struct spi_mem_op *op)
{
	struct stm32_qspi_priv *priv = dev_get_priv(slave->dev->parent);
	u32 cr, ccr, addr_max;
	u8 mode = STM32_QSPI_CCR_IND_WRITE;
	int timeout, ret;

	dev_dbg(slave->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
		op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
		op->dummy.buswidth, op->data.buswidth,
		op->addr.val, op->data.nbytes);

	addr_max = op->addr.val + op->data.nbytes + 1;

	if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes) {
		if (addr_max < priv->mm_size && op->addr.buswidth)
			mode = STM32_QSPI_CCR_MEM_MAP;
		else
			mode = STM32_QSPI_CCR_IND_READ;
	}

	if (op->data.nbytes)
		writel(op->data.nbytes - 1, &priv->regs->dlr);

	ccr = (mode << STM32_QSPI_CCR_FMODE_SHIFT);
	ccr |= op->cmd.opcode;
	ccr |= (_stm32_qspi_get_mode(op->cmd.buswidth)
		<< STM32_QSPI_CCR_IMODE_SHIFT);

	if (op->addr.nbytes) {
		ccr |= ((op->addr.nbytes - 1) << STM32_QSPI_CCR_ADSIZE_SHIFT);
		ccr |= (_stm32_qspi_get_mode(op->addr.buswidth)
			<< STM32_QSPI_CCR_ADMODE_SHIFT);
	}

	if (op->dummy.buswidth && op->dummy.nbytes)
		ccr |= (op->dummy.nbytes * 8 / op->dummy.buswidth
			<< STM32_QSPI_CCR_DCYC_SHIFT);

	if (op->data.nbytes)
		ccr |= (_stm32_qspi_get_mode(op->data.buswidth)
			<< STM32_QSPI_CCR_DMODE_SHIFT);

	writel(ccr, &priv->regs->ccr);

	if (op->addr.nbytes && mode != STM32_QSPI_CCR_MEM_MAP)
		writel(op->addr.val, &priv->regs->ar);

	ret = _stm32_qspi_tx(priv, op, mode);
	/*
	 * Abort in:
	 * -error case
	 * -read memory map: prefetching must be stopped if we read the last
	 *  byte of device (device size - fifo size). like device size is not
	 *  knows, the prefetching is always stop.
	 */
	if (ret || mode == STM32_QSPI_CCR_MEM_MAP)
		goto abort;

	/* Wait end of tx in indirect mode */
	ret = _stm32_qspi_wait_cmd(priv, op);
	if (ret)
		goto abort;

	return 0;

abort:
	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT);

	/* Wait clear of abort bit by hw */
	timeout = readl_poll_timeout(&priv->regs->cr, cr,
				     !(cr & STM32_QSPI_CR_ABORT),
				     STM32_ABT_TIMEOUT_US);

	writel(STM32_QSPI_FCR_CTCF, &priv->regs->fcr);

	if (ret || timeout)
		dev_err(slave->dev, "ret:%d abort timeout:%d\n", ret, timeout);

	return ret;
}

static int stm32_qspi_probe(struct udevice *bus)
{
	struct stm32_qspi_priv *priv = dev_get_priv(bus);
	struct resource res;
	struct clk clk;
	struct reset_ctl reset_ctl;
	int ret;

	ret = dev_read_resource_byname(bus, "qspi", &res);
	if (ret) {
		dev_err(bus, "can't get regs base addresses(ret = %d)!\n", ret);
		return ret;
	}

	priv->regs = (struct stm32_qspi_regs *)res.start;

	ret = dev_read_resource_byname(bus, "qspi_mm", &res);
	if (ret) {
		dev_err(bus, "can't get mmap base address(ret = %d)!\n", ret);
		return ret;
	}

	priv->mm_base = (void __iomem *)res.start;

	priv->mm_size = resource_size(&res);
	if (priv->mm_size > STM32_QSPI_MAX_MMAP_SZ)
		return -EINVAL;

	dev_dbg(bus, "regs=<0x%p> mapped=<0x%p> mapped_size=<0x%lx>\n",
		priv->regs, priv->mm_base, priv->mm_size);

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

	ret = clk_enable(&clk);
	if (ret) {
		dev_err(bus, "failed to enable clock\n");
		return ret;
	}

	priv->clock_rate = clk_get_rate(&clk);
	if (!priv->clock_rate) {
		clk_disable(&clk);
		return -EINVAL;
	}

	ret = reset_get_by_index(bus, 0, &reset_ctl);
	if (ret) {
		if (ret != -ENOENT) {
			dev_err(bus, "failed to get reset\n");
			clk_disable(&clk);
			return ret;
		}
	} else {
		/* Reset QSPI controller */
		reset_assert(&reset_ctl);
		udelay(2);
		reset_deassert(&reset_ctl);
	}

	priv->cs_used = -1;

	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);

	/* Set dcr fsize to max address */
	setbits_le32(&priv->regs->dcr,
		     STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT);

	return 0;
}

static int stm32_qspi_claim_bus(struct udevice *dev)
{
	struct stm32_qspi_priv *priv = dev_get_priv(dev->parent);
	struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
	int slave_cs = slave_plat->cs;

	if (slave_cs >= STM32_QSPI_MAX_CHIP)
		return -ENODEV;

	if (priv->cs_used != slave_cs) {
		struct stm32_qspi_flash *flash = &priv->flash[slave_cs];

		priv->cs_used = slave_cs;

		if (flash->initialized) {
			/* Set the configuration: speed + cs */
			writel(flash->cr, &priv->regs->cr);
			writel(flash->dcr, &priv->regs->dcr);
		} else {
			/* Set chip select */
			clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL,
					priv->cs_used ? STM32_QSPI_CR_FSEL : 0);

			/* Save the configuration: speed + cs */
			flash->cr = readl(&priv->regs->cr);
			flash->dcr = readl(&priv->regs->dcr);

			flash->initialized = true;
		}
	}

	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);

	return 0;
}

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

	clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);

	return 0;
}

static int stm32_qspi_set_speed(struct udevice *bus, uint speed)
{
	struct stm32_qspi_priv *priv = dev_get_priv(bus);
	u32 qspi_clk = priv->clock_rate;
	u32 prescaler = 255;
	u32 csht;
	int ret;

	if (speed > 0) {
		prescaler = 0;
		if (qspi_clk) {
			prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1;
			if (prescaler > 255)
				prescaler = 255;
		}
	}

	csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000);
	csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK;

	ret = _stm32_qspi_wait_for_not_busy(priv);
	if (ret)
		return ret;

	clrsetbits_le32(&priv->regs->cr,
			STM32_QSPI_CR_PRESCALER_MASK <<
			STM32_QSPI_CR_PRESCALER_SHIFT,
			prescaler << STM32_QSPI_CR_PRESCALER_SHIFT);

	clrsetbits_le32(&priv->regs->dcr,
			STM32_QSPI_DCR_CSHT_MASK << STM32_QSPI_DCR_CSHT_SHIFT,
			csht << STM32_QSPI_DCR_CSHT_SHIFT);

	dev_dbg(bus, "regs=%p, speed=%d\n", priv->regs,
		(qspi_clk / (prescaler + 1)));

	return 0;
}

static int stm32_qspi_set_mode(struct udevice *bus, uint mode)
{
	struct stm32_qspi_priv *priv = dev_get_priv(bus);
	int ret;
	const char *str_rx, *str_tx;

	ret = _stm32_qspi_wait_for_not_busy(priv);
	if (ret)
		return ret;

	if ((mode & SPI_CPHA) && (mode & SPI_CPOL))
		setbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE);
	else if (!(mode & SPI_CPHA) && !(mode & SPI_CPOL))
		clrbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE);
	else
		return -ENODEV;

	if (mode & SPI_CS_HIGH)
		return -ENODEV;

	if (mode & SPI_RX_QUAD)
		str_rx = "quad";
	else if (mode & SPI_RX_DUAL)
		str_rx = "dual";
	else
		str_rx = "single";

	if (mode & SPI_TX_QUAD)
		str_tx = "quad";
	else if (mode & SPI_TX_DUAL)
		str_tx = "dual";
	else
		str_tx = "single";

	dev_dbg(bus, "regs=%p, mode=%d rx: %s, tx: %s\n",
		priv->regs, mode, str_rx, str_tx);

	return 0;
}

static const struct spi_controller_mem_ops stm32_qspi_mem_ops = {
	.exec_op = stm32_qspi_exec_op,
};

static const struct dm_spi_ops stm32_qspi_ops = {
	.claim_bus	= stm32_qspi_claim_bus,
	.release_bus	= stm32_qspi_release_bus,
	.set_speed	= stm32_qspi_set_speed,
	.set_mode	= stm32_qspi_set_mode,
	.mem_ops	= &stm32_qspi_mem_ops,
};

static const struct udevice_id stm32_qspi_ids[] = {
	{ .compatible = "st,stm32f469-qspi" },
	{ }
};

U_BOOT_DRIVER(stm32_qspi) = {
	.name = "stm32_qspi",
	.id = UCLASS_SPI,
	.of_match = stm32_qspi_ids,
	.ops = &stm32_qspi_ops,
	.priv_auto	= sizeof(struct stm32_qspi_priv),
	.probe = stm32_qspi_probe,
};
