diff --git a/src/device/Kconfig b/src/device/Kconfig index a5e00aa331..22a2f773fd 100644 --- a/src/device/Kconfig +++ b/src/device/Kconfig @@ -65,6 +65,23 @@ config MAINBOARD_HAS_EARLY_LIBGFXINIT stage) support of `libgfxinit`. Usually this requires a list of ports to be probed for displays. +config MAINBOARD_VERSION_HAS_AMD_DGPU_WITHOUT_EEPROM + def_bool n + help + Selected by mainboards that have a version with the onboard AMD + discrete GPU without its own EEPROM storage for VGA Option ROM. + +config AMD_DGPU_WITHOUT_EEPROM + def_bool n + prompt "AMD discrete GPU without EEPROM" + depends on MAINBOARD_VERSION_HAS_AMD_DGPU_WITHOUT_EEPROM + help + Some platforms like Lenovo G505S have the motherboard versions + with the onboard AMD discrete GPU without its own dedicated EEPROM + storage for VGA Option ROM. For such a discrete GPU to be usable + with coreboot, the PCI init of GPUs has to be done differently. + Enable this option if your motherboard has such a discrete GPU. + choice prompt "Graphics initialization" default NO_GFX_INIT if VGA_ROM_RUN_DEFAULT && PAYLOAD_SEABIOS diff --git a/src/device/pci_device.c b/src/device/pci_device.c index a3ddcdcc9e..69dbb4b3a6 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -860,6 +860,10 @@ static int should_run_oprom(struct device *dev, struct rom_header *rom) if (should_run >= 0) return should_run; + if (CONFIG(AMD_DGPU_WITHOUT_EEPROM) && + ((dev->class >> 8) == PCI_CLASS_DISPLAY_OTHER)) + return 0; + if (CONFIG(ALWAYS_RUN_OPROM)) { should_run = 1; return should_run; @@ -881,8 +885,13 @@ static int should_load_oprom(struct device *dev) * ROMs when coming out of an S3 resume. */ if (!CONFIG(S3_VGA_ROM_RUN) && acpi_is_wakeup_s3() && - ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)) + (((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) || + (CONFIG(AMD_DGPU_WITHOUT_EEPROM) && + ((dev->class >> 8) == PCI_CLASS_DISPLAY_OTHER)))) return 0; + if (CONFIG(AMD_DGPU_WITHOUT_EEPROM) && + ((dev->class >> 8) == PCI_CLASS_DISPLAY_OTHER)) + return 1; if (CONFIG(ALWAYS_LOAD_OPROM)) return 1; if (should_run_oprom(dev, NULL)) @@ -905,8 +914,10 @@ void pci_dev_init(struct device *dev) if (!CONFIG(VGA_ROM_RUN)) return; - /* Only execute VGA ROMs. */ - if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)) + /* Only process VGA ROMs. */ + if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) && + (!CONFIG(AMD_DGPU_WITHOUT_EEPROM) || + ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER))) return; if (!should_load_oprom(dev)) @@ -914,12 +925,20 @@ void pci_dev_init(struct device *dev) timestamp_add_now(TS_OPROM_INITIALIZE); rom = pci_rom_probe(dev); - if (rom == NULL) + if (rom == NULL) { + printk(BIOS_DEBUG, "PCI_CLASS_DISPLAY_%s%s ROM probe failed\n", + (dev->class >> 8) == PCI_CLASS_DISPLAY_VGA ? "VGA" : "", + (dev->class >> 8) == PCI_CLASS_DISPLAY_OTHER ? "OTHER" : ""); return; + } ram = pci_rom_load(dev, rom); - if (ram == NULL) + if (ram == NULL) { + printk(BIOS_DEBUG, "PCI_CLASS_DISPLAY_%s%s ROM load failed\n", + (dev->class >> 8) == PCI_CLASS_DISPLAY_VGA ? "VGA" : "", + (dev->class >> 8) == PCI_CLASS_DISPLAY_OTHER ? "OTHER" : ""); return; + } timestamp_add_now(TS_OPROM_COPY_END); if (!should_run_oprom(dev, rom)) diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c index bc693fb764..3d36b561d3 100644 --- a/src/device/pci_rom.c +++ b/src/device/pci_rom.c @@ -232,6 +232,12 @@ pci_rom_write_acpi_tables(const struct device *device, unsigned long current, if ((device->class >> 16) != PCI_BASE_CLASS_DISPLAY) return current; + /* Write ACPI VFCT only for Discrete VGA. */ + /* TODO: do this also for Integrated VGA. */ + if (CONFIG(AMD_DGPU_WITHOUT_EEPROM) && + ((device->class >> 8) == PCI_CLASS_DISPLAY_VGA)) + return current; + /* Only handle enabled devices */ if (!device->enabled) return current; diff --git a/src/mainboard/lenovo/g505s/Kconfig b/src/mainboard/lenovo/g505s/Kconfig index dbf8b68253..5576f6af9b 100644 --- a/src/mainboard/lenovo/g505s/Kconfig +++ b/src/mainboard/lenovo/g505s/Kconfig @@ -16,6 +16,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_TABLES select BOARD_ROMSIZE_KB_4096 select GFXUMA + select MAINBOARD_VERSION_HAS_AMD_DGPU_WITHOUT_EEPROM select NO_UART_ON_SUPERIO config MAINBOARD_DIR diff --git a/src/mainboard/lenovo/g505s/devicetree.cb b/src/mainboard/lenovo/g505s/devicetree.cb index 4b4df367b1..6d7d3e526f 100644 --- a/src/mainboard/lenovo/g505s/devicetree.cb +++ b/src/mainboard/lenovo/g505s/devicetree.cb @@ -15,7 +15,7 @@ chip northbridge/amd/agesa/family15tn/root_complex device pci 0.2 on end # IOMMU device pci 1.0 on end # Internal Graphics P2P bridge 0x99XX device pci 1.1 on end # Internal Multimedia - device pci 2.0 off end + device pci 2.0 on end # Discrete Graphics PCI bus 0x666X device pci 3.0 off end device pci 4.0 on end # PCIE MINI0 device pci 5.0 on end # PCIE MINI1