// 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("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");
