// 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/of_device.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->master);
	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->master);
	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_master(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");
