// SPDX-License-Identifier: GPL-2.0-or-later
/* Copyright (C) 2022 Hewlett-Packard Development Company, L.P. */

#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>

#define GXP_SPI0_MAX_CHIPSELECT	2
#define GXP_SPI_SLEEP_TIME	1
#define GXP_SPI_TIMEOUT (130 * 1000000 / GXP_SPI_SLEEP_TIME)

#define MANUAL_MODE		0
#define DIRECT_MODE		1
#define SPILDAT_LEN		256

#define OFFSET_SPIMCFG		0x0
#define OFFSET_SPIMCTRL		0x4
#define OFFSET_SPICMD		0x5
#define OFFSET_SPIDCNT		0x6
#define OFFSET_SPIADDR		0x8
#define OFFSET_SPIINTSTS	0xc

#define SPIMCTRL_START		0x01
#define SPIMCTRL_BUSY		0x02
#define SPIMCTRL_DIR		0x08

struct gxp_spi;

struct gxp_spi_chip {
	struct gxp_spi *spifi;
	u32 cs;
};

struct gxp_spi_data {
	u32 max_cs;
	u32 mode_bits;
};

struct gxp_spi {
	const struct gxp_spi_data *data;
	void __iomem *reg_base;
	void __iomem *dat_base;
	void __iomem *dir_base;
	struct device *dev;
	struct gxp_spi_chip chips[GXP_SPI0_MAX_CHIPSELECT];
};

static void gxp_spi_set_mode(struct gxp_spi *spifi, int mode)
{
	u8 value;
	void __iomem *reg_base = spifi->reg_base;

	value = readb(reg_base + OFFSET_SPIMCTRL);

	if (mode == MANUAL_MODE) {
		writeb(0x55, reg_base + OFFSET_SPICMD);
		writeb(0xaa, reg_base + OFFSET_SPICMD);
		value &= ~0x30;
	} else {
		value |= 0x30;
	}
	writeb(value, reg_base + OFFSET_SPIMCTRL);
}

static int gxp_spi_read_reg(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
{
	int ret;
	struct gxp_spi *spifi = chip->spifi;
	void __iomem *reg_base = spifi->reg_base;
	u32 value;

	value = readl(reg_base + OFFSET_SPIMCFG);
	value &= ~(1 << 24);
	value |= (chip->cs << 24);
	value &= ~(0x07 << 16);
	value &= ~(0x1f << 19);
	writel(value, reg_base + OFFSET_SPIMCFG);

	writel(0, reg_base + OFFSET_SPIADDR);

	writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD);

	writew(op->data.nbytes, reg_base + OFFSET_SPIDCNT);

	value = readb(reg_base + OFFSET_SPIMCTRL);
	value &= ~SPIMCTRL_DIR;
	value |= SPIMCTRL_START;

	writeb(value, reg_base + OFFSET_SPIMCTRL);

	ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value,
				 !(value & SPIMCTRL_BUSY),
				 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT);
	if (ret) {
		dev_warn(spifi->dev, "read reg busy time out\n");
		return ret;
	}

	memcpy_fromio(op->data.buf.in, spifi->dat_base, op->data.nbytes);
	return ret;
}

static int gxp_spi_write_reg(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
{
	int ret;
	struct gxp_spi *spifi = chip->spifi;
	void __iomem *reg_base = spifi->reg_base;
	u32 value;

	value = readl(reg_base + OFFSET_SPIMCFG);
	value &= ~(1 << 24);
	value |= (chip->cs << 24);
	value &= ~(0x07 << 16);
	value &= ~(0x1f << 19);
	writel(value, reg_base + OFFSET_SPIMCFG);

	writel(0, reg_base + OFFSET_SPIADDR);

	writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD);

	memcpy_toio(spifi->dat_base, op->data.buf.in, op->data.nbytes);

	writew(op->data.nbytes, reg_base + OFFSET_SPIDCNT);

	value = readb(reg_base + OFFSET_SPIMCTRL);
	value |= SPIMCTRL_DIR;
	value |= SPIMCTRL_START;

	writeb(value, reg_base + OFFSET_SPIMCTRL);

	ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value,
				 !(value & SPIMCTRL_BUSY),
				 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT);
	if (ret)
		dev_warn(spifi->dev, "write reg busy time out\n");

	return ret;
}

static ssize_t gxp_spi_read(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
{
	struct gxp_spi *spifi = chip->spifi;
	u32 offset = op->addr.val;

	if (chip->cs == 0)
		offset += 0x4000000;

	memcpy_fromio(op->data.buf.in, spifi->dir_base + offset, op->data.nbytes);

	return 0;
}

static ssize_t gxp_spi_write(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
{
	struct gxp_spi *spifi = chip->spifi;
	void __iomem *reg_base = spifi->reg_base;
	u32 write_len;
	u32 value;
	int ret;

	write_len = op->data.nbytes;
	if (write_len > SPILDAT_LEN)
		write_len = SPILDAT_LEN;

	value = readl(reg_base + OFFSET_SPIMCFG);
	value &= ~(1 << 24);
	value |= (chip->cs << 24);
	value &= ~(0x07 << 16);
	value |= (op->addr.nbytes << 16);
	value &= ~(0x1f << 19);
	writel(value, reg_base + OFFSET_SPIMCFG);

	writel(op->addr.val, reg_base + OFFSET_SPIADDR);

	writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD);

	writew(write_len, reg_base + OFFSET_SPIDCNT);

	memcpy_toio(spifi->dat_base, op->data.buf.in, write_len);

	value = readb(reg_base + OFFSET_SPIMCTRL);
	value |= SPIMCTRL_DIR;
	value |= SPIMCTRL_START;

	writeb(value, reg_base + OFFSET_SPIMCTRL);

	ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value,
				 !(value & SPIMCTRL_BUSY),
				 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT);
	if (ret) {
		dev_warn(spifi->dev, "write busy time out\n");
		return ret;
	}

	return write_len;
}

static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
	struct gxp_spi *spifi = spi_controller_get_devdata(mem->spi->controller);
	struct gxp_spi_chip *chip = &spifi->chips[spi_get_chipselect(mem->spi, 0)];
	int ret;

	if (op->data.dir == SPI_MEM_DATA_IN) {
		if (!op->addr.nbytes)
			ret = gxp_spi_read_reg(chip, op);
		else
			ret = gxp_spi_read(chip, op);
	} else {
		if (!op->addr.nbytes)
			ret = gxp_spi_write_reg(chip, op);
		else
			ret = gxp_spi_write(chip, op);
	}

	return ret;
}

static int gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
	int ret;

	ret = do_gxp_exec_mem_op(mem, op);
	if (ret)
		dev_err(&mem->spi->dev, "operation failed: %d", ret);

	return ret;
}

static const struct spi_controller_mem_ops gxp_spi_mem_ops = {
	.exec_op = gxp_exec_mem_op,
};

static int gxp_spi_setup(struct spi_device *spi)
{
	struct gxp_spi *spifi = spi_controller_get_devdata(spi->controller);
	unsigned int cs = spi_get_chipselect(spi, 0);
	struct gxp_spi_chip *chip = &spifi->chips[cs];

	chip->spifi = spifi;
	chip->cs = cs;

	gxp_spi_set_mode(spifi, MANUAL_MODE);

	return 0;
}

static int gxp_spifi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	const struct gxp_spi_data *data;
	struct spi_controller *ctlr;
	struct gxp_spi *spifi;
	int ret;

	data = of_device_get_match_data(&pdev->dev);

	ctlr = devm_spi_alloc_host(dev, sizeof(*spifi));
	if (!ctlr)
		return -ENOMEM;

	spifi = spi_controller_get_devdata(ctlr);

	platform_set_drvdata(pdev, spifi);
	spifi->data = data;
	spifi->dev = dev;

	spifi->reg_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(spifi->reg_base))
		return PTR_ERR(spifi->reg_base);

	spifi->dat_base = devm_platform_ioremap_resource(pdev, 1);
	if (IS_ERR(spifi->dat_base))
		return PTR_ERR(spifi->dat_base);

	spifi->dir_base = devm_platform_ioremap_resource(pdev, 2);
	if (IS_ERR(spifi->dir_base))
		return PTR_ERR(spifi->dir_base);

	ctlr->mode_bits = data->mode_bits;
	ctlr->bus_num = pdev->id;
	ctlr->mem_ops = &gxp_spi_mem_ops;
	ctlr->setup = gxp_spi_setup;
	ctlr->num_chipselect = data->max_cs;
	ctlr->dev.of_node = dev->of_node;

	ret = devm_spi_register_controller(dev, ctlr);
	if (ret) {
		return dev_err_probe(&pdev->dev, ret,
				     "failed to register spi controller\n");
	}

	return 0;
}

static const struct gxp_spi_data gxp_spifi_data = {
	.max_cs	= 2,
	.mode_bits = 0,
};

static const struct of_device_id gxp_spifi_match[] = {
	{.compatible = "hpe,gxp-spifi", .data = &gxp_spifi_data },
	{ /* null */ }
};
MODULE_DEVICE_TABLE(of, gxp_spifi_match);

static struct platform_driver gxp_spifi_driver = {
	.probe = gxp_spifi_probe,
	.driver = {
		.name = "gxp-spifi",
		.of_match_table = gxp_spifi_match,
	},
};
module_platform_driver(gxp_spifi_driver);

MODULE_DESCRIPTION("HPE GXP SPI Flash Interface driver");
MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>");
MODULE_LICENSE("GPL");
