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

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

#include <kernel.h>
#include <device.h>
#include <drivers/pcie/pcie.h>
#include <drivers/pcie/controller.h>
#ifdef CONFIG_GIC_V3_ITS
#include <drivers/interrupt_controller/gicv3_its.h>
#endif

#define DT_DRV_COMPAT pci_host_ecam_generic

/*
 * PCIe Controllers Regions
 *
 * TOFIX:
 * - handle prefetchable regions
 */
enum pcie_region_type {
	PCIE_REGION_IO = 0,
	PCIE_REGION_MEM,
	PCIE_REGION_MEM64,
	PCIE_REGION_MAX,
};

struct pcie_ecam_data {
	uintptr_t cfg_phys_addr;
	mm_reg_t cfg_addr;
	size_t cfg_size;
	struct {
		uintptr_t phys_start;
		uintptr_t bus_start;
		size_t size;
		size_t allocation_offset;
	} regions[PCIE_REGION_MAX];
};

static int pcie_ecam_init(const struct device *dev)
{
	const struct pcie_ctrl_config *cfg = dev->config;
	struct pcie_ecam_data *data = dev->data;
	int i;

	/*
	 * Flags defined in the PCI Bus Binding to IEEE Std 1275-1994 :
	 *           Bit# 33222222 22221111 11111100 00000000
	 *                10987654 32109876 54321098 76543210
	 *
	 * phys.hi cell:  npt000ss bbbbbbbb dddddfff rrrrrrrr
	 * phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
	 * phys.lo cell:  llllllll llllllll llllllll llllllll
	 *
	 * where:
	 *
	 * n	is 0 if the address is relocatable, 1 otherwise
	 * p	is 1 if the addressable region is "prefetchable", 0 otherwise
	 * t	is 1 if the address is aliased (for non-relocatable I/O), below 1 MB (for Memory),
	 *	or below 64 KB (for relocatable I/O).
	 * ss	is the space code, denoting the address space
	 *	00 denotes Configuration Space
	 *	01 denotes I/O Space
	 *	10 denotes 32-bit-address Memory Space
	 *	11 denotes 64-bit-address Memory Space
	 * bbbbbbbb	is the 8-bit Bus Number
	 * ddddd	is the 5-bit Device Number
	 * fff	is the 3-bit Function Number
	 * rrrrrrrr	is the 8-bit Register Number
	 * hh...hh	is a 32-bit unsigned number
	 * ll...ll	is a 32-bit unsigned number
	 *	for I/O Space is the 32-bit offset from the start of the region
	 *	for 32-bit-address Memory Space is the 32-bit offset from the start of the region
	 *	for 64-bit-address Memory Space is the 64-bit offset from the start of the region
	 *
	 * Here we only handle the p, ss, hh and ll fields.
	 *
	 * TOFIX:
	 * - handle prefetchable bit
	 */
	for (i = 0 ; i < cfg->ranges_count ; ++i) {
		switch ((cfg->ranges[i].flags >> 24) & 0x03) {
		case 0x01:
			data->regions[PCIE_REGION_IO].bus_start = cfg->ranges[i].pcie_bus_addr;
			data->regions[PCIE_REGION_IO].phys_start = cfg->ranges[i].host_map_addr;
			data->regions[PCIE_REGION_IO].size = cfg->ranges[i].map_length;
			/* Linux & U-Boot avoids allocating PCI resources from address 0 */
			if (data->regions[PCIE_REGION_IO].bus_start < 0x1000)
				data->regions[PCIE_REGION_IO].allocation_offset = 0x1000;
			break;
		case 0x02:
			data->regions[PCIE_REGION_MEM].bus_start = cfg->ranges[i].pcie_bus_addr;
			data->regions[PCIE_REGION_MEM].phys_start = cfg->ranges[i].host_map_addr;
			data->regions[PCIE_REGION_MEM].size = cfg->ranges[i].map_length;
			/* Linux & U-Boot avoids allocating PCI resources from address 0 */
			if (data->regions[PCIE_REGION_MEM].bus_start < 0x1000)
				data->regions[PCIE_REGION_MEM].allocation_offset = 0x1000;
			break;
		case 0x03:
			data->regions[PCIE_REGION_MEM64].bus_start = cfg->ranges[i].pcie_bus_addr;
			data->regions[PCIE_REGION_MEM64].phys_start = cfg->ranges[i].host_map_addr;
			data->regions[PCIE_REGION_MEM64].size = cfg->ranges[i].map_length;
			/* Linux & U-Boot avoids allocating PCI resources from address 0 */
			if (data->regions[PCIE_REGION_MEM64].bus_start < 0x1000)
				data->regions[PCIE_REGION_MEM64].allocation_offset = 0x1000;
			break;
		}
	}

	if (!data->regions[PCIE_REGION_IO].size &&
	    !data->regions[PCIE_REGION_MEM].size &&
	    !data->regions[PCIE_REGION_MEM64].size) {
		LOG_ERR("No regions defined");
		return -EINVAL;
	}

	/* Get Config address space physical address & size */
	data->cfg_phys_addr = cfg->cfg_addr;
	data->cfg_size = cfg->cfg_size;

	if (data->regions[PCIE_REGION_IO].size) {
		LOG_DBG("IO bus [0x%lx - 0x%lx, size 0x%lx]",
			data->regions[PCIE_REGION_IO].bus_start,
			(data->regions[PCIE_REGION_IO].bus_start +
			 data->regions[PCIE_REGION_IO].size - 1),
			data->regions[PCIE_REGION_IO].size);
		LOG_DBG("IO space [0x%lx - 0x%lx, size 0x%lx]",
			data->regions[PCIE_REGION_IO].phys_start,
			(data->regions[PCIE_REGION_IO].phys_start +
			 data->regions[PCIE_REGION_IO].size - 1),
			data->regions[PCIE_REGION_IO].size);
	}
	if (data->regions[PCIE_REGION_MEM].size) {
		LOG_DBG("MEM bus [0x%lx - 0x%lx, size 0x%lx]",
			data->regions[PCIE_REGION_MEM].bus_start,
			(data->regions[PCIE_REGION_MEM].bus_start +
			 data->regions[PCIE_REGION_MEM].size - 1),
			data->regions[PCIE_REGION_MEM].size);
		LOG_DBG("MEM space [0x%lx - 0x%lx, size 0x%lx]",
			data->regions[PCIE_REGION_MEM].phys_start,
			(data->regions[PCIE_REGION_MEM].phys_start +
			 data->regions[PCIE_REGION_MEM].size - 1),
			data->regions[PCIE_REGION_MEM].size);
	}
	if (data->regions[PCIE_REGION_MEM64].size) {
		LOG_DBG("MEM64 bus [0x%lx - 0x%lx, size 0x%lx]",
			data->regions[PCIE_REGION_MEM64].bus_start,
			(data->regions[PCIE_REGION_MEM64].bus_start +
			 data->regions[PCIE_REGION_MEM64].size - 1),
			data->regions[PCIE_REGION_MEM64].size);
		LOG_DBG("MEM64 space [0x%lx - 0x%lx, size 0x%lx]",
			data->regions[PCIE_REGION_MEM64].phys_start,
			(data->regions[PCIE_REGION_MEM64].phys_start +
			 data->regions[PCIE_REGION_MEM64].size - 1),
			data->regions[PCIE_REGION_MEM64].size);
	}

	/* Map config space to be used by the pcie_generic_ctrl_conf_read/write callbacks */
	device_map(&data->cfg_addr, data->cfg_phys_addr, data->cfg_size, K_MEM_CACHE_NONE);

	LOG_DBG("Config space [0x%lx - 0x%lx, size 0x%lx]",
		data->cfg_phys_addr, (data->cfg_phys_addr + data->cfg_size - 1), data->cfg_size);
	LOG_DBG("Config mapped [0x%lx - 0x%lx, size 0x%lx]",
		data->cfg_addr, (data->cfg_addr + data->cfg_size - 1), data->cfg_size);

	pcie_generic_ctrl_enumerate(dev, PCIE_BDF(0, 0, 0));

	return 0;
}

static uint32_t pcie_ecam_ctrl_conf_read(const struct device *dev, pcie_bdf_t bdf, unsigned int reg)
{
	struct pcie_ecam_data *data = dev->data;

	return pcie_generic_ctrl_conf_read(data->cfg_addr, bdf, reg);
}

static void pcie_ecam_ctrl_conf_write(const struct device *dev, pcie_bdf_t bdf, unsigned int reg,
				      uint32_t reg_data)
{
	struct pcie_ecam_data *data = dev->data;

	pcie_generic_ctrl_conf_write(data->cfg_addr, bdf, reg, reg_data);
}

static bool pcie_ecam_region_allocate_type(struct pcie_ecam_data *data, pcie_bdf_t bdf,
					   size_t bar_size, uintptr_t *bar_bus_addr,
					   enum pcie_region_type type)
{
	uintptr_t addr;

	addr = (((data->regions[type].bus_start + data->regions[type].allocation_offset) - 1) |
		((bar_size) - 1)) + 1;

	if (addr - data->regions[type].bus_start + bar_size > data->regions[type].size)
		return false;

	*bar_bus_addr = addr;
	data->regions[type].allocation_offset = addr - data->regions[type].bus_start + bar_size;

	return true;
}

static bool pcie_ecam_region_allocate(const struct device *dev, pcie_bdf_t bdf,
				      bool mem, bool mem64, size_t bar_size,
				      uintptr_t *bar_bus_addr)
{
	struct pcie_ecam_data *data = dev->data;
	enum pcie_region_type type;

	if (mem && !data->regions[PCIE_REGION_MEM64].size &&
	    !data->regions[PCIE_REGION_MEM].size) {
		LOG_DBG("bdf %x no mem region defined for allocation", bdf);
		return false;
	}

	if (!mem && !data->regions[PCIE_REGION_IO].size) {
		LOG_DBG("bdf %x no io region defined for allocation", bdf);
		return false;
	}

	/*
	 * Allocate into mem64 region if available or is the only available
	 *
	 * TOFIX:
	 * - handle allocation from/to mem/mem64 when a region is full
	 */
	if (mem && ((mem64 && data->regions[PCIE_REGION_MEM64].size) ||
		    (data->regions[PCIE_REGION_MEM64].size &&
		     !data->regions[PCIE_REGION_MEM].size))) {
		type = PCIE_REGION_MEM64;
	} else if (mem) {
		type = PCIE_REGION_MEM;
	} else {
		type = PCIE_REGION_IO;
	}

	return pcie_ecam_region_allocate_type(data, bdf, bar_size, bar_bus_addr, type);
}

static bool pcie_ecam_region_get_allocate_base(const struct device *dev, pcie_bdf_t bdf,
					       bool mem, bool mem64, size_t align,
					       uintptr_t *bar_base_addr)
{
	struct pcie_ecam_data *data = (struct pcie_ecam_data *)dev->data;
	enum pcie_region_type type;

	if (mem && !data->regions[PCIE_REGION_MEM64].size &&
	    !data->regions[PCIE_REGION_MEM].size) {
		LOG_DBG("bdf %x no mem region defined for allocation", bdf);
		return false;
	}

	if (!mem && !data->regions[PCIE_REGION_IO].size) {
		LOG_DBG("bdf %x no io region defined for allocation", bdf);
		return false;
	}

	/*
	 * Allocate into mem64 region if available or is the only available
	 *
	 * TOFIX:
	 * - handle allocation from/to mem/mem64 when a region is full
	 */
	if (mem && ((mem64 && data->regions[PCIE_REGION_MEM64].size) ||
		    (data->regions[PCIE_REGION_MEM64].size &&
		     !data->regions[PCIE_REGION_MEM].size))) {
		type = PCIE_REGION_MEM64;
	} else if (mem) {
		type = PCIE_REGION_MEM;
	} else {
		type = PCIE_REGION_IO;
	}

	*bar_base_addr = (((data->regions[type].bus_start +
			    data->regions[type].allocation_offset) - 1) | ((align) - 1)) + 1;

	return true;
}

static bool pcie_ecam_region_translate(const struct device *dev, pcie_bdf_t bdf,
				       bool mem, bool mem64, uintptr_t bar_bus_addr,
				       uintptr_t *bar_addr)
{
	struct pcie_ecam_data *data = dev->data;
	enum pcie_region_type type;

	/* Means it hasn't been allocated */
	if (!bar_bus_addr)
		return false;

	if (mem && ((mem64 && data->regions[PCIE_REGION_MEM64].size) ||
		    (data->regions[PCIE_REGION_MEM64].size &&
		     !data->regions[PCIE_REGION_MEM].size))) {
		type = PCIE_REGION_MEM64;
	} else if (mem) {
		type = PCIE_REGION_MEM;
	} else {
		type = PCIE_REGION_IO;
	}

	*bar_addr = data->regions[type].phys_start + (bar_bus_addr - data->regions[type].bus_start);

	return true;
}

#if CONFIG_PCIE_MSI
static uint8_t pcie_ecam_msi_device_setup(const struct device *dev, unsigned int priority,
					  msi_vector_t *vectors, uint8_t n_vector)
{
#ifdef CONFIG_GIC_V3_ITS
	const struct pcie_ctrl_config *cfg = (const struct pcie_ctrl_config *)dev->config;
	unsigned int device_id;
	pcie_bdf_t bdf;
	int ret, i;

	if (!n_vector) {
		return 0;
	}

	bdf = vectors[0].bdf;

	/* We do not support allocating vectors for multiple BDFs for now,
	 * This would need tracking vectors already allocated for a BDF and
	 * re-allocating a proper table in ITS for each BDF since we can't be
	 * sure more vectors for each BDF will be allocated later.
	 * Simply bail-out if it's the case here.
	 */
	for (i = 1; i < n_vector; i++) {
		if (vectors[i].bdf != bdf) {
			LOG_ERR("Multiple BDFs in a single MSI vector allocation isn't supported");
			return 0;
		}
	}

	device_id = PCI_BDF_TO_DEVID(bdf);

	ret = its_setup_deviceid(cfg->msi_parent, device_id, n_vector);
	if (ret) {
		return 0;
	}

	for (i = 0; i < n_vector; i++) {
		vectors[i].arch.irq = its_alloc_intid(cfg->msi_parent);
		vectors[i].arch.address = its_get_msi_addr(cfg->msi_parent);
		vectors[i].arch.eventid = i;
		vectors[i].arch.priority = priority;

		ret = its_map_intid(cfg->msi_parent, device_id,
				    vectors[i].arch.eventid, vectors[i].arch.irq);
		if (ret) {
			break;
		}
	}

	return i;
#else
	return 0;
#endif
}
#endif

static const struct pcie_ctrl_driver_api pcie_ecam_api = {
	.conf_read = pcie_ecam_ctrl_conf_read,
	.conf_write = pcie_ecam_ctrl_conf_write,
	.region_allocate = pcie_ecam_region_allocate,
	.region_get_allocate_base = pcie_ecam_region_get_allocate_base,
	.region_translate = pcie_ecam_region_translate,
#if CONFIG_PCIE_MSI
	.msi_device_setup = pcie_ecam_msi_device_setup,
#endif
};

#if CONFIG_PCIE_MSI
#define DEVICE_DT_GET_MSI_PARENT(n)						\
	.msi_parent = DEVICE_DT_GET(DT_PHANDLE(DT_DRV_INST(n), msi_parent)),
#else
#define DEVICE_DT_GET_MSI_PARENT(n)
#endif

#define PCIE_ECAM_INIT(n)							\
	static struct pcie_ecam_data pcie_ecam_data##n;				\
	static const struct pcie_ctrl_config pcie_ecam_config##n = {		\
		DEVICE_DT_GET_MSI_PARENT(n)					\
		.cfg_addr = DT_INST_REG_ADDR(n),				\
		.cfg_size = DT_INST_REG_SIZE(n),				\
		.ranges_count = DT_NUM_RANGES(DT_DRV_INST(n)),		\
		.ranges = {							\
			DT_FOREACH_RANGE(DT_DRV_INST(n), PCIE_RANGE_FORMAT)	\
		},								\
	};									\
	DEVICE_DT_INST_DEFINE(n, &pcie_ecam_init, NULL,				\
			      &pcie_ecam_data##n,				\
			      &pcie_ecam_config##n,				\
			      PRE_KERNEL_1,					\
			      CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,		\
			      &pcie_ecam_api);

DT_INST_FOREACH_STATUS_OKAY(PCIE_ECAM_INIT)
