// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2012
 * Armando Visconti, ST Microelectronics, armando.visconti@st.com.
 *
 * (C) Copyright 2018
 * Quentin Schulz, Bootlin, quentin.schulz@bootlin.com
 *
 * Driver for ARM PL022 SPI Controller.
 */

#include <clk.h>
#include <common.h>
#include <dm.h>
#include <dm/platform_data/spi_pl022.h>
#include <linux/io.h>
#include <asm/global_data.h>
#include <spi.h>

#define SSP_CR0		0x000
#define SSP_CR1		0x004
#define SSP_DR		0x008
#define SSP_SR		0x00C
#define SSP_CPSR	0x010
#define SSP_IMSC	0x014
#define SSP_RIS		0x018
#define SSP_MIS		0x01C
#define SSP_ICR		0x020
#define SSP_DMACR	0x024
#define SSP_CSR		0x030 /* vendor extension */
#define SSP_ITCR	0x080
#define SSP_ITIP	0x084
#define SSP_ITOP	0x088
#define SSP_TDR		0x08C

#define SSP_PID0	0xFE0
#define SSP_PID1	0xFE4
#define SSP_PID2	0xFE8
#define SSP_PID3	0xFEC

#define SSP_CID0	0xFF0
#define SSP_CID1	0xFF4
#define SSP_CID2	0xFF8
#define SSP_CID3	0xFFC

/* SSP Control Register 0  - SSP_CR0 */
#define SSP_CR0_SPO		(0x1 << 6)
#define SSP_CR0_SPH		(0x1 << 7)
#define SSP_CR0_BIT_MODE(x)	((x) - 1)
#define SSP_SCR_MIN		(0x00)
#define SSP_SCR_MAX		(0xFF)
#define SSP_SCR_SHFT		8
#define DFLT_CLKRATE		2

/* SSP Control Register 1  - SSP_CR1 */
#define SSP_CR1_MASK_SSE	(0x1 << 1)

#define SSP_CPSR_MIN		(0x02)
#define SSP_CPSR_MAX		(0xFE)
#define DFLT_PRESCALE		(0x40)

/* SSP Status Register - SSP_SR */
#define SSP_SR_MASK_TFE		(0x1 << 0) /* Transmit FIFO empty */
#define SSP_SR_MASK_TNF		(0x1 << 1) /* Transmit FIFO not full */
#define SSP_SR_MASK_RNE		(0x1 << 2) /* Receive FIFO not empty */
#define SSP_SR_MASK_RFF		(0x1 << 3) /* Receive FIFO full */
#define SSP_SR_MASK_BSY		(0x1 << 4) /* Busy Flag */

struct pl022_spi_slave {
	void *base;
	unsigned int freq;
};

/*
 * ARM PL022 exists in different 'flavors'.
 * This drivers currently support the standard variant (0x00041022), that has a
 * 16bit wide and 8 locations deep TX/RX FIFO.
 */
static int pl022_is_supported(struct pl022_spi_slave *ps)
{
	/* PL022 version is 0x00041022 */
	if ((readw(ps->base + SSP_PID0) == 0x22) &&
	    (readw(ps->base + SSP_PID1) == 0x10) &&
	    ((readw(ps->base + SSP_PID2) & 0xf) == 0x04) &&
	    (readw(ps->base + SSP_PID3) == 0x00))
		return 1;

	return 0;
}

static int pl022_spi_probe(struct udevice *bus)
{
	struct pl022_spi_pdata *plat = dev_get_plat(bus);
	struct pl022_spi_slave *ps = dev_get_priv(bus);

	ps->base = ioremap(plat->addr, plat->size);
	ps->freq = plat->freq;

	/* Check the PL022 version */
	if (!pl022_is_supported(ps))
		return -ENOTSUPP;

	/* 8 bits per word, high polarity and default clock rate */
	writew(SSP_CR0_BIT_MODE(8), ps->base + SSP_CR0);
	writew(DFLT_PRESCALE, ps->base + SSP_CPSR);

	return 0;
}

static void flush(struct pl022_spi_slave *ps)
{
	do {
		while (readw(ps->base + SSP_SR) & SSP_SR_MASK_RNE)
			readw(ps->base + SSP_DR);
	} while (readw(ps->base + SSP_SR) & SSP_SR_MASK_BSY);
}

static int pl022_spi_claim_bus(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct pl022_spi_slave *ps = dev_get_priv(bus);
	u16 reg;

	/* Enable the SPI hardware */
	reg = readw(ps->base + SSP_CR1);
	reg |= SSP_CR1_MASK_SSE;
	writew(reg, ps->base + SSP_CR1);

	flush(ps);

	return 0;
}

static int pl022_spi_release_bus(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct pl022_spi_slave *ps = dev_get_priv(bus);
	u16 reg;

	flush(ps);

	/* Disable the SPI hardware */
	reg = readw(ps->base + SSP_CR1);
	reg &= ~SSP_CR1_MASK_SSE;
	writew(reg, ps->base + SSP_CR1);

	return 0;
}

static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen,
			  const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct pl022_spi_slave *ps = dev_get_priv(bus);
	u32		len_tx = 0, len_rx = 0, len;
	u32		ret = 0;
	const u8	*txp = dout;
	u8		*rxp = din, value;

	if (bitlen == 0)
		/* Finish any previously submitted transfers */
		return 0;

	/*
	 * TODO: The controller can do non-multiple-of-8 bit
	 * transfers, but this driver currently doesn't support it.
	 *
	 * It's also not clear how such transfers are supposed to be
	 * represented as a stream of bytes...this is a limitation of
	 * the current SPI interface.
	 */
	if (bitlen % 8) {
		/* Errors always terminate an ongoing transfer */
		flags |= SPI_XFER_END;
		return -1;
	}

	len = bitlen / 8;

	while (len_tx < len) {
		if (readw(ps->base + SSP_SR) & SSP_SR_MASK_TNF) {
			value = txp ? *txp++ : 0;
			writew(value, ps->base + SSP_DR);
			len_tx++;
		}

		if (readw(ps->base + SSP_SR) & SSP_SR_MASK_RNE) {
			value = readw(ps->base + SSP_DR);
			if (rxp)
				*rxp++ = value;
			len_rx++;
		}
	}

	while (len_rx < len_tx) {
		if (readw(ps->base + SSP_SR) & SSP_SR_MASK_RNE) {
			value = readw(ps->base + SSP_DR);
			if (rxp)
				*rxp++ = value;
			len_rx++;
		}
	}

	return ret;
}

static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr)
{
	return rate / (cpsdvsr * (1 + scr));
}

static int pl022_spi_set_speed(struct udevice *bus, uint speed)
{
	struct pl022_spi_slave *ps = dev_get_priv(bus);
	u16 scr = SSP_SCR_MIN, cr0 = 0, cpsr = SSP_CPSR_MIN, best_scr = scr,
	    best_cpsr = cpsr;
	u32 min, max, best_freq = 0, tmp;
	u32 rate = ps->freq;
	bool found = false;

	max = spi_rate(rate, SSP_CPSR_MIN, SSP_SCR_MIN);
	min = spi_rate(rate, SSP_CPSR_MAX, SSP_SCR_MAX);

	if (speed > max || speed < min) {
		pr_err("Tried to set speed to %dHz but min=%d and max=%d\n",
		       speed, min, max);
		return -EINVAL;
	}

	while (cpsr <= SSP_CPSR_MAX && !found) {
		while (scr <= SSP_SCR_MAX) {
			tmp = spi_rate(rate, cpsr, scr);

			if (abs(speed - tmp) < abs(speed - best_freq)) {
				best_freq = tmp;
				best_cpsr = cpsr;
				best_scr = scr;

				if (tmp == speed) {
					found = true;
					break;
				}
			}

			scr++;
		}
		cpsr += 2;
		scr = SSP_SCR_MIN;
	}

	writew(best_cpsr, ps->base + SSP_CPSR);
	cr0 = readw(ps->base + SSP_CR0);
	writew(cr0 | (best_scr << SSP_SCR_SHFT), ps->base + SSP_CR0);

	return 0;
}

static int pl022_spi_set_mode(struct udevice *bus, uint mode)
{
	struct pl022_spi_slave *ps = dev_get_priv(bus);
	u16 reg;

	reg = readw(ps->base + SSP_CR0);
	reg &= ~(SSP_CR0_SPH | SSP_CR0_SPO);
	if (mode & SPI_CPHA)
		reg |= SSP_CR0_SPH;
	if (mode & SPI_CPOL)
		reg |= SSP_CR0_SPO;
	writew(reg, ps->base + SSP_CR0);

	return 0;
}

static int pl022_cs_info(struct udevice *bus, uint cs,
			 struct spi_cs_info *info)
{
	return 0;
}

static const struct dm_spi_ops pl022_spi_ops = {
	.claim_bus      = pl022_spi_claim_bus,
	.release_bus    = pl022_spi_release_bus,
	.xfer           = pl022_spi_xfer,
	.set_speed      = pl022_spi_set_speed,
	.set_mode       = pl022_spi_set_mode,
	.cs_info        = pl022_cs_info,
};

#if !CONFIG_IS_ENABLED(OF_PLATDATA)
static int pl022_spi_of_to_plat(struct udevice *bus)
{
	struct pl022_spi_pdata *plat = dev_get_plat(bus);
	const void *fdt = gd->fdt_blob;
	int node = dev_of_offset(bus);
	struct clk clkdev;
	int ret;

	plat->addr = fdtdec_get_addr_size(fdt, node, "reg", &plat->size);

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

	plat->freq = clk_get_rate(&clkdev);

	return 0;
}

static const struct udevice_id pl022_spi_ids[] = {
	{ .compatible = "arm,pl022-spi" },
	{ }
};
#endif

U_BOOT_DRIVER(pl022_spi) = {
	.name   = "pl022_spi",
	.id     = UCLASS_SPI,
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	.of_match = pl022_spi_ids,
	.of_to_plat = pl022_spi_of_to_plat,
#endif
	.ops    = &pl022_spi_ops,
	.plat_auto	= sizeof(struct pl022_spi_pdata),
	.priv_auto	= sizeof(struct pl022_spi_slave),
	.probe  = pl022_spi_probe,
};
