// SPDX-License-Identifier: GPL-2.0+
/*
 * KP2000 SPI controller driver
 *
 * Copyright (C) 2014-2018 Daktronics
 * Author: Matt Sickler <matt.sickler@daktronics.com>
 * Very loosely based on spi-omap2-mcspi.c
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/gcd.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/mtd/partitions.h>

#include "kpc.h"

static struct mtd_partition p2kr0_spi0_parts[] = {
	{ .name = "SLOT_0",	.size = 7798784,		.offset = 0,                },
	{ .name = "SLOT_1",	.size = 7798784,		.offset = MTDPART_OFS_NXTBLK},
	{ .name = "SLOT_2",	.size = 7798784,		.offset = MTDPART_OFS_NXTBLK},
	{ .name = "SLOT_3",	.size = 7798784,		.offset = MTDPART_OFS_NXTBLK},
	{ .name = "CS0_EXTRA",	.size = MTDPART_SIZ_FULL,	.offset = MTDPART_OFS_NXTBLK},
};

static struct mtd_partition p2kr0_spi1_parts[] = {
	{ .name = "SLOT_4",	.size = 7798784,		.offset = 0,                },
	{ .name = "SLOT_5",	.size = 7798784,		.offset = MTDPART_OFS_NXTBLK},
	{ .name = "SLOT_6",	.size = 7798784,		.offset = MTDPART_OFS_NXTBLK},
	{ .name = "SLOT_7",	.size = 7798784,		.offset = MTDPART_OFS_NXTBLK},
	{ .name = "CS1_EXTRA",	.size = MTDPART_SIZ_FULL,	.offset = MTDPART_OFS_NXTBLK},
};

static struct flash_platform_data p2kr0_spi0_pdata = {
	.name =		"SPI0",
	.nr_parts =	ARRAY_SIZE(p2kr0_spi0_parts),
	.parts =	p2kr0_spi0_parts,
};
static struct flash_platform_data p2kr0_spi1_pdata = {
	.name =		"SPI1",
	.nr_parts =	ARRAY_SIZE(p2kr0_spi1_parts),
	.parts =	p2kr0_spi1_parts,
};

static struct spi_board_info p2kr0_board_info[] = {
	{
		.modalias =		"n25q256a11",
		.bus_num =		1,
		.chip_select =		0,
		.mode =			SPI_MODE_0,
		.platform_data =	&p2kr0_spi0_pdata
	},
	{
		.modalias =		"n25q256a11",
		.bus_num =		1,
		.chip_select =		1,
		.mode =			SPI_MODE_0,
		.platform_data =	&p2kr0_spi1_pdata
	},
};

/***************
 * SPI Defines *
 ***************/
#define KP_SPI_REG_CONFIG 0x0 /* 0x00 */
#define KP_SPI_REG_STATUS 0x1 /* 0x08 */
#define KP_SPI_REG_FFCTRL 0x2 /* 0x10 */
#define KP_SPI_REG_TXDATA 0x3 /* 0x18 */
#define KP_SPI_REG_RXDATA 0x4 /* 0x20 */

#define KP_SPI_CLK           48000000
#define KP_SPI_MAX_FIFODEPTH 64
#define KP_SPI_MAX_FIFOWCNT  0xFFFF

#define KP_SPI_REG_CONFIG_TRM_TXRX 0
#define KP_SPI_REG_CONFIG_TRM_RX   1
#define KP_SPI_REG_CONFIG_TRM_TX   2

#define KP_SPI_REG_STATUS_RXS   0x01
#define KP_SPI_REG_STATUS_TXS   0x02
#define KP_SPI_REG_STATUS_EOT   0x04
#define KP_SPI_REG_STATUS_TXFFE 0x10
#define KP_SPI_REG_STATUS_TXFFF 0x20
#define KP_SPI_REG_STATUS_RXFFE 0x40
#define KP_SPI_REG_STATUS_RXFFF 0x80

/******************
 * SPI Structures *
 ******************/
struct kp_spi {
	struct spi_master  *master;
	u64 __iomem        *base;
	struct device      *dev;
};

struct kp_spi_controller_state {
	void __iomem   *base;
	s64             conf_cache;
};

union kp_spi_config {
	/* use this to access individual elements */
	struct __packed spi_config_bitfield {
		unsigned int pha       : 1; /* spim_clk Phase      */
		unsigned int pol       : 1; /* spim_clk Polarity   */
		unsigned int epol      : 1; /* spim_csx Polarity   */
		unsigned int dpe       : 1; /* Transmission Enable */
		unsigned int wl        : 5; /* Word Length         */
		unsigned int           : 3;
		unsigned int trm       : 2; /* TxRx Mode           */
		unsigned int cs        : 4; /* Chip Select         */
		unsigned int wcnt      : 7; /* Word Count          */
		unsigned int ffen      : 1; /* FIFO Enable         */
		unsigned int spi_en    : 1; /* SPI Enable          */
		unsigned int           : 5;
	} bitfield;
	/* use this to grab the whole register */
	u32 reg;
};

union kp_spi_status {
	struct __packed spi_status_bitfield {
		unsigned int rx    :  1; /* Rx Status       */
		unsigned int tx    :  1; /* Tx Status       */
		unsigned int eo    :  1; /* End of Transfer */
		unsigned int       :  1;
		unsigned int txffe :  1; /* Tx FIFO Empty   */
		unsigned int txfff :  1; /* Tx FIFO Full    */
		unsigned int rxffe :  1; /* Rx FIFO Empty   */
		unsigned int rxfff :  1; /* Rx FIFO Full    */
		unsigned int       : 24;
	} bitfield;
	u32 reg;
};

union kp_spi_ffctrl {
	struct __packed spi_ffctrl_bitfield {
		unsigned int ffstart :  1; /* FIFO Start */
		unsigned int         : 31;
	} bitfield;
	u32 reg;
};

/***************
 * SPI Helpers *
 ***************/
	static inline u64
kp_spi_read_reg(struct kp_spi_controller_state *cs, int idx)
{
	u64 __iomem *addr = cs->base;
	u64 val;

	addr += idx;
	if ((idx == KP_SPI_REG_CONFIG) && (cs->conf_cache >= 0))
		return cs->conf_cache;

	val = readq(addr);
	return val;
}

	static inline void
kp_spi_write_reg(struct kp_spi_controller_state *cs, int idx, u64 val)
{
	u64 __iomem *addr = cs->base;

	addr += idx;
	writeq(val, addr);
	if (idx == KP_SPI_REG_CONFIG)
		cs->conf_cache = val;
}

	static int
kp_spi_wait_for_reg_bit(struct kp_spi_controller_state *cs, int idx,
			unsigned long bit)
{
	unsigned long timeout;

	timeout = jiffies + msecs_to_jiffies(1000);
	while (!(kp_spi_read_reg(cs, idx) & bit)) {
		if (time_after(jiffies, timeout)) {
			if (!(kp_spi_read_reg(cs, idx) & bit))
				return -ETIMEDOUT;
			else
				return 0;
		}
		cpu_relax();
	}
	return 0;
}

	static unsigned
kp_spi_txrx_pio(struct spi_device *spidev, struct spi_transfer *transfer)
{
	struct kp_spi_controller_state *cs = spidev->controller_state;
	unsigned int count = transfer->len;
	unsigned int c = count;

	int i;
	int res;
	u8 *rx       = transfer->rx_buf;
	const u8 *tx = transfer->tx_buf;
	int processed = 0;

	if (tx) {
		for (i = 0 ; i < c ; i++) {
			char val = *tx++;

			res = kp_spi_wait_for_reg_bit(cs, KP_SPI_REG_STATUS,
						      KP_SPI_REG_STATUS_TXS);
			if (res < 0)
				goto out;

			kp_spi_write_reg(cs, KP_SPI_REG_TXDATA, val);
			processed++;
		}
	}
	else if (rx) {
		for (i = 0 ; i < c ; i++) {
			char test = 0;

			kp_spi_write_reg(cs, KP_SPI_REG_TXDATA, 0x00);
			res = kp_spi_wait_for_reg_bit(cs, KP_SPI_REG_STATUS,
						      KP_SPI_REG_STATUS_RXS);
			if (res < 0)
				goto out;

			test = kp_spi_read_reg(cs, KP_SPI_REG_RXDATA);
			*rx++ = test;
			processed++;
		}
	}

	if (kp_spi_wait_for_reg_bit(cs, KP_SPI_REG_STATUS,
				    KP_SPI_REG_STATUS_EOT) < 0) {
		//TODO: Figure out how to abort transaction??
		//Ths has never happened in practice though...
	}

out:
	return processed;
}

/*****************
 * SPI Functions *
 *****************/
	static int
kp_spi_setup(struct spi_device *spidev)
{
	union kp_spi_config sc;
	struct kp_spi *kpspi = spi_master_get_devdata(spidev->master);
	struct kp_spi_controller_state *cs;

	/* setup controller state */
	cs = spidev->controller_state;
	if (!cs) {
		cs = kzalloc(sizeof(*cs), GFP_KERNEL);
		if (!cs)
			return -ENOMEM;
		cs->base = kpspi->base;
		cs->conf_cache = -1;
		spidev->controller_state = cs;
	}

	/* set config register */
	sc.bitfield.wl = spidev->bits_per_word - 1;
	sc.bitfield.cs = spidev->chip_select;
	sc.bitfield.spi_en = 0;
	sc.bitfield.trm = 0;
	sc.bitfield.ffen = 0;
	kp_spi_write_reg(spidev->controller_state, KP_SPI_REG_CONFIG, sc.reg);
	return 0;
}

	static int
kp_spi_transfer_one_message(struct spi_master *master, struct spi_message *m)
{
	struct kp_spi_controller_state *cs;
	struct spi_device   *spidev;
	struct kp_spi       *kpspi;
	struct spi_transfer *transfer;
	union kp_spi_config sc;
	int status = 0;

	spidev = m->spi;
	kpspi = spi_master_get_devdata(master);
	m->actual_length = 0;
	m->status = 0;

	cs = spidev->controller_state;

	/* reject invalid messages and transfers */
	if (list_empty(&m->transfers))
		return -EINVAL;

	/* validate input */
	list_for_each_entry(transfer, &m->transfers, transfer_list) {
		const void *tx_buf = transfer->tx_buf;
		void       *rx_buf = transfer->rx_buf;
		unsigned int len = transfer->len;

		if (transfer->speed_hz > KP_SPI_CLK ||
		    (len && !(rx_buf || tx_buf))) {
			dev_dbg(kpspi->dev, "  transfer: %d Hz, %d %s%s, %d bpw\n",
					transfer->speed_hz,
					len,
					tx_buf ? "tx" : "",
					rx_buf ? "rx" : "",
					transfer->bits_per_word);
			dev_dbg(kpspi->dev, "  transfer -EINVAL\n");
			return -EINVAL;
		}
		if (transfer->speed_hz &&
		    transfer->speed_hz < (KP_SPI_CLK >> 15)) {
			dev_dbg(kpspi->dev, "speed_hz %d below minimum %d Hz\n",
					transfer->speed_hz,
					KP_SPI_CLK >> 15);
			dev_dbg(kpspi->dev, "  speed_hz -EINVAL\n");
			return -EINVAL;
		}
	}

	/* assert chip select to start the sequence*/
	sc.reg = kp_spi_read_reg(cs, KP_SPI_REG_CONFIG);
	sc.bitfield.spi_en = 1;
	kp_spi_write_reg(cs, KP_SPI_REG_CONFIG, sc.reg);

	/* work */
	if (kp_spi_wait_for_reg_bit(cs, KP_SPI_REG_STATUS,
				    KP_SPI_REG_STATUS_EOT) < 0) {
		dev_info(kpspi->dev, "EOT timed out\n");
		goto out;
	}

	/* do the transfers for this message */
	list_for_each_entry(transfer, &m->transfers, transfer_list) {
		if (!transfer->tx_buf && !transfer->rx_buf &&
		    transfer->len) {
			status = -EINVAL;
			goto error;
		}

		/* transfer */
		if (transfer->len) {
			unsigned int word_len = spidev->bits_per_word;
			unsigned int count;

			/* set up the transfer... */
			sc.reg = kp_spi_read_reg(cs, KP_SPI_REG_CONFIG);

			/* ...direction */
			if (transfer->tx_buf)
				sc.bitfield.trm = KP_SPI_REG_CONFIG_TRM_TX;
			else if (transfer->rx_buf)
				sc.bitfield.trm = KP_SPI_REG_CONFIG_TRM_RX;

			/* ...word length */
			if (transfer->bits_per_word)
				word_len = transfer->bits_per_word;
			sc.bitfield.wl = word_len - 1;

			/* ...chip select */
			sc.bitfield.cs = spidev->chip_select;

			/* ...and write the new settings */
			kp_spi_write_reg(cs, KP_SPI_REG_CONFIG, sc.reg);

			/* do the transfer */
			count = kp_spi_txrx_pio(spidev, transfer);
			m->actual_length += count;

			if (count != transfer->len) {
				status = -EIO;
				goto error;
			}
		}

		if (transfer->delay_usecs)
			udelay(transfer->delay_usecs);
	}

	/* de-assert chip select to end the sequence */
	sc.reg = kp_spi_read_reg(cs, KP_SPI_REG_CONFIG);
	sc.bitfield.spi_en = 0;
	kp_spi_write_reg(cs, KP_SPI_REG_CONFIG, sc.reg);

out:
	/* done work */
	spi_finalize_current_message(master);
	return 0;

error:
	m->status = status;
	return status;
}

	static void
kp_spi_cleanup(struct spi_device *spidev)
{
	struct kp_spi_controller_state *cs = spidev->controller_state;

	kfree(cs);
}

/******************
 * Probe / Remove *
 ******************/
	static int
kp_spi_probe(struct platform_device *pldev)
{
	struct kpc_core_device_platdata *drvdata;
	struct spi_master *master;
	struct kp_spi *kpspi;
	struct resource *r;
	int status = 0;
	int i;

	drvdata = pldev->dev.platform_data;
	if (!drvdata) {
		dev_err(&pldev->dev, "%s: platform_data is NULL\n", __func__);
		return -ENODEV;
	}

	master = spi_alloc_master(&pldev->dev, sizeof(struct kp_spi));
	if (!master) {
		dev_err(&pldev->dev, "%s: master allocation failed\n",
			__func__);
		return -ENOMEM;
	}

	/* set up the spi functions */
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
	master->bits_per_word_mask = (unsigned int)SPI_BPW_RANGE_MASK(4, 32);
	master->setup = kp_spi_setup;
	master->transfer_one_message = kp_spi_transfer_one_message;
	master->cleanup = kp_spi_cleanup;

	platform_set_drvdata(pldev, master);

	kpspi = spi_master_get_devdata(master);
	kpspi->master = master;
	kpspi->dev = &pldev->dev;

	master->num_chipselect = 4;
	if (pldev->id != -1)
		master->bus_num = pldev->id;

	r = platform_get_resource(pldev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pldev->dev, "%s: Unable to get platform resources\n",
			__func__);
		status = -ENODEV;
		goto free_master;
	}

	kpspi->base = devm_ioremap_nocache(&pldev->dev, r->start,
					   resource_size(r));

	status = spi_register_master(master);
	if (status < 0) {
		dev_err(&pldev->dev, "Unable to register SPI device\n");
		goto free_master;
	}

	/* register the slave boards */
#define NEW_SPI_DEVICE_FROM_BOARD_INFO_TABLE(table) \
	for (i = 0 ; i < ARRAY_SIZE(table) ; i++) { \
		spi_new_device(master, &(table[i])); \
	}

	switch ((drvdata->card_id & 0xFFFF0000) >> 16) {
	case PCI_DEVICE_ID_DAKTRONICS_KADOKA_P2KR0:
		NEW_SPI_DEVICE_FROM_BOARD_INFO_TABLE(p2kr0_board_info);
		break;
	default:
		dev_err(&pldev->dev, "Unknown hardware, cant know what partition table to use!\n");
		goto free_master;
	}

	return status;

free_master:
	spi_master_put(master);
	return status;
}

	static int
kp_spi_remove(struct platform_device *pldev)
{
	struct spi_master *master = platform_get_drvdata(pldev);

	spi_unregister_master(master);
	return 0;
}

static struct platform_driver kp_spi_driver = {
	.driver = {
		.name =     KP_DRIVER_NAME_SPI,
	},
	.probe =    kp_spi_probe,
	.remove =   kp_spi_remove,
};

module_platform_driver(kp_spi_driver);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:kp_spi");
