/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2005 Linux Networx
 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pciexp.h>

#if IS_ENABLED(CONFIG_MMCONF_SUPPORT)
unsigned int pciexp_find_extended_cap(device_t dev, unsigned int cap)
{
	unsigned int this_cap_offset, next_cap_offset;
	unsigned int this_cap, cafe;

	this_cap_offset = PCIE_EXT_CAP_OFFSET;
	do {
		this_cap = pci_mmio_read_config32(dev, this_cap_offset);
		next_cap_offset = this_cap >> 20;
		this_cap &= 0xffff;
		cafe = pci_mmio_read_config32(dev, this_cap_offset + 4);
		cafe &= 0xffff;
		if (this_cap == cap)
			return this_cap_offset;
		else if (cafe == cap)
			return this_cap_offset + 4;
		else
			this_cap_offset = next_cap_offset;
	} while (next_cap_offset != 0);

	return 0;
}
#endif

#if CONFIG_PCIEXP_COMMON_CLOCK
/*
 * Re-train a PCIe link
 */
#define PCIE_TRAIN_RETRY 10000
static int pciexp_retrain_link(device_t dev, unsigned cap)
{
	unsigned try = PCIE_TRAIN_RETRY;
	u16 lnk;

	/* Start link retraining */
	lnk = pci_read_config16(dev, cap + PCI_EXP_LNKCTL);
	lnk |= PCI_EXP_LNKCTL_RL;
	pci_write_config16(dev, cap + PCI_EXP_LNKCTL, lnk);

	/* Wait for training to complete */
	while (try--) {
		lnk = pci_read_config16(dev, cap + PCI_EXP_LNKSTA);
		if (!(lnk & PCI_EXP_LNKSTA_LT))
			return 0;
		udelay(100);
	}

	printk(BIOS_ERR, "%s: Link Retrain timeout\n", dev_path(dev));
	return -1;
}

/*
 * Check the Slot Clock Configuration for root port and endpoint
 * and enable Common Clock Configuration if possible.  If CCC is
 * enabled the link must be retrained.
 */
static void pciexp_enable_common_clock(device_t root, unsigned root_cap,
				       device_t endp, unsigned endp_cap)
{
	u16 root_scc, endp_scc, lnkctl;

	/* Get Slot Clock Configuration for root port */
	root_scc = pci_read_config16(root, root_cap + PCI_EXP_LNKSTA);
	root_scc &= PCI_EXP_LNKSTA_SLC;

	/* Get Slot Clock Configuration for endpoint */
	endp_scc = pci_read_config16(endp, endp_cap + PCI_EXP_LNKSTA);
	endp_scc &= PCI_EXP_LNKSTA_SLC;

	/* Enable Common Clock Configuration and retrain */
	if (root_scc && endp_scc) {
		printk(BIOS_INFO, "Enabling Common Clock Configuration\n");

		/* Set in endpoint */
		lnkctl = pci_read_config16(endp, endp_cap + PCI_EXP_LNKCTL);
		lnkctl |= PCI_EXP_LNKCTL_CCC;
		pci_write_config16(endp, endp_cap + PCI_EXP_LNKCTL, lnkctl);

		/* Set in root port */
		lnkctl = pci_read_config16(root, root_cap + PCI_EXP_LNKCTL);
		lnkctl |= PCI_EXP_LNKCTL_CCC;
		pci_write_config16(root, root_cap + PCI_EXP_LNKCTL, lnkctl);

		/* Retrain link if CCC was enabled */
		pciexp_retrain_link(root, root_cap);
	}
}
#endif /* CONFIG_PCIEXP_COMMON_CLOCK */

#if CONFIG_PCIEXP_CLK_PM
static void pciexp_enable_clock_power_pm(device_t endp, unsigned endp_cap)
{
	/* check if per port clk req is supported in device */
	u32 endp_ca;
	u16 lnkctl;
	endp_ca = pci_read_config32(endp, endp_cap + PCI_EXP_LNKCAP);
	if ((endp_ca & PCI_EXP_CLK_PM) == 0) {
		printk(BIOS_INFO, "PCIE CLK PM is not supported by endpoint");
		return;
	}
	lnkctl = pci_read_config16(endp, endp_cap + PCI_EXP_LNKCTL);
	lnkctl = lnkctl | PCI_EXP_EN_CLK_PM;
	pci_write_config16(endp, endp_cap + PCI_EXP_LNKCTL, lnkctl);
}
#endif /* CONFIG_PCIEXP_CLK_PM */

#if IS_ENABLED(CONFIG_PCIEXP_L1_SUB_STATE) && IS_ENABLED(CONFIG_MMCONF_SUPPORT)
static void pcie_update_cfg(device_t dev, int reg, u32 mask, u32 or)
{
	u32 reg32;

	reg32 = pci_mmio_read_config32(dev, reg);
	reg32 &= mask;
	reg32 |= or;
	pci_mmio_write_config32(dev, reg, reg32);
}

static void pciexp_config_max_latency(device_t root, device_t dev)
{
	unsigned int cap;
	cap = pciexp_find_extended_cap(dev, PCIE_EXT_CAP_LTR_ID);
	if ((cap) && (root->ops->ops_pci != NULL) &&
		(root->ops->ops_pci->set_L1_ss_latency != NULL))
			root->ops->ops_pci->set_L1_ss_latency(dev, cap + 4);
}

static void pciexp_enable_ltr(device_t dev)
{
	unsigned int cap;
	cap = pci_find_capability(dev, PCI_CAP_ID_PCIE);
	if(!cap) {
		printk(BIOS_INFO, "Failed to enable LTR for dev = %s\n",
			dev_path(dev));
		return;
	}
	pcie_update_cfg(dev, cap + 0x28, ~(1 << 10), 1 << 10);
}

static unsigned char pciexp_L1_substate_cal(device_t dev, unsigned int endp_cap,
	unsigned int *data)
{
	unsigned char mult[4] = {2, 10, 100, 0};

	unsigned int L1SubStateSupport = *data & 0xf;
	unsigned int comm_mode_rst_time = (*data >> 8) & 0xff;
	unsigned int power_on_scale = (*data >> 16) & 0x3;
	unsigned int power_on_value = (*data >> 19) & 0x1f;

	unsigned int endp_data = pci_mmio_read_config32(dev, endp_cap + 4);
	unsigned int endp_L1SubStateSupport = endp_data & 0xf;
	unsigned int endp_comm_mode_restore_time = (endp_data >> 8) & 0xff;
	unsigned int endp_power_on_scale = (endp_data >> 16) & 0x3;
	unsigned int endp_power_on_value = (endp_data >> 19) & 0x1f;

	L1SubStateSupport &= endp_L1SubStateSupport;

	if (L1SubStateSupport == 0)
		return 0;

	if (power_on_value * mult[power_on_scale] <
		endp_power_on_value * mult[endp_power_on_scale]) {
		power_on_value = endp_power_on_value;
		power_on_scale = endp_power_on_scale;
	}
	if (comm_mode_rst_time < endp_comm_mode_restore_time)
		comm_mode_rst_time = endp_comm_mode_restore_time;

	*data = (comm_mode_rst_time << 8) | (power_on_scale << 16)
		| (power_on_value << 19) | L1SubStateSupport;

	return 1;
}

static void pciexp_L1_substate_commit(device_t root, device_t dev,
	unsigned int root_cap, unsigned int end_cap)
{
	device_t dev_t;
	unsigned char L1_ss_ok;
	unsigned int rp_L1_support = pci_mmio_read_config32(root, root_cap + 4);
	unsigned int L1SubStateSupport;
	unsigned int comm_mode_rst_time;
	unsigned int power_on_scale;
	unsigned int endp_power_on_value;

	for (dev_t = dev; dev_t; dev_t = dev_t->sibling) {
		/*
		 * rp_L1_support is init'd above from root port.
		 * it needs coordination with endpoints to reach in common.
		 * if certain endpoint doesn't support L1 Sub-State, abort
		 * this feature enabling.
		 */
		L1_ss_ok = pciexp_L1_substate_cal(dev_t, end_cap,
						&rp_L1_support);
		if (!L1_ss_ok)
			return;
	}

	L1SubStateSupport = rp_L1_support & 0xf;
	comm_mode_rst_time = (rp_L1_support >> 8) & 0xff;
	power_on_scale = (rp_L1_support >> 16) & 0x3;
	endp_power_on_value = (rp_L1_support >> 19) & 0x1f;

	printk(BIOS_INFO, "L1 Sub-State supported from root port %d\n",
		root->path.pci.devfn >> 3);
	printk(BIOS_INFO, "L1 Sub-State Support = 0x%x\n", L1SubStateSupport);
	printk(BIOS_INFO, "CommonModeRestoreTime = 0x%x\n", comm_mode_rst_time);
	printk(BIOS_INFO, "Power On Value = 0x%x, Power On Scale = 0x%x\n",
		endp_power_on_value, power_on_scale);

	pciexp_enable_ltr(root);

	pcie_update_cfg(root, root_cap + 0x08, ~0xff00,
		(comm_mode_rst_time << 8));

	pcie_update_cfg(root, root_cap + 0x0c , 0xffffff04,
		(endp_power_on_value << 3) | (power_on_scale));

	pcie_update_cfg(root, root_cap + 0x08, ~0xe3ff0000,
		(1 << 21) | (1 << 23) | (1 << 30));

	pcie_update_cfg(root, root_cap + 0x08, ~0x1f,
		L1SubStateSupport);

	for (dev_t = dev; dev_t; dev_t = dev_t->sibling) {
		pcie_update_cfg(dev_t, end_cap + 0x0c , 0xffffff04,
			(endp_power_on_value << 3) | (power_on_scale));

		pcie_update_cfg(dev_t, end_cap + 0x08, ~0xe3ff0000,
			(1 << 21) | (1 << 23) | (1 << 30));

		pcie_update_cfg(dev_t, end_cap + 0x08, ~0x1f,
			L1SubStateSupport);

		pciexp_enable_ltr(dev_t);

		pciexp_config_max_latency(root, dev_t);
	}
}

static void pciexp_config_L1_sub_state(device_t root, device_t dev)
{
	unsigned int root_cap, end_cap;

	/* Do it for function 0 only */
	if (dev->path.pci.devfn & 0x7)
		return;

	root_cap = pciexp_find_extended_cap(root, PCIE_EXT_CAP_L1SS_ID);
	if (!root_cap)
		return;

	end_cap = pciexp_find_extended_cap(dev, PCIE_EXT_CAP_L1SS_ID);
	if (!end_cap) {
		end_cap = pciexp_find_extended_cap(dev, 0xcafe);
		if (!end_cap)
			return;
	}

	pciexp_L1_substate_commit(root, dev, root_cap, end_cap);
}
#endif /* CONFIG_PCIEXP_L1_SUB_STATE */

#if CONFIG_PCIEXP_ASPM
/*
 * Determine the ASPM L0s or L1 exit latency for a link
 * by checking both root port and endpoint and returning
 * the highest latency value.
 */
static int pciexp_aspm_latency(device_t root, unsigned root_cap,
			       device_t endp, unsigned endp_cap,
			       enum aspm_type type)
{
	int root_lat = 0, endp_lat = 0;
	u32 root_lnkcap, endp_lnkcap;

	root_lnkcap = pci_read_config32(root, root_cap + PCI_EXP_LNKCAP);
	endp_lnkcap = pci_read_config32(endp, endp_cap + PCI_EXP_LNKCAP);

	/* Make sure the link supports this ASPM type by checking
	 * capability bits 11:10 with aspm_type offset by 1 */
	if (!(root_lnkcap & (1 << (type + 9))) ||
	    !(endp_lnkcap & (1 << (type + 9))))
		return -1;

	/* Find the one with higher latency */
	switch (type) {
	case PCIE_ASPM_L0S:
		root_lat = (root_lnkcap & PCI_EXP_LNKCAP_L0SEL) >> 12;
		endp_lat = (endp_lnkcap & PCI_EXP_LNKCAP_L0SEL) >> 12;
		break;
	case PCIE_ASPM_L1:
		root_lat = (root_lnkcap & PCI_EXP_LNKCAP_L1EL) >> 15;
		endp_lat = (endp_lnkcap & PCI_EXP_LNKCAP_L1EL) >> 15;
		break;
	default:
		return -1;
	}

	return (endp_lat > root_lat) ? endp_lat : root_lat;
}

/*
 * Enable ASPM on PCIe root port and endpoint.
 *
 * Returns APMC value:
 *   -1 = Error
 *    0 = no ASPM
 *    1 = L0s Enabled
 *    2 = L1 Enabled
 *    3 = L0s and L1 Enabled
 */
static enum aspm_type pciexp_enable_aspm(device_t root, unsigned root_cap,
					 device_t endp, unsigned endp_cap)
{
	const char *aspm_type_str[] = { "None", "L0s", "L1", "L0s and L1" };
	enum aspm_type apmc = PCIE_ASPM_NONE;
	int exit_latency, ok_latency;
	u16 lnkctl;
	u32 devcap;

	/* Get endpoint device capabilities for acceptable limits */
	devcap = pci_read_config32(endp, endp_cap + PCI_EXP_DEVCAP);

	/* Enable L0s if it is within endpoint acceptable limit */
	ok_latency = (devcap & PCI_EXP_DEVCAP_L0S) >> 6;
	exit_latency = pciexp_aspm_latency(root, root_cap, endp, endp_cap,
					   PCIE_ASPM_L0S);
	if (exit_latency >= 0 && exit_latency <= ok_latency)
		apmc |= PCIE_ASPM_L0S;

	/* Enable L1 if it is within endpoint acceptable limit */
	ok_latency = (devcap & PCI_EXP_DEVCAP_L1) >> 9;
	exit_latency = pciexp_aspm_latency(root, root_cap, endp, endp_cap,
					   PCIE_ASPM_L1);
	if (exit_latency >= 0 && exit_latency <= ok_latency)
		apmc |= PCIE_ASPM_L1;

	if (apmc != PCIE_ASPM_NONE) {
		/* Set APMC in root port first */
		lnkctl = pci_read_config16(root, root_cap + PCI_EXP_LNKCTL);
		lnkctl |= apmc;
		pci_write_config16(root, root_cap + PCI_EXP_LNKCTL, lnkctl);

		/* Set APMC in endpoint device next */
		lnkctl = pci_read_config16(endp, endp_cap + PCI_EXP_LNKCTL);
		lnkctl |= apmc;
		pci_write_config16(endp, endp_cap + PCI_EXP_LNKCTL, lnkctl);
	}

	printk(BIOS_INFO, "ASPM: Enabled %s\n", aspm_type_str[apmc]);
	return apmc;
}
#endif /* CONFIG_PCIEXP_ASPM */

static void pciexp_tune_dev(device_t dev)
{
	device_t root = dev->bus->dev;
	unsigned int root_cap, cap;

	cap = pci_find_capability(dev, PCI_CAP_ID_PCIE);
	if (!cap)
		return;

	root_cap = pci_find_capability(root, PCI_CAP_ID_PCIE);
	if (!root_cap)
		return;

#if CONFIG_PCIEXP_COMMON_CLOCK
	/* Check for and enable Common Clock */
	pciexp_enable_common_clock(root, root_cap, dev, cap);
#endif

#if CONFIG_PCIEXP_CLK_PM
	/* Check if per port CLK req is supported by endpoint*/
	pciexp_enable_clock_power_pm(dev, cap);
#endif

#if CONFIG_PCIEXP_L1_SUB_STATE
	/* Enable L1 Sub-State when both root port and endpoint support */
	pciexp_config_L1_sub_state(root, dev);
#endif /* CONFIG_PCIEXP_L1_SUB_STATE */

#if CONFIG_PCIEXP_ASPM
	/* Check for and enable ASPM */
	enum aspm_type apmc = pciexp_enable_aspm(root, root_cap, dev, cap);

	if (apmc != PCIE_ASPM_NONE) {
		/* Enable ASPM role based error reporting. */
		u32 reg32 = pci_read_config32(dev, cap + PCI_EXP_DEVCAP);
		reg32 |= PCI_EXP_DEVCAP_RBER;
		pci_write_config32(dev, cap + PCI_EXP_DEVCAP, reg32);
	}
#endif
}

void pciexp_scan_bus(struct bus *bus, unsigned int min_devfn,
			     unsigned int max_devfn)
{
	device_t child;

	pci_scan_bus(bus, min_devfn, max_devfn);

	for (child = bus->children; child; child = child->sibling) {
		if ((child->path.pci.devfn < min_devfn) ||
		    (child->path.pci.devfn > max_devfn)) {
			continue;
		}
		pciexp_tune_dev(child);
	}
}

void pciexp_scan_bridge(device_t dev)
{
	do_pci_scan_bridge(dev, pciexp_scan_bus);
}

/** Default device operations for PCI Express bridges */
static struct pci_operations pciexp_bus_ops_pci = {
	.set_subsystem = 0,
};

struct device_operations default_pciexp_ops_bus = {
	.read_resources   = pci_bus_read_resources,
	.set_resources    = pci_dev_set_resources,
	.enable_resources = pci_bus_enable_resources,
	.init             = 0,
	.scan_bus         = pciexp_scan_bridge,
	.enable           = 0,
	.reset_bus        = pci_bus_reset,
	.ops_pci          = &pciexp_bus_ops_pci,
};
