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

#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_SPI_XEC_QMSPI_0_LINES > 1
	case SPI_LINES_DUAL:
		qlines = MCHP_QMSPI_C_IFM_2X;
		break;
#endif
#if DT_SPI_XEC_QMSPI_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->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_SPI_XEC_QMSPI_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->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->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->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_SPI_XEC_QMSPI_0_DCSCKON,		\
				DT_SPI_XEC_QMSPI_0_DCKCSOFF,		\
				DT_SPI_XEC_QMSPI_0_DLDH,		\
				DT_SPI_XEC_QMSPI_0_DCSDA)

#ifdef DT_SPI_XEC_QMSPI_0_BASE_ADDRESS

static const struct spi_qmspi_config spi_qmspi_0_config = {
	.regs = (QMSPI_Type *)DT_SPI_XEC_QMSPI_0_BASE_ADDRESS,
	.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_SPI_XEC_QMSPI_0_IRQ_PRI,
	.chip_sel = DT_SPI_XEC_QMSPI_0_CHIP_SELECT,
	.width = DT_SPI_XEC_QMSPI_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_SPI_XEC_QMSPI_0_LABEL,
		    &qmspi_init, &spi_qmspi_0_dev_data,
		    &spi_qmspi_0_config, POST_KERNEL,
		    CONFIG_SPI_INIT_PRIORITY, &spi_qmspi_driver_api);

#endif /* DT_SPI_XEC_QMSPI_0_BASE_ADDRESS */
