soc/intel/meteorlake: Expose In-Band ECC UPD config to mainboard

Meteor Lake has a UPD config called In-Band ECC(IBECC) which uses a part of the system DRAM to store the ECC information. There are a few UPD parameters in FSP-M to configure this feature as needed.

This patch adds code to expose these parameters to the devicetree so
that they can be configured on the mainboard level as needed.

Change-Id: Ice1ede430d36dff4175a92941ee85cc933fa56d5
Signed-off-by: Marx Wang <marx.wang@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/78485
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Eric Lai <ericllai@google.com>
diff --git a/src/soc/intel/meteorlake/chip.h b/src/soc/intel/meteorlake/chip.h
index 818cc05..57471b7 100644
--- a/src/soc/intel/meteorlake/chip.h
+++ b/src/soc/intel/meteorlake/chip.h
@@ -18,9 +18,28 @@
 #include <soc/usb.h>
 #include <stdint.h>
 
+/* Define config parameters for In-Band ECC (IBECC). */
+#define MAX_IBECC_REGIONS 8
+
 #define MAX_SAGV_POINTS 4
 #define MAX_HD_AUDIO_SDI_LINKS 2
 
+/* In-Band ECC Operation Mode */
+enum ibecc_mode {
+	IBECC_MODE_PER_REGION,
+	IBECC_MODE_NONE,
+	IBECC_MODE_ALL
+};
+
+struct ibecc_config {
+	bool enable;
+	bool parity_en;
+	enum ibecc_mode mode;
+	bool region_enable[MAX_IBECC_REGIONS];
+	uint16_t region_base[MAX_IBECC_REGIONS];
+	uint16_t region_mask[MAX_IBECC_REGIONS];
+};
+
 /* Types of different SKUs */
 enum soc_intel_meteorlake_power_limits {
 	MTL_P_282_242_CORE,
@@ -151,6 +170,9 @@
 	/* TCC activation offset */
 	uint32_t tcc_offset;
 
+	/* In-Band ECC (IBECC) configuration */
+	struct ibecc_config ibecc;
+
 	/* System Agent dynamic frequency support. Only effects ULX/ULT CPUs.
 	 * When enabled memory will be training at two different frequencies.
 	 * 0:Disabled, 1:Enabled
diff --git a/src/soc/intel/meteorlake/romstage/fsp_params.c b/src/soc/intel/meteorlake/romstage/fsp_params.c
index 2d8a6c7..8f64d4f 100644
--- a/src/soc/intel/meteorlake/romstage/fsp_params.c
+++ b/src/soc/intel/meteorlake/romstage/fsp_params.c
@@ -361,6 +361,25 @@
 	}
 }
 
+static void fill_fspm_ibecc_params(FSP_M_CONFIG *m_cfg,
+		const struct soc_intel_meteorlake_config *config)
+{
+	/* In-Band ECC configuration */
+	if (config->ibecc.enable) {
+		m_cfg->Ibecc = config->ibecc.enable;
+		m_cfg->IbeccParity = config->ibecc.parity_en;
+		m_cfg->IbeccOperationMode = config->ibecc.mode;
+		if (m_cfg->IbeccOperationMode == IBECC_MODE_PER_REGION) {
+			FSP_ARRAY_LOAD(m_cfg->IbeccProtectedRegionEnable,
+				       config->ibecc.region_enable);
+			FSP_ARRAY_LOAD(m_cfg->IbeccProtectedRegionBase,
+				       config->ibecc.region_base);
+			FSP_ARRAY_LOAD(m_cfg->IbeccProtectedRegionMask,
+				       config->ibecc.region_mask);
+		}
+	}
+}
+
 static void soc_memory_init_params(FSP_M_CONFIG *m_cfg,
 		const struct soc_intel_meteorlake_config *config)
 {
@@ -383,6 +402,7 @@
 		fill_fspm_vtd_params,
 		fill_fspm_trace_params,
 		fill_fspm_vr_config_params,
+		fill_fspm_ibecc_params,
 	};
 
 	for (size_t i = 0; i < ARRAY_SIZE(fill_fspm_params); i++)