[coreboot-gerrit] Patch set updated for coreboot: device/device: handle multiple VGA devices
Patrick Rudolph (siro@das-labor.org)
gerrit at coreboot.org
Mon Feb 22 07:26:21 CET 2016
Patrick Rudolph (siro at das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/12897
-gerrit
commit 264f009a3fdda33994953b2f7b45861ae79f8996
Author: Patrick Rudolph <siro at das-labor.org>
Date: Sat Dec 26 08:27:20 2015 +0100
device/device: handle multiple VGA devices
Add nvram option "dual_graphics_mode" to switch between
VGA devices.
As dual_graphics_mode is 0 or not set, the existing code
will run and disable devices based on CONFIG_VGA_IS_PRIMARY.
dual_graphics_mode is 1 and an onboard VGA device exists,
disable all other VGA devices.
dual_graphics_mode is 2 and non onboard VGA device exists,
disable all other VGA devices.
dual_graphics_mode is 3 isn't handled yet, and could be used for
multiple VGA devices active at once.
Tested on Lenovo T530 using Nvidia NVS 5400m.
WIP: Do not commit yet !
Change-Id: Ie37ec4aeae8ab49fe8e26438c430911d1815551c
Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
src/device/device.c | 93 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 72 insertions(+), 21 deletions(-)
diff --git a/src/device/device.c b/src/device/device.c
index e23c9de..765d6a2 100644
--- a/src/device/device.c
+++ b/src/device/device.c
@@ -44,6 +44,7 @@
#include <arch/ebda.h>
#endif
#include <timer.h>
+#include <option.h>
/** Linked list of ALL devices */
struct device *all_devices = &dev_root;
@@ -748,28 +749,52 @@ static void avoid_fixed_resources(struct device *dev)
}
}
+static struct device *get_next_vga_dev(struct device *dev)
+{
+ while ((dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev))) {
+ if (!dev->enabled)
+ continue;
+
+ return dev;
+ }
+ return NULL;
+}
+
+/*
+ * Disables all PCI_CLASS_DISPLAY_VGA devices except the one
+ * given as argument.
+ * @param dev_primary The device to ignore
+ */
+static void disable_secondary_vga_devs(struct device *dev_primary)
+{
+ struct device *dev = NULL;
+
+ while ((dev = get_next_vga_dev(dev))) {
+ /* disable unused devices to save power */
+ if (dev != dev_primary) {
+ if (dev->ops && dev->ops->disable)
+ dev->ops->disable(dev);
+ else
+ dev->enabled = 0;
+ }
+ }
+}
+
device_t vga_pri = 0;
static void set_vga_bridge_bits(void)
{
- /*
- * FIXME: Modify set_vga_bridge() so it is less PCI-centric!
- * This function knows too much about PCI stuff, it should be just
- * an iterator/visitor.
- */
-
/* FIXME: Handle the VGA palette snooping. */
struct device *dev, *vga, *vga_onboard;
struct bus *bus;
+ u8 vga_primary_is_peg;
+ u8 vga_secondary_powersave;
bus = 0;
vga = 0;
vga_onboard = 0;
dev = NULL;
- while ((dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev))) {
- if (!dev->enabled)
- continue;
-
+ while ((dev = get_next_vga_dev(dev))) {
printk(BIOS_DEBUG, "found VGA at %s\n", dev_path(dev));
if (dev->on_mainboard) {
@@ -782,23 +807,49 @@ static void set_vga_bridge_bits(void)
dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
}
- if (!vga)
- vga = vga_onboard;
+ if ((get_option(&vga_primary_is_peg, "vga_primary_is_peg") != CB_SUCCESS) ||
+ (get_option(&vga_secondary_powersave, "vga_secondary_powersave") != CB_SUCCESS) ||
+ !vga || !vga_onboard) {
+ /* fallback */
+ if (!vga)
+ vga = vga_onboard;
+
+ if (IS_ENABLED(CONFIG_ONBOARD_VGA_IS_PRIMARY) && vga_onboard)
+ vga = vga_onboard;
+
+ /* If we prefer plugin VGA over chipset VGA, the chipset might
+ want to know. */
+ if (!IS_ENABLED(CONFIG_ONBOARD_VGA_IS_PRIMARY) &&
+ (vga != vga_onboard) &&
+ vga_onboard) {
+ printk(BIOS_DEBUG, "Use plugin graphics over integrated.\n");
+
+ if (vga_onboard->ops && vga_onboard->ops->disable)
+ vga_onboard->ops->disable(vga_onboard);
+ else
+ vga_onboard->enabled = 0;
+ }
+
+ disable_secondary_vga_devs(vga);
+ } else {
+ /* have vga and vga_onboard (two or more VGAs) */
- if (CONFIG_ONBOARD_VGA_IS_PRIMARY && vga_onboard)
- vga = vga_onboard;
+ /* make onboard primary if vga_primary_is_peg is disabled */
+ if (vga_primary_is_peg == 0) {
+ printk(BIOS_DEBUG, "Use integrated graphics over plugin.\n");
+ vga = vga_onboard;
+ }
- /* If we prefer plugin VGA over chipset VGA, the chipset might
- want to know. */
- if (!CONFIG_ONBOARD_VGA_IS_PRIMARY && (vga != vga_onboard) &&
- vga_onboard && vga_onboard->ops && vga_onboard->ops->disable) {
- printk(BIOS_DEBUG, "Use plugin graphics over integrated.\n");
- vga_onboard->ops->disable(vga_onboard);
+ /* disable secondary VGAs if vga_secondary_powersave is enabled */
+ if (vga_secondary_powersave == 1) {
+ printk(BIOS_DEBUG, "Disable secondary graphics to save power.\n");
+ disable_secondary_vga_devs(vga);
+ }
}
if (vga) {
/* VGA is first add-on card or the only onboard VGA. */
- printk(BIOS_DEBUG, "Setting up VGA for %s\n", dev_path(vga));
+ printk(BIOS_DEBUG, "Setting up %s for primary VGA.\n", dev_path(vga));
/* All legacy VGA cards have MEM & I/O space registers. */
vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
vga_pri = vga;
More information about the coreboot-gerrit
mailing list