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

#include <console/console.h>
#include <cpu/intel/haswell/haswell.h>
#include <delay.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pciexp.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <soc/lpc.h>
#include <soc/pch.h>
#include <soc/pci_devs.h>
#include <soc/rcba.h>
#include <soc/intel/broadwell/pch/chip.h>
#include <southbridge/intel/lynxpoint/iobp.h>
#include <southbridge/intel/lynxpoint/lp_gpio.h>
#include <types.h>

/* Low Power variant has 6 root ports. */
#define MAX_NUM_ROOT_PORTS 6

struct root_port_config {
	/* RPFN is a write-once register so keep a copy until it is written */
	u32 orig_rpfn;
	u32 new_rpfn;
	u32 pin_ownership;
	u32 strpfusecfg1;
	u32 strpfusecfg2;
	u32 strpfusecfg3;
	u32 b0d28f0_32c;
	u32 b0d28f4_32c;
	u32 b0d28f5_32c;
	bool coalesce;
	int gbe_port;
	int num_ports;
	struct device *ports[MAX_NUM_ROOT_PORTS];
};

static struct root_port_config rpc;

static inline int root_port_is_first(struct device *dev)
{
	return PCI_FUNC(dev->path.pci.devfn) == 0;
}

static inline int root_port_is_last(struct device *dev)
{
	return PCI_FUNC(dev->path.pci.devfn) == (rpc.num_ports - 1);
}

/* Root ports are numbered 1..N in the documentation. */
static inline int root_port_number(struct device *dev)
{
	return PCI_FUNC(dev->path.pci.devfn) + 1;
}

static void root_port_config_update_gbe_port(void)
{
	/* Is the Gbe Port enabled? */
	if (!((rpc.strpfusecfg1 >> 19) & 1))
		return;

	switch ((rpc.strpfusecfg1 >> 16) & 0x7) {
	case 0:
		rpc.gbe_port = 3;
		break;
	case 1:
		rpc.gbe_port = 4;
		break;
	case 2:
	case 3:
	case 4:
	case 5:
		/* Lanes 0-4 of Root Port 5. */
		rpc.gbe_port = 5;
		break;
	default:
		printk(BIOS_DEBUG, "Invalid GbE Port Selection.\n");
	}
}

static void pcie_iosf_port_grant_count(struct device *dev)
{
	u8 update_val;
	u32 rpcd = (pci_read_config32(dev, 0xfc) >> 14) & 0x3;

	switch (rpcd) {
	case 1:
	case 3:
		update_val = 0x02;
		break;
	case 2:
		update_val = 0x22;
		break;
	default:
		update_val = 0x00;
		break;
	}

	RCBA32(0x103C) = (RCBA32(0x103C) & (~0xff)) | update_val;
}

static void root_port_init_config(struct device *dev)
{
	int rp;
	u32 data = 0;
	u8 resp, id;

	if (root_port_is_first(dev)) {
		rpc.orig_rpfn = RCBA32(RPFN);
		rpc.new_rpfn = rpc.orig_rpfn;
		rpc.num_ports = MAX_NUM_ROOT_PORTS;
		rpc.gbe_port = -1;
		/* RP0 f5[3:0] = 0101b*/
		pci_update_config8(dev, 0xf5, ~0xa, 0x5);

		pcie_iosf_port_grant_count(dev);

		rpc.pin_ownership = pci_read_config32(dev, 0x410);
		root_port_config_update_gbe_port();

		pci_or_config8(dev, 0xe2, 3 << 4);
		const struct soc_intel_broadwell_pch_config *config = config_of(dev);
		rpc.coalesce = config->pcie_port_coalesce;
	}

	rp = root_port_number(dev);
	if (rp > rpc.num_ports) {
		printk(BIOS_ERR, "Found Root Port %d, expecting %d\n",
		       rp, rpc.num_ports);
		return;
	}

	/* Read the fuse configuration and pin ownership. */
	switch (rp) {
	case 1:
		rpc.strpfusecfg1 = pci_read_config32(dev, 0xfc);
		rpc.b0d28f0_32c = pci_read_config32(dev, 0x32c);
		break;
	case 5:
		rpc.strpfusecfg2 = pci_read_config32(dev, 0xfc);
		rpc.b0d28f4_32c = pci_read_config32(dev, 0x32c);
		break;
	case 6:
		rpc.b0d28f5_32c = pci_read_config32(dev, 0x32c);
		rpc.strpfusecfg3 = pci_read_config32(dev, 0xfc);
		break;
	default:
		break;
	}

	pci_write_config32(dev, 0x418, 0x02000430);

	if (root_port_is_first(dev)) {
		/*
		 * set RP0 PCICFG E2h[5:4] = 11b and E1h[6] = 1
		 * before configuring ASPM
		 */
		id = 0xe0 + (u8)(RCBA32(RPFN) & 0x07);
		pch_iobp_exec(0xE00000E0, IOBP_PCICFG_READ, id, &data, &resp);
		data |= ((0x30 << 16) | (0x40 << 8));
		pch_iobp_exec(0xE00000E0, IOBP_PCICFG_WRITE, id, &data, &resp);
	}

	/* Cache pci device. */
	rpc.ports[rp - 1] = dev;
}

/* Update devicetree with new Root Port function number assignment */
static void pch_pcie_device_set_func(int index, int pci_func)
{
	struct device *dev;
	unsigned int new_devfn;

	dev = rpc.ports[index];

	/* Set the new PCI function field for this Root Port. */
	rpc.new_rpfn &= ~RPFN_FNMASK(index);
	rpc.new_rpfn |= RPFN_FNSET(index, pci_func);

	/* Determine the new devfn for this port */
	new_devfn = PCI_DEVFN(PCH_DEV_SLOT_PCIE, pci_func);

	if (dev && dev->path.pci.devfn != new_devfn) {
		printk(BIOS_DEBUG,
		       "PCH: PCIe map %02x.%1x -> %02x.%1x\n",
		       PCI_SLOT(dev->path.pci.devfn),
		       PCI_FUNC(dev->path.pci.devfn),
		       PCI_SLOT(new_devfn), PCI_FUNC(new_devfn));

		dev->path.pci.devfn = new_devfn;
	}
}

static void pcie_enable_clock_gating(void)
{
	int i;
	int enabled_ports = 0;
	int is_broadwell = !!(cpu_family_model() == BROADWELL_FAMILY_ULT);

	for (i = 0; i < rpc.num_ports; i++) {
		struct device *dev;
		int rp;

		dev = rpc.ports[i];
		if (!dev)
			continue;

		rp = root_port_number(dev);

		if (!dev->enabled) {
			/* Configure shared resource clock gating. */
			if (rp == 1 || rp == 5 || rp == 6)
				pci_or_config8(dev, 0xe1, 0x3c);

			pci_or_config8(dev, 0xe2, 3 << 4);
			pci_or_config32(dev, 0x420, 1 << 31);

			/* Per-Port CLKREQ# handling. */
			if (gpio_is_native(18 + rp - 1))
				pci_or_config32(dev, 0x420, 3 << 29);

			/* Enable static clock gating. */
			if (rp == 1 && !rpc.ports[1]->enabled &&
			    !rpc.ports[2]->enabled && !rpc.ports[3]->enabled) {
				pci_or_config8(dev, 0xe2, 1);
				pci_or_config8(dev, 0xe1, 1 << 7);
			} else if (rp == 5 || rp == 6) {
				pci_or_config8(dev, 0xe2, 1);
				pci_or_config8(dev, 0xe1, 1 << 7);
			}
			continue;
		}

		enabled_ports++;

		/* Enable dynamic clock gating. */
		pci_or_config8(dev, 0xe1, 0x03);
		pci_or_config8(dev, 0xe2, 1 << 6);
		pci_update_config8(dev, 0xe8, ~(3 << 2), (2 << 2));

		/* Update PECR1 register. */
		pci_or_config8(dev, 0xe8, 3);

		if (is_broadwell) {
			pci_or_config32(dev, 0x324, (1 << 5) | (1 << 14));
		} else {
			pci_or_config32(dev, 0x324, 1 << 5);
		}
		/* Per-Port CLKREQ# handling. */
		if (gpio_is_native(18 + rp - 1))
			/*
			 * In addition to D28Fx PCICFG 420h[30:29] = 11b,
			 * set 420h[17] = 0b and 420[0] = 1b for L1 SubState.
			 */
			pci_update_config32(dev, 0x420, ~(1 << 17), (3 << 29) | 1);

		/* Configure shared resource clock gating. */
		if (rp == 1 || rp == 5 || rp == 6)
			pci_or_config8(dev, 0xe1, 0x3c);

		/* CLKREQ# VR Idle Enable */
		RCBA32_OR(0x2b1c, (1 << (16 + i)));
	}

	if (!enabled_ports)
		pci_or_config8(rpc.ports[0], 0xe1, 1 << 6);
}

static void root_port_commit_config(void)
{
	int i;

	/* If the first root port is disabled the coalesce ports. */
	if (!rpc.ports[0]->enabled)
		rpc.coalesce = true;

	/* Perform clock gating configuration. */
	pcie_enable_clock_gating();

	for (i = 0; i < rpc.num_ports; i++) {
		struct device *dev;
		u32 reg32;
		int n = 0;

		dev = rpc.ports[i];

		if (dev == NULL) {
			printk(BIOS_ERR, "Root Port %d device is NULL?\n", i+1);
			continue;
		}

		if (dev->enabled)
			continue;

		printk(BIOS_DEBUG, "%s: Disabling device\n",  dev_path(dev));

		/* 8.2 Configuration of PCI Express Root Ports */
		pci_or_config32(dev, 0x338, 1 << 26);

		do {
			reg32 = pci_read_config32(dev, 0x328);
			n++;
			if (((reg32 & 0xff000000) == 0x01000000) || (n > 50))
				break;
			udelay(100);
		} while (1);

		if (n > 50)
			printk(BIOS_DEBUG, "%s: Timeout waiting for 328h\n",
				dev_path(dev));

		pci_or_config32(dev, 0x408, 1 << 27);

		/* Disable this device if possible */
		pch_disable_devfn(dev);
	}

	if (rpc.coalesce) {
		int current_func;

		/* For all Root Ports N enabled ports get assigned the lower
		 * PCI function number. The disabled ones get upper PCI
		 * function numbers. */
		current_func = 0;
		for (i = 0; i < rpc.num_ports; i++) {
			if (!rpc.ports[i]->enabled)
				continue;
			pch_pcie_device_set_func(i, current_func);
			current_func++;
		}

		/* Allocate the disabled devices' PCI function number. */
		for (i = 0; i < rpc.num_ports; i++) {
			if (rpc.ports[i]->enabled)
				continue;
			pch_pcie_device_set_func(i, current_func);
			current_func++;
		}
	}

	printk(BIOS_SPEW, "PCH: RPFN 0x%08x -> 0x%08x\n",
	       rpc.orig_rpfn, rpc.new_rpfn);
	RCBA32(RPFN) = rpc.new_rpfn;
}

static void root_port_mark_disable(struct device *dev)
{
	/* Mark device as disabled. */
	dev->enabled = 0;
	/* Mark device to be hidden. */
	rpc.new_rpfn |= RPFN_HIDE(PCI_FUNC(dev->path.pci.devfn));
}

static void root_port_check_disable(struct device *dev)
{
	int rp;

	/* Device already disabled. */
	if (!dev->enabled) {
		root_port_mark_disable(dev);
		return;
	}

	rp = root_port_number(dev);

	/* Is the GbE port mapped to this Root Port? */
	if (rp == rpc.gbe_port) {
		root_port_mark_disable(dev);
		return;
	}

	/* Check Root Port Configuration. */
	switch (rp) {
	case 2:
		/* Root Port 2 is disabled for all lane configurations
		 * but config 00b (4x1 links). */
		if ((rpc.strpfusecfg1 >> 14) & 0x3) {
			root_port_mark_disable(dev);
			return;
		}
		break;
	case 3:
		/* Root Port 3 is disabled in config 11b (1x4 links). */
		if (((rpc.strpfusecfg1 >> 14) & 0x3) == 0x3) {
			root_port_mark_disable(dev);
			return;
		}
		break;
	case 4:
		/* Root Port 4 is disabled in configs 11b (1x4 links)
		 * and 10b (2x2 links). */
		if ((rpc.strpfusecfg1 >> 14) & 0x2) {
			root_port_mark_disable(dev);
			return;
		}
		break;
	}

	/* Check Pin Ownership. */
	switch (rp) {
	case 1:
		/* Bit 0 is Root Port 1 ownership. */
		if ((rpc.pin_ownership & 0x1) == 0) {
			root_port_mark_disable(dev);
			return;
		}
		break;
	case 2:
		/* Bit 2 is Root Port 2 ownership. */
		if ((rpc.pin_ownership & 0x4) == 0) {
			root_port_mark_disable(dev);
			return;
		}
		break;
	case 6:
		/* Bits 7:4 are Root Port 6 pin-lane ownership. */
		if ((rpc.pin_ownership & 0xf0) == 0) {
			root_port_mark_disable(dev);
			return;
		}
		break;
	}
}

static void pcie_add_0x0202000_iobp(u32 reg)
{
	u32 reg32;

	reg32 = pch_iobp_read(reg);
	reg32 += (0x2 << 16) | (0x2 << 8);
	pch_iobp_write(reg, reg32);
}

static void pch_pcie_early(struct device *dev)
{
	const struct soc_intel_broadwell_pch_config *config = config_of(dev);
	int do_aspm = 0;
	int rp = root_port_number(dev);

	switch (rp) {
	case 1:
	case 2:
	case 3:
	case 4:
		/*
		 * Bits 31:28 of b0d28f0 0x32c register correspond to
		 * Root Ports 4:1.
		 */
		do_aspm = !!(rpc.b0d28f0_32c & (1 << (28 + rp - 1)));
		break;
	case 5:
		/*
		 * Bit 28 of b0d28f4 0x32c register correspond to
		 * Root Ports 4:1.
		 */
		do_aspm = !!(rpc.b0d28f4_32c & (1 << 28));
		break;
	case 6:
		/*
		 * Bit 28 of b0d28f5 0x32c register correspond to
		 * Root Ports 4:1.
		 */
		do_aspm = !!(rpc.b0d28f5_32c & (1 << 28));
		break;
	}

	/* Allow ASPM to be forced on in devicetree */
	if ((config->pcie_port_force_aspm & (1 << (rp - 1))))
		do_aspm = 1;

	printk(BIOS_DEBUG, "PCIe Root Port %d ASPM is %sabled\n",
	       rp, do_aspm ? "en" : "dis");

	if (do_aspm) {
		/* Set ASPM bits in MPC2 register. */
		pci_update_config32(dev, 0xd4, ~(0x3 << 2), (1 << 4) | (0x2 << 2));

		/* Set unique clock exit latency in MPC register. */
		pci_update_config32(dev, 0xd8, ~(0x7 << 18), (0x7 << 18));

		switch (rp) {
		case 1:
			pcie_add_0x0202000_iobp(0xe9002440);
			break;
		case 2:
			pcie_add_0x0202000_iobp(0xe9002640);
			break;
		case 3:
			pcie_add_0x0202000_iobp(0xe9000840);
			break;
		case 4:
			pcie_add_0x0202000_iobp(0xe9000a40);
			break;
		case 5:
			pcie_add_0x0202000_iobp(0xe9000c40);
			pcie_add_0x0202000_iobp(0xe9000e40);
			pcie_add_0x0202000_iobp(0xe9001040);
			pcie_add_0x0202000_iobp(0xe9001240);
			break;
		case 6:
			/* Update IOBP based on lane ownership. */
			if (rpc.pin_ownership & (1 << 4))
				pcie_add_0x0202000_iobp(0xea002040);
			if (rpc.pin_ownership & (1 << 5))
				pcie_add_0x0202000_iobp(0xea002240);
			if (rpc.pin_ownership & (1 << 6))
				pcie_add_0x0202000_iobp(0xea002440);
			if (rpc.pin_ownership & (1 << 7))
				pcie_add_0x0202000_iobp(0xea002640);
			break;
		}

		pci_update_config32(dev, 0x338, ~(1 << 26), 0);
	}

	/* Enable LTR in Root Port. Disable OBFF. */
	pci_update_config32(dev, 0x64, ~(3 << 18), (1 << 11));
	pci_or_config32(dev, 0x68, 1 << 10);

	pci_update_config32(dev, 0x318, ~(0xffff << 16), (0x1414 << 16));

	/* Set L1 exit latency in LCAP register. */
	if (!do_aspm && (pci_read_config8(dev, 0xf5) & 0x1))
		pci_update_config32(dev, 0x4c, ~(0x7 << 15), (0x4 << 15));
	else
		pci_update_config32(dev, 0x4c, ~(0x7 << 15), (0x2 << 15));

	pci_update_config32(dev, 0x314, 0, 0x743a361b);

	/* Set Common Clock Exit Latency in MPC register. */
	pci_update_config32(dev, 0xd8, ~(0x7 << 15), (0x3 << 15));

	pci_update_config32(dev, 0x33c, ~0x00ffffff, 0x854d74);

	/* Set Invalid Receive Range Check Enable in MPC register. */
	pci_or_config32(dev, 0xd8, 1 << 25);

	pci_and_config8(dev, 0xf5, 0x0f);

	/* Set AER Extended Cap ID to 01h and Next Cap Pointer to 200h. */
	if (CONFIG(PCIEXP_AER))
		pci_update_config32(dev, 0x100, ~0xfffff, (1 << 29) | 0x10001);
	else
		pci_update_config32(dev, 0x100, ~0xfffff, (1 << 29));

	/* Set L1 Sub-State Cap ID to 1Eh and Next Cap Pointer to None. */
	if (CONFIG(PCIEXP_L1_SUB_STATE))
		pci_update_config32(dev, 0x200, ~0xfffff, 0x001e);
	else
		pci_update_config32(dev, 0x200, ~0xfffff, 0);

	pci_update_config32(dev, 0x320, ~(3 << 20) & ~(7 << 6), (1 << 20) | (3 << 6));

	/* Enable Relaxed Order from Root Port. */
	pci_or_config32(dev, 0x320, 3 << 23);

	if (rp == 1 || rp == 5 || rp == 6)
		pci_update_config8(dev, 0xf7, ~0xc, 0);

	/* Set EOI forwarding disable. */
	pci_update_config32(dev, 0xd4, ~0, (1 << 1));

	/* Read and write back write-once capability registers. */
	pci_update_config32(dev, 0x34, ~0, 0);
	pci_update_config32(dev, 0x40, ~0, 0);
	pci_update_config32(dev, 0x80, ~0, 0);
	pci_update_config32(dev, 0x90, ~0, 0);
}

static void pch_pcie_init(struct device *dev)
{
	printk(BIOS_DEBUG, "Initializing PCH PCIe bridge.\n");

	/* Enable SERR */
	pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR);

	/* Enable Bus Master */
	pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);

	/* Set Cache Line Size to 0x10 */
	pci_write_config8(dev, 0x0c, 0x10);

	pci_and_config16(dev, PCI_BRIDGE_CONTROL, ~PCI_BRIDGE_CTL_PARITY);

	/* Clear errors in status registers */
	pci_update_config16(dev, 0x06, ~0, 0);
	pci_update_config16(dev, 0x1e, ~0, 0);
}

static void pch_pcie_enable(struct device *dev)
{
	/* Add this device to the root port config structure. */
	root_port_init_config(dev);

	/* Check to see if this Root Port should be disabled. */
	root_port_check_disable(dev);

	/* Power Management init before enumeration */
	if (dev->enabled)
		pch_pcie_early(dev);

	/*
	 * When processing the last PCIe root port we can now
	 * update the Root Port Function Number and Hide register.
	 */
	if (root_port_is_last(dev))
		root_port_commit_config();
}

static void pcie_get_ltr_max_latencies(u16 *max_snoop, u16 *max_nosnoop)
{
	*max_snoop = PCIE_LTR_MAX_SNOOP_LATENCY_3146US;
	*max_nosnoop = PCIE_LTR_MAX_NO_SNOOP_LATENCY_3146US;
}

static struct pci_operations pcie_ops = {
	.set_subsystem = pci_dev_set_subsystem,
	.get_ltr_max_latencies = pcie_get_ltr_max_latencies,
};

static struct device_operations device_ops = {
	.read_resources		= pci_bus_read_resources,
	.set_resources		= pci_dev_set_resources,
	.enable_resources	= pci_bus_enable_resources,
	.init			= pch_pcie_init,
	.enable			= pch_pcie_enable,
	.scan_bus		= pciexp_scan_bridge,
	.ops_pci		= &pcie_ops,
};

static const unsigned short pcie_device_ids[] = {
	/* Lynxpoint-LP */
	0x9c10, 0x9c12, 0x9c14, 0x9c16, 0x9c18, 0x9c1a,
	/* WildcatPoint */
	0x9c90, 0x9c92, 0x9c94, 0x9c96, 0x9c98, 0x9c9a, 0x2448,
	0
};

static const struct pci_driver pch_pcie __pci_driver = {
	.ops	 = &device_ops,
	.vendor	 = PCI_VID_INTEL,
	.devices = pcie_device_ids,
};
