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

#include <amdblocks/lpc.h>
#include <amdblocks/spi.h>
#include <assert.h>
#include <boot_device.h>
#include <cbfs.h>
#include <commonlib/bsd/helpers.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <delay.h>
#include <device/pci_ops.h>
#include <soc/pci_devs.h>
#include <spi_flash.h>
#include <string.h>
#include <thread.h>
#include <types.h>

/* The ROM is memory mapped just below 4GiB. Form a pointer for the base. */
#define rom_base ((void *)(uintptr_t)(0x100000000ULL - CONFIG_ROM_SIZE))

struct spi_dma_transaction {
	uint8_t *destination;
	size_t source;
	size_t size;
	size_t transfer_size;
	size_t remaining;
};

static ssize_t spi_dma_readat_mmap(const struct region_device *rd, void *b, size_t offset,
				   size_t size)
{
	const struct mem_region_device *mdev;

	mdev = container_of(rd, __typeof__(*mdev), rdev);

	memcpy(b, &mdev->base[offset], size);

	return size;
}

static bool spi_dma_is_busy(void)
{
	return pci_read_config32(SOC_LPC_DEV, LPC_ROM_DMA_EC_HOST_CONTROL)
	       & LPC_ROM_DMA_CTRL_START;
}

static bool spi_dma_has_error(void)
{
	return pci_read_config32(SOC_LPC_DEV, LPC_ROM_DMA_EC_HOST_CONTROL)
	       & LPC_ROM_DMA_CTRL_ERROR;
}

static bool can_use_dma(void *destination, size_t source, size_t size)
{
	/*
	 * Print a notice if reading more than 1024 bytes using mmap. This makes
	 * it easier to debug why the SPI DMA wasn't used.
	 */
	const size_t warning_size = 1024;

	if (size < LPC_ROM_DMA_MIN_ALIGNMENT)
		return false;

	if (!IS_ALIGNED((uintptr_t)destination, LPC_ROM_DMA_MIN_ALIGNMENT)) {
		if (size > warning_size)
			printk(BIOS_DEBUG, "Target %p is unaligned\n", destination);
		return false;
	}

	if (!IS_ALIGNED(source, LPC_ROM_DMA_MIN_ALIGNMENT)) {
		if (size > warning_size)
			printk(BIOS_DEBUG, "Source %#zx is unaligned\n", source);
		return false;
	}

	return true;
}

static void start_spi_dma_transaction(struct spi_dma_transaction *transaction)
{
	uint32_t ctrl;

	printk(BIOS_SPEW, "%s: dest: %p, source: %#zx, remaining: %zu\n", __func__,
	       transaction->destination, transaction->source, transaction->remaining);

	/*
	 * We should have complete control over the DMA controller, so there shouldn't
	 * be any outstanding transactions.
	 */
	assert(!spi_dma_is_busy());
	assert(IS_ALIGNED((uintptr_t)transaction->destination, LPC_ROM_DMA_MIN_ALIGNMENT));
	assert(IS_ALIGNED(transaction->source, LPC_ROM_DMA_MIN_ALIGNMENT));
	assert(transaction->remaining >= LPC_ROM_DMA_MIN_ALIGNMENT);

	pci_write_config32(SOC_LPC_DEV, LPC_ROM_DMA_SRC_ADDR, transaction->source);
	pci_write_config32(SOC_LPC_DEV, LPC_ROM_DMA_DST_ADDR,
			   (uintptr_t)transaction->destination);

	ctrl = pci_read_config32(SOC_LPC_DEV, LPC_ROM_DMA_EC_HOST_CONTROL);
	ctrl &= ~LPC_ROM_DMA_CTRL_DW_COUNT_MASK;

	transaction->transfer_size =
		MIN(LPC_ROM_DMA_CTRL_MAX_BYTES,
		    ALIGN_DOWN(transaction->remaining, LPC_ROM_DMA_MIN_ALIGNMENT));

	ctrl |= LPC_ROM_DMA_CTRL_DW_COUNT(transaction->transfer_size);
	ctrl |= LPC_ROM_DMA_CTRL_ERROR; /* Clear error */
	ctrl |= LPC_ROM_DMA_CTRL_START;

	/*
	 * Ensure we have exclusive access to the SPI controller before starting the LPC SPI DMA
	 * transaction.
	 */
	thread_mutex_lock(&spi_hw_mutex);

	pci_write_config32(SOC_LPC_DEV, LPC_ROM_DMA_EC_HOST_CONTROL, ctrl);
}

/* Returns true if transaction is still in progress. */
static bool continue_spi_dma_transaction(const struct region_device *rd,
					 struct spi_dma_transaction *transaction)
{
	/* Verify we are looking at the correct transaction */
	assert(pci_read_config32(SOC_LPC_DEV, LPC_ROM_DMA_SRC_ADDR) == transaction->source);

	if (spi_dma_is_busy())
		return true;

	/*
	 * Unlock the SPI mutex between DMA transactions to allow other users of the SPI
	 * controller to interleave their transactions.
	 */
	thread_mutex_unlock(&spi_hw_mutex);

	if (spi_dma_has_error()) {
		printk(BIOS_ERR, "SPI DMA failure: dest: %p, source: %#zx, size: %zu\n",
		       transaction->destination, transaction->source,
		       transaction->transfer_size);
		return false;
	}

	transaction->destination += transaction->transfer_size;
	transaction->source += transaction->transfer_size;
	transaction->remaining -= transaction->transfer_size;

	if (transaction->remaining >= LPC_ROM_DMA_MIN_ALIGNMENT) {
		start_spi_dma_transaction(transaction);
		return true;
	}

	if (transaction->remaining > 0) {
		/* Use mmap to finish off the transfer */
		spi_dma_readat_mmap(rd, transaction->destination, transaction->source,
				    transaction->remaining);

		transaction->destination += transaction->remaining;
		transaction->source += transaction->remaining;
		transaction->remaining -= transaction->remaining;
	}

	return false;
}

static struct thread_mutex spi_dma_hw_mutex;

static ssize_t spi_dma_readat_dma(const struct region_device *rd, void *destination,
				  size_t source, size_t size)
{
	struct spi_dma_transaction transaction = {
		.destination = destination,
		.source = source,
		.size = size,
		.remaining = size,
	};

	printk(BIOS_SPEW, "%s: start: dest: %p, source: %#zx, size: %zu\n", __func__,
	       destination, source, size);

	thread_mutex_lock(&spi_dma_hw_mutex);

	start_spi_dma_transaction(&transaction);

	do {
		udelay(2);
	} while (continue_spi_dma_transaction(rd, &transaction));

	thread_mutex_unlock(&spi_dma_hw_mutex);

	printk(BIOS_SPEW, "%s: end: dest: %p, source: %#zx, remaining: %zu\n",
	       __func__, destination, source, transaction.remaining);

	/* Allow queued up transaction to continue */
	thread_yield();

	if (transaction.remaining)
		return -1;

	return transaction.size;
}

static ssize_t spi_dma_readat(const struct region_device *rd, void *b, size_t offset,
			      size_t size)
{
	if (can_use_dma(b, offset, size))
		return spi_dma_readat_dma(rd, b, offset, size);
	else
		return spi_dma_readat_mmap(rd, b, offset, size);
}

static void *spi_dma_mmap(const struct region_device *rd, size_t offset, size_t size)
{
	const struct mem_region_device *mdev;
	void *mapping;

	mdev = container_of(rd, __typeof__(*mdev), rdev);

	if (!CONFIG_CBFS_CACHE_SIZE)
		return &mdev->base[offset];

	mapping = mem_pool_alloc(&cbfs_cache, size);
	if (!mapping) {
		printk(BIOS_INFO, "%s: Could not allocate %zu bytes from memory pool\n",
		       __func__, size);
		/* Fall-back to memory map */
		return &mdev->base[offset];
	}

	if (spi_dma_readat(rd, mapping, offset, size) != size) {
		printk(BIOS_ERR, "%s: Error reading into mmap buffer\n", __func__);
		mem_pool_free(&cbfs_cache, mapping);
		/* Fall-back to memory mapped read - not expected to fail atleast for now */
		spi_dma_readat_mmap(rd, mapping, offset, size);
	}

	return mapping;
}

static int spi_dma_munmap(const struct region_device *rd __always_unused, void *mapping)
{
	if (CONFIG_CBFS_CACHE_SIZE)
		mem_pool_free(&cbfs_cache, mapping);
	return 0;
}

const struct region_device_ops spi_dma_rdev_ro_ops = {
	.mmap = spi_dma_mmap,
	.munmap = spi_dma_munmap,
	.readat = spi_dma_readat,
};

static const struct mem_region_device boot_dev = {
	.base = rom_base,
	.rdev = REGION_DEV_INIT(&spi_dma_rdev_ro_ops, 0, CONFIG_ROM_SIZE),
};

const struct region_device *boot_device_ro(void)
{
	return &boot_dev.rdev;
}

uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
{
	table->flash_base = 0;
	table->host_base = (uint32_t)(uintptr_t)rom_base;
	table->size = CONFIG_ROM_SIZE;

	return 1;
}

/*
 * Without this magic bit, the SPI DMA controller will write 0s into the destination if an MMAP
 * read happens while a DMA transaction is in progress. i.e., PSP is reading from SPI. The bit
 * that fixes this was added to Cezanne, Renoir and later SoCs. So the SPI DMA controller is not
 * reliable on any prior generations.
 */
static void spi_dma_fix(void)
{
	/* Internal only registers */
	uint8_t val = spi_read8(0xfc);
	val |= BIT(6);
	spi_write8(0xfc, val);
}

void boot_device_init(void)
{
	spi_dma_fix();
}
