summaryrefslogtreecommitdiff
path: root/config/coreboot/next
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2024-12-01 05:45:06 +0000
committerLeah Rowe <leah@libreboot.org>2024-12-01 23:51:20 +0000
commit264928c6cdefb0b7a3c3ff01d4fe16fa4cc3cbd8 (patch)
treed4927e1455934e8aee6a58f773eacd61579aabc7 /config/coreboot/next
parent597b45fdbd56b737d911aafa35915419184b70c9 (diff)
NEW MAINBOARD: ThinkPad T480
This uses the excellent deguard utility, written by the excellent Mate Kukri. A few bugs but it mostly works. Documentation to come shortly, in lbwww.git. Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'config/coreboot/next')
-rw-r--r--config/coreboot/next/patches/0001-mb-dell-OptiPlex-3050-Micro-port-Intel-KabyLake.patch1541
-rw-r--r--config/coreboot/next/patches/0001-soc-intel-skylake-configure-usb-acpi.patch94
-rw-r--r--config/coreboot/next/patches/0002-mb-lenovo-Add-initial-code-for-Lenovo-ThinkPad-E460.patch308
-rw-r--r--config/coreboot/next/patches/0003-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch30
-rw-r--r--config/coreboot/next/patches/0004-mb-lenovo-Add-ThinkPad-T480.patch1175
-rw-r--r--config/coreboot/next/patches/0005-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch (renamed from config/coreboot/next/patches/0002-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch)4
-rw-r--r--config/coreboot/next/patches/0006-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch (renamed from config/coreboot/next/patches/0003-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch)24
-rw-r--r--config/coreboot/next/patches/0007-Remove-warning-for-coreboot-images-built-without-a-p.patch (renamed from config/coreboot/next/patches/0004-Remove-warning-for-coreboot-images-built-without-a-p.patch)4
-rw-r--r--config/coreboot/next/patches/0008-mb-dell-optiplex_780-Add-USFF-variant.patch (renamed from config/coreboot/next/patches/0005-mb-dell-optiplex_780-Add-USFF-variant.patch)4
-rw-r--r--config/coreboot/next/patches/0009-lenovo-t480-Add-MAINBOARD_USES_IFD_GBE_REGION.patch27
-rw-r--r--config/coreboot/next/patches/0010-t480-hack-turn-off-the-dgpu.patch45
-rw-r--r--config/coreboot/next/target.cfg2
12 files changed, 1698 insertions, 1560 deletions
diff --git a/config/coreboot/next/patches/0001-mb-dell-OptiPlex-3050-Micro-port-Intel-KabyLake.patch b/config/coreboot/next/patches/0001-mb-dell-OptiPlex-3050-Micro-port-Intel-KabyLake.patch
deleted file mode 100644
index 99bd2b69..00000000
--- a/config/coreboot/next/patches/0001-mb-dell-OptiPlex-3050-Micro-port-Intel-KabyLake.patch
+++ /dev/null
@@ -1,1541 +0,0 @@
-From 496cdb9ccfe8908ec0fe7f703ce6f25e5abf1c18 Mon Sep 17 00:00:00 2001
-From: Mate Kukri <kukri.mate@gmail.com>
-Date: Thu, 24 Oct 2024 18:05:19 +0100
-Subject: [PATCH 1/5] mb/dell: OptiPlex 3050 Micro port (Intel KabyLake)
-
-- Boots Linux 6.11 (Debian)
-- GRUB and SeaBIOS payloads work
-- SMSC SCH5553 SIO/EC
- + Serial port works
- + PWM fan control works
-- Realtek Gigabit LAN works
-- WiFi slot works
-- NVMe SSD slot works
-- Extra: LPSS UART0
- + Stock FW sets undocumented power gating bit, RTC battery needs to
- be pulled for it to work.
- + Signals exposed on test points on the back of the board.
- FIXME: add documentation about this
-- Needs 'deguard' to bypass BootGuard
- + See https://review.coreboot.org/plugins/gitiles/deguard
-- Audio works
-- All USB ports work
-- Currently limited to the Micro form factor, but others are very
- similar
-- HDA verbs and VBT by Leah Rowe
-
-Change-Id: I8d443e39ee684a4eaa19c835a945cfe569c051e2
-Signed-off-by: Mate Kukri <kukri.mate@gmail.com>
----
- src/mainboard/dell/optiplex_3050/Kconfig | 37 ++
- src/mainboard/dell/optiplex_3050/Kconfig.name | 4 +
- src/mainboard/dell/optiplex_3050/Makefile.mk | 12 +
- src/mainboard/dell/optiplex_3050/acpi/ec.asl | 3 +
- .../dell/optiplex_3050/acpi/superio.asl | 3 +
- .../dell/optiplex_3050/board_info.txt | 7 +
- src/mainboard/dell/optiplex_3050/bootblock.c | 107 ++++
- src/mainboard/dell/optiplex_3050/cmos.default | 5 +
- src/mainboard/dell/optiplex_3050/cmos.layout | 54 ++
- src/mainboard/dell/optiplex_3050/data.vbt | Bin 0 -> 4300 bytes
- .../dell/optiplex_3050/devicetree.cb | 103 ++++
- src/mainboard/dell/optiplex_3050/dsdt.asl | 27 +
- .../dell/optiplex_3050/gma-mainboard.ads | 19 +
- src/mainboard/dell/optiplex_3050/hda_verb.c | 90 +++
- .../dell/optiplex_3050/include/early_gpio.h | 11 +
- .../dell/optiplex_3050/include/gpio.h | 241 +++++++++
- src/mainboard/dell/optiplex_3050/ramstage.c | 512 ++++++++++++++++++
- src/mainboard/dell/optiplex_3050/romstage.c | 18 +
- src/mainboard/dell/optiplex_3050/sch5555_ec.c | 54 ++
- src/mainboard/dell/optiplex_3050/sch5555_ec.h | 10 +
- 20 files changed, 1317 insertions(+)
- create mode 100644 src/mainboard/dell/optiplex_3050/Kconfig
- create mode 100644 src/mainboard/dell/optiplex_3050/Kconfig.name
- create mode 100644 src/mainboard/dell/optiplex_3050/Makefile.mk
- create mode 100644 src/mainboard/dell/optiplex_3050/acpi/ec.asl
- create mode 100644 src/mainboard/dell/optiplex_3050/acpi/superio.asl
- create mode 100644 src/mainboard/dell/optiplex_3050/board_info.txt
- create mode 100644 src/mainboard/dell/optiplex_3050/bootblock.c
- create mode 100644 src/mainboard/dell/optiplex_3050/cmos.default
- create mode 100644 src/mainboard/dell/optiplex_3050/cmos.layout
- create mode 100644 src/mainboard/dell/optiplex_3050/data.vbt
- create mode 100644 src/mainboard/dell/optiplex_3050/devicetree.cb
- create mode 100644 src/mainboard/dell/optiplex_3050/dsdt.asl
- create mode 100644 src/mainboard/dell/optiplex_3050/gma-mainboard.ads
- create mode 100644 src/mainboard/dell/optiplex_3050/hda_verb.c
- create mode 100644 src/mainboard/dell/optiplex_3050/include/early_gpio.h
- create mode 100644 src/mainboard/dell/optiplex_3050/include/gpio.h
- create mode 100644 src/mainboard/dell/optiplex_3050/ramstage.c
- create mode 100644 src/mainboard/dell/optiplex_3050/romstage.c
- create mode 100644 src/mainboard/dell/optiplex_3050/sch5555_ec.c
- create mode 100644 src/mainboard/dell/optiplex_3050/sch5555_ec.h
-
-diff --git a/src/mainboard/dell/optiplex_3050/Kconfig b/src/mainboard/dell/optiplex_3050/Kconfig
-new file mode 100644
-index 0000000000..6c8e72956e
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/Kconfig
-@@ -0,0 +1,37 @@
-+## SPDX-License-Identifier: GPL-2.0-only
-+
-+if BOARD_DELL_OPTIPLEX_3050
-+
-+config BOARD_SPECIFIC_OPTIONS
-+ def_bool y
-+ select BOARD_ROMSIZE_KB_16384
-+ select HAVE_ACPI_RESUME
-+ select HAVE_ACPI_TABLES
-+ select HAVE_CMOS_DEFAULT
-+ select HAVE_OPTION_TABLE
-+ select INTEL_GMA_ADD_VBT
-+ select INTEL_GMA_HAVE_VBT
-+ select MAINBOARD_HAS_LIBGFXINIT
-+ select MAINBOARD_SUPPORTS_KABYLAKE_CPU
-+ select MAINBOARD_SUPPORTS_SKYLAKE_CPU
-+ select SKYLAKE_SOC_PCH_H
-+ select SOC_INTEL_COMMON_BLOCK_HDA_VERB
-+ select SOC_INTEL_KABYLAKE
-+ select SUPERIO_SMSC_SCH555x
-+
-+config CBFS_SIZE
-+ default 0x900000
-+
-+config MAINBOARD_DIR
-+ default "dell/optiplex_3050"
-+
-+config MAINBOARD_PART_NUMBER
-+ default "OptiPlex 3050 Micro"
-+
-+config INTEL_GMA_VBT_FILE
-+ default "src/mainboard/\$(MAINBOARDDIR)/data.vbt"
-+
-+config DIMM_SPD_SIZE
-+ default 512 # DDR4
-+
-+endif
-diff --git a/src/mainboard/dell/optiplex_3050/Kconfig.name b/src/mainboard/dell/optiplex_3050/Kconfig.name
-new file mode 100644
-index 0000000000..14eab7f52c
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/Kconfig.name
-@@ -0,0 +1,4 @@
-+## SPDX-License-Identifier: GPL-2.0-only
-+
-+config BOARD_DELL_OPTIPLEX_3050
-+ bool "OptiPlex 3050 Micro"
-diff --git a/src/mainboard/dell/optiplex_3050/Makefile.mk b/src/mainboard/dell/optiplex_3050/Makefile.mk
-new file mode 100644
-index 0000000000..0bd72fe691
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/Makefile.mk
-@@ -0,0 +1,12 @@
-+## SPDX-License-Identifier: GPL-2.0-only
-+
-+bootblock-y += bootblock.c
-+bootblock-y += sch5555_ec.c
-+
-+romstage-y += romstage.c
-+
-+ramstage-y += ramstage.c
-+ramstage-y += sch5555_ec.c
-+ramstage-y += hda_verb.c
-+
-+ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads
-diff --git a/src/mainboard/dell/optiplex_3050/acpi/ec.asl b/src/mainboard/dell/optiplex_3050/acpi/ec.asl
-new file mode 100644
-index 0000000000..16990d45f4
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/acpi/ec.asl
-@@ -0,0 +1,3 @@
-+/* SPDX-License-Identifier: CC-PDDC */
-+
-+/* Please update the license if adding licensable material. */
-diff --git a/src/mainboard/dell/optiplex_3050/acpi/superio.asl b/src/mainboard/dell/optiplex_3050/acpi/superio.asl
-new file mode 100644
-index 0000000000..16990d45f4
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/acpi/superio.asl
-@@ -0,0 +1,3 @@
-+/* SPDX-License-Identifier: CC-PDDC */
-+
-+/* Please update the license if adding licensable material. */
-diff --git a/src/mainboard/dell/optiplex_3050/board_info.txt b/src/mainboard/dell/optiplex_3050/board_info.txt
-new file mode 100644
-index 0000000000..47a4a3a4f3
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/board_info.txt
-@@ -0,0 +1,7 @@
-+Category: desktop
-+Board URL: https://www.dell.com/support/kbdoc/en-uk/000124265/dell-optiplex-3050-system-guide
-+ROM package: SOIC-8
-+ROM protocol: SPI
-+ROM socketed: n
-+Flashrom support: y
-+Release year: 2017
-diff --git a/src/mainboard/dell/optiplex_3050/bootblock.c b/src/mainboard/dell/optiplex_3050/bootblock.c
-new file mode 100644
-index 0000000000..10689c42a1
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/bootblock.c
-@@ -0,0 +1,107 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#include <bootblock_common.h>
-+#include <device/pnp_ops.h>
-+#include <soc/gpio.h>
-+#include <superio/smsc/sch555x/sch555x.h>
-+#include "include/early_gpio.h"
-+#include "sch5555_ec.h"
-+
-+struct ec_init_entry {
-+ uint16_t addr;
-+ uint8_t val;
-+};
-+
-+static void bootblock_ec_init(void)
-+{
-+ /*
-+ * Early EC init
-+ */
-+
-+ static const struct ec_init_entry init_table1[] = {
-+ {0x08cc, 0x11}, {0x08d0, 0x11}, {0x088c, 0x10}, {0x0890, 0x10},
-+ {0x0894, 0x10}, {0x0898, 0x12}, {0x089c, 0x12}, {0x08a0, 0x10},
-+ {0x08a4, 0x12}, {0x08a8, 0x10}, {0x0820, 0x12}, {0x0824, 0x12},
-+ {0x0878, 0x12}, {0x0880, 0x12}, {0x0884, 0x12}, {0x08e0, 0x12},
-+ {0x08e4, 0x12}, {0x083c, 0x10}, {0x0840, 0x10}, {0x0844, 0x10},
-+ {0x0848, 0x10}, {0x084c, 0x10}, {0x0850, 0x10}, {0x0814, 0x11},
-+ };
-+
-+ for (size_t i = 0; i < ARRAY_SIZE(init_table1); ++i)
-+ sch5555_mbox_write(2, init_table1[i].addr, init_table1[i].val);
-+
-+ static const struct ec_init_entry init_table2[] = {
-+ {0x0040, 0x00}, {0x00f8, 0x10}, {0x00f9, 0x00}, {0x00f0, 0x30},
-+ {0x00fa, 0x00}, {0x00fb, 0x00}, {0x00ea, 0x00}, {0x00eb, 0x00},
-+ {0x00ef, 0x7c}, {0x0005, 0x0f}, {0x0014, 0x01}, {0x0018, 0x2f},
-+ {0x0019, 0x2f}, {0x001a, 0x2f}, {0x001b, 0x2f}, {0x01d8, 0x01},
-+ {0x0040, 0x11},
-+ };
-+
-+ for (size_t i = 0; i < ARRAY_SIZE(init_table2); ++i)
-+ sch5555_mbox_write(1, init_table2[i].addr, init_table2[i].val);
-+
-+ sch5555_mbox_write(1, 0x000b, 0x01);
-+ sch5555_mbox_write(4, 0x001a, 0x04);
-+ sch5555_mbox_write(4, 0x0028, 0x18);
-+ sch5555_mbox_write(4, 0x001a, 0x00);
-+ sch5555_mbox_write(1, 0x000b, 0x03);
-+
-+ /*
-+ * Early HWM init
-+ */
-+
-+ sch5555_mbox_read(1, 0xcb);
-+ sch5555_mbox_read(1, 0xb8);
-+
-+ static const struct ec_init_entry hwm_init_table[] = {
-+ {0x02fc, 0xa0}, {0x02fd, 0x32}, {0x0005, 0x77}, {0x0019, 0x2f},
-+ {0x001a, 0x2f}, {0x008a, 0x33}, {0x008b, 0x33}, {0x008c, 0x33},
-+ {0x00ba, 0x10}, {0x00d1, 0xff}, {0x00d6, 0xff}, {0x00db, 0xff},
-+ {0x0048, 0x00}, {0x0049, 0x00}, {0x007a, 0x00}, {0x007b, 0x00},
-+ {0x007c, 0x00}, {0x0080, 0x00}, {0x0081, 0x00}, {0x0082, 0x00},
-+ {0x0083, 0xbb}, {0x0084, 0xb0}, {0x01a1, 0x88}, {0x01a4, 0x80},
-+ {0x0088, 0x00}, {0x0089, 0x00}, {0x00a0, 0x02}, {0x00a1, 0x02},
-+ {0x00a2, 0x02}, {0x00a4, 0x04}, {0x00a5, 0x04}, {0x00a6, 0x04},
-+ {0x00ab, 0x00}, {0x00ad, 0x3f}, {0x00b7, 0x07}, {0x0062, 0x50},
-+ {0x0000, 0x46}, {0x0000, 0x50}, {0x0000, 0x46}, {0x0000, 0x50},
-+ {0x0000, 0x46}, {0x0000, 0x98}, {0x0059, 0x98}, {0x0061, 0x7c},
-+ {0x01bc, 0x00}, {0x01bd, 0x00}, {0x01bb, 0x00}, {0x0085, 0xdd},
-+ {0x0086, 0xdd}, {0x0087, 0x07}, {0x0090, 0x82}, {0x0091, 0x5e},
-+ {0x0095, 0x5d}, {0x0096, 0xa9}, {0x0097, 0x00}, {0x009b, 0x00},
-+ {0x00ae, 0x86}, {0x00af, 0x86}, {0x00b3, 0x67}, {0x00c4, 0xff},
-+ {0x00c5, 0xff}, {0x00c9, 0xff}, {0x0040, 0x01}, {0x02fc, 0x00},
-+ {0x02b3, 0x9a}, {0x02b4, 0x05}, {0x02cc, 0x01}, {0x02d0, 0x4c},
-+ {0x02d2, 0x01}, {0x02db, 0x01}, {0x006f, 0x01}, {0x0070, 0x02},
-+ {0x0071, 0x03}, {0x018b, 0x03}, {0x018c, 0x03}, {0x0015, 0x33},
-+ {0x018b, 0x00}, {0x018c, 0x00}, {0x02f8, 0x5e}, {0x02f9, 0x01},
-+ };
-+
-+ for (size_t i = 0; i < ARRAY_SIZE(hwm_init_table); ++i)
-+ sch5555_mbox_write(1, hwm_init_table[i].addr, hwm_init_table[i].val);
-+}
-+
-+
-+#define SCH555x_IOBASE 0x2e
-+#define GLOBAL_DEV PNP_DEV(SCH555x_IOBASE, SCH555x_LDN_GLOBAL)
-+#define SERIAL_DEV PNP_DEV(SCH555x_IOBASE, SCH555x_LDN_UART1)
-+
-+void bootblock_mainboard_early_init(void)
-+{
-+ gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table));
-+
-+ // Super I/O early init will map Runtime and EMI registers
-+ sch555x_early_init(GLOBAL_DEV);
-+
-+ // Changes LED color among a few other things
-+ outb(1, SCH555x_RUNTIME_IOBASE + SCH555x_RUNTIME_PME_STS);
-+ outb(1, SCH555x_RUNTIME_IOBASE + SCH555x_RUNTIME_PME_EN);
-+ outb(0xf, SCH555x_RUNTIME_IOBASE + SCH555x_RUNTIME_LED);
-+ outb(1, SCH555x_RUNTIME_IOBASE + SCH555x_RUNTIME_UNK1);
-+
-+ // Perform bootblock EC initialization
-+ bootblock_ec_init();
-+
-+ // Bootblock EC initialization is required for UART1 to work
-+ sch555x_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
-+}
-diff --git a/src/mainboard/dell/optiplex_3050/cmos.default b/src/mainboard/dell/optiplex_3050/cmos.default
-new file mode 100644
-index 0000000000..79961f43d8
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/cmos.default
-@@ -0,0 +1,5 @@
-+## SPDX-License-Identifier: GPL-2.0-only
-+
-+boot_option=Fallback
-+debug_level=Debug
-+power_on_after_fail=Disable
-diff --git a/src/mainboard/dell/optiplex_3050/cmos.layout b/src/mainboard/dell/optiplex_3050/cmos.layout
-new file mode 100644
-index 0000000000..54a5147b7d
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/cmos.layout
-@@ -0,0 +1,54 @@
-+## SPDX-License-Identifier: GPL-2.0-only
-+
-+# -----------------------------------------------------------------
-+entries
-+
-+#start-bit length config config-ID name
-+
-+# -----------------------------------------------------------------
-+0 120 r 0 reserved_memory
-+
-+# -----------------------------------------------------------------
-+# RTC_BOOT_BYTE (coreboot hardcoded)
-+384 1 e 4 boot_option
-+388 4 h 0 reboot_counter
-+
-+# -----------------------------------------------------------------
-+# coreboot config options: console
-+395 4 e 6 debug_level
-+
-+# coreboot config options: southbridge
-+409 2 e 7 power_on_after_fail
-+
-+# coreboot config options: bootloader
-+#Used by ChromeOS:
-+416 128 r 0 vbnv
-+
-+# coreboot config options: check sums
-+984 16 h 0 check_sum
-+
-+# -----------------------------------------------------------------
-+
-+enumerations
-+
-+#ID value text
-+1 0 Disable
-+1 1 Enable
-+4 0 Fallback
-+4 1 Normal
-+6 0 Emergency
-+6 1 Alert
-+6 2 Critical
-+6 3 Error
-+6 4 Warning
-+6 5 Notice
-+6 6 Info
-+6 7 Debug
-+6 8 Spew
-+7 0 Disable
-+7 1 Enable
-+7 2 Keep
-+# -----------------------------------------------------------------
-+checksums
-+
-+checksum 392 415 984
-diff --git a/src/mainboard/dell/optiplex_3050/data.vbt b/src/mainboard/dell/optiplex_3050/data.vbt
-new file mode 100644
-index 0000000000000000000000000000000000000000..6dc40cd99563bcd957ec2a9c4567e3b21e5d1d1f
-GIT binary patch
-literal 4300
-zcmeHJZ)_A*5TD(>zi)T1ds~!pU>y<RuF$e~N-bJsuXmJ|7P*63&uGGx+#w{DmbQ?B
-ze^_HpNECA))Sw}xiC;|p(!}^ljU+}T!9QpeKH4uPN;EMM;}_tZeY@?IBiNH@l!V#L
-zn>X`jfBW9Nd2eS$e@7qg=y|L+*|P~<Du4l>Ybk24rH<}xJ9eg%eaW32z1vbf_%+-P
-zC$uXU01ASzM2Q>g;@$hkii6SZG3@E+#eVw*w9N;N1g6_?YiB3s;_)?@>DbVf-r9}P
-zO`Vx|jP%robSBQ#gsrAYO>p&IQpqWSxVK|yXmkvV`v!Im77N$TZXru*X!y{`-Y55r
-zVKf!Pgkc!X2_qgyK4nY|jSRP7a&Qp0+diYXy*OGNIan;Ts7z%5ry$@FKoGo8XMq5h
-z6OcC{V?x>l17U>+7I|RUgn|iuCftWGW>(Kf196=odH`0=A3;(GULp|y6Ks_T0R#_x
-zlLt);9A0GWnQsLE?*|8{0RgE`gv2JC<6bXwubJ}!0Qv+3{3xJE9q#3H2<s&G0tf>5
-z>@mL~p#5nF3*pl}^hKC<v1C31Ae!^M&^2;#l`=O_ZLQWF$7*Y}Uh$G>xt9(*`c-X6
-zFkpAE5jIOv7?VVJPHKbYp3@KrBCHN-@DOp9_>7mqcf{Wl|3v&7@nvGak3pDtDe*nT
-zYl+trr--)_KT146>^lIL%Ay5+{&h=mW!RCRdEk{8SSMWj3D+L{)!qr(URTPl<i;AB
-za@p^PE9Ea6pj-}YuxDTr0>wf|yGUKG?B!CDGOpf7(oT__tC!2cJgEtK{*6}R$n1=r
-z$PSguH+xU1hb?rHq(J+G2P}V^ryazPkEs%j0}In3b4gctpl8)ZC&3qS6o31yv0DC@
-zBN6*5So*Vg*3aOq|DtfT{{PvtW2P<e%*HkB(yV?<-ipBd2rTP@b3v<wGk0i#{Bmcc
-z@y0B7K0!Gt2Iyi?fd2i^HUB$v{Q!tv^fz~$94j}a>75FZ$;1Eo6%!)V*$4D5C>nt}
-z7_D}&ricJyuY&X-!vUs`GWIOPx0wDOV;?d6f$4uRCdjx-*4N7{CF5RMe_CcQ%J`0~
-ze<-uhWc)?e%Q6cpxK`1V3hPmDzoNgOuwx3otLUF7>?;L-S9HJ1!Ybac>fI{aq2eJ`
-ze@SJpsrbICf1$GTDqdFgx)56u!i^z48)A=#)F$0)i8F!~4)H=KFrv`ilM@v#FA5q-
-zZ`~^T%U!!Etw*TnvRA91loJ<5n5;vH=aymAq8i4g#?~Vu@R%z0b-pk{VF{Q?SZOpI
-zZFLYDT8~J)KBGPNg2zT^r<&>dt1z12coq!P7_N5^Xb$wE-B-rFk(v<3F&oiLZ61P9
-z^8O8kx7Uu(WFsrh-0{jBgc7g$6w^0d!yLLcn#Qi_glV3tAo!dLNa^?163N|n^-pD?
-z(daC>dtpbi#Q&W%m0IHPOiO7pA89lVboYWH=_yh1N|ChuwX7oAZcPqP-%SWj_FFt3
-zyd_?zD3jia8uH=I*yP#l#Bw9^#^N~y33zEtk*o#5XfjXdCkjSG)~N^WoRlb;h;B3|
-zIfCjSc(I06T!_GA1{WKOk*chsMCXx5vW@41o#fZgYViT9VSih*nQN}>g+zCejX>9!
-zZ{c$hGa+w5eO}YT_FH@}B)U(Dl-|zF&dk8R;^4yrPZe)YrI^k%j}0~VZ%*1PT98&h
-z556thD#%T3IZc)NKi{(4RJn@8Dq3?JywFKA?WW585y(IR)(Ee|k5bDtz|lFnDY}0G
-Ds8qe3
-
-literal 0
-HcmV?d00001
-
-diff --git a/src/mainboard/dell/optiplex_3050/devicetree.cb b/src/mainboard/dell/optiplex_3050/devicetree.cb
-new file mode 100644
-index 0000000000..039709aa4a
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/devicetree.cb
-@@ -0,0 +1,103 @@
-+## SPDX-License-Identifier: GPL-2.0-only
-+
-+chip soc/intel/skylake
-+ register "deep_sx_config" = "DSX_EN_WAKE_PIN | DSX_EN_LAN_WAKE_PIN"
-+
-+ # Enable Enhanced Intel SpeedStep
-+ register "eist_enable" = "1"
-+
-+ device domain 0 on
-+ device ref igpu on
-+ register "PrimaryDisplay" = "Display_iGFX"
-+ end
-+
-+ device ref south_xhci on
-+ register "usb2_ports" = "{
-+ [0] = USB2_PORT_MID(OC0), // Front panel (blue)
-+ [1] = USB2_PORT_MID(OC0), // Front panel (blue)
-+ [2] = USB2_PORT_MID(OC3), // Back panel (black)
-+ [3] = USB2_PORT_MID(OC2), // Back panel (blue)
-+ [4] = USB2_PORT_MID(OC1), // Back panel (blue)
-+ [6] = USB2_PORT_MID(OC1), // Back panel (black)
-+ [8] = USB2_PORT_MID(OC_SKIP), // WiFi slot
-+ }"
-+ register "usb3_ports" = "{
-+ [0] = USB3_PORT_DEFAULT(OC0), // Front panel (blue)
-+ [1] = USB3_PORT_DEFAULT(OC0), // Front panel (blue)
-+ [2] = USB3_PORT_DEFAULT(OC2), // Back panel (blue)
-+ [3] = USB3_PORT_DEFAULT(OC1), // Back panel (blue)
-+ }"
-+ end
-+
-+ # ME interface is 'off' to avoid HECI reset delay due to HAP
-+ device ref heci1 off end
-+
-+ device ref sata on
-+ register "SataSalpSupport" = "1"
-+ register "SataPortsEnable[0]" = "1"
-+ end
-+
-+ # M.2 SSD
-+ device ref pcie_rp21 on
-+ register "PcieRpEnable[20]" = "1"
-+ register "PcieRpClkReqSupport[20]" = "1"
-+ register "PcieRpClkReqNumber[20]" = "3"
-+ register "PcieRpAdvancedErrorReporting[20]" = "1"
-+ register "PcieRpLtrEnable[20]" = "1"
-+ register "PcieRpClkSrcNumber[20]" = "3"
-+ register "PcieRpHotPlug[20]" = "1"
-+ end
-+
-+ # Realtek LAN
-+ device ref pcie_rp5 on
-+ register "PcieRpEnable[4]" = "1"
-+ register "PcieRpClkReqSupport[4]" = "0"
-+ register "PcieRpHotPlug[4]" = "0"
-+ end
-+
-+ # M.2 WiFi
-+ device ref pcie_rp8 on
-+ register "PcieRpEnable[7]" = "1"
-+ register "PcieRpClkReqSupport[7]" = "0"
-+ register "PcieRpHotPlug[7]" = "1"
-+ end
-+
-+ # UART0 is exposed on test points on the bottom of the board
-+ device ref uart0 on
-+ register "SerialIoDevMode[PchSerialIoIndexUart0]" = "PchSerialIoPci"
-+ end
-+
-+ device ref lpc_espi on
-+ register "serirq_mode" = "SERIRQ_CONTINUOUS"
-+
-+ # I/O decode for EMI/Runtime registers
-+ register "gen1_dec" = "0x007c0a01"
-+
-+ # SCH5553
-+ chip superio/smsc/sch555x
-+ device pnp 2e.0 on # EMI
-+ io 0x60 = 0xa00
-+ end
-+ device pnp 2e.1 off end # 8042
-+ device pnp 2e.7 on # UART1
-+ io 0x60 = 0x3f8
-+ irq 0x0f = 2
-+ irq 0x70 = 4
-+ end
-+ device pnp 2e.8 off end # UART2
-+ device pnp 2e.c on # LPC interface
-+ io 0x60 = 0x2e
-+ end
-+ device pnp 2e.a on # Runtime registers
-+ io 0x60 = 0xa40
-+ end
-+ device pnp 2e.b off end # Floppy Controller
-+ device pnp 2e.11 off end # Parallel Port
-+ end
-+ end
-+
-+ device ref hda on end
-+
-+ device ref smbus on end
-+ end
-+end
-diff --git a/src/mainboard/dell/optiplex_3050/dsdt.asl b/src/mainboard/dell/optiplex_3050/dsdt.asl
-new file mode 100644
-index 0000000000..9762f6ff74
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/dsdt.asl
-@@ -0,0 +1,27 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#include <acpi/acpi.h>
-+DefinitionBlock(
-+ "dsdt.aml",
-+ "DSDT",
-+ ACPI_DSDT_REV_2,
-+ OEM_ID,
-+ ACPI_TABLE_CREATOR,
-+ 0x20110725
-+)
-+{
-+ #include <acpi/dsdt_top.asl>
-+ #include <soc/intel/common/block/acpi/acpi/globalnvs.asl>
-+ #include <cpu/intel/common/acpi/cpu.asl>
-+
-+ Scope (\_SB)
-+ {
-+ Device (PCI0)
-+ {
-+ #include <soc/intel/skylake/acpi/systemagent.asl>
-+ #include <soc/intel/skylake/acpi/pch.asl>
-+ }
-+ }
-+
-+ #include <southbridge/intel/common/acpi/sleepstates.asl>
-+}
-diff --git a/src/mainboard/dell/optiplex_3050/gma-mainboard.ads b/src/mainboard/dell/optiplex_3050/gma-mainboard.ads
-new file mode 100644
-index 0000000000..cb4c22f285
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/gma-mainboard.ads
-@@ -0,0 +1,19 @@
-+-- SPDX-License-Identifier: GPL-2.0-or-later
-+
-+with HW.GFX.GMA;
-+with HW.GFX.GMA.Display_Probing;
-+
-+use HW.GFX.GMA;
-+use HW.GFX.GMA.Display_Probing;
-+
-+private package GMA.Mainboard is
-+
-+ ports : constant Port_List :=
-+ (HDMI1, -- External HDMI
-+ DP2, -- External DP (native)
-+ HDMI2, -- External DP (DP++)
-+ DP3, -- Video I/O card: VGA (0PKGGG), DP (H64DC)
-+ HDMI3, -- Video I/O card: VGA (0PKGGG), DP (H64DC)
-+ others => Disabled);
-+
-+end GMA.Mainboard;
-diff --git a/src/mainboard/dell/optiplex_3050/hda_verb.c b/src/mainboard/dell/optiplex_3050/hda_verb.c
-new file mode 100644
-index 0000000000..621e4f7a52
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/hda_verb.c
-@@ -0,0 +1,90 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#include <device/azalia_device.h>
-+
-+const u32 cim_verb_data[] = {
-+ /* coreboot specific header, codec 0 */
-+ 0x10ec0255, /* Realtek ALC3234 */
-+ 0x102807a3, /* Subsystem ID */
-+ 11, /* Number of entries */
-+
-+ /* Pin Widget Verb Table */
-+
-+ AZALIA_SUBVENDOR(0, 0x102807a3),
-+
-+ AZALIA_PIN_CFG(0, 0x12, 0x40000000), // does not describe a jack or internal device
-+ AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC(
-+ AZALIA_INTEGRATED,
-+ AZALIA_INTERNAL,
-+ AZALIA_SPEAKER,
-+ AZALIA_OTHER_ANALOG,
-+ AZALIA_COLOR_UNKNOWN,
-+ AZALIA_NO_JACK_PRESENCE_DETECT,
-+ 5, 0
-+ )),
-+ AZALIA_PIN_CFG(0, 0x17, AZALIA_PIN_CFG_NC(0)),
-+ AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)),
-+ AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_CFG_NC(0)),
-+ AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)),
-+ AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_DESC(
-+ AZALIA_JACK,
-+ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_FRONT,
-+ AZALIA_LINE_OUT,
-+ AZALIA_STEREO_MONO_1_8,
-+ AZALIA_BLACK,
-+ AZALIA_JACK_PRESENCE_DETECT,
-+ 2, 0
-+ )),
-+ AZALIA_PIN_CFG(0, 0x1d, 0x4054c029), // does not describe a jack or internal device
-+ AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)),
-+ AZALIA_PIN_CFG(0, 0x21, AZALIA_PIN_DESC(
-+ AZALIA_JACK,
-+ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_FRONT,
-+ AZALIA_HP_OUT,
-+ AZALIA_STEREO_MONO_1_8,
-+ AZALIA_BLACK,
-+ AZALIA_JACK_PRESENCE_DETECT,
-+ 5, 15
-+ )),
-+
-+ /* coreboot specific header, codec 2 */
-+ 0x80862809, /* Intel Skylake HDMI */
-+ 0x80860101, /* Subsystem ID */
-+ 4, /* Number of entries */
-+
-+ /* Pin Widget Verb Table */
-+
-+ AZALIA_SUBVENDOR(2, 0x80860101),
-+
-+ AZALIA_PIN_CFG(2, 0x05, AZALIA_PIN_DESC(
-+ AZALIA_JACK,
-+ AZALIA_DIGITAL_DISPLAY,
-+ AZALIA_DIGITAL_OTHER_OUT,
-+ AZALIA_OTHER_DIGITAL,
-+ AZALIA_COLOR_UNKNOWN,
-+ AZALIA_JACK_PRESENCE_DETECT,
-+ 1, 0
-+ )),
-+ AZALIA_PIN_CFG(2, 0x06, AZALIA_PIN_DESC(
-+ AZALIA_JACK,
-+ AZALIA_DIGITAL_DISPLAY,
-+ AZALIA_DIGITAL_OTHER_OUT,
-+ AZALIA_OTHER_DIGITAL,
-+ AZALIA_COLOR_UNKNOWN,
-+ AZALIA_JACK_PRESENCE_DETECT,
-+ 1, 0
-+ )),
-+ AZALIA_PIN_CFG(2, 0x07, AZALIA_PIN_DESC(
-+ AZALIA_JACK,
-+ AZALIA_DIGITAL_DISPLAY,
-+ AZALIA_DIGITAL_OTHER_OUT,
-+ AZALIA_OTHER_DIGITAL,
-+ AZALIA_COLOR_UNKNOWN,
-+ AZALIA_JACK_PRESENCE_DETECT,
-+ 1, 0
-+ )),
-+};
-+
-+const u32 pc_beep_verbs[] = {};
-+
-+AZALIA_ARRAY_SIZES;
-diff --git a/src/mainboard/dell/optiplex_3050/include/early_gpio.h b/src/mainboard/dell/optiplex_3050/include/early_gpio.h
-new file mode 100644
-index 0000000000..17a16371e3
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/include/early_gpio.h
-@@ -0,0 +1,11 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#ifndef __OPTIPLEX_3050_EARLY_GPIO_H__
-+#define __OPTIPLEX_3050_EARLY_GPIO_H__
-+
-+static const struct pad_config early_gpio_table[] = {
-+ PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0_RXD */
-+ PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0_TXD */
-+};
-+
-+#endif
-diff --git a/src/mainboard/dell/optiplex_3050/include/gpio.h b/src/mainboard/dell/optiplex_3050/include/gpio.h
-new file mode 100644
-index 0000000000..83293c32a9
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/include/gpio.h
-@@ -0,0 +1,241 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#ifndef __OPTIPLEX_3050_GPIO_H__
-+#define __OPTIPLEX_3050_GPIO_H__
-+
-+static const struct pad_config gpio_table[] = {
-+
-+ /* ------- GPIO Community 0 ------- */
-+
-+ /* ------- GPIO Group GPP_A ------- */
-+ PAD_CFG_NF(GPP_A0, UP_20K, PLTRST, NF1), /* RCIN# */
-+ PAD_CFG_NF(GPP_A1, UP_20K, PLTRST, NF1), /* LAD0 */
-+ PAD_CFG_NF(GPP_A2, UP_20K, PLTRST, NF1), /* LAD1 */
-+ PAD_CFG_NF(GPP_A3, UP_20K, PLTRST, NF1), /* LAD2 */
-+ PAD_CFG_NF(GPP_A4, UP_20K, PLTRST, NF1), /* LAD3 */
-+ PAD_CFG_NF(GPP_A5, NONE, PLTRST, NF1), /* LFRAME# */
-+ PAD_CFG_NF(GPP_A6, NONE, PLTRST, NF1), /* SERIRQ */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_A7, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* CLKRUN# */
-+ PAD_CFG_NF(GPP_A9, NONE, PLTRST, NF1), /* CLKOUT_LPC0 */
-+ PAD_CFG_NF(GPP_A10, NONE, PLTRST, NF1), /* CLKOUT_LPC1 */
-+ PAD_CFG_NF(GPP_A11, UP_20K, DEEP, NF1), /* PME# */
-+ PAD_CFG_GPO(GPP_A12, 0, PLTRST), /* GPIO */
-+ PAD_CFG_NF(GPP_A13, NONE, PLTRST, NF1), /* SUSWARN#/SUSPWRDNACK */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_A14, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_A15, UP_20K, PLTRST, NF1), /* SUS_ACK# */
-+ PAD_CFG_GPO(GPP_A16, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_A17, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_A18, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_A19, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_A21, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_A22, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_A23, 0, PLTRST), /* GPIO */
-+
-+ /* ------- GPIO Group GPP_B ------- */
-+ PAD_CFG_GPO(GPP_B0, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B1, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B2, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_B3, 1, RSMRST), /* GPIO (ME_CNTL, B3 -> LOW => HDA_SDO -> HIGH) */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_B4, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_B5, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B6, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B7, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_B8, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_B9, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B10, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_B11, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_B12, NONE, PLTRST, NF1), /* SLP_S0# */
-+ PAD_CFG_NF(GPP_B13, NONE, PLTRST, NF1), /* PLTRST# */
-+ PAD_CFG_NF(GPP_B14, DN_20K, PLTRST, NF1), /* SPKR */
-+ PAD_CFG_GPO(GPP_B15, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B16, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B17, 0, PLTRST), /* GPIO */
-+ PAD_CFG_NF(GPP_B18, DN_20K, DEEP, NF1), /* GSPIO_MOSI */
-+ PAD_CFG_GPO(GPP_B19, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_B20, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_B21, 0, DEEP), /* GPIO */
-+ PAD_CFG_NF(GPP_B22, DN_20K, DEEP, NF1), /* GSPI1_MOSI */
-+ PAD_CFG_NF(GPP_B23, DN_20K, DEEP, NF2), /* PCHHOT# */
-+
-+ /* ------- GPIO Community 1 ------- */
-+
-+ /* ------- GPIO Group GPP_C ------- */
-+ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMBCLK */
-+ PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMBDATA */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_C2, DN_20K, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_C3, NONE, PLTRST, NF1), /* SML0CLK */
-+ PAD_CFG_NF(GPP_C4, NONE, PLTRST, NF1), /* SML0DATA */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_C5, DN_20K, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* SML1CLK */
-+ PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* SML1DATA */
-+ PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0_RXD */
-+ PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0_TXD */
-+ PAD_CFG_GPO(GPP_C10, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C11, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C12, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C13, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C14, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C15, 0, PLTRST), /* GPIO */
-+ PAD_CFG_NF(GPP_C16, NONE, PLTRST, NF1), /* I2C0_SDA */
-+ PAD_CFG_NF(GPP_C17, NONE, PLTRST, NF1), /* I2C0_SCL */
-+ PAD_CFG_GPO(GPP_C18, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C19, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C20, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C21, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_C22, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* GPIO */
-+
-+ /* ------- GPIO Group GPP_D ------- */
-+ PAD_CFG_GPO(GPP_D0, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D1, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D2, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D3, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D4, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_D5, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_D6, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_D7, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D8, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D9, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D10, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D11, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D12, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D13, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D14, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D15, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D17, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D18, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D19, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D20, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D21, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D22, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_D23, 0, PLTRST), /* GPIO */
-+
-+ /* ------- GPIO Group GPP_E ------- */
-+ PAD_CFG_NF(GPP_E0, NONE, DEEP, NF1), /* SATAXPCIE0 */
-+ PAD_CFG_NF(GPP_E1, NONE, DEEP, NF1), /* SATAXPCIE1 */
-+ PAD_CFG_NF(GPP_E2, NONE, DEEP, NF1), /* SATAXPCIE2 */
-+ PAD_CFG_GPO(GPP_E3, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_E4, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_E5, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_E6, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_E7, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_E8, NONE, PLTRST, NF1), /* SATA_LED# */
-+ PAD_CFG_NF(GPP_E9, UP_20K, PLTRST, NF1), /* USB_OC0# */
-+ PAD_CFG_NF(GPP_E10, UP_20K, PLTRST, NF1), /* USB_OC1# */
-+ PAD_CFG_NF(GPP_E11, UP_20K, PLTRST, NF1), /* USB_OC2# */
-+ PAD_CFG_NF(GPP_E12, UP_20K, PLTRST, NF1), /* USB_OC3# */
-+
-+ /* ------- GPIO Group GPP_F ------- */
-+ PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), /* SATAXPCIE3 */
-+ PAD_CFG_NF(GPP_F1, NONE, DEEP, NF1), /* SATAXPCIE4 */
-+ PAD_CFG_NF(GPP_F2, NONE, DEEP, NF1), /* SATAXPCIE5 */
-+ PAD_CFG_NF(GPP_F3, NONE, DEEP, NF1), /* SATAXPCIE6 */
-+ PAD_CFG_NF(GPP_F4, NONE, DEEP, NF1), /* SATAXPCIE7 */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_F5, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_F6, NONE, RSMRST, NF1), /* SATA_DEVSLP4 */
-+ PAD_CFG_GPO(GPP_F7, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_F8, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_F9, 0, RSMRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_F10, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_F11, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_F12, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_F13, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_F14, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_NF(GPP_F15, UP_20K, DEEP, NF1), /* USB_OC4# */
-+ PAD_CFG_NF(GPP_F16, UP_20K, DEEP, NF1), /* USB_OC5# */
-+ PAD_CFG_NF(GPP_F17, UP_20K, PLTRST, NF1), /* USB_OC6# */
-+ PAD_CFG_TERM_GPO(GPP_F18, 0, UP_20K, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_F19, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_F20, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_F21, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_F22, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_F23, 1, RSMRST), /* GPIO */
-+
-+ /* ------- GPIO Group GPP_G ------- */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G0, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G1, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G2, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G3, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G4, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G5, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G6, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G7, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G8, NONE, PLTRST, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_G9, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G10, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G11, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_G12, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPI_TRIG_OWN(GPP_G13, NONE, DEEP, OFF, ACPI), /* GPIO */
-+ PAD_CFG_GPO(GPP_G14, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_G15, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_G16, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_G17, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_G18, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_G19, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_G20, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_G21, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_G22, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_G23, 0, PLTRST), /* GPIO */
-+
-+ /* ------- GPIO Group GPP_H ------- */
-+ PAD_CFG_GPO(GPP_H0, 0, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_H1, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H3, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H4, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H5, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H6, 1, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_H7, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H8, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H9, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H10, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H11, 0, PLTRST), /* GPIO */
-+ PAD_CFG_TERM_GPO(GPP_H12, 1, DN_20K, DEEP), /* GPIO */
-+ PAD_CFG_GPO(GPP_H13, 1, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H14, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H15, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H16, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H17, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H18, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H19, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H20, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H21, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H22, 0, PLTRST), /* GPIO */
-+ PAD_CFG_GPO(GPP_H23, 0, PLTRST), /* GPIO */
-+
-+ /* ------- GPIO Community 2 ------- */
-+
-+ /* -------- GPIO Group GPD -------- */
-+ PAD_CFG_NF(GPD0, NONE, RSMRST, NF1), /* BATLOW# */
-+ PAD_CFG_GPO(GPD1, 0, PWROK), /* GPIO */
-+ PAD_CFG_NF(GPD2, NONE, RSMRST, NF1), /* LAN_WAKE# */
-+ PAD_CFG_NF(GPD3, UP_20K, RSMRST, NF1), /* PWRBTN# */
-+ PAD_CFG_NF(GPD4, NONE, RSMRST, NF1), /* SLP_S3# */
-+ PAD_CFG_NF(GPD5, NONE, RSMRST, NF1), /* SLP_S4# */
-+ PAD_CFG_NF(GPD6, NONE, RSMRST, NF1), /* SLP_A# */
-+ PAD_CFG_GPO(GPD7, 1, RSMRST), /* GPIO */
-+ PAD_CFG_NF(GPD8, NONE, RSMRST, NF1), /* SUSCLK */
-+ PAD_CFG_NF(GPD9, NONE, RSMRST, NF1), /* SLP_WLAN# */
-+ PAD_CFG_NF(GPD10, NONE, RSMRST, NF1), /* SLP_S5# */
-+ PAD_CFG_GPO(GPD11, 1, RSMRST), /* GPIO */
-+
-+ /* ------- GPIO Community 3 ------- */
-+
-+ /* ------- GPIO Group GPP_I ------- */
-+ PAD_CFG_NF(GPP_I0, NONE, PLTRST, NF1), /* DDPB_HPD0 */
-+ PAD_CFG_NF(GPP_I1, NONE, PLTRST, NF1), /* DDPC_HPD1 */
-+ PAD_CFG_NF(GPP_I2, NONE, PLTRST, NF1), /* DDPD_HPD2 */
-+ PAD_CFG_NF(GPP_I3, NONE, PLTRST, NF1), /* DDPE_HPD3 */
-+ PAD_CFG_NF(GPP_I4, NONE, PLTRST, NF1), /* EDP_HPD */
-+ PAD_CFG_NF(GPP_I5, NONE, PLTRST, NF1), /* DDPB_CTRLCLK */
-+ PAD_CFG_NF(GPP_I6, DN_20K, PLTRST, NF1), /* DDPB_CTRLDATA */
-+ PAD_CFG_NF(GPP_I7, NONE, PLTRST, NF1), /* DDPC_CTRLCLK */
-+ PAD_CFG_NF(GPP_I8, DN_20K, PLTRST, NF1), /* DDPC_CTRLDATA */
-+ PAD_CFG_NF(GPP_I9, NONE, PLTRST, NF1), /* DDPD_CTRLCLK */
-+ PAD_CFG_NF(GPP_I10, DN_20K, PLTRST, NF1), /* DDPD_CTRLDATA */
-+};
-+
-+#endif
-diff --git a/src/mainboard/dell/optiplex_3050/ramstage.c b/src/mainboard/dell/optiplex_3050/ramstage.c
-new file mode 100644
-index 0000000000..94778f60c9
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/ramstage.c
-@@ -0,0 +1,512 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#include <bootstate.h>
-+#include <arch/cpuid.h>
-+#include <cpu/x86/msr.h>
-+#include <soc/gpio.h>
-+#include <soc/ramstage.h>
-+#include "include/gpio.h"
-+#include "sch5555_ec.h"
-+
-+void mainboard_silicon_init_params(FSP_SIL_UPD *params)
-+{
-+ gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table));
-+}
-+
-+#define FORM_FACTOR_MICRO 0
-+#define FORM_FACTOR_SFF 1
-+// Probably DT and MT
-+#define FORM_FACTOR_UNK2 2
-+#define FORM_FACTOR_UNK3 3
-+
-+#define HWM_TAB_ADD_TEMP_TARGET 1
-+#define HWM_TAB_PKG_POWER_ANY 0xffff
-+
-+struct hwm_tab_entry {
-+ uint16_t addr;
-+ uint8_t val;
-+ uint8_t flags;
-+ uint16_t pkg_power;
-+};
-+
-+static const struct hwm_tab_entry HWM_TAB_MICRO_BASE[] = {
-+ { 0x005, 0x33, 0, 0xffff },
-+ { 0x018, 0x2f, 0, 0xffff },
-+ { 0x019, 0x2f, 0, 0xffff },
-+ { 0x01a, 0x2f, 0, 0xffff },
-+ { 0x01b, 0x0f, 0, 0xffff },
-+ { 0x057, 0xff, 0, 0xffff },
-+ { 0x059, 0xff, 0, 0xffff },
-+ { 0x05b, 0xff, 0, 0xffff },
-+ { 0x05d, 0xff, 0, 0xffff },
-+ { 0x05f, 0xff, 0, 0xffff },
-+ { 0x061, 0xff, 0, 0xffff },
-+ { 0x06e, 0x00, 0, 0xffff },
-+ { 0x06f, 0x03, 0, 0xffff },
-+ { 0x070, 0x03, 0, 0xffff },
-+ { 0x071, 0x02, 0, 0xffff },
-+ { 0x072, 0x02, 0, 0xffff },
-+ { 0x073, 0x01, 0, 0xffff },
-+ { 0x074, 0x06, 0, 0xffff },
-+ { 0x075, 0x07, 0, 0xffff },
-+ { 0x080, 0x00, 0, 0xffff },
-+ { 0x081, 0x80, 0, 0xffff },
-+ { 0x082, 0x80, 0, 0xffff },
-+ { 0x083, 0xbb, 0, 0xffff },
-+ { 0x085, 0xf1, 0, 0xffff },
-+ { 0x086, 0x88, 0, 0xffff },
-+ { 0x087, 0x61, 0, 0xffff },
-+ { 0x088, 0x08, 0, 0xffff },
-+ { 0x089, 0x00, 0, 0xffff },
-+ { 0x08a, 0x73, 0, 0xffff },
-+ { 0x08b, 0x73, 0, 0xffff },
-+ { 0x08c, 0x73, 0, 0xffff },
-+ { 0x090, 0x6d, 0, 0xffff },
-+ { 0x091, 0x7e, 0, 0xffff },
-+ { 0x092, 0x66, 0, 0xffff },
-+ { 0x093, 0xa4, 0, 0xffff },
-+ { 0x094, 0x7c, 0, 0xffff },
-+ { 0x095, 0xa4, 0, 0xffff },
-+ { 0x096, 0xa4, 0, 0xffff },
-+ { 0x097, 0xa4, 0, 0xffff },
-+ { 0x098, 0xa4, 0, 0xffff },
-+ { 0x099, 0xa4, 0, 0xffff },
-+ { 0x09a, 0xa4, 0, 0xffff },
-+ { 0x09b, 0xa4, 0, 0xffff },
-+ { 0x0a0, 0x2e, 0, 0xffff },
-+ { 0x0a1, 0x00, 0, 0xffff },
-+ { 0x0a2, 0x00, 0, 0xffff },
-+ { 0x0ae, 0xa4, 0, 0xffff },
-+ { 0x0af, 0xa4, 0, 0xffff },
-+ { 0x0b0, 0xa4, 0, 0xffff },
-+ { 0x0b1, 0xa4, 0, 0xffff },
-+ { 0x0b2, 0xa4, 0, 0xffff },
-+ { 0x0b3, 0xa4, 0, 0xffff },
-+ { 0x0b6, 0x00, 0, 0xffff },
-+ { 0x0b7, 0x00, 0, 0xffff },
-+ { 0x0d1, 0xff, 0, 0xffff },
-+ { 0x0d6, 0xff, 0, 0xffff },
-+ { 0x0db, 0xff, 0, 0xffff },
-+ { 0x0ea, 0x5c, 0, 0xffff },
-+ { 0x0eb, 0x5c, 0, 0xffff },
-+ { 0x0ef, 0xff, 0, 0xffff },
-+ { 0x0f8, 0x15, 0, 0xffff },
-+ { 0x0f9, 0x00, 0, 0xffff },
-+ { 0x0f0, 0x30, 0, 0xffff },
-+ { 0x184, 0xff, 0, 0xffff },
-+ { 0x186, 0xff, 0, 0xffff },
-+ { 0x1a1, 0xce, 0, 0xffff },
-+ { 0x1a2, 0x0c, 0, 0xffff },
-+ { 0x1a3, 0x0c, 0, 0xffff },
-+ { 0x1a6, 0x00, 0, 0xffff },
-+ { 0x1a7, 0x00, 0, 0xffff },
-+ { 0x1a8, 0xa4, 0, 0xffff },
-+ { 0x1a9, 0xa4, 0, 0xffff },
-+ { 0x1ab, 0x2d, 0, 0xffff },
-+ { 0x1ac, 0x2d, 0, 0xffff },
-+ { 0x1b1, 0x00, 0, 0xffff },
-+ { 0x1bb, 0x00, 0, 0xffff },
-+ { 0x1bc, 0x00, 0, 0xffff },
-+ { 0x1bd, 0x00, 0, 0xffff },
-+ { 0x1be, 0x01, 0, 0xffff },
-+ { 0x1bf, 0x01, 0, 0xffff },
-+ { 0x1c0, 0x01, 0, 0xffff },
-+ { 0x1c1, 0x01, 0, 0xffff },
-+ { 0x1c2, 0x01, 0, 0xffff },
-+ { 0x280, 0x00, 0, 0xffff },
-+ { 0x281, 0x00, 0, 0xffff },
-+ { 0x282, 0x03, 0, 0xffff },
-+ { 0x283, 0x0a, 0, 0xffff },
-+ { 0x284, 0x80, 0, 0xffff },
-+ { 0x285, 0x03, 0, 0xffff },
-+ { 0x040, 0x01, 0, 0xffff },
-+};
-+
-+static const struct hwm_tab_entry HWM_TAB_MICRO_TEMP80[] = {
-+ { 0x005, 0x33, 0, 0xffff },
-+ { 0x018, 0x2f, 0, 0xffff },
-+ { 0x019, 0x2f, 0, 0xffff },
-+ { 0x01a, 0x2f, 0, 0xffff },
-+ { 0x01b, 0x0f, 0, 0xffff },
-+ { 0x057, 0xff, 0, 0xffff },
-+ { 0x059, 0xff, 0, 0xffff },
-+ { 0x05b, 0xff, 0, 0xffff },
-+ { 0x05d, 0xff, 0, 0xffff },
-+ { 0x05f, 0xff, 0, 0xffff },
-+ { 0x061, 0xff, 0, 0xffff },
-+ { 0x06e, 0x00, 0, 0xffff },
-+ { 0x06f, 0x03, 0, 0xffff },
-+ { 0x070, 0x03, 0, 0xffff },
-+ { 0x071, 0x02, 0, 0xffff },
-+ { 0x072, 0x02, 0, 0xffff },
-+ { 0x073, 0x01, 0, 0xffff },
-+ { 0x074, 0x06, 0, 0xffff },
-+ { 0x075, 0x07, 0, 0xffff },
-+ { 0x080, 0x00, 0, 0xffff },
-+ { 0x081, 0x80, 0, 0xffff },
-+ { 0x082, 0x80, 0, 0xffff },
-+ { 0x083, 0xbb, 0, 0xffff },
-+ { 0x085, 0xf6, 0, 0xffff },
-+ { 0x086, 0x88, 0, 0xffff },
-+ { 0x087, 0x61, 0, 0xffff },
-+ { 0x088, 0x08, 0, 0xffff },
-+ { 0x089, 0x00, 0, 0xffff },
-+ { 0x08a, 0x73, 0, 0xffff },
-+ { 0x08b, 0x73, 0, 0xffff },
-+ { 0x08c, 0x73, 0, 0xffff },
-+ { 0x090, 0x6d, 0, 0xffff },
-+ { 0x091, 0x86, 0, 0xffff },
-+ { 0x092, 0x66, 0, 0xffff },
-+ { 0x093, 0xa4, 0, 0xffff },
-+ { 0x094, 0x7c, 0, 0xffff },
-+ { 0x095, 0xa4, 0, 0xffff },
-+ { 0x096, 0xa4, 0, 0xffff },
-+ { 0x097, 0xa4, 0, 0xffff },
-+ { 0x098, 0xa4, 0, 0xffff },
-+ { 0x099, 0xa4, 0, 0xffff },
-+ { 0x09a, 0xa4, 0, 0xffff },
-+ { 0x09b, 0xa4, 0, 0xffff },
-+ { 0x0a0, 0x2e, 0, 0xffff },
-+ { 0x0a1, 0x00, 0, 0xffff },
-+ { 0x0a2, 0x00, 0, 0xffff },
-+ { 0x0ae, 0xa4, 0, 0xffff },
-+ { 0x0af, 0xa4, 0, 0xffff },
-+ { 0x0b0, 0xa4, 0, 0xffff },
-+ { 0x0b1, 0xa4, 0, 0xffff },
-+ { 0x0b2, 0xa4, 0, 0xffff },
-+ { 0x0b3, 0xa4, 0, 0xffff },
-+ { 0x0b6, 0x00, 0, 0xffff },
-+ { 0x0b7, 0x00, 0, 0xffff },
-+ { 0x0d1, 0xff, 0, 0xffff },
-+ { 0x0d6, 0xff, 0, 0xffff },
-+ { 0x0db, 0xff, 0, 0xffff },
-+ { 0x0ea, 0x50, 0, 0xffff },
-+ { 0x0eb, 0x50, 0, 0xffff },
-+ { 0x0ef, 0xff, 0, 0xffff },
-+ { 0x0f8, 0x15, 0, 0xffff },
-+ { 0x0f9, 0x00, 0, 0xffff },
-+ { 0x0f0, 0x30, 0, 0xffff },
-+ { 0x184, 0xff, 0, 0xffff },
-+ { 0x186, 0xff, 0, 0xffff },
-+ { 0x1a1, 0xce, 0, 0xffff },
-+ { 0x1a2, 0x0c, 0, 0xffff },
-+ { 0x1a3, 0x0c, 0, 0xffff },
-+ { 0x1a6, 0x00, 0, 0xffff },
-+ { 0x1a7, 0x00, 0, 0xffff },
-+ { 0x1a8, 0xa4, 0, 0xffff },
-+ { 0x1a9, 0xa4, 0, 0xffff },
-+ { 0x1ab, 0x2d, 0, 0xffff },
-+ { 0x1ac, 0x2d, 0, 0xffff },
-+ { 0x1b1, 0x00, 0, 0xffff },
-+ { 0x1bb, 0x00, 0, 0xffff },
-+ { 0x1bc, 0x00, 0, 0xffff },
-+ { 0x1bd, 0x00, 0, 0xffff },
-+ { 0x1be, 0x01, 0, 0xffff },
-+ { 0x1bf, 0x01, 0, 0xffff },
-+ { 0x1c0, 0x01, 0, 0xffff },
-+ { 0x1c1, 0x01, 0, 0xffff },
-+ { 0x1c2, 0x01, 0, 0xffff },
-+ { 0x280, 0x00, 0, 0xffff },
-+ { 0x281, 0x00, 0, 0xffff },
-+ { 0x282, 0x03, 0, 0xffff },
-+ { 0x283, 0x0a, 0, 0xffff },
-+ { 0x284, 0x80, 0, 0xffff },
-+ { 0x285, 0x03, 0, 0xffff },
-+ { 0x040, 0x01, 0, 0xffff },
-+};
-+
-+static const struct hwm_tab_entry HWM_TAB_MICRO_EARLY_STEPPING[] = {
-+ { 0x005, 0x33, 0, 0xffff },
-+ { 0x018, 0x2f, 0, 0xffff },
-+ { 0x019, 0x2f, 0, 0xffff },
-+ { 0x01a, 0x2f, 0, 0xffff },
-+ { 0x01b, 0x0f, 0, 0xffff },
-+ { 0x057, 0xff, 0, 0xffff },
-+ { 0x059, 0xff, 0, 0xffff },
-+ { 0x05b, 0xff, 0, 0xffff },
-+ { 0x05d, 0xff, 0, 0xffff },
-+ { 0x05f, 0xff, 0, 0xffff },
-+ { 0x061, 0xff, 0, 0xffff },
-+ { 0x06e, 0x01, 0, 0xffff },
-+ { 0x06f, 0x03, 0, 0xffff },
-+ { 0x070, 0x03, 0, 0xffff },
-+ { 0x071, 0x02, 0, 0xffff },
-+ { 0x072, 0x02, 0, 0xffff },
-+ { 0x073, 0x01, 0, 0xffff },
-+ { 0x074, 0x06, 0, 0xffff },
-+ { 0x075, 0x07, 0, 0xffff },
-+ { 0x080, 0x00, 0, 0xffff },
-+ { 0x081, 0x80, 0, 0xffff },
-+ { 0x082, 0x80, 0, 0xffff },
-+ { 0x083, 0xbb, 0, 0xffff },
-+ { 0x085, 0xfd, 0, 0xffff },
-+ { 0x086, 0x60, 0, 0xffff },
-+ { 0x087, 0x50, 0, 0xffff },
-+ { 0x088, 0x08, 0, 0xffff },
-+ { 0x089, 0x00, 0, 0xffff },
-+ { 0x08a, 0x73, 0, 0xffff },
-+ { 0x08b, 0x73, 0, 0xffff },
-+ { 0x08c, 0x73, 0, 0xffff },
-+ { 0x090, 0x6d, 0, 0xffff },
-+ { 0x091, 0x7a, 0, 0xffff },
-+ { 0x092, 0x6b, 0, 0xffff },
-+ { 0x093, 0xa4, 0, 0xffff },
-+ { 0x094, 0x78, 0, 0xffff },
-+ { 0x095, 0xa4, 0, 0xffff },
-+ { 0x096, 0xa4, 0, 0xffff },
-+ { 0x097, 0xa4, 0, 0xffff },
-+ { 0x098, 0xa4, 0, 0xffff },
-+ { 0x099, 0xa4, 0, 0xffff },
-+ { 0x09a, 0xa4, 0, 0xffff },
-+ { 0x09b, 0xa4, 0, 0xffff },
-+ { 0x0a0, 0x2e, 0, 0xffff },
-+ { 0x0a1, 0x00, 0, 0xffff },
-+ { 0x0a2, 0x00, 0, 0xffff },
-+ { 0x0ae, 0xa4, 0, 0xffff },
-+ { 0x0af, 0xa4, 0, 0xffff },
-+ { 0x0b0, 0xa4, 0, 0xffff },
-+ { 0x0b1, 0xa4, 0, 0xffff },
-+ { 0x0b2, 0xa4, 0, 0xffff },
-+ { 0x0b3, 0xa4, 0, 0xffff },
-+ { 0x0b6, 0x00, 0, 0xffff },
-+ { 0x0b7, 0x00, 0, 0xffff },
-+ { 0x0d1, 0xff, 0, 0xffff },
-+ { 0x0d6, 0xff, 0, 0xffff },
-+ { 0x0db, 0xff, 0, 0xffff },
-+ { 0x0ea, 0x64, 0, 0xffff },
-+ { 0x0eb, 0x64, 0, 0xffff },
-+ { 0x0ef, 0xff, 0, 0xffff },
-+ { 0x0f8, 0x15, 0, 0xffff },
-+ { 0x0f9, 0x00, 0, 0xffff },
-+ { 0x0f0, 0x30, 0, 0xffff },
-+ { 0x184, 0xff, 0, 0xffff },
-+ { 0x186, 0xff, 0, 0xffff },
-+ { 0x1a1, 0xce, 0, 0xffff },
-+ { 0x1a2, 0x0c, 0, 0xffff },
-+ { 0x1a3, 0x0c, 0, 0xffff },
-+ { 0x1a6, 0x00, 0, 0xffff },
-+ { 0x1a7, 0x00, 0, 0xffff },
-+ { 0x1a8, 0xa4, 0, 0xffff },
-+ { 0x1a9, 0xa4, 0, 0xffff },
-+ { 0x1ab, 0x2d, 0, 0xffff },
-+ { 0x1ac, 0x2d, 0, 0xffff },
-+ { 0x1b1, 0x00, 0, 0xffff },
-+ { 0x1bb, 0x00, 0, 0xffff },
-+ { 0x1bc, 0x00, 0, 0xffff },
-+ { 0x1bd, 0x00, 0, 0xffff },
-+ { 0x1be, 0x01, 0, 0xffff },
-+ { 0x1bf, 0x01, 0, 0xffff },
-+ { 0x1c0, 0x01, 0, 0xffff },
-+ { 0x1c1, 0x01, 0, 0xffff },
-+ { 0x1c2, 0x01, 0, 0xffff },
-+ { 0x280, 0x00, 0, 0xffff },
-+ { 0x281, 0x00, 0, 0xffff },
-+ { 0x282, 0x03, 0, 0xffff },
-+ { 0x283, 0x0a, 0, 0xffff },
-+ { 0x284, 0x80, 0, 0xffff },
-+ { 0x285, 0x03, 0, 0xffff },
-+ { 0x040, 0x01, 0, 0xffff },
-+};
-+
-+static const struct hwm_tab_entry HWM_TAB_SFF[] = {
-+ { 0x019, 0x2f, 0, 0xffff },
-+ { 0x040, 0x01, 0, 0xffff },
-+ { 0x072, 0x03, 0, 0xffff },
-+ { 0x075, 0x06, 0, 0xffff },
-+ { 0x07c, 0x00, 0, 0xffff },
-+ { 0x080, 0x00, 0, 0xffff },
-+ { 0x081, 0x00, 0, 0xffff },
-+ { 0x083, 0xbb, 0, 0xffff },
-+ { 0x085, 0x59, 0, 0xffff },
-+ { 0x086, 0x6a, 0, 0xffff },
-+ { 0x087, 0xc0, 0, 0xffff },
-+ { 0x08a, 0x33, 0, 0xffff },
-+ { 0x090, 0x77, 0, 0xffff },
-+ { 0x091, 0x66, 0, 0xffff },
-+ { 0x092, 0x94, 0, 0xffff },
-+ { 0x093, 0x90, 0, 0xffff },
-+ { 0x094, 0x68, 0, 0xffff },
-+ { 0x096, 0xa4, 0, 0xffff },
-+ { 0x097, 0xa4, 0, 0xffff },
-+ { 0x098, 0xa4, 0, 0xffff },
-+ { 0x099, 0xa4, 0, 0xffff },
-+ { 0x09a, 0xa4, 0, 0xffff },
-+ { 0x09b, 0xa4, 0, 0xffff },
-+ { 0x0a0, 0x3e, 0, 0xffff },
-+ { 0x0ae, 0x86, 0, 0xffff },
-+ { 0x0af, 0x86, 0, 0xffff },
-+ { 0x0b0, 0xa4, 0, 0xffff },
-+ { 0x0b1, 0xa4, 0, 0xffff },
-+ { 0x0b2, 0x90, 0, 0xffff },
-+ { 0x0b6, 0x48, 0, 0xffff },
-+ { 0x0b7, 0x48, 0, 0xffff },
-+ { 0x0ea, 0x64, 0, 0xffff },
-+ { 0x0f0, 0x30, 0, 0xffff },
-+ { 0x1b1, 0x48, 0, 0xffff },
-+ { 0x1b8, 0x00, 0, 0xffff },
-+ { 0x1be, 0x95, 0, 0xffff },
-+ { 0x1c1, 0x90, 0, 0xffff },
-+ { 0x1c6, 0x00, 0, 0xffff },
-+ { 0x1c9, 0x00, 0, 0xffff },
-+ { 0x280, 0x68, 0, 0xffff },
-+ { 0x281, 0x10, 0, 0xffff },
-+ { 0x282, 0x03, 0, 0xffff },
-+ { 0x283, 0x0a, 0, 0xffff },
-+ { 0x284, 0x80, 0, 0xffff },
-+ { 0x285, 0x03, 0, 0xffff}
-+};
-+
-+static const struct hwm_tab_entry HWM_TAB_MT[] = {
-+ { 0x005, 0x33, 0, 0xffff },
-+ { 0x018, 0x2f, 0, 0xffff },
-+ { 0x019, 0x2f, 0, 0xffff },
-+ { 0x01a, 0x2f, 0, 0xffff },
-+ { 0x080, 0x00, 0, 0xffff },
-+ { 0x081, 0x00, 0, 0xffff },
-+ { 0x082, 0x80, 0, 0xffff },
-+ { 0x083, 0xbb, 0, 0xffff },
-+ { 0x085, 0xb9, 0, 0x0010 },
-+ { 0x086, 0xac, 0, 0x0010 },
-+ { 0x087, 0x87, 0, 0x0010 },
-+ { 0x08a, 0x51, 0, 0x0010 },
-+ { 0x08b, 0x39, 0, 0x0010 },
-+ { 0x090, 0x78, 0, 0xffff },
-+ { 0x091, 0x6a, 0, 0xffff },
-+ { 0x092, 0x8f, 0, 0xffff },
-+ { 0x094, 0x68, 0, 0xffff },
-+ { 0x095, 0x5b, 0, 0xffff },
-+ { 0x096, 0x92, 0, 0xffff },
-+ { 0x097, 0x86, 0, 0xffff },
-+ { 0x098, 0xa4, 0, 0xffff },
-+ { 0x09a, 0x8b, 0, 0xffff },
-+ { 0x0a0, 0x0a, 0, 0xffff },
-+ { 0x0a1, 0x26, 0, 0xffff },
-+ { 0x0a2, 0xd1, 0, 0xffff },
-+ { 0x0ae, 0x7c, 0, 0xffff },
-+ { 0x0af, 0x7c, 0, 0xffff },
-+ { 0x0b0, 0x9a, 0, 0xffff },
-+ { 0x0b3, 0x7c, 0, 0xffff },
-+ { 0x0b6, 0x08, 0, 0xffff },
-+ { 0x0b7, 0x00, 0, 0xffff },
-+ { 0x0ea, 0x64, 0, 0xffff },
-+ { 0x0ef, 0xff, 0, 0xffff },
-+ { 0x0f8, 0x15, 0, 0xffff },
-+ { 0x0f9, 0x00, 0, 0xffff },
-+ { 0x0f0, 0x30, 0, 0xffff },
-+ { 0x0fd, 0x01, 0, 0xffff },
-+ { 0x1a1, 0x99, 0, 0xffff },
-+ { 0x1a2, 0x00, 0, 0xffff },
-+ { 0x1a4, 0x00, 0, 0xffff },
-+ { 0x1b1, 0x00, 0, 0xffff },
-+ { 0x1be, 0x90, 0, 0xffff },
-+ { 0x280, 0xc4, 0, 0xffff },
-+ { 0x281, 0x09, 0, 0xffff },
-+ { 0x282, 0x0a, 0, 0xffff },
-+ { 0x283, 0x14, 0, 0xffff },
-+ { 0x284, 0x01, 0, 0xffff },
-+ { 0x285, 0x01, 0, 0xffff },
-+ { 0x288, 0x94, 0, 0xffff },
-+ { 0x289, 0x11, 0, 0xffff },
-+ { 0x28a, 0x0a, 0, 0xffff },
-+ { 0x28b, 0x14, 0, 0xffff },
-+ { 0x28c, 0x01, 0, 0xffff },
-+ { 0x28d, 0x01, 0, 0xffff },
-+ { 0x294, 0x24, 0, 0xffff },
-+};
-+
-+static uint8_t get_temp_target(void)
-+{
-+ uint8_t val = rdmsr(0x1a2).lo >> 8 & 0xff;
-+ if (!val)
-+ val = 20;
-+ return 0x95 - val;
-+}
-+
-+static uint16_t get_pkg_power(void)
-+{
-+ const unsigned int pkg_power = rdmsr(0x614).lo & 0x7fff;
-+ const unsigned int power_unit = 1 << (rdmsr(0x606).lo & 0xf);
-+ if (pkg_power / power_unit > 65)
-+ return 32;
-+ else
-+ return 16;
-+}
-+
-+static uint8_t get_core_cnt(void)
-+{
-+ // Intel describes this CPUID field as:
-+ // > Maximum number of addressable IDs for processor cores in the physical package
-+ if (cpuid(0).eax >= 4)
-+ return cpuid_ext(4, 0).eax >> 26;
-+ return 0;
-+}
-+
-+static void apply_hwm_tab(const struct hwm_tab_entry *arr, size_t size)
-+{
-+ uint8_t temp_target = get_temp_target();
-+ uint16_t pkg_power = get_pkg_power();
-+
-+ printk(BIOS_DEBUG, "Temp target = %#x\n", temp_target);
-+ printk(BIOS_DEBUG, "Package power = %#x\n", pkg_power);
-+
-+ for (size_t i = 0; i < size; ++i) {
-+ // Skip entry if it doesn't apply for this package power
-+ if (arr[i].pkg_power != pkg_power &&
-+ arr[i].pkg_power != HWM_TAB_PKG_POWER_ANY)
-+ continue;
-+
-+ uint8_t val = arr[i].val;
-+
-+ // Add temp target to value if requested (current tables never do)
-+ if (arr[i].flags & HWM_TAB_ADD_TEMP_TARGET)
-+ val += temp_target;
-+
-+ // Perform write
-+ sch5555_mbox_write(1, arr[i].addr, val);
-+ }
-+}
-+
-+static void sch5555_ec_hwm_init(void *arg)
-+{
-+ uint8_t form_fac_id, saved_2fc, core_cnt;
-+
-+ printk(BIOS_DEBUG, "OptiPlex 3050 late HWM init\n");
-+
-+ form_fac_id = gpio_get(GPP_G2) | gpio_get(GPP_G3) << 1;
-+ printk(BIOS_DEBUG, "Form Factor ID = %#x\n", form_fac_id);
-+
-+ saved_2fc = sch5555_mbox_read(1, 0x2fc);
-+ sch5555_mbox_write(1, 0x2fc, 0xa0);
-+ sch5555_mbox_write(1, 0x2fd, 0x32);
-+
-+ switch (form_fac_id) {
-+ case FORM_FACTOR_MICRO:
-+ // CPU stepping <= 3
-+ if ((cpuid(1).eax & 0xf) <= 3)
-+ apply_hwm_tab(HWM_TAB_MICRO_EARLY_STEPPING, ARRAY_SIZE(HWM_TAB_MICRO_EARLY_STEPPING));
-+ // Tjunction == 80
-+ else if ((rdmsr(0x1a2).lo >> 16 & 0xff) == 80)
-+ apply_hwm_tab(HWM_TAB_MICRO_TEMP80, ARRAY_SIZE(HWM_TAB_MICRO_TEMP80));
-+ else
-+ apply_hwm_tab(HWM_TAB_MICRO_BASE, ARRAY_SIZE(HWM_TAB_MICRO_BASE));
-+ break;
-+ case FORM_FACTOR_SFF:
-+ apply_hwm_tab(HWM_TAB_SFF, ARRAY_SIZE(HWM_TAB_SFF));
-+ break;
-+ default:
-+ apply_hwm_tab(HWM_TAB_MT, ARRAY_SIZE(HWM_TAB_MT));
-+ break;
-+ }
-+
-+ core_cnt = get_core_cnt();
-+ printk(BIOS_DEBUG, "CPU Core Count = %#x\n", core_cnt);
-+ if (core_cnt > 2) {
-+ sch5555_mbox_write(1, 0x9e, 0x30);
-+ sch5555_mbox_write(1, 0xeb, sch5555_mbox_read(1, 0xea));
-+ }
-+
-+ sch5555_mbox_write(1, 0x2fc, saved_2fc);
-+ sch5555_mbox_read(1, 0xb8);
-+}
-+
-+BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, sch5555_ec_hwm_init, NULL);
-diff --git a/src/mainboard/dell/optiplex_3050/romstage.c b/src/mainboard/dell/optiplex_3050/romstage.c
-new file mode 100644
-index 0000000000..501b254232
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/romstage.c
-@@ -0,0 +1,18 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#include <soc/romstage.h>
-+#include <spd_bin.h>
-+
-+void mainboard_memory_init_params(FSPM_UPD *mupd)
-+{
-+ struct spd_block blk = { .addr_map = { 0x50, 0x52, } };
-+ get_spd_smbus(&blk);
-+ dump_spd_info(&blk);
-+
-+ FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig;
-+ mem_cfg->DqPinsInterleaved = true;
-+ mem_cfg->CaVrefConfig = 2;
-+ mem_cfg->MemorySpdDataLen = blk.len;
-+ mem_cfg->MemorySpdPtr00 = (uintptr_t)blk.spd_array[0];
-+ mem_cfg->MemorySpdPtr10 = (uintptr_t)blk.spd_array[1];
-+}
-diff --git a/src/mainboard/dell/optiplex_3050/sch5555_ec.c b/src/mainboard/dell/optiplex_3050/sch5555_ec.c
-new file mode 100644
-index 0000000000..1df5026531
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/sch5555_ec.c
-@@ -0,0 +1,54 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#include <arch/io.h>
-+#include <device/pnp_ops.h>
-+#include <superio/smsc/sch555x/sch555x.h>
-+#include "sch5555_ec.h"
-+
-+uint8_t sch5555_mbox_read(uint8_t addr1, uint16_t addr2)
-+{
-+ // clear ec-to-host mailbox
-+ uint8_t tmp = inb(SCH555x_EMI_IOBASE + 1);
-+ outb(tmp, SCH555x_EMI_IOBASE + 1);
-+
-+ // send address
-+ outw(0 | 0x8001, SCH555x_EMI_IOBASE + 2);
-+ outw((addr1 * 2) | 0x100, SCH555x_EMI_IOBASE + 4);
-+
-+ outw(4 | 0x8002, SCH555x_EMI_IOBASE + 2);
-+ outl(addr2 << 16, SCH555x_EMI_IOBASE + 4);
-+
-+ // send message to ec
-+ outb(1, SCH555x_EMI_IOBASE);
-+
-+ // wait for ack
-+ for (size_t retry = 0; retry < 0xfff; ++retry)
-+ if (inb(SCH555x_EMI_IOBASE + 1) & 1)
-+ break;
-+
-+ // read result
-+ outw(4 | 0x8000, SCH555x_EMI_IOBASE + 2);
-+ return inb(SCH555x_EMI_IOBASE + 4);
-+}
-+
-+void sch5555_mbox_write(uint8_t addr1, uint16_t addr2, uint8_t val)
-+{
-+ // clear ec-to-host mailbox
-+ uint8_t tmp = inb(SCH555x_EMI_IOBASE + 1);
-+ outb(tmp, SCH555x_EMI_IOBASE + 1);
-+
-+ // send address and value
-+ outw(0 | 0x8001, SCH555x_EMI_IOBASE + 2);
-+ outw((addr1 * 2) | 0x101, SCH555x_EMI_IOBASE + 4);
-+
-+ outw(4 | 0x8002, SCH555x_EMI_IOBASE + 2);
-+ outl(val | (addr2 << 16), SCH555x_EMI_IOBASE + 4);
-+
-+ // send message to ec
-+ outb(1, SCH555x_EMI_IOBASE);
-+
-+ // wait for ack
-+ for (size_t retry = 0; retry < 0xfff; ++retry)
-+ if (inb(SCH555x_EMI_IOBASE + 1) & 1)
-+ break;
-+}
-diff --git a/src/mainboard/dell/optiplex_3050/sch5555_ec.h b/src/mainboard/dell/optiplex_3050/sch5555_ec.h
-new file mode 100644
-index 0000000000..9d262d5787
---- /dev/null
-+++ b/src/mainboard/dell/optiplex_3050/sch5555_ec.h
-@@ -0,0 +1,10 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+
-+#ifndef __SCH5555_EC_H__
-+#define __SCH5555_EC_H__
-+
-+uint8_t sch5555_mbox_read(uint8_t addr1, uint16_t addr2);
-+
-+void sch5555_mbox_write(uint8_t addr1, uint16_t addr2, uint8_t val);
-+
-+#endif
---
-2.39.5
-
diff --git a/config/coreboot/next/patches/0001-soc-intel-skylake-configure-usb-acpi.patch b/config/coreboot/next/patches/0001-soc-intel-skylake-configure-usb-acpi.patch
new file mode 100644
index 00000000..1b6b5372
--- /dev/null
+++ b/config/coreboot/next/patches/0001-soc-intel-skylake-configure-usb-acpi.patch
@@ -0,0 +1,94 @@
+From 18b68185f44599cf6ea6a20816bf6a5eb7aeda17 Mon Sep 17 00:00:00 2001
+From: Felix Singer <felixsinger@posteo.net>
+Date: Wed, 26 Jun 2024 04:24:31 +0200
+Subject: [PATCH 1/8] soc/intel/skylake: configure usb acpi
+
+Change-Id: I53fc73046e4b107064fa8c3c617ba6d9b807b71d
+Signed-off-by: Felix Singer <felixsinger@posteo.net>
+---
+ src/soc/intel/skylake/Kconfig | 1 +
+ src/soc/intel/skylake/chipset.cb | 56 +++++++++++++++++++++++++++++++-
+ 2 files changed, 56 insertions(+), 1 deletion(-)
+
+diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
+index 22017c848b..c24df2ef75 100644
+--- a/src/soc/intel/skylake/Kconfig
++++ b/src/soc/intel/skylake/Kconfig
+@@ -10,6 +10,7 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE
+ select CPU_INTEL_COMMON
+ select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
+ select CPU_SUPPORTS_PM_TIMER_EMULATION
++ select DRIVERS_USB_ACPI
+ select EDK2_CPU_TIMER_LIB if PAYLOAD_EDK2
+ select FSP_COMPRESS_FSP_S_LZ4
+ select FSP_M_XIP
+diff --git a/src/soc/intel/skylake/chipset.cb b/src/soc/intel/skylake/chipset.cb
+index 6538a1475b..dfb81d496e 100644
+--- a/src/soc/intel/skylake/chipset.cb
++++ b/src/soc/intel/skylake/chipset.cb
+@@ -13,7 +13,61 @@ chip soc/intel/skylake
+ device pci 07.0 alias chap off end
+ device pci 08.0 alias gmm off end # Gaussian Mixture Model
+ device pci 13.0 alias ish off end # SensorHub
+- device pci 14.0 alias south_xhci off ops usb_xhci_ops end
++ device pci 14.0 alias south_xhci off ops usb_xhci_ops
++ chip drivers/usb/acpi
++ register "type" = "UPC_TYPE_HUB"
++ device usb 0.0 alias xhci_root_hub off
++ chip drivers/usb/acpi
++ device usb 2.0 alias usb2_port1 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.1 alias usb2_port2 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.2 alias usb2_port3 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.3 alias usb2_port4 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.4 alias usb2_port5 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.5 alias usb2_port6 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.6 alias usb2_port7 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.7 alias usb2_port8 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.8 alias usb2_port9 off end
++ end
++ chip drivers/usb/acpi
++ device usb 2.9 alias usb2_port10 off end
++ end
++ chip drivers/usb/acpi
++ device usb 3.0 alias usb3_port1 off end
++ end
++ chip drivers/usb/acpi
++ device usb 3.1 alias usb3_port2 off end
++ end
++ chip drivers/usb/acpi
++ device usb 3.2 alias usb3_port3 off end
++ end
++ chip drivers/usb/acpi
++ device usb 3.3 alias usb3_port4 off end
++ end
++ chip drivers/usb/acpi
++ device usb 3.4 alias usb3_port5 off end
++ end
++ chip drivers/usb/acpi
++ device usb 3.5 alias usb3_port6 off end
++ end
++ end
++ end
++ end
+ device pci 14.1 alias south_xdci off ops usb_xdci_ops end
+ device pci 14.2 alias thermal off end
+ device pci 14.3 alias cio off end
+--
+2.39.5
+
diff --git a/config/coreboot/next/patches/0002-mb-lenovo-Add-initial-code-for-Lenovo-ThinkPad-E460.patch b/config/coreboot/next/patches/0002-mb-lenovo-Add-initial-code-for-Lenovo-ThinkPad-E460.patch
new file mode 100644
index 00000000..77d7b080
--- /dev/null
+++ b/config/coreboot/next/patches/0002-mb-lenovo-Add-initial-code-for-Lenovo-ThinkPad-E460.patch
@@ -0,0 +1,308 @@
+From a7cbcbc7037fe3473e5ebe475cbfd12f653e9827 Mon Sep 17 00:00:00 2001
+From: Felix Singer <felixsinger@posteo.net>
+Date: Wed, 26 Jun 2024 00:59:03 +0200
+Subject: [PATCH 2/8] mb/lenovo: Add initial code for Lenovo ThinkPad E460
+
+Change-Id: Ia02f81750105c95c867d961dbdadcd5991ad371f
+Signed-off-by: Felix Singer <felixsinger@posteo.net>
+---
+ src/mainboard/lenovo/sklkbl_thinkpad/Kconfig | 47 +++++++++++++++++++
+ .../lenovo/sklkbl_thinkpad/Kconfig.name | 4 ++
+ .../lenovo/sklkbl_thinkpad/Makefile.mk | 7 +++
+ .../lenovo/sklkbl_thinkpad/acpi/ec.asl | 3 ++
+ .../lenovo/sklkbl_thinkpad/acpi/superio.asl | 3 ++
+ .../lenovo/sklkbl_thinkpad/bootblock.c | 7 +++
+ .../lenovo/sklkbl_thinkpad/devicetree.cb | 17 +++++++
+ src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl | 23 +++++++++
+ .../lenovo/sklkbl_thinkpad/ramstage.c | 11 +++++
+ .../lenovo/sklkbl_thinkpad/romstage.c | 7 +++
+ .../variants/e460/gma-mainboard.ads | 15 ++++++
+ .../sklkbl_thinkpad/variants/e460/hda_verb.c | 10 ++++
+ .../variants/e460/overridetree.cb | 37 +++++++++++++++
+ 13 files changed, 191 insertions(+)
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/romstage.c
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/gma-mainboard.ads
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/hda_verb.c
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/overridetree.cb
+
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
+new file mode 100644
+index 0000000000..fcc80dffe3
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
+@@ -0,0 +1,47 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++config BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
++ bool
++ select BOARD_ROMSIZE_KB_12288
++ select HAVE_ACPI_RESUME
++ select HAVE_ACPI_TABLES
++# select HAVE_CMOS_DEFAULT
++# select INTEL_GMA_HAVE_VBT
++ select INTEL_LPSS_UART_FOR_CONSOLE
++ select MAINBOARD_HAS_LIBGFXINIT
++ select MEMORY_MAPPED_TPM
++ select MAINBOARD_HAS_TPM2
++ select NO_UART_ON_SUPERIO
++ select SOC_INTEL_COMMON_BLOCK_HDA_VERB
++ select SPD_READ_BY_WORD
++ select SYSTEM_TYPE_LAPTOP
++
++config BOARD_LENOVO_E460
++ bool
++ select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
++ select SOC_INTEL_SKYLAKE
++
++if BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
++
++config MAINBOARD_DIR
++ default "lenovo/sklkbl_thinkpad"
++
++config VARIANT_DIR
++ default "e460" if BOARD_LENOVO_E460
++
++config MAINBOARD_PART_NUMBER
++ default "E460" if BOARD_LENOVO_E460
++
++config CBFS_SIZE
++ default 0x600000 if BOARD_LENOVO_E460
++
++config DIMM_MAX
++ default 4
++
++config DIMM_SPD_SIZE
++ default 256
++
++config UART_FOR_CONSOLE
++ default 2
++
++endif
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name
+new file mode 100644
+index 0000000000..61d971fe8d
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++config BOARD_LENOVO_E460
++ bool "ThinkPad E460"
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk
+new file mode 100644
+index 0000000000..6e544fd6b9
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk
+@@ -0,0 +1,7 @@
++## SPDX-License-Identifier: GPL-2.0-only
++
++bootblock-y += bootblock.c
++
++ramstage-y += ramstage.c
++ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c
++ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += variants/$(VARIANT_DIR)/gma-mainboard.ads
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl
+new file mode 100644
+index 0000000000..16990d45f4
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl
+@@ -0,0 +1,3 @@
++/* SPDX-License-Identifier: CC-PDDC */
++
++/* Please update the license if adding licensable material. */
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl
+new file mode 100644
+index 0000000000..55b1db5b11
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl
+@@ -0,0 +1,3 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <drivers/pc80/pc/ps2_controller.asl>
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c
+new file mode 100644
+index 0000000000..ccd8ec1b40
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c
+@@ -0,0 +1,7 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <bootblock_common.h>
++
++void bootblock_mainboard_early_init(void)
++{
++}
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb
+new file mode 100644
+index 0000000000..ddb6e8aaa5
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb
+@@ -0,0 +1,17 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++chip soc/intel/skylake
++ device domain 0 on
++ device ref igpu on end
++ device ref sa_thermal on end
++ device ref thermal on end
++ device ref south_xhci on end
++ device ref lpc_espi on
++ register "serirq_mode" = "SERIRQ_CONTINUOUS"
++ chip drivers/pc80/tpm
++ device pnp 0c31.0 on end
++ end
++ end
++ device ref hda on end
++ end
++end
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl
+new file mode 100644
+index 0000000000..967b652853
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl
+@@ -0,0 +1,23 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <acpi/acpi.h>
++DefinitionBlock(
++ "dsdt.aml",
++ "DSDT",
++ ACPI_DSDT_REV_2,
++ OEM_ID,
++ ACPI_TABLE_CREATOR,
++ 0x20110725
++)
++{
++ #include <acpi/dsdt_top.asl>
++ #include <soc/intel/common/block/acpi/acpi/globalnvs.asl>
++ #include <cpu/intel/common/acpi/cpu.asl>
++
++ Device (\_SB.PCI0) {
++ #include <soc/intel/skylake/acpi/systemagent.asl>
++ #include <soc/intel/skylake/acpi/pch.asl>
++ }
++
++ #include <southbridge/intel/common/acpi/sleepstates.asl>
++}
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
+new file mode 100644
+index 0000000000..6c3b077cc4
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
+@@ -0,0 +1,11 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <device/device.h>
++
++static void init_mainboard(void *chip_info)
++{
++}
++
++struct chip_operations mainboard_ops = {
++ .init = init_mainboard,
++};
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/romstage.c b/src/mainboard/lenovo/sklkbl_thinkpad/romstage.c
+new file mode 100644
+index 0000000000..59a62f484e
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/romstage.c
+@@ -0,0 +1,7 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <soc/romstage.h>
++
++void mainboard_memory_init_params(FSPM_UPD *mupd)
++{
++}
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/gma-mainboard.ads b/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/gma-mainboard.ads
+new file mode 100644
+index 0000000000..e0a166fe55
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/gma-mainboard.ads
+@@ -0,0 +1,15 @@
++-- SPDX-License-Identifier: GPL-2.0-or-later
++
++with HW.GFX.GMA;
++with HW.GFX.GMA.Display_Probing;
++
++use HW.GFX.GMA;
++use HW.GFX.GMA.Display_Probing;
++
++private package GMA.Mainboard is
++
++ ports : constant Port_List :=
++ (eDP,
++ others => Disabled);
++
++end GMA.Mainboard;
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/hda_verb.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/hda_verb.c
+new file mode 100644
+index 0000000000..d9d103f862
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/hda_verb.c
+@@ -0,0 +1,10 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <device/azalia_device.h>
++
++const u32 cim_verb_data[] = {
++};
++
++const u32 pc_beep_verbs[] = {};
++
++AZALIA_ARRAY_SIZES;
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/overridetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/overridetree.cb
+new file mode 100644
+index 0000000000..a7384848a6
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/e460/overridetree.cb
+@@ -0,0 +1,37 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++chip soc/intel/skylake
++ device domain 0 on
++ device ref south_xhci on
++ register "usb2_ports" = "{
++ [0] = USB2_PORT_MID(OC_SKIP), // On board, right front
++ [1] = USB2_PORT_MID(OC_SKIP), // On board, right back
++ [2] = USB2_PORT_MID(OC_SKIP), // Charger port
++ [3] = USB2_PORT_MID(OC_SKIP), // Docking
++ [4] = USB2_PORT_MID(OC_SKIP), // Touch panel
++ [5] = USB2_PORT_MID(OC_SKIP), // Bluetooth
++ [6] = USB2_PORT_MID(OC_SKIP), // Camera
++ [7] = USB2_PORT_MID(OC_SKIP), // Fingerprint
++ }"
++ register "usb3_ports" = "{
++ [0] = USB3_PORT_DEFAULT(OC_SKIP), // On board, right front
++ [1] = USB3_PORT_DEFAULT(OC_SKIP), // On board, right back
++ [2] = USB3_PORT_DEFAULT(OC_SKIP), // Charger port
++ [3] = USB3_PORT_DEFAULT(OC_SKIP), // Docking
++ }"
++ end
++ device ref sata on
++ register "SataPortsEnable[0]" = "1"
++ register "SataPortsDevSlp[0]" = "1"
++ end
++ device ref pcie_rp3 on
++ # WLAN
++ end
++ device ref pcie_rp4 on
++ # LAN
++ end
++ device ref pcie_rp6 on
++ # Card reader
++ end
++ end
++end
+--
+2.39.5
+
diff --git a/config/coreboot/next/patches/0003-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch b/config/coreboot/next/patches/0003-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch
new file mode 100644
index 00000000..6e7d4b7c
--- /dev/null
+++ b/config/coreboot/next/patches/0003-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch
@@ -0,0 +1,30 @@
+From b3049cfd11aa0f3c124ed8f87e98a200201ecbdc Mon Sep 17 00:00:00 2001
+From: Mate Kukri <km@mkukri.xyz>
+Date: Fri, 22 Nov 2024 21:26:48 +0000
+Subject: [PATCH 3/8] soc/intel/skylake: Enable 4E/4F PNP I/O ports in
+ bootblock
+
+Change-Id: I57c9d8a9513a268e2ca6a0abd1306cd038598173
+Signed-off-by: Mate Kukri <km@mkukri.xyz>
+---
+ src/soc/intel/skylake/bootblock/pch.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c
+index df00bb85a9..beaece960b 100644
+--- a/src/soc/intel/skylake/bootblock/pch.c
++++ b/src/soc/intel/skylake/bootblock/pch.c
+@@ -100,8 +100,8 @@ static void soc_config_pwrmbase(void)
+
+ void pch_early_iorange_init(void)
+ {
+- uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_KBC_60_64 |
+- LPC_IOE_EC_62_66;
++ uint16_t io_enables = LPC_IOE_EC_4E_4F | LPC_IOE_SUPERIO_2E_2F |
++ LPC_IOE_KBC_60_64 | LPC_IOE_EC_62_66;
+
+ const config_t *config = config_of_soc();
+
+--
+2.39.5
+
diff --git a/config/coreboot/next/patches/0004-mb-lenovo-Add-ThinkPad-T480.patch b/config/coreboot/next/patches/0004-mb-lenovo-Add-ThinkPad-T480.patch
new file mode 100644
index 00000000..115635f1
--- /dev/null
+++ b/config/coreboot/next/patches/0004-mb-lenovo-Add-ThinkPad-T480.patch
@@ -0,0 +1,1175 @@
+From c4efef17d76623916f69de0bdaf24565e02f8e3e Mon Sep 17 00:00:00 2001
+From: Mate Kukri <kukri.mate@gmail.com>
+Date: Sat, 30 Nov 2024 19:44:36 +0000
+Subject: [PATCH 4/8] mb/lenovo: Add ThinkPad T480
+
+This machine has BootGuard fused and requires deguard to boot coreboot.
+
+Works:
+- Internal screen with VGA ROM executed by SeaBIOS
+- Intel iGPU
+- Nvidia dGPU (on some models)
+- Ethernet
+- USB
+- EC
+ + Fan control
+ + Keyboard
+ + Both batteries
+ + Charging via both Type-C ports
+ + Debug UART
+- WLAN card:
+ + WiFi works
+ + Bluetooth works
+- M.2 main SSD
+- Speakers, headphone jack
+- S3 sleep
+
+Known issues:
+- libgfxinit does not work
+- VGA ROM executed by coreboot does not work
+- Alpine Ridge Thunderbolt 3 controller does not work
+- Missing HDA verbs, audio still works
+- Missing VBT
+- Function keys are handled differently from stock firmware
+ + These should inject XF86 keycodes instead of directly
+ controlling, volume, brightness, etc in hardware.
+
+Untested (should work):
+- SATA main SSD
+- WWAN slot
+ + PCIe x2 NVME drive
+ + WWAN card (bus)
+- SD reader (USB)
+- Webcam (USB)
+- External video outputs
+
+Signed-off-by: Mate Kukri <kukri.mate@gmail.com>
+Change-Id: I19d421412c771c1f242f6ff39453f824fa866163
+---
+ src/ec/lenovo/h8/bluetooth.c | 12 +-
+ src/ec/lenovo/h8/wwan.c | 12 +-
+ src/mainboard/lenovo/sklkbl_thinkpad/Kconfig | 29 ++-
+ .../lenovo/sklkbl_thinkpad/Kconfig.name | 3 +
+ .../lenovo/sklkbl_thinkpad/Makefile.mk | 8 +-
+ .../lenovo/sklkbl_thinkpad/acpi/ec.asl | 13 +-
+ .../lenovo/sklkbl_thinkpad/bootblock.c | 50 +++++
+ .../lenovo/sklkbl_thinkpad/devicetree.cb | 36 ++++
+ src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl | 5 +
+ src/mainboard/lenovo/sklkbl_thinkpad/ec.c | 151 +++++++++++++
+ src/mainboard/lenovo/sklkbl_thinkpad/ec.h | 94 ++++++++
+ src/mainboard/lenovo/sklkbl_thinkpad/gpio.h | 8 +
+ .../lenovo/sklkbl_thinkpad/ramstage.c | 96 ++++++++-
+ .../lenovo/sklkbl_thinkpad/romstage.c | 24 +++
+ .../variants/t480/gma-mainboard.ads | 15 ++
+ .../sklkbl_thinkpad/variants/t480/gpio.c | 203 ++++++++++++++++++
+ .../sklkbl_thinkpad/variants/t480/hda_verb.c | 10 +
+ .../variants/t480/overridetree.cb | 114 ++++++++++
+ 18 files changed, 860 insertions(+), 23 deletions(-)
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ec.c
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ec.h
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/gpio.h
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c
+ create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb
+
+diff --git a/src/ec/lenovo/h8/bluetooth.c b/src/ec/lenovo/h8/bluetooth.c
+index 16fc8dce39..ef4f6ad1f5 100644
+--- a/src/ec/lenovo/h8/bluetooth.c
++++ b/src/ec/lenovo/h8/bluetooth.c
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+
+-#include <southbridge/intel/common/gpio.h>
++// #include <southbridge/intel/common/gpio.h>
+ #include <console/console.h>
+ #include <device/device.h>
+ #include <ec/acpi/ec.h>
+@@ -28,16 +28,16 @@ bool h8_has_bdc(const struct device *dev)
+ {
+ struct ec_lenovo_h8_config *conf = dev->chip_info;
+
+- if (!conf->has_bdc_detection) {
++ if (1 || !conf->has_bdc_detection) {
+ printk(BIOS_INFO, "H8: BDC detection not implemented. "
+ "Assuming BDC installed\n");
+ return true;
+ }
+
+- if (get_gpio(conf->bdc_gpio_num) == conf->bdc_gpio_lvl) {
+- printk(BIOS_INFO, "H8: BDC installed\n");
+- return true;
+- }
++ // if (get_gpio(conf->bdc_gpio_num) == conf->bdc_gpio_lvl) {
++ // printk(BIOS_INFO, "H8: BDC installed\n");
++ // return true;
++ // }
+
+ printk(BIOS_INFO, "H8: BDC not installed\n");
+ return false;
+diff --git a/src/ec/lenovo/h8/wwan.c b/src/ec/lenovo/h8/wwan.c
+index 685886fcce..5e0ae030e2 100644
+--- a/src/ec/lenovo/h8/wwan.c
++++ b/src/ec/lenovo/h8/wwan.c
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+
+-#include <southbridge/intel/common/gpio.h>
++// #include <southbridge/intel/common/gpio.h>
+ #include <console/console.h>
+ #include <device/device.h>
+ #include <ec/acpi/ec.h>
+@@ -26,16 +26,16 @@ bool h8_has_wwan(const struct device *dev)
+ {
+ struct ec_lenovo_h8_config *conf = dev->chip_info;
+
+- if (!conf->has_wwan_detection) {
++ if (1 || !conf->has_wwan_detection) {
+ printk(BIOS_INFO, "H8: WWAN detection not implemented. "
+ "Assuming WWAN installed\n");
+ return true;
+ }
+
+- if (get_gpio(conf->wwan_gpio_num) == conf->wwan_gpio_lvl) {
+- printk(BIOS_INFO, "H8: WWAN installed\n");
+- return true;
+- }
++ // if (get_gpio(conf->wwan_gpio_num) == conf->wwan_gpio_lvl) {
++ // printk(BIOS_INFO, "H8: WWAN installed\n");
++ // return true;
++ // }
+
+ printk(BIOS_INFO, "H8: WWAN not installed\n");
+ return false;
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
+index fcc80dffe3..08273c5d27 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
+@@ -2,16 +2,19 @@
+
+ config BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
+ bool
+- select BOARD_ROMSIZE_KB_12288
++ select EC_LENOVO_H8
++ select EC_LENOVO_PMH7
++ select H8_HAS_BAT_THRESHOLDS_IMPL
++ select H8_HAS_LEDLOGO
++ select H8_HAS_PRIMARY_FN_KEYS
+ select HAVE_ACPI_RESUME
+ select HAVE_ACPI_TABLES
+ # select HAVE_CMOS_DEFAULT
+ # select INTEL_GMA_HAVE_VBT
+- select INTEL_LPSS_UART_FOR_CONSOLE
++ select INTEL_INT15
+ select MAINBOARD_HAS_LIBGFXINIT
+ select MEMORY_MAPPED_TPM
+ select MAINBOARD_HAS_TPM2
+- select NO_UART_ON_SUPERIO
+ select SOC_INTEL_COMMON_BLOCK_HDA_VERB
+ select SPD_READ_BY_WORD
+ select SYSTEM_TYPE_LAPTOP
+@@ -19,8 +22,16 @@ config BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
+ config BOARD_LENOVO_E460
+ bool
+ select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
++ select BOARD_ROMSIZE_KB_12288
++ select INTEL_LPSS_UART_FOR_CONSOLE
+ select SOC_INTEL_SKYLAKE
+
++config BOARD_LENOVO_T480
++ bool
++ select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
++ select BOARD_ROMSIZE_KB_16384
++ select SOC_INTEL_KABYLAKE
++
+ if BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
+
+ config MAINBOARD_DIR
+@@ -28,19 +39,29 @@ config MAINBOARD_DIR
+
+ config VARIANT_DIR
+ default "e460" if BOARD_LENOVO_E460
++ default "t480" if BOARD_LENOVO_T480
++
++config OVERRIDE_DEVICETREE
++ default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb"
+
+ config MAINBOARD_PART_NUMBER
+ default "E460" if BOARD_LENOVO_E460
++ default "T480" if BOARD_LENOVO_T480
+
+ config CBFS_SIZE
+ default 0x600000 if BOARD_LENOVO_E460
++ default 0x900000 if BOARD_LENOVO_T480
+
+ config DIMM_MAX
+- default 4
++ default 2
+
+ config DIMM_SPD_SIZE
+ default 256
+
++endif
++
++if BOARD_LENOVO_E460
++
+ config UART_FOR_CONSOLE
+ default 2
+
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name
+index 61d971fe8d..7b813be284 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name
+@@ -2,3 +2,6 @@
+
+ config BOARD_LENOVO_E460
+ bool "ThinkPad E460"
++
++config BOARD_LENOVO_T480
++ bool "ThinkPad T480"
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk
+index 6e544fd6b9..348e3d4582 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk
+@@ -1,7 +1,9 @@
+ ## SPDX-License-Identifier: GPL-2.0-only
+
+-bootblock-y += bootblock.c
++bootblock-y += bootblock.c ec.c
+
+-ramstage-y += ramstage.c
+-ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c
++romstage-y += romstage.c
++
++ramstage-y += ramstage.c ec.c
++ramstage-y += variants/$(VARIANT_DIR)/gpio.c variants/$(VARIANT_DIR)/hda_verb.c
+ ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += variants/$(VARIANT_DIR)/gma-mainboard.ads
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl
+index 16990d45f4..514b95a60f 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl
+@@ -1,3 +1,12 @@
+-/* SPDX-License-Identifier: CC-PDDC */
++/* SPDX-License-Identifier: GPL-2.0-only */
+
+-/* Please update the license if adding licensable material. */
++#define BRIGHTNESS_UP()
++#define BRIGHTNESS_DOWN()
++#define THINKPAD_EC_GPE 22
++
++Name(\TCRT, 100)
++Name(\TPSV, 90)
++Name(\FLVL, 0)
++
++#include <ec/lenovo/h8/acpi/ec.asl>
++#include <ec/lenovo/h8/acpi/thinkpad_bat_thresholds_b0.asl>
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c
+index ccd8ec1b40..55afd3d048 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c
+@@ -1,7 +1,57 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+
++#include <arch/io.h>
+ #include <bootblock_common.h>
++#include <device/pci.h>
++#include <soc/pci_devs.h>
++#include "ec.h"
++
++static void configure_uart(uint16_t port, uint16_t iobase, uint8_t irqno)
++{
++ microchip_pnp_enter_conf_state(port);
++
++ // Select LPC I/F LDN
++ pnp_write(port, PNP_LDN_SELECT, LDN_LPCIF);
++ // Write UART BAR
++ pnp_write_le32(port, LPCIF_BAR_UART, (uint32_t) iobase << 16 | 0x8707);
++ // Set SIRQ4 to UART
++ pnp_write(port, LPCIF_SIRQ(irqno), LDN_UART);
++
++ // Configure UART LDN
++ pnp_write(port, PNP_LDN_SELECT, LDN_UART);
++ pnp_write(port, UART_ACTIVATE, 0x01);
++ pnp_write(port, UART_CONFIG_SELECT, 0x00);
++
++ microchip_pnp_exit_conf_state(port);
++
++ // NOTE: this is incredibly hacky and uses a debug backdoor in the EC
++ // firmware to control the UART GPIOs.
++ // Unfortunately production EC firmware has no way to do this via regular EC
++ // commands.
++
++ // Supply debug unlock key
++ debug_write_key(DEBUG_RW_KEY_IDX, debug_rw_key);
++
++ // Use debug writes to set UART_TX and UART_RX GPIOs
++ debug_write_dword(0xf0c400 + 0x110, 0x00001000);
++ debug_write_dword(0xf0c400 + 0x114, 0x00001000);
++}
++
++
++#define UART_PORT 0x3f8
++#define UART_IRQ 4
+
+ void bootblock_mainboard_early_init(void)
+ {
++ // Tell EC via BIOS Debug Port 1 that the world isn't on fire
++
++ // Let the EC know that BIOS code is running
++ outb(0x11, 0x86);
++ outb(0x6e, 0x86);
++
++ // Enable accesses to EC1 interface
++ ec0_write(0, ec0_read(0) | 0x20);
++
++ // Setup debug UART
++ configure_uart(EC_CFG_PORT, UART_PORT, UART_IRQ);
+ }
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb
+index ddb6e8aaa5..745af8c8cd 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb
+@@ -8,6 +8,42 @@ chip soc/intel/skylake
+ device ref south_xhci on end
+ device ref lpc_espi on
+ register "serirq_mode" = "SERIRQ_CONTINUOUS"
++
++ register "gen1_dec" = "0x007c1601"
++ register "gen2_dec" = "0x000c15e1"
++
++ chip ec/lenovo/pmh7
++ register "backlight_enable" = "true"
++ register "dock_event_enable" = "true"
++ device pnp ff.1 on end # dummy
++ end
++
++ chip ec/lenovo/h8
++ register "beepmask0" = "0x00"
++ register "beepmask1" = "0x86"
++ register "config0" = "0xa6"
++ register "config1" = "0x0d"
++ register "config2" = "0xa8"
++ register "config3" = "0xc4"
++ register "has_keyboard_backlight" = "1"
++ register "event2_enable" = "0xff"
++ register "event3_enable" = "0xff"
++ register "event4_enable" = "0xd0"
++ register "event5_enable" = "0x3c"
++ register "event7_enable" = "0x01"
++ register "event8_enable" = "0x7b"
++ register "event9_enable" = "0xff"
++ register "eventc_enable" = "0xff"
++ register "eventd_enable" = "0xff"
++ register "evente_enable" = "0x9d"
++ device pnp ff.2 on # dummy
++ io 0x60 = 0x62
++ io 0x62 = 0x66
++ io 0x64 = 0x1600
++ io 0x66 = 0x1604
++ end
++ end
++
+ chip drivers/pc80/tpm
+ device pnp 0c31.0 on end
+ end
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl
+index 967b652853..e8dc4cbae2 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl
+@@ -1,5 +1,10 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+
++#define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB
++#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB
++#define EC_LENOVO_H8_ME_WORKAROUND 1
++#define THINKPAD_EC_GPE 17
++
+ #include <acpi/acpi.h>
+ DefinitionBlock(
+ "dsdt.aml",
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ec.c b/src/mainboard/lenovo/sklkbl_thinkpad/ec.c
+new file mode 100644
+index 0000000000..47449eabd6
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ec.c
+@@ -0,0 +1,151 @@
++#include <arch/io.h>
++#include "ec.h"
++
++#define MICROCHIP_CONFIGURATION_ENTRY_KEY 0x55
++#define MICROCHIP_CONFIGURATION_EXIT_KEY 0xaa
++
++void microchip_pnp_enter_conf_state(uint16_t port)
++{
++ outb(MICROCHIP_CONFIGURATION_ENTRY_KEY, port);
++}
++
++void microchip_pnp_exit_conf_state(uint16_t port)
++{
++ outb(MICROCHIP_CONFIGURATION_EXIT_KEY, port);
++}
++
++uint8_t pnp_read(uint16_t port, uint8_t index)
++{
++ outb(index, port);
++ return inb(port + 1);
++}
++
++uint32_t pnp_read_le32(uint16_t port, uint8_t index)
++{
++ return (uint32_t) pnp_read(port, index) |
++ (uint32_t) pnp_read(port, index + 1) << 8 |
++ (uint32_t) pnp_read(port, index + 2) << 16 |
++ (uint32_t) pnp_read(port, index + 3) << 24;
++}
++
++void pnp_write(uint16_t port, uint8_t index, uint8_t value)
++{
++ outb(index, port);
++ outb(value, port + 1);
++}
++
++void pnp_write_le32(uint16_t port, uint8_t index, uint32_t value)
++{
++ pnp_write(port, index, value & 0xff);
++ pnp_write(port, index + 1, value >> 8 & 0xff);
++ pnp_write(port, index + 2, value >> 16 & 0xff);
++ pnp_write(port, index + 3, value >> 24 & 0xff);
++}
++
++static void ecN_clear_out_queue(uint16_t cmd_port, uint16_t data_port)
++{
++ while (inb(cmd_port) & EC_OBF)
++ inb(data_port);
++}
++
++static void ecN_wait_to_send(uint16_t cmd_port, uint16_t data_port)
++{
++ while (inb(cmd_port) & EC_IBF)
++ ;
++}
++
++static void ecN_wait_to_recv(uint16_t cmd_port, uint16_t data_port)
++{
++ while (!(inb(cmd_port) & EC_OBF))
++ ;
++}
++
++uint8_t ecN_read(uint16_t cmd_port, uint16_t data_port, uint8_t addr)
++{
++ ecN_clear_out_queue(cmd_port, data_port);
++ ecN_wait_to_send(cmd_port, data_port);
++ outb(EC_READ, cmd_port);
++ ecN_wait_to_send(cmd_port, data_port);
++ outb(addr, data_port);
++ ecN_wait_to_recv(cmd_port, data_port);
++ return inb(data_port);
++}
++
++void ecN_write(uint16_t cmd_port, uint16_t data_port, uint8_t addr, uint8_t val)
++{
++ ecN_clear_out_queue(cmd_port, data_port);
++ ecN_wait_to_send(cmd_port, data_port);
++ outb(EC_WRITE, cmd_port);
++ ecN_wait_to_send(cmd_port, data_port);
++ outb(addr, data_port);
++ ecN_wait_to_send(cmd_port, data_port);
++ outb(val, data_port);
++}
++
++uint8_t eeprom_read(uint16_t addr)
++{
++ ecN_clear_out_queue(EC2_CMD, EC2_DATA);
++ ecN_wait_to_send(EC2_CMD, EC2_DATA);
++ outl(1, EC2_CMD);
++ ecN_wait_to_send(EC2_CMD, EC2_DATA);
++ outl(addr, EC2_DATA);
++ ecN_wait_to_recv(EC2_CMD, EC2_DATA);
++ return inl(EC2_DATA);
++}
++
++void eeprom_write(uint16_t addr, uint8_t val)
++{
++ ecN_clear_out_queue(EC2_CMD, EC2_DATA);
++ ecN_wait_to_send(EC2_CMD, EC2_DATA);
++ outl(2, EC2_CMD);
++ ecN_wait_to_send(EC2_CMD, EC2_DATA);
++ outl((uint32_t) addr | (uint32_t) val << 16, EC2_DATA);
++ ecN_wait_to_recv(EC2_CMD, EC2_DATA);
++ inl(EC2_DATA);
++}
++
++uint16_t debug_loaded_keys(void)
++{
++ return (uint16_t) ec0_read(0x87) << 8 | (uint16_t) ec0_read(0x86);
++}
++
++static void debug_cmd(uint8_t cmd)
++{
++ ec0_write(EC_DEBUG_CMD, cmd);
++ while (ec0_read(EC_DEBUG_CMD) & 0x80)
++ ;
++}
++
++void debug_read_key(uint8_t i, uint8_t *key)
++{
++ debug_cmd(0x80 | (i & 0xf));
++ for (int j = 0; j < 8; ++j)
++ key[j] = ec0_read(0x3e + j);
++}
++
++void debug_write_key(uint8_t i, const uint8_t *key)
++{
++ for (int j = 0; j < 8; ++j)
++ ec0_write(0x3e + j, key[j]);
++ debug_cmd(0xc0 | (i & 0xf));
++}
++
++uint32_t debug_read_dword(uint32_t addr)
++{
++ ecN_clear_out_queue(EC3_CMD, EC3_DATA);
++ ecN_wait_to_send(EC3_CMD, EC3_DATA);
++ outl(addr << 8 | 0xE2, EC3_DATA);
++ ecN_wait_to_recv(EC3_CMD, EC3_DATA);
++ return inl(EC3_DATA);
++}
++
++void debug_write_dword(uint32_t addr, uint32_t val)
++{
++ ecN_clear_out_queue(EC3_CMD, EC3_DATA);
++ ecN_wait_to_send(EC3_CMD, EC3_DATA);
++ outl(addr << 8 | 0xEA, EC3_DATA);
++ ecN_wait_to_send(EC3_CMD, EC3_DATA);
++ outl(val, EC3_DATA);
++}
++
++const uint8_t debug_rw_key[8] = { 0x7a, 0x41, 0xb1, 0x49, 0xfe, 0x21, 0x01, 0xcf };
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ec.h b/src/mainboard/lenovo/sklkbl_thinkpad/ec.h
+new file mode 100644
+index 0000000000..aa5582f30b
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ec.h
+@@ -0,0 +1,94 @@
++#pragma once
++
++// EC configuration base address
++#define EC_CFG_PORT 0x4e
++
++// Chip global registers
++#define PNP_LDN_SELECT 0x07
++# define LDN_UART 0x07
++# define LDN_LPCIF 0x0c
++#define EC_DEVICE_ID 0x20
++#define EC_DEVICE_REV 0x21
++
++// LPC I/F registers
++#define LPCIF_SIRQ(i) (0x40 + (i))
++
++#define LPCIF_BAR_CFG 0x60
++#define LPCIF_BAR_MAILBOX 0x64
++#define LPCIF_BAR_8042 0x68
++#define LPCIF_BAR_ACPI_EC0 0x6c
++#define LPCIF_BAR_ACPI_EC1 0x70
++#define LPCIF_BAR_ACPI_EC2 0x74
++#define LPCIF_BAR_ACPI_EC3 0x78
++#define LPCIF_BAR_ACPI_PM0 0x7c
++#define LPCIF_BAR_UART 0x80
++#define LPCIF_BAR_FAST_KYBD 0x84
++#define LPCIF_BAR_EMBED_FLASH 0x88
++#define LPCIF_BAR_GP_SPI 0x8c
++#define LPCIF_BAR_EMI 0x90
++#define LPCIF_BAR_PMH7 0x94
++#define LPCIF_BAR_PORT80_DBG0 0x98
++#define LPCIF_BAR_PORT80_DBG1 0x9c
++#define LPCIF_BAR_RTC 0xa0
++
++// UART registers
++#define UART_ACTIVATE 0x30
++#define UART_CONFIG_SELECT 0xf0
++
++void microchip_pnp_enter_conf_state(uint16_t port);
++void microchip_pnp_exit_conf_state(uint16_t port);
++uint8_t pnp_read(uint16_t port, uint8_t index);
++uint32_t pnp_read_le32(uint16_t port, uint8_t index);
++void pnp_write(uint16_t port, uint8_t index, uint8_t value);
++void pnp_write_le32(uint16_t port, uint8_t index, uint32_t value);
++
++#define EC0_CMD 0x0066
++#define EC0_DATA 0x0062
++#define EC1_CMD 0x1604
++#define EC1_DATA 0x1600
++#define EC2_CMD 0x1634
++#define EC2_DATA 0x1630
++#define EC3_CMD 0x161c
++#define EC3_DATA 0x1618
++
++#define EC_OBF (1 << 0)
++#define EC_IBF (1 << 1)
++
++#define EC_READ 0x80
++#define EC_WRITE 0x81
++
++uint8_t ecN_read(uint16_t cmd_port, uint16_t data_port, uint8_t addr);
++
++void ecN_write(uint16_t cmd_port, uint16_t data_port, uint8_t addr, uint8_t val);
++
++// EC0 and EC1 mostly are useful with the READ/WRITE commands
++#define ec0_read(addr) ecN_read(EC0_CMD, EC0_DATA, addr)
++#define ec0_write(addr, val) ecN_write(EC0_CMD, EC0_DATA, addr, val)
++#define ec1_read(addr) ecN_read(EC1_CMD, EC1_DATA, addr)
++#define ec1_write(addr, val) ecN_write(EC1_CMD, EC1_DATA, addr, val)
++
++// Read from the emulated EEPROM
++uint8_t eeprom_read(uint16_t addr);
++
++// Write to the emulated EEPROM
++void eeprom_write(uint16_t addr, uint8_t val);
++
++// Read loaded debug key mask
++uint16_t debug_loaded_keys(void);
++
++// The following location (via either EC0 or EC1) can be used to interact with the debug interface
++#define EC_DEBUG_CMD 0x3d
++
++void debug_read_key(uint8_t i, uint8_t *key);
++
++void debug_write_key(uint8_t i, const uint8_t *key);
++
++uint32_t debug_read_dword(uint32_t addr);
++
++void debug_write_dword(uint32_t addr, uint32_t val);
++
++// RW unlock key index
++#define DEBUG_RW_KEY_IDX 1
++
++// RW unlock key for EC version N24HT37W
++extern const uint8_t debug_rw_key[8];
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h b/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h
+new file mode 100644
+index 0000000000..d89ed712d4
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h
+@@ -0,0 +1,8 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#ifndef GPIO_H
++#define GPIO_H
++
++void variant_config_gpios(void);
++
++#endif
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
+index 6c3b077cc4..9526642c57 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
+@@ -1,11 +1,103 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+
++#include <arch/io.h>
+ #include <device/device.h>
++#include <drivers/intel/gma/int15.h>
++#include <option.h>
++#include <soc/ramstage.h>
++#include "ec.h"
++#include "gpio.h"
+
+-static void init_mainboard(void *chip_info)
++#define GPIO_GPU_RST GPP_E22 // active low
++#define GPIO_1R8VIDEO_AON_ON GPP_E23
++
++#define GPIO_DGFX_PWRGD GPP_F3
++
++#define GPIO_DISCRETE_PRESENCE GPP_D9 // active low
++#define GPIO_DGFX_VRAM_ID0 GPP_D11
++#define GPIO_DGFX_VRAM_ID1 GPP_D12
++
++void mainboard_silicon_init_params(FSP_SIL_UPD *params)
++{
++ static const char *dgfx_vram_id_str[] = { "1GB", "2GB", "4GB", "N/A" };
++
++ int dgfx_vram_id;
++
++ // Setup GPIOs
++ variant_config_gpios();
++
++ // Detect and enable dGPU
++ if (gpio_get(GPIO_DISCRETE_PRESENCE) == 0) { // active low
++ dgfx_vram_id = gpio_get(GPIO_DGFX_VRAM_ID0) | gpio_get(GPIO_DGFX_VRAM_ID1) << 1;
++ printk(BIOS_DEBUG, "Discrete GPU present with %s VRAM\n", dgfx_vram_id_str[dgfx_vram_id]);
++
++ if (get_uint_option("dgpu_enable", 1)) {
++ printk(BIOS_DEBUG, "Enabling discrete GPU\n");
++ // NOTE: i pulled this GPU enable sequence from thin air but it seems to work
++ gpio_set(GPIO_1R8VIDEO_AON_ON, 1); // Enable GPU power rail
++ while (!gpio_get(GPIO_DGFX_PWRGD)) // Wait for power good signal from GPU
++ ;
++ gpio_set(GPIO_GPU_RST, 1); // Release GPU from reset
++ } else {
++ printk(BIOS_DEBUG, "Discrete GPU will remain disabled\n");
++ }
++
++ } else {
++ printk(BIOS_DEBUG, "Discrete GPU not present\n");
++ }
++}
++
++static void dump_ec_cfg(uint16_t port)
++{
++ microchip_pnp_enter_conf_state(port);
++
++ // Device info
++ printk(BIOS_DEBUG, "Device id %02x\n", pnp_read(port, EC_DEVICE_ID));
++ printk(BIOS_DEBUG, "Device rev %02x\n", pnp_read(port, EC_DEVICE_REV));
++
++ // Switch to LPCIF LDN
++ pnp_write(port, PNP_LDN_SELECT, LDN_LPCIF);
++
++ // Dump SIRQs
++ for (int i = 0; i <= 15; i += 1)
++ printk(BIOS_DEBUG, "SIRQ%d = %02x\n", i, pnp_read(port, LPCIF_SIRQ(i)));
++
++ // Dump BARs
++ printk(BIOS_DEBUG, "BAR CFG = %08x\n", pnp_read_le32(port, LPCIF_BAR_CFG));
++ printk(BIOS_DEBUG, "BAR MAILBOX = %08x\n", pnp_read_le32(port, LPCIF_BAR_MAILBOX));
++ printk(BIOS_DEBUG, "BAR 8042 = %08x\n", pnp_read_le32(port, LPCIF_BAR_8042));
++ printk(BIOS_DEBUG, "BAR ACPI_EC0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC0));
++ printk(BIOS_DEBUG, "BAR ACPI_EC1 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC1));
++ printk(BIOS_DEBUG, "BAR ACPI_EC2 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC2));
++ printk(BIOS_DEBUG, "BAR ACPI_EC3 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC3));
++ printk(BIOS_DEBUG, "BAR ACPI_PM0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_PM0));
++ printk(BIOS_DEBUG, "BAR UART = %08x\n", pnp_read_le32(port, LPCIF_BAR_UART));
++ printk(BIOS_DEBUG, "BAR FAST_KYBD = %08x\n", pnp_read_le32(port, LPCIF_BAR_FAST_KYBD));
++ printk(BIOS_DEBUG, "BAR EMBED_FLASH = %08x\n", pnp_read_le32(port, LPCIF_BAR_EMBED_FLASH));
++ printk(BIOS_DEBUG, "BAR GP_SPI = %08x\n", pnp_read_le32(port, LPCIF_BAR_GP_SPI));
++ printk(BIOS_DEBUG, "BAR EMI = %08x\n", pnp_read_le32(port, LPCIF_BAR_EMI));
++ printk(BIOS_DEBUG, "BAR PMH7 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PMH7));
++ printk(BIOS_DEBUG, "BAR PORT80_DBG0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PORT80_DBG0));
++ printk(BIOS_DEBUG, "BAR PORT80_DBG1 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PORT80_DBG1));
++ printk(BIOS_DEBUG, "BAR RTC = %08x\n", pnp_read_le32(port, LPCIF_BAR_RTC));
++
++ microchip_pnp_exit_conf_state(port);
++}
++
++static void mainboard_enable(struct device *dev)
++{
++ if (CONFIG(VGA_ROM_RUN))
++ install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_EDP,
++ GMA_INT15_PANEL_FIT_DEFAULT,
++ GMA_INT15_BOOT_DISPLAY_DEFAULT, 0);
++}
++
++static void mainboard_init(void *chip_info)
+ {
++ dump_ec_cfg(EC_CFG_PORT);
+ }
+
+ struct chip_operations mainboard_ops = {
+- .init = init_mainboard,
++ .enable_dev = mainboard_enable,
++ .init = mainboard_init,
+ };
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/romstage.c b/src/mainboard/lenovo/sklkbl_thinkpad/romstage.c
+index 59a62f484e..4cc0591b4f 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/romstage.c
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/romstage.c
+@@ -1,7 +1,31 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+
+ #include <soc/romstage.h>
++#include <spd_bin.h>
++
++// FIXME: verify SPD addrs, DQ interleave, and CA vref for other SKL/KBL ThinkPads
+
+ void mainboard_memory_init_params(FSPM_UPD *mupd)
+ {
++ /* T480
++ * JDDR1 - 0x50
++ * JDDR2 - 0x51 */
++ struct spd_block blk = { .addr_map = { 0x50, 0x51, } };
++ get_spd_smbus(&blk);
++ dump_spd_info(&blk);
++
++ FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig;
++
++ /* T480 (DDR_DQ pins wired in interleave mode) */
++ mem_cfg->DqPinsInterleaved = true;
++
++ /* T480 (VREF_CA to CH_A and VREF_DQ_B to CH_B)
++ * DDR_VREF_CA -> M_A_VREF_CA_CPU
++ * DDR0_VREF_DQ -> NC
++ * DDR1_VREF_DQ -> M_B_VREF_CA_CPU */
++ mem_cfg->CaVrefConfig = 2;
++
++ mem_cfg->MemorySpdDataLen = blk.len;
++ mem_cfg->MemorySpdPtr00 = (uintptr_t)blk.spd_array[0];
++ mem_cfg->MemorySpdPtr10 = (uintptr_t)blk.spd_array[1];
+ }
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads
+new file mode 100644
+index 0000000000..e0a166fe55
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads
+@@ -0,0 +1,15 @@
++-- SPDX-License-Identifier: GPL-2.0-or-later
++
++with HW.GFX.GMA;
++with HW.GFX.GMA.Display_Probing;
++
++use HW.GFX.GMA;
++use HW.GFX.GMA.Display_Probing;
++
++private package GMA.Mainboard is
++
++ ports : constant Port_List :=
++ (eDP,
++ others => Disabled);
++
++end GMA.Mainboard;
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c
+new file mode 100644
+index 0000000000..f7c29e1f39
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c
+@@ -0,0 +1,203 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <soc/gpio.h>
++#include "../../gpio.h"
++
++/* FIXME: There are multiple GPIOs here that should be locked to prevent "TPM GPIO fail" style
++ * attacks. Unfortunately SKL/KBL GPIO locking *does not* work currently. */
++
++static const struct pad_config gpio_table[] = {
++
++ /* ------- GPIO Community 0 ------- */
++
++ /* ------- GPIO Group GPP_A ------- */
++ PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* -KBRC */
++ PAD_CFG_NF(GPP_A1, NATIVE, DEEP, NF1), /* LPC_AD0 */
++ PAD_CFG_NF(GPP_A2, NATIVE, DEEP, NF1), /* LPC_AD1 */
++ PAD_CFG_NF(GPP_A3, NATIVE, DEEP, NF1), /* LPC_AD2 */
++ PAD_CFG_NF(GPP_A4, NATIVE, DEEP, NF1), /* LPC_AD3 */
++ PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* -LPC_FRAME */
++ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* IRQSER */
++ PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* -TPM_IRQ */
++ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* -CLKRUN */
++ PAD_CFG_NF(GPP_A9, NATIVE, DEEP, NF1), /* LPCCLK_EC_24M */
++ PAD_CFG_NF(GPP_A10, NATIVE, DEEP, NF1), /* LPCCLK_DEBUG_24M */
++ PAD_NC(GPP_A11, NONE),
++ PAD_NC(GPP_A12, NONE),
++ PAD_CFG_NF(GPP_A13, NATIVE, DEEP, NF1), /* -SUSWARN */
++ PAD_CFG_NF(GPP_A14, NATIVE, DEEP, NF1), /* -SUS_STAT */
++ PAD_CFG_NF(GPP_A15, NATIVE, DEEP, NF1), /* -SUSWARN */
++ PAD_NC(GPP_A16, NONE),
++ PAD_NC(GPP_A17, NONE),
++ PAD_NC(GPP_A18, NONE),
++ PAD_NC(GPP_A19, NONE),
++ PAD_NC(GPP_A20, NONE),
++ PAD_NC(GPP_A21, NONE),
++ PAD_NC(GPP_A22, NONE),
++ PAD_NC(GPP_A23, NONE),
++
++ /* ------- GPIO Group GPP_B ------- */
++ PAD_NC(GPP_B0, NONE),
++ PAD_NC(GPP_B1, NONE),
++ PAD_NC(GPP_B2, NONE),
++ PAD_NC(GPP_B3, NONE),
++ PAD_CFG_GPI_SCI(GPP_B4, NONE, DEEP, EDGE_SINGLE, INVERT), /* -TBT_PLUG_EVENT */
++ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1), /* -CLKREQ_PCIE0 */
++ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1), /* -CLKREQ_PCIE4 */
++ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF1), /* -CLKREQ_PCIE5 */
++ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF1), /* -CLKREQ_PCIE6 */
++ PAD_CFG_NF(GPP_B9, NONE, DEEP, NF1), /* -CLKREQ_PCIE8 */
++ PAD_CFG_NF(GPP_B10, NONE, DEEP, NF1), /* -CLKREQ_PCIE10 */
++ PAD_NC(GPP_B11, NONE),
++ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), /* -PCH_SLP_S0 */
++ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* -PLTRST */
++ PAD_CFG_NF(GPP_B14, NATIVE, DEEP, NF1), /* PCH_SPKR */
++ PAD_CFG_GPO(GPP_B15, 1, DEEP), /* NFC_DLREQ */
++ PAD_NC(GPP_B16, NONE),
++ PAD_NC(GPP_B17, NONE),
++ PAD_NC(GPP_B18, NONE),
++ PAD_NC(GPP_B19, NONE),
++ PAD_NC(GPP_B20, NONE),
++ PAD_NC(GPP_B21, NONE),
++ PAD_NC(GPP_B22, NONE),
++ PAD_NC(GPP_B23, NONE),
++
++ /* ------- GPIO Community 1 ------- */
++
++ /* ------- GPIO Group GPP_C ------- */
++ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */
++ PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */
++ PAD_NC(GPP_C2, NONE),
++ PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* SML0_CLK */
++ PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* SML0_DATA */
++ PAD_NC(GPP_C5, NONE),
++ PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* EC_SCL2 */
++ PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* EC_SDA2 */
++ PAD_NC(GPP_C8, NONE),
++ PAD_NC(GPP_C9, NONE),
++ PAD_NC(GPP_C10, NONE),
++ PAD_NC(GPP_C11, NONE),
++ PAD_NC(GPP_C12, NONE),
++ PAD_NC(GPP_C13, NONE),
++ PAD_NC(GPP_C14, NONE),
++ PAD_NC(GPP_C15, NONE),
++ PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* I2C0_DATA */
++ PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* I2C0_CLK */
++ PAD_NC(GPP_C18, NONE),
++ PAD_NC(GPP_C19, NONE),
++ PAD_CFG_GPO(GPP_C20, 0, DEEP), /* EPRIVACY_ON */
++ PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */
++ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */
++ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */
++
++ /* ------- GPIO Group GPP_D ------- */
++ PAD_NC(GPP_D0, NONE),
++ PAD_NC(GPP_D1, NONE),
++ PAD_NC(GPP_D2, NONE),
++ PAD_NC(GPP_D3, NONE),
++ PAD_NC(GPP_D4, NONE),
++ PAD_NC(GPP_D5, NONE),
++ PAD_NC(GPP_D6, NONE),
++ PAD_NC(GPP_D7, NONE),
++ PAD_NC(GPP_D8, NONE),
++ PAD_CFG_GPI_TRIG_OWN(GPP_D9, UP_20K, DEEP, OFF, ACPI), /* -DISCRETE_PRESENCE */
++ PAD_NC(GPP_D10, NONE),
++ PAD_CFG_GPI_TRIG_OWN(GPP_D11, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID0 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_D12, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID1 */
++ PAD_NC(GPP_D13, NONE),
++ PAD_NC(GPP_D14, NONE),
++ PAD_NC(GPP_D15, NONE),
++ PAD_NC(GPP_D16, NONE),
++ PAD_CFG_GPO(GPP_D17, 0, DEEP), /* DDI_PRIORITY1 */
++ PAD_NC(GPP_D18, NONE),
++ PAD_NC(GPP_D19, NONE),
++ PAD_NC(GPP_D20, NONE),
++ PAD_NC(GPP_D21, NONE),
++ PAD_CFG_GPI_TRIG_OWN(GPP_D22, UP_20K, DEEP, OFF, ACPI), /* -NFC_DTCT */
++ PAD_NC(GPP_D23, NONE),
++
++ /* ------- GPIO Group GPP_E ------- */
++ PAD_NC(GPP_E0, NONE),
++ PAD_CFG_NF(GPP_E1, NONE, DEEP, NF1), /* -WWAN_SATA_DTCT (always HIGH) */
++ PAD_CFG_NF(GPP_E2, NONE, DEEP, NF1), /* -PE_DTCT */
++ PAD_CFG_GPI_TRIG_OWN(GPP_E3, NONE, DEEP, EDGE_SINGLE, ACPI), /* -TBT_PLUG_EVENT */
++ PAD_CFG_GPO(GPP_E4, 1, DEEP), /* NFC_ON */
++ PAD_NC(GPP_E5, NONE),
++ PAD_CFG_NF(GPP_E6, NONE, RSMRST, NF1), /* SATA2_DEVSLP */
++ PAD_NC(GPP_E7, NONE),
++ PAD_NC(GPP_E8, NONE),
++ PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), /* -USB_PORT0_OC0 (AON port) */
++ PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), /* -USB_PORT1_OC1 (regular port) */
++ PAD_NC(GPP_E11, NONE),
++ PAD_CFG_GPI_APIC_HIGH(GPP_E12, NONE, DEEP), /* NFC_INT */
++ PAD_CFG_NF(GPP_E13, NONE, DEEP, NF1), /* DDIP1_HPD */
++ PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDIP2_HPD */
++ PAD_NC(GPP_E15, NONE),
++ PAD_NC(GPP_E16, NONE),
++ PAD_CFG_NF(GPP_E17, NONE, DEEP, NF1), /* EDP_HPD */
++ PAD_NC(GPP_E18, NONE),
++ PAD_NC(GPP_E19, NONE),
++ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), /* DDIP2_CTRLCLK */
++ PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), /* DDIP2_CTRLDATA */
++ PAD_CFG_TERM_GPO(GPP_E22, 0, UP_20K, RSMRST), /* -GPU_RST */
++ PAD_CFG_TERM_GPO(GPP_E23, 0, UP_20K, RSMRST), /* 1R8VIDEO_AON_ON */
++
++ /* ------- GPIO Community 2 ------- */
++
++ /* -------- GPIO Group GPD -------- */
++ PAD_CFG_NF(GPD0, NONE, PWROK, NF1), /* -BATLOW */
++ PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), /* AC_PRESENT */
++ PAD_CFG_NF(GPD2, NATIVE, PWROK, NF1), /* -LANWAKE */
++ PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), /* -PWRSW_EC */
++ PAD_CFG_NF(GPD4, NONE, PWROK, NF1), /* -PCH_SLP_S3 */
++ PAD_CFG_NF(GPD5, NONE, PWROK, NF1), /* -PCH_SLP_S4 */
++ PAD_CFG_NF(GPD6, NONE, PWROK, NF1), /* -PCH_SLP_M */
++ PAD_NC(GPD7, NONE),
++ PAD_CFG_NF(GPD8, NONE, PWROK, NF1), /* SUSCLK_32K */
++ PAD_CFG_NF(GPD9, NONE, PWROK, NF1), /* -PCH_SLP_WLAN */
++ PAD_CFG_NF(GPD10, NONE, PWROK, NF1), /* -PCH_SLP_S5 */
++ PAD_CFG_NF(GPD11, NONE, PWROK, NF1), /* LANPHYPC */
++
++ /* ------- GPIO Community 3 ------- */
++
++ /* ------- GPIO Group GPP_F ------- */
++ PAD_NC(GPP_F0, NONE),
++ PAD_CFG_GPI_TRIG_OWN(GPP_F1, NONE, DEEP, OFF, ACPI), /* GC6_FB_EN */
++ PAD_CFG_GPO(GPP_F2, 1, DEEP), /* -GPU_EVENT */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F3, NONE, DEEP, OFF, ACPI), /* DGFX_PWRGD */
++ PAD_CFG_GPO(GPP_F4, 1, DEEP), /* -WWAN_RESET */
++ PAD_NC(GPP_F5, NONE),
++ PAD_CFG_GPI_TRIG_OWN(GPP_F6, UP_20K, DEEP, OFF, ACPI), /* -MIC_HW_EN (R961 to GND) */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F7, UP_20K, DEEP, OFF, ACPI), /* -INT_MIC_DTCT */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F8, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG0 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F9, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG1 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F10, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG2 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F11, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG3 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F12, UP_20K, DEEP, OFF, ACPI), /* PLANARID0 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F13, UP_20K, DEEP, OFF, ACPI), /* PLANARID1 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F14, UP_20K, DEEP, OFF, ACPI), /* PLANARID2 */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F15, UP_20K, DEEP, OFF, ACPI), /* PLANARID3 */
++ PAD_NC(GPP_F16, NONE),
++ PAD_NC(GPP_F17, NONE),
++ PAD_NC(GPP_F18, NONE),
++ PAD_NC(GPP_F19, NONE),
++ PAD_NC(GPP_F20, NONE),
++ PAD_NC(GPP_F21, NONE),
++ PAD_CFG_GPI_TRIG_OWN(GPP_F22, UP_20K, DEEP, OFF, ACPI), /* -INTRUDER_PCH */
++ PAD_CFG_GPI_TRIG_OWN(GPP_F23, UP_20K, DEEP, OFF, ACPI), /* -SC_DTCT */
++
++ /* ------- GPIO Group GPP_G ------- */
++ PAD_NC(GPP_G0, NONE),
++ PAD_NC(GPP_G1, NONE),
++ PAD_NC(GPP_G2, NONE),
++ PAD_NC(GPP_G3, NONE),
++ PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */
++ PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */
++ PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */
++ PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */
++};
++
++void variant_config_gpios(void)
++{
++ gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table));
++}
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c
+new file mode 100644
+index 0000000000..d9d103f862
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c
+@@ -0,0 +1,10 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#include <device/azalia_device.h>
++
++const u32 cim_verb_data[] = {
++};
++
++const u32 pc_beep_verbs[] = {};
++
++AZALIA_ARRAY_SIZES;
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb
+new file mode 100644
+index 0000000000..f1f19bc3bf
+--- /dev/null
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb
+@@ -0,0 +1,114 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++chip soc/intel/skylake
++ # Power
++ register "PmConfigSlpS3MinAssert" = "2" # 50ms
++ register "PmConfigSlpS4MinAssert" = "1" # 1s
++ register "PmConfigSlpSusMinAssert" = "3" # 500ms
++ register "PmConfigSlpAMinAssert" = "3" # 2s
++
++ device domain 0 on
++ device ref south_xhci on
++ register "usb2_ports" = "{
++ [0] = USB2_PORT_MID(OC1), // USB-A
++ [1] = USB2_PORT_MID(OC0), // USB-A (always on)
++ [2] = USB2_PORT_MID(OC_SKIP), // JSC-1 (smartcard slot)
++ [3] = USB2_PORT_MID(OC_SKIP), // USB-C (charging port)
++ [4] = USB2_PORT_MID(OC_SKIP), // JCAM1 (IR camera)
++ [5] = USB2_PORT_MID(OC_SKIP), // JWWAN1 (M.2 WWAN USB)
++ [6] = USB2_PORT_MID(OC_SKIP), // JWLAN1 (M.2 WLAN USB)
++ [7] = USB2_PORT_MID(OC_SKIP), // JCAM1 (webcam)
++ [8] = USB2_PORT_MID(OC_SKIP), // JFPR1 (fingerprint reader)
++ [9] = USB2_PORT_MID(OC_SKIP), // JLCD1 (touch panel)
++ }"
++ register "usb3_ports" = "{
++ [0] = USB3_PORT_DEFAULT(OC1), // USB-A
++ [1] = USB3_PORT_DEFAULT(OC0), // USB-A (always on)
++ [2] = USB3_PORT_DEFAULT(OC_SKIP), // RTS5344S (SD card reader)
++ [3] = USB3_PORT_DEFAULT(OC_SKIP), // USB-C (charging port)
++ }"
++ end
++
++ device ref sata on
++ # SATA_0 - NC
++ # SATA_1A - NC
++ # SATA_1B - NC
++ # SATA_2 - SATA caddy
++ register "SataPortsEnable[3]" = "1"
++ register "SataPortsDevSlp[3]" = "1"
++ end
++
++ # The PCIe lane routing is a bit convoluted on this board:
++ #
++ # PCIe controller 1 - 1x4
++ # PCIE 1-4 - RP1 - dGPU - CLKOUT0 - CLKREQ0
++ #
++ # PCIe controller 2 - 2x1+1x2 (lane reversal)
++ # PCIE 5 - GBE - GBE - CLKOUT1 - CLKREQ1 (clobbers RP8)
++ # PCIE 6 - RP7 - WLAN - CLKOUT2 - CLKREQ2
++ # PCIE 7-8 - RP5 - WWAN - CLKOUT3 - CLKREQ3
++ #
++ # PCIe controller 3 - 2x2
++ # PCIE 9-10 - RP9 - TB3 - CLKOUT4 - CLKREQ4
++ # PCIE 11-12 - RP11 - SSD - CLKOUT5 - CLKREQ5
++
++ # dGPU - x4
++ device ref pcie_rp1 on
++ register "PcieRpEnable[0]" = "1"
++ register "PcieRpClkReqSupport[0]" = "1"
++ register "PcieRpClkReqNumber[0]" = "0"
++ register "PcieRpClkSrcNumber[0]" = "0"
++ register "PcieRpAdvancedErrorReporting[0]" = "1"
++ register "PcieRpLtrEnable[0]" = "1"
++ end
++
++ # Ethernet (clobbers RP8)
++ device ref gbe on
++ register "LanClkReqSupported" = "1"
++ register "LanClkReqNumber" = "1"
++ register "EnableLanLtr" = "1"
++ register "EnableLanK1Off" = "1"
++ end
++
++ # M.2 WLAN - x1
++ device ref pcie_rp7 on
++ register "PcieRpEnable[6]" = "1"
++ register "PcieRpClkReqSupport[6]" = "1"
++ register "PcieRpClkReqNumber[6]" = "2"
++ register "PcieRpClkSrcNumber[6]" = "2"
++ register "PcieRpAdvancedErrorReporting[6]" = "1"
++ register "PcieRpLtrEnable[6]" = "1"
++ end
++
++ # M.2 WWAN - x2
++ device ref pcie_rp5 on
++ register "PcieRpEnable[4]" = "1"
++ register "PcieRpClkReqSupport[4]" = "1"
++ register "PcieRpClkReqNumber[4]" = "3"
++ register "PcieRpClkSrcNumber[4]" = "3"
++ register "PcieRpAdvancedErrorReporting[4]" = "1"
++ register "PcieRpLtrEnable[4]" = "1"
++ end
++
++ # TB3 (Alpine Ridge LP) - x2
++ device ref pcie_rp9 on
++ register "PcieRpEnable[8]" = "1"
++ register "PcieRpClkReqSupport[8]" = "1"
++ register "PcieRpClkReqNumber[8]" = "4"
++ register "PcieRpClkSrcNumber[8]" = "4"
++ register "PcieRpAdvancedErrorReporting[8]" = "1"
++ register "PcieRpLtrEnable[8]" = "1"
++ register "PcieRpHotPlug[8]" = "1"
++ end
++
++ # M.2 caddy - x2
++ device ref pcie_rp11 on
++ register "PcieRpEnable[10]" = "1"
++ register "PcieRpClkReqSupport[10]" = "1"
++ register "PcieRpClkReqNumber[10]" = "5"
++ register "PcieRpClkSrcNumber[10]" = "5"
++ register "PcieRpAdvancedErrorReporting[10]" = "1"
++ register "PcieRpLtrEnable[10]" = "1"
++ end
++ end
++end
+--
+2.39.5
+
diff --git a/config/coreboot/next/patches/0002-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch b/config/coreboot/next/patches/0005-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch
index 7e2ce1f3..fa5ac312 100644
--- a/config/coreboot/next/patches/0002-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch
+++ b/config/coreboot/next/patches/0005-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch
@@ -1,7 +1,7 @@
-From 53151be243024957386012a099ccf3858f830555 Mon Sep 17 00:00:00 2001
+From 1e10400616ab16e17980af23c91a8efc633529e8 Mon Sep 17 00:00:00 2001
From: Nicholas Chin <nic.c3.14@gmail.com>
Date: Mon, 30 Sep 2024 20:44:38 -0400
-Subject: [PATCH 2/5] mb/dell: Add Optiplex 780 MT (x4x/ICH10)
+Subject: [PATCH 5/8] mb/dell: Add Optiplex 780 MT (x4x/ICH10)
Change-Id: Idb45737ce95bfd26e978323c650de7d308b5079c
Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com>
diff --git a/config/coreboot/next/patches/0003-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch b/config/coreboot/next/patches/0006-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch
index afa778a5..39a8e2be 100644
--- a/config/coreboot/next/patches/0003-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch
+++ b/config/coreboot/next/patches/0006-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch
@@ -1,7 +1,7 @@
-From 50ae904625d6917c68ff8f8f50c280d79842142b Mon Sep 17 00:00:00 2001
+From c900ff6f05ee431c7bf6ab31bc0215faa4ad6971 Mon Sep 17 00:00:00 2001
From: Leah Rowe <info@minifree.org>
Date: Sun, 19 Feb 2023 18:21:43 +0000
-Subject: [PATCH 3/5] util/ifdtool: add --nuke flag (all 0xFF on region)
+Subject: [PATCH 6/8] util/ifdtool: add --nuke flag (all 0xFF on region)
When this option is used, the region's contents are overwritten
with all ones (0xFF).
@@ -20,10 +20,10 @@ Signed-off-by: Leah Rowe <leah@libreboot.org>
1 file changed, 83 insertions(+), 31 deletions(-)
diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c
-index 36477eef66..3ebef74042 100644
+index ace05e2265..ba292fd142 100644
--- a/util/ifdtool/ifdtool.c
+++ b/util/ifdtool/ifdtool.c
-@@ -2217,6 +2217,7 @@ static void print_usage(const char *name)
+@@ -2230,6 +2230,7 @@ static void print_usage(const char *name)
" tgl - Tiger Lake\n"
" wbg - Wellsburg\n"
" -S | --setpchstrap Write a PCH strap\n"
@@ -31,7 +31,7 @@ index 36477eef66..3ebef74042 100644
" -V | --newvalue The new value to write into PCH strap specified by -S\n"
" -v | --version: print the version\n"
" -h | --help: print this help\n\n"
-@@ -2225,6 +2226,60 @@ static void print_usage(const char *name)
+@@ -2238,6 +2239,60 @@ static void print_usage(const char *name)
"\n");
}
@@ -92,7 +92,7 @@ index 36477eef66..3ebef74042 100644
int main(int argc, char *argv[])
{
int opt, option_index = 0;
-@@ -2232,6 +2287,7 @@ int main(int argc, char *argv[])
+@@ -2245,6 +2300,7 @@ int main(int argc, char *argv[])
int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_validate = 0;
int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0;
int mode_read = 0, mode_altmedisable = 0, altmedisable = 0, mode_fmap_template = 0;
@@ -100,7 +100,7 @@ index 36477eef66..3ebef74042 100644
int mode_gpr0_disable = 0, mode_gpr0_enable = 0, mode_gpr0_status = 0;
char *region_type_string = NULL, *region_fname = NULL;
const char *layout_fname = NULL;
-@@ -2267,6 +2323,7 @@ int main(int argc, char *argv[])
+@@ -2280,6 +2336,7 @@ int main(int argc, char *argv[])
{"validate", 0, NULL, 't'},
{"setpchstrap", 1, NULL, 'S'},
{"newvalue", 1, NULL, 'V'},
@@ -108,7 +108,7 @@ index 36477eef66..3ebef74042 100644
{0, 0, 0, 0}
};
-@@ -2316,35 +2373,8 @@ int main(int argc, char *argv[])
+@@ -2329,35 +2386,8 @@ int main(int argc, char *argv[])
region_fname++;
// Descriptor, BIOS, ME, GbE, Platform
// valid type?
@@ -146,7 +146,7 @@ index 36477eef66..3ebef74042 100644
fprintf(stderr, "No such region type: '%s'\n\n",
region_type_string);
fprintf(stderr, "run '%s -h' for usage\n", argv[0]);
-@@ -2521,6 +2551,22 @@ int main(int argc, char *argv[])
+@@ -2534,6 +2564,22 @@ int main(int argc, char *argv[])
case 't':
mode_validate = 1;
break;
@@ -169,7 +169,7 @@ index 36477eef66..3ebef74042 100644
case 'v':
print_version();
exit(EXIT_SUCCESS);
-@@ -2540,7 +2586,8 @@ int main(int argc, char *argv[])
+@@ -2553,7 +2599,8 @@ int main(int argc, char *argv[])
if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject +
mode_setstrap + mode_newlayout + (mode_spifreq | mode_em100 |
mode_unlocked | mode_locked) + mode_altmedisable + mode_validate +
@@ -179,7 +179,7 @@ index 36477eef66..3ebef74042 100644
fprintf(stderr, "You may not specify more than one mode.\n\n");
fprintf(stderr, "run '%s -h' for usage\n", argv[0]);
exit(EXIT_FAILURE);
-@@ -2549,7 +2596,8 @@ int main(int argc, char *argv[])
+@@ -2562,7 +2609,8 @@ int main(int argc, char *argv[])
if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject +
mode_setstrap + mode_newlayout + mode_spifreq + mode_em100 +
mode_locked + mode_unlocked + mode_density + mode_altmedisable +
@@ -189,7 +189,7 @@ index 36477eef66..3ebef74042 100644
fprintf(stderr, "You need to specify a mode.\n\n");
fprintf(stderr, "run '%s -h' for usage\n", argv[0]);
exit(EXIT_FAILURE);
-@@ -2662,6 +2710,10 @@ int main(int argc, char *argv[])
+@@ -2675,6 +2723,10 @@ int main(int argc, char *argv[])
write_image(new_filename, image, size);
}
diff --git a/config/coreboot/next/patches/0004-Remove-warning-for-coreboot-images-built-without-a-p.patch b/config/coreboot/next/patches/0007-Remove-warning-for-coreboot-images-built-without-a-p.patch
index ef561b42..b28a7165 100644
--- a/config/coreboot/next/patches/0004-Remove-warning-for-coreboot-images-built-without-a-p.patch
+++ b/config/coreboot/next/patches/0007-Remove-warning-for-coreboot-images-built-without-a-p.patch
@@ -1,7 +1,7 @@
-From 895f9a49fb73d000178d8422b9d0c7e0ef71ae03 Mon Sep 17 00:00:00 2001
+From 4102bedd708450a83e1cf4c59743bbf65a46413a Mon Sep 17 00:00:00 2001
From: Nicholas Chin <nic.c3.14@gmail.com>
Date: Fri, 12 May 2023 19:55:15 -0600
-Subject: [PATCH 4/5] Remove warning for coreboot images built without a
+Subject: [PATCH 7/8] Remove warning for coreboot images built without a
payload
I added this in upstream to prevent people from accidentally flashing
diff --git a/config/coreboot/next/patches/0005-mb-dell-optiplex_780-Add-USFF-variant.patch b/config/coreboot/next/patches/0008-mb-dell-optiplex_780-Add-USFF-variant.patch
index d63e2061..3d1e1e31 100644
--- a/config/coreboot/next/patches/0005-mb-dell-optiplex_780-Add-USFF-variant.patch
+++ b/config/coreboot/next/patches/0008-mb-dell-optiplex_780-Add-USFF-variant.patch
@@ -1,7 +1,7 @@
-From 0b26b89118b9bde0a722b9743b9871aa68f8ca38 Mon Sep 17 00:00:00 2001
+From 4215d9db7515b1c03646ff0a98a99eb4398c1dee Mon Sep 17 00:00:00 2001
From: Nicholas Chin <nic.c3.14@gmail.com>
Date: Wed, 30 Oct 2024 20:55:25 -0600
-Subject: [PATCH 5/5] mb/dell/optiplex_780: Add USFF variant
+Subject: [PATCH 8/8] mb/dell/optiplex_780: Add USFF variant
Change-Id: I3aa21c743749f4a11a2501f4c121316bd2f1a103
Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com>
diff --git a/config/coreboot/next/patches/0009-lenovo-t480-Add-MAINBOARD_USES_IFD_GBE_REGION.patch b/config/coreboot/next/patches/0009-lenovo-t480-Add-MAINBOARD_USES_IFD_GBE_REGION.patch
new file mode 100644
index 00000000..8ec2cde9
--- /dev/null
+++ b/config/coreboot/next/patches/0009-lenovo-t480-Add-MAINBOARD_USES_IFD_GBE_REGION.patch
@@ -0,0 +1,27 @@
+From 519d79d0d33a63082e474938fa2850044095732e Mon Sep 17 00:00:00 2001
+From: Leah Rowe <info@minifree.org>
+Date: Sun, 1 Dec 2024 07:16:20 +0000
+Subject: [PATCH 1/1] lenovo/t480: Add MAINBOARD_USES_IFD_GBE_REGION
+
+This board does use a GbE region, so support it in menuconfig.
+
+Signed-off-by: Leah Rowe <info@minifree.org>
+---
+ src/mainboard/lenovo/sklkbl_thinkpad/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
+index 08273c5d27..a83e17b71f 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig
+@@ -15,6 +15,7 @@ config BOARD_LENOVO_SKLKBL_THINKPAD_COMMON
+ select MAINBOARD_HAS_LIBGFXINIT
+ select MEMORY_MAPPED_TPM
+ select MAINBOARD_HAS_TPM2
++ select MAINBOARD_USES_IFD_GBE_REGION
+ select SOC_INTEL_COMMON_BLOCK_HDA_VERB
+ select SPD_READ_BY_WORD
+ select SYSTEM_TYPE_LAPTOP
+--
+2.39.5
+
diff --git a/config/coreboot/next/patches/0010-t480-hack-turn-off-the-dgpu.patch b/config/coreboot/next/patches/0010-t480-hack-turn-off-the-dgpu.patch
new file mode 100644
index 00000000..eaddf398
--- /dev/null
+++ b/config/coreboot/next/patches/0010-t480-hack-turn-off-the-dgpu.patch
@@ -0,0 +1,45 @@
+From 7c386cbe38fc42c036bd14b9048b13f1a1d45877 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <info@minifree.org>
+Date: Sun, 1 Dec 2024 23:40:08 +0000
+Subject: [PATCH 1/1] t480 hack: turn off the dgpu
+
+too buggy, in mkukri's testing. just turn it off.
+
+thanks go to mkukri for showing me how to turn this off.
+as nicholas explained to me, if there's no nvram on this board,
+coreboot can't use a static option table, because that works by
+copying those settings to the nvram.
+
+so we just have to hardcode for the time being
+
+Signed-off-by: Leah Rowe <info@minifree.org>
+---
+ 3rdparty/vboot | 2 +-
+ src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c | 4 +++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/3rdparty/vboot b/3rdparty/vboot
+index f1f70f46dc..1f53ea9b7f 160000
+--- a/3rdparty/vboot
++++ b/3rdparty/vboot
+@@ -1 +1 @@
+-Subproject commit f1f70f46dc5482bb7c654e53ed58d4001e386df2
++Subproject commit 1f53ea9b7f398884f722fca046129eae5ea6a71c
+diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
+index 9526642c57..bf5da12689 100644
+--- a/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c
+@@ -31,7 +31,9 @@ void mainboard_silicon_init_params(FSP_SIL_UPD *params)
+ dgfx_vram_id = gpio_get(GPIO_DGFX_VRAM_ID0) | gpio_get(GPIO_DGFX_VRAM_ID1) << 1;
+ printk(BIOS_DEBUG, "Discrete GPU present with %s VRAM\n", dgfx_vram_id_str[dgfx_vram_id]);
+
+- if (get_uint_option("dgpu_enable", 1)) {
++// if (get_uint_option("dgpu_enable", 1)) {
++ if (get_uint_option("dgpu_enable", 0)) { // HACK: no option table due to no nvram.
++ // (turn off the dgpu by default due to bugs)
+ printk(BIOS_DEBUG, "Enabling discrete GPU\n");
+ // NOTE: i pulled this GPU enable sequence from thin air but it seems to work
+ gpio_set(GPIO_1R8VIDEO_AON_ON, 1); // Enable GPU power rail
+--
+2.39.5
+
diff --git a/config/coreboot/next/target.cfg b/config/coreboot/next/target.cfg
index 80044097..be61aab7 100644
--- a/config/coreboot/next/target.cfg
+++ b/config/coreboot/next/target.cfg
@@ -1,2 +1,2 @@
tree="next"
-rev="d28fedf4f2cb7e4475a6cdfcab37d64cc60bba1f"
+rev="9992a98c671d356b9770282df5d58a302b6dbeda"