// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
 */
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/pci-acpi.h>
#include <linux/pci-ecam.h>

#include <asm/pci.h>
#include <asm/numa.h>
#include <asm/loongson.h>

struct pci_root_info {
	struct acpi_pci_root_info common;
	struct pci_config_window *cfg;
};

void pcibios_add_bus(struct pci_bus *bus)
{
	acpi_pci_add_bus(bus);
}

int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
{
	struct acpi_device *adev = NULL;
	struct device *bus_dev = &bridge->bus->dev;
	struct pci_config_window *cfg = bridge->bus->sysdata;

	if (!acpi_disabled)
		adev = to_acpi_device(cfg->parent);

	ACPI_COMPANION_SET(&bridge->dev, adev);
	set_dev_node(bus_dev, pa_to_nid(cfg->res.start));

	return 0;
}

int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
{
	struct pci_config_window *cfg = bus->sysdata;
	struct acpi_device *adev = to_acpi_device(cfg->parent);
	struct acpi_pci_root *root = acpi_driver_data(adev);

	return root->segment;
}

static void acpi_release_root_info(struct acpi_pci_root_info *ci)
{
	struct pci_root_info *info;

	info = container_of(ci, struct pci_root_info, common);
	pci_ecam_free(info->cfg);
	kfree(ci->ops);
	kfree(info);
}

static int acpi_prepare_root_resources(struct acpi_pci_root_info *ci)
{
	int status;
	struct resource_entry *entry, *tmp;
	struct acpi_device *device = ci->bridge;

	status = acpi_pci_probe_root_resources(ci);
	if (status > 0) {
		resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
			if (entry->res->flags & IORESOURCE_MEM) {
				entry->offset = ci->root->mcfg_addr & GENMASK_ULL(63, 40);
				entry->res->start |= entry->offset;
				entry->res->end   |= entry->offset;
			}
		}
		return status;
	}

	resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
		dev_dbg(&device->dev,
			   "host bridge window %pR (ignored)\n", entry->res);
		resource_list_destroy_entry(entry);
	}

	return 0;
}

/*
 * Create a PCI config space window
 *  - reserve mem region
 *  - alloc struct pci_config_window with space for all mappings
 *  - ioremap the config space
 */
static struct pci_config_window *arch_pci_ecam_create(struct device *dev,
		struct resource *cfgres, struct resource *busr, const struct pci_ecam_ops *ops)
{
	int bsz, bus_range, err;
	struct resource *conflict;
	struct pci_config_window *cfg;

	if (busr->start > busr->end)
		return ERR_PTR(-EINVAL);

	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
	if (!cfg)
		return ERR_PTR(-ENOMEM);

	cfg->parent = dev;
	cfg->ops = ops;
	cfg->busr.start = busr->start;
	cfg->busr.end = busr->end;
	cfg->busr.flags = IORESOURCE_BUS;
	bus_range = resource_size(cfgres) >> ops->bus_shift;

	bsz = 1 << ops->bus_shift;

	cfg->res.start = cfgres->start;
	cfg->res.end = cfgres->end;
	cfg->res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
	cfg->res.name = "PCI ECAM";

	conflict = request_resource_conflict(&iomem_resource, &cfg->res);
	if (conflict) {
		err = -EBUSY;
		dev_err(dev, "can't claim ECAM area %pR: address conflict with %s %pR\n",
			&cfg->res, conflict->name, conflict);
		goto err_exit;
	}

	cfg->win = pci_remap_cfgspace(cfgres->start, bus_range * bsz);
	if (!cfg->win)
		goto err_exit_iomap;

	if (ops->init) {
		err = ops->init(cfg);
		if (err)
			goto err_exit;
	}
	dev_info(dev, "ECAM at %pR for %pR\n", &cfg->res, &cfg->busr);

	return cfg;

err_exit_iomap:
	err = -ENOMEM;
	dev_err(dev, "ECAM ioremap failed\n");
err_exit:
	pci_ecam_free(cfg);
	return ERR_PTR(err);
}

/*
 * Lookup the bus range for the domain in MCFG, and set up config space
 * mapping.
 */
static struct pci_config_window *
pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
{
	int ret, bus_shift;
	u16 seg = root->segment;
	struct device *dev = &root->device->dev;
	struct resource cfgres;
	struct resource *bus_res = &root->secondary;
	struct pci_config_window *cfg;
	const struct pci_ecam_ops *ecam_ops;

	ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops);
	if (ret < 0) {
		dev_err(dev, "%04x:%pR ECAM region not found, use default value\n", seg, bus_res);
		ecam_ops = &loongson_pci_ecam_ops;
		root->mcfg_addr = mcfg_addr_init(0);
	}

	bus_shift = ecam_ops->bus_shift ? : 20;

	if (bus_shift == 20)
		cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops);
	else {
		cfgres.start = root->mcfg_addr + (bus_res->start << bus_shift);
		cfgres.end = cfgres.start + (resource_size(bus_res) << bus_shift) - 1;
		cfgres.end |= BIT(28) + (((PCI_CFG_SPACE_EXP_SIZE - 1) & 0xf00) << 16);
		cfgres.flags = IORESOURCE_MEM;
		cfg = arch_pci_ecam_create(dev, &cfgres, bus_res, ecam_ops);
	}

	if (IS_ERR(cfg)) {
		dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res, PTR_ERR(cfg));
		return NULL;
	}

	return cfg;
}

struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
	struct pci_bus *bus;
	struct pci_root_info *info;
	struct acpi_pci_root_ops *root_ops;
	int domain = root->segment;
	int busnum = root->secondary.start;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		pr_warn("pci_bus %04x:%02x: ignored (out of memory)\n", domain, busnum);
		return NULL;
	}

	root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL);
	if (!root_ops) {
		kfree(info);
		return NULL;
	}

	info->cfg = pci_acpi_setup_ecam_mapping(root);
	if (!info->cfg) {
		kfree(info);
		kfree(root_ops);
		return NULL;
	}

	root_ops->release_info = acpi_release_root_info;
	root_ops->prepare_resources = acpi_prepare_root_resources;
	root_ops->pci_ops = (struct pci_ops *)&info->cfg->ops->pci_ops;

	bus = pci_find_bus(domain, busnum);
	if (bus) {
		memcpy(bus->sysdata, info->cfg, sizeof(struct pci_config_window));
		kfree(info);
		kfree(root_ops);
	} else {
		struct pci_bus *child;

		bus = acpi_pci_root_create(root, root_ops,
					   &info->common, info->cfg);
		if (!bus) {
			kfree(info);
			kfree(root_ops);
			return NULL;
		}

		pci_bus_size_bridges(bus);
		pci_bus_assign_resources(bus);
		list_for_each_entry(child, &bus->children, node)
			pcie_bus_configure_settings(child);
	}

	return bus;
}
