// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Microsemi SoCs spi driver
 *
 * Copyright (c) 2018 Microsemi Corporation
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <spi.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/delay.h>

struct mscc_bb_priv {
	void __iomem *regs;
	u32 deactivate_delay_us;
	bool cs_active;   /* State flag as to whether CS is asserted */
	int cs_num;
	u32 svalue;			/* Value to start transfer with */
	u32 clk1;			/* Clock value start */
	u32 clk2;			/* Clock value 2nd phase */
};

/* Delay 24 instructions for this particular application */
#define hold_time_delay() mscc_vcoreiii_nop_delay(3)

static int mscc_bb_spi_cs_activate(struct mscc_bb_priv *priv, int mode, int cs)
{
	if (!priv->cs_active) {
		int cpha = mode & SPI_CPHA;
		u32 cs_value;

		priv->cs_num = cs;

		if (cpha) {
			/* Initial clock starts SCK=1 */
			priv->clk1 = ICPU_SW_MODE_SW_SPI_SCK;
			priv->clk2 = 0;
		} else {
			/* Initial clock starts SCK=0 */
			priv->clk1 = 0;
			priv->clk2 = ICPU_SW_MODE_SW_SPI_SCK;
		}

		/* Enable bitbang, SCK_OE, SDO_OE */
		priv->svalue = (ICPU_SW_MODE_SW_PIN_CTRL_MODE | /* Bitbang */
				ICPU_SW_MODE_SW_SPI_SCK_OE    | /* SCK_OE */
				ICPU_SW_MODE_SW_SPI_SDO_OE);   /* SDO OE */

		/* Add CS */
		if (cs >= 0) {
			cs_value =
				ICPU_SW_MODE_SW_SPI_CS_OE(BIT(cs)) |
				ICPU_SW_MODE_SW_SPI_CS(BIT(cs));
		} else {
			cs_value = 0;
		}

		priv->svalue |= cs_value;

		/* Enable the CS in HW, Initial clock value */
		writel(priv->svalue | priv->clk2, priv->regs);

		priv->cs_active = true;
		debug("Activated CS%d\n", priv->cs_num);
	}

	return 0;
}

static int mscc_bb_spi_cs_deactivate(struct mscc_bb_priv *priv, int deact_delay)
{
	if (priv->cs_active) {
		/* Keep driving the CLK to its current value while
		 * actively deselecting CS.
		 */
		u32 value = readl(priv->regs);

		value &= ~ICPU_SW_MODE_SW_SPI_CS_M;
		writel(value, priv->regs);
		hold_time_delay();

		/* Stop driving the clock, but keep CS with nCS == 1 */
		value &= ~ICPU_SW_MODE_SW_SPI_SCK_OE;
		writel(value, priv->regs);

		/* Deselect hold time delay */
		if (deact_delay)
			udelay(deact_delay);

		/* Drop everything */
		writel(0, priv->regs);

		priv->cs_active = false;
		debug("Deactivated CS%d\n", priv->cs_num);
	}

	return 0;
}

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

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

int mscc_bb_spi_xfer(struct udevice *dev, unsigned int bitlen,
		     const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev_get_parent(dev);
	struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
	struct mscc_bb_priv *priv = dev_get_priv(bus);
	u32             i, count;
	const u8	*txd = dout;
	u8		*rxd = din;

	debug("spi_xfer: slave %s:%s cs%d mode %d, dout %p din %p bitlen %u\n",
	      dev->parent->name, dev->name, plat->cs,  plat->mode, dout,
	      din, bitlen);

	if (flags & SPI_XFER_BEGIN)
		mscc_bb_spi_cs_activate(priv, plat->mode, plat->cs);

	count = bitlen / 8;
	for (i = 0; i < count; i++) {
		u32 rx = 0, mask = 0x80, value;

		while (mask) {
			/* Initial condition: CLK is low. */
			value = priv->svalue;
			if (txd && txd[i] & mask)
				value |= ICPU_SW_MODE_SW_SPI_SDO;

			/* Drive data while taking CLK low. The device
			 * we're accessing will sample on the
			 * following rising edge and will output data
			 * on this edge for us to be sampled at the
			 * end of this loop.
			 */
			writel(value | priv->clk1, priv->regs);

			/* Wait for t_setup. All devices do have a
			 * setup-time, so we always insert some delay
			 * here. Some devices have a very long
			 * setup-time, which can be adjusted by the
			 * user through vcoreiii_device->delay.
			 */
			hold_time_delay();

			/* Drive the clock high. */
			writel(value | priv->clk2, priv->regs);

			/* Wait for t_hold. See comment about t_setup
			 * above.
			 */
			hold_time_delay();

			/* We sample as close to the next falling edge
			 * as possible.
			 */
			value = readl(priv->regs);
			if (value & ICPU_SW_MODE_SW_SPI_SDI)
				rx |= mask;
			mask >>= 1;
		}
		if (rxd) {
			debug("Read 0x%02x\n", rx);
			rxd[i] = (u8)rx;
		}
		debug("spi_xfer: byte %d/%d\n", i + 1, count);
	}

	debug("spi_xfer: done\n");

	if (flags & SPI_XFER_END)
		mscc_bb_spi_cs_deactivate(priv, priv->deactivate_delay_us);

	return 0;
}

int mscc_bb_spi_set_speed(struct udevice *dev, unsigned int speed)
{
	/* Accept any speed */
	return 0;
}

int mscc_bb_spi_set_mode(struct udevice *dev, unsigned int mode)
{
	return 0;
}

static const struct dm_spi_ops mscc_bb_ops = {
	.claim_bus	= mscc_bb_spi_claim_bus,
	.release_bus	= mscc_bb_spi_release_bus,
	.xfer		= mscc_bb_spi_xfer,
	.set_speed	= mscc_bb_spi_set_speed,
	.set_mode	= mscc_bb_spi_set_mode,
};

static const struct udevice_id mscc_bb_ids[] = {
	{ .compatible = "mscc,luton-bb-spi" },
	{ }
};

static int mscc_bb_spi_probe(struct udevice *bus)
{
	struct mscc_bb_priv *priv = dev_get_priv(bus);

	debug("%s: loaded, priv %p\n", __func__, priv);

	priv->regs = dev_read_addr_ptr(bus);

	priv->deactivate_delay_us =
		dev_read_u32_default(bus, "spi-deactivate-delay", 0);

	priv->cs_active = false;

	return 0;
}

U_BOOT_DRIVER(mscc_bb) = {
	.name	= "mscc_bb",
	.id	= UCLASS_SPI,
	.of_match = mscc_bb_ids,
	.ops	= &mscc_bb_ops,
	.priv_auto	= sizeof(struct mscc_bb_priv),
	.probe	= mscc_bb_spi_probe,
};
