From f530d37da736c190f475bbe7333932e612edf43f Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 14 Feb 2026 18:35:58 +0100 Subject: [PATCH] mb/lenovo/x220: Add PCIe ports in CFR Allow the user to disable PCIe ports that are not required. Change-Id: Id2d7640255c347c768387408f27e9f5448cbef01 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91232 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/lenovo/x220/cfr.c | 21 ++++++++++++++++++ src/mainboard/lenovo/x220/mainboard.c | 32 +++++++++++++++++++++++++++ src/southbridge/intel/bd82x6x/cfr.h | 12 ++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/mainboard/lenovo/x220/cfr.c b/src/mainboard/lenovo/x220/cfr.c index 6d43c17856..2ebfd32d77 100644 --- a/src/mainboard/lenovo/x220/cfr.c +++ b/src/mainboard/lenovo/x220/cfr.c @@ -8,6 +8,26 @@ #include #include +GEN_RP_ENUM(1, "Wifi") +#if CONFIG(BOARD_LENOVO_X220) +GEN_RP_ENUM(3, "ExpressCard") +#endif +GEN_RP_ENUM(4, "SD Card Reader") +GEN_RP_ENUM(6, "xHCI") + +static struct sm_obj_form pcie = { + .ui_name = "PCH PCIe", + .obj_list = (const struct sm_object *[]) { + &pcie_rp1, +#if CONFIG(BOARD_LENOVO_X220) + &pcie_rp3, +#endif + &pcie_rp4, + &pcie_rp6, + NULL + }, +}; + static struct sm_obj_form ec = { .ui_name = "Embedded Controller", .obj_list = (const struct sm_object *[]) { @@ -49,6 +69,7 @@ static struct sm_obj_form *sm_root[] = { &system, &power, &ec, + &pcie, NULL }; diff --git a/src/mainboard/lenovo/x220/mainboard.c b/src/mainboard/lenovo/x220/mainboard.c index 50c944e341..92e4b8e12e 100644 --- a/src/mainboard/lenovo/x220/mainboard.c +++ b/src/mainboard/lenovo/x220/mainboard.c @@ -1,7 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include +#include +#include +#include static void mainboard_enable(struct device *dev) { @@ -10,6 +14,34 @@ static void mainboard_enable(struct device *dev) GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); } +static void mainboard_init(void *chip_info) +{ + char option[20]; + + /* Apply user config and disable ports if option exists and is 0 */ + for (struct device *dev = all_devices; dev; dev = dev->next) { + /* Only care about PCH PCIe root ports */ + if (PCI_SLOT(dev->path.pci.devfn) != + PCH_PCIE_DEV_SLOT) + continue; + /* + * Only care about ports enabled at this point. Ports that are + * disabled here are not implemented on this mainboard. + */ + if (!dev->enabled) + continue; + + const unsigned int idx = PCI_FUNC(dev->path.pci.devfn); + snprintf(option, sizeof(option), "pch_pcie_enable_rp%u", idx); + + /* When option is not found keep current configuration */ + dev->enabled = get_uint_option(option, dev->enabled); + printk(BIOS_DEBUG, "%s: %s %sabled\n", __func__, dev_path(dev), + dev->enabled ? "en" : "dis"); + } +} + struct chip_operations mainboard_ops = { + .init = mainboard_init, .enable_dev = mainboard_enable, }; diff --git a/src/southbridge/intel/bd82x6x/cfr.h b/src/southbridge/intel/bd82x6x/cfr.h index 8b9f928f34..d70650463a 100644 --- a/src/southbridge/intel/bd82x6x/cfr.h +++ b/src/southbridge/intel/bd82x6x/cfr.h @@ -11,6 +11,18 @@ #include #include "me.h" +#define GEN_RP_ENUM(x, y) \ +static const struct sm_object pcie_rp##x = SM_DECLARE_ENUM({ \ + .opt_name = "pch_pcie_enable_rp"#x, \ + .ui_name = y, \ + .ui_helptext = "Enable or disable "#y, \ + .default_value = 1, \ + .values = (const struct sm_enum_value[]) { \ + { "Disabled", 0 }, \ + { "Enabled", 1 }, \ + SM_ENUM_VALUE_END }, \ +}); + /* Power state after power loss */ static const struct sm_object power_on_after_fail = SM_DECLARE_ENUM({ .opt_name = "power_on_after_fail",