// SPDX-License-Identifier: GPL-2.0
/*
 * Lattice FPGA programming over slave SPI sysCONFIG interface.
 */

#include <linux/of.h>
#include <linux/spi/spi.h>

#include "lattice-sysconfig.h"

static const u32 ecp5_spi_max_speed_hz = 60000000;

static int sysconfig_spi_cmd_transfer(struct sysconfig_priv *priv,
				      const void *tx_buf, size_t tx_len,
				      void *rx_buf, size_t rx_len)
{
	struct spi_device *spi = to_spi_device(priv->dev);

	return spi_write_then_read(spi, tx_buf, tx_len, rx_buf, rx_len);
}

static int sysconfig_spi_bitstream_burst_init(struct sysconfig_priv *priv)
{
	const u8 lsc_bitstream_burst[] = SYSCONFIG_LSC_BITSTREAM_BURST;
	struct spi_device *spi = to_spi_device(priv->dev);
	struct spi_transfer xfer = {};
	struct spi_message msg;
	size_t buf_len;
	void *buf;
	int ret;

	buf_len = sizeof(lsc_bitstream_burst);

	buf = kmemdup(lsc_bitstream_burst, buf_len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	xfer.len = buf_len;
	xfer.tx_buf = buf;
	xfer.cs_change = 1;

	spi_message_init_with_transfers(&msg, &xfer, 1);

	/*
	 * Lock SPI bus for exclusive usage until FPGA programming is done.
	 * SPI bus will be released in sysconfig_spi_bitstream_burst_complete().
	 */
	spi_bus_lock(spi->controller);

	ret = spi_sync_locked(spi, &msg);
	if (ret)
		spi_bus_unlock(spi->controller);

	kfree(buf);

	return ret;
}

static int sysconfig_spi_bitstream_burst_write(struct sysconfig_priv *priv,
					       const char *buf, size_t len)
{
	struct spi_device *spi = to_spi_device(priv->dev);
	struct spi_transfer xfer = {
		.tx_buf = buf,
		.len = len,
		.cs_change = 1,
	};
	struct spi_message msg;

	spi_message_init_with_transfers(&msg, &xfer, 1);

	return spi_sync_locked(spi, &msg);
}

static int sysconfig_spi_bitstream_burst_complete(struct sysconfig_priv *priv)
{
	struct spi_device *spi = to_spi_device(priv->dev);

	/* Bitstream burst write is done, release SPI bus */
	spi_bus_unlock(spi->controller);

	/* Toggle CS to finish bitstream write */
	return spi_write(spi, NULL, 0);
}

static int sysconfig_spi_probe(struct spi_device *spi)
{
	const struct spi_device_id *dev_id;
	struct device *dev = &spi->dev;
	struct sysconfig_priv *priv;
	const u32 *spi_max_speed;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	spi_max_speed = device_get_match_data(dev);
	if (!spi_max_speed) {
		dev_id = spi_get_device_id(spi);
		if (!dev_id)
			return -ENODEV;

		spi_max_speed = (const u32 *)dev_id->driver_data;
	}

	if (!spi_max_speed)
		return -EINVAL;

	if (spi->max_speed_hz > *spi_max_speed) {
		dev_err(dev, "SPI speed %u is too high, maximum speed is %u\n",
			spi->max_speed_hz, *spi_max_speed);
		return -EINVAL;
	}

	priv->dev = dev;
	priv->command_transfer = sysconfig_spi_cmd_transfer;
	priv->bitstream_burst_write_init = sysconfig_spi_bitstream_burst_init;
	priv->bitstream_burst_write = sysconfig_spi_bitstream_burst_write;
	priv->bitstream_burst_write_complete = sysconfig_spi_bitstream_burst_complete;

	return sysconfig_probe(priv);
}

static const struct spi_device_id sysconfig_spi_ids[] = {
	{
		.name = "sysconfig-ecp5",
		.driver_data = (kernel_ulong_t)&ecp5_spi_max_speed_hz,
	}, {},
};
MODULE_DEVICE_TABLE(spi, sysconfig_spi_ids);

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id sysconfig_of_ids[] = {
	{
		.compatible = "lattice,sysconfig-ecp5",
		.data = &ecp5_spi_max_speed_hz,
	}, {},
};
MODULE_DEVICE_TABLE(of, sysconfig_of_ids);
#endif /* IS_ENABLED(CONFIG_OF) */

static struct spi_driver lattice_sysconfig_driver = {
	.probe = sysconfig_spi_probe,
	.id_table = sysconfig_spi_ids,
	.driver = {
		.name = "lattice_sysconfig_spi_fpga_mgr",
		.of_match_table = of_match_ptr(sysconfig_of_ids),
	},
};
module_spi_driver(lattice_sysconfig_driver);

MODULE_DESCRIPTION("Lattice sysCONFIG Slave SPI FPGA Manager");
MODULE_LICENSE("GPL");
