mikeb mikeb would like Mike Banon to review this change.

View Change

src/device/pci: Add support for discrete VGA initialization and OpROM loading

Required to make the discrete VGA working at some boards like AMD Lenovo G505S.
If CONFIG_MULTIPLE_VGA_ADAPTERS is enabled, coreboot will try to initialize the
discrete VGA and load OpROM on it. ACPI VFCT table will be created only for
discrete VGA instead of integrated, but everything seems to be working fine.
Maybe later we would find a way to make a common VFCT table for both adapters.

Based on the original patches by Hans Jürgen Kitter <eforname@freemail.hu>.

Signed-off-by: Mike Banon <mikebdp2@gmail.com>
Signed-off-by: Hans Jürgen Kitter <eforname@freemail.hu>
Change-Id: If3269a0911e86ea07014484365c7c830485e52ec
---
M src/device/pci_device.c
M src/device/pci_rom.c
2 files changed, 68 insertions(+), 12 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/48/31448/1
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index 82033a6..96dec0b 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -764,7 +764,9 @@
* ROMs when coming out of an S3 resume.
*/
if (!IS_ENABLED(CONFIG_S3_VGA_ROM_RUN) && acpi_is_wakeup_s3() &&
- ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA))
+ (((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) ||
+ (IS_ENABLED(CONFIG_MULTIPLE_VGA_ADAPTERS) &&
+ ((dev->class >> 8) == PCI_CLASS_DISPLAY_OTHER))))
return 0;
if (IS_ENABLED(CONFIG_ALWAYS_LOAD_OPROM))
return 1;
@@ -778,25 +780,41 @@
void pci_dev_init(struct device *dev)
{
struct rom_header *rom, *ram;
+ unsigned int pci_class = (dev->class >> 8);

if (!IS_ENABLED(CONFIG_VGA_ROM_RUN))
return;

- /* Only execute VGA ROMs. */
- if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA))
- return;
+ /* Only load VGA ROMs. */
+ if (pci_class != PCI_CLASS_DISPLAY_VGA) {
+ if (!IS_ENABLED(CONFIG_MULTIPLE_VGA_ADAPTERS)) {
+ return;
+ } else if (pci_class != PCI_CLASS_DISPLAY_OTHER) {
+ return;
+ }
+ }

if (!should_load_oprom(dev))
return;
timestamp_add_now(TS_OPROM_INITIALIZE);

rom = pci_rom_probe(dev);
- if (rom == NULL)
+ if (rom == NULL) {
+ if (pci_class == PCI_CLASS_DISPLAY_VGA)
+ printk(BIOS_DEBUG, "Integrated VGA ROM probe failed\n");
+ else
+ printk(BIOS_DEBUG, "Discrete VGA ROM probe failed\n");
return;
+ }

ram = pci_rom_load(dev, rom);
- if (ram == NULL)
+ if (ram == NULL) {
+ if (pci_class == PCI_CLASS_DISPLAY_VGA)
+ printk(BIOS_DEBUG, "Integrated VGA ROM load failed\n");
+ else
+ printk(BIOS_DEBUG, "Discrete VGA ROM load failed\n");
return;
+ }
timestamp_add_now(TS_OPROM_COPY_END);

if (!should_run_oprom(dev))
@@ -804,7 +822,11 @@

run_bios(dev, (unsigned long)ram);
gfx_set_init_done(1);
- printk(BIOS_DEBUG, "VGA Option ROM was run\n");
+ if (pci_class == PCI_CLASS_DISPLAY_VGA)
+ printk(BIOS_DEBUG, "Integrated VGA Option ROM was run\n");
+ else
+ printk(BIOS_DEBUG, "Discrete VGA Option ROM was run\n");
+
timestamp_add_now(TS_OPROM_END);
}

diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c
index 82d9a30..60f9aed 100644
--- a/src/device/pci_rom.c
+++ b/src/device/pci_rom.c
@@ -179,13 +179,24 @@
/* VBIOS may be modified after oprom init so use the copy if present. */
static struct rom_header *check_initialized(struct device *dev)
{
- struct rom_header *run_rom;
+ struct rom_header *run_rom = NULL;
struct pci_data *rom_data;

if (!IS_ENABLED(CONFIG_VGA_ROM_RUN))
return NULL;

- run_rom = (struct rom_header *)(uintptr_t)PCI_VGA_RAM_IMAGE_START;
+ /* Set the start of shadow memory for this Integrated or Discrete VGA. */
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+ run_rom = (struct rom_header *)(uintptr_t)PCI_VGA_RAM_IMAGE_START;
+ } else if (IS_ENABLED(CONFIG_MULTIPLE_VGA_ADAPTERS)) {
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_OTHER) {
+ run_rom = (struct rom_header *)(uintptr_t)PCI_RAM_IMAGE_START;
+ }
+ }
+
+ if (run_rom == NULL)
+ return NULL;
+
if (read_le16(&run_rom->signature) != PCI_ROM_HDR)
return NULL;

@@ -217,11 +228,22 @@
return current;
}

- printk(BIOS_DEBUG, " Copying %sVBIOS image from %p\n",
+ if (!IS_ENABLED(CONFIG_MULTIPLE_VGA_ADAPTERS)) {
+ /* Copy Integrated VGA VBIOS from CBFS to ACPI VFCT. */
+ printk(BIOS_DEBUG, " Copying %sVBIOS image from %p\n",
rom == (struct rom_header *)
(uintptr_t)PCI_VGA_RAM_IMAGE_START ?
"initialized " : "",
rom);
+ } else {
+ /* Copy Discrete VGA VBIOS from CBFS to ACPI VFCT. */
+ printk(BIOS_DEBUG, " Copying %sVBIOS image from %p\n",
+ rom == (struct rom_header *)
+ (uintptr_t)PCI_RAM_IMAGE_START ?
+ "initialized " : "",
+ rom);
+ /* TODO: do this also for Integrated VGA VBIOS. */
+ }

header->DeviceID = device->device;
header->VendorID = device->vendor;
@@ -243,8 +265,20 @@
struct rom_header *rom;

/* Only handle VGA devices */
- if ((device->class >> 8) != PCI_CLASS_DISPLAY_VGA)
- return current;
+
+ if (!IS_ENABLED(CONFIG_MULTIPLE_VGA_ADAPTERS)) {
+ if ((device->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
+ return current;
+ }
+ } else {
+ /* Write ACPI VFCT only for Discrete VGA. */
+ if ((device->class >> 8) == PCI_CLASS_DISPLAY_OTHER) {
+ ;
+ } else {
+ return current;
+ }
+ /* TODO: do this also for Integrated VGA. */
+ }

/* Only handle enabled devices */
if (!device->enabled)

To view, visit change 31448. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: If3269a0911e86ea07014484365c7c830485e52ec
Gerrit-Change-Number: 31448
Gerrit-PatchSet: 1
Gerrit-Owner: mikeb mikeb <mikebdp2@gmail.com>
Gerrit-Reviewer: Mike Banon <mikebdp2@gmail.com>
Gerrit-MessageType: newchange