// SPDX-License-Identifier: GPL-2.0
/*
 * SH QSPI (Quad SPI) driver
 *
 * Copyright (C) 2013 Renesas Electronics Corporation
 * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
 */

#include <common.h>
#include <console.h>
#include <malloc.h>
#include <spi.h>
#include <wait_bit.h>
#include <asm/arch/rmobile.h>
#include <asm/io.h>
#include <linux/bitops.h>

/* SH QSPI register bit masks <REG>_<BIT> */
#define SPCR_MSTR	0x08
#define SPCR_SPE	0x40
#define SPSR_SPRFF	0x80
#define SPSR_SPTEF	0x20
#define SPPCR_IO3FV	0x04
#define SPPCR_IO2FV	0x02
#define SPPCR_IO1FV	0x01
#define SPBDCR_RXBC0	BIT(0)
#define SPCMD_SCKDEN	BIT(15)
#define SPCMD_SLNDEN	BIT(14)
#define SPCMD_SPNDEN	BIT(13)
#define SPCMD_SSLKP	BIT(7)
#define SPCMD_BRDV0	BIT(2)
#define SPCMD_INIT1	SPCMD_SCKDEN | SPCMD_SLNDEN | \
			SPCMD_SPNDEN | SPCMD_SSLKP | \
			SPCMD_BRDV0
#define SPCMD_INIT2	SPCMD_SPNDEN | SPCMD_SSLKP | \
			SPCMD_BRDV0
#define SPBFCR_TXRST	BIT(7)
#define SPBFCR_RXRST	BIT(6)
#define SPBFCR_TXTRG	0x30
#define SPBFCR_RXTRG	0x07

/* SH QSPI register set */
struct sh_qspi_regs {
	u8	spcr;
	u8	sslp;
	u8	sppcr;
	u8	spsr;
	u32	spdr;
	u8	spscr;
	u8	spssr;
	u8	spbr;
	u8	spdcr;
	u8	spckd;
	u8	sslnd;
	u8	spnd;
	u8	dummy0;
	u16	spcmd0;
	u16	spcmd1;
	u16	spcmd2;
	u16	spcmd3;
	u8	spbfcr;
	u8	dummy1;
	u16	spbdcr;
	u32	spbmul0;
	u32	spbmul1;
	u32	spbmul2;
	u32	spbmul3;
};

struct sh_qspi_slave {
#if !CONFIG_IS_ENABLED(DM_SPI)
	struct spi_slave	slave;
#endif
	struct sh_qspi_regs	*regs;
};

static void sh_qspi_init(struct sh_qspi_slave *ss)
{
	/* QSPI initialize */
	/* Set master mode only */
	writeb(SPCR_MSTR, &ss->regs->spcr);

	/* Set SSL signal level */
	writeb(0x00, &ss->regs->sslp);

	/* Set MOSI signal value when transfer is in idle state */
	writeb(SPPCR_IO3FV|SPPCR_IO2FV, &ss->regs->sppcr);

	/* Set bit rate. See 58.3.8 Quad Serial Peripheral Interface */
	writeb(0x01, &ss->regs->spbr);

	/* Disable Dummy Data Transmission */
	writeb(0x00, &ss->regs->spdcr);

	/* Set clock delay value */
	writeb(0x00, &ss->regs->spckd);

	/* Set SSL negation delay value */
	writeb(0x00, &ss->regs->sslnd);

	/* Set next-access delay value */
	writeb(0x00, &ss->regs->spnd);

	/* Set equence command */
	writew(SPCMD_INIT2, &ss->regs->spcmd0);

	/* Reset transfer and receive Buffer */
	setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);

	/* Clear transfer and receive Buffer control bit */
	clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);

	/* Set equence control method. Use equence0 only */
	writeb(0x00, &ss->regs->spscr);

	/* Enable SPI function */
	setbits_8(&ss->regs->spcr, SPCR_SPE);
}

static void sh_qspi_cs_activate(struct sh_qspi_slave *ss)
{
	/* Set master mode only */
	writeb(SPCR_MSTR, &ss->regs->spcr);

	/* Set command */
	writew(SPCMD_INIT1, &ss->regs->spcmd0);

	/* Reset transfer and receive Buffer */
	setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);

	/* Clear transfer and receive Buffer control bit */
	clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST);

	/* Set equence control method. Use equence0 only */
	writeb(0x00, &ss->regs->spscr);

	/* Enable SPI function */
	setbits_8(&ss->regs->spcr, SPCR_SPE);
}

static void sh_qspi_cs_deactivate(struct sh_qspi_slave *ss)
{
	/* Disable SPI Function */
	clrbits_8(&ss->regs->spcr, SPCR_SPE);
}

static int sh_qspi_xfer_common(struct sh_qspi_slave *ss, unsigned int bitlen,
			       const void *dout, void *din, unsigned long flags)
{
	u32 nbyte, chunk;
	int i, ret = 0;
	u8 dtdata = 0, drdata;
	u8 *tdata = &dtdata, *rdata = &drdata;
	u32 *spbmul0 = &ss->regs->spbmul0;

	if (dout == NULL && din == NULL) {
		if (flags & SPI_XFER_END)
			sh_qspi_cs_deactivate(ss);
		return 0;
	}

	if (bitlen % 8) {
		printf("%s: bitlen is not 8bit alined %d", __func__, bitlen);
		return 1;
	}

	nbyte = bitlen / 8;

	if (flags & SPI_XFER_BEGIN) {
		sh_qspi_cs_activate(ss);

		/* Set 1048576 byte */
		writel(0x100000, spbmul0);
	}

	if (flags & SPI_XFER_END)
		writel(nbyte, spbmul0);

	if (dout != NULL)
		tdata = (u8 *)dout;

	if (din != NULL)
		rdata = din;

	while (nbyte > 0) {
		/*
		 * Check if there is 32 Byte chunk and if there is, transfer
		 * it in one burst, otherwise transfer on byte-by-byte basis.
		 */
		chunk = (nbyte >= 32) ? 32 : 1;

		clrsetbits_8(&ss->regs->spbfcr, SPBFCR_TXTRG | SPBFCR_RXTRG,
			     chunk == 32 ? SPBFCR_TXTRG | SPBFCR_RXTRG : 0);

		ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPTEF,
				     true, 1000, true);
		if (ret)
			return ret;

		for (i = 0; i < chunk; i++) {
			writeb(*tdata, &ss->regs->spdr);
			if (dout != NULL)
				tdata++;
		}

		ret = wait_for_bit_8(&ss->regs->spsr, SPSR_SPRFF,
				     true, 1000, true);
		if (ret)
			return ret;

		for (i = 0; i < chunk; i++) {
			*rdata = readb(&ss->regs->spdr);
			if (din != NULL)
				rdata++;
		}

		nbyte -= chunk;
	}

	if (flags & SPI_XFER_END)
		sh_qspi_cs_deactivate(ss);

	return ret;
}

#if !CONFIG_IS_ENABLED(DM_SPI)
static inline struct sh_qspi_slave *to_sh_qspi(struct spi_slave *slave)
{
	return container_of(slave, struct sh_qspi_slave, slave);
}

int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
	return 1;
}

void spi_cs_activate(struct spi_slave *slave)
{
	struct sh_qspi_slave *ss = to_sh_qspi(slave);

	sh_qspi_cs_activate(ss);
}

void spi_cs_deactivate(struct spi_slave *slave)
{
	struct sh_qspi_slave *ss = to_sh_qspi(slave);

	sh_qspi_cs_deactivate(ss);
}

struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int mode)
{
	struct sh_qspi_slave *ss;

	if (!spi_cs_is_valid(bus, cs))
		return NULL;

	ss = spi_alloc_slave(struct sh_qspi_slave, bus, cs);
	if (!ss) {
		printf("SPI_error: Fail to allocate sh_qspi_slave\n");
		return NULL;
	}

	ss->regs = (struct sh_qspi_regs *)SH_QSPI_BASE;

	/* Init SH QSPI */
	sh_qspi_init(ss);

	return &ss->slave;
}

void spi_free_slave(struct spi_slave *slave)
{
	struct sh_qspi_slave *spi = to_sh_qspi(slave);

	free(spi);
}

int spi_claim_bus(struct spi_slave *slave)
{
	return 0;
}

void spi_release_bus(struct spi_slave *slave)
{
}

int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
	     const void *dout, void *din, unsigned long flags)
{
	struct sh_qspi_slave *ss = to_sh_qspi(slave);

	return sh_qspi_xfer_common(ss, bitlen, dout, din, flags);
}

#else

#include <dm.h>

static int sh_qspi_xfer(struct udevice *dev, unsigned int bitlen,
			const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct sh_qspi_slave *ss = dev_get_plat(bus);

	return sh_qspi_xfer_common(ss, bitlen, dout, din, flags);
}

static int sh_qspi_set_speed(struct udevice *dev, uint speed)
{
	/* This is a SPI NOR controller, do nothing. */
	return 0;
}

static int sh_qspi_set_mode(struct udevice *dev, uint mode)
{
	/* This is a SPI NOR controller, do nothing. */
	return 0;
}

static int sh_qspi_probe(struct udevice *dev)
{
	struct sh_qspi_slave *ss = dev_get_plat(dev);

	sh_qspi_init(ss);

	return 0;
}

static int sh_qspi_of_to_plat(struct udevice *dev)
{
	struct sh_qspi_slave *plat = dev_get_plat(dev);

	plat->regs = (struct sh_qspi_regs *)dev_read_addr(dev);

	return 0;
}

static const struct dm_spi_ops sh_qspi_ops = {
	.xfer		= sh_qspi_xfer,
	.set_speed	= sh_qspi_set_speed,
	.set_mode	= sh_qspi_set_mode,
};

static const struct udevice_id sh_qspi_ids[] = {
	{ .compatible = "renesas,qspi" },
	{ }
};

U_BOOT_DRIVER(sh_qspi) = {
	.name		= "sh_qspi",
	.id		= UCLASS_SPI,
	.of_match	= sh_qspi_ids,
	.ops		= &sh_qspi_ops,
	.of_to_plat = sh_qspi_of_to_plat,
	.plat_auto	= sizeof(struct sh_qspi_slave),
	.probe		= sh_qspi_probe,
};
#endif
