/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/mmio.h>
#include <soc/spi.h>
#include <soc/clock.h>
#include <soc/addressmap.h>

#include "spi_internal.h"

static struct spi_ctrl *spictrls[] = {
	(struct spi_ctrl *)FU540_QSPI0,
	(struct spi_ctrl *)FU540_QSPI1,
	(struct spi_ctrl *)FU540_QSPI2
};

/**
 * Wait until SPI is ready for transmission and transmit byte.
 */
static void spi_tx(volatile struct spi_ctrl *spictrl, uint8_t in)
{
#if __riscv_atomic
	int32_t r;
	do {
		asm volatile (
			"amoor.w %0, %2, %1\n"
			: "=r" (r), "+A" (spictrl->txdata.raw_bits)
			: "r" (in)
		);
	} while (r < 0);
#else
	while ((int32_t) spictrl->txdata.raw_bits < 0)
		;
	spictrl->txdata.data = in;
#endif
}

/**
 * Wait until SPI receive queue has data and read byte.
 */
static uint8_t spi_rx(volatile struct spi_ctrl *spictrl)
{
	int32_t out;
	while ((out = (int32_t) spictrl->rxdata.raw_bits) < 0)
		;
	return (uint8_t) out;
}

static int spi_claim_bus_(const struct spi_slave *slave)
{
	struct spi_ctrl *spictrl = spictrls[slave->bus];
	spi_reg_csmode csmode;
	csmode.raw_bits = 0;
	csmode.mode = FU540_SPI_CSMODE_HOLD;
	write32(&spictrl->csmode.raw_bits, csmode.raw_bits);
	return 0;
}

static void spi_release_bus_(const struct spi_slave *slave)
{
	struct spi_ctrl *spictrl = spictrls[slave->bus];
	spi_reg_csmode csmode;
	csmode.raw_bits = 0;
	csmode.mode = FU540_SPI_CSMODE_OFF;
	write32(&spictrl->csmode.raw_bits, csmode.raw_bits);
}

static int spi_xfer_(const struct spi_slave *slave,
		const void *dout, size_t bytesout,
		void *din, size_t bytesin)
{
	struct spi_ctrl *spictrl = spictrls[slave->bus];
	spi_reg_fmt fmt;
	fmt.raw_bits = read32(&spictrl->fmt.raw_bits);
	if (fmt.proto == FU540_SPI_PROTO_S) {
		/* working in full-duplex mode
		 * receiving data needs to be triggered by sending data */
		while (bytesout || bytesin) {
			uint8_t in, out = 0;
			if (bytesout) {
				out = *(uint8_t *)dout++;
				bytesout--;
			}
			spi_tx(spictrl, out);
			in = spi_rx(spictrl);
			if (bytesin) {
				*(uint8_t *)din++ = in;
				bytesin--;
			}
		}
	} else {
		/* Working in half duplex
		 * send and receive can be done separately */
		if (dout && din)
			return -1;

		if (dout) {
			while (bytesout) {
				spi_tx(spictrl, *(uint8_t *)dout++);
				bytesout--;
			}
		}

		if (din) {
			while (bytesin) {
				*(uint8_t *)din++ = spi_rx(spictrl);
				bytesin--;
			}
		}
	}
	return 0;
}

static int spi_setup_(const struct spi_slave *slave)
{
	spi_reg_sckmode sckmode;
	spi_reg_csmode csmode;
	spi_reg_fmt fmt;

	if ((slave->bus > 2) || (slave->cs != 0))
		return -1;

	struct spi_ctrl *spictrl = spictrls[slave->bus];

	write32(&spictrl->sckdiv, spi_min_clk_divisor(clock_get_tlclk_khz(),
				10000));

	sckmode.raw_bits = 0;
	sckmode.pha = FU540_SPI_PHA_LOW;
	sckmode.pol = FU540_SPI_POL_LEADING;
	write32(&spictrl->sckmode.raw_bits, sckmode.raw_bits);

	write32(&spictrl->csdef, 0xffffffff);

	csmode.raw_bits = 0;
	csmode.mode = FU540_SPI_CSMODE_AUTO;
	write32(&spictrl->csmode.raw_bits, csmode.raw_bits);

	fmt.raw_bits = 0;
	fmt.proto = FU540_SPI_PROTO_S;
	fmt.endian = FU540_SPI_ENDIAN_BIG;
	fmt.dir = 0;
	fmt.len = 8;
	write32(&spictrl->fmt.raw_bits, fmt.raw_bits);

	return 0;
}

struct spi_ctrlr fu540_spi_ctrlr = {
	.xfer  = spi_xfer_,
	.setup = spi_setup_,
	.claim_bus = spi_claim_bus_,
	.release_bus = spi_release_bus_,
};

const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
	{
		.bus_start = 0,
		.bus_end = 2,
		.ctrlr = &fu540_spi_ctrlr,
	}
};

const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);

int fu540_spi_setup(unsigned int bus, unsigned int cs,
		struct spi_slave *slave,
		struct fu540_spi_config *config)
{
	spi_reg_sckmode sckmode;
	spi_reg_csmode csmode;
	spi_reg_fmt fmt;

	if ((bus > 2) || (cs != 0))
		return -1;

	if ((config->pha > 1)
		|| (config->pol > 1)
		|| (config->protocol > 2)
		|| (config->endianness > 1)
		|| (config->bits_per_frame > 8))
		return -1;

	slave->bus = bus;
	slave->cs = cs;
	slave->ctrlr = &fu540_spi_ctrlr;

	struct spi_ctrl *spictrl = spictrls[slave->bus];

	write32(&spictrl->sckdiv, spi_min_clk_divisor(clock_get_tlclk_khz(),
			config->freq / 1000));

	sckmode.raw_bits = 0;
	sckmode.pha = config->pha;
	sckmode.pol = config->pol;
	write32(&spictrl->sckmode.raw_bits, sckmode.raw_bits);

	write32(&spictrl->csdef, 0xffffffff);

	csmode.raw_bits = 0;
	csmode.mode = FU540_SPI_CSMODE_AUTO;
	write32(&spictrl->csmode.raw_bits, csmode.raw_bits);

	fmt.raw_bits = 0;
	fmt.proto = config->protocol;
	fmt.endian = config->endianness;
	fmt.dir = 0;
	fmt.len = config->bits_per_frame;
	write32(&spictrl->fmt.raw_bits, fmt.raw_bits);

	return 0;
}

int fu540_spi_mmap(
		const struct spi_slave *slave,
		const struct fu540_spi_mmap_config *config)
{
	spi_reg_fctrl fctrl;
	spi_reg_ffmt ffmt;

	if (slave->bus > 2)
		return -1;

	if ((config->cmd_en > 1)
		|| (config->addr_len > 4)
		|| (config->pad_cnt > 15)
		|| (config->cmd_proto > 2)
		|| (config->addr_proto > 2)
		|| (config->data_proto > 2)
		|| (config->cmd_code > 255)
		|| (config->pad_code > 255))
		return -1;

	struct spi_ctrl *spictrl = spictrls[slave->bus];

	/* disable direct memory-mapped spi flash mode */
	fctrl.raw_bits = 0;
	fctrl.en = 0;
	write32(&spictrl->fctrl.raw_bits, fctrl.raw_bits);

	/* reset spi flash chip */
	spi_tx(spictrl, 0x66);
	spi_tx(spictrl, 0x99);

	/* Pass the information of the flash read operation to the spi
	 * controller */
	ffmt.raw_bits = 0;
	ffmt.cmd_en = config->cmd_en;
	ffmt.addr_len = config->addr_len;
	ffmt.pad_cnt = config->pad_cnt;
	ffmt.command_proto = config->cmd_proto;
	ffmt.addr_proto = config->addr_proto;
	ffmt.data_proto = config->data_proto;
	ffmt.command_code = config->cmd_code;
	ffmt.pad_code = config->pad_code;
	write32(&spictrl->ffmt.raw_bits, ffmt.raw_bits);

	/* enable direct memory-mapped spi flash mode */
	fctrl.raw_bits = 0;
	fctrl.en = 1;
	write32(&spictrl->fctrl.raw_bits, fctrl.raw_bits);

	return 0;
}
