/*
 * Copyright (c) 2019 Intel Corporation
 * Copyright (c) 2020 acontis technologies GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT pcie_controller

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(pcie, LOG_LEVEL_ERR);

#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/sys/check.h>
#include <stdbool.h>
#include <zephyr/drivers/pcie/pcie.h>
#include <zephyr/sys/iterable_sections.h>

#ifdef CONFIG_ACPI
#include <zephyr/acpi/acpi.h>
#endif

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

#ifdef CONFIG_PCIE_CONTROLLER
#include <zephyr/drivers/pcie/controller.h>
#endif

#ifdef CONFIG_PCIE_PRT
/* platform interrupt are hardwired or can be dynamically allocated. */
static bool prt_en;
#endif

/* functions documented in drivers/pcie/pcie.h */

void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on)
{
	uint32_t cmdstat;

	cmdstat = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT);

	if (on) {
		cmdstat |= bits;
	} else {
		cmdstat &= ~bits;
	}

	pcie_conf_write(bdf, PCIE_CONF_CMDSTAT, cmdstat);
}

uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id)
{
	uint32_t reg = 0U;
	uint32_t data;

	data = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT);
	if ((data & PCIE_CONF_CMDSTAT_CAPS) != 0U) {
		data = pcie_conf_read(bdf, PCIE_CONF_CAPPTR);
		reg = PCIE_CONF_CAPPTR_FIRST(data);
	}

	while (reg != 0U) {
		data = pcie_conf_read(bdf, reg);

		if (PCIE_CONF_CAP_ID(data) == cap_id) {
			break;
		}

		reg = PCIE_CONF_CAP_NEXT(data);
	}

	return reg;
}

uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id)
{
	unsigned int reg = PCIE_CONF_EXT_CAPPTR; /* Start at end of the PCI configuration space */
	uint32_t data;

	while (reg != 0U) {
		data = pcie_conf_read(bdf, reg);
		if (!data || data == 0xffffffffU) {
			return 0;
		}

		if (PCIE_CONF_EXT_CAP_ID(data) == cap_id) {
			break;
		}

		reg = PCIE_CONF_EXT_CAP_NEXT(data) >> 2;

		if (reg < PCIE_CONF_EXT_CAPPTR) {
			return 0;
		}
	}

	return reg;
}

/**
 * @brief Get the BAR at a specific BAR index
 *
 * @param bdf the PCI(e) endpoint
 * @param bar_index 0-based BAR index
 * @param bar Pointer to struct pcie_bar
 * @param io true for I/O BARs, false otherwise
 * @return true if the BAR was found and is valid, false otherwise
 */
static bool pcie_get_bar(pcie_bdf_t bdf,
			 unsigned int bar_index,
			 struct pcie_bar *bar,
			 bool io)
{
	uint32_t reg = bar_index + PCIE_CONF_BAR0;
	uint32_t cmd_reg;
	bool ret = false;
#ifdef CONFIG_PCIE_CONTROLLER
	const struct device *dev;
#endif
	uintptr_t phys_addr;
	size_t size;

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

	if (reg > PCIE_CONF_BAR5) {
		return false;
	}

	phys_addr = pcie_conf_read(bdf, reg);
#ifndef CONFIG_PCIE_CONTROLLER
	if ((PCIE_CONF_BAR_MEM(phys_addr) && io) || (PCIE_CONF_BAR_IO(phys_addr) && !io)) {
		return false;
	}
#endif

	if (PCIE_CONF_BAR_INVAL_FLAGS(phys_addr)) {
		/* Discard on invalid flags */
		return false;
	}

	cmd_reg = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT);

	/* IO/memory decode should be disabled before sizing/update BAR. */
	pcie_conf_write(bdf, PCIE_CONF_CMDSTAT,
			cmd_reg & (~(PCIE_CONF_CMDSTAT_IO | PCIE_CONF_CMDSTAT_MEM)));

	pcie_conf_write(bdf, reg, 0xFFFFFFFFU);
	size = pcie_conf_read(bdf, reg);
	pcie_conf_write(bdf, reg, (uint32_t)phys_addr);

	if (IS_ENABLED(CONFIG_64BIT) && PCIE_CONF_BAR_64(phys_addr)) {
		reg++;
		phys_addr |= ((uint64_t)pcie_conf_read(bdf, reg)) << 32;

		if ((PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_INVAL64) ||
		    (PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_NONE)) {
			/* Discard on invalid address */
			goto err_exit;
		}

		pcie_conf_write(bdf, reg, 0xFFFFFFFFU);
		size |= ((uint64_t)pcie_conf_read(bdf, reg)) << 32;
		pcie_conf_write(bdf, reg, (uint32_t)((uint64_t)phys_addr >> 32));
	} else if ((PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_INVAL) ||
		   (PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_NONE)) {
		/* Discard on invalid address */
		goto err_exit;
	}

	if (PCIE_CONF_BAR_IO(phys_addr)) {
		size = PCIE_CONF_BAR_IO_ADDR(size);
		if (size == 0) {
			/* Discard on invalid size */
			goto err_exit;
		}
	} else {
		size = PCIE_CONF_BAR_ADDR(size);
		if (size == 0) {
			/* Discard on invalid size */
			goto err_exit;
		}
	}

#ifdef CONFIG_PCIE_CONTROLLER
	/* Translate to physical memory address from bus address */
	if (!pcie_ctrl_region_translate(dev, bdf, PCIE_CONF_BAR_MEM(phys_addr),
					PCIE_CONF_BAR_64(phys_addr),
					PCIE_CONF_BAR_MEM(phys_addr) ?
						PCIE_CONF_BAR_ADDR(phys_addr)
						: PCIE_CONF_BAR_IO_ADDR(phys_addr),
					&bar->phys_addr)) {
		goto err_exit;
	}
#else
	bar->phys_addr = PCIE_CONF_BAR_ADDR(phys_addr);
#endif /* CONFIG_PCIE_CONTROLLER */
	bar->size = size & ~(size-1);

	ret = true;
err_exit:
	pcie_conf_write(bdf, PCIE_CONF_CMDSTAT, cmd_reg);

	return ret;
}

/**
 * @brief Probe the nth BAR assigned to an endpoint.
 *
 * A PCI(e) endpoint has 0 or more BARs. This function
 * allows the caller to enumerate them by calling with index=0..n.
 * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
 * are order-preserving with respect to the endpoint BARs: e.g., index 0
 * will return the lowest-numbered BAR on the endpoint.
 *
 * @param bdf the PCI(e) endpoint
 * @param index (0-based) index
 * @param bar Pointer to struct pcie_bar
 * @param io true for I/O BARs, false otherwise
 * @return true if the BAR was found and is valid, false otherwise
 */
static bool pcie_probe_bar(pcie_bdf_t bdf,
			   unsigned int index,
			   struct pcie_bar *bar,
			   bool io)
{
	uint32_t reg;

	for (reg = PCIE_CONF_BAR0;
	     (index > 0) && (reg <= PCIE_CONF_BAR5); reg++, index--) {
		uintptr_t addr = pcie_conf_read(bdf, reg);

		if (PCIE_CONF_BAR_MEM(addr) && PCIE_CONF_BAR_64(addr)) {
			reg++;
		}
	}

	if (index != 0) {
		return false;
	}

	return pcie_get_bar(bdf, reg - PCIE_CONF_BAR0, bar, io);
}

bool pcie_get_mbar(pcie_bdf_t bdf,
		   unsigned int bar_index,
		   struct pcie_bar *mbar)
{
	return pcie_get_bar(bdf, bar_index, mbar, false);
}

bool pcie_probe_mbar(pcie_bdf_t bdf,
		     unsigned int index,
		     struct pcie_bar *mbar)
{
	return pcie_probe_bar(bdf, index, mbar, false);
}

bool pcie_get_iobar(pcie_bdf_t bdf,
		    unsigned int bar_index,
		    struct pcie_bar *iobar)
{
	return pcie_get_bar(bdf, bar_index, iobar, true);
}

bool pcie_probe_iobar(pcie_bdf_t bdf,
		      unsigned int index,
		      struct pcie_bar *iobar)
{
	return pcie_probe_bar(bdf, index, iobar, true);
}

#ifndef CONFIG_PCIE_CONTROLLER

unsigned int pcie_alloc_irq(pcie_bdf_t bdf)
{
	unsigned int irq;
	uint32_t data;

	data = pcie_conf_read(bdf, PCIE_CONF_INTR);
	irq = PCIE_CONF_INTR_IRQ(data);

	if ((irq == PCIE_CONF_INTR_IRQ_NONE) ||
	    (irq >= CONFIG_MAX_IRQ_LINES) ||
	    arch_irq_is_used(irq)) {

		/* In some platforms, PCI interrupts are hardwired to specific interrupt inputs
		 * on the interrupt controller and are not configurable. Hence we need to retrieve
		 * IRQ from acpi. But if it is configurable then we allocate irq dynamically.
		 */
#ifdef CONFIG_PCIE_PRT
		if (prt_en) {
			irq = acpi_legacy_irq_get(bdf);
		} else {
			irq = arch_irq_allocate();
		}
#else
		irq = arch_irq_allocate();
#endif

		if (irq == UINT_MAX) {
			return PCIE_CONF_INTR_IRQ_NONE;
		}

		data &= ~0xffU;
		data |= irq;
		pcie_conf_write(bdf, PCIE_CONF_INTR, data);
	} else {
		arch_irq_set_used(irq);
	}

	return irq;
}
#endif /* CONFIG_PCIE_CONTROLLER */

unsigned int pcie_get_irq(pcie_bdf_t bdf)
{
	uint32_t data = pcie_conf_read(bdf, PCIE_CONF_INTR);

	return PCIE_CONF_INTR_IRQ(data);
}

bool pcie_connect_dynamic_irq(pcie_bdf_t bdf,
			      unsigned int irq,
			      unsigned int priority,
			      void (*routine)(const void *parameter),
			      const void *parameter,
			      uint32_t flags)
{
#if defined(CONFIG_PCIE_MSI) && defined(CONFIG_PCIE_MSI_MULTI_VECTOR)
	if (pcie_is_msi(bdf)) {
		msi_vector_t vector;

		if ((pcie_msi_vectors_allocate(bdf, priority,
					       &vector, 1) == 0) ||
		    !pcie_msi_vector_connect(bdf, &vector,
					     routine, parameter, flags)) {
			return false;
		}
	} else
#endif /* CONFIG_PCIE_MSI && CONFIG_PCIE_MSI_MULTI_VECTOR */
	{
		if (irq_connect_dynamic(irq, priority, routine,
					parameter, flags) < 0) {
			return false;
		}
	}

	return true;
}

void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq)
{
#if CONFIG_PCIE_MSI
	if (pcie_msi_enable(bdf, NULL, 1, irq)) {
		return;
	}
#endif
	irq_enable(irq);
}

static bool scan_flag(const struct pcie_scan_opt *opt, uint32_t flag)
{
	return ((opt->flags & flag) != 0U);
}

/* Forward declaration needed since scanning a device may reveal a bridge */
static bool scan_bus(uint8_t bus, const struct pcie_scan_opt *opt);

static bool scan_dev(uint8_t bus, uint8_t dev, const struct pcie_scan_opt *opt)
{
	for (uint8_t func = 0; func <= PCIE_MAX_FUNC; func++) {
		pcie_bdf_t bdf = PCIE_BDF(bus, dev, func);
		uint32_t secondary = 0;
		uint32_t id, type;
		bool do_cb;

		id = pcie_conf_read(bdf, PCIE_CONF_ID);
		if (!PCIE_ID_IS_VALID(id)) {
			continue;
		}

		type = pcie_conf_read(bdf, PCIE_CONF_TYPE);
		switch (PCIE_CONF_TYPE_GET(type)) {
		case PCIE_CONF_TYPE_STANDARD:
			do_cb = true;
			break;
		case PCIE_CONF_TYPE_PCI_BRIDGE:
			if (scan_flag(opt, PCIE_SCAN_RECURSIVE)) {
				uint32_t num = pcie_conf_read(bdf,
							      PCIE_BUS_NUMBER);
				secondary = PCIE_BUS_SECONDARY_NUMBER(num);
			}
			__fallthrough;
		default:
			do_cb = scan_flag(opt, PCIE_SCAN_CB_ALL);
			break;
		}

		if (do_cb && !opt->cb(bdf, id, opt->cb_data)) {
			return false;
		}

		if (scan_flag(opt, PCIE_SCAN_RECURSIVE) && secondary != 0) {
			if (!scan_bus(secondary, opt)) {
				return false;
			}
		}

		/* Only function 0 is valid for non-multifunction devices */
		if (func == 0 && !PCIE_CONF_MULTIFUNCTION(type)) {
			break;
		}
	}

	return true;
}

static bool scan_bus(uint8_t bus, const struct pcie_scan_opt *opt)
{
	for (uint8_t dev = 0; dev <= PCIE_MAX_DEV; dev++) {
		if (!scan_dev(bus, dev, opt)) {
			return false;
		}
	}

	return true;
}

int pcie_scan(const struct pcie_scan_opt *opt)
{
	uint32_t type;
	bool multi;

	CHECKIF(opt->cb == NULL) {
		return -EINVAL;
	}

	type = pcie_conf_read(PCIE_HOST_CONTROLLER(0), PCIE_CONF_TYPE);
	multi = PCIE_CONF_MULTIFUNCTION(type);
	if (opt->bus == 0 && scan_flag(opt, PCIE_SCAN_RECURSIVE) && multi) {
		/* Each function on the host controller represents a portential bus */
		for (uint8_t bus = 0; bus <= PCIE_MAX_FUNC; bus++) {
			pcie_bdf_t bdf = PCIE_HOST_CONTROLLER(bus);

			if (pcie_conf_read(bdf, PCIE_CONF_ID) == PCIE_ID_NONE) {
				continue;
			}

			if (!scan_bus(bus, opt)) {
				break;
			}
		}
	} else {
		/* Single PCI host controller */
		scan_bus(opt->bus, opt);
	}

	return 0;
}

struct scan_data {
	size_t found;
	size_t max_dev;
};

static bool pcie_dev_cb(pcie_bdf_t bdf, pcie_id_t id, void *cb_data)
{
	struct scan_data *data = cb_data;

	STRUCT_SECTION_FOREACH(pcie_dev, dev) {
		if (dev->bdf != PCIE_BDF_NONE) {
			continue;
		}

		if (dev->id != id) {
			continue;
		}

		uint32_t class_rev = pcie_conf_read(bdf, PCIE_CONF_CLASSREV);

		if (dev->class_rev == (class_rev & dev->class_rev_mask)) {
			dev->bdf = bdf;
			dev->class_rev = class_rev;
			data->found++;
			break;
		}
	}

	/* Continue if we've not yet found all devices */
	return (data->found != data->max_dev);
}

static int pcie_init(void)
{
	struct scan_data data;
	struct pcie_scan_opt opt = {
		.cb = pcie_dev_cb,
		.cb_data = &data,
		.flags = PCIE_SCAN_RECURSIVE,
	};

#ifdef CONFIG_PCIE_PRT
	const char *hid, *uid = ACPI_DT_UID(DT_DRV_INST(0));
	int ret;

	BUILD_ASSERT(ACPI_DT_HAS_HID(DT_DRV_INST(0)),
		 "No HID property for PCIe devicetree node");
	hid = ACPI_DT_HID(DT_DRV_INST(0));

	ret = acpi_legacy_irq_init(hid, uid);
	if (!ret) {
		prt_en = true;
	} else {
		__ASSERT(ret == -ENOENT, "Error retrieve interrupt routing table!");
	}
#endif

	STRUCT_SECTION_COUNT(pcie_dev, &data.max_dev);
	/* Don't bother calling pcie_scan() if there are no devices to look for */
	if (data.max_dev == 0) {
		return 0;
	}

	data.found = 0;

	pcie_scan(&opt);

	return 0;
}


/*
 * If a pcie controller is employed, pcie_scan() depends on it for working.
 * Thus, pcie must be bumped to the next level
 */
#ifdef CONFIG_PCIE_CONTROLLER
#define PCIE_SYS_INIT_LEVEL	PRE_KERNEL_2
#else
#define PCIE_SYS_INIT_LEVEL	PRE_KERNEL_1
#endif

SYS_INIT(pcie_init, PCIE_SYS_INIT_LEVEL, CONFIG_PCIE_INIT_PRIORITY);
