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

#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <fsp/api.h>
#include <soc/ramstage.h>
#include <soc/vr_config.h>
#include <console/console.h>
#include <intelblocks/cpulib.h>

/* Default values for domain configuration. */
static const struct vr_config default_configs[NUM_VR_DOMAINS] = {
	[VR_SYSTEM_AGENT] = {
		.vr_config_enable = 1,
		.psi1threshold = VR_CFG_AMP(20),
		.psi2threshold = VR_CFG_AMP(4),
		.psi3threshold = VR_CFG_AMP(1),
		.psi3enable = 1,
		.psi4enable = 1,
		.imon_slope = 0,
		.imon_offset = 0,
		.icc_max = 0,
		.voltage_limit = 1520,
	},
	[VR_IA_CORE] = {
		.vr_config_enable = 1,
		.psi1threshold = VR_CFG_AMP(20),
		.psi2threshold = VR_CFG_AMP(5),
		.psi3threshold = VR_CFG_AMP(1),
		.psi3enable = 1,
		.psi4enable = 1,
		.imon_slope = 0,
		.imon_offset = 0,
		.icc_max = 0,
		.voltage_limit = 1520,
	},
	[VR_GT_UNSLICED] = {
		.vr_config_enable = 1,
		.psi1threshold = VR_CFG_AMP(20),
		.psi2threshold = VR_CFG_AMP(5),
		.psi3threshold = VR_CFG_AMP(1),
		.psi3enable = 1,
		.psi4enable = 1,
		.imon_slope = 0,
		.imon_offset = 0,
		.icc_max = 0,
		.voltage_limit = 1520,
	},
	[VR_GT_SLICED] = {
		.vr_config_enable = 1,
		.psi1threshold = VR_CFG_AMP(20),
		.psi2threshold = VR_CFG_AMP(5),
		.psi3threshold = VR_CFG_AMP(1),
		.psi3enable = 1,
		.psi4enable = 1,
		.imon_slope = 0,
		.imon_offset = 0,
		.icc_max = 0,
		.voltage_limit = 1520,
	},
};

static uint16_t get_sku_icc_max(int domain)
{
	const uint16_t tdp = cpu_get_power_max() / 1000;

	static uint16_t mch_id = 0, igd_id = 0;
	if (!mch_id) {
		struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT);
		mch_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
	}
	if (!igd_id) {
		struct device *dev = pcidev_path_on_root(SA_DEVFN_IGD);
		igd_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
	}

	/*
	 * Iccmax table from Doc #559100 Section 7.2 DC Specifications, the
	 * Iccmax is the same among KBL-Y but KBL-U/R.
	 * Addendum for AML-Y #594883, IccMax for IA core is 28A.
	 * KBL-S #335195, KBL-H #335190, SKL-S #332687, SKL-H #332986,
	 * SKL-U/Y #332990
	 *
	 *   Platform             Segment           SA       IA      GT (GT/GTx)
	 * ---------------------------------------------------------------------
	 *   KBL/SKL-S            (95W) quad        11.1     100     45
	 *   SKL-S                (80W) quad        11.1     82      45
	 *   KBL/SKL-S            (65W) quad        11.1     79      45
	 *   SKL-S                (45W) quad        11.1     70      0
	 *   KBL/SKL-S            (35W) quad        11.1     66      35
	 *   SKL-S                (25W) quad        11.1     55      35
	 *
	 *   KBL/SKL-S            (54W) dual        11.1     58      48
	 *   KBL/SKL-S            (51W) dual        11.1     45      48
	 *   KBL/SKL-S            (35W) dual        11.1     40      48
	 *
	 *   SKL-H + OPC          (65W) GT4 quad    8        74      105/24
	 *   SKL-H + OPC          (45W) GT4 quad    8        74      94/20
	 *   SKL-H + OPC          (35W) GT4 quad    8        66      94/20
	 *
	 *   SKL-H                (35W) GT2 dual    11.1     60      55
	 *
	 *   KBL/SKL-H            (45W) GT2 quad    11.1     68      55
	 *   KBL-H                (18W) GT2 quad    6.6      60      55
	 *
	 *   SKL-U + OPC          (28W) GT3 dual    5.1      32      57/19
	 *   SKL-U + OPC          (15W) GT3 dual    5.1      29      57/19
	 *   SKL-U                (15W) GT2 dual    4.5      29      31
	 *
	 *   KBL-U + OPC          (28W) GT3 dual    5.1      32      57/19
	 *   KBL-U + OPC          (15W) GT3 dual    5.1      32      57/19
	 *   KBL-U                (15W) GT1/2 dual  4.5      32      31
	 *   KBL-U [*]            (15W) GT1 quad    4.5      29      31
	 *
	 *   KBL-U/R              (15W) GT2 quad    6        64      31
	 *
	 *   SKL/KBL-Y            (6W)              4.1      24      24
	 *   SKL/KBL-Y            (4.5W)            4.1      24      24
	 *
	 *   [*] Pentium/Celeron CPUs with HD Graphics 610
	 */

	switch (mch_id) {
	case PCI_DEVICE_ID_INTEL_SKL_ID_S_2: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_S: {
		uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(11.1, 40, 48, 48);
		if (tdp >= 54)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(58);
		else if (tdp >= 51)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(45);

		return icc_max[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_S_4:  /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_DT_2: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_DT: {
		uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(11.1, 55, 45, 45);
		if (tdp >= 91)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(100);
		else if (tdp >= 80)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(82);
		else if (tdp >= 65)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(79);
		else if (tdp >= 45) {
			icc_max[VR_IA_CORE] = VR_CFG_AMP(70);
			icc_max[VR_GT_SLICED] = 0;
			icc_max[VR_GT_UNSLICED] = 0;
		} else if (tdp >= 25) {
			if (tdp >= 35)
				icc_max[VR_IA_CORE] = VR_CFG_AMP(66);

			icc_max[VR_GT_SLICED] = VR_CFG_AMP(35);
			icc_max[VR_GT_UNSLICED] = VR_CFG_AMP(35);
		}

		return icc_max[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_H_4: {
		uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(11.1, 60, 94, 20);
		if (tdp >= 45) {
			icc_max[VR_IA_CORE] = VR_CFG_AMP(74);
			if (tdp >= 65) {
				icc_max[VR_GT_SLICED] = VR_CFG_AMP(105);
				icc_max[VR_GT_UNSLICED] = VR_CFG_AMP(24);
			}
		}
		return icc_max[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_H_2:  /* fallthrough */
	case PCI_DEVICE_ID_INTEL_SKL_ID_H_EM: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_H: {
		uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(6.6, 60, 55, 55);
		if (tdp >= 35) {
			if (tdp >= 45)
				icc_max[VR_IA_CORE] = VR_CFG_AMP(68);

			icc_max[VR_SYSTEM_AGENT] = VR_CFG_AMP(11.1);
		}

		return icc_max[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_U: {
		uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(5.1, 29, 57, 19);
		if (tdp >= 28)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(32);
		else if (igd_id != PCI_DEVICE_ID_INTEL_SKL_GT3E_SULTM_1) {
			const uint16_t icc_max_gt2[NUM_VR_DOMAINS] =
				VR_CFG_ALL_DOMAINS_ICC(4.5, 29, 31, 31);

			return icc_max_gt2[domain];
		}
		return icc_max[domain];
	}
	case PCI_DEVICE_ID_INTEL_KBL_U_R: {
		const uint16_t icc_max[NUM_VR_DOMAINS] =
				VR_CFG_ALL_DOMAINS_ICC(6, 64, 31, 31);
		return icc_max[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_Y: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_Y: {
		uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(4.1, 24, 24, 24);

		if (igd_id == PCI_DEVICE_ID_INTEL_AML_GT2_ULX)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(28);

		return icc_max[domain];
	}
	case PCI_DEVICE_ID_INTEL_KBL_ID_U: {
		uint16_t icc_max[NUM_VR_DOMAINS] = VR_CFG_ALL_DOMAINS_ICC(4.5, 32, 31, 31);

		if (igd_id == PCI_DEVICE_ID_INTEL_KBL_GT1_SULTM)
			icc_max[VR_IA_CORE] = VR_CFG_AMP(29);

		else if ((igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_1) ||
		         (igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_2)) {
			const uint16_t icc_max_gt3[NUM_VR_DOMAINS] =
				VR_CFG_ALL_DOMAINS_ICC(5.1, 32, 57, 19);

			return icc_max_gt3[domain];
		}

		return icc_max[domain];
	}
	default:
		printk(BIOS_ERR, "Unknown MCH (0x%x) in %s\n", mch_id, __func__);
	}
	return 0;
}

static uint16_t get_sku_ac_dc_loadline(const int domain)
{
	static uint16_t mch_id = 0, igd_id = 0;
	if (!mch_id) {
		struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT);
		mch_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
	}
	if (!igd_id) {
		struct device *dev = pcidev_path_on_root(SA_DEVFN_IGD);
		igd_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
	}

	switch (mch_id) {
	case PCI_DEVICE_ID_INTEL_SKL_ID_S_2: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_SKL_ID_S_4: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_S:   /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_DT:  /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_DT_2: {
		/* SA Loadline is not specified */
		const uint16_t loadline[NUM_VR_DOMAINS] =
				VR_CFG_ALL_DOMAINS_LOADLINE(0, 2.1, 3.1, 3.1);
		return loadline[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_H_2:  /* fallthrough */
	case PCI_DEVICE_ID_INTEL_SKL_ID_H_EM: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_SKL_ID_H_4:  /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_H: {
		const uint16_t loadline[NUM_VR_DOMAINS] =
				VR_CFG_ALL_DOMAINS_LOADLINE(10, 1.8, 2.65, 2.65);

		if (igd_id == PCI_DEVICE_ID_INTEL_SKL_GT4_SHALM) {
			const uint16_t loadline_gt4[NUM_VR_DOMAINS] =
					VR_CFG_ALL_DOMAINS_LOADLINE(6, 1.6, 1.4, 6);
			return loadline_gt4[domain];
		}

		return loadline[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_Y: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_Y: {
		uint16_t loadline[NUM_VR_DOMAINS] =
				VR_CFG_ALL_DOMAINS_LOADLINE(18, 5.9, 5.7, 5.7);

		if (igd_id == PCI_DEVICE_ID_INTEL_AML_GT2_ULX)
			loadline[VR_IA_CORE] = VR_CFG_MOHMS(4);

		return loadline[domain];
	}
	case PCI_DEVICE_ID_INTEL_SKL_ID_U: /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_U_R:  /* fallthrough */
	case PCI_DEVICE_ID_INTEL_KBL_ID_U: {
		uint16_t loadline[NUM_VR_DOMAINS] =
				VR_CFG_ALL_DOMAINS_LOADLINE(10.3, 2.4, 3.1, 3.1);

		if ((igd_id == PCI_DEVICE_ID_INTEL_SKL_GT3E_SULTM_1) ||
		    (igd_id == PCI_DEVICE_ID_INTEL_SKL_GT3E_SULTM_2) ||
		    (igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_1) ||
		    (igd_id == PCI_DEVICE_ID_INTEL_KBL_GT3E_SULTM_2)) {
			loadline[VR_GT_UNSLICED] = VR_CFG_MOHMS(2);
			loadline[VR_GT_SLICED] = VR_CFG_MOHMS(6);
		}

		return loadline[domain];
	}
	default:
		printk(BIOS_ERR, "Unknown MCH (0x%x) in %s\n", mch_id, __func__);
	}
	return 0;
}

void fill_vr_domain_config(void *params,
		int domain, const struct vr_config *chip_cfg)
{
	FSP_SIL_UPD *vr_params = (FSP_SIL_UPD *)params;
	const struct vr_config *cfg;

	if (domain < 0 || domain >= NUM_VR_DOMAINS)
		return;

	/* Use device tree override if requested. */
	if (chip_cfg->vr_config_enable)
		cfg = chip_cfg;
	else
		cfg = &default_configs[domain];

	vr_params->VrConfigEnable[domain] = cfg->vr_config_enable;
	vr_params->Psi1Threshold[domain] = cfg->psi1threshold;
	vr_params->Psi2Threshold[domain] = cfg->psi2threshold;
	vr_params->Psi3Threshold[domain] = cfg->psi3threshold;
	vr_params->Psi3Enable[domain] = cfg->psi3enable;
	vr_params->Psi4Enable[domain] = cfg->psi4enable;
	vr_params->ImonSlope[domain] = cfg->imon_slope;
	vr_params->ImonOffset[domain] = cfg->imon_offset;

	/* If board provided non-zero value, use it. */
	if (cfg->icc_max)
		vr_params->IccMax[domain] = cfg->icc_max;
	else
		vr_params->IccMax[domain] = get_sku_icc_max(domain);
	vr_params->VrVoltageLimit[domain] = cfg->voltage_limit;

	if (cfg->ac_loadline)
		vr_params->AcLoadline[domain] = cfg->ac_loadline;
	else
		vr_params->AcLoadline[domain] = get_sku_ac_dc_loadline(domain);
	if (cfg->dc_loadline)
		vr_params->DcLoadline[domain] = cfg->dc_loadline;
	else
		vr_params->DcLoadline[domain] = get_sku_ac_dc_loadline(domain);
}
