SNB+MRC boards: Migrate MRC settings to devicetree

For Sandy Bridge boards with MRC raminit support, migrate as much
MRC settings to devicetree as possible, to stop mainboard code from
needlessly overwriting entire PEI data structure, so they will not
interfere with upcoming transition to one standard Haswell way of
providing SPD info to northbridge.

Some exceptions allowed are described below and in code comments.

SPD-related items are kept out of devicetree for now. They will be
migrated (with a different representation) with the Haswell SPD
transition.

google/{butterfly,link,parrot,stout} have max DDR3 frequency set in
pei_data to 1600 (2*800), but in devicetree to 666. The reason for the
difference seems to be problems with native raminit code. These are
converted into ternaries tied to CONFIG_USE_NATIVE_RAMINIT, with an
added "fix me" tag. asus/p8x7x-series also needs the same treatment,
based on testing various memory on p8z77-m hardware.

TEST=Builds on all affected boards. asus/p8z77-m still works with multiple RAM modules tested.

Change-Id: Ie349a8f400eecca3cdbc196ea0790aebe0549e39
Signed-off-by: Keith Hui <buurin@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76962
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
diff --git a/src/mainboard/asus/p8x7x-series/devicetree.cb b/src/mainboard/asus/p8x7x-series/devicetree.cb
index 0dc77f3..2913519 100644
--- a/src/mainboard/asus/p8x7x-series/devicetree.cb
+++ b/src/mainboard/asus/p8x7x-series/devicetree.cb
@@ -1,6 +1,24 @@
 ## SPDX-License-Identifier: GPL-2.0-only
 
 chip northbridge/intel/sandybridge
+	# All MRC-capable boards in family (P8Z77-M[ PRO]) lists supported
+	# DIMMs down to 1.25v
+	register "ddr3lv_support" = "1"
+	# FIXME: Nothing can run native at 800MHz on p8z77-m, others may have same problem
+	register "max_mem_clock_mhz" = "CONFIG(USE_NATIVE_RAMINIT) ? 666 : 800"
+
+	register "usb_port_config" = "{
+		{1, 0, 0x0080}, {1, 0, 0x0080}, {1, 1, 0x0080}, {1, 1, 0x0080}, {1, 2, 0x0080},
+		{1, 2, 0x0080}, {1, 3, 0x0080}, {1, 3, 0x0080}, {1, 4, 0x0080}, {1, 4, 0x0080},
+		{1, 6, 0x0080}, {1, 5, 0x0080}, {1, 5, 0x0080}, {1, 6, 0x0080}
+		}"
+	# 4 bit switch mask. 0=not switchable, 1=switchable
+	# Means once it's loaded the OS, it can swap ports
+	# from/to EHCI/xHCI. Z77 has four USB3 ports, so 0xf
+	register "usb3.hs_port_switch_mask" = "0xf"
+	# (The other 3 usb3.* settings can be set from nvram options, and so are set
+	# from runtime code)
+
 	device domain 0 on
 		device ref host_bridge on  end		# Host bridge
 		device ref peg10 on  end		# PCIEX16_1
diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c
index 9b4fa1d..fdb0a45 100644
--- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c
+++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c
@@ -52,34 +52,10 @@
 
 void mainboard_fill_pei_data(struct pei_data *pei)
 {
-	uint8_t spdaddr[] = {0xa0, 0xa2, 0xa4, 0xa6}; /* SMBus mul 2 */
-	uint16_t usbcfg[16][3] = {
-		/* {enabled, oc_pin, cable len 0x0080=<8inches/20cm} */
-		{1, 0, 0x0080}, {1, 0, 0x0080}, {1, 1, 0x0080}, {1, 1, 0x0080}, {1, 2, 0x0080},
-		{1, 2, 0x0080}, {1, 3, 0x0080}, {1, 3, 0x0080}, {1, 4, 0x0080}, {1, 4, 0x0080},
-		{1, 6, 0x0080}, {1, 5, 0x0080}, {1, 5, 0x0080}, {1, 6, 0x0080}
-	};
+	const uint8_t spdaddr[] = {0xa0, 0xa2, 0xa4, 0xa6}; /* SMBus mul 2 */
 
 	memcpy(pei->spd_addresses, &spdaddr, sizeof(spdaddr));
 
-	pei->gbe_enable = 0;	   /* Board uses no Intel GbE but a RTL8111F */
-	pei->max_ddr3_freq = 1600; /* 1333=Sandy; 1600=Ivy */
-
-	memcpy(pei->usb_port_config, &usbcfg, sizeof(usbcfg));
-
-	/* ASUS P8Z77-M manual lists some supported DIMMs down to 1.25v */
-	pei->ddr3lv_support = 1;
-	/*
-	 * PCIe 3.0 support. As we use Ivy Bridge, let's enable it,
-	 * but might cause some system instability!
-	 */
-	pei->pcie_init = 1;
-	/*
-	 * 4 bit switch mask. 0=not switchable, 1=switchable
-	 * Means once it's loaded the OS, it can swap ports
-	 * from/to EHCI/xHCI. Z77 has four USB3 ports, so 0xf
-	 */
-	pei->usb3.hs_port_switch_mask = 0xf;
 	/*
 	 * USB 3 mode settings.
 	 * These are obtained from option table then bit masked to keep within range.
diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/overridetree.cb b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/overridetree.cb
index cad9c5c..cdcaa57 100644
--- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/overridetree.cb
+++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/overridetree.cb
@@ -1,6 +1,11 @@
 ## SPDX-License-Identifier: GPL-2.0-only
 
 chip northbridge/intel/sandybridge
+	register "usb_port_config" = "{
+		{1, 0, 0x0080}, {1, 0, 0x0080}, {1, 1, 0x0080}, {1, 1, 0x0080}, {1, 2, 0x0080},
+		{1, 2, 0x0080}, {1, 3, 0x0080}, {1, 3, 0x0080}, {1, 4, 0x0080}, {1, 4, 0x0080},
+		{1, 6, 0x0080}, {1, 5, 0x0080}, {1, 5, 0x0080}, {1, 6, 0x0080}
+		}"
 	device domain 0 on
 		subsystemid 0x1043 0x84ca inherit
 		chip southbridge/intel/bd82x6x # Intel Series 7 Panther Point PCH
diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c
index a93f5e9..ac3eb42 100644
--- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c
+++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c
@@ -58,6 +58,10 @@
 
 void mainboard_fill_pei_data(struct pei_data *pei_data)
 {
+	const uint8_t spdaddr[] = {0xa0, 0xa2, 0xa4, 0xa6}; /* SMBus mul 2 */
+
+	memcpy(pei_data->spd_addresses, &spdaddr, sizeof(pei_data->spd_addresses));
+
 	/*
 	 * USB3 mode:
 	 * 0 = Disable: work always as USB 2.0(ehci)
@@ -66,88 +70,9 @@
 	 * 3 = Smart Auto : same than Auto, but if OS loads USB3 driver
 	 *     and reboots, it will keep the USB3.0 speed
 	 */
-	unsigned int usb3_mode = get_uint_option("usb3_mode", 1);
-	usb3_mode &= 0x3; /* ensure it's 0/1/2/3 only */
-
+	pei_data->usb3.mode = get_uint_option("usb3_mode", 1) & 0x3;
 	/* Load USB3 pre-OS xHCI driver */
-	unsigned int usb3_drv = get_uint_option("usb3_drv", 1);
-	usb3_drv &= 0x1; /* ensure it's 0/1 only */
-
+	pei_data->usb3.preboot_support = get_uint_option("usb3_drv", 1) & 0x1;
 	/* Use USB3 xHCI streams */
-	unsigned int usb3_streams = get_uint_option("usb3_streams", 1);
-	usb3_streams &= 0x1; /* ensure it's 0/1 only */
-
-	struct pei_data pd = {
-		.pei_version = PEI_VERSION,
-		.mchbar = CONFIG_FIXED_MCHBAR_MMIO_BASE,
-		.dmibar = CONFIG_FIXED_DMIBAR_MMIO_BASE,
-		.epbar = CONFIG_FIXED_EPBAR_MMIO_BASE,
-		.pciexbar = CONFIG_ECAM_MMCONF_BASE_ADDRESS,
-		.smbusbar = CONFIG_FIXED_SMBUS_IO_BASE,
-		.wdbbar = 0x4000000,
-		.wdbsize = 0x1000,
-		.hpet_address = HPET_BASE_ADDRESS,
-		.rcba = (uintptr_t)DEFAULT_RCBA,
-		.pmbase = DEFAULT_PMBASE,
-		.gpiobase = DEFAULT_GPIOBASE,
-		.thermalbase = 0xfed08000,
-		.system_type = 1, /* 0=Mobile, 1=Desktop/Server */
-		.tseg_size = CONFIG_SMM_TSEG_SIZE,
-		.spd_addresses = { 0xa0, 0xa2, 0xa4, 0xa6 }, /* SMBus mul 2 */
-		.ts_addresses = { 0x00, 0x00, 0x00, 0x00 },
-		.ec_present = 0, /* Asus 2203 BIOS shows XUECA016, but no EC */
-		.gbe_enable = 0, /* Board uses no Intel GbE but a RTL8111F */
-		.max_ddr3_freq = 1600, /* 1333=Sandy; 1600=Ivy */
-		.usb_port_config = {
-			/* {enabled, oc_pin, cable len 0x0080=<8inches/20cm} */
-			{ 1, 0, 0x0080 }, /* USB3 front internal header */
-			{ 1, 0, 0x0080 }, /* USB3 front internal header */
-			{ 1, 1, 0x0080 }, /* USB3 ETH top connector */
-			{ 1, 1, 0x0080 }, /* USB3 ETH bottom connector */
-			{ 1, 2, 0x0080 }, /* USB2 PS2 top connector */
-			{ 1, 2, 0x0080 }, /* USB2 PS2 bottom connector */
-			{ 1, 3, 0x0080 }, /* USB2 internal header (USB78) */
-			{ 1, 3, 0x0080 }, /* USB2 internal header (USB78) */
-			{ 1, 4, 0x0080 }, /* USB2 internal header (USB910) */
-			{ 1, 4, 0x0080 }, /* USB2 internal header (USB910) */
-			{ 1, 6, 0x0080 }, /* USB2 internal header (USB1112) */
-			{ 1, 5, 0x0080 }, /* USB2 internal header (USB1112) */
-			{ 0, 5, 0x0080 }, /* Unused. Asus DEBUG_PORT ??? */
-			{ 0, 6, 0x0080 }  /* Unused. Asus DEBUG_PORT ??? */
-		},
-		.usb3 = {
-			/* 0=Disable; 1=Enable (start at USB3 speed)
-			 * 2=Auto (start as USB2 speed until OS loads)
-			 * 3=Smart Auto (like Auto but keep speed on reboot)
-			 */
-			usb3_mode,
-			/* 4 bit switch mask. 0=not switchable, 1=switchable
-			 * Means once it's loaded the OS, it can swap ports
-			 * from/to EHCI/xHCI. Z77 has four USB3 ports, so 0xf
-			 */
-			0xf,
-			usb3_drv, /* 1=Load xHCI pre-OS drv */
-			/* 0=Don't use xHCI streams for better compatibility
-			 * 1=use xHCI streams for better speed
-			 */
-			usb3_streams
-		},
-		/* ASUS P8Z77-M PRO manual says 1.35v DIMMs are supported */
-		.ddr3lv_support = 1,
-		/* PCIe 3.0 support. As we use Ivy Bridge, let's enable it,
-		 * but might cause some system instability !
-		 */
-		.pcie_init = 1,
-		/* Command Rate. 0=Auto; 1=1N; 2=2N.
-		 * Leave it always at Auto for compatibility & stability
-		 */
-		.nmode = 0,
-		/* DDR refresh rate. 0=Auto based on DRAM's temperature;
-		 * 1=Normal rate for speed; 2=Double rate for stability
-		 */
-		.ddr_refresh_rate_config = 0
-	};
-
-	/* copy the data to output PEI */
-	*pei_data = pd;
+	pei_data->usb3.xhci_streams = get_uint_option("usb3_streams", 1) & 0x1;
 }
diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/overridetree.cb b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/overridetree.cb
index 0162547..d7aea49 100644
--- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/overridetree.cb
+++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/overridetree.cb
@@ -1,6 +1,11 @@
 ## SPDX-License-Identifier: GPL-2.0-only
 
 chip northbridge/intel/sandybridge
+	register "usb_port_config" = "{
+		{1, 0, 0x0080}, {1, 0, 0x0080}, {1, 1, 0x0080}, {1, 1, 0x0080}, {1, 2, 0x0080},
+		{1, 2, 0x0080}, {1, 3, 0x0080}, {1, 3, 0x0080}, {1, 4, 0x0080}, {1, 4, 0x0080},
+		{1, 6, 0x0080}, {1, 5, 0x0080}, {0, 5, 0x0080}, {0, 6, 0x0080}
+		}"
 	device domain 0 on
 		subsystemid 0x1043 0x84ca inherit
 		chip southbridge/intel/bd82x6x