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

#include <spi-generic.h>
#include <spi_flash.h>
#include <arch/cache.h>
#include <device/mmio.h>
#include <soc/addressmap.h>
#include <soc/qspi.h>
#include <soc/gpio.h>
#include <soc/clock.h>
#include <symbols.h>
#include <assert.h>
#include <gpio.h>
#include <string.h>

#define CACHE_LINE_SIZE	64

static int curr_desc_idx = -1;

struct cmd_desc {
	uint32_t data_address;
	uint32_t next_descriptor;
	uint32_t direction:1;
	uint32_t multi_io_mode:3;
	uint32_t reserved1:4;
	uint32_t fragment:1;
	uint32_t reserved2:7;
	uint32_t length:16;
	//------------------------//
	uint32_t bounce_src;
	uint32_t bounce_dst;
	uint32_t bounce_length;
	uint64_t padding[5];
};

enum qspi_mode {
	SDR_1BIT = 1,
	SDR_2BIT = 2,
	SDR_4BIT = 3,
	DDR_1BIT = 5,
	DDR_2BIT = 6,
	DDR_4BIT = 7,
};

enum cs_state {
	CS_DEASSERT,
	CS_ASSERT
};

struct xfer_cfg {
	enum qspi_mode mode;
};

enum bus_xfer_direction {
	MASTER_READ = 0,
	MASTER_WRITE = 1,
};

struct {
	struct cmd_desc descriptors[3];
	uint8_t buffers[3][CACHE_LINE_SIZE];
} *dma = (void *)_dma_coherent;

static void dma_transfer_chain(struct cmd_desc *chain)
{
	uint32_t mstr_int_status;

	write32(&sc7180_qspi->mstr_int_sts, 0xFFFFFFFF);
	write32(&sc7180_qspi->next_dma_desc_addr, (uint32_t)(uintptr_t) chain);

	while (1) {
		mstr_int_status = read32(&sc7180_qspi->mstr_int_sts);
		if (mstr_int_status & DMA_CHAIN_DONE)
			break;
	}
}

static void flush_chain(void)
{
	struct cmd_desc *desc = &dma->descriptors[0];
	uint8_t *src;
	uint8_t *dst;

	dma_transfer_chain(desc);

	while (desc) {
		if (desc->direction == MASTER_READ) {
			if (desc->bounce_length == 0)
				dcache_invalidate_by_mva(
					(void *)(uintptr_t) desc->data_address,
					desc->length);
			else {
				src = (void *)(uintptr_t) desc->bounce_src;
				dst = (void *)(uintptr_t) desc->bounce_dst;
				memcpy(dst, src, desc->bounce_length);
			}
		}
		desc = (void *)(uintptr_t) desc->next_descriptor;
	}
	curr_desc_idx = -1;
}

static struct cmd_desc *allocate_descriptor(void)
{
	struct cmd_desc *current;
	struct cmd_desc *next;
	uint8_t index;

	current = (curr_desc_idx == -1) ?
		NULL : &dma->descriptors[curr_desc_idx];

	index = ++curr_desc_idx;
	next = &dma->descriptors[index];

	next->data_address = (uint32_t) (uintptr_t) dma->buffers[index];

	next->next_descriptor = 0;
	next->direction = MASTER_READ;
	next->multi_io_mode = 0;
	next->reserved1 = 0;
	/*
	 * QSPI controller doesn't support transfer starts with read segment.
	 * So to support read transfers that are not preceded by write, set
	 * transfer fragment bit = 1
	 */
	next->fragment = 1;
	next->reserved2 = 0;
	next->length = 0;
	next->bounce_src = 0;
	next->bounce_dst = 0;
	next->bounce_length = 0;

	if (current)
		current->next_descriptor = (uint32_t)(uintptr_t) next;

	return next;
}

static void cs_change(enum cs_state state)
{
	gpio_set(GPIO(68), state == CS_DEASSERT);
}

static void configure_gpios(void)
{
	gpio_output(GPIO(68), 1);

	gpio_configure(GPIO(64), GPIO64_FUNC_QSPI_DATA_0,
		GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT_ENABLE);

	gpio_configure(GPIO(65), GPIO65_FUNC_QSPI_DATA_1,
		GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT_ENABLE);

	gpio_configure(GPIO(63), GPIO63_FUNC_QSPI_CLK,
		GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT_ENABLE);
}

static void queue_bounce_data(uint8_t *data, uint32_t data_bytes,
			      enum qspi_mode data_mode, bool write)
{
	struct cmd_desc *desc;
	uint8_t *ptr;

	desc = allocate_descriptor();
	desc->direction = write;
	desc->multi_io_mode = data_mode;
	ptr = (void *)(uintptr_t) desc->data_address;

	if (write) {
		memcpy(ptr, data, data_bytes);
	} else {
		desc->bounce_src = (uint32_t)(uintptr_t) ptr;
		desc->bounce_dst = (uint32_t)(uintptr_t) data;
		desc->bounce_length = data_bytes;
	}

	desc->length = data_bytes;
}

static void queue_direct_data(uint8_t *data, uint32_t data_bytes,
			      enum qspi_mode data_mode, bool write)
{
	struct cmd_desc *desc;

	desc = allocate_descriptor();
	desc->direction = write;
	desc->multi_io_mode = data_mode;
	desc->data_address = (uint32_t)(uintptr_t) data;
	desc->length = data_bytes;

	if (write)
		dcache_clean_by_mva(data, data_bytes);
	else
		dcache_invalidate_by_mva(data, data_bytes);
}

static void queue_data(uint8_t *data, uint32_t data_bytes,
	enum qspi_mode data_mode, bool write)
{
	uint8_t *aligned_ptr;
	uint8_t *epilog_ptr;
	uint32_t prolog_bytes, aligned_bytes, epilog_bytes;

	if (data_bytes == 0)
		return;

	aligned_ptr =
		(uint8_t *)ALIGN_UP((uintptr_t)data, CACHE_LINE_SIZE);

	prolog_bytes = MIN(data_bytes, aligned_ptr - data);
	aligned_bytes = ALIGN_DOWN(data_bytes - prolog_bytes, CACHE_LINE_SIZE);
	epilog_bytes = data_bytes - prolog_bytes - aligned_bytes;

	epilog_ptr = data + prolog_bytes + aligned_bytes;

	if (prolog_bytes)
		queue_bounce_data(data, prolog_bytes, data_mode, write);
	if (aligned_bytes)
		queue_direct_data(aligned_ptr, aligned_bytes, data_mode, write);
	if (epilog_bytes)
		queue_bounce_data(epilog_ptr, epilog_bytes, data_mode, write);
}

static void reg_init(void)
{
	uint32_t spi_mode;
	uint32_t tx_data_oe_delay, tx_data_delay;
	uint32_t mstr_config;

	spi_mode = 0;

	tx_data_oe_delay = 0;
	tx_data_delay = 0;

	mstr_config = (tx_data_oe_delay << TX_DATA_OE_DELAY_SHIFT) |
		(tx_data_delay << TX_DATA_DELAY_SHIFT) | (SBL_EN) |
		(spi_mode << SPI_MODE_SHIFT) |
		(PIN_HOLDN) |
		(FB_CLK_EN) |
		(DMA_ENABLE) |
		(FULL_CYCLE_MODE);

	write32(&sc7180_qspi->mstr_cfg, mstr_config);
	write32(&sc7180_qspi->ahb_mstr_cfg, 0xA42);
	write32(&sc7180_qspi->mstr_int_en, 0x0);
	write32(&sc7180_qspi->mstr_int_sts, 0xFFFFFFFF);
	write32(&sc7180_qspi->rd_fifo_cfg, 0x0);
	write32(&sc7180_qspi->rd_fifo_rst, RESET_FIFO);
}

void quadspi_init(uint32_t hz)
{
	assert(dcache_line_bytes() == CACHE_LINE_SIZE);
	clock_configure_qspi(hz * 4);
	configure_gpios();
	reg_init();
}

int sc7180_claim_bus(const struct spi_slave *slave)
{
	cs_change(CS_ASSERT);
	return 0;
}

void sc7180_release_bus(const struct spi_slave *slave)
{
	cs_change(CS_DEASSERT);
}

static int xfer(enum qspi_mode mode, const void *dout, size_t out_bytes,
		void *din, size_t in_bytes)
{
	if ((out_bytes && !dout) || (in_bytes && !din) ||
		(in_bytes && out_bytes)) {
		return -1;
	}

	queue_data((uint8_t *) (out_bytes ? dout : din),
		in_bytes | out_bytes, mode, !!out_bytes);

	flush_chain();

	return 0;
}

int sc7180_xfer(const struct spi_slave *slave, const void *dout,
		size_t out_bytes, void *din, size_t in_bytes)
{
	return xfer(SDR_1BIT, dout, out_bytes, din, in_bytes);
}

int sc7180_xfer_dual(const struct spi_slave *slave, const void *dout,
		     size_t out_bytes, void *din, size_t in_bytes)
{
	return xfer(SDR_2BIT, dout, out_bytes, din, in_bytes);
}
