soc/intel/alderlake: Add support to update the FIVR configs

This patch adds the supports to update the optimal FIVR
configurations for external voltage rails via devicetree.

Signed-off-by: V Sowmya <v.sowmya@intel.com>
Change-Id: Icf6c74bda5a167abf63938ebed6affc6b31c76f5
Reviewed-on: https://review.coreboot.org/c/coreboot/+/55702
Reviewed-by: Subrata Banik <subrata.banik@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/intel/alderlake/chip.h b/src/soc/intel/alderlake/chip.h
index 58daa25..709ab3c 100644
--- a/src/soc/intel/alderlake/chip.h
+++ b/src/soc/intel/alderlake/chip.h
@@ -43,6 +43,35 @@
 	DDI_ENABLE_HPD = 1 << 1,
 };
 
+/*
+ * Enable External V1P05/Vnn/VnnSx Rail in: BIT0:S0i1/S0i2,
+ * BIT1:S0i3, BIT2:S3, BIT3:S4, BIT4:S5
+ */
+enum fivr_enable_states {
+	FIVR_ENABLE_S0i1_S0i2	= BIT(0),
+	FIVR_ENABLE_S0i3	= BIT(1),
+	FIVR_ENABLE_S3		= BIT(2),
+	FIVR_ENABLE_S4		= BIT(3),
+	FIVR_ENABLE_S5		= BIT(4),
+};
+
+/*
+ * Enable the following for External V1p05 rail
+ * BIT0: Retention active switch support
+ * BIT1: Normal Active voltage supported
+ * BIT2: Minimum active voltage supported
+ * BIT3: Minimum Retention voltage supported
+ */
+enum fivr_voltage_supported {
+	FIVR_RET_ACTIVE_SWITCH_SUPPORT	= BIT(0),
+	FIVR_VOLTAGE_NORMAL		= BIT(1),
+	FIVR_VOLTAGE_MIN_ACTIVE		= BIT(2),
+	FIVR_VOLTAGE_MIN_RETENTION	= BIT(3),
+};
+
+#define FIVR_ENABLE_ALL_SX (FIVR_ENABLE_S0i1_S0i2 | FIVR_ENABLE_S0i3 |	\
+			    FIVR_ENABLE_S3 | FIVR_ENABLE_S4 | FIVR_ENABLE_S5)
+
 struct soc_intel_alderlake_config {
 
 	/* Common struct containing soc config data required by common code */
@@ -324,6 +353,26 @@
 		ISA_SERIAL_BASE_ADDR_3F8,
 		ISA_SERIAL_BASE_ADDR_2F8,
 	} IsaSerialUartBase;
+
+	/* structure containing various settings for PCH FIVRs */
+	struct {
+		bool configure_ext_fivr;
+		enum fivr_enable_states v1p05_enable_bitmap;
+		enum fivr_enable_states vnn_enable_bitmap;
+		enum fivr_enable_states vnn_sx_enable_bitmap;
+		enum fivr_voltage_supported v1p05_supported_voltage_bitmap;
+		enum fivr_voltage_supported vnn_supported_voltage_bitmap;
+		/* V1p05 Rail Voltage in mv  */
+		int v1p05_voltage_mv;
+		/* Vnn Rail Voltage in mv  */
+		int vnn_voltage_mv;
+		/* VnnSx Rail Voltage in mv  */
+		int vnn_sx_voltage_mv;
+		/* External Icc Max for V1p05 rail in mA  */
+		int v1p05_icc_max_ma;
+		/* External Icc Max for VnnSx rail in mA  */
+		int vnn_icc_max_ma;
+	} ext_fivr_settings;
 };
 
 typedef struct soc_intel_alderlake_config config_t;
diff --git a/src/soc/intel/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c
index e29133e..5b0d631 100644
--- a/src/soc/intel/alderlake/fsp_params.c
+++ b/src/soc/intel/alderlake/fsp_params.c
@@ -549,6 +549,45 @@
 	printk(BIOS_INFO, "IRQ: Using dynamically assigned PCI IO-APIC IRQs\n");
 }
 
+static void fill_fsps_fivr_params(FSP_S_CONFIG *s_cfg,
+		const struct soc_intel_alderlake_config *config)
+{
+	/* PCH FIVR settings override */
+	if (!config->ext_fivr_settings.configure_ext_fivr)
+		return;
+
+	s_cfg->PchFivrExtV1p05RailEnabledStates =
+			config->ext_fivr_settings.v1p05_enable_bitmap;
+
+	s_cfg->PchFivrExtV1p05RailSupportedVoltageStates =
+			config->ext_fivr_settings.v1p05_supported_voltage_bitmap;
+
+	s_cfg->PchFivrExtVnnRailEnabledStates =
+			config->ext_fivr_settings.vnn_enable_bitmap;
+
+	s_cfg->PchFivrExtVnnRailSupportedVoltageStates =
+			config->ext_fivr_settings.vnn_supported_voltage_bitmap;
+
+	s_cfg->PchFivrExtVnnRailSxEnabledStates =
+			config->ext_fivr_settings.vnn_enable_bitmap;
+
+	/* Convert the voltages to increments of 2.5mv */
+	s_cfg->PchFivrExtV1p05RailVoltage =
+			(config->ext_fivr_settings.v1p05_voltage_mv * 10) / 25;
+
+	s_cfg->PchFivrExtVnnRailVoltage =
+			(config->ext_fivr_settings.vnn_voltage_mv * 10) / 25;
+
+	s_cfg->PchFivrExtVnnRailSxVoltage =
+			(config->ext_fivr_settings.vnn_sx_voltage_mv * 10 / 25);
+
+	s_cfg->PchFivrExtV1p05RailIccMaximum =
+			config->ext_fivr_settings.v1p05_icc_max_ma;
+
+	s_cfg->PchFivrExtVnnRailIccMaximum =
+			config->ext_fivr_settings.vnn_icc_max_ma;
+}
+
 static void arch_silicon_init_params(FSPS_ARCH_UPD *s_arch_cfg)
 {
 	/* EnableMultiPhaseSiliconInit for running MultiPhaseSiInit */
@@ -583,6 +622,7 @@
 		fill_fsps_pcie_params,
 		fill_fsps_misc_power_params,
 		fill_fsps_irq_params,
+		fill_fsps_fivr_params,
 	};
 
 	for (size_t i = 0; i < ARRAY_SIZE(fill_fsps_params); i++)