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

#include <commonlib/helpers.h>
#include <console/console.h>
#include <acpi/acpi.h>
#include <delay.h>
#include <cpu/intel/haswell/haswell.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <boot/tables.h>
#include <security/intel/txt/txt_register.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include <types.h>

#include "chip.h"
#include "haswell.h"

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;
}

struct device_operations haswell_pci_domain_ops = {
	.read_resources    = pci_domain_read_resources,
	.set_resources     = pci_domain_set_resources,
	.scan_bus          = pci_host_bridge_scan_bus,
	.acpi_name         = northbridge_acpi_name,
	.write_acpi_tables = northbridge_write_acpi_tables,
};

static int get_bar(struct device *dev, unsigned int index, u32 *base, u32 *len)
{
	u32 bar = pci_read_config32(dev, index);

	/* If not enabled don't report it */
	if (!(bar & 0x1))
		return 0;

	/* Knock down the enable bit */
	*base = bar & ~1;

	return 1;
}

/*
 * There are special BARs that actually are programmed in the MCHBAR. These Intel special
 * features, but they do consume resources that need to be accounted for.
 */
static int get_bar_in_mchbar(struct device *dev, unsigned int index, u32 *base, u32 *len)
{
	u32 bar = mchbar_read32(index);

	/* If not enabled don't report it */
	if (!(bar & 0x1))
		return 0;

	/* Knock down the enable bit */
	*base = bar & ~1;

	return 1;
}

struct fixed_mmio_descriptor {
	unsigned int index;
	u32 size;
	int (*get_resource)(struct device *dev, unsigned int index, u32 *base, u32 *size);
	const char *description;
};

struct fixed_mmio_descriptor mc_fixed_resources[] = {
	{ MCHBAR,   MCH_BASE_SIZE,   get_bar,           "MCHBAR"   },
	{ DMIBAR,   DMI_BASE_SIZE,   get_bar,           "DMIBAR"   },
	{ EPBAR,    EP_BASE_SIZE,    get_bar,           "EPBAR"    },
	{ GDXCBAR,  GDXC_BASE_SIZE,  get_bar_in_mchbar, "GDXCBAR"  },
	{ EDRAMBAR, EDRAM_BASE_SIZE, get_bar_in_mchbar, "EDRAMBAR" },
};

/* Add all known fixed MMIO ranges that hang off the host bridge/memory controller device. */
static void mc_add_fixed_mmio_resources(struct device *dev)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(mc_fixed_resources); i++) {
		u32 base;
		u32 size;
		unsigned int index;

		size = mc_fixed_resources[i].size;
		index = mc_fixed_resources[i].index;
		if (!mc_fixed_resources[i].get_resource(dev, index, &base, &size))
			continue;

		mmio_range(dev, mc_fixed_resources[i].index, base, size);
		printk(BIOS_DEBUG, "%s: Adding %s @ %x 0x%08lx-0x%08lx.\n",
		       __func__, mc_fixed_resources[i].description, index,
		       (unsigned long)base, (unsigned long)(base + size - 1));
	}

	mmconf_resource(dev, PCIEXBAR);
}

/*
 * Host Memory Map:
 *
 * +--------------------------+ TOUUD
 * |                          |
 * +--------------------------+ 4GiB
 * |     PCI Address Space    |
 * +--------------------------+ TOLUD (also maps into MC address space)
 * |     iGD                  |
 * +--------------------------+ BDSM
 * |     GTT                  |
 * +--------------------------+ BGSM
 * |     TSEG                 |
 * +--------------------------+ TSEGMB
 * |     DPR                  |
 * +--------------------------+ (DPR top - DPR size)
 * |     Usage DRAM           |
 * +--------------------------+ 0
 *
 * Some of the base registers above can be equal, making the size of the regions within 0.
 * This is because the memory controller internally subtracts the base registers from each
 * other to determine sizes of the regions. In other words, the memory map regions are always
 * in a fixed order, no matter what sizes they have.
 */

struct map_entry {
	int reg;
	int is_64_bit;
	int is_limit;
	const char *description;
};

static void read_map_entry(struct device *dev, struct map_entry *entry, uint64_t *result)
{
	uint64_t value;
	uint64_t mask;

	/* All registers have a 1MiB granularity */
	mask = ((1ULL << 20) - 1);
	mask = ~mask;

	value = 0;

	if (entry->is_64_bit) {
		value = pci_read_config32(dev, entry->reg + 4);
		value <<= 32;
	}

	value |= pci_read_config32(dev, entry->reg);
	value &= mask;

	if (entry->is_limit)
		value |= ~mask;

	*result = value;
}

#define MAP_ENTRY(reg_, is_64_, is_limit_, desc_) \
	{ \
		.reg = reg_,           \
		.is_64_bit = is_64_,   \
		.is_limit = is_limit_, \
		.description = desc_,  \
	}

#define MAP_ENTRY_BASE_32(reg_, desc_)	MAP_ENTRY(reg_, 0, 0, desc_)
#define MAP_ENTRY_BASE_64(reg_, desc_)	MAP_ENTRY(reg_, 1, 0, desc_)
#define MAP_ENTRY_LIMIT_64(reg_, desc_)	MAP_ENTRY(reg_, 1, 1, desc_)

enum {
	TOM_REG,
	TOUUD_REG,
	MESEG_BASE_REG,
	MESEG_LIMIT_REG,
	REMAP_BASE_REG,
	REMAP_LIMIT_REG,
	TOLUD_REG,
	BGSM_REG,
	BDSM_REG,
	TSEG_REG,
	/* Must be last */
	NUM_MAP_ENTRIES,
};

static struct map_entry memory_map[NUM_MAP_ENTRIES] = {
	[TOM_REG]         = MAP_ENTRY_BASE_64(TOM, "TOM"),
	[TOUUD_REG]       = MAP_ENTRY_BASE_64(TOUUD, "TOUUD"),
	[MESEG_BASE_REG]  = MAP_ENTRY_BASE_64(MESEG_BASE, "MESEG_BASE"),
	[MESEG_LIMIT_REG] = MAP_ENTRY_LIMIT_64(MESEG_LIMIT, "MESEG_LIMIT"),
	[REMAP_BASE_REG]  = MAP_ENTRY_BASE_64(REMAPBASE, "REMAP_BASE"),
	[REMAP_LIMIT_REG] = MAP_ENTRY_LIMIT_64(REMAPLIMIT, "REMAP_LIMIT"),
	[TOLUD_REG]       = MAP_ENTRY_BASE_32(TOLUD, "TOLUD"),
	[BDSM_REG]        = MAP_ENTRY_BASE_32(BDSM, "BDSM"),
	[BGSM_REG]        = MAP_ENTRY_BASE_32(BGSM, "BGSM"),
	[TSEG_REG]        = MAP_ENTRY_BASE_32(TSEG, "TSEGMB"),
};

static void mc_read_map_entries(struct device *dev, uint64_t *values)
{
	int i;
	for (i = 0; i < NUM_MAP_ENTRIES; i++) {
		read_map_entry(dev, &memory_map[i], &values[i]);
	}
}

static void mc_report_map_entries(struct device *dev, uint64_t *values)
{
	int i;
	for (i = 0; i < NUM_MAP_ENTRIES; i++) {
		printk(BIOS_DEBUG, "MC MAP: %s: 0x%llx\n",
		       memory_map[i].description, values[i]);
	}
	/* One can validate the BDSM and BGSM against the GGC */
	printk(BIOS_DEBUG, "MC MAP: GGC: 0x%x\n", pci_read_config16(dev, GGC));
}

static void mc_add_dram_resources(struct device *dev, int *resource_cnt)
{
	int index;
	uint64_t mc_values[NUM_MAP_ENTRIES];

	/* Read in the MAP registers and report their values */
	mc_read_map_entries(dev, &mc_values[0]);
	mc_report_map_entries(dev, &mc_values[0]);

	/*
	 * DMA Protected Range can be reserved below TSEG for PCODE patch
	 * or TXT/Boot Guard related data.  Rather than report a base address,
	 * the DPR register reports the TOP of the region, which is the same
	 * as TSEG base. The region size is reported in MiB in bits 11:4.
	 */
	const union dpr_register dpr = {
		.raw = pci_read_config32(dev, DPR),
	};
	printk(BIOS_DEBUG, "MC MAP: DPR: 0x%x\n", dpr.raw);

	/*
	 * These are the host memory ranges that should be added:
	 * - 0 -> 0xa0000:    cacheable
	 * - 0xc0000 -> TSEG: cacheable
	 * - TSEG -> BGSM:    cacheable with standard MTRRs and reserved
	 * - BGSM -> TOLUD:   not cacheable with standard MTRRs and reserved
	 * - 4GiB -> TOUUD:   cacheable
	 *
	 * The default SMRAM space is reserved so that the range doesn't have to be saved
	 * during S3 Resume. Once marked reserved the OS cannot use the memory. This is a
	 * bit of an odd place to reserve the region, but the CPU devices don't have
	 * dev_ops->read_resources() called on them.
	 *
	 * The range 0xa0000 -> 0xc0000 does not have any resources associated with it to
	 * handle legacy VGA memory. If this range is not omitted the mtrr code will setup
	 * the area as cacheable, causing VGA access to not work.
	 *
	 * The TSEG region is mapped as cacheable so that one can perform SMRAM relocation
	 * faster. Once the SMRR is enabled, the SMRR takes precedence over the existing
	 * MTRRs covering this region.
	 *
	 * It should be noted that cacheable entry types need to be added in order. The reason
	 * is that the current MTRR code assumes this and falls over itself if it isn't.
	 *
	 * The resource index starts low and should not meet or exceed PCI_BASE_ADDRESS_0.
	 */
	index = *resource_cnt;

	/*
	 * 0 - > 0xa0000: RAM
	 * 0xa0000 - 0xbffff: Legacy VGA
	 * 0xc0000 - 0xfffff: RAM
	 */

	ram_range(dev, index++, 0, 0xa0000);
	mmio_from_to(dev, index++, 0xa0000, 0xc0000);
	reserved_ram_from_to(dev, index++, 0xc0000, 1 * MiB);

	/* 1MiB -> TSEG - DPR */
	ram_from_to(dev, index++, 1 * MiB, mc_values[TSEG_REG] - dpr.size * MiB);

	/* TSEG - DPR -> BGSM */
	reserved_ram_from_to(dev, index++, mc_values[TSEG_REG] - dpr.size * MiB,
			     mc_values[BGSM_REG]);

	/* BGSM -> TOLUD. If the IGD is disabled, BGSM can equal TOLUD. */
	if (mc_values[BGSM_REG] != mc_values[TOLUD_REG])
		mmio_from_to(dev, index++, mc_values[BGSM_REG], mc_values[TOLUD_REG]);

	/* 4GiB -> TOUUD */
	upper_ram_end(dev, index++, mc_values[TOUUD_REG]);

	*resource_cnt = index;
}

static void mc_read_resources(struct device *dev)
{
	int index = 0;
	const bool vtd_capable = !(pci_read_config32(dev, CAPID0_A) & VTD_DISABLE);

	/* Read standard PCI resources */
	pci_dev_read_resources(dev);

	/* Add all fixed MMIO resources */
	mc_add_fixed_mmio_resources(dev);

	/* Add VT-d MMIO resources, if capable */
	if (vtd_capable) {
		mmio_range(dev, index++, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE);
		mmio_range(dev, index++, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE);
	}

	/* Calculate and add DRAM resources */
	mc_add_dram_resources(dev, &index);
}

/*
 * The Mini-HD audio device is disabled whenever the IGD is. This is because it provides
 * audio over the integrated graphics port(s), which requires the IGD to be functional.
 */
static void disable_devices(void)
{
	static const struct {
		const unsigned int devfn;
		const u32 mask;
		const char *const name;
	} nb_devs[] = {
		{ PCI_DEVFN(1, 2), DEVEN_D1F2EN, "PEG12" },
		{ PCI_DEVFN(1, 1), DEVEN_D1F1EN, "PEG11" },
		{ PCI_DEVFN(1, 0), DEVEN_D1F0EN, "PEG10" },
		{ PCI_DEVFN(2, 0), DEVEN_D2EN | DEVEN_D3EN, "IGD" },
		{ PCI_DEVFN(3, 0), DEVEN_D3EN, "Mini-HD audio" },
		{ PCI_DEVFN(4, 0), DEVEN_D4EN, "\"device 4\"" },
		{ PCI_DEVFN(7, 0), DEVEN_D7EN, "\"device 7\"" },
	};

	struct device *host_dev = pcidev_on_root(0, 0);
	u32 deven;
	size_t i;

	if (!host_dev)
		return;

	deven = pci_read_config32(host_dev, DEVEN);

	for (i = 0; i < ARRAY_SIZE(nb_devs); i++) {
		struct device *dev = pcidev_path_on_root(nb_devs[i].devfn);
		if (!dev || !dev->enabled) {
			printk(BIOS_DEBUG, "Disabling %s.\n", nb_devs[i].name);
			deven &= ~nb_devs[i].mask;
		}
	}

	pci_write_config32(host_dev, DEVEN, deven);
}

static void init_egress(void)
{
	/* VC0: Enable, ID0, TC0 */
	epbar_write32(EPVC0RCTL, 1 << 31 | 0 << 24 | 1 << 0);

	/* No Low Priority Extended VCs, one Extended VC */
	epbar_write32(EPPVCCAP1, 0 << 4 | 1 << 0);

	/* VC1: Enable, ID1, TC1 */
	epbar_write32(EPVC1RCTL, 1 << 31 | 1 << 24 | 1 << 1);

	/* Poll the VC1 Negotiation Pending bit */
	while ((epbar_read16(EPVC1RSTS) & (1 << 1)) != 0)
		;
}

static void northbridge_dmi_init(void)
{
	const bool is_haswell_h = !CONFIG(INTEL_LYNXPOINT_LP);

	/* Steps prior to DMI ASPM */
	if (is_haswell_h) {
		/* Configure DMI De-Emphasis */
		dmibar_setbits16(DMILCTL2, 1 << 6);	/* 0b: -6.0 dB, 1b: -3.5 dB */

		dmibar_setbits32(DMIL0SLAT, 1 << 31);
		dmibar_setbits32(DMILLTC, 1 << 29);

		dmibar_clrsetbits32(DMI_AFE_PM_TMR, 0x1f, 0x13);
	}

	/* Clear error status bits */
	dmibar_write32(DMIUESTS, 0xffffffff);
	dmibar_write32(DMICESTS, 0xffffffff);

	if (is_haswell_h) {
		/* Enable ASPM L0s and L1 on SA link, should happen before PCH link */
		dmibar_setbits16(DMILCTL, 1 << 1 | 1 << 0);
	}
}

static void northbridge_topology_init(void)
{
	const u32 eple_a[3] = { EPLE2A, EPLE3A, EPLE4A };
	const u32 eple_d[3] = { EPLE2D, EPLE3D, EPLE4D };

	/* Set the CID1 Egress Port 0 Root Topology */
	epbar_clrsetbits32(EPESD, 0xff << 16, 1 << 16);

	epbar_clrsetbits32(EPLE1D, 0xff << 16, 1 | 1 << 16);
	epbar_write32(EPLE1A, CONFIG_FIXED_DMIBAR_MMIO_BASE);
	epbar_write32(EPLE1A + 4, 0);

	for (unsigned int i = 0; i <= 2; i++) {
		const struct device *const dev = pcidev_on_root(1, i);

		if (!dev || !dev->enabled)
			continue;

		epbar_write32(eple_a[i], (u32)PCI_DEV(0, 1, i));
		epbar_write32(eple_a[i] + 4, 0);

		epbar_clrsetbits32(eple_d[i], 0xff << 16, 1 | 1 << 16);

		pci_update_config32(dev, PEG_ESD, ~(0xff << 16), (1 << 16));
		pci_write_config32(dev, PEG_LE1A, CONFIG_FIXED_EPBAR_MMIO_BASE);
		pci_write_config32(dev, PEG_LE1A + 4, 0);
		pci_update_config32(dev, PEG_LE1D, ~(0xff << 16), (1 << 16) | 1);

		/* Read and write to lock register */
		pci_or_config32(dev, PEG_DCAP2, 0);
	}

	/* Set the CID1 DMI Port Root Topology */
	dmibar_clrsetbits32(DMIESD, 0xff << 16, 1 << 16);

	dmibar_clrsetbits32(DMILE1D, 0xffff << 16, 1 | 2 << 16);
	dmibar_write32(DMILE1A, CONFIG_FIXED_RCBA_MMIO_BASE);
	dmibar_write32(DMILE1A + 4, 0);

	dmibar_write32(DMILE2A, CONFIG_FIXED_EPBAR_MMIO_BASE);
	dmibar_write32(DMILE2A + 4, 0);
	dmibar_clrsetbits32(DMILE2D, 0xff << 16, 1 | 1 << 16);

	/* Program RO and Write-Once Registers */
	dmibar_setbits32(DMIPVCCAP1, 0);
	dmibar_setbits32(DMILCAP, 0);
}

static void northbridge_init(struct device *dev)
{
	init_egress();
	northbridge_dmi_init();
	northbridge_topology_init();

	/* Enable Power Aware Interrupt Routing. */
	mchbar_clrsetbits8(INTRDIRCTL, 0x7, 0x4);	/* Clear 2:0, set Fixed Priority */

	disable_devices();

	/*
	 * Set bits 0 + 1 of BIOS_RESET_CPL to indicate to the CPU
	 * that BIOS has initialized memory and power management.
	 */
	mchbar_setbits8(BIOS_RESET_CPL, 3);
	printk(BIOS_DEBUG, "Set BIOS_RESET_CPL\n");

	/* Configure turbo power limits 1ms after reset complete bit. */
	mdelay(1);
	set_power_limits(28);
}

static void northbridge_final(struct device *dev)
{
	pci_or_config16(dev, GGC,         1 << 0);
	pci_or_config32(dev, DPR,         1 << 0);
	pci_or_config32(dev, MESEG_LIMIT, 1 << 10);
	pci_or_config32(dev, REMAPBASE,   1 << 0);
	pci_or_config32(dev, REMAPLIMIT,  1 << 0);
	pci_or_config32(dev, TOM,         1 << 0);
	pci_or_config32(dev, TOUUD,       1 << 0);
	pci_or_config32(dev, BDSM,        1 << 0);
	pci_or_config32(dev, BGSM,        1 << 0);
	pci_or_config32(dev, TSEG,        1 << 0);
	pci_or_config32(dev, TOLUD,       1 << 0);

	/* Memory Controller Lockdown */
	mchbar_setbits32(MC_LOCK, 0x8f);

	mchbar_setbits32(MMIO_PAVP_MSG, 1 << 0);	/* PAVP */
	mchbar_setbits32(PCU_DDR_PTM_CTL, 1 << 5);	/* DDR PTM */
	mchbar_setbits32(DMIVCLIM, 1 << 31);
	mchbar_setbits32(CRDTLCK, 1 << 0);
	mchbar_setbits32(MCARBLCK, 1 << 0);
	mchbar_setbits32(REQLIM, 1 << 31);
	mchbar_setbits32(UMAGFXCTL, 1 << 0);		/* UMA GFX */
	mchbar_setbits32(VTDTRKLCK, 1 << 0);		/* VTDTRK */

	/* Read+write the following */
	mchbar_setbits32(VDMBDFBARKVM, 0);
	mchbar_setbits32(VDMBDFBARPAVP, 0);
	mchbar_setbits32(HDAUDRID, 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,
	.final			= northbridge_final,
	.ops_pci		= &pci_dev_ops_pci,
};

static const unsigned short mc_pci_device_ids[] = {
	0x0c00, /* Desktop */
	0x0c04, /* Mobile */
	0x0a04, /* ULT */
	0x0c08, /* Server */
	0x0d00, /* Crystal Well Desktop */
	0x0d04, /* Crystal Well Mobile */
	0x0d08, /* Crystal Well Server (by extrapolation) */
	0
};

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

struct device_operations haswell_cpu_bus_ops = {
	.read_resources   = noop_read_resources,
	.set_resources    = noop_set_resources,
	.init             = mp_cpu_bus_init,
	.acpi_fill_ssdt   = generate_cpu_entries,
};

struct chip_operations northbridge_intel_haswell_ops = {
	.name = "Intel Haswell integrated Northbridge",
};
