// SPDX-License-Identifier: GPL-2.0-only
//
// HiSilicon SPI Controller Driver for Kunpeng SoCs
//
// Copyright (c) 2021 HiSilicon Technologies Co., Ltd.
// Author: Jay Fang <f.fangjian@huawei.com>
//
// This code is based on spi-dw-core.c.

#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>

/* Register offsets */
#define HISI_SPI_CSCR		0x00	/* cs control register */
#define HISI_SPI_CR		0x04	/* spi common control register */
#define HISI_SPI_ENR		0x08	/* spi enable register */
#define HISI_SPI_FIFOC		0x0c	/* fifo level control register */
#define HISI_SPI_IMR		0x10	/* interrupt mask register */
#define HISI_SPI_DIN		0x14	/* data in register */
#define HISI_SPI_DOUT		0x18	/* data out register */
#define HISI_SPI_SR		0x1c	/* status register */
#define HISI_SPI_RISR		0x20	/* raw interrupt status register */
#define HISI_SPI_ISR		0x24	/* interrupt status register */
#define HISI_SPI_ICR		0x28	/* interrupt clear register */
#define HISI_SPI_VERSION	0xe0	/* version register */

/* Bit fields in HISI_SPI_CR */
#define CR_LOOP_MASK		GENMASK(1, 1)
#define CR_CPOL_MASK		GENMASK(2, 2)
#define CR_CPHA_MASK		GENMASK(3, 3)
#define CR_DIV_PRE_MASK		GENMASK(11, 4)
#define CR_DIV_POST_MASK	GENMASK(19, 12)
#define CR_BPW_MASK		GENMASK(24, 20)
#define CR_SPD_MODE_MASK	GENMASK(25, 25)

/* Bit fields in HISI_SPI_FIFOC */
#define FIFOC_TX_MASK		GENMASK(5, 3)
#define FIFOC_RX_MASK		GENMASK(11, 9)

/* Bit fields in HISI_SPI_IMR, 4 bits */
#define IMR_RXOF		BIT(0)		/* Receive Overflow */
#define IMR_RXTO		BIT(1)		/* Receive Timeout */
#define IMR_RX			BIT(2)		/* Receive */
#define IMR_TX			BIT(3)		/* Transmit */
#define IMR_MASK		(IMR_RXOF | IMR_RXTO | IMR_RX | IMR_TX)

/* Bit fields in HISI_SPI_SR, 5 bits */
#define SR_TXE			BIT(0)		/* Transmit FIFO empty */
#define SR_TXNF			BIT(1)		/* Transmit FIFO not full */
#define SR_RXNE			BIT(2)		/* Receive FIFO not empty */
#define SR_RXF			BIT(3)		/* Receive FIFO full */
#define SR_BUSY			BIT(4)		/* Busy Flag */

/* Bit fields in HISI_SPI_ISR, 4 bits */
#define ISR_RXOF		BIT(0)		/* Receive Overflow */
#define ISR_RXTO		BIT(1)		/* Receive Timeout */
#define ISR_RX			BIT(2)		/* Receive */
#define ISR_TX			BIT(3)		/* Transmit */
#define ISR_MASK		(ISR_RXOF | ISR_RXTO | ISR_RX | ISR_TX)

/* Bit fields in HISI_SPI_ICR, 2 bits */
#define ICR_RXOF		BIT(0)		/* Receive Overflow */
#define ICR_RXTO		BIT(1)		/* Receive Timeout */
#define ICR_MASK		(ICR_RXOF | ICR_RXTO)

#define DIV_POST_MAX		0xFF
#define DIV_POST_MIN		0x00
#define DIV_PRE_MAX		0xFE
#define DIV_PRE_MIN		0x02
#define CLK_DIV_MAX		((1 + DIV_POST_MAX) * DIV_PRE_MAX)
#define CLK_DIV_MIN		((1 + DIV_POST_MIN) * DIV_PRE_MIN)

#define DEFAULT_NUM_CS		1

#define HISI_SPI_WAIT_TIMEOUT_MS	10UL

enum hisi_spi_rx_level_trig {
	HISI_SPI_RX_1,
	HISI_SPI_RX_4,
	HISI_SPI_RX_8,
	HISI_SPI_RX_16,
	HISI_SPI_RX_32,
	HISI_SPI_RX_64,
	HISI_SPI_RX_128
};

enum hisi_spi_tx_level_trig {
	HISI_SPI_TX_1_OR_LESS,
	HISI_SPI_TX_4_OR_LESS,
	HISI_SPI_TX_8_OR_LESS,
	HISI_SPI_TX_16_OR_LESS,
	HISI_SPI_TX_32_OR_LESS,
	HISI_SPI_TX_64_OR_LESS,
	HISI_SPI_TX_128_OR_LESS
};

enum hisi_spi_frame_n_bytes {
	HISI_SPI_N_BYTES_NULL,
	HISI_SPI_N_BYTES_U8,
	HISI_SPI_N_BYTES_U16,
	HISI_SPI_N_BYTES_U32 = 4
};

/* Slave spi_dev related */
struct hisi_chip_data {
	u32 cr;
	u32 speed_hz;	/* baud rate */
	u16 clk_div;	/* baud rate divider */

	/* clk_div = (1 + div_post) * div_pre */
	u8 div_post;	/* value from 0 to 255 */
	u8 div_pre;	/* value from 2 to 254 (even only!) */
};

struct hisi_spi {
	struct device		*dev;

	void __iomem		*regs;
	int			irq;
	u32			fifo_len; /* depth of the FIFO buffer */

	/* Current message transfer state info */
	const void		*tx;
	unsigned int		tx_len;
	void			*rx;
	unsigned int		rx_len;
	u8			n_bytes; /* current is a 1/2/4 bytes op */

	struct dentry *debugfs;
	struct debugfs_regset32 regset;
};

#define HISI_SPI_DBGFS_REG(_name, _off)	\
{					\
	.name = _name,			\
	.offset = _off,			\
}

static const struct debugfs_reg32 hisi_spi_regs[] = {
	HISI_SPI_DBGFS_REG("CSCR", HISI_SPI_CSCR),
	HISI_SPI_DBGFS_REG("CR", HISI_SPI_CR),
	HISI_SPI_DBGFS_REG("ENR", HISI_SPI_ENR),
	HISI_SPI_DBGFS_REG("FIFOC", HISI_SPI_FIFOC),
	HISI_SPI_DBGFS_REG("IMR", HISI_SPI_IMR),
	HISI_SPI_DBGFS_REG("DIN", HISI_SPI_DIN),
	HISI_SPI_DBGFS_REG("DOUT", HISI_SPI_DOUT),
	HISI_SPI_DBGFS_REG("SR", HISI_SPI_SR),
	HISI_SPI_DBGFS_REG("RISR", HISI_SPI_RISR),
	HISI_SPI_DBGFS_REG("ISR", HISI_SPI_ISR),
	HISI_SPI_DBGFS_REG("ICR", HISI_SPI_ICR),
	HISI_SPI_DBGFS_REG("VERSION", HISI_SPI_VERSION),
};

static int hisi_spi_debugfs_init(struct hisi_spi *hs)
{
	char name[32];

	struct spi_controller *host;

	host = container_of(hs->dev, struct spi_controller, dev);
	snprintf(name, 32, "hisi_spi%d", host->bus_num);
	hs->debugfs = debugfs_create_dir(name, NULL);
	if (IS_ERR(hs->debugfs))
		return -ENOMEM;

	hs->regset.regs = hisi_spi_regs;
	hs->regset.nregs = ARRAY_SIZE(hisi_spi_regs);
	hs->regset.base = hs->regs;
	debugfs_create_regset32("registers", 0400, hs->debugfs, &hs->regset);

	return 0;
}

static u32 hisi_spi_busy(struct hisi_spi *hs)
{
	return readl(hs->regs + HISI_SPI_SR) & SR_BUSY;
}

static u32 hisi_spi_rx_not_empty(struct hisi_spi *hs)
{
	return readl(hs->regs + HISI_SPI_SR) & SR_RXNE;
}

static u32 hisi_spi_tx_not_full(struct hisi_spi *hs)
{
	return readl(hs->regs + HISI_SPI_SR) & SR_TXNF;
}

static void hisi_spi_flush_fifo(struct hisi_spi *hs)
{
	unsigned long limit = loops_per_jiffy << 1;

	do {
		while (hisi_spi_rx_not_empty(hs))
			readl(hs->regs + HISI_SPI_DOUT);
	} while (hisi_spi_busy(hs) && limit--);
}

/* Disable the controller and all interrupts */
static void hisi_spi_disable(struct hisi_spi *hs)
{
	writel(0, hs->regs + HISI_SPI_ENR);
	writel(IMR_MASK, hs->regs + HISI_SPI_IMR);
	writel(ICR_MASK, hs->regs + HISI_SPI_ICR);
}

static u8 hisi_spi_n_bytes(struct spi_transfer *transfer)
{
	if (transfer->bits_per_word <= 8)
		return HISI_SPI_N_BYTES_U8;
	else if (transfer->bits_per_word <= 16)
		return HISI_SPI_N_BYTES_U16;
	else
		return HISI_SPI_N_BYTES_U32;
}

static void hisi_spi_reader(struct hisi_spi *hs)
{
	u32 max = min_t(u32, hs->rx_len, hs->fifo_len);
	u32 rxw;

	while (hisi_spi_rx_not_empty(hs) && max--) {
		rxw = readl(hs->regs + HISI_SPI_DOUT);
		/* Check the transfer's original "rx" is not null */
		if (hs->rx) {
			switch (hs->n_bytes) {
			case HISI_SPI_N_BYTES_U8:
				*(u8 *)(hs->rx) = rxw;
				break;
			case HISI_SPI_N_BYTES_U16:
				*(u16 *)(hs->rx) = rxw;
				break;
			case HISI_SPI_N_BYTES_U32:
				*(u32 *)(hs->rx) = rxw;
				break;
			}
			hs->rx += hs->n_bytes;
		}
		--hs->rx_len;
	}
}

static void hisi_spi_writer(struct hisi_spi *hs)
{
	u32 max = min_t(u32, hs->tx_len, hs->fifo_len);
	u32 txw = 0;

	while (hisi_spi_tx_not_full(hs) && max--) {
		/* Check the transfer's original "tx" is not null */
		if (hs->tx) {
			switch (hs->n_bytes) {
			case HISI_SPI_N_BYTES_U8:
				txw = *(u8 *)(hs->tx);
				break;
			case HISI_SPI_N_BYTES_U16:
				txw = *(u16 *)(hs->tx);
				break;
			case HISI_SPI_N_BYTES_U32:
				txw = *(u32 *)(hs->tx);
				break;
			}
			hs->tx += hs->n_bytes;
		}
		writel(txw, hs->regs + HISI_SPI_DIN);
		--hs->tx_len;
	}
}

static void __hisi_calc_div_reg(struct hisi_chip_data *chip)
{
	chip->div_pre = DIV_PRE_MAX;
	while (chip->div_pre >= DIV_PRE_MIN) {
		if (chip->clk_div % chip->div_pre == 0)
			break;

		chip->div_pre -= 2;
	}

	if (chip->div_pre > chip->clk_div)
		chip->div_pre = chip->clk_div;

	chip->div_post = (chip->clk_div / chip->div_pre) - 1;
}

static u32 hisi_calc_effective_speed(struct spi_controller *host,
			struct hisi_chip_data *chip, u32 speed_hz)
{
	u32 effective_speed;

	/* Note clock divider doesn't support odd numbers */
	chip->clk_div = DIV_ROUND_UP(host->max_speed_hz, speed_hz) + 1;
	chip->clk_div &= 0xfffe;
	if (chip->clk_div > CLK_DIV_MAX)
		chip->clk_div = CLK_DIV_MAX;

	effective_speed = host->max_speed_hz / chip->clk_div;
	if (chip->speed_hz != effective_speed) {
		__hisi_calc_div_reg(chip);
		chip->speed_hz = effective_speed;
	}

	return effective_speed;
}

static u32 hisi_spi_prepare_cr(struct spi_device *spi)
{
	u32 cr = FIELD_PREP(CR_SPD_MODE_MASK, 1);

	cr |= FIELD_PREP(CR_CPHA_MASK, (spi->mode & SPI_CPHA) ? 1 : 0);
	cr |= FIELD_PREP(CR_CPOL_MASK, (spi->mode & SPI_CPOL) ? 1 : 0);
	cr |= FIELD_PREP(CR_LOOP_MASK, (spi->mode & SPI_LOOP) ? 1 : 0);

	return cr;
}

static void hisi_spi_hw_init(struct hisi_spi *hs)
{
	hisi_spi_disable(hs);

	/* FIFO default config */
	writel(FIELD_PREP(FIFOC_TX_MASK, HISI_SPI_TX_64_OR_LESS) |
		FIELD_PREP(FIFOC_RX_MASK, HISI_SPI_RX_16),
		hs->regs + HISI_SPI_FIFOC);

	hs->fifo_len = 256;
}

static irqreturn_t hisi_spi_irq(int irq, void *dev_id)
{
	struct spi_controller *host = dev_id;
	struct hisi_spi *hs = spi_controller_get_devdata(host);
	u32 irq_status = readl(hs->regs + HISI_SPI_ISR) & ISR_MASK;

	if (!irq_status)
		return IRQ_NONE;

	if (!host->cur_msg)
		return IRQ_HANDLED;

	/* Error handling */
	if (irq_status & ISR_RXOF) {
		dev_err(hs->dev, "interrupt_transfer: fifo overflow\n");
		host->cur_msg->status = -EIO;
		goto finalize_transfer;
	}

	/*
	 * Read data from the Rx FIFO every time. If there is
	 * nothing left to receive, finalize the transfer.
	 */
	hisi_spi_reader(hs);
	if (!hs->rx_len)
		goto finalize_transfer;

	/* Send data out when Tx FIFO IRQ triggered */
	if (irq_status & ISR_TX)
		hisi_spi_writer(hs);

	return IRQ_HANDLED;

finalize_transfer:
	hisi_spi_disable(hs);
	spi_finalize_current_transfer(host);
	return IRQ_HANDLED;
}

static int hisi_spi_transfer_one(struct spi_controller *host,
		struct spi_device *spi, struct spi_transfer *transfer)
{
	struct hisi_spi *hs = spi_controller_get_devdata(host);
	struct hisi_chip_data *chip = spi_get_ctldata(spi);
	u32 cr = chip->cr;

	/* Update per transfer options for speed and bpw */
	transfer->effective_speed_hz =
		hisi_calc_effective_speed(host, chip, transfer->speed_hz);
	cr |= FIELD_PREP(CR_DIV_PRE_MASK, chip->div_pre);
	cr |= FIELD_PREP(CR_DIV_POST_MASK, chip->div_post);
	cr |= FIELD_PREP(CR_BPW_MASK, transfer->bits_per_word - 1);
	writel(cr, hs->regs + HISI_SPI_CR);

	hisi_spi_flush_fifo(hs);

	hs->n_bytes = hisi_spi_n_bytes(transfer);
	hs->tx = transfer->tx_buf;
	hs->tx_len = transfer->len / hs->n_bytes;
	hs->rx = transfer->rx_buf;
	hs->rx_len = hs->tx_len;

	/*
	 * Ensure that the transfer data above has been updated
	 * before the interrupt to start.
	 */
	smp_mb();

	/* Enable all interrupts and the controller */
	writel(~(u32)IMR_MASK, hs->regs + HISI_SPI_IMR);
	writel(1, hs->regs + HISI_SPI_ENR);

	return 1;
}

static void hisi_spi_handle_err(struct spi_controller *host,
		struct spi_message *msg)
{
	struct hisi_spi *hs = spi_controller_get_devdata(host);

	hisi_spi_disable(hs);

	/*
	 * Wait for interrupt handler that is
	 * already in timeout to complete.
	 */
	msleep(HISI_SPI_WAIT_TIMEOUT_MS);
}

static int hisi_spi_setup(struct spi_device *spi)
{
	struct hisi_chip_data *chip;

	/* Only alloc on first setup */
	chip = spi_get_ctldata(spi);
	if (!chip) {
		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
		if (!chip)
			return -ENOMEM;
		spi_set_ctldata(spi, chip);
	}

	chip->cr = hisi_spi_prepare_cr(spi);

	return 0;
}

static void hisi_spi_cleanup(struct spi_device *spi)
{
	struct hisi_chip_data *chip = spi_get_ctldata(spi);

	kfree(chip);
	spi_set_ctldata(spi, NULL);
}

static int hisi_spi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct spi_controller *host;
	struct hisi_spi *hs;
	int ret, irq;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	host = devm_spi_alloc_host(dev, sizeof(*hs));
	if (!host)
		return -ENOMEM;

	platform_set_drvdata(pdev, host);

	hs = spi_controller_get_devdata(host);
	hs->dev = dev;
	hs->irq = irq;

	hs->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(hs->regs))
		return PTR_ERR(hs->regs);

	/* Specify maximum SPI clocking speed (host only) by firmware */
	ret = device_property_read_u32(dev, "spi-max-frequency",
					&host->max_speed_hz);
	if (ret) {
		dev_err(dev, "failed to get max SPI clocking speed, ret=%d\n",
			ret);
		return -EINVAL;
	}

	ret = device_property_read_u16(dev, "num-cs",
					&host->num_chipselect);
	if (ret)
		host->num_chipselect = DEFAULT_NUM_CS;

	host->use_gpio_descriptors = true;
	host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
	host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
	host->bus_num = pdev->id;
	host->setup = hisi_spi_setup;
	host->cleanup = hisi_spi_cleanup;
	host->transfer_one = hisi_spi_transfer_one;
	host->handle_err = hisi_spi_handle_err;
	host->dev.fwnode = dev->fwnode;

	hisi_spi_hw_init(hs);

	ret = devm_request_irq(dev, hs->irq, hisi_spi_irq, 0, dev_name(dev),
			       host);
	if (ret < 0) {
		dev_err(dev, "failed to get IRQ=%d, ret=%d\n", hs->irq, ret);
		return ret;
	}

	ret = spi_register_controller(host);
	if (ret) {
		dev_err(dev, "failed to register spi host, ret=%d\n", ret);
		return ret;
	}

	if (hisi_spi_debugfs_init(hs))
		dev_info(dev, "failed to create debugfs dir\n");

	dev_info(dev, "hw version:0x%x max-freq:%u kHz\n",
		readl(hs->regs + HISI_SPI_VERSION),
		host->max_speed_hz / 1000);

	return 0;
}

static void hisi_spi_remove(struct platform_device *pdev)
{
	struct spi_controller *host = platform_get_drvdata(pdev);
	struct hisi_spi *hs = spi_controller_get_devdata(host);

	debugfs_remove_recursive(hs->debugfs);
	spi_unregister_controller(host);
}

static const struct acpi_device_id hisi_spi_acpi_match[] = {
	{"HISI03E1", 0},
	{}
};
MODULE_DEVICE_TABLE(acpi, hisi_spi_acpi_match);

static struct platform_driver hisi_spi_driver = {
	.probe		= hisi_spi_probe,
	.remove_new	= hisi_spi_remove,
	.driver		= {
		.name	= "hisi-kunpeng-spi",
		.acpi_match_table = hisi_spi_acpi_match,
	},
};
module_platform_driver(hisi_spi_driver);

MODULE_AUTHOR("Jay Fang <f.fangjian@huawei.com>");
MODULE_DESCRIPTION("HiSilicon SPI Controller Driver for Kunpeng SoCs");
MODULE_LICENSE("GPL v2");
