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

#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. */

	/* 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");
		}
		pci_or_config32(pciePort[i], 0x300, 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) {
				pci_or_config32(pciePort[i], 0xe8, 1);
			}
		}
	}

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

	/* 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)
		pci_update_config32(pciePort[i], 0x4c, ~0, 0);
}

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