util/ifdtool: Add Wellsburg support

Wellsburg is IFDv2 compatible in most fields, but not in all.
It only has 8 regions and the flash master bits match the defines for
IFDv1 and thus has an "IFDv1.5" descriptor.

Add a new enum for IFDv1.5 descriptor and use them to properly operate
on this IFD.

The 'SPI programming guide' is inconsistent and mentions 6 regions
in one place, but 7 regions in another chapter. Tests showed that it
actually supports 7 regions.

Add support using the -p argument to specify Wellsburg platform.

The previous patch made sure that only 8 regions are used and that no
corruption can happen when operating in IFDv2/IFDv1.5 mode.

Tested on Intel Grangeville.

Documents used:
Intel Document Id: 516552
Intel Document Id: 565117

Change-Id: I651730b05deb512478d059174cf8615547d2fde4
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Co-developed-by: Julian Elischer <jrelis@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/68657
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c
index 95bf152..1ddb6b7 100644
--- a/util/ifdtool/ifdtool.c
+++ b/util/ifdtool/ifdtool.c
@@ -258,6 +258,8 @@
 		return CHIPSET_C620_SERIES_LEWISBURG;
 	case PLATFORM_DNV:
 		return CHIPSET_DENVERTON;
+	case PLATFORM_WBG:
+		return CHIPSET_8_SERIES_WELLSBURG;
 	default:
 		return CHIPSET_PCH_UNKNOWN;
 	}
@@ -285,6 +287,7 @@
 		PLATFORM_SKLKBL,
 		PLATFORM_IFD2,
 		PLATFORM_MTL,
+		PLATFORM_WBG,
 	};
 	unsigned int i;
 
@@ -301,8 +304,11 @@
 	const fdbar_t *fdb = find_fd(image, size);
 
 	if (is_platform_ifd_2()) {
-		ifd_version = IFD_VERSION_2;
 		chipset = ifd2_platform_to_chipset(platform);
+		if (chipset == CHIPSET_8_SERIES_WELLSBURG)
+			ifd_version = IFD_VERSION_1_5;
+		else
+			ifd_version = IFD_VERSION_2;
 		max_regions = MIN(max_regions_from_fdbar(fdb), MAX_REGIONS);
 	} else {
 		ifd_version = IFD_VERSION_1;
@@ -517,6 +523,7 @@
 	case SPI_FREQUENCY_50MHZ_30MHZ:
 		switch (ifd_version) {
 		case IFD_VERSION_1:
+		case IFD_VERSION_1_5:
 			printf("50MHz");
 			break;
 		case IFD_VERSION_2:
@@ -709,6 +716,7 @@
 		printf("\n  Component 1 Density:                 ");
 		decode_component_density(fcba->flcomp & 7);
 		break;
+	case IFD_VERSION_1_5:
 	case IFD_VERSION_2:
 		printf("\n  Component 2 Density:                 ");
 		decode_component_density((fcba->flcomp >> 4) & 0xf);
@@ -1153,6 +1161,7 @@
 
 	switch (ifd_version) {
 	case IFD_VERSION_1:
+	case IFD_VERSION_1_5:
 		freq = SPI_FREQUENCY_20MHZ;
 		break;
 	case IFD_VERSION_2:
@@ -1191,6 +1200,7 @@
 		mask = 0x7;
 		chip2_offset = 3;
 		break;
+	case IFD_VERSION_1_5:
 	case IFD_VERSION_2:
 		mask = 0xf;
 		chip2_offset = 4;
@@ -1318,6 +1328,7 @@
 		}
 		break;
 	case PLATFORM_DNV:
+	case PLATFORM_WBG:
 		/* CPU/BIOS can read descriptor and BIOS. */
 		fmba->flmstr1 |= (1 << REGION_DESC) << rd_shift;
 		fmba->flmstr1 |= (1 << REGION_BIOS) << rd_shift;
@@ -1756,6 +1767,7 @@
 	       "                                         jsl    - Jasper Lake\n"
 	       "                                         sklkbl - Sky Lake/Kaby Lake\n"
 	       "                                         tgl    - Tiger Lake\n"
+	       "                                         wbg    - Wellsburg\n"
 	       "   -S | --setpchstrap                    Write a PCH strap\n"
 	       "   -V | --newvalue                       The new value to write into PCH strap specified by -S\n"
 	       "   -v | --version:                       print the version\n"
@@ -2026,6 +2038,8 @@
 				platform = PLATFORM_IFD2;
 			} else if (!strcmp(optarg, "mtl")) {
 				platform = PLATFORM_MTL;
+			} else if (!strcmp(optarg, "wbg")) {
+				platform = PLATFORM_WBG;
 			} else {
 				fprintf(stderr, "Unknown platform: %s\n", optarg);
 				exit(EXIT_FAILURE);