/* SPDX-License-Identifier: GPL-2.0-only */
/* This file is part of the coreboot project. */

#include <arch/io.h>
#include <device/pci_ops.h>
#include <device/device.h>
#include <device/pci.h>
#include <console/console.h>
#include "chip.h"
#include "i82801ix.h"

typedef struct southbridge_intel_i82801ix_config config_t;

static void i82801ix_enable_device(struct device *dev)
{
	/* Enable SERR */
	pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR);
}

static void i82801ix_early_settings(const config_t *const info)
{
	/* Program FERR# as processor break event indicator. */
	RCBA32(GCS) |= (1 << 6);
	/* BIOS must program...
	 * NB: other CIRs are handled in i82801ix_dmi_setup(). */
	RCBA32(RCBA_CIR8) = (RCBA32(RCBA_CIR8) & ~(0x3 <<  0)) | (0x2 <<  0);
	RCBA32(RCBA_FD) |= (1 << 0);
	RCBA32(RCBA_CIR9) = (RCBA32(RCBA_CIR9) & ~(0x3 << 26)) | (0x2 << 26);
	RCBA32(RCBA_CIR7) = (RCBA32(RCBA_CIR7) & ~(0xf << 16)) | (0x5 << 16);
	RCBA32(RCBA_CIR13) = (RCBA32(RCBA_CIR13) & ~(0xf << 16)) | (0x5 << 16);
	/* RCBA32(RCBA_CIR5) |= (1 << 0); cf. Specification Update */
	RCBA32(RCBA_CIR10) |= (3 << 16);
}

static void i82801ix_pcie_init(const config_t *const info)
{
	struct device *pciePort[6];
	int i, slot_number = 1; /* Reserve slot number 0 for nb's PEG. */
	u32 reg32;

	/* PCIe - BIOS must program... */
	for (i = 0; i < 6; ++i) {
		pciePort[i] = pcidev_on_root(0x1c, i);
		if (!pciePort[i]) {
			printk(BIOS_EMERG, "PCIe port 00:1c.%x", i);
			die(" is not listed in devicetree.\n");
		}
		reg32 = pci_read_config32(pciePort[i], 0x300);
		pci_write_config32(pciePort[i], 0x300, reg32 | (1 << 21));
		pci_write_config8(pciePort[i], 0x324, 0x40);
	}

	if (LPC_IS_MOBILE(pcidev_on_root(0x1f, 0))) {
		for (i = 0; i < 6; ++i) {
			if (pciePort[i]->enabled) {
				reg32 = pci_read_config32(pciePort[i], 0xe8);
				reg32 |= 1;
				pci_write_config32(pciePort[i], 0xe8, reg32);
			}
		}
	}

	for (i = 5; (i >= 0) && !pciePort[i]->enabled; --i) {
		/* Only for the top disabled ports. */
		reg32 = pci_read_config32(pciePort[i], 0x300);
		reg32 |= 0x3 << 16;
		pci_write_config32(pciePort[i], 0x300, reg32);
	}

	/* Set slot implemented, slot number and slot power limits. */
	for (i = 0; i < 6; ++i) {
		struct device *const dev = pciePort[i];
		u32 xcap = pci_read_config32(dev, D28Fx_XCAP);
		if (info->pcie_slot_implemented & (1 << i))
			xcap |=  PCI_EXP_FLAGS_SLOT;
		else
			xcap &= ~PCI_EXP_FLAGS_SLOT;
		pci_write_config32(dev, D28Fx_XCAP, xcap);

		if (info->pcie_slot_implemented & (1 << i)) {
			u32 slcap = pci_read_config32(dev, D28Fx_SLCAP);
			slcap &= ~(0x1fff << 19);
			slcap |=  (slot_number++ << 19);
			slcap &= ~(0x0003 << 16);
			slcap |=  (info->pcie_power_limits[i].scale << 16);
			slcap &= ~(0x00ff <<  7);
			slcap |=  (info->pcie_power_limits[i].value <<  7);
			pci_write_config32(dev, D28Fx_SLCAP, slcap);
		}
	}

	/* Lock R/WO ASPM support bits. */
	for (i = 0; i < 6; ++i) {
		reg32 = pci_read_config32(pciePort[i], 0x4c);
		pci_write_config32(pciePort[i], 0x4c, reg32);
	}
}

static void i82801ix_ehci_init(void)
{
	struct device *const pciEHCI1 = pcidev_on_root(0x1d, 7);
	if (!pciEHCI1)
		die("EHCI controller (00:1d.7) not listed in devicetree.\n");
	struct device *const pciEHCI2 = pcidev_on_root(0x1a, 7);
	if (!pciEHCI2)
		die("EHCI controller (00:1a.7) not listed in devicetree.\n");

	u32 reg32;

	/* TODO: Maybe we have to save and
		 restore these settings across S3. */
	reg32 = pci_read_config32(pciEHCI1, 0xfc);
	pci_write_config32(pciEHCI1, 0xfc, (reg32 & ~(3 << 2)) |
					   (1 << 29) | (1 << 17) | (2 << 2));
	reg32 = pci_read_config32(pciEHCI2, 0xfc);
	pci_write_config32(pciEHCI2, 0xfc, (reg32 & ~(3 << 2)) |
					   (1 << 29) | (1 << 17) | (2 << 2));
}

static int i82801ix_function_disabled(const unsigned int devfn)
{
	struct device *const dev = pcidev_path_on_root(devfn);
	if (!dev) {
		printk(BIOS_EMERG,
		       "PCI device 00:%x.%x",
		       PCI_SLOT(devfn), PCI_FUNC(devfn));
		die(" is not listed in devicetree.\n");
	}
	return !dev->enabled;
}

static void i82801ix_hide_functions(void)
{
	int i;
	u32 reg32;

	/* FIXME: This works pretty good if the devicetree is consistent. But
	          some functions have to be disabled in right order and/or have
		  other constraints. */

	if (i82801ix_function_disabled(PCI_DEVFN(0x19, 0)))
		RCBA32(RCBA_BUC) |= BUC_LAND;

	reg32 = RCBA32(RCBA_FD);
	struct {
		int devfn;
		u32 mask;
	} functions[] = {
		{ PCI_DEVFN(0x1a, 0), FD_U4D },		/* UHCI #4 */
		{ PCI_DEVFN(0x1a, 1), FD_U5D },		/* UHCI #5 */
		{ PCI_DEVFN(0x1a, 2), FD_U6D },		/* UHCI #6 */
		{ PCI_DEVFN(0x1a, 7), FD_EHCI2D },	/* EHCI #2 */
		{ PCI_DEVFN(0x1b, 0), FD_HDAD },	/* HD Audio */
		{ PCI_DEVFN(0x1c, 0), FD_PE1D },	/* PCIe #1 */
		{ PCI_DEVFN(0x1c, 1), FD_PE2D },	/* PCIe #2 */
		{ PCI_DEVFN(0x1c, 2), FD_PE3D },	/* PCIe #3 */
		{ PCI_DEVFN(0x1c, 3), FD_PE4D },	/* PCIe #4 */
		{ PCI_DEVFN(0x1c, 4), FD_PE5D },	/* PCIe #5 */
		{ PCI_DEVFN(0x1c, 5), FD_PE6D },	/* PCIe #6 */
		{ PCI_DEVFN(0x1d, 0), FD_U1D },		/* UHCI #1 */
		{ PCI_DEVFN(0x1d, 1), FD_U2D },		/* UHCI #2 */
		{ PCI_DEVFN(0x1d, 2), FD_U3D },		/* UHCI #3 */
		{ PCI_DEVFN(0x1d, 7), FD_EHCI1D },	/* EHCI #1 */
		{ PCI_DEVFN(0x1f, 0), FD_LBD },		/* LPC */
		{ PCI_DEVFN(0x1f, 2), FD_SAD1 },	/* SATA #1 */
		{ PCI_DEVFN(0x1f, 3), FD_SD },		/* SMBus */
		{ PCI_DEVFN(0x1f, 5), FD_SAD2 },	/* SATA #2 */
		{ PCI_DEVFN(0x1f, 6), FD_TTD },		/* Thermal Throttle */
	};
	for (i = 0; i < ARRAY_SIZE(functions); ++i) {
		if (i82801ix_function_disabled(functions[i].devfn))
			reg32 |= functions[i].mask;
	}
	RCBA32(RCBA_FD) = reg32;
	RCBA32(RCBA_FD) |= (1 << 0); /* BIOS must write this... */
	RCBA32(RCBA_FDSW) |= (1 << 7); /* Lock function-disable? */

	/* Hide PCIe root port PCI functions. RPFN is partially R/WO. */
	reg32 = RCBA32(RCBA_RPFN);
	for (i = 0; i < 6; ++i) {
		if (i82801ix_function_disabled(PCI_DEVFN(0x1c, i)))
			reg32 |= (1 << ((i * 4) + 3));
	}
	RCBA32(RCBA_RPFN) = reg32;

	/* Lock R/WO UHCI controller #6 remapping. */
	RCBA32(RCBA_MAP) = RCBA32(RCBA_MAP);
}

static void i82801ix_init(void *chip_info)
{
	const config_t *const info = (config_t *)chip_info;

	printk(BIOS_DEBUG, "Initializing i82801ix southbridge...\n");

	i82801ix_early_settings(info);

	/* PCI Express setup. */
	i82801ix_pcie_init(info);

	/* EHCI configuration. */
	i82801ix_ehci_init();

	/* Now hide internal functions. We can't access them after this. */
	i82801ix_hide_functions();

	/* Reset watchdog timer. */
#if !CONFIG(HAVE_SMI_HANDLER)
	outw(0x0008, DEFAULT_TCOBASE + 0x12); /* Set higher timer value. */
#endif
	outw(0x0000, DEFAULT_TCOBASE + 0x00); /* Update timer. */
}

struct chip_operations southbridge_intel_i82801ix_ops = {
	CHIP_NAME("Intel ICH9/ICH9-M (82801Ix) Series Southbridge")
	.enable_dev	= i82801ix_enable_device,
	.init		= i82801ix_init,
};
