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

#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/mmio.h>
#include <device/pci_ops.h>
#include <arch/ioapic.h>
#include <acpi/acpi.h>
#include <cpu/x86/smm.h>
#include <bootstate.h>

#include <soc/lpc.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
#include <soc/iomap.h>
#include <soc/pcr.h>
#include <soc/p2sb.h>
#include <soc/acpi.h>

#include "chip.h"

/* PCH I/O APIC redirection entries */
#define PCH_REDIR_ETR 120

/**
 * Set miscellaneous static southbridge features.
 *
 * @param dev PCI device with I/O APIC control registers
 */
static void pch_enable_ioapic(struct device *dev)
{
	/* affirm full set of redirection table entries ("write once") */
	ioapic_set_max_vectors(IO_APIC_ADDR, PCH_REDIR_ETR);

	register_new_ioapic_gsi0(IO_APIC_ADDR);
}

/* interrupt router lookup for internal devices */
struct dnv_ir_lut {
	/* (dev << 3) | fn */
	u8 devfn;
	u8 ir;
};

#define DEVFN(dev, fn) ((dev << 3) | (fn))

static const struct dnv_ir_lut dnv_ir_lut[] = {
	{.devfn = DEVFN(0x05, 0), .ir = 3},  /* RCEC */
	{.devfn = DEVFN(0x06, 0), .ir = 4},  /* Virtual RP to QAT */
	{.devfn = DEVFN(0x09, 0), .ir = 7},  /* PCIe RP0 */
	{.devfn = DEVFN(0x0a, 0), .ir = 7},  /* PCIe RP1 */
	{.devfn = DEVFN(0x0b, 0), .ir = 7},  /* PCIe RP2 */
	{.devfn = DEVFN(0x0c, 0), .ir = 7},  /* PCIe RP3 */
	{.devfn = DEVFN(0x0e, 0), .ir = 8},  /* PCIe RP4 */
	{.devfn = DEVFN(0x0f, 0), .ir = 8},  /* PCIe RP5 */
	{.devfn = DEVFN(0x10, 0), .ir = 8},  /* PCIe RP6 */
	{.devfn = DEVFN(0x11, 0), .ir = 8},  /* PCIe RP7 */
	{.devfn = DEVFN(0x12, 0), .ir = 10}, /* SMBus - Host */
	{.devfn = DEVFN(0x13, 0), .ir = 6},  /* AHCI0 */
	{.devfn = DEVFN(0x14, 0), .ir = 11}, /* AHCI1 */
	{.devfn = DEVFN(0x15, 0), .ir = 9},  /* USB */
	{.devfn = DEVFN(0x16, 0), .ir = 1},  /* Virtual RP to LAN0 */
	{.devfn = DEVFN(0x17, 0), .ir = 2},  /* Virtual RP to LAN1 */
	{.devfn = DEVFN(0x18, 0), .ir = 5},  /* ME HECI1 */
	{.devfn = DEVFN(0x18, 1), .ir = 5},  /* ME HECI1 */
	{.devfn = DEVFN(0x18, 2), .ir = 5},  /* ME PTIO-IDER */
	{.devfn = DEVFN(0x18, 3), .ir = 5},  /* ME PTIO-KT */
	{.devfn = DEVFN(0x18, 4), .ir = 5},  /* ME HECI3 */
	{.devfn = DEVFN(0x1a, 0), .ir = 10}, /* HSUART0 */
	{.devfn = DEVFN(0x1a, 1), .ir = 10}, /* HSUART1 */
	{.devfn = DEVFN(0x1a, 2), .ir = 10}, /* HSUART2 */
	{.devfn = DEVFN(0x1b, 0), .ir = 12}, /* IE HECI1 */
	{.devfn = DEVFN(0x1b, 1), .ir = 12}, /* IE HECI1 */
	{.devfn = DEVFN(0x1b, 2), .ir = 12}, /* IE PTIO-IDER */
	{.devfn = DEVFN(0x1b, 3), .ir = 12}, /* IE PTIO-KT */
	{.devfn = DEVFN(0x1b, 4), .ir = 12}, /* IE HECI3 */
	{.devfn = DEVFN(0x1c, 0), .ir = 12}, /* SDHCI */
	{.devfn = DEVFN(0x1f, 0), .ir = 0},  /* LPC */
	{.devfn = DEVFN(0x1f, 1), .ir = 0},  /* PS2B */
	{.devfn = DEVFN(0x1f, 4), .ir = 0},  /* SMBus - Legacy */
	{.devfn = DEVFN(0x1f, 7), .ir = 0},  /* Trace Hub */
};

/*
 * Only 6 of the 8 root ports have swizzling, return '1' if this bdf is one of
 * them, '0' otherwise
 */
static int is_dnv_swizzled_rp(uint16_t bdf)
{
	switch (bdf) {
	case DEVFN(10, 0):
	case DEVFN(11, 0):
	case DEVFN(12, 0):
	case DEVFN(15, 0):
	case DEVFN(16, 0):
	case DEVFN(17, 0):
		return 1;
	}

	return 0;
}

/*
 * Figure out which upstream interrupt pin a downstream device gets swizzled to
 *
 * config - pointer to chip_info containing routing info
 * devfn - device/function of root port to check swizzling for
 * pin - interrupt pin 1-4 = A-D
 *
 * Return new pin mapping, 0 if invalid pin
 */
static int dnv_get_swizzled_pin(config_t *config, u8 devfn, u8 pin)
{
	if (pin < 1 || pin > 4)
		return 0;

	devfn >>= 3;
	if (devfn < 13)
		devfn -= 9;
	else
		devfn -= 14;

	return ((pin - 1 + devfn) % 4) + 1;
}

/*
 * Figure out which upstream interrupt pin a downstream device gets swizzled to
 *
 * config - pointer to chip_info containing routing info
 * devfn - device/function of root port to check swizzling for
 * pin - interrupt pin 1-4 = A-D
 *
 * Return new pin mapping, 0 if invalid pin
 */
static int dnv_get_ir(config_t *config, u8 devfn, u8 pin)
{
	int i = 0;
	int line = 0xff;
	u16 ir = 0xffff;

	/* The only valid pin values are 1-4 for A-D */
	if (pin < 1 || pin > 4) {
		printk(BIOS_WARNING, "%s: pin %d is invalid\n", __func__, pin);
		goto dnv_get_ir_done;
	}

	for (i = 0; i < ARRAY_SIZE(dnv_ir_lut); i++) {
		if (dnv_ir_lut[i].devfn == devfn)
			break;
	}

	if (i == ARRAY_SIZE(dnv_ir_lut)) {
		printk(BIOS_WARNING, "%s: no entry\n", __func__);
		goto dnv_get_ir_done;
	}

	switch (dnv_ir_lut[i].ir) {
	case 0:
		ir = config->ir00_routing;
		break;
	case 1:
		ir = config->ir01_routing;
		break;
	case 2:
		ir = config->ir02_routing;
		break;
	case 3:
		ir = config->ir03_routing;
		break;
	case 4:
		ir = config->ir04_routing;
		break;
	case 5:
		ir = config->ir05_routing;
		break;
	case 6:
		ir = config->ir06_routing;
		break;
	case 7:
		ir = config->ir07_routing;
		break;
	case 8:
		ir = config->ir08_routing;
		break;
	case 9:
		ir = config->ir09_routing;
		break;
	case 10:
		ir = config->ir10_routing;
		break;
	case 11:
		ir = config->ir11_routing;
		break;
	case 12:
		ir = config->ir12_routing;
		break;
	default:
		printk(BIOS_ERR, "%s: invalid ir %d for entry %d\n", __func__, dnv_ir_lut[i].ir,
		       i);
		goto dnv_get_ir_done;
	}

	ir >>= (pin - 1) * 4;
	ir &= 0xf;
	switch (ir) {
	case 0:
		line = config->pirqa_routing;
		break;
	case 1:
		line = config->pirqb_routing;
		break;
	case 2:
		line = config->pirqc_routing;
		break;
	case 3:
		line = config->pirqd_routing;
		break;
	case 4:
		line = config->pirqe_routing;
		break;
	case 5:
		line = config->pirqf_routing;
		break;
	case 6:
		line = config->pirqg_routing;
		break;
	case 7:
		line = config->pirqh_routing;
		break;
	default:
		printk(BIOS_ERR, "%s: invalid ir pirq %d for entry %d\n", __func__, ir, i);
		break;
	}

dnv_get_ir_done:
	return line;
}

/*
 * PCI devices have the INT_LINE (0x3C) and INT_PIN (0x3D) registers which
 * report interrupt routing information to operating systems and drivers.  The
 * INT_PIN register is generally read only and reports which interrupt pin
 * A - D it uses.  The INT_LINE register is configurable and reports which IRQ
 * (generally the PIC IRQs 1 - 15) it will use.  This needs to take interrupt
 * pin swizzling on devices that are downstream on a PCI bridge into account.
 */
static u8 dnv_get_int_line(struct device *irq_dev)
{
	config_t *config;
	struct device *targ_dev = NULL;
	uint16_t parent_bdf = 0;
	int8_t original_int_pin = 0, new_int_pin = 0, swiz_int_pin = 0;
	uint8_t int_line = 0xff;

	if (!is_enabled_pci(irq_dev)) {
		printk(BIOS_ERR, "%s for non pci device?\n", __func__);
		goto dnv_get_int_line_done;
	}

	/*
	 * Get the INT_PIN swizzled up to the root port if necessary
	 * using the existing coreboot pci_device code
	 */
	original_int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
	new_int_pin = get_pci_irq_pins(irq_dev, &targ_dev);
	if (targ_dev == NULL || new_int_pin < 1)
		goto dnv_get_int_line_done;

	printk(BIOS_DEBUG, "%s: irq_dev %s, targ_dev %s:\n", __func__, dev_path(irq_dev),
	       dev_path(targ_dev));
	printk(BIOS_DEBUG, "%s: std swizzle %s from %c to %c\n", __func__, dev_path(targ_dev),
	       '@' + original_int_pin, '@' + new_int_pin);

	/* Swizzle this device if needed */
	config = targ_dev->chip_info;
	parent_bdf = targ_dev->path.pci.devfn | targ_dev->upstream->secondary << 8;
	if (is_dnv_swizzled_rp(parent_bdf) && irq_dev != targ_dev) {
		swiz_int_pin = dnv_get_swizzled_pin(config, parent_bdf, new_int_pin);
		printk(BIOS_DEBUG, "%s: dnv swizzle %s from %c to %c\n", __func__,
		       dev_path(targ_dev), '@' + new_int_pin, '@' + swiz_int_pin);
	} else {
		swiz_int_pin = new_int_pin;
	}

	/* Look up the routing for the pin */
	int_line = dnv_get_ir(config, parent_bdf, swiz_int_pin);

dnv_get_int_line_done:
	printk(BIOS_DEBUG, "\tINT_LINE\t\t: %d\n", int_line);
	return int_line;
}

/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
 * 0x00 - 0000 = Reserved
 * 0x01 - 0001 = Reserved
 * 0x02 - 0010 = Reserved
 * 0x03 - 0011 = IRQ3
 * 0x04 - 0100 = IRQ4
 * 0x05 - 0101 = IRQ5
 * 0x06 - 0110 = IRQ6
 * 0x07 - 0111 = IRQ7
 * 0x08 - 1000 = Reserved
 * 0x09 - 1001 = IRQ9
 * 0x0A - 1010 = IRQ10
 * 0x0B - 1011 = IRQ11
 * 0x0C - 1100 = IRQ12
 * 0x0D - 1101 = Reserved
 * 0x0E - 1110 = IRQ14
 * 0x0F - 1111 = IRQ15
 * PIRQ[n]_ROUT[7] - PIRQ Routing Control
 * 0x80 - The PIRQ is not routed.
 */

static void pch_pirq_init(struct device *dev)
{
	struct device *irq_dev;
	/* Get the chip configuration */
	config_t *config = config_of(dev);

	/* Initialize PIRQ Routings */
	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQA_ROUT),
	       config->pirqa_routing);
	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQB_ROUT),
	       config->pirqb_routing);
	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQC_ROUT),
	       config->pirqc_routing);
	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQD_ROUT),
	       config->pirqd_routing);

	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQE_ROUT),
	       config->pirqe_routing);
	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQF_ROUT),
	       config->pirqf_routing);
	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQG_ROUT),
	       config->pirqg_routing);
	write8((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIRQH_ROUT),
	       config->pirqh_routing);

	/* Initialize device's Interrupt Routings */
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR00),
		config->ir00_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR01),
		config->ir01_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR02),
		config->ir02_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR03),
		config->ir03_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR04),
		config->ir04_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR05),
		config->ir05_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR06),
		config->ir06_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR07),
		config->ir07_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR08),
		config->ir08_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR09),
		config->ir09_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR10),
		config->ir10_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR11),
		config->ir11_routing);
	write16((void *)PCH_PCR_ADDRESS(PID_ITSS, PCR_ITSS_PIR12),
		config->ir12_routing);

	/* Initialize device's Interrupt Polarity Control */
	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC0),
		config->ipc0);
	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC1),
		config->ipc1);
	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC2),
		config->ipc2);
	write32((void *)PCH_PCR_ADDRESS(PID_ITSS, PCH_PCR_ITSS_IPC3),
		config->ipc3);

	for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
		int devfn = irq_dev->path.pci.devfn;
		u8 int_pin = 0, int_line = 0;

		if (!is_enabled_pci(irq_dev))
			continue;

		int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);

		int_line = dnv_get_int_line(irq_dev);
		printk(BIOS_DEBUG, "%s: %02x:%02x.%d pin %d int line %d\n", __func__,
		       irq_dev->upstream->secondary, devfn >> 3, devfn & 0x7, int_pin, int_line);

		pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
	}
}

static void pci_p2sb_read_resources(struct device *dev)
{
	struct resource *res;

	/* Add MMIO resource
	 * Use 0xda as an unused index for PCR BAR.
	 */
	res = new_resource(dev, 0xda);
	res->base = DEFAULT_PCR_BASE;
	res->size = 16 * 1024 * 1024; /* 16MB PCR config space */
	res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |
		     IORESOURCE_ASSIGNED;

	/* Add MMIO resource
	 * Use 0xdb as an unused index for IOAPIC.
	 */
	res = new_resource(dev, 0xdb); /* IOAPIC */
	res->base = IO_APIC_ADDR;
	res->size = 0x00001000;
	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}

static void pch_enable_serial_irqs(struct device *dev)
{
	/* Set packet length and toggle silent mode bit for one frame. */
	pci_write_config8(dev, SERIRQ_CNTL,
			  (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
#if !CONFIG(SERIRQ_CONTINUOUS_MODE)
	pci_write_config8(dev, SERIRQ_CNTL,
			  (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
#endif
}

static void lpc_init(struct device *dev)
{
	printk(BIOS_DEBUG, "pch: %s\n", __func__);

	/* Get the base address */

	/* Set the value for PCI command register. */
	pci_write_config16(dev, PCI_COMMAND,
			   PCI_COMMAND_SPECIAL | PCI_COMMAND_MASTER |
				   PCI_COMMAND_MEMORY | PCI_COMMAND_IO);

	/* Serial IRQ initialization. */
	pch_enable_serial_irqs(dev);

	/* IO APIC initialization. */
	pch_enable_ioapic(dev);

	/* Setup the PIRQ. */
	pch_pirq_init(dev);
}

static void pch_lpc_add_mmio_resources(struct device *dev) { /* TODO */ }

static void pch_lpc_add_io_resources(struct device *dev)
{
	struct resource *res;
	u8 io_index = 0;

	/* Add an extra subtractive resource for both memory and I/O. */
	res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
	res->base = 0;
	res->size = 0x1000;
	res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;

	res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
	res->base = 0xff000000;
	res->size = 0x01000000; /* 16 MB for flash */
	res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
		     IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
}

static void lpc_read_resources(struct device *dev)
{
	/* Get the normal PCI resources of this device. */
	pci_dev_read_resources(dev);

	/* Add non-standard MMIO resources. */
	pch_lpc_add_mmio_resources(dev);

	/* Add IO resources. */
	pch_lpc_add_io_resources(dev);

	/* Add MMIO resource for IOAPIC. */
	pci_p2sb_read_resources(dev);
}

static void pch_decode_init(struct device *dev) { /* TODO */ }

static void lpc_enable_resources(struct device *dev)
{
	pch_decode_init(dev);
	pci_dev_enable_resources(dev);
}

/* Set bit in Function Disable register to hide this device */
static void pch_hide_devfn(uint32_t devfn) { /* TODO */ }

void southcluster_enable_dev(struct device *dev)
{
	u16 reg16;

	if (!dev->enabled) {
		printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));

		/* Ensure memory, io, and bus master are all disabled */
		reg16 = pci_read_config16(dev, PCI_COMMAND);
		reg16 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
			   PCI_COMMAND_IO);
		pci_write_config16(dev, PCI_COMMAND, reg16);

		/* Hide this device if possible */
		pch_hide_devfn(dev->path.pci.devfn);
	} else {
		/* Enable SERR */
		pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR);
	}
}

static struct device_operations device_ops = {
	.read_resources = lpc_read_resources,
	.set_resources = pci_dev_set_resources,
#if CONFIG(HAVE_ACPI_TABLES)
	.write_acpi_tables = southcluster_write_acpi_tables,
#endif
	.enable_resources = lpc_enable_resources,
	.init = lpc_init,
	.enable = southcluster_enable_dev,
	.scan_bus = scan_static_bus,
	.ops_pci = &soc_pci_ops,
};

static const struct pci_driver lpc_driver __pci_driver = {
	.ops = &device_ops,
	.vendor = PCI_VID_INTEL,
	.device = PCI_DID_INTEL_DNV_LPC,
};

static void finalize_chipset(void *unused)
{
	apm_control(APM_CNT_FINALIZE);
}

BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, finalize_chipset, NULL);
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, finalize_chipset, NULL);
