// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2021 Nuvoton Technology.
 */

#include <common.h>
#include <dm.h>
#include <spi.h>
#include <clk.h>
#include <reset.h>
#include <asm/gpio.h>
#include <linux/iopoll.h>

#define MAX_DIV	127

/* Register offsets */
#define PSPI_DATA		0
#define PSPI_CTL1		2
#define PSPI_STAT		4

/* PSPI_CTL1 fields */
#define PSPI_CTL1_SPIEN		BIT(0)
#define PSPI_CTL1_SCM		BIT(7)
#define PSPI_CTL1_SCIDL		BIT(8)
#define PSPI_CTL1_SCDV_MASK	GENMASK(15, 9)
#define PSPI_CTL1_SCDV_SHIFT	9

/* PSPI_STAT fields */
#define PSPI_STAT_BSY		BIT(0)
#define PSPI_STAT_RBF		BIT(1)

struct npcm_pspi_priv {
	void __iomem *base;
	struct clk clk;
	struct gpio_desc cs_gpio;
	u32 max_hz;
};

static inline void spi_cs_activate(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct npcm_pspi_priv *priv = dev_get_priv(bus);

	dm_gpio_set_value(&priv->cs_gpio, 1);
}

static inline void spi_cs_deactivate(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct npcm_pspi_priv *priv = dev_get_priv(bus);

	dm_gpio_set_value(&priv->cs_gpio, 0);
}

static inline void npcm_pspi_enable(struct npcm_pspi_priv *priv)
{
	u16 val;

	val = readw(priv->base + PSPI_CTL1);
	val |= PSPI_CTL1_SPIEN;
	writew(val, priv->base + PSPI_CTL1);
}

static inline void npcm_pspi_disable(struct npcm_pspi_priv *priv)
{
	u16 val;

	val = readw(priv->base + PSPI_CTL1);
	val &= ~PSPI_CTL1_SPIEN;
	writew(val, priv->base + PSPI_CTL1);
}

static int npcm_pspi_xfer(struct udevice *dev, unsigned int bitlen,
			  const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct npcm_pspi_priv *priv = dev_get_priv(bus);
	void __iomem *base = priv->base;
	const u8 *tx = dout;
	u8 *rx = din;
	u32 bytes = bitlen / 8;
	u8 tmp;
	u32 val;
	int i, ret = 0;

	npcm_pspi_enable(priv);

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(dev);

	for (i = 0; i < bytes; i++) {
		/* Making sure we can write */
		ret = readb_poll_timeout(base + PSPI_STAT, val,
					 !(val & PSPI_STAT_BSY),
					 1000000);
		if (ret < 0)
			break;

		if (tx)
			writeb(*tx++, base + PSPI_DATA);
		else
			writeb(0, base + PSPI_DATA);

		/* Wait till write completed */
		ret = readb_poll_timeout(base + PSPI_STAT, val,
					 !(val & PSPI_STAT_BSY),
					 1000000);
		if (ret < 0)
			break;

		/* Wait till read buffer full */
		ret = readb_poll_timeout(base + PSPI_STAT, val,
					 (val & PSPI_STAT_RBF),
					 1000000);
		if (ret < 0)
			break;

		tmp = readb(base + PSPI_DATA);
		if (rx)
			*rx++ = tmp;
	}

	if (flags & SPI_XFER_END)
		spi_cs_deactivate(dev);

	debug("npcm_pspi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
	      dev->parent->name, dev->name, *(uint *)tx, *(uint *)rx, bitlen);

	npcm_pspi_disable(priv);

	return ret;
}

static int npcm_pspi_set_speed(struct udevice *bus, uint speed)
{
	struct npcm_pspi_priv *priv = dev_get_priv(bus);
	ulong apb_clock;
	u32 divisor;
	u16 val;

	apb_clock = clk_get_rate(&priv->clk);
	if (!apb_clock)
		return -EINVAL;

	if (speed > priv->max_hz)
		speed = priv->max_hz;

	divisor = DIV_ROUND_CLOSEST(apb_clock, (2 * speed)) - 1;
	if (divisor > MAX_DIV)
		divisor = MAX_DIV;

	val = readw(priv->base + PSPI_CTL1);
	val &= ~PSPI_CTL1_SCDV_MASK;
	val |= divisor << PSPI_CTL1_SCDV_SHIFT;
	writew(val, priv->base + PSPI_CTL1);

	debug("%s: apb_clock=%lu speed=%d divisor=%u\n",
	      __func__, apb_clock, speed, divisor);

	return 0;
}

static int npcm_pspi_set_mode(struct udevice *bus, uint mode)
{
	struct npcm_pspi_priv *priv = dev_get_priv(bus);
	u16 pspi_mode, val;

	switch (mode & (SPI_CPOL | SPI_CPHA)) {
	case SPI_MODE_0:
		pspi_mode = 0;
		break;
	case SPI_MODE_1:
		pspi_mode = PSPI_CTL1_SCM;
		break;
	case SPI_MODE_2:
		pspi_mode = PSPI_CTL1_SCIDL;
		break;
	case SPI_MODE_3:
		pspi_mode = PSPI_CTL1_SCIDL | PSPI_CTL1_SCM;
		break;
	default:
		break;
	}

	val = readw(priv->base + PSPI_CTL1);
	val &= ~(PSPI_CTL1_SCIDL | PSPI_CTL1_SCM);
	val |= pspi_mode;
	writew(val, priv->base + PSPI_CTL1);

	debug("%s: mode=%u\n", __func__, mode);
	return 0;
}

static int npcm_pspi_probe(struct udevice *bus)
{
	struct npcm_pspi_priv *priv = dev_get_priv(bus);
	int node = dev_of_offset(bus);
	struct reset_ctl reset;
	int ret;

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

	priv->base = dev_read_addr_ptr(bus);
	priv->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 1000000);
	gpio_request_by_name_nodev(offset_to_ofnode(node), "cs-gpios", 0,
				   &priv->cs_gpio, GPIOD_IS_OUT| GPIOD_ACTIVE_LOW);

	/* Reset HW */
	ret = reset_get_by_index(bus, 0, &reset);
	if (!ret) {
		reset_assert(&reset);
		udelay(5);
		reset_deassert(&reset);
	}

	return 0;
}

static const struct dm_spi_ops npcm_pspi_ops = {
	.xfer           = npcm_pspi_xfer,
	.set_speed      = npcm_pspi_set_speed,
	.set_mode       = npcm_pspi_set_mode,
};

static const struct udevice_id npcm_pspi_ids[] = {
	{ .compatible = "nuvoton,npcm845-pspi"},
	{ .compatible = "nuvoton,npcm750-pspi"},
	{ }
};

U_BOOT_DRIVER(npcm_pspi) = {
	.name   = "npcm_pspi",
	.id     = UCLASS_SPI,
	.of_match = npcm_pspi_ids,
	.ops    = &npcm_pspi_ops,
	.priv_auto = sizeof(struct npcm_pspi_priv),
	.probe  = npcm_pspi_probe,
};
