soc/intel/meteorlake: Allow to override Fast Vmode

This patch adds option to override Fast Vmode on Meteor Lake SoC.
This requires CepEnable, EnableFastVmode, IccLimit FSPM UPDs in FSP
header. If the hardware supports Fast Vmode, the FSPM will set the
ICC limit value to the value passed from coreboot.

With CepEnable and EnableFastVmode enabled, if IccLimit is not
specified by coreboot, FSPM sets IccLimit as default value. If no
values assigned to all the three CepEnable, EnableFastVmode and
IccLimit, coreboot sets their values to 0 and Fast Vmode is disabled.

BUG=b:286809233
TEST=In debug MTL FSP logs, the value of FSP parameters is as passed
from coreboot including enable_fast_vmode, cep_enable, and
fast_vmode_i_trip. Also, fast_vmode_i_trip value is passed to pcode
using mailbox command without any error. This test done on google/rex
board.

Signed-off-by: Jay Patel <jay2.patel@intel.com>
Change-Id: Id05dccac56c504523f9327babe0c6fbeff488ec2
Reviewed-on: https://review.coreboot.org/c/coreboot/+/75566
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jakub Czapiga <jacz@semihalf.com>
diff --git a/src/soc/intel/meteorlake/chip.h b/src/soc/intel/meteorlake/chip.h
index 178dd7c..2c3ec03 100644
--- a/src/soc/intel/meteorlake/chip.h
+++ b/src/soc/intel/meteorlake/chip.h
@@ -94,6 +94,20 @@
 		     | LPM_S0i3_0 | LPM_S0i3_1 | LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4,
 };
 
+/*
+ * As per definition from FSP header:
+ * - [0] for IA
+ * - [1] for GT
+ * - [2] for SA
+ * - [3] through [5] are reserved
+ */
+enum vr_domain {
+	VR_DOMAIN_IA,
+	VR_DOMAIN_GT,
+	VR_DOMAIN_SA,
+	NUM_VR_DOMAINS
+};
+
 struct soc_intel_meteorlake_config {
 
 	/* Common struct containing soc config data required by common code */
@@ -245,6 +259,29 @@
 	/* Enable/Disable EIST. 1b:Enabled, 0b:Disabled */
 	uint8_t eist_enable;
 
+	/*
+	 * When enabled, this feature makes the SoC throttle when the power
+	 * consumption exceeds the I_TRIP threshold.
+	 *
+	 * FSPs sets a by default I_TRIP threshold adapted to the current SoC
+	 * and assuming a Voltage Regulator error accuracy of 6.5%.
+	 */
+	bool enable_fast_vmode[NUM_VR_DOMAINS];
+
+	/*
+	 * Current Excursion Protection needs to be set for each VR domain
+	 * in order to be able to enable fast Vmode.
+	 */
+	bool cep_enable[NUM_VR_DOMAINS];
+
+	/*
+	 * VR Fast Vmode I_TRIP threshold.
+	 * 0-255A in 1/4 A units. Example: 400 = 100A
+	 * This setting overrides the default value set by FSPs when Fast VMode
+	 * is enabled.
+	 */
+	uint16_t fast_vmode_i_trip[NUM_VR_DOMAINS];
+
 	uint8_t PmTimerDisabled;
 	/*
 	 * SerialIO device mode selection:
diff --git a/src/soc/intel/meteorlake/romstage/fsp_params.c b/src/soc/intel/meteorlake/romstage/fsp_params.c
index fd634ec..bb5b6e7 100644
--- a/src/soc/intel/meteorlake/romstage/fsp_params.c
+++ b/src/soc/intel/meteorlake/romstage/fsp_params.c
@@ -224,6 +224,20 @@
 	m_cfg->SmbusEnable = is_devfn_enabled(PCI_DEVFN_SMBUS);
 }
 
+static void fill_fspm_vr_config_params(FSP_M_CONFIG *m_cfg,
+		const struct soc_intel_meteorlake_config *config)
+{
+	/* FastVmode Settings for VR domains */
+	for (size_t domain = 0; domain < NUM_VR_DOMAINS; domain++) {
+		m_cfg->CepEnable[domain] = config->cep_enable[domain];
+		if (m_cfg->CepEnable[domain]) {
+			m_cfg->EnableFastVmode[domain] = config->enable_fast_vmode[domain];
+			if (m_cfg->EnableFastVmode[domain])
+				m_cfg->IccLimit[domain] = config->fast_vmode_i_trip[domain];
+		}
+	}
+}
+
 static void fill_fspm_misc_params(FSP_M_CONFIG *m_cfg,
 		const struct soc_intel_meteorlake_config *config)
 {
@@ -360,6 +374,7 @@
 		fill_fspm_usb4_params,
 		fill_fspm_vtd_params,
 		fill_fspm_trace_params,
+		fill_fspm_vr_config_params,
 	};
 
 	for (size_t i = 0; i < ARRAY_SIZE(fill_fspm_params); i++)