soc/intel/xeon_sp: Select INTEL_COMMON_BLOCK_TCO

TCO is configured by FSP. This mostly makes it possible to report TCO
events in SMM if enabled.

Change-Id: I4f81c7888e45ed01ee68b1d6e6a9986a4d735467
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47764
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/intel/xeon_sp/Kconfig b/src/soc/intel/xeon_sp/Kconfig
index ea38dfd..2b1034b 100644
--- a/src/soc/intel/xeon_sp/Kconfig
+++ b/src/soc/intel/xeon_sp/Kconfig
@@ -52,6 +52,7 @@
 	select SOC_INTEL_COMMON_BLOCK_P2SB
 	select SOC_INTEL_COMMON_BLOCK_PMC
 	select SOC_INTEL_COMMON_BLOCK_PMC_DISCOVERABLE
+	select SOC_INTEL_COMMON_BLOCK_TCO
 	select TSC_MONOTONIC_TIMER
 	select UDELAY_TSC
 	select SUPPORT_CPU_UCODE_IN_CBFS
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 bcb2641..53503df 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
@@ -102,10 +102,12 @@
 #define  PCH_DEVFN_LPC          _PCH_DEVFN(LPC, 0)
 #define  PCH_DEVFN_P2SB         _PCH_DEVFN(LPC, 1)
 #define  PCH_DEVFN_PMC          _PCH_DEVFN(LPC, 2)
+#define  PCH_DEVFN_SMBUS        _PCH_DEVFN(LPC, 4)
 #define  PCH_DEVFN_SPI          _PCH_DEVFN(LPC, 5)
 #define  PCH_DEV_LPC            _PCH_DEV(LPC, 0)
 #define  PCH_DEV_P2SB           _PCH_DEV(LPC, 1)
 #define  PCH_DEV_PMC            _PCH_DEV(LPC, 2)
+#define  PCH_DEV_SMBUS          _PCH_DEV(LPC, 4)
 #define  PCH_DEV_SPI            _PCH_DEV(LPC, 5)
 
 #define HPET_BUS_NUM            0x0
diff --git a/src/soc/intel/xeon_sp/include/soc/smbus.h b/src/soc/intel/xeon_sp/include/soc/smbus.h
new file mode 100644
index 0000000..00aae2c
--- /dev/null
+++ b/src/soc/intel/xeon_sp/include/soc/smbus.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SMBUS_H_
+#define _SOC_SMBUS_H_
+
+/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */
+#define TCO1_STS			0x04
+#define  TCO_TIMEOUT			(1 << 3)
+#define TCO2_STS			0x06
+#define  TCO_STS_SECOND_TO		(1 << 1)
+#define  TCO_INTRD_DET			(1 << 0)
+#define TCO1_CNT			0x08
+#define  TCO_LOCK			(1 << 12)
+#define  TCO_TMR_HLT			(1 << 11)
+#define TCO2_CNT			0x0A
+#define  TCO_INTRD_SEL_MASK		(3 << 1)
+#define  TCO_INTRD_SEL_SMI		(1 << 2)
+#define  TCO_INTRD_SEL_INT		(1 << 1)
+
+/* SMBus I/O bits. */
+#define SMBUS_SLAVE_ADDR	0x24
+
+#endif
diff --git a/src/soc/intel/xeon_sp/pmc.c b/src/soc/intel/xeon_sp/pmc.c
index a418ae5..b4f86db 100644
--- a/src/soc/intel/xeon_sp/pmc.c
+++ b/src/soc/intel/xeon_sp/pmc.c
@@ -193,3 +193,25 @@
 	*smi_arr = ARRAY_SIZE(smi_sts_bits);
 	return smi_sts_bits;
 }
+
+const char *const *soc_tco_sts_array(size_t *tco_arr)
+{
+	static const char *const tco_sts_bits[] = {
+		[0] = "NMI2SMI",
+		[1] = "OS_TCO",
+		[2] = "TCO_INT",
+		[3] = "TIMEOUT",
+		[7] = "NEWCENTURY",
+		[8] = "BIOSWR",
+		[9] = "CPUSCI",
+		[10] = "CPUSMI",
+		[12] = "CPUSERR",
+		[13] = "SLVSEL",
+		[16] = "INTRD_DET",
+		[17] = "SECOND_TO",
+		[20] = "SMLINK_SLV"
+	};
+
+	*tco_arr = ARRAY_SIZE(tco_sts_bits);
+	return tco_sts_bits;
+}
diff --git a/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h
index cd5d553..3539555 100644
--- a/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h
+++ b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h
@@ -141,10 +141,12 @@
 #define  PCH_DEVFN_LPC          _PCH_DEVFN(LPC, 0)
 #define  PCH_DEVFN_P2SB         _PCH_DEVFN(LPC, 1)
 #define  PCH_DEVFN_PMC          _PCH_DEVFN(LPC, 2)
+#define  PCH_DEVFN_SMBUS        _PCH_DEVFN(LPC, 4)
 #define  PCH_DEVFN_SPI          _PCH_DEVFN(LPC, 5)
 #define  PCH_DEV_LPC            _PCH_DEV(LPC, 0)
 #define  PCH_DEV_P2SB           _PCH_DEV(LPC, 1)
 #define  PCH_DEV_PMC            _PCH_DEV(LPC, 2)
+#define  PCH_DEV_SMBUS          _PCH_DEV(LPC, 4)
 #define  PCH_DEV_SPI            _PCH_DEV(LPC, 5)
 
 #define CBDMA_DEV_NUM           0x04