// 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;

	if (cs)
		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");
