src/soc/intel/xeon_sp/cpx: Add enable IIO error masks

This adds functionality to mask certain IIO errors on the root complex as recommended by HW vendor.

Tested on DeltaLake mainboard. Boot to OS, verify IIO mask registers are programmed correctly.

Signed-off-by: Rocky Phagura <rphagura@fb.com>
Change-Id: I99f05928930bbf1f617c2d8ce31e8df2a6fd15e6
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50843
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Marc Jones <marc@marcjonesconsulting.com>
diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c
index 2c731da..46cb7d0 100644
--- a/src/soc/intel/xeon_sp/cpx/chip.c
+++ b/src/soc/intel/xeon_sp/cpx/chip.c
@@ -67,6 +67,49 @@
 	}
 }
 
+static void iio_write_mask(u16 bus, u16 dev, u8 func)
+{
+	pci_devfn_t device = PCI_DEV(bus, dev, func);
+	u32 val = pci_s_read_config32(device, IIO_XPUNCCERRMSK_REG);
+	val |= (SENT_PCIE_UNSUPP_MASK | RCVD_PCIE_CA_STS_MASK | RCVD_PCIE_UR_STS_MASK);
+	pci_s_write_config32(device, IIO_XPUNCCERRMSK_REG, val);
+
+	val = pci_s_read_config32(device, RP_UNCERRMSK);
+	val |= (SURPRISE_DWN_ERR_MSK | UNSUPPORTED_REQ_ERR_MSK);
+	pci_s_write_config32(device, RP_UNCERRMSK, val);
+}
+
+static void iio_dmi_en_masks(void)
+{
+	pci_devfn_t device;
+	u32 val;
+	device = PCI_DEV(DMI_BUS_INDEX, DMI_DEV, DMI_FUNC);
+	val = pci_s_read_config32(device, IIO_XPUNCCERRMSK_REG);
+	val |= (SENT_PCIE_UNSUPP_MASK | RCVD_PCIE_CA_STS_MASK | RCVD_PCIE_UR_STS_MASK);
+	pci_s_write_config32(device, IIO_XPUNCCERRMSK_REG, val);
+
+	val = pci_s_read_config32(device, DMI_UNCERRMSK);
+	val |= (ECRC_ERR | MLFRMD_TLP | RCV_BUF_OVRFLOW | FLOW_CNTR | POISON_TLP | DLL_PRT_ERR);
+	pci_s_write_config32(device, DMI_UNCERRMSK, val);
+}
+
+static void iio_enable_masks(void)
+{
+	struct iiostack_resource iio = {0};
+	get_iiostack_info(&iio);
+	int i, k;
+	for (i = 0; i < iio.no_of_stacks; i++) {
+		const STACK_RES *st = &iio.res[i];
+		if (st->BusBase > 0 && st->BusBase != 0xff) {
+			for (k = 0; k < DEVICES_PER_IIO_STACK; k++) {
+				printk(BIOS_DEBUG, "%s: bus:%x dev:%x func:%x\n", __func__,
+					st->BusBase, k, 0);
+				iio_write_mask(st->BusBase, k, 0);
+			}
+		}
+	}
+	iio_dmi_en_masks();
+}
 static void chip_final(void *data)
 {
 	/* Lock SBI */
@@ -84,7 +127,7 @@
 	pci_io_write_config8(PCI_DEV(0, 0, 0), 0x88, reg8 | (1 << 4));
 
 	p2sb_hide();
-
+	iio_enable_masks();
 	set_bios_init_completion();
 }
 
diff --git a/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
index 8f7f92a..46c034c 100644
--- a/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
+++ b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h
@@ -92,6 +92,16 @@
 #define APIC_DEV_NUM            0x05
 #define APIC_FUNC_NUM           0x04
 
+/* Root port Registers */
+#define RP_UNCERRMSK			0x150
+#define  SURPRISE_DWN_ERR_MSK		(1 << 5)
+#define  UNSUPPORTED_REQ_ERR_MSK	(1 << 20)
+#define IIO_XPUNCCERRMSK_REG		0x20c
+#define  SENT_PCIE_UNSUPP_MASK		(1 << 4)
+#define  RCVD_PCIE_CA_STS_MASK		(1 << 5)
+#define  RCVD_PCIE_UR_STS_MASK		(1 << 6)
+
+#define DEVICES_PER_IIO_STACK		4
 
 /* PCH Device info */
 
@@ -138,6 +148,19 @@
 #define DMI3_DEVID		0x2020
 #define DMIRCBAR		0x50
 #define ERRINJCON		0x1d8
+#define DMI_BUS_INDEX		0
+#define DMI_DEV			0
+#define DMI_FUNC		0
+#define DMI_ERRCAP_REG		0x160
+#define DMI_RPERR_CMD_REG	0x174
+#define DMI_UNCERRMSK		0x150
+#define  ECRC_ERR		(1 << 19)
+#define  MLFRMD_TLP		(1 << 18)
+#define  RCV_BUF_OVRFLOW	(1 << 17)
+#define  FLOW_CNTR		(1 << 13)
+#define  POISON_TLP		(1 << 12)
+#define  DLL_PRT_ERR		(1 << 4)
+
 
 // IIO DFX Global D7F7 registers
 #define IIO_DFX_TSWCTL0		0x30c