/*
 * NVIDIA Tegra SPI controller (T114 and later)
 *
 * Copyright (c) 2010-2013 NVIDIA Corporation
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <malloc.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/gpio.h>
#include <asm/arch/clock.h>
#include <asm/arch/clk_rst.h>
#include <asm/arch-tegra/tegra1x4_spi.h>
#include <spi.h>
#include <fdtdec.h>
#include <asm/arch/pinmux.h>

DECLARE_GLOBAL_DATA_PTR;

/* COMMAND1 */
#define SPI_CMD1_GO			(1 << 31)
#define SPI_CMD1_M_S			(1 << 30)
#define SPI_CMD1_MODE_MASK		0x3
#define SPI_CMD1_MODE_SHIFT		28
#define SPI_CMD1_CS_SEL_MASK		0x3
#define SPI_CMD1_CS_SEL_SHIFT		26
#define SPI_CMD1_CS_POL_INACTIVE3	(1 << 25)
#define SPI_CMD1_CS_POL_INACTIVE2	(1 << 24)
#define SPI_CMD1_CS_POL_INACTIVE1	(1 << 23)
#define SPI_CMD1_CS_POL_INACTIVE0	(1 << 22)
#define SPI_CMD1_CS_SW_HW		(1 << 21)
#define SPI_CMD1_CS_SW_VAL		(1 << 20)
#define SPI_CMD1_IDLE_SDA_MASK		0x3
#define SPI_CMD1_IDLE_SDA_SHIFT		18
#define SPI_CMD1_BIDIR			(1 << 17)
#define SPI_CMD1_LSBI_FE		(1 << 16)
#define SPI_CMD1_LSBY_FE		(1 << 15)
#define SPI_CMD1_BOTH_EN_BIT		(1 << 14)
#define SPI_CMD1_BOTH_EN_BYTE		(1 << 13)
#define SPI_CMD1_RX_EN			(1 << 12)
#define SPI_CMD1_TX_EN			(1 << 11)
#define SPI_CMD1_PACKED			(1 << 5)
#define SPI_CMD1_BIT_LEN_MASK		0x1F
#define SPI_CMD1_BIT_LEN_SHIFT		0

/* COMMAND2 */
#define SPI_CMD2_TX_CLK_TAP_DELAY	(1 << 6)
#define SPI_CMD2_TX_CLK_TAP_DELAY_MASK	(0x3F << 6)
#define SPI_CMD2_RX_CLK_TAP_DELAY	(1 << 0)
#define SPI_CMD2_RX_CLK_TAP_DELAY_MASK	(0x3F << 0)

/* TRANSFER STATUS */
#define SPI_XFER_STS_RDY		(1 << 30)

/* FIFO STATUS */
#define SPI_FIFO_STS_CS_INACTIVE	(1 << 31)
#define SPI_FIFO_STS_FRAME_END		(1 << 30)
#define SPI_FIFO_STS_RX_FIFO_FLUSH	(1 << 15)
#define SPI_FIFO_STS_TX_FIFO_FLUSH	(1 << 14)
#define SPI_FIFO_STS_ERR		(1 << 8)
#define SPI_FIFO_STS_TX_FIFO_OVF	(1 << 7)
#define SPI_FIFO_STS_TX_FIFO_UNR	(1 << 6)
#define SPI_FIFO_STS_RX_FIFO_OVF	(1 << 5)
#define SPI_FIFO_STS_RX_FIFO_UNR	(1 << 4)
#define SPI_FIFO_STS_TX_FIFO_FULL	(1 << 3)
#define SPI_FIFO_STS_TX_FIFO_EMPTY	(1 << 2)
#define SPI_FIFO_STS_RX_FIFO_FULL	(1 << 1)
#define SPI_FIFO_STS_RX_FIFO_EMPTY	(1 << 0)

#define SPI_TIMEOUT		1000
#define TEGRA_SPI_MAX_FREQ	52000000
#define SPI_REPLY_TIMEOUT_MS	100

struct spi_regs {
	u32 command1;	/* 000:SPI_COMMAND1 register */
	u32 command2;	/* 004:SPI_COMMAND2 register */
	u32 timing1;	/* 008:SPI_CS_TIM1 register */
	u32 timing2;	/* 00c:SPI_CS_TIM2 register */
	u32 xfer_status;/* 010:SPI_TRANS_STATUS register */
	u32 fifo_status;/* 014:SPI_FIFO_STATUS register */
	u32 tx_data;	/* 018:SPI_TX_DATA register */
	u32 rx_data;	/* 01c:SPI_RX_DATA register */
	u32 dma_ctl;	/* 020:SPI_DMA_CTL register */
	u32 dma_blk;	/* 024:SPI_DMA_BLK register */
	u32 rsvd[56];	/* 028-107 reserved */
	u32 tx_fifo;	/* 108:SPI_FIFO1 register */
	u32 rsvd2[31];	/* 10c-187 reserved */
	u32 rx_fifo;	/* 188:SPI_FIFO2 register */
	u32 spare_ctl;	/* 18c:SPI_SPARE_CTRL register */
};

struct tegra_spi_ctrl {
	struct spi_regs *regs;
	unsigned int freq;
	unsigned int mode;
	int periph_id;
	int valid;
	int node;
	uint deactivate_delay_us;	/* Delay to wait after deactivate */
	int cs_pinmux;
};

struct tegra_spi_slave {
	struct spi_slave slave;
	struct tegra_spi_ctrl *ctrl;
	ulong last_transaction_us;	/* Time of the last transaction end */
};

static struct tegra_spi_ctrl spi_ctrls[CONFIG_TEGRA114_SPI_CTRLS];

static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
{
	return container_of(slave, struct tegra_spi_slave, slave);
}

int tegra114_spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
	if (bus >= CONFIG_TEGRA114_SPI_CTRLS || cs > 3 || !spi_ctrls[bus].valid)
		return 0;
	else
		return 1;
}

struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int mode)
{
	struct tegra_spi_slave *spi;

	debug("%s: bus: %u, cs: %u, max_hz: %u, mode: %u\n", __func__,
		bus, cs, max_hz, mode);

	if (!spi_cs_is_valid(bus, cs)) {
		printf("SPI error: unsupported bus %d / chip select %d\n",
		       bus, cs);
		return NULL;
	}

	if (max_hz > TEGRA_SPI_MAX_FREQ) {
		printf("SPI error: unsupported frequency %d Hz. Max frequency"
			" is %d Hz\n", max_hz, TEGRA_SPI_MAX_FREQ);
		return NULL;
	}

	spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
	if (!spi) {
		printf("SPI error: malloc of SPI structure failed\n");
		return NULL;
	}

	spi->ctrl = &spi_ctrls[bus];
	if (!spi->ctrl) {
		printf("SPI error: could not find controller for bus %d\n",
		       bus);
		return NULL;
	}

	if (max_hz < spi->ctrl->freq) {
		debug("%s: limiting frequency from %u to %u\n", __func__,
		      spi->ctrl->freq, max_hz);
		spi->ctrl->freq = max_hz;
	}
	spi->ctrl->mode = mode;
	spi->last_transaction_us = timer_get_us();

	return &spi->slave;
}

void tegra114_spi_free_slave(struct spi_slave *slave)
{
	struct tegra_spi_slave *spi = to_tegra_spi(slave);

	free(spi);
}

int tegra114_spi_init(int *node_list, int count)
{
	struct tegra_spi_ctrl *ctrl;
	int i;
	int node = 0;
	int found = 0;

	for (i = 0; i < count; i++) {
		ctrl = &spi_ctrls[i];
		node = node_list[i];

		ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
								 node, "reg");
		if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
			debug("%s: no spi register found\n", __func__);
			continue;
		}
		ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
					    "spi-max-frequency", 0);
		if (!ctrl->freq) {
			debug("%s: no spi max frequency found\n", __func__);
			continue;
		}
		ctrl->cs_pinmux = fdtdec_get_int(gd->fdt_blob, node,
						 "nvidia,cs-pinmux", 0);
		if (!ctrl->cs_pinmux) {
			debug("%s: cs-pinmux must be specified.\n", __func__);
			continue;
		}

		ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
		if (ctrl->periph_id == PERIPH_ID_NONE) {
			debug("%s: could not decode periph id\n", __func__);
			continue;
		}
		ctrl->valid = 1;
		found = 1;

		ctrl->node = node;
		ctrl->deactivate_delay_us = fdtdec_get_int(gd->fdt_blob, node,
						"spi-deactivate-delay", 0);

		debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
		      __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
	}

	return !found;
}

int tegra114_spi_claim_bus(struct spi_slave *slave)
{
	struct tegra_spi_slave *spi = to_tegra_spi(slave);
	struct spi_regs *regs = spi->ctrl->regs;

	/*
	 * Change SPI clock to correct frequency, PLLP_OUT0 source
	 *
	 * Note that calling clock_start_periph_pll() will reset the SPI
	 * controller, and that will cause CS line to be asserted.
	 *
	 * We tristate (and pull-up) the CS line before the call, so the line
	 * won't be driven out low during reset.
	 */
	if (spi->ctrl->cs_pinmux) {
		pinmux_set_pullupdown(spi->ctrl->cs_pinmux, PMUX_PULL_UP);
		pinmux_tristate_enable(spi->ctrl->cs_pinmux);
	}
	clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
			       spi->ctrl->freq);
	if (spi->ctrl->cs_pinmux) {
		pinmux_set_pullupdown(spi->ctrl->cs_pinmux, PMUX_PULL_NORMAL);
		pinmux_tristate_disable(spi->ctrl->cs_pinmux);
	}

	/* Clear stale status here */
	setbits_le32(&regs->fifo_status,
		     SPI_FIFO_STS_ERR		|
		     SPI_FIFO_STS_TX_FIFO_OVF	|
		     SPI_FIFO_STS_TX_FIFO_UNR	|
		     SPI_FIFO_STS_RX_FIFO_OVF	|
		     SPI_FIFO_STS_RX_FIFO_UNR	|
		     SPI_FIFO_STS_TX_FIFO_FULL	|
		     SPI_FIFO_STS_TX_FIFO_EMPTY	|
		     SPI_FIFO_STS_RX_FIFO_FULL	|
		     SPI_FIFO_STS_RX_FIFO_EMPTY);
	debug("%s: FIFO STATUS = %08x\n", __func__, readl(&regs->fifo_status));

	/* Set master mode and sw controlled CS */
	setbits_le32(&regs->command1, SPI_CMD1_M_S | SPI_CMD1_CS_SW_HW |
		     (spi->ctrl->mode << SPI_CMD1_MODE_SHIFT));
	debug("%s: COMMAND1 = %08x\n", __func__, readl(&regs->command1));

	return 0;
}

void tegra114_spi_cs_activate(struct spi_slave *slave)
{
	struct tegra_spi_slave *spi = to_tegra_spi(slave);
	struct spi_regs *regs = spi->ctrl->regs;
	ulong delay_us;			/* The delay completed so far */

	/* If it's too soon to do another transaction, wait */
	if (spi->ctrl->deactivate_delay_us && spi->last_transaction_us) {
		delay_us = timer_get_us() - spi->last_transaction_us;
		if (delay_us < spi->ctrl->deactivate_delay_us) {
			debug("%s: delaying %lu uSec\n", __func__,
			      spi->ctrl->deactivate_delay_us - delay_us);
			udelay(spi->ctrl->deactivate_delay_us - delay_us);
		}
	}
	clrbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);
}

void tegra114_spi_cs_deactivate(struct spi_slave *slave)
{
	struct tegra_spi_slave *spi = to_tegra_spi(slave);
	struct spi_regs *regs = spi->ctrl->regs;

	setbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);

	/* Remember time of this transaction so we can honor the bus delay */
	if (spi->ctrl->deactivate_delay_us)
		spi->last_transaction_us = timer_get_us();

	debug("%s: deactivate_delay_us = %u, last_transaction_us = %lu\n",
	      __func__, spi->ctrl->deactivate_delay_us,
	      spi->last_transaction_us);
}

void spi_set_deactivate_delay_us(struct spi_slave *slave, int delay_us)
{
	struct tegra_spi_slave *spi = to_tegra_spi(slave);

	spi->ctrl->deactivate_delay_us = delay_us;

	debug("%s: deactivate_delay_us set to %d\n",
	      __func__, spi->ctrl->deactivate_delay_us);
}

static int spi_check_fifo_error(int fifo_status)
{
	int ret = 0;

	if (fifo_status & SPI_FIFO_STS_ERR) {
		ret = fifo_status;
		debug("%s: got a fifo error: ", __func__);
		if (fifo_status & SPI_FIFO_STS_TX_FIFO_OVF)
			debug("tx FIFO overflow ");
		if (fifo_status & SPI_FIFO_STS_TX_FIFO_UNR)
			debug("tx FIFO underrun ");
		if (fifo_status & SPI_FIFO_STS_RX_FIFO_OVF)
			debug("rx FIFO overflow ");
		if (fifo_status & SPI_FIFO_STS_RX_FIFO_UNR)
			debug("rx FIFO underrun ");
		if (fifo_status & SPI_FIFO_STS_TX_FIFO_FULL)
			debug("tx FIFO full ");
		if (fifo_status & SPI_FIFO_STS_TX_FIFO_EMPTY)
			debug("tx FIFO empty ");
		if (fifo_status & SPI_FIFO_STS_RX_FIFO_FULL)
			debug("rx FIFO full ");
		if (fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY)
			debug("rx FIFO empty ");
		debug("\n");
	} else {
		/* no error, but fifo is still empty, set as an error */
		if (fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY) {
			ret = SPI_FIFO_STS_RX_FIFO_EMPTY;
			debug("%s: rx FIFO should not be empty\n", __func__);
		}
	}

	return ret;
}

/**
 * Output number of 'bytes' of data from dout to SPI interface.
 *
 * If out_bytes is 0 or if dout is NULL, data of 0 is output to SPI interface.
 *
 * @param regs		pointer to SPI register structure
 * @param dout		data is output from this pointer
 * @param bytes		# of bytes to send, must be <= 4
 * @param out_bytes	a counter to keep track # of bytes to output from dout;
 *			will be updated by this routine if data are outputted
 *			from dout
 * @return # of bytes are output from dout.
 */
static int spi_out_data(struct spi_regs *regs, const u8 *dout, int bytes,
			int *out_bytes)
{
	int tmpdout;
	int dout_len;

	if (dout && (*out_bytes > 0)) {
		memcpy((void *)&tmpdout, (void *)dout, bytes);
		*out_bytes -= bytes;
		dout_len = bytes;
	} else {
		tmpdout = 0;
		dout_len = 0;
	}

	clrsetbits_le32(&regs->command1,
			SPI_CMD1_BIT_LEN_MASK << SPI_CMD1_BIT_LEN_SHIFT,
			(bytes * 8 - 1) << SPI_CMD1_BIT_LEN_SHIFT);
	writel(tmpdout, &regs->tx_fifo);
	setbits_le32(&regs->command1, SPI_CMD1_GO);

	return dout_len;
}

int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
		const void *data_out, void *data_in, unsigned long flags)
{
	struct tegra_spi_slave *spi = to_tegra_spi(slave);
	struct spi_regs *regs = spi->ctrl->regs;
	u32 tmpdin = 0;
	const u8 *dout = data_out;
	u8 *din = data_in;
	int num_bytes, out_bytes;
	int ret;
	int found = 1;
	u32 max_timeout_ms = 0;
	u32 start_time = 0;
	unsigned header = slave->frame_header;

	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
	      __func__, slave->bus, slave->cs, dout, din, bitlen);
	if (bitlen % 8)
		return -1;
	num_bytes = bitlen / 8;
	out_bytes = num_bytes;

	if (slave->half_duplex) {
		found = 0;
		max_timeout_ms = slave->max_timeout_ms;
		if (max_timeout_ms == 0)
			max_timeout_ms = SPI_REPLY_TIMEOUT_MS;

		start_time = get_timer(0);
	}

	ret = 0;

	/* clear all error status bits */
	writel(readl(&regs->fifo_status), &regs->fifo_status);

	/* clear ready bit */
	setbits_le32(&regs->xfer_status, SPI_XFER_STS_RDY);

	clrsetbits_le32(&regs->command1,
			SPI_CMD1_LSBI_FE | SPI_CMD1_LSBY_FE,
			SPI_CMD1_RX_EN | SPI_CMD1_TX_EN |
			(slave->cs << SPI_CMD1_CS_SEL_SHIFT));

	/* set xfer size to 1 block (32 bits) */
	writel(0, &regs->dma_blk);

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(slave);

	/* handle data in 32-bit chunks */
	while (num_bytes > 0) {
		int bytes;
		int tm;
		u8 *pheader;
		u32 fifo_status, xfer_status;

		if (!found)
			if (get_timer(start_time) > max_timeout_ms) {
				printf("%s: did not get reply in %u ms\n",
				       __func__, max_timeout_ms);
				ret = -EIO;
				break;
			}

		/* Send out data, 4 bytes a time */
		bytes = (num_bytes > 4) ?  4 : num_bytes;
		dout += spi_out_data(regs, dout, bytes, &out_bytes);

		/*
		 * Wait for SPI transmit FIFO to empty, or to time out.
		 * The RX FIFO status will be read and cleared last
		 */
		for (tm = 0; tm < SPI_TIMEOUT; ++tm) {
			xfer_status = readl(&regs->xfer_status);
			if (xfer_status & SPI_XFER_STS_RDY)
				break;
		}

		if (tm >= SPI_TIMEOUT) {
			debug("%s: timed out waiting for STS_RDY\n", __func__);
			ret = tm;
			break;	/* break out of while (num_bytes > 0) loop */
		}

		/* clear RDY status */
		writel(SPI_XFER_STS_RDY, &regs->xfer_status);

		/* check if there is any FIFO error */
		fifo_status = readl(&regs->fifo_status);
		ret = spi_check_fifo_error(fifo_status);
		if (ret)
			/* break out of while loop if there is any fifo error */
			break;

		/* no error, read RX FIFO */
		tmpdin = readl(&regs->rx_fifo);

		/* process input package */
		if (din) {
			if (found) {
				memcpy(din, &tmpdin, bytes);
				din += bytes;
			} else {
				pheader = memchr(&tmpdin, header, bytes);
				if (pheader) {
					int len;

					found = 1;
					/* determine how many bytes to copy */
					len = pheader - (u8 *)&tmpdin;
					bytes -= (len + 1);
					memcpy(din, pheader + 1, bytes);
					din += bytes;
				} else {
					bytes = 0;
				}
			}
		}

		/* clear ACK RDY, etc. bits */
		writel(readl(&regs->fifo_status), &regs->fifo_status);

		num_bytes -= bytes;
	}

	if (flags & SPI_XFER_END)
		spi_cs_deactivate(slave);

	if (ret) {
		printf("%s: error during SPI transfer, ret=%d\n",
		       __func__, ret);
		return -1;
	}

	return 0;
}

#ifdef CONFIG_OF_CONTROL
/**
 * Get the SPI bus for an fdt node
 *
 * @param blob         Device tree blob
 * @param spi_node     cached pointer to the SPI interface this node belongs to
 * @return spi bus # if ok, -1 on error
 */
int spi_get_bus_by_node(const void *blob, unsigned spi_node)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(spi_ctrls); i++)
		if (spi_ctrls[i].node == spi_node)
			return i;
	return -1;
}
#endif
