/*
 * Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT xlnx_xps_spi_2_00_a

#include <zephyr/device.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(xlnx_quadspi, CONFIG_SPI_LOG_LEVEL);

#include "spi_context.h"

/* AXI Quad SPI v3.2 register offsets (See Xilinx PG153 for details) */
#define SRR_OFFSET             0x40
#define SPICR_OFFSET           0x60
#define SPISR_OFFSET           0x64
#define SPI_DTR_OFFSET         0x68
#define SPI_DRR_OFFSET         0x6c
#define SPISSR_OFFSET          0x70
#define SPI_TX_FIFO_OCR_OFFSET 0x74
#define SPI_RX_FIFO_OCR_OFFSET 0x78
#define DGIER_OFFSET           0x1c
#define IPISR_OFFSET           0x20
#define IPIER_OFFSET           0x28

/* SRR bit definitions */
#define SRR_SOFTRESET_MAGIC 0xa

/* SPICR bit definitions */
#define SPICR_LOOP            BIT(0)
#define SPICR_SPE             BIT(1)
#define SPICR_MASTER          BIT(2)
#define SPICR_CPOL            BIT(3)
#define SPICR_CPHA            BIT(4)
#define SPICR_TX_FIFO_RESET   BIT(5)
#define SPICR_RX_FIFO_RESET   BIT(6)
#define SPICR_MANUAL_SS       BIT(7)
#define SPICR_MASTER_XFER_INH BIT(8)
#define SPICR_LSB_FIRST       BIT(9)

/* SPISR bit definitions */
#define SPISR_RX_EMPTY          BIT(0)
#define SPISR_RX_FULL           BIT(1)
#define SPISR_TX_EMPTY          BIT(2)
#define SPISR_TX_FULL           BIT(3)
#define SPISR_MODF              BIT(4)
#define SPISR_SLAVE_MODE_SELECT BIT(5)
#define SPISR_CPOL_CPHA_ERROR   BIT(6)
#define SPISR_SLAVE_MODE_ERROR  BIT(7)
#define SPISR_MSB_ERROR         BIT(8)
#define SPISR_LOOPBACK_ERROR    BIT(9)
#define SPISR_COMMAND_ERROR     BIT(10)

#define SPISR_ERROR_MASK (SPISR_COMMAND_ERROR |		\
			  SPISR_LOOPBACK_ERROR |	\
			  SPISR_MSB_ERROR |		\
			  SPISR_SLAVE_MODE_ERROR |	\
			  SPISR_CPOL_CPHA_ERROR)

/* DGIER bit definitions */
#define DGIER_GIE BIT(31)

/* IPISR and IPIER bit definitions */
#define IPIXR_MODF               BIT(0)
#define IPIXR_SLAVE_MODF         BIT(1)
#define IPIXR_DTR_EMPTY          BIT(2)
#define IPIXR_DTR_UNDERRUN       BIT(3)
#define IPIXR_DRR_FULL           BIT(4)
#define IPIXR_DRR_OVERRUN        BIT(5)
#define IPIXR_TX_FIFO_HALF_EMPTY BIT(6)
#define IPIXR_SLAVE_MODE_SELECT  BIT(7)
#define IPIXR_DDR_NOT_EMPTY      BIT(8)
#define IPIXR_CPOL_CPHA_ERROR    BIT(9)
#define IPIXR_SLAVE_MODE_ERROR   BIT(10)
#define IPIXR_MSB_ERROR          BIT(11)
#define IPIXR_LOOPBACK_ERROR     BIT(12)
#define IPIXR_COMMAND_ERROR      BIT(13)

struct xlnx_quadspi_config {
	mm_reg_t base;
	void (*irq_config_func)(const struct device *dev);
	uint8_t num_ss_bits;
	uint8_t num_xfer_bytes;
};

struct xlnx_quadspi_data {
	struct spi_context ctx;
};

static inline uint32_t xlnx_quadspi_read32(const struct device *dev,
					   mm_reg_t offset)
{
	const struct xlnx_quadspi_config *config = dev->config;

	return sys_read32(config->base + offset);
}

static inline void xlnx_quadspi_write32(const struct device *dev,
					uint32_t value,
					mm_reg_t offset)
{
	const struct xlnx_quadspi_config *config = dev->config;

	sys_write32(value, config->base + offset);
}

static void xlnx_quadspi_cs_control(const struct device *dev, bool on)
{
	const struct xlnx_quadspi_config *config = dev->config;
	struct xlnx_quadspi_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;
	uint32_t spissr = BIT_MASK(config->num_ss_bits);

	if (IS_ENABLED(CONFIG_SPI_SLAVE) && spi_context_is_slave(ctx)) {
		/* Skip slave select assert/de-assert in slave mode */
		return;
	}

	if (on) {
		/* SPISSR is one-hot, active-low */
		spissr &= ~BIT(ctx->config->slave);
	} else if (ctx->config->operation & SPI_HOLD_ON_CS) {
		/* Skip slave select de-assert */
		return;
	}

	xlnx_quadspi_write32(dev, spissr, SPISSR_OFFSET);
	spi_context_cs_control(ctx, on);
}

static int xlnx_quadspi_configure(const struct device *dev,
				  const struct spi_config *spi_cfg)
{
	const struct xlnx_quadspi_config *config = dev->config;
	struct xlnx_quadspi_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;
	uint32_t word_size;
	uint32_t spicr;
	uint32_t spisr;

	if (spi_context_configured(ctx, spi_cfg)) {
		/* Configuration already active, just enable SPI IOs */
		spicr = xlnx_quadspi_read32(dev, SPICR_OFFSET);
		spicr |= SPICR_SPE;
		xlnx_quadspi_write32(dev, spicr, SPICR_OFFSET);
		return 0;
	}

	if (spi_cfg->operation & SPI_HALF_DUPLEX) {
		LOG_ERR("Half-duplex not supported");
		return -ENOTSUP;
	}

	if (spi_cfg->slave >= config->num_ss_bits) {
		LOG_ERR("unsupported slave %d, num_ss_bits %d",
			spi_cfg->slave, config->num_ss_bits);
		return -ENOTSUP;
	}

	if (spi_cfg->operation & SPI_CS_ACTIVE_HIGH) {
		LOG_ERR("unsupported CS polarity active high");
		return -ENOTSUP;
	}

	if (!IS_ENABLED(CONFIG_SPI_SLAVE) && \
	    (spi_cfg->operation & SPI_OP_MODE_SLAVE)) {
		LOG_ERR("slave mode support not enabled");
		return -ENOTSUP;
	}

	word_size = SPI_WORD_SIZE_GET(spi_cfg->operation);
	if (word_size != (config->num_xfer_bytes * 8)) {
		LOG_ERR("unsupported word size %d bits, num_xfer_bytes %d",
			word_size, config->num_xfer_bytes);
		return -ENOTSUP;
	}

	/* Reset FIFOs, SPI IOs enabled */
	spicr = SPICR_TX_FIFO_RESET | SPICR_RX_FIFO_RESET | SPICR_SPE;

	/* Master mode, inhibit master transmit, manual slave select */
	if (!IS_ENABLED(CONFIG_SPI_SLAVE) ||
	    (spi_cfg->operation & SPI_OP_MODE_SLAVE) == 0U) {
		spicr |= SPICR_MASTER | SPICR_MASTER_XFER_INH | SPICR_MANUAL_SS;
	}

	if (spi_cfg->operation & SPI_MODE_CPOL) {
		spicr |= SPICR_CPOL;
	}

	if (spi_cfg->operation & SPI_MODE_CPHA) {
		spicr |= SPICR_CPHA;
	}

	if (spi_cfg->operation & SPI_MODE_LOOP) {
		spicr |= SPICR_LOOP;
	}

	if (spi_cfg->operation & SPI_TRANSFER_LSB) {
		spicr |= SPICR_LSB_FIRST;
	}

	/*
	 * Write configuration and verify it is compliant with the IP core
	 * configuration. Tri-state SPI IOs on error.
	 */
	xlnx_quadspi_write32(dev, spicr, SPICR_OFFSET);
	spisr = xlnx_quadspi_read32(dev, SPISR_OFFSET);
	if (spisr & SPISR_ERROR_MASK) {
		LOG_ERR("unsupported configuration, spisr = 0x%08x", spisr);
		xlnx_quadspi_write32(dev, SPICR_MASTER_XFER_INH, SPICR_OFFSET);
		ctx->config = NULL;
		return -ENOTSUP;
	}

	ctx->config = spi_cfg;

	return 0;
}

static void xlnx_quadspi_start_tx(const struct device *dev)
{
	const struct xlnx_quadspi_config *config = dev->config;
	struct xlnx_quadspi_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;
	size_t xfer_len;
	uint32_t spicr = 0U;
	uint32_t spisr;
	uint32_t dtr = 0U;

	if (!spi_context_tx_on(ctx) && !spi_context_rx_on(ctx)) {
		/* All done, de-assert slave select */
		xlnx_quadspi_cs_control(dev, false);

		if ((ctx->config->operation & SPI_HOLD_ON_CS) == 0U) {
			/* Tri-state SPI IOs */
			spicr = xlnx_quadspi_read32(dev, SPICR_OFFSET);
			spicr &= ~(SPICR_SPE);
			xlnx_quadspi_write32(dev, spicr, SPICR_OFFSET);
		}

		spi_context_complete(ctx, 0);
		return;
	}

	if (!IS_ENABLED(CONFIG_SPI_SLAVE) || !spi_context_is_slave(ctx)) {
		/* Inhibit master transaction while writing TX data */
		spicr = xlnx_quadspi_read32(dev, SPICR_OFFSET);
		spicr |= SPICR_MASTER_XFER_INH;
		xlnx_quadspi_write32(dev, spicr, SPICR_OFFSET);
	}

	/* We can only see as far as the current rx buffer */
	xfer_len = spi_context_longest_current_buf(ctx);

	/* Write TX data */
	while (xfer_len--) {
		if (spi_context_tx_buf_on(ctx)) {
			switch (config->num_xfer_bytes) {
			case 1:
				dtr = UNALIGNED_GET((uint8_t *)(ctx->tx_buf));
				break;
			case 2:
				dtr = UNALIGNED_GET((uint16_t *)(ctx->tx_buf));
				break;
			case 4:
				dtr = UNALIGNED_GET((uint32_t *)(ctx->tx_buf));
				break;
			default:
				__ASSERT(0, "unsupported num_xfer_bytes");
			}
		} else {
			/* No TX buffer. Use dummy TX data */
			dtr = 0U;
		}

		xlnx_quadspi_write32(dev, dtr, SPI_DTR_OFFSET);
		spi_context_update_tx(ctx, config->num_xfer_bytes, 1);

		spisr = xlnx_quadspi_read32(dev, SPISR_OFFSET);
		if (spisr & SPISR_TX_FULL) {
			break;
		}
	}

	spisr = xlnx_quadspi_read32(dev, SPISR_OFFSET);
	if (spisr & SPISR_COMMAND_ERROR) {
		/* Command not supported by memory type configured in IP core */
		LOG_ERR("unsupported command");
		xlnx_quadspi_cs_control(dev, false);

		spicr = xlnx_quadspi_read32(dev, SPICR_OFFSET);
		if ((ctx->config->operation & SPI_HOLD_ON_CS) == 0U) {
			/* Tri-state SPI IOs */
			spicr &= ~(SPICR_SPE);
		}
		xlnx_quadspi_write32(dev, spicr | SPICR_TX_FIFO_RESET,
				     SPICR_OFFSET);

		spi_context_complete(ctx, -ENOTSUP);
	}

	if (!IS_ENABLED(CONFIG_SPI_SLAVE) || !spi_context_is_slave(ctx)) {
		/* Uninhibit master transaction */
		spicr &= ~(SPICR_MASTER_XFER_INH);
		xlnx_quadspi_write32(dev, spicr, SPICR_OFFSET);
	}
}

static int xlnx_quadspi_transceive(const struct device *dev,
				   const struct spi_config *spi_cfg,
				   const struct spi_buf_set *tx_bufs,
				   const struct spi_buf_set *rx_bufs,
				   bool async, struct k_poll_signal *signal)
{
	const struct xlnx_quadspi_config *config = dev->config;
	struct xlnx_quadspi_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;
	int ret;

	spi_context_lock(ctx, async, signal, spi_cfg);

	ret = xlnx_quadspi_configure(dev, spi_cfg);
	if (ret) {
		goto out;
	}

	spi_context_buffers_setup(ctx, tx_bufs, rx_bufs,
				  config->num_xfer_bytes);

	xlnx_quadspi_cs_control(dev, true);

	xlnx_quadspi_start_tx(dev);

	ret = spi_context_wait_for_completion(ctx);
out:
	spi_context_release(ctx, ret);

	return ret;
}

static int xlnx_quadspi_transceive_blocking(const struct device *dev,
					    const struct spi_config *spi_cfg,
					    const struct spi_buf_set *tx_bufs,
					    const struct spi_buf_set *rx_bufs)
{
	return xlnx_quadspi_transceive(dev, spi_cfg, tx_bufs, rx_bufs, false,
				       NULL);
}

#ifdef CONFIG_SPI_ASYNC
static int xlnx_quadspi_transceive_async(const struct device *dev,
					 const struct spi_config *spi_cfg,
					 const struct spi_buf_set *tx_bufs,
					 const struct spi_buf_set *rx_bufs,
					 struct k_poll_signal *signal)
{
	return xlnx_quadspi_transceive(dev, spi_cfg, tx_bufs, rx_bufs, true,
				       signal);
}
#endif /* CONFIG_SPI_ASYNC */

static int xlnx_quadspi_release(const struct device *dev,
				const struct spi_config *spi_cfg)
{
	const struct xlnx_quadspi_config *config = dev->config;
	struct xlnx_quadspi_data *data = dev->data;
	uint32_t spicr;

	/* Force slave select de-assert */
	xlnx_quadspi_write32(dev, BIT_MASK(config->num_ss_bits), SPISSR_OFFSET);

	/* Tri-state SPI IOs */
	spicr = xlnx_quadspi_read32(dev, SPICR_OFFSET);
	spicr &= ~(SPICR_SPE);
	xlnx_quadspi_write32(dev, spicr, SPICR_OFFSET);

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

static void xlnx_quadspi_isr(const struct device *dev)
{
	const struct xlnx_quadspi_config *config = dev->config;
	struct xlnx_quadspi_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;
	uint32_t temp;
	uint32_t drr;

	/* Acknowledge interrupt */
	temp = xlnx_quadspi_read32(dev, IPISR_OFFSET);
	xlnx_quadspi_write32(dev, temp, IPISR_OFFSET);

	if (temp & IPIXR_DTR_EMPTY) {
		temp = xlnx_quadspi_read32(dev, SPISR_OFFSET);

		/* Read RX data */
		while (!(temp & SPISR_RX_EMPTY)) {
			drr = xlnx_quadspi_read32(dev, SPI_DRR_OFFSET);

			if (spi_context_rx_buf_on(ctx)) {
				switch (config->num_xfer_bytes) {
				case 1:
					UNALIGNED_PUT(drr,
						      (uint8_t *)ctx->rx_buf);
					break;
				case 2:
					UNALIGNED_PUT(drr,
						      (uint16_t *)ctx->rx_buf);
					break;
				case 4:
					UNALIGNED_PUT(drr,
						      (uint32_t *)ctx->rx_buf);
					break;
				default:
					__ASSERT(0,
						 "unsupported num_xfer_bytes");
				}
			}

			spi_context_update_rx(ctx, config->num_xfer_bytes, 1);

			temp = xlnx_quadspi_read32(dev, SPISR_OFFSET);
		}

		/* Start next TX */
		xlnx_quadspi_start_tx(dev);
	} else {
		LOG_WRN("unhandled interrupt, ipisr = 0x%08x", temp);
	}
}

static int xlnx_quadspi_init(const struct device *dev)
{
	int err;
	const struct xlnx_quadspi_config *config = dev->config;
	struct xlnx_quadspi_data *data = dev->data;

	/* Reset controller */
	xlnx_quadspi_write32(dev, SRR_SOFTRESET_MAGIC, SRR_OFFSET);

	config->irq_config_func(dev);

	/* Enable DTR Empty interrupt */
	xlnx_quadspi_write32(dev, IPIXR_DTR_EMPTY, IPIER_OFFSET);
	xlnx_quadspi_write32(dev, DGIER_GIE, DGIER_OFFSET);

	err = spi_context_cs_configure_all(&data->ctx);
	if (err < 0) {
		return err;
	}

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

static const struct spi_driver_api xlnx_quadspi_driver_api = {
	.transceive = xlnx_quadspi_transceive_blocking,
#ifdef CONFIG_SPI_ASYNC
	.transceive_async = xlnx_quadspi_transceive_async,
#endif /* CONFIG_SPI_ASYNC */
	.release = xlnx_quadspi_release,
};

#define XLNX_QUADSPI_INIT(n)						\
	static void xlnx_quadspi_config_func_##n(const struct device *dev);	\
									\
	static const struct xlnx_quadspi_config xlnx_quadspi_config_##n = { \
		.base = DT_INST_REG_ADDR(n),				\
		.irq_config_func = xlnx_quadspi_config_func_##n,	\
		.num_ss_bits = DT_INST_PROP(n, xlnx_num_ss_bits),	\
		.num_xfer_bytes =					\
			DT_INST_PROP(n, xlnx_num_transfer_bits) / 8,	\
	};								\
									\
	static struct xlnx_quadspi_data xlnx_quadspi_data_##n = {	\
		SPI_CONTEXT_INIT_LOCK(xlnx_quadspi_data_##n, ctx),	\
		SPI_CONTEXT_INIT_SYNC(xlnx_quadspi_data_##n, ctx),	\
		SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)	\
	};								\
									\
	DEVICE_DT_INST_DEFINE(n, &xlnx_quadspi_init,			\
			    NULL,					\
			    &xlnx_quadspi_data_##n,			\
			    &xlnx_quadspi_config_##n, POST_KERNEL,	\
			    CONFIG_SPI_INIT_PRIORITY,			\
			    &xlnx_quadspi_driver_api);			\
									\
	static void xlnx_quadspi_config_func_##n(const struct device *dev)	\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority),	\
			    xlnx_quadspi_isr,				\
			    DEVICE_DT_INST_GET(n), 0);			\
		irq_enable(DT_INST_IRQN(n));				\
	}

DT_INST_FOREACH_STATUS_OKAY(XLNX_QUADSPI_INIT)
