// 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[mem->spi->chip_select];
	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->chip_select;
	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");
