// SPDX-License-Identifier: GPL-2.0
//
// SPI controller driver for Qualcomm Atheros AR934x/QCA95xx SoCs
//
// Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com>
//
// Based on spi-mt7621.c:
// Copyright (C) 2011 Sergiy <piratfm@gmail.com>
// Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
// Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>

#include <linux/clk.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>

#define DRIVER_NAME "spi-ar934x"

#define AR934X_SPI_REG_FS		0x00
#define AR934X_SPI_ENABLE		BIT(0)

#define AR934X_SPI_REG_IOC		0x08
#define AR934X_SPI_IOC_INITVAL		0x70000

#define AR934X_SPI_REG_CTRL		0x04
#define AR934X_SPI_CLK_MASK		GENMASK(5, 0)

#define AR934X_SPI_DATAOUT		0x10

#define AR934X_SPI_REG_SHIFT_CTRL	0x14
#define AR934X_SPI_SHIFT_EN		BIT(31)
#define AR934X_SPI_SHIFT_CS(n)		BIT(28 + (n))
#define AR934X_SPI_SHIFT_TERM		26
#define AR934X_SPI_SHIFT_VAL(cs, term, count)			\
	(AR934X_SPI_SHIFT_EN | AR934X_SPI_SHIFT_CS(cs) |	\
	(term) << AR934X_SPI_SHIFT_TERM | (count))

#define AR934X_SPI_DATAIN 0x18

struct ar934x_spi {
	struct spi_controller *ctlr;
	void __iomem *base;
	struct clk *clk;
	unsigned int clk_freq;
};

static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq)
{
	int div = DIV_ROUND_UP(sp->clk_freq, freq * 2) - 1;

	if (div < 0)
		return 0;
	else if (div > AR934X_SPI_CLK_MASK)
		return -EINVAL;
	else
		return div;
}

static int ar934x_spi_setup(struct spi_device *spi)
{
	struct ar934x_spi *sp = spi_controller_get_devdata(spi->controller);

	if ((spi->max_speed_hz == 0) ||
	    (spi->max_speed_hz > (sp->clk_freq / 2))) {
		spi->max_speed_hz = sp->clk_freq / 2;
	} else if (spi->max_speed_hz < (sp->clk_freq / 128)) {
		dev_err(&spi->dev, "spi clock is too low\n");
		return -EINVAL;
	}

	return 0;
}

static int ar934x_spi_transfer_one_message(struct spi_controller *ctlr,
					   struct spi_message *m)
{
	struct ar934x_spi *sp = spi_controller_get_devdata(ctlr);
	struct spi_transfer *t = NULL;
	struct spi_device *spi = m->spi;
	unsigned long trx_done, trx_cur;
	int stat = 0;
	u8 bpw, term = 0;
	int div, i;
	u32 reg;
	const u8 *tx_buf;
	u8 *buf;

	m->actual_length = 0;
	list_for_each_entry(t, &m->transfers, transfer_list) {
		if (t->bits_per_word >= 8 && t->bits_per_word < 32)
			bpw = t->bits_per_word >> 3;
		else
			bpw = 4;

		if (t->speed_hz)
			div = ar934x_spi_clk_div(sp, t->speed_hz);
		else
			div = ar934x_spi_clk_div(sp, spi->max_speed_hz);
		if (div < 0) {
			stat = -EIO;
			goto msg_done;
		}

		reg = ioread32(sp->base + AR934X_SPI_REG_CTRL);
		reg &= ~AR934X_SPI_CLK_MASK;
		reg |= div;
		iowrite32(reg, sp->base + AR934X_SPI_REG_CTRL);
		iowrite32(0, sp->base + AR934X_SPI_DATAOUT);

		for (trx_done = 0; trx_done < t->len; trx_done += bpw) {
			trx_cur = t->len - trx_done;
			if (trx_cur > bpw)
				trx_cur = bpw;
			else if (list_is_last(&t->transfer_list, &m->transfers))
				term = 1;

			if (t->tx_buf) {
				tx_buf = t->tx_buf + trx_done;
				reg = tx_buf[0];
				for (i = 1; i < trx_cur; i++)
					reg = reg << 8 | tx_buf[i];
				iowrite32(reg, sp->base + AR934X_SPI_DATAOUT);
			}

			reg = AR934X_SPI_SHIFT_VAL(spi_get_chipselect(spi, 0), term,
						   trx_cur * 8);
			iowrite32(reg, sp->base + AR934X_SPI_REG_SHIFT_CTRL);
			stat = readl_poll_timeout(
				sp->base + AR934X_SPI_REG_SHIFT_CTRL, reg,
				!(reg & AR934X_SPI_SHIFT_EN), 0, 5);
			if (stat < 0)
				goto msg_done;

			if (t->rx_buf) {
				reg = ioread32(sp->base + AR934X_SPI_DATAIN);
				buf = t->rx_buf + trx_done;
				for (i = 0; i < trx_cur; i++) {
					buf[trx_cur - i - 1] = reg & 0xff;
					reg >>= 8;
				}
			}
			spi_delay_exec(&t->word_delay, t);
		}
		m->actual_length += t->len;
		spi_transfer_delay_exec(t);
	}

msg_done:
	m->status = stat;
	spi_finalize_current_message(ctlr);

	return 0;
}

static const struct of_device_id ar934x_spi_match[] = {
	{ .compatible = "qca,ar934x-spi" },
	{},
};
MODULE_DEVICE_TABLE(of, ar934x_spi_match);

static int ar934x_spi_probe(struct platform_device *pdev)
{
	struct spi_controller *ctlr;
	struct ar934x_spi *sp;
	void __iomem *base;
	struct clk *clk;
	int ret;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "failed to get clock\n");
		return PTR_ERR(clk);
	}

	ret = clk_prepare_enable(clk);
	if (ret)
		return ret;

	ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*sp));
	if (!ctlr) {
		dev_info(&pdev->dev, "failed to allocate spi controller\n");
		ret = -ENOMEM;
		goto err_clk_disable;
	}

	/* disable flash mapping and expose spi controller registers */
	iowrite32(AR934X_SPI_ENABLE, base + AR934X_SPI_REG_FS);
	/* restore pins to default state: CSn=1 DO=CLK=0 */
	iowrite32(AR934X_SPI_IOC_INITVAL, base + AR934X_SPI_REG_IOC);

	ctlr->mode_bits = SPI_LSB_FIRST;
	ctlr->setup = ar934x_spi_setup;
	ctlr->transfer_one_message = ar934x_spi_transfer_one_message;
	ctlr->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
				   SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
	ctlr->dev.of_node = pdev->dev.of_node;
	ctlr->num_chipselect = 3;

	dev_set_drvdata(&pdev->dev, ctlr);

	sp = spi_controller_get_devdata(ctlr);
	sp->base = base;
	sp->clk = clk;
	sp->clk_freq = clk_get_rate(clk);
	sp->ctlr = ctlr;

	ret = spi_register_controller(ctlr);
	if (!ret)
		return 0;

err_clk_disable:
	clk_disable_unprepare(clk);
	return ret;
}

static void ar934x_spi_remove(struct platform_device *pdev)
{
	struct spi_controller *ctlr;
	struct ar934x_spi *sp;

	ctlr = dev_get_drvdata(&pdev->dev);
	sp = spi_controller_get_devdata(ctlr);

	spi_unregister_controller(ctlr);
	clk_disable_unprepare(sp->clk);
}

static struct platform_driver ar934x_spi_driver = {
	.driver = {
		.name = DRIVER_NAME,
		.of_match_table = ar934x_spi_match,
	},
	.probe = ar934x_spi_probe,
	.remove_new = ar934x_spi_remove,
};

module_platform_driver(ar934x_spi_driver);

MODULE_DESCRIPTION("SPI controller driver for Qualcomm Atheros AR934x/QCA95xx");
MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRIVER_NAME);
