/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <acpi/acpigen_pci.h>
#include <assert.h>
#include <console/console.h>
#include <device/pci.h>
#include <intelblocks/acpi.h>
#include <soc/acpi.h>
#include <soc/chip_common.h>
#include <soc/soc_util.h>
#include <soc/util.h>
#include <stdlib.h>

/**
 * Find all device of a given vendor and type for the specified socket.
 * The function iterates over all PCI domains of the specified socket
 * and matches the PCI vendor and device ID.
 *
 * @param socket The socket where to search for the device.
 * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
 * @param device A PCI device ID.
 * @param from The device pointer to start search from.
 *
 * @return Pointer to the device struct. When there are multiple device
 * instances, the caller should continue search upon a non-NULL match.
 */
struct device *dev_find_all_devices_on_socket(uint8_t socket, u16 vendor, u16 device,
	struct device *from)
{
	return dev_find_all_devices_on_stack(socket, XEONSP_STACK_MAX, vendor, device, from);
}

/*
 * Find device of a given vendor and type for the specified socket.
 * The function will return at the 1st match.
 */
struct device *dev_find_device_on_socket(uint8_t socket, u16 vendor, u16 device)
{
	return dev_find_all_devices_on_socket(socket, vendor, device, NULL);
}

static int filter_device_on_stack(struct device *dev, uint8_t socket, uint8_t stack,
	u16 vendor, u16 device)
{
	struct device *domain = dev_get_pci_domain(dev);
	if (!domain)
		return 0;
	if (dev->path.type != DEVICE_PATH_PCI)
		return 0;

	union xeon_domain_path dn;
	dn.domain_path = domain->path.domain.domain;

	if (socket != XEONSP_SOCKET_MAX && dn.socket != socket)
		return 0;
	if (stack != XEONSP_STACK_MAX && dn.stack != stack)
		return 0;
	if (vendor != XEONSP_VENDOR_MAX && dev->vendor != vendor)
		return 0;
	if (device != XEONSP_DEVICE_MAX && dev->device != device)
		return 0;

	return 1;
};

/**
 * Find all device of a given vendor and type for the specified socket and stack.
 *
 * @param socket The socket where to search for the device.
 *              XEONSP_SOCKET_MAX indicates any socket.
 * @param stack The stack where to search for the device.
 *              XEONSP_STACK_MAX indicates any stack.
 * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel).
 *              XEONSP_VENDOR_MAX indicates any vendor.
 * @param device A PCI device ID.
 *              XEONSP_DEVICE_MAX indicates any device.
 * @param from The device pointer to start search from.
 *
 * @return Pointer to the device struct. When there are multiple device
 * instances, the caller should continue search upon a non-NULL match.
 */
struct device *dev_find_all_devices_on_stack(uint8_t socket, uint8_t stack,
	u16 vendor, u16 device, struct device *from)
{
	if (!from)
		from = all_devices;
	else
		from = from->next;

	while (from && (!filter_device_on_stack(from, socket, stack,
		vendor, device)))
		from = from->next;

	return from;
}

/**
 * Find all device of a given vendor and type for the specific domain
 * Only the direct child of the input domain is iterated
 *
 * @param domain Pointer to the input domain
 * @param vendor A PCI vendor ID
 *              XEONSP_VENDOR_MAX indicates any vendor
 * @param vendor A PCI device ID
 *              XEONSP_DEVICE_MAX indicates any vendor
 * @param from The device pointer to start search from.
 *
 * @return Pointer to the device struct. When there are multiple device
 * instances, the caller should continue search upon a non-NULL match.
 */
struct device *dev_find_all_devices_on_domain(struct device *domain, u16 vendor,
	u16 device, struct device *from)
{
	struct device *dev = from;
	while ((dev = dev_bus_each_child(domain->downstream, dev))) {
		if (vendor != XEONSP_VENDOR_MAX && dev->vendor != vendor)
			continue;
		if (device != XEONSP_DEVICE_MAX && dev->device != device)
			continue;
		break;
	}

	return dev;
}

/**
 * Returns the socket ID where the specified device is connected to.
 * This is an integer in the range [0, CONFIG_MAX_SOCKET).
 *
 * @param dev The device to look up
 *
 * @return Socket ID the device is attached to, negative number on error.
 */
int iio_pci_domain_socket_from_dev(struct device *dev)
{
	struct device *domain;
	union xeon_domain_path dn;

	if (dev->path.type == DEVICE_PATH_DOMAIN)
		domain = dev;
	else
		domain = dev_get_pci_domain(dev);

	if (!domain)
		return -1;

	dn.domain_path = domain->path.domain.domain;

	return dn.socket;
}

/**
 * Returns the stack ID where the specified device is connected to.
 * This is an integer in the range [0, MAX_IIO_STACK).
 *
 * @param dev The device to look up
 *
 * @return Stack ID the device is attached to, negative number on error.
 */
int iio_pci_domain_stack_from_dev(struct device *dev)
{
	struct device *domain;
	union xeon_domain_path dn;

	if (dev->path.type == DEVICE_PATH_DOMAIN)
		domain = dev;
	else
		domain = dev_get_pci_domain(dev);

	if (!domain)
		return -1;

	dn.domain_path = domain->path.domain.domain;

	return dn.stack;
}

void create_domain(const union xeon_domain_path dp, struct bus *upstream,
			       int bus_base, int bus_limit, const char *type,
			       struct device_operations *ops,
			       const size_t pci_segment_group)
{
	struct device_path path;
	init_xeon_domain_path(&path, dp.socket, dp.stack, bus_base);

	struct device *const domain = alloc_find_dev(upstream, &path);
	if (!domain)
		die("%s: out of memory.\n", __func__);

	domain->ops = ops;
	iio_domain_set_acpi_name(domain, type);

	struct bus *const bus = alloc_bus(domain);
	bus->secondary = bus_base;
	bus->subordinate = bus_base;
	bus->max_subordinate = bus_limit;
	bus->segment_group = pci_segment_group;
}

/* Attach stack as domains */
void attach_iio_stacks(void)
{
	const IIO_UDS *hob = get_iio_uds();
	union xeon_domain_path dn = { .domain_path = 0 };
	if (!hob)
		return;

	struct bus *root_bus = dev_root.downstream;
	for (int s = 0; s < CONFIG_MAX_SOCKET; ++s) {
		if (!soc_cpu_is_enabled(s))
			continue;
		for (int x = 0; x < MAX_LOGIC_IIO_STACK; ++x) {
			const xSTACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x];
			const size_t seg = hob->PlatformData.CpuQpiInfo[s].PcieSegment;

			if (ri->BusBase > ri->BusLimit)
				continue;

			/* Prepare domain path */
			dn.socket = s;
			dn.stack = x;

			create_xeonsp_domains(dn, root_bus, ri, seg);
		}
	}
}

bool is_pcie_domain(struct device *dev)
{
	if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
		return false;

	return strstr(dev->name, DOMAIN_TYPE_PCIE);
}

bool is_ioat_domain(struct device *dev)
{
	if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
		return false;

	return (strstr(dev->name, DOMAIN_TYPE_CPM0) ||
		strstr(dev->name, DOMAIN_TYPE_CPM1) ||
		strstr(dev->name, DOMAIN_TYPE_DINO) ||
		strstr(dev->name, DOMAIN_TYPE_HQM0) ||
		strstr(dev->name, DOMAIN_TYPE_HQM1));
}

bool is_ubox_domain(struct device *dev)
{
	if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
		return false;

	return (strstr(dev->name, DOMAIN_TYPE_UBX0) ||
		strstr(dev->name, DOMAIN_TYPE_UBX1));
}

bool is_cxl_domain(struct device *dev)
{
	if ((!dev) || (dev->path.type != DEVICE_PATH_DOMAIN))
		return false;

	return strstr(dev->name, DOMAIN_TYPE_CXL);
}
