/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <acpi/acpi.h>
#include <arch/hpet.h>
#include <device/pci_ops.h>
#include <stdint.h>
#include <cpu/intel/model_2065x/model_2065x.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include "chip.h"
#include <commonlib/bsd/helpers.h>
#include "ironlake.h"
#include <cpu/intel/smm_reloc.h>

static int bridge_revision_id = -1;

int bridge_silicon_revision(void)
{
	if (bridge_revision_id < 0) {
		uint8_t stepping = cpuid_eax(1) & 0x0f;
		uint8_t bridge_id = pci_read_config16(pcidev_on_root(0, 0), PCI_DEVICE_ID);
		bridge_revision_id = (bridge_id & 0xf0) | stepping;
	}
	return bridge_revision_id;
}

/*
 * Reserve everything between A segment and 1MB:
 *
 * 0xa0000 - 0xbffff: legacy VGA
 * 0xc0000 - 0xcffff: VGA OPROM (needed by kernel)
 * 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI
 */

static void add_fixed_resources(struct device *dev, int index)
{
	/* 0xe0000000-0xf0000000 PCIe config.
	   0xfed10000-0xfed14000 MCH
	   0xfed17000-0xfed18000 HECI
	   0xfed18000-0xfed19000 DMI
	   0xfed19000-0xfed1a000 EPBAR
	   0xfed1c000-0xfed20000 RCBA
	   0xfed90000-0xfed94000 IOMMU
	   0xff800000-0xffffffff ROM. */

	mmio_range(dev, index++, HPET_BASE_ADDRESS, 0x00100000);
	mmio_from_to(dev, index++, 0xa0000, 0xc0000);
	reserved_ram_from_to(dev, index++, 0xc0000, 1 * MiB);
}

#if CONFIG(HAVE_ACPI_TABLES)
static const char *northbridge_acpi_name(const struct device *dev)
{
	if (dev->path.type == DEVICE_PATH_DOMAIN)
		return "PCI0";

	if (!is_pci_dev_on_bus(dev, 0))
		return NULL;

	switch (dev->path.pci.devfn) {
	case PCI_DEVFN(0, 0):
		return "MCHC";
	}

	return NULL;
}
#endif

struct device_operations ironlake_pci_domain_ops = {
	.read_resources	= pci_domain_read_resources,
	.set_resources	= pci_domain_set_resources,
	.scan_bus	= pci_domain_scan_bus,
#if CONFIG(HAVE_ACPI_TABLES)
	.acpi_name	= northbridge_acpi_name,
#endif
};

static void mc_read_resources(struct device *dev)
{
	uint32_t tseg_base, tseg_end;
	uint64_t touud;
	uint16_t reg16;
	int index = 3;

	pci_dev_read_resources(dev);

	mmconf_resource(dev, 0x50);

	tseg_base = pci_read_config32(pcidev_on_root(0, 0), TSEG);
	tseg_end = tseg_base + CONFIG_SMM_TSEG_SIZE;
	touud = pci_read_config16(pcidev_on_root(0, 0),
				  TOUUD);

	printk(BIOS_DEBUG, "ram_before_4g_top: 0x%x\n", tseg_base);
	printk(BIOS_DEBUG, "TOUUD: 0x%x\n", (unsigned int)touud);

	/* Report the memory regions */
	ram_range(dev, index++, 0, 0xa0000);
	ram_from_to(dev, index++, 1 * MiB, tseg_base);

	mmio_range(dev, index++, tseg_base, CONFIG_SMM_TSEG_SIZE);

	reg16 = pci_read_config16(pcidev_on_root(0, 0), GGC);
	const int uma_sizes_gtt[16] =
	    { 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 3, 4, 42, 42, 42, 42 };
	/* Igd memory */
	const int uma_sizes_igd[16] = {
		0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352, 256, 512
	};
	u32 igd_base, gtt_base;
	int uma_size_igd, uma_size_gtt;

	uma_size_igd = uma_sizes_igd[(reg16 >> 4) & 0xF];
	uma_size_gtt = uma_sizes_gtt[(reg16 >> 8) & 0xF];

	igd_base =
	    pci_read_config32(pcidev_on_root(0, 0), IGD_BASE);
	gtt_base =
	    pci_read_config32(pcidev_on_root(0, 0), GTT_BASE);
	if (gtt_base > tseg_end) {
		/* Reserve the gap. MMIO doesn't work in this range. Keep
		   it uncacheable, though, for easier MTRR allocation. */
		mmio_from_to(dev, index++, tseg_end, gtt_base);
	}
	mmio_range(dev, index++, gtt_base, uma_size_gtt * MiB);
	mmio_range(dev, index++, igd_base, uma_size_igd * MiB);

	upper_ram_end(dev, index++, touud * MiB);

	/* This memory is not DMA-capable. */
	if (touud >= 8192 - 64)
		bad_ram_range(dev, index++, 0x1fc000000ULL, 0x004000000);

	add_fixed_resources(dev, index);
}

static void northbridge_init(struct device *dev)
{
	/* Clear error status bits */
	dmibar_write32(DMIUESTS, 0xffffffff);
	dmibar_write32(DMICESTS, 0xffffffff);

	dmibar_setbits32(DMILLTC, 1 << 29);

	dmibar_setbits32(0x1f8, 1 << 16);

	dmibar_setbits32(DMILCTL, 1 << 1 | 1 << 0);
}

/* Disable unused PEG devices based on devicetree before PCI enumeration */
static void ironlake_init(void *const chip_info)
{
	u32 deven_mask = UINT32_MAX;
	const struct device *dev;

	dev = pcidev_on_root(1, 0);
	if (!dev || !dev->enabled) {
		printk(BIOS_DEBUG, "Disabling PEG10.\n");
		deven_mask &= ~DEVEN_PEG10;
	}
	dev = pcidev_on_root(2, 0);
	if (!dev || !dev->enabled) {
		printk(BIOS_DEBUG, "Disabling IGD.\n");
		deven_mask &= ~DEVEN_IGD;
	}
	const struct device *const d0f0 = pcidev_on_root(0, 0);
	if (d0f0)
		pci_update_config32(d0f0, DEVEN, deven_mask, 0);

}

static struct device_operations mc_ops = {
	.read_resources		= mc_read_resources,
	.set_resources		= pci_dev_set_resources,
	.enable_resources	= pci_dev_enable_resources,
	.init			= northbridge_init,
	.acpi_fill_ssdt		= generate_cpu_entries,
	.ops_pci		= &pci_dev_ops_pci,
};

/*
 * The host bridge PCI device ID can be changed by the firmware. There
 * is no documentation about it, though. There's 'official' IDs, which
 * appear in spec updates and Windows drivers, and 'mysterious' IDs,
 * which Intel doesn't want OSes to know about and thus are not listed.
 *
 * The current coreboot code seems to be able to change the device ID
 * of the host bridge, but it seems to be missing a warm reset so that
 * the device ID changes. Account for the 'mysterious' device IDs in
 * the northbridge driver, so that booting an OS has a chance to work.
 */
static const unsigned short pci_device_ids[] = {
	/* 'Official' DIDs */
	0x0040, /* Clarkdale */
	0x0044, /* Arrandale */
	0x0048, /* Unknown, but it appears in OS drivers and raminit */

	/* Mysterious DIDs, taken from Linux' intel-agp driver */
	0x0062, /* Arrandale A-? */
	0x0069, /* Clarkdale K-0 */
	0x006a, /* Arrandale K-0 */
	0
};

static const struct pci_driver mc_driver_ilk __pci_driver = {
	.ops     = &mc_ops,
	.vendor  = PCI_VID_INTEL,
	.devices = pci_device_ids,
};

struct device_operations ironlake_cpu_bus_ops = {
	.read_resources = noop_read_resources,
	.set_resources = noop_set_resources,
	.init = mp_cpu_bus_init,
};

struct chip_operations northbridge_intel_ironlake_ops = {
	CHIP_NAME("Intel Ironlake integrated Northbridge")
	.init = ironlake_init,
};
