/*
 * Copyright (c) 2021 BayLibre, SAS
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(pcie_core, LOG_LEVEL_INF);

#include <kernel.h>
#include <drivers/pcie/pcie.h>
#include <drivers/pcie/controller.h>

#if CONFIG_PCIE_MSI
#include <drivers/pcie/msi.h>
#endif

/* arch agnostic PCIe API implementation */

uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg)
{
	const struct device *dev;

	dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_pcie_controller));
	if (!dev) {
		LOG_ERR("Failed to get PCIe root complex");
		return 0xffffffff;
	}

	return pcie_ctrl_conf_read(dev, bdf, reg);
}

void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data)
{
	const struct device *dev;

	dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_pcie_controller));
	if (!dev) {
		LOG_ERR("Failed to get PCIe root complex");
		return;
	}

	pcie_ctrl_conf_write(dev, bdf, reg, data);
}

uint32_t pcie_generic_ctrl_conf_read(mm_reg_t cfg_addr, pcie_bdf_t bdf, unsigned int reg)
{
	volatile uint32_t *bdf_cfg_mem = (volatile uint32_t *)((uintptr_t)cfg_addr + (bdf << 4));

	if (!cfg_addr) {
		return 0xffffffff;
	}

	return bdf_cfg_mem[reg];
}

void pcie_generic_ctrl_conf_write(mm_reg_t cfg_addr, pcie_bdf_t bdf,
				 unsigned int reg, uint32_t data)
{
	volatile uint32_t *bdf_cfg_mem = (volatile uint32_t *)((uintptr_t)cfg_addr + (bdf << 4));

	if (!cfg_addr) {
		return;
	}

	bdf_cfg_mem[reg] = data;
}

static void pcie_generic_ctrl_enumerate_bars(const struct device *ctrl_dev, pcie_bdf_t bdf,
					     unsigned int nbars)
{
	unsigned int bar, reg, data;
	uintptr_t scratch, bar_bus_addr;
	size_t size, bar_size;

	for (bar = 0, reg = PCIE_CONF_BAR0; bar < nbars && reg <= PCIE_CONF_BAR5; reg ++, bar++) {
		bool found_mem64 = false;
		bool found_mem = false;

		data = scratch = pcie_conf_read(bdf, reg);

		if (PCIE_CONF_BAR_INVAL_FLAGS(data)) {
			continue;
		}

		if (PCIE_CONF_BAR_MEM(data)) {
			found_mem = true;
			if (PCIE_CONF_BAR_64(data)) {
				found_mem64 = true;
				scratch |= ((uint64_t)pcie_conf_read(bdf, reg + 1)) << 32;
				if (PCIE_CONF_BAR_ADDR(scratch) == PCIE_CONF_BAR_INVAL64) {
					continue;
				}
			} else {
				if (PCIE_CONF_BAR_ADDR(scratch) == PCIE_CONF_BAR_INVAL) {
					continue;
				}
			}
		}

		pcie_conf_write(bdf, reg, 0xFFFFFFFF);
		size = pcie_conf_read(bdf, reg);
		pcie_conf_write(bdf, reg, scratch & 0xFFFFFFFF);

		if (found_mem64) {
			pcie_conf_write(bdf, reg + 1, 0xFFFFFFFF);
			size |= ((uint64_t)pcie_conf_read(bdf, reg + 1)) << 32;
			pcie_conf_write(bdf, reg + 1, scratch >> 32);
		}

		if (!PCIE_CONF_BAR_ADDR(size)) {
			if (found_mem64) {
				reg++;
			}
			continue;
		}

		if (found_mem) {
			if (found_mem64) {
				bar_size = (uint64_t)~PCIE_CONF_BAR_ADDR(size) + 1;
			} else {
				bar_size = (uint32_t)~PCIE_CONF_BAR_ADDR(size) + 1;
			}
		} else {
			bar_size = (uint32_t)~PCIE_CONF_BAR_IO_ADDR(size) + 1;
		}

		if (pcie_ctrl_region_allocate(ctrl_dev, bdf, found_mem,
					      found_mem64, bar_size, &bar_bus_addr)) {
			uintptr_t bar_phys_addr;

			pcie_ctrl_region_translate(ctrl_dev, bdf, found_mem,
						   found_mem64, bar_bus_addr, &bar_phys_addr);

			LOG_INF("[%02x:%02x.%x] BAR%d size 0x%lx "
				"assigned [%s 0x%lx-0x%lx -> 0x%lx-0x%lx]",
				PCIE_BDF_TO_BUS(bdf), PCIE_BDF_TO_DEV(bdf), PCIE_BDF_TO_FUNC(bdf),
				bar, bar_size,
				found_mem ? (found_mem64 ? "mem64" : "mem") : "io",
				bar_bus_addr, bar_bus_addr + bar_size - 1,
				bar_phys_addr, bar_phys_addr + bar_size - 1);

			pcie_conf_write(bdf, reg, bar_bus_addr & 0xFFFFFFFF);
			if (found_mem64) {
				pcie_conf_write(bdf, reg + 1, bar_bus_addr >> 32);
			}
		} else {
			LOG_INF("[%02x:%02x.%x] BAR%d size 0x%lx Failed memory allocation.",
				PCIE_BDF_TO_BUS(bdf), PCIE_BDF_TO_DEV(bdf), PCIE_BDF_TO_FUNC(bdf),
				bar, bar_size);
		}

		if (found_mem64) {
			reg++;
		}
	}
}

static bool pcie_generic_ctrl_enumerate_type1(const struct device *ctrl_dev, pcie_bdf_t bdf,
					      unsigned int bus_number)
{
	uint32_t class = pcie_conf_read(bdf, PCIE_CONF_CLASSREV);

	/* Handle only PCI-to-PCI bridge for now */
	if (PCIE_CONF_CLASSREV_CLASS(class) == 0x06 &&
	    PCIE_CONF_CLASSREV_SUBCLASS(class) == 0x04) {
		uint32_t number = pcie_conf_read(bdf, PCIE_BUS_NUMBER);
		uintptr_t bar_base_addr;

		pcie_generic_ctrl_enumerate_bars(ctrl_dev, bdf, 2);

		/* Configure bus number registers */
		pcie_conf_write(bdf, PCIE_BUS_NUMBER,
				PCIE_BUS_NUMBER_VAL(PCIE_BDF_TO_BUS(bdf),
						    bus_number,
						    0xff, /* set max until we finished scanning */
						    PCIE_SECONDARY_LATENCY_TIMER(number)));

		/* I/O align on 4k boundary */
		if (pcie_ctrl_region_get_allocate_base(ctrl_dev, bdf, false, false,
						       KB(4), &bar_base_addr)) {
			uint32_t io = pcie_conf_read(bdf, PCIE_IO_SEC_STATUS);
			uint32_t io_upper = pcie_conf_read(bdf, PCIE_IO_BASE_LIMIT_UPPER);

			pcie_conf_write(bdf, PCIE_IO_SEC_STATUS,
					PCIE_IO_SEC_STATUS_VAL(PCIE_IO_BASE(io),
							       PCIE_IO_LIMIT(io),
							       PCIE_SEC_STATUS(io)));

			pcie_conf_write(bdf, PCIE_IO_BASE_LIMIT_UPPER,
				PCIE_IO_BASE_LIMIT_UPPER_VAL(PCIE_IO_BASE_UPPER(io_upper),
							     PCIE_IO_LIMIT_UPPER(io_upper)));

			pcie_set_cmd(bdf, PCIE_CONF_CMDSTAT_IO, true);
		}

		/* MEM align on 1MiB boundary */
		if (pcie_ctrl_region_get_allocate_base(ctrl_dev, bdf, true, false,
						       MB(1), &bar_base_addr)) {
			uint32_t mem = pcie_conf_read(bdf, PCIE_MEM_BASE_LIMIT);

			pcie_conf_write(bdf, PCIE_MEM_BASE_LIMIT,
					PCIE_MEM_BASE_LIMIT_VAL((bar_base_addr & 0xfff00000) >> 16,
								PCIE_MEM_LIMIT(mem)));

			pcie_set_cmd(bdf, PCIE_CONF_CMDSTAT_MEM, true);
		}

		/* TODO: add support for prefetchable */

		pcie_set_cmd(bdf, PCIE_CONF_CMDSTAT_MASTER, true);

		return true;
	}

	return false;
}

static void pcie_generic_ctrl_post_enumerate_type1(const struct device *ctrl_dev, pcie_bdf_t bdf,
						   unsigned int bus_number)
{
	uint32_t number = pcie_conf_read(bdf, PCIE_BUS_NUMBER);
	uintptr_t bar_base_addr;

	/* Configure bus subordinate */
	pcie_conf_write(bdf, PCIE_BUS_NUMBER,
			PCIE_BUS_NUMBER_VAL(PCIE_BUS_PRIMARY_NUMBER(number),
				PCIE_BUS_SECONDARY_NUMBER(number),
				bus_number - 1,
				PCIE_SECONDARY_LATENCY_TIMER(number)));

	/* I/O align on 4k boundary */
	if (pcie_ctrl_region_get_allocate_base(ctrl_dev, bdf, false, false,
					       KB(4), &bar_base_addr)) {
		uint32_t io = pcie_conf_read(bdf, PCIE_IO_SEC_STATUS);
		uint32_t io_upper = pcie_conf_read(bdf, PCIE_IO_BASE_LIMIT_UPPER);

		pcie_conf_write(bdf, PCIE_IO_SEC_STATUS,
				PCIE_IO_SEC_STATUS_VAL(PCIE_IO_BASE(io),
					((bar_base_addr - 1) & 0x0000f000) >> 16,
					PCIE_SEC_STATUS(io)));

		pcie_conf_write(bdf, PCIE_IO_BASE_LIMIT_UPPER,
				PCIE_IO_BASE_LIMIT_UPPER_VAL(PCIE_IO_BASE_UPPER(io_upper),
					((bar_base_addr - 1) & 0xffff0000) >> 16));
	}

	/* MEM align on 1MiB boundary */
	if (pcie_ctrl_region_get_allocate_base(ctrl_dev, bdf, true, false,
					       MB(1), &bar_base_addr)) {
		uint32_t mem = pcie_conf_read(bdf, PCIE_MEM_BASE_LIMIT);

		pcie_conf_write(bdf, PCIE_MEM_BASE_LIMIT,
				PCIE_MEM_BASE_LIMIT_VAL(PCIE_MEM_BASE(mem),
					(bar_base_addr - 1) >> 16));
	}

	/* TODO: add support for prefetchable */
}

static void pcie_generic_ctrl_enumerate_type0(const struct device *ctrl_dev, pcie_bdf_t bdf)
{
	/* Setup Type0 BARs */
	pcie_generic_ctrl_enumerate_bars(ctrl_dev, bdf, 6);
}

static bool pcie_generic_ctrl_enumerate_endpoint(const struct device *ctrl_dev,
						 pcie_bdf_t bdf, unsigned int bus_number,
						 bool *skip_next_func)
{
	bool multifunction_device = false;
	bool layout_type_1 = false;
	uint32_t data, class, id;
	bool is_bridge = false;

	*skip_next_func = false;

	id = pcie_conf_read(bdf, PCIE_CONF_ID);
	if (id == PCIE_ID_NONE) {
		return false;
	}

	class = pcie_conf_read(bdf, PCIE_CONF_CLASSREV);
	data = pcie_conf_read(bdf, PCIE_CONF_TYPE);

	multifunction_device = PCIE_CONF_MULTIFUNCTION(data);
	layout_type_1 = PCIE_CONF_TYPE_BRIDGE(data);

	LOG_INF("[%02x:%02x.%x] %04x:%04x class %x subclass %x progif %x "
		"rev %x Type%x multifunction %s",
		PCIE_BDF_TO_BUS(bdf), PCIE_BDF_TO_DEV(bdf), PCIE_BDF_TO_FUNC(bdf),
		id & 0xffff, id >> 16,
		PCIE_CONF_CLASSREV_CLASS(class),
		PCIE_CONF_CLASSREV_SUBCLASS(class),
		PCIE_CONF_CLASSREV_PROGIF(class),
		PCIE_CONF_CLASSREV_REV(class),
		layout_type_1 ? 1 : 0,
		multifunction_device ? "true" : "false");

	/* Do not enumerate sub-functions if not a multifunction device */
	if (PCIE_BDF_TO_FUNC(bdf) == 0 && !multifunction_device) {
		*skip_next_func = true;
	}

	if (layout_type_1) {
		is_bridge = pcie_generic_ctrl_enumerate_type1(ctrl_dev, bdf, bus_number);
	} else {
		pcie_generic_ctrl_enumerate_type0(ctrl_dev, bdf);
	}

	return is_bridge;
}

/* Return the next BDF or PCIE_BDF_NONE without changing bus number */
static inline unsigned int pcie_bdf_bus_next(unsigned int bdf, bool skip_next_func)
{
	if (skip_next_func) {
		if (PCIE_BDF_TO_DEV(bdf) == PCIE_BDF_DEV_MASK) {
			return PCIE_BDF_NONE;
		}

		return PCIE_BDF(PCIE_BDF_TO_BUS(bdf), PCIE_BDF_TO_DEV(bdf) + 1, 0);
	}

	if (PCIE_BDF_TO_DEV(bdf) == PCIE_BDF_DEV_MASK &&
	    PCIE_BDF_TO_FUNC(bdf) == PCIE_BDF_FUNC_MASK) {
		return PCIE_BDF_NONE;
	}

	return PCIE_BDF(PCIE_BDF_TO_BUS(bdf),
			(PCIE_BDF_TO_DEV(bdf) +
			 ((PCIE_BDF_TO_FUNC(bdf) + 1) / (PCIE_BDF_FUNC_MASK + 1))),
			((PCIE_BDF_TO_FUNC(bdf) + 1) & PCIE_BDF_FUNC_MASK));
}

struct pcie_bus_state {
	/* Current scanned bus BDF, always valid */
	unsigned int bus_bdf;
	/* Current bridge endpoint BDF, either valid or PCIE_BDF_NONE */
	unsigned int bridge_bdf;
	/* Next BDF to scan on bus, either valid or PCIE_BDF_NONE when all EP scanned */
	unsigned int next_bdf;
};

#define MAX_TRAVERSE_STACK 256

/* Non-recursive stack based PCIe bus & bridge enumeration */
void pcie_generic_ctrl_enumerate(const struct device *ctrl_dev, pcie_bdf_t bdf_start)
{
	struct pcie_bus_state stack[MAX_TRAVERSE_STACK], *state;
	unsigned int bus_number = PCIE_BDF_TO_BUS(bdf_start) + 1;
	bool skip_next_func = false;
	bool is_bridge = false;

	int stack_top = 0;

	/* Start with first endpoint of immediate Root Controller bus */
	stack[stack_top].bus_bdf = PCIE_BDF(PCIE_BDF_TO_BUS(bdf_start), 0, 0);
	stack[stack_top].bridge_bdf = PCIE_BDF_NONE;
	stack[stack_top].next_bdf = bdf_start;

	while (stack_top >= 0) {
		/* Top of stack contains the current PCIe bus to traverse */
		state = &stack[stack_top];

		/* Finish current bridge configuration before scanning other endpoints */
		if (state->bridge_bdf != PCIE_BDF_NONE) {
			pcie_generic_ctrl_post_enumerate_type1(ctrl_dev, state->bridge_bdf,
							       bus_number);

			state->bridge_bdf = PCIE_BDF_NONE;
		}

		/* We still have more endpoints to scan */
		if (state->next_bdf != PCIE_BDF_NONE) {
			while (state->next_bdf != PCIE_BDF_NONE) {
				is_bridge = pcie_generic_ctrl_enumerate_endpoint(ctrl_dev,
										 state->next_bdf,
										 bus_number,
										 &skip_next_func);
				if (is_bridge) {
					state->bridge_bdf = state->next_bdf;
					state->next_bdf = pcie_bdf_bus_next(state->next_bdf,
									    skip_next_func);

					/* If we can't handle more bridges, don't go further */
					if (stack_top == (MAX_TRAVERSE_STACK - 1) ||
					    bus_number == PCIE_BDF_BUS_MASK) {
						break;
					}

					/* Push to stack to scan this bus */
					stack_top++;
					stack[stack_top].bus_bdf = PCIE_BDF(bus_number, 0, 0);
					stack[stack_top].bridge_bdf = PCIE_BDF_NONE;
					stack[stack_top].next_bdf = PCIE_BDF(bus_number, 0, 0);

					/* Increase bus number */
					bus_number++;

					break;
				}

				state->next_bdf = pcie_bdf_bus_next(state->next_bdf,
								    skip_next_func);
			}
		} else {
			/* We finished scanning this bus, go back and scan next endpoints */
			stack_top--;
		}
	}
}

#ifdef CONFIG_PCIE_MSI
uint32_t pcie_msi_map(unsigned int irq, msi_vector_t *vector, uint8_t n_vector)
{
	ARG_UNUSED(irq);

	return vector->arch.address;
}

uint16_t pcie_msi_mdr(unsigned int irq, msi_vector_t *vector)
{
	ARG_UNUSED(irq);

	return vector->arch.eventid;
}

uint8_t arch_pcie_msi_vectors_allocate(unsigned int priority,
				       msi_vector_t *vectors,
				       uint8_t n_vector)
{
	const struct device *dev;

	dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_pcie_controller));
	if (!dev) {
		LOG_ERR("Failed to get PCIe root complex");
		return 0;
	}

	return pcie_ctrl_msi_device_setup(dev, priority, vectors, n_vector);
}

bool arch_pcie_msi_vector_connect(msi_vector_t *vector,
				  void (*routine)(const void *parameter),
				  const void *parameter,
				  uint32_t flags)
{
	if (irq_connect_dynamic(vector->arch.irq, vector->arch.priority, routine,
				parameter, flags) != vector->arch.irq) {
		return false;
	}

	irq_enable(vector->arch.irq);

	return true;
}
#endif
