// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * MPC512x PSC in SPI mode driver.
 *
 * Copyright (C) 2007,2008 Freescale Semiconductor Inc.
 * Original port from 52xx driver:
 *	Hongjun Chen <hong-jun.chen@freescale.com>
 *
 * Fork of mpc52xx_psc_spi.c:
 *	Copyright (C) 2006 TOPTICA Photonics AG., Dragos Carp
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/spi/spi.h>
#include <asm/mpc52xx_psc.h>

enum {
	TYPE_MPC5121,
	TYPE_MPC5125,
};

/*
 * This macro abstracts the differences in the PSC register layout between
 * MPC5121 (which uses a struct mpc52xx_psc) and MPC5125 (using mpc5125_psc).
 */
#define psc_addr(mps, regname) ({					\
	void *__ret = NULL;						\
	switch (mps->type) {						\
	case TYPE_MPC5121: {						\
			struct mpc52xx_psc __iomem *psc = mps->psc;	\
			__ret = &psc->regname;				\
		};							\
		break;							\
	case TYPE_MPC5125: {						\
			struct mpc5125_psc __iomem *psc = mps->psc;	\
			__ret = &psc->regname;				\
		};							\
		break;							\
	}								\
	__ret; })

struct mpc512x_psc_spi {
	/* driver internal data */
	int type;
	void __iomem *psc;
	struct mpc512x_psc_fifo __iomem *fifo;
	int irq;
	u8 bits_per_word;
	u32 mclk_rate;

	struct completion txisrdone;
};

/* controller state */
struct mpc512x_psc_spi_cs {
	int bits_per_word;
	int speed_hz;
};

/* set clock freq, clock ramp, bits per work
 * if t is NULL then reset the values to the default values
 */
static int mpc512x_psc_spi_transfer_setup(struct spi_device *spi,
					  struct spi_transfer *t)
{
	struct mpc512x_psc_spi_cs *cs = spi->controller_state;

	cs->speed_hz = (t && t->speed_hz)
	    ? t->speed_hz : spi->max_speed_hz;
	cs->bits_per_word = (t && t->bits_per_word)
	    ? t->bits_per_word : spi->bits_per_word;
	cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8;
	return 0;
}

static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
{
	struct mpc512x_psc_spi_cs *cs = spi->controller_state;
	struct mpc512x_psc_spi *mps = spi_controller_get_devdata(spi->controller);
	u32 sicr;
	u32 ccr;
	int speed;
	u16 bclkdiv;

	sicr = in_be32(psc_addr(mps, sicr));

	/* Set clock phase and polarity */
	if (spi->mode & SPI_CPHA)
		sicr |= 0x00001000;
	else
		sicr &= ~0x00001000;

	if (spi->mode & SPI_CPOL)
		sicr |= 0x00002000;
	else
		sicr &= ~0x00002000;

	if (spi->mode & SPI_LSB_FIRST)
		sicr |= 0x10000000;
	else
		sicr &= ~0x10000000;
	out_be32(psc_addr(mps, sicr), sicr);

	ccr = in_be32(psc_addr(mps, ccr));
	ccr &= 0xFF000000;
	speed = cs->speed_hz;
	if (!speed)
		speed = 1000000;	/* default 1MHz */
	bclkdiv = (mps->mclk_rate / speed) - 1;

	ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
	out_be32(psc_addr(mps, ccr), ccr);
	mps->bits_per_word = cs->bits_per_word;

	if (spi_get_csgpiod(spi, 0)) {
		/* gpiolib will deal with the inversion */
		gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
	}
}

static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi)
{
	if (spi_get_csgpiod(spi, 0)) {
		/* gpiolib will deal with the inversion */
		gpiod_set_value(spi_get_csgpiod(spi, 0), 0);
	}
}

/* extract and scale size field in txsz or rxsz */
#define MPC512x_PSC_FIFO_SZ(sz) ((sz & 0x7ff) << 2);

#define EOFBYTE 1

static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi,
					 struct spi_transfer *t)
{
	struct mpc512x_psc_spi *mps = spi_controller_get_devdata(spi->controller);
	struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
	size_t tx_len = t->len;
	size_t rx_len = t->len;
	u8 *tx_buf = (u8 *)t->tx_buf;
	u8 *rx_buf = (u8 *)t->rx_buf;

	if (!tx_buf && !rx_buf && t->len)
		return -EINVAL;

	while (rx_len || tx_len) {
		size_t txcount;
		u8 data;
		size_t fifosz;
		size_t rxcount;
		int rxtries;

		/*
		 * send the TX bytes in as large a chunk as possible
		 * but neither exceed the TX nor the RX FIFOs
		 */
		fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->txsz));
		txcount = min(fifosz, tx_len);
		fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->rxsz));
		fifosz -= in_be32(&fifo->rxcnt) + 1;
		txcount = min(fifosz, txcount);
		if (txcount) {

			/* fill the TX FIFO */
			while (txcount-- > 0) {
				data = tx_buf ? *tx_buf++ : 0;
				if (tx_len == EOFBYTE && t->cs_change)
					setbits32(&fifo->txcmd,
						  MPC512x_PSC_FIFO_EOF);
				out_8(&fifo->txdata_8, data);
				tx_len--;
			}

			/* have the ISR trigger when the TX FIFO is empty */
			reinit_completion(&mps->txisrdone);
			out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
			out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY);
			wait_for_completion(&mps->txisrdone);
		}

		/*
		 * consume as much RX data as the FIFO holds, while we
		 * iterate over the transfer's TX data length
		 *
		 * only insist in draining all the remaining RX bytes
		 * when the TX bytes were exhausted (that's at the very
		 * end of this transfer, not when still iterating over
		 * the transfer's chunks)
		 */
		rxtries = 50;
		do {

			/*
			 * grab whatever was in the FIFO when we started
			 * looking, don't bother fetching what was added to
			 * the FIFO while we read from it -- we'll return
			 * here eventually and prefer sending out remaining
			 * TX data
			 */
			fifosz = in_be32(&fifo->rxcnt);
			rxcount = min(fifosz, rx_len);
			while (rxcount-- > 0) {
				data = in_8(&fifo->rxdata_8);
				if (rx_buf)
					*rx_buf++ = data;
				rx_len--;
			}

			/*
			 * come back later if there still is TX data to send,
			 * bail out of the RX drain loop if all of the TX data
			 * was sent and all of the RX data was received (i.e.
			 * when the transmission has completed)
			 */
			if (tx_len)
				break;
			if (!rx_len)
				break;

			/*
			 * TX data transmission has completed while RX data
			 * is still pending -- that's a transient situation
			 * which depends on wire speed and specific
			 * hardware implementation details (buffering) yet
			 * should resolve very quickly
			 *
			 * just yield for a moment to not hog the CPU for
			 * too long when running SPI at low speed
			 *
			 * the timeout range is rather arbitrary and tries
			 * to balance throughput against system load; the
			 * chosen values result in a minimal timeout of 50
			 * times 10us and thus work at speeds as low as
			 * some 20kbps, while the maximum timeout at the
			 * transfer's end could be 5ms _if_ nothing else
			 * ticks in the system _and_ RX data still wasn't
			 * received, which only occurs in situations that
			 * are exceptional; removing the unpredictability
			 * of the timeout either decreases throughput
			 * (longer timeouts), or puts more load on the
			 * system (fixed short timeouts) or requires the
			 * use of a timeout API instead of a counter and an
			 * unknown inner delay
			 */
			usleep_range(10, 100);

		} while (--rxtries > 0);
		if (!tx_len && rx_len && !rxtries) {
			/*
			 * not enough RX bytes even after several retries
			 * and the resulting rather long timeout?
			 */
			rxcount = in_be32(&fifo->rxcnt);
			dev_warn(&spi->dev,
				 "short xfer, missing %zd RX bytes, FIFO level %zd\n",
				 rx_len, rxcount);
		}

		/*
		 * drain and drop RX data which "should not be there" in
		 * the first place, for undisturbed transmission this turns
		 * into a NOP (except for the FIFO level fetch)
		 */
		if (!tx_len && !rx_len) {
			while (in_be32(&fifo->rxcnt))
				in_8(&fifo->rxdata_8);
		}

	}
	return 0;
}

static int mpc512x_psc_spi_msg_xfer(struct spi_controller *host,
				    struct spi_message *m)
{
	struct spi_device *spi;
	unsigned cs_change;
	int status;
	struct spi_transfer *t;

	spi = m->spi;
	cs_change = 1;
	status = 0;
	list_for_each_entry(t, &m->transfers, transfer_list) {
		status = mpc512x_psc_spi_transfer_setup(spi, t);
		if (status < 0)
			break;

		if (cs_change)
			mpc512x_psc_spi_activate_cs(spi);
		cs_change = t->cs_change;

		status = mpc512x_psc_spi_transfer_rxtx(spi, t);
		if (status)
			break;
		m->actual_length += t->len;

		spi_transfer_delay_exec(t);

		if (cs_change)
			mpc512x_psc_spi_deactivate_cs(spi);
	}

	m->status = status;
	if (m->complete)
		m->complete(m->context);

	if (status || !cs_change)
		mpc512x_psc_spi_deactivate_cs(spi);

	mpc512x_psc_spi_transfer_setup(spi, NULL);

	spi_finalize_current_message(host);
	return status;
}

static int mpc512x_psc_spi_prep_xfer_hw(struct spi_controller *host)
{
	struct mpc512x_psc_spi *mps = spi_controller_get_devdata(host);

	dev_dbg(&host->dev, "%s()\n", __func__);

	/* Zero MR2 */
	in_8(psc_addr(mps, mr2));
	out_8(psc_addr(mps, mr2), 0x0);

	/* enable transmitter/receiver */
	out_8(psc_addr(mps, command), MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);

	return 0;
}

static int mpc512x_psc_spi_unprep_xfer_hw(struct spi_controller *host)
{
	struct mpc512x_psc_spi *mps = spi_controller_get_devdata(host);
	struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;

	dev_dbg(&host->dev, "%s()\n", __func__);

	/* disable transmitter/receiver and fifo interrupt */
	out_8(psc_addr(mps, command), MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
	out_be32(&fifo->tximr, 0);

	return 0;
}

static int mpc512x_psc_spi_setup(struct spi_device *spi)
{
	struct mpc512x_psc_spi_cs *cs = spi->controller_state;

	if (spi->bits_per_word % 8)
		return -EINVAL;

	if (!cs) {
		cs = kzalloc(sizeof(*cs), GFP_KERNEL);
		if (!cs)
			return -ENOMEM;

		spi->controller_state = cs;
	}

	cs->bits_per_word = spi->bits_per_word;
	cs->speed_hz = spi->max_speed_hz;

	return 0;
}

static void mpc512x_psc_spi_cleanup(struct spi_device *spi)
{
	kfree(spi->controller_state);
}

static int mpc512x_psc_spi_port_config(struct spi_controller *host,
				       struct mpc512x_psc_spi *mps)
{
	struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
	u32 sicr;
	u32 ccr;
	int speed;
	u16 bclkdiv;

	/* Reset the PSC into a known state */
	out_8(psc_addr(mps, command), MPC52xx_PSC_RST_RX);
	out_8(psc_addr(mps, command), MPC52xx_PSC_RST_TX);
	out_8(psc_addr(mps, command), MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);

	/* Disable psc interrupts all useful interrupts are in fifo */
	out_be16(psc_addr(mps, isr_imr.imr), 0);

	/* Disable fifo interrupts, will be enabled later */
	out_be32(&fifo->tximr, 0);
	out_be32(&fifo->rximr, 0);

	/* Setup fifo slice address and size */
	/*out_be32(&fifo->txsz, 0x0fe00004);*/
	/*out_be32(&fifo->rxsz, 0x0ff00004);*/

	sicr =	0x01000000 |	/* SIM = 0001 -- 8 bit */
		0x00800000 |	/* GenClk = 1 -- internal clk */
		0x00008000 |	/* SPI = 1 */
		0x00004000 |	/* MSTR = 1   -- SPI host */
		0x00000800;	/* UseEOF = 1 -- SS low until EOF */

	out_be32(psc_addr(mps, sicr), sicr);

	ccr = in_be32(psc_addr(mps, ccr));
	ccr &= 0xFF000000;
	speed = 1000000;	/* default 1MHz */
	bclkdiv = (mps->mclk_rate / speed) - 1;
	ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
	out_be32(psc_addr(mps, ccr), ccr);

	/* Set 2ms DTL delay */
	out_8(psc_addr(mps, ctur), 0x00);
	out_8(psc_addr(mps, ctlr), 0x82);

	/* we don't use the alarms */
	out_be32(&fifo->rxalarm, 0xfff);
	out_be32(&fifo->txalarm, 0);

	/* Enable FIFO slices for Rx/Tx */
	out_be32(&fifo->rxcmd,
		 MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA);
	out_be32(&fifo->txcmd,
		 MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA);

	mps->bits_per_word = 8;

	return 0;
}

static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id)
{
	struct mpc512x_psc_spi *mps = (struct mpc512x_psc_spi *)dev_id;
	struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;

	/* clear interrupt and wake up the rx/tx routine */
	if (in_be32(&fifo->txisr) &
	    in_be32(&fifo->tximr) & MPC512x_PSC_FIFO_EMPTY) {
		out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
		out_be32(&fifo->tximr, 0);
		complete(&mps->txisrdone);
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}

static int mpc512x_psc_spi_of_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mpc512x_psc_spi *mps;
	struct spi_controller *host;
	int ret;
	void *tempp;
	struct clk *clk;

	host = devm_spi_alloc_host(dev, sizeof(*mps));
	if (host == NULL)
		return -ENOMEM;

	dev_set_drvdata(dev, host);
	mps = spi_controller_get_devdata(host);
	mps->type = (int)device_get_match_data(dev);

	host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
	host->setup = mpc512x_psc_spi_setup;
	host->prepare_transfer_hardware = mpc512x_psc_spi_prep_xfer_hw;
	host->transfer_one_message = mpc512x_psc_spi_msg_xfer;
	host->unprepare_transfer_hardware = mpc512x_psc_spi_unprep_xfer_hw;
	host->use_gpio_descriptors = true;
	host->cleanup = mpc512x_psc_spi_cleanup;

	device_set_node(&host->dev, dev_fwnode(dev));

	tempp = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
	if (IS_ERR(tempp))
		return dev_err_probe(dev, PTR_ERR(tempp), "could not ioremap I/O port range\n");
	mps->psc = tempp;
	mps->fifo =
		(struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc));

	mps->irq = platform_get_irq(pdev, 0);
	if (mps->irq < 0)
		return mps->irq;

	ret = devm_request_irq(dev, mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
				"mpc512x-psc-spi", mps);
	if (ret)
		return ret;
	init_completion(&mps->txisrdone);

	clk = devm_clk_get_enabled(dev, "mclk");
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	mps->mclk_rate = clk_get_rate(clk);

	clk = devm_clk_get_enabled(dev, "ipg");
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	ret = mpc512x_psc_spi_port_config(host, mps);
	if (ret < 0)
		return ret;

	return devm_spi_register_controller(dev, host);
}

static const struct of_device_id mpc512x_psc_spi_of_match[] = {
	{ .compatible = "fsl,mpc5121-psc-spi", .data = (void *)TYPE_MPC5121 },
	{ .compatible = "fsl,mpc5125-psc-spi", .data = (void *)TYPE_MPC5125 },
	{},
};

MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match);

static struct platform_driver mpc512x_psc_spi_of_driver = {
	.probe = mpc512x_psc_spi_of_probe,
	.driver = {
		.name = "mpc512x-psc-spi",
		.of_match_table = mpc512x_psc_spi_of_match,
	},
};
module_platform_driver(mpc512x_psc_spi_of_driver);

MODULE_AUTHOR("John Rigby");
MODULE_DESCRIPTION("MPC512x PSC SPI Driver");
MODULE_LICENSE("GPL");
