/*
 * Copyright (c) 2019 Microchip Technology Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_xec_qmspi

#include <logging/log.h>
LOG_MODULE_REGISTER(spi_xec, CONFIG_SPI_LOG_LEVEL);

#include "spi_context.h"
#include <errno.h>
#include <device.h>
#include <drivers/spi.h>
#include <soc.h>

/* Device constant configuration parameters */
struct spi_qmspi_config {
	QMSPI_Type *regs;
	u32_t cs_timing;
	u8_t girq;
	u8_t girq_pos;
	u8_t girq_nvic_aggr;
	u8_t girq_nvic_direct;
	u8_t irq_pri;
	u8_t chip_sel;
	u8_t width;	/* 1(single), 2(dual), 4(quad) */
};

/* Device run time data */
struct spi_qmspi_data {
	struct spi_context ctx;
};

static inline u32_t descr_rd(QMSPI_Type *regs, u32_t did)
{
	uintptr_t raddr = (uintptr_t)regs + MCHP_QMSPI_DESC0_OFS +
			  ((did & MCHP_QMSPI_C_NEXT_DESCR_MASK0) << 2);

	return REG32(raddr);
}

static inline void descr_wr(QMSPI_Type *regs, u32_t did, u32_t val)
{
	uintptr_t raddr = (uintptr_t)regs + MCHP_QMSPI_DESC0_OFS +
			  ((did & MCHP_QMSPI_C_NEXT_DESCR_MASK0) << 2);

	REG32(raddr) = val;
}

static inline void txb_wr8(QMSPI_Type *regs, u8_t data8)
{
	REG8(&regs->TX_FIFO) = data8;
}

static inline u8_t rxb_rd8(QMSPI_Type *regs)
{
	return REG8(&regs->RX_FIFO);
}

/*
 * Program QMSPI frequency.
 * MEC1501 base frequency is 48MHz. QMSPI frequency divider field in the
 * mode register is defined as: 0=maximum divider of 256. Values 1 through
 * 255 divide 48MHz by that value.
 */
static void qmspi_set_frequency(QMSPI_Type *regs, u32_t freq_hz)
{
	u32_t div, qmode;

	if (freq_hz == 0) {
		div = 0; /* max divider = 256 */
	} else {
		div = MCHP_QMSPI_INPUT_CLOCK_FREQ_HZ / freq_hz;
		if (div == 0) {
			div = 1; /* max freq. divider = 1 */
		} else if (div > 0xffu) {
			div = 0u; /* max divider = 256 */
		}
	}

	qmode = regs->MODE & ~(MCHP_QMSPI_M_FDIV_MASK);
	qmode |= (div << MCHP_QMSPI_M_FDIV_POS) & MCHP_QMSPI_M_FDIV_MASK;
	regs->MODE = qmode;
}

/*
 * SPI signalling mode: CPOL and CPHA
 * CPOL = 0 is clock idles low, 1 is clock idle high
 * CPHA = 0 Transmitter changes data on trailing of preceding clock cycle.
 *          Receiver samples data on leading edge of clock cyle.
 *        1 Transmitter changes data on leading edge of current clock cycle.
 *          Receiver samples data on the trailing edge of clock cycle.
 * SPI Mode nomenclature:
 * Mode CPOL CPHA
 *  0     0    0
 *  1     0    1
 *  2     1    0
 *  3     1    1
 * MEC1501 has three controls, CPOL, CPHA for output and CPHA for input.
 * SPI frequency < 48MHz
 *	Mode 0: CPOL=0 CHPA=0 (CHPA_MISO=0 and CHPA_MOSI=0)
 *	Mode 3: CPOL=1 CHPA=1 (CHPA_MISO=1 and CHPA_MOSI=1)
 * Data sheet recommends when QMSPI set at max. SPI frequency (48MHz).
 * SPI frequency == 48MHz sample and change data on same edge.
 *  Mode 0: CPOL=0 CHPA=0 (CHPA_MISO=1 and CHPA_MOSI=0)
 *  Mode 3: CPOL=1 CHPA=1 (CHPA_MISO=0 and CHPA_MOSI=1)
 */

const u8_t smode_tbl[4] = {
	0x00u, 0x06u, 0x01u, 0x07u
};

const u8_t smode48_tbl[4] = {
	0x04u, 0x02u, 0x05u, 0x03u
};

static void qmspi_set_signalling_mode(QMSPI_Type *regs, u32_t smode)
{
	const u8_t *ptbl;
	u32_t m;

	ptbl = smode_tbl;
	if (((regs->MODE >> MCHP_QMSPI_M_FDIV_POS) &
	    MCHP_QMSPI_M_FDIV_MASK0) == 1) {
		ptbl = smode48_tbl;
	}

	m = (u32_t)ptbl[smode & 0x03];
	regs->MODE = (regs->MODE & ~(MCHP_QMSPI_M_SIG_MASK))
		     | (m << MCHP_QMSPI_M_SIG_POS);
}

/*
 * QMSPI HW support single, dual, and quad.
 * Return QMSPI Control/Descriptor register encoded value.
 */
static u32_t qmspi_config_get_lines(const struct spi_config *config)
{
	u32_t qlines;

	switch (config->operation & SPI_LINES_MASK) {
	case SPI_LINES_SINGLE:
		qlines = MCHP_QMSPI_C_IFM_1X;
		break;
#if DT_INST_PROP(0, lines) > 1
	case SPI_LINES_DUAL:
		qlines = MCHP_QMSPI_C_IFM_2X;
		break;
#endif
#if DT_INST_PROP(0, lines) > 2
	case SPI_LINES_QUAD:
		qlines = MCHP_QMSPI_C_IFM_4X;
		break;
#endif
	default:
		qlines = 0xffu;
	}

	return qlines;
}

/*
 * Configure QMSPI.
 * NOTE: QMSPI can control two chip selects. At this time we use CS0# only.
 */
static int qmspi_configure(struct device *dev,
			   const struct spi_config *config)
{
	const struct spi_qmspi_config *cfg = dev->config_info;
	struct spi_qmspi_data *data = dev->driver_data;
	QMSPI_Type *regs = cfg->regs;
	u32_t smode;

	if (spi_context_configured(&data->ctx, config)) {
		return 0;
	}

	if (config->operation & (SPI_TRANSFER_LSB | SPI_OP_MODE_SLAVE
				 | SPI_MODE_LOOP)) {
		return -ENOTSUP;
	}

	smode = qmspi_config_get_lines(config);
	if (smode == 0xff) {
		return -ENOTSUP;
	}

	regs->CTRL = smode;

	/* Use the requested or next highest possible frequency */
	qmspi_set_frequency(regs, config->frequency);

	smode = 0;
	if ((config->operation & SPI_MODE_CPHA) != 0U) {
		smode |= (1ul << 0);
	}

	if ((config->operation & SPI_MODE_CPOL) != 0U) {
		smode |= (1ul << 1);
	}

	qmspi_set_signalling_mode(regs, smode);

	if (SPI_WORD_SIZE_GET(config->operation) != 8) {
		return -ENOTSUP;
	}

	/* chip select */
	smode = regs->MODE & ~(MCHP_QMSPI_M_CS_MASK);
#if DT_INST_PROP(0, chip_select) == 0
	smode |= MCHP_QMSPI_M_CS0;
#else
	smode |= MCHP_QMSPI_M_CS1;
#endif
	regs->MODE = smode;

	/* chip select timing */
	regs->CSTM = cfg->cs_timing;

	data->ctx.config = config;

	/* Add driver specific data to SPI context structure */
	spi_context_cs_configure(&data->ctx);

	regs->MODE |= MCHP_QMSPI_M_ACTIVATE;

	return 0;
}

/*
 * Transmit dummy clocks - QMSPI will generate requested number of
 * SPI clocks with I/O pins tri-stated.
 * Single mode: 1 bit per clock -> IFM field = 00b. Max 0x7fff clocks
 * Dual mode: 2 bits per clock  -> IFM field = 01b. Max 0x3fff clocks
 * Quad mode: 4 bits per clock  -> IFM fiels = 1xb. Max 0x1fff clocks
 * QMSPI unit size set to bits.
 */
static int qmspi_tx_dummy_clocks(QMSPI_Type *regs, u32_t nclocks)
{
	u32_t descr, ifm, qstatus;

	ifm = regs->CTRL & MCHP_QMSPI_C_IFM_MASK;
	descr = ifm | MCHP_QMSPI_C_TX_DIS | MCHP_QMSPI_C_XFR_UNITS_BITS
		| MCHP_QMSPI_C_DESCR_LAST | MCHP_QMSPI_C_DESCR0;

	if (ifm & 0x01) {
		nclocks <<= 1;
	} else if (ifm & 0x02) {
		nclocks <<= 2;
	}
	descr |= (nclocks << MCHP_QMSPI_C_XFR_NUNITS_POS);

	descr_wr(regs, 0, descr);

	regs->CTRL |= MCHP_QMSPI_C_DESCR_EN;
	regs->IEN = 0;
	regs->STS = 0xfffffffful;

	regs->EXE = MCHP_QMSPI_EXE_START;
	do {
		qstatus = regs->STS;
		if (qstatus & MCHP_QMSPI_STS_PROG_ERR) {
			return -EIO;
		}
	} while ((qstatus & MCHP_QMSPI_STS_DONE) == 0);

	return 0;
}

/*
 * Return unit size power of 2 given number of bytes to transfer.
 */
static u32_t qlen_shift(u32_t len)
{
	u32_t ushift;

	/* is len a multiple of 4 or 16? */
	if ((len & 0x0F) == 0) {
		ushift = 4;
	} else if ((len & 0x03) == 0) {
		ushift = 2;
	} else {
		ushift = 0;
	}

	return ushift;
}

/*
 * Return QMSPI unit size of the number of units field in QMSPI
 * control/descriptor register.
 * Input: power of 2 unit size 4, 2, or 0(default) corresponding
 * to 16, 4, or 1 byte units.
 */
static u32_t get_qunits(u32_t qshift)
{
	if (qshift == 4) {
		return MCHP_QMSPI_C_XFR_UNITS_16;
	} else if (qshift == 2) {
		return MCHP_QMSPI_C_XFR_UNITS_4;
	} else {
		return MCHP_QMSPI_C_XFR_UNITS_1;
	}
}

/*
 * Allocate(build) one or more descriptors.
 * QMSPI contains 16 32-bit descriptor registers used as a linked
 * list of operations. Using only 32-bits there are limitations.
 * Each descriptor is limited to 0x7FFF units where unit size can
 * be 1, 4, or 16 bytes. A descriptor can perform transmit or receive
 * but not both simultaneously. Order of descriptor processing is specified
 * by the first descriptor field of the control register, the next descriptor
 * fields in each descriptor, and the descriptors last flag.
 */
static int qmspi_descr_alloc(QMSPI_Type *regs, const struct spi_buf *txb,
			     int didx, bool is_tx)
{
	u32_t descr, qshift, n, nu;
	int dn;

	if (didx >= MCHP_QMSPI_MAX_DESCR) {
		return -EAGAIN;
	}

	if (txb->len == 0) {
		return didx; /* nothing to do */
	}

	/* b[1:0] IFM and b[3:2] transmit mode */
	descr = (regs->CTRL & MCHP_QMSPI_C_IFM_MASK);
	if (is_tx) {
		descr |= MCHP_QMSPI_C_TX_DATA;
	} else {
		descr |= MCHP_QMSPI_C_RX_EN;
	}

	/* b[11:10] unit size 1, 4, or 16 bytes */
	qshift = qlen_shift(txb->len);
	nu = txb->len >> qshift;
	descr |= get_qunits(qshift);

	do {
		descr &= 0x0FFFul;

		dn = didx + 1;
		/* b[15:12] next descriptor pointer */
		descr |= ((dn & MCHP_QMSPI_C_NEXT_DESCR_MASK0) <<
			  MCHP_QMSPI_C_NEXT_DESCR_POS);

		n = nu;
		if (n > MCHP_QMSPI_C_MAX_UNITS) {
			n = MCHP_QMSPI_C_MAX_UNITS;
		}

		descr |= (n << MCHP_QMSPI_C_XFR_NUNITS_POS);
		descr_wr(regs, didx, descr);

		if (dn < MCHP_QMSPI_MAX_DESCR) {
			didx++;
		} else {
			return -EAGAIN;
		}

		nu -= n;
	} while (nu);

	return dn;
}

static int qmspi_tx(QMSPI_Type *regs, const struct spi_buf *tx_buf,
		    bool close)
{
	const u8_t *p = tx_buf->buf;
	size_t tlen = tx_buf->len;
	u32_t descr;
	int didx;

	if (tlen == 0) {
		return 0;
	}

	/* Buffer pointer is NULL and number of bytes != 0 ? */
	if (p == NULL) {
		return qmspi_tx_dummy_clocks(regs, tlen);
	}

	didx = qmspi_descr_alloc(regs, tx_buf, 0, true);
	if (didx < 0) {
		return didx;
	}

	/* didx points to last allocated descriptor + 1 */
	__ASSERT(didx > 0, "QMSPI descriptor index=%d expected > 0\n", didx);
	didx--;

	descr = descr_rd(regs, didx) | MCHP_QMSPI_C_DESCR_LAST;
	if (close) {
		descr |= MCHP_QMSPI_C_CLOSE;
	}
	descr_wr(regs, didx, descr);

	regs->CTRL = (regs->CTRL & MCHP_QMSPI_C_IFM_MASK) |
		     MCHP_QMSPI_C_DESCR_EN | MCHP_QMSPI_C_DESCR0;
	regs->IEN = 0;
	regs->STS = 0xfffffffful;

	/* preload TX_FIFO */
	while (tlen) {
		tlen--;
		txb_wr8(regs, *p);
		p++;

		if (regs->STS & MCHP_QMSPI_STS_TXBF_RO) {
			break;
		}
	}

	regs->EXE = MCHP_QMSPI_EXE_START;

	if (regs->STS & MCHP_QMSPI_STS_PROG_ERR) {
		return -EIO;
	}

	while (tlen) {

		while (regs->STS & MCHP_QMSPI_STS_TXBF_RO) {
		}

		txb_wr8(regs, *p);
		p++;
		tlen--;
	}

	/* Wait for TX FIFO to drain and last byte to be clocked out */
	for (;;) {
		if (regs->STS & MCHP_QMSPI_STS_DONE) {
			break;
		}
	}

	return 0;
}

static int qmspi_rx(QMSPI_Type *regs, const struct spi_buf *rx_buf,
		    bool close)
{
	u8_t *p = rx_buf->buf;
	size_t rlen = rx_buf->len;
	u32_t descr;
	int didx;
	u8_t data_byte;

	if (rlen == 0) {
		return 0;
	}

	didx = qmspi_descr_alloc(regs, rx_buf, 0, false);
	if (didx < 0) {
		return didx;
	}

	/* didx points to last allocated descriptor + 1 */
	__ASSERT_NO_MSG(didx > 0);
	didx--;

	descr = descr_rd(regs, didx) | MCHP_QMSPI_C_DESCR_LAST;
	if (close) {
		descr |= MCHP_QMSPI_C_CLOSE;
	}
	descr_wr(regs, didx, descr);

	regs->CTRL = (regs->CTRL & MCHP_QMSPI_C_IFM_MASK)
		     | MCHP_QMSPI_C_DESCR_EN | MCHP_QMSPI_C_DESCR0;
	regs->IEN = 0;
	regs->STS = 0xfffffffful;

	/*
	 * Trigger read based on the descriptor(s) programmed above.
	 * QMSPI will generate clocks until the RX FIFO is filled.
	 * More clocks will be generated as we pull bytes from the RX FIFO.
	 * QMSPI Programming error will be triggered after start if
	 * descriptors were programmed options that cannot be enabled
	 * simultaneously.
	 */
	regs->EXE = MCHP_QMSPI_EXE_START;
	if (regs->STS & MCHP_QMSPI_STS_PROG_ERR) {
		return -EIO;
	}

	while (rlen) {
		if (!(regs->STS & MCHP_QMSPI_STS_RXBE_RO)) {
			data_byte = rxb_rd8(regs);
			if (p != NULL) {
				*p++ = data_byte;
			}
			rlen--;
		}
	}

	return 0;
}

static int qmspi_transceive(struct device *dev,
			    const struct spi_config *config,
			    const struct spi_buf_set *tx_bufs,
			    const struct spi_buf_set *rx_bufs)
{
	const struct spi_qmspi_config *cfg = dev->config_info;
	struct spi_qmspi_data *data = dev->driver_data;
	QMSPI_Type *regs = cfg->regs;
	const struct spi_buf *ptx;
	const struct spi_buf *prx;
	size_t nb;
	u32_t descr, last_didx;
	int err;

	spi_context_lock(&data->ctx, false, NULL);

	err = qmspi_configure(dev, config);
	if (err != 0) {
		goto done;
	}

	spi_context_cs_control(&data->ctx, true);

	if (tx_bufs != NULL) {
		ptx = tx_bufs->buffers;
		nb = tx_bufs->count;
		while (nb--) {
			err = qmspi_tx(regs, ptx, false);
			if (err != 0) {
				goto done;
			}
			ptx++;
		}
	}

	if (rx_bufs != NULL) {
		prx = rx_bufs->buffers;
		nb = rx_bufs->count;
		while (nb--) {
			err = qmspi_rx(regs, prx, false);
			if (err != 0) {
				goto done;
			}
			prx++;
		}
	}

	/*
	 * If caller doesn't need CS# held asserted then find the last
	 * descriptor, set its close flag, and set stop.
	 */
	if (!(config->operation & SPI_HOLD_ON_CS)) {
		/* Get last descriptor from status register */
		last_didx = (regs->STS >> MCHP_QMSPI_C_NEXT_DESCR_POS)
			    & MCHP_QMSPI_C_NEXT_DESCR_MASK0;
		descr = descr_rd(regs, last_didx) | MCHP_QMSPI_C_CLOSE;
		descr_wr(regs, last_didx, descr);
		regs->EXE = MCHP_QMSPI_EXE_STOP;
	}

	spi_context_cs_control(&data->ctx, false);

done:
	spi_context_release(&data->ctx, err);
	return err;
}

static int qmspi_transceive_sync(struct device *dev,
				 const struct spi_config *config,
				 const struct spi_buf_set *tx_bufs,
				 const struct spi_buf_set *rx_bufs)
{
	return qmspi_transceive(dev, config, tx_bufs, rx_bufs);
}

#ifdef CONFIG_SPI_ASYNC
static int qmspi_transceive_async(struct device *dev,
				  const struct spi_config *config,
				  const struct spi_buf_set *tx_bufs,
				  const struct spi_buf_set *rx_bufs,
				  struct k_poll_signal *async)
{
	return -ENOTSUP;
}
#endif

static int qmspi_release(struct device *dev,
			 const struct spi_config *config)
{
	struct spi_qmspi_data *data = dev->driver_data;
	const struct spi_qmspi_config *cfg = dev->config_info;
	QMSPI_Type *regs = cfg->regs;

	/* Force CS# to de-assert on next unit boundary */
	regs->EXE = MCHP_QMSPI_EXE_STOP;

	while (regs->STS & MCHP_QMSPI_STS_ACTIVE_RO) {
	}

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

/*
 * Initialize QMSPI controller.
 * Disable sleep control.
 * Disable and clear interrupt status.
 * Initialize SPI context.
 * QMSPI will be configured and enabled when the transceive API is called.
 */
static int qmspi_init(struct device *dev)
{
	const struct spi_qmspi_config *cfg = dev->config_info;
	struct spi_qmspi_data *data = dev->driver_data;
	QMSPI_Type *regs = cfg->regs;

	mchp_pcr_periph_slp_ctrl(PCR_QMSPI, MCHP_PCR_SLEEP_DIS);

	regs->MODE = MCHP_QMSPI_M_SRST;

	MCHP_GIRQ_CLR_EN(cfg->girq, cfg->girq_pos);
	MCHP_GIRQ_SRC_CLR(cfg->girq, cfg->girq_pos);

	MCHP_GIRQ_BLK_CLREN(cfg->girq);
	NVIC_ClearPendingIRQ(cfg->girq_nvic_direct);

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

static const struct spi_driver_api spi_qmspi_driver_api = {
	.transceive = qmspi_transceive_sync,
#ifdef CONFIG_SPI_ASYNC
	.transceive_async = qmspi_transceive_async,
#endif
	.release = qmspi_release,
};


#define XEC_QMSPI_CS_TIMING_VAL(a, b, c, d) (((a) & 0xFu) \
					     | (((b) & 0xFu) << 8) \
					     | (((c) & 0xFu) << 16) \
					     | (((d) & 0xFu) << 24))


#define XEC_QMSPI_0_CS_TIMING XEC_QMSPI_CS_TIMING_VAL(			\
				DT_INST_PROP(0, dcsckon),		\
				DT_INST_PROP(0, dckcsoff),		\
				DT_INST_PROP(0, dldh),			\
				DT_INST_PROP(0, dcsda))

#if DT_HAS_NODE_STATUS_OKAY(DT_INST(0, microchip_xec_qmspi))

static const struct spi_qmspi_config spi_qmspi_0_config = {
	.regs = (QMSPI_Type *)DT_INST_REG_ADDR(0),
	.cs_timing = XEC_QMSPI_0_CS_TIMING,
	.girq = MCHP_QMSPI_GIRQ_NUM,
	.girq_pos = MCHP_QMSPI_GIRQ_POS,
	.girq_nvic_direct = MCHP_QMSPI_GIRQ_NVIC_DIRECT,
	.irq_pri = DT_INST_IRQ(0, priority),
	.chip_sel = DT_INST_PROP(0, chip_select),
	.width = DT_INST_PROP(0, lines)
};

static struct spi_qmspi_data spi_qmspi_0_dev_data = {
	SPI_CONTEXT_INIT_LOCK(spi_qmspi_0_dev_data, ctx),
	SPI_CONTEXT_INIT_SYNC(spi_qmspi_0_dev_data, ctx)
};

DEVICE_AND_API_INIT(spi_xec_qmspi_0,
		    DT_INST_LABEL(0),
		    &qmspi_init, &spi_qmspi_0_dev_data,
		    &spi_qmspi_0_config, POST_KERNEL,
		    CONFIG_SPI_INIT_PRIORITY, &spi_qmspi_driver_api);

#endif /* DT_HAS_NODE_STATUS_OKAY(DT_INST(0, microchip_xec_qmspi)) */
