mb/msi/ms7d25: Configure PCIe Root Ports

Add the full PCIe root port configuration. Proper initialization of
the root ports depends on the correct GPIO programming including
virtual wires. Do not program the CLKREQ signals in coreboot to let FSP
detect and configure CLKREQ pads. Otherwise the CLKREQ pads are
reprogrammed by FSP despite having GpioOverride=1. The pads that
should not be touched by coreboot are left commented in the board GPIO
file. CLKREQ reprogramming caused undefined behavior when ASPM and
Clock PM was being enabled by coreboot on PCIe endpoints of CPU PCIe
x4 slot (coreboot printed a lot of exceptions and simply halted).

TEST=Boot the MSI PRO Z690-A DDR4 WiFi with all PCIe/M.2 slots
populated and check if they are detected and functional in Linux.

Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Change-Id: I50199d2caf54509a72c5100acb770bf766327e7f
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63656
Reviewed-by: Krystian Hebel <krystian.hebel@3mdeb.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/configs/config.msi_ms7d25 b/configs/config.msi_ms7d25
index e016a70..ed042f5 100644
--- a/configs/config.msi_ms7d25
+++ b/configs/config.msi_ms7d25
@@ -3,7 +3,9 @@
 CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000
 CONFIG_TIANOCORE_BOOT_TIMEOUT=3
 CONFIG_BOARD_MSI_Z690_A_PRO_WIFI_DDR4=y
-# CONFIG_SMMSTORE is not set
+CONFIG_POWER_STATE_OFF_AFTER_FAILURE=y
+CONFIG_PCIEXP_HOTPLUG=y
+CONFIG_PCIEXP_HOTPLUG_PREFETCH_MEM_BELOW_4G=y
 CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0=y
 CONFIG_POST_DEVICE_PCI_PCIE=y
 CONFIG_POST_IO_PORT=0x80
@@ -13,4 +15,3 @@
 CONFIG_TIANOCORE_CBMEM_LOGGING=y
 CONFIG_TIANOCORE_FOLLOW_BGRT_SPEC=y
 CONFIG_TIANOCORE_SD_MMC_TIMEOUT=1000
-CONFIG_POWER_STATE_OFF_AFTER_FAILURE=y
diff --git a/src/mainboard/msi/ms7d25/devicetree.cb b/src/mainboard/msi/ms7d25/devicetree.cb
index 8644ad5..78ad207 100644
--- a/src/mainboard/msi/ms7d25/devicetree.cb
+++ b/src/mainboard/msi/ms7d25/devicetree.cb
@@ -81,11 +81,42 @@
 		[DDI_PORT_4] = DDI_ENABLE_HPD,
 	}"
 
+	register "hybrid_storage_mode" = "1"
+	register "dmi_power_optimize_disable" = "1"
+
 	device domain 0 on
+		subsystemid 0x1462 0x7d25 inherit
+		device ref pcie5_0 on
+			register "cpu_pcie_rp[CPU_RP(2)]" = "{
+				.clk_src = 0,
+				.clk_req = 0,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_HOTPLUG,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypePciExpressGen5x16" "SlotLengthLong"
+					 "PCI_E1" "SlotDataBusWidth16X"
+		end
+		device ref pcie5_1 off end
 		device ref igpu on end
+		device ref pcie4_0 on
+			register "cpu_pcie_rp[CPU_RP(1)]" = "{
+				.clk_src = 9,
+				.clk_req = 9,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther"
+					 "M2_1" "SlotDataBusWidth4X"
+		end
 		device ref crashlog off end
 		device ref xhci on end
-		device ref cnvi_wifi on end
+		device ref cnvi_wifi on
+			# Enable CNVi BT
+			register "cnvi_bt_core" = "true"
+			register "cnvi_bt_audio_offload" = "false"
+		end
 		device ref heci1 on end
 		device ref heci2 off end
 		device ref ide_r off end
@@ -93,6 +124,98 @@
 		device ref heci3 off end
 		device ref heci4 off end
 		device ref sata on end
+		device ref pcie_rp1 on
+			register "pch_pcie_rp[PCH_RP(1)]" = "{
+				.clk_src = 10,
+				.clk_req = 10,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_HOTPLUG | PCIE_RP_CLK_REQ_DETECT,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypePciExpressGen3X1" "SlotLengthShort"
+					 "PCI_E2" "SlotDataBusWidth1X"
+		end
+		device ref pcie_rp2 on
+			register "pch_pcie_rp[PCH_RP(2)]" = "{
+				.clk_src = 17,
+				.clk_req = 17,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_HOTPLUG | PCIE_RP_CLK_REQ_DETECT,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypePciExpressGen3X16" "SlotLengthLong"
+					 "PCI_E4" "SlotDataBusWidth1X"
+		end
+		device ref pcie_rp3 on
+			# i225 Ethernet, Clock PM unsupported, onboard device
+			register "pch_pcie_rp[PCH_RP(3)]" = "{
+				.clk_src = 12,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_UNUSED | PCIE_RP_BUILT_IN,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+		end
+		device ref pcie_rp4 off end
+
+		device ref pcie_rp5 on
+			register "pch_pcie_rp[PCH_RP(5)]" = "{
+				.clk_src = 15,
+				.clk_req = 15,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_HOTPLUG | PCIE_RP_CLK_REQ_DETECT,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypePciExpressGen3X16" "SlotLengthLong"
+					 "PCI_E3" "SlotDataBusWidth4X"
+		end
+
+		device ref pcie_rp9 on
+			register "pch_pcie_rp[PCH_RP(9)]" = "{
+				.clk_src = 13,
+				.clk_req = 13,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther"
+					 "M2_3" "SlotDataBusWidth4X"
+		end
+
+		# These are not enabled. The Flex I/O mode is SATA to cover all 8 SATA ports.
+		# There is an ASMedia switch on-board to mux the SATA ports 7, 8 and PCIe
+		# 9-12, 21-24 to M2_3 and M2_4 slots
+		device ref pcie_rp13 off end
+		device ref pcie_rp14 off end
+		device ref pcie_rp15 off end
+		device ref pcie_rp16 off end
+		device ref pcie_rp17 off end
+		device ref pcie_rp18 off end
+		device ref pcie_rp19 off end
+		device ref pcie_rp20 off end
+
+		device ref pcie_rp21 on
+			register "pch_pcie_rp[PCH_RP(21)]" = "{
+				.clk_src = 14,
+				.clk_req = 14,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther"
+					 "M2_4" "SlotDataBusWidth4X"
+		end
+
+		device ref pcie_rp25 on
+			register "pch_pcie_rp[PCH_RP(25)]" = "{
+				.clk_src = 8,
+				.clk_req = 8,
+				.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT,
+				.PcieRpL1Substates = L1_SS_L1_2,
+				.pcie_rp_aspm = ASPM_L0S_L1,
+			}"
+			smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther"
+					 "M2_2" "SlotDataBusWidth4X"
+		end
 		device ref p2sb on end
 		device ref hda on end
 		device ref smbus on end
diff --git a/src/mainboard/msi/ms7d25/gpio.h b/src/mainboard/msi/ms7d25/gpio.h
index d4694ea..74a2d93 100644
--- a/src/mainboard/msi/ms7d25/gpio.h
+++ b/src/mainboard/msi/ms7d25/gpio.h
@@ -2,6 +2,25 @@
 
 #include <soc/gpio.h>
 
+/* GPIO Native Function Virtual Wire Enable */
+#define PAD_CFG_GPIO_NAF_VWE		(1 << 27)
+
+/*
+ * Do not program the CLKREQ signals in coreboot to let FSP detect and
+ * configure CLKREQ pads for PCIe ports. Otherwise the CLKREQ pads are
+ * reprogrammed by FSP despite having GpioOverride=1 in the following manner:
+ *
+ * GPIO (reset) -> (CLKREQ (coreboot, configure pads) ->
+ * GPIO input (FSP, detect) -> CLKREQ (FSP).
+ *
+ * Also if GpioOverride=1 the NAF_VME bit is not set for virtual wire GPIOs
+ * that require it, e.g. the CPU PCIe CLKREQ bus. The pads that should not be
+ * touched by coreboot are left commented in this file for reference. CLKREQ
+ * reprogramming caused undefined behavior when ASPM and Clock PM was being
+ * enabled by coreboot on PCIe endpoints of CPU PCIe x4 slot (coreboot printed
+ * a lot of exceptions and simply halted).
+ */
+
 /* Pad configuration was generated automatically using intelp2m utility */
 static const struct pad_config gpio_table[] = {
 
@@ -121,10 +140,11 @@
 	PAD_CFG_GPI_TRIG_OWN(GPP_J6, NONE, PLTRST, OFF, ACPI),
 	/* GPP_J7 - GPIO */
 	PAD_CFG_GPI_TRIG_OWN(GPP_J7, NONE, PLTRST, OFF, ACPI),
+	/* Let FSP enable the respective CLKREQ pins, see comment at the top of file */
 	/* GPP_J8 - SRCCLKREQ16# */
-	PAD_CFG_NF(GPP_J8, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_J8, NONE, DEEP, NF1),
 	/* GPP_J9 - SRCCLKREQ17# */
-	PAD_CFG_NF(GPP_J9, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_J9, NONE, DEEP, NF1),
 	/* GPP_J10 - GPIO */
 	PAD_CFG_GPI_TRIG_OWN(GPP_J10, NONE, PLTRST, OFF, ACPI),
 	/* GPP_J11 - GPIO */
@@ -133,25 +153,28 @@
 	/* vGPIO controls certain features like CNVi, include the definitions as well */
 
 	/* ------- GPIO Group vGPIO ------- */
-	_PAD_CFG_STRUCT(VGPIO_0, PAD_FUNC(GPIO) | PAD_RESET(DEEP) | PAD_BUF(RX_DISABLE) | 1, 0),	/* GPIO */
-	_PAD_CFG_STRUCT(VGPIO_4, PAD_FUNC(GPIO) | PAD_RESET(DEEP) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1), 0),	/* GPIO */
-	_PAD_CFG_STRUCT(VGPIO_5, PAD_FUNC(GPIO) | PAD_RESET(DEEP) | PAD_BUF(RX_DISABLE) | 1, 0),	/* GPIO */
+	/* CNVi BT Enable, TX = 1 */
+	_PAD_CFG_STRUCT(VGPIO_0, PAD_FUNC(GPIO) | PAD_RESET(DEEP) | PAD_BUF(RX_DISABLE) | 1, 0),
+	/* CNVi BT host wake */
+	_PAD_CFG_STRUCT(VGPIO_4, PAD_FUNC(GPIO) | PAD_RESET(DEEP) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), 0),
+	/* CNVi BT on USB, TX = 1 */
+	_PAD_CFG_STRUCT(VGPIO_5, PAD_FUNC(GPIO) | PAD_RESET(DEEP) | PAD_BUF(RX_DISABLE) | 1, 0),
 	_PAD_CFG_STRUCT(VGPIO_6, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_7, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_8, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_9, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
-	_PAD_CFG_STRUCT(VGPIO_10, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_10 */
-	_PAD_CFG_STRUCT(VGPIO_11, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_11 */
-	_PAD_CFG_STRUCT(VGPIO_12, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_12 */
-	_PAD_CFG_STRUCT(VGPIO_13, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_13 */
+	_PAD_CFG_STRUCT(VGPIO_10, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vCNV_MFUART1_TXD */
+	_PAD_CFG_STRUCT(VGPIO_11, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vCNV_MFUART1_RXD */
+	_PAD_CFG_STRUCT(VGPIO_12, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vCNV_MFUART1_CTS# */
+	_PAD_CFG_STRUCT(VGPIO_13, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vCNV_MFUART1_RTS# */
 	_PAD_CFG_STRUCT(VGPIO_18, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_19, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_20, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_21, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
-	_PAD_CFG_STRUCT(VGPIO_22, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_22 */
-	_PAD_CFG_STRUCT(VGPIO_23, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_23 */
-	_PAD_CFG_STRUCT(VGPIO_24, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_24 */
-	_PAD_CFG_STRUCT(VGPIO_25, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_25 */
+	_PAD_CFG_STRUCT(VGPIO_22, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vISH_UART0_TXD */
+	_PAD_CFG_STRUCT(VGPIO_23, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vISH_UART0_RXD */
+	_PAD_CFG_STRUCT(VGPIO_24, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vISH_UART0_CTS# */
+	_PAD_CFG_STRUCT(VGPIO_25, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* vISH_UART0_RTS# */
 	_PAD_CFG_STRUCT(VGPIO_30, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_31, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 	_PAD_CFG_STRUCT(VGPIO_32, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
@@ -162,14 +185,15 @@
 	_PAD_CFG_STRUCT(VGPIO_37, PAD_FUNC(GPIO) | PAD_RESET(DEEP), 0),	/* GPIO */
 
 	/* ------- GPIO Group vGPIO_0 ------- */
-	_PAD_CFG_STRUCT(VGPIO_USB_0, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_USB_0 */
-	_PAD_CFG_STRUCT(VGPIO_USB_1, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_USB_1 */
-	_PAD_CFG_STRUCT(VGPIO_USB_2, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_USB_2 */
-	_PAD_CFG_STRUCT(VGPIO_USB_3, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),	/* VGPIO_USB_3 */
-	_PAD_CFG_STRUCT(VGPIO_USB_8, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_USB_8 */
-	_PAD_CFG_STRUCT(VGPIO_USB_9, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_USB_9 */
-	_PAD_CFG_STRUCT(VGPIO_USB_10, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_USB_10 */
-	_PAD_CFG_STRUCT(VGPIO_USB_11, PAD_FUNC(NF1) | PAD_RESET(DEEP) | (1 << 1), 0),	/* VGPIO_USB_11 */
+	/* These are Virtual USB OC pins */
+	_PAD_CFG_STRUCT(VGPIO_USB_0,  PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_0 */
+	_PAD_CFG_STRUCT(VGPIO_USB_1,  PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_1 */
+	_PAD_CFG_STRUCT(VGPIO_USB_2,  PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_2 */
+	_PAD_CFG_STRUCT(VGPIO_USB_3,  PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_3 */
+	_PAD_CFG_STRUCT(VGPIO_USB_8,  PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_8 */
+	_PAD_CFG_STRUCT(VGPIO_USB_9,  PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_9 */
+	_PAD_CFG_STRUCT(VGPIO_USB_10, PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_10 */
+	_PAD_CFG_STRUCT(VGPIO_USB_11, PAD_FUNC(NF1) | PAD_RESET(DEEP)| PAD_CFG_GPIO_NAF_VWE, 0), /* VGPIO_USB_11 */
 
 	/* ------- GPIO Community 1 ------- */
 
@@ -249,22 +273,23 @@
 	PAD_CFG_GPI_TRIG_OWN(GPP_H0, NONE, PLTRST, OFF, ACPI),
 	/* GPP_H1 - GPIO */
 	PAD_CFG_GPI_TRIG_OWN(GPP_H1, NONE, PLTRST, OFF, ACPI),
+	/* Let FSP enable the respective CLKREQ pins, see comment at the top of file */
 	/* GPP_H2 - SRCCLKREQ8# */
-	PAD_CFG_NF(GPP_H2, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H2, NONE, DEEP, NF1),
 	/* GPP_H3 - SRCCLKREQ9# */
-	PAD_CFG_NF(GPP_H3, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H3, NONE, DEEP, NF1),
 	/* GPP_H4 - SRCCLKREQ10# */
-	PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1),
 	/* GPP_H5 - SRCCLKREQ11# */
-	PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1),
 	/* GPP_H6 - SRCCLKREQ12# */
-	PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1),
 	/* GPP_H7 - SRCCLKREQ13# */
-	PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1),
 	/* GPP_H8 - SRCCLKREQ14# */
-	PAD_CFG_NF(GPP_H8, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H8, NONE, DEEP, NF1),
 	/* GPP_H9 - SRCCLKREQ15# */
-	PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1),
+	// PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1),
 
 	/* GPP_H10 - GPIO */
 	PAD_CFG_GPI_TRIG_OWN(GPP_H10, NONE, PLTRST, OFF, ACPI),
@@ -412,6 +437,52 @@
 	/* GPP_C23 - GPIO */
 	PAD_CFG_GPI_TRIG_OWN(GPP_C23, NONE, PLTRST, OFF, ACPI),
 
+	/* TODO: move VW programming to soc directory and make it dependent on FSP settings? */
+	/* Let FSP enable the respective CLKREQ pins, see comment at the top of file */
+	/* CPU PCIe 6.0 CLKREQ virtual wire message bus */
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_0,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_1,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_2,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_3,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_4,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_5,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_6,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_7,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_8,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_9,  PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_10, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_11, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_12, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_13, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_14, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_15, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_64, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_65, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_66, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_67, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+
+	/* CPU PCIe 1.0 CLKREQ virtual wire message bus */
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_16, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_17, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_18, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_19, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_20, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_21, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_22, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_23, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_24, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_25, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_26, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_27, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_28, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_29, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_30, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_31, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_68, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_69, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_70, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+	// _PAD_CFG_STRUCT(VGPIO_PCIE_71, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_CFG_GPIO_NAF_VWE, 0),
+
 	/* ------- GPIO Community 4 ------- */
 
 	/* ------- GPIO Group GPP_S ------- */
@@ -562,8 +633,9 @@
 
 	/* ------- GPIO Group GPP_D ------- */
 
-	/* GPP_D0 - GPIO */
-	PAD_CFG_GPI_TRIG_OWN(GPP_D0, NONE, PLTRST, OFF, ACPI),
+	/* Let FSP enable the respective CLKREQ pins, see comment at the top of file */
+	/* GPP_D0 - CLKREQ0# */
+	// PAD_CFG_NF(GPP_D0, NONE, DEEP, NF1),
 	/* GPP_D1 - GPIO */
 	PAD_CFG_GPI_TRIG_OWN(GPP_D1, NONE, PLTRST, OFF, ACPI),
 	/* GPP_D2 - GPIO */
diff --git a/src/mainboard/msi/ms7d25/mainboard.c b/src/mainboard/msi/ms7d25/mainboard.c
index e4a47d8..161f137 100644
--- a/src/mainboard/msi/ms7d25/mainboard.c
+++ b/src/mainboard/msi/ms7d25/mainboard.c
@@ -1,8 +1,15 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
+#include <acpi/acpi.h>
 #include <device/device.h>
 #include <soc/ramstage.h>
-#include "gpio.h"
+#include <string.h>
+
+void mainboard_fill_fadt(acpi_fadt_t *fadt)
+{
+	fadt->preferred_pm_profile = PM_DESKTOP;
+	fadt->iapc_boot_arch |= ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
+}
 
 static void mainboard_init(void *chip_info)
 {
@@ -16,7 +23,77 @@
 
 void mainboard_silicon_init_params(FSP_S_CONFIG *params)
 {
-	gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table));
+	memset(params->PcieRpEnableCpm, 0, sizeof(params->PcieRpEnableCpm));
+	memset(params->CpuPcieRpEnableCpm, 0, sizeof(params->CpuPcieRpEnableCpm));
+	memset(params->CpuPcieClockGating, 0, sizeof(params->CpuPcieClockGating));
+	memset(params->CpuPciePowerGating, 0, sizeof(params->CpuPciePowerGating));
+
+	params->CpuPcieFiaProgramming = 1;
+
+	params->PcieRpFunctionSwap = 0;
+	params->CpuPcieRpFunctionSwap = 0;
+
+	params->CpuPcieRpPmSci[0] = 1; // M2_1
+	params->CpuPcieRpPmSci[1] = 1; // PCI_E1
+	params->PcieRpPmSci[0]    = 1; // PCI_E2
+	params->PcieRpPmSci[1]    = 1; // PCI_E4
+	params->PcieRpPmSci[2]    = 1; // Ethernet
+	params->PcieRpPmSci[4]    = 1; // PCI_E3
+	params->PcieRpPmSci[8]    = 1; // M2_3
+	params->PcieRpPmSci[20]   = 1; // M2_4
+	params->PcieRpPmSci[24]   = 1; // M2_2
+
+	params->PcieRpMaxPayload[0]    = 1; // PCI_E2
+	params->PcieRpMaxPayload[1]    = 1; // PCI_E4
+	params->PcieRpMaxPayload[2]    = 1; // Ethernet
+	params->PcieRpMaxPayload[4]    = 1; // PCI_E3
+	params->PcieRpMaxPayload[8]    = 1; // M2_3
+	params->PcieRpMaxPayload[20]   = 1; // M2_4
+	params->PcieRpMaxPayload[24]   = 1; // M2_2
+
+	params->CpuPcieRpTransmitterHalfSwing[0] = 1; // M2_1
+	params->CpuPcieRpTransmitterHalfSwing[1] = 1; // PCI_E1
+	params->PcieRpTransmitterHalfSwing[0]    = 1; // PCI_E2
+	params->PcieRpTransmitterHalfSwing[1]    = 1; // PCI_E4
+	params->PcieRpTransmitterHalfSwing[2]    = 1; // Ethernet
+	params->PcieRpTransmitterHalfSwing[4]    = 1; // PCI_E3
+	params->PcieRpTransmitterHalfSwing[8]    = 1; // M2_3
+	params->PcieRpTransmitterHalfSwing[20]   = 1; // M2_4
+	params->PcieRpTransmitterHalfSwing[24]   = 1; // M2_2
+
+	params->PcieRpEnableCpm[0]  = 1; // PCI_E2
+	params->PcieRpEnableCpm[1]  = 1; // PCI_E4
+	params->PcieRpEnableCpm[4]  = 1; // PCI_E3
+	params->PcieRpEnableCpm[8]  = 1; // M2_3
+	params->PcieRpEnableCpm[20] = 1; // M2_4
+	params->PcieRpEnableCpm[24] = 1; // M2_2
+
+	params->PcieRpAcsEnabled[0]  = 1; // PCI_E2
+	params->PcieRpAcsEnabled[1]  = 1; // PCI_E4
+	params->PcieRpAcsEnabled[2]  = 1; // Ethernet
+	params->PcieRpAcsEnabled[4]  = 1; // PCI_E3
+	params->PcieRpAcsEnabled[8]  = 1; // M2_3
+	params->PcieRpAcsEnabled[20] = 1; // M2_4
+	params->PcieRpAcsEnabled[24] = 1; // M2_2
+
+	params->CpuPcieRpEnableCpm[0] = 1; // M2_1
+	params->CpuPcieClockGating[0] = 1;
+	params->CpuPciePowerGating[0] = 1;
+	params->CpuPcieRpMultiVcEnabled[0] = 1;
+	params->CpuPcieRpPeerToPeerMode[0] = 1;
+	params->CpuPcieRpMaxPayload[0] = 2; // 512B
+	params->CpuPcieRpAcsEnabled[0] = 1;
+
+	params->CpuPcieRpEnableCpm[1] = 1; // PCI_E1
+	params->CpuPcieClockGating[1] = 1;
+	params->CpuPciePowerGating[1] = 1;
+	params->CpuPcieRpPeerToPeerMode[1] = 1;
+	params->CpuPcieRpMaxPayload[1] = 2; // 512B
+	params->CpuPcieRpAcsEnabled[1] = 1;
+
+	params->SataPortsSolidStateDrive[6] = 1; // M2_3
+	params->SataPortsSolidStateDrive[7] = 1; // M2_4
+	params->SataLedEnable = 1;
 }
 
 struct chip_operations mainboard_ops = {
diff --git a/src/mainboard/msi/ms7d25/romstage_fsp_params.c b/src/mainboard/msi/ms7d25/romstage_fsp_params.c
index 60f2371..9199a81 100644
--- a/src/mainboard/msi/ms7d25/romstage_fsp_params.c
+++ b/src/mainboard/msi/ms7d25/romstage_fsp_params.c
@@ -6,6 +6,8 @@
 #include <soc/romstage.h>
 #include <soc/meminit.h>
 
+#include "gpio.h"
+
 static const struct mb_cfg ddr4_mem_config = {
 	.type = MEM_TYPE_DDR4,
 
@@ -35,5 +37,24 @@
 
 void mainboard_memory_init_params(FSPM_UPD *memupd)
 {
+	memupd->FspmConfig.CpuPcieRpClockReqMsgEnable[0] = 1;
+	memupd->FspmConfig.CpuPcieRpClockReqMsgEnable[1] = 1;
+	memupd->FspmConfig.CpuPcieRpClockReqMsgEnable[2] = 0;
+	memupd->FspmConfig.DmiMaxLinkSpeed = 4; // Gen4 speed, undocumented
+	memupd->FspmConfig.SkipExtGfxScan = 0;
+
+	memupd->FspmConfig.PchHdaAudioLinkHdaEnable = 1;
+	memupd->FspmConfig.PchHdaSdiEnable[0] = 1;
+
+	/*
+	 * Let FSP configure virtual wires, CLKREQs, etc.
+	 * Otherwise undefined behaviour occurs when coreboot enables ASPM on
+	 * CPU PCIe root ports. This is caused by FSP reprogramming certain
+	 * pads including CLKREQ pins, despite GpioOverride = 1.
+	 */
+	memupd->FspmConfig.GpioOverride = 0;
+
 	memcfg_init(memupd, &ddr4_mem_config, &dimm_module_spd_info, false);
+
+	gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table));
 }