Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/20794
Change subject: drvs/lenovo/hybrid_graphics: Switch to new hybrid driver ......................................................................
drvs/lenovo/hybrid_graphics: Switch to new hybrid driver
Get rid of old hybrid graphics driver and use the new one. Disable IGD and PEG in early romstage and remove the PCI based driver. Add GPIO configuration in devicetree.
Needs test on all devices.
Change-Id: Ibf18b75e8afe2568de8498b39a608dac8db3ba73 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M src/drivers/lenovo/Kconfig M src/drivers/lenovo/Makefile.inc D src/drivers/lenovo/hybrid_graphics.c M src/mainboard/lenovo/t420/devicetree.cb M src/mainboard/lenovo/t420/romstage.c M src/mainboard/lenovo/t420s/devicetree.cb M src/mainboard/lenovo/t420s/romstage.c M src/mainboard/lenovo/t430/devicetree.cb M src/mainboard/lenovo/t430/romstage.c M src/mainboard/lenovo/t520/devicetree.cb M src/mainboard/lenovo/t520/romstage.c M src/mainboard/lenovo/t530/devicetree.cb M src/mainboard/lenovo/t530/romstage.c 13 files changed, 220 insertions(+), 131 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/94/20794/1
diff --git a/src/drivers/lenovo/Kconfig b/src/drivers/lenovo/Kconfig index 38b86da..f20f3b2 100644 --- a/src/drivers/lenovo/Kconfig +++ b/src/drivers/lenovo/Kconfig @@ -27,15 +27,3 @@ endchoice
endif - -config DRIVERS_LENOVO_HYBRID_GRAPHICS - bool - default n - -config HYBRID_GRAPHICS_GPIO_NUM - depends on DRIVERS_LENOVO_HYBRID_GRAPHICS - int - default 52 - help - Set a default GPIO that sets the panel LVDS signal routing to - integrated or discrete GPU. diff --git a/src/drivers/lenovo/Makefile.inc b/src/drivers/lenovo/Makefile.inc index 66f8594..c50db5b 100644 --- a/src/drivers/lenovo/Makefile.inc +++ b/src/drivers/lenovo/Makefile.inc @@ -1,2 +1 @@ ramstage-$(CONFIG_DRIVERS_LENOVO_WACOM) += wacom.c -ramstage-$(CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS) += hybrid_graphics.c diff --git a/src/drivers/lenovo/hybrid_graphics.c b/src/drivers/lenovo/hybrid_graphics.c deleted file mode 100644 index 802823a..0000000 --- a/src/drivers/lenovo/hybrid_graphics.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015-2016 Patrick Rudolph - * Copyright (C) 2015 Timothy Pearson tpearson@raptorengineeringinc.com, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <types.h> -#include <string.h> -#include <option.h> -#include <device/device.h> -#include <device/pci_def.h> -#include <device/pci_ops.h> -#include <device/pci_ids.h> -#include <device/pci.h> -#include <console/console.h> -#include <southbridge/intel/common/gpio.h> - -/* Hybrid graphics allows to connect LVDS interface to either iGPU - * or dGPU depending on GPIO level. - * Nvidia is calling this functionality "muxed Optimus". - * Some devices, like T430s, only support "muxless Optimus" where the - * Intel GPU is always connected to the panel. - * As it is only linked on lenovo and only executed if the GPU exists - * we know for sure that the dGPU is there and connected to first PEG slot. - * - * Note: Once native gfx init is done for AMD or Nvida graphic - * cards, merge this code. - */ - -#define HYBRID_GRAPHICS_INTEGRATED 0 -#define HYBRID_GRAPHICS_DISCRETE 1 - -static void hybrid_graphics_disable_peg(struct device *dev) -{ - struct device *peg_dev; - - /* connect LVDS interface to iGPU */ - set_gpio(CONFIG_HYBRID_GRAPHICS_GPIO_NUM, GPIO_LEVEL_HIGH); - printk(BIOS_DEBUG, "Hybrid graphics: Switching panel to integrated GPU.\n"); - dev->enabled = 0; - - /* Disable PEG10 */ - peg_dev = dev_find_slot(0, PCI_DEVFN(1, 0)); - if (peg_dev) - peg_dev->enabled = 0; - - printk(BIOS_DEBUG, "Hybrid graphics: Disabled PEG10.\n"); -} - -/* Called before VGA enable bits are set and only if dGPU - * is present. Enable/disable VGA devices here. */ -static void hybrid_graphics_enable_peg(struct device *dev) -{ - u8 hybrid_graphics_mode; - - hybrid_graphics_mode = HYBRID_GRAPHICS_INTEGRATED; - get_option(&hybrid_graphics_mode, "hybrid_graphics_mode"); - - if (hybrid_graphics_mode == HYBRID_GRAPHICS_DISCRETE) { - /* connect LVDS interface to dGPU */ - set_gpio(CONFIG_HYBRID_GRAPHICS_GPIO_NUM, GPIO_LEVEL_LOW); - printk(BIOS_DEBUG, "Hybrid graphics: Switching panel to discrete GPU.\n"); - dev->enabled = 1; - - /* Disable IGD */ - dev = dev_find_slot(0, PCI_DEVFN(2, 0)); - if (dev && dev->ops->disable) - dev->ops->disable(dev); - dev->enabled = 0; - - printk(BIOS_DEBUG, "Hybrid graphics: Disabled IGD.\n"); - } else - hybrid_graphics_disable_peg(dev); -} - -static struct pci_operations pci_dev_ops_pci = { - .set_subsystem = pci_dev_set_subsystem, -}; - -struct device_operations hybrid_graphics_ops = { - .read_resources = pci_dev_read_resources, - .set_resources = pci_dev_set_resources, - .enable_resources = pci_dev_enable_resources, - .init = pci_dev_init, - .scan_bus = 0, - .enable = hybrid_graphics_enable_peg, - .disable = hybrid_graphics_disable_peg, - .ops_pci = &pci_dev_ops_pci, -}; - -static const unsigned short pci_device_ids_nvidia[] = { - 0x0ffc, /* Nvidia NVS Quadro K1000m Lenovo W530 */ - 0x0def, /* NVidia NVS 5400m Lenovo T430/T530 */ - 0x0dfc, /* NVidia NVS 5200m Lenovo T430s */ - 0x1056, /* NVidia NVS 4200m Lenovo T420/T520 */ - 0x1057, /* NVidia NVS 4200m Lenovo T420/T520 */ - 0x0a6c, /* NVidia NVS 3100m Lenovo T410/T510 */ - 0 }; - -static const struct pci_driver hybrid_peg_nvidia __pci_driver = { - .ops = &hybrid_graphics_ops, - .vendor = PCI_VENDOR_ID_NVIDIA, - .devices = pci_device_ids_nvidia, -}; diff --git a/src/mainboard/lenovo/t420/devicetree.cb b/src/mainboard/lenovo/t420/devicetree.cb index deb62b7..7d41204 100644 --- a/src/mainboard/lenovo/t420/devicetree.cb +++ b/src/mainboard/lenovo/t420/devicetree.cb @@ -162,6 +162,17 @@ register "eventd_enable" = "0xff" register "evente_enable" = "0x0d" end + chip drivers/lenovo/hybrid_graphics + device pnp ff.f on end # dummy + + register "detect_gpio" = "21" + + register "has_panel_hybrid_gpio" = "1" + register "panel_hybrid_gpio" = "52" + register "panel_integrated_lvl" = "1" + + register "has_backlight_gpio" = "0" + end end # LPC Controller device pci 1f.2 on subsystemid 0x17aa 0x21ce diff --git a/src/mainboard/lenovo/t420/romstage.c b/src/mainboard/lenovo/t420/romstage.c index 94b8d62..f08ca03 100644 --- a/src/mainboard/lenovo/t420/romstage.c +++ b/src/mainboard/lenovo/t420/romstage.c @@ -18,6 +18,37 @@ #include <arch/io.h> #include <northbridge/intel/sandybridge/raminit_native.h> #include <southbridge/intel/bd82x6x/pch.h> +#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h> +#include <northbridge/intel/sandybridge/sandybridge.h> +#include <device/device.h> +#include <device/pci.h> + +static void hybrid_graphics_init(void) +{ + struct device *dev; + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + if (!dev) + return; + + /* Hide disabled devices */ + reg32 = pci_read_config32(dev, DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + + pci_write_config32(dev, DEVEN, reg32); + + /* TODO: Toggle GPU power */ +}
void pch_enable_lpc(void) { @@ -65,6 +96,7 @@
void mainboard_early_init(int s3resume) { + hybrid_graphics_init(); }
void mainboard_config_superio(void) diff --git a/src/mainboard/lenovo/t420s/devicetree.cb b/src/mainboard/lenovo/t420s/devicetree.cb index 3224322..b0ed992 100644 --- a/src/mainboard/lenovo/t420s/devicetree.cb +++ b/src/mainboard/lenovo/t420s/devicetree.cb @@ -154,6 +154,17 @@ register "eventd_enable" = "0xff" register "evente_enable" = "0x0d" end + chip drivers/lenovo/hybrid_graphics + device pnp ff.f on end # dummy + + register "detect_gpio" = "21" + + register "has_panel_hybrid_gpio" = "1" + register "panel_hybrid_gpio" = "52" + register "panel_integrated_lvl" = "1" + + register "has_backlight_gpio" = "0" + end end # LPC Controller device pci 1f.2 on subsystemid 0x17aa 0x21d2 diff --git a/src/mainboard/lenovo/t420s/romstage.c b/src/mainboard/lenovo/t420s/romstage.c index d7f1c23..207abc6 100644 --- a/src/mainboard/lenovo/t420s/romstage.c +++ b/src/mainboard/lenovo/t420s/romstage.c @@ -17,10 +17,40 @@
#include <arch/byteorder.h> #include <arch/io.h> -#include <device/pci_def.h> #include <console/console.h> #include <northbridge/intel/sandybridge/raminit_native.h> #include <southbridge/intel/bd82x6x/pch.h> +#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h> +#include <northbridge/intel/sandybridge/sandybridge.h> +#include <device/device.h> +#include <device/pci.h> + +static void hybrid_graphics_init(void) +{ + struct device *dev; + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + if (!dev) + return; + + /* Hide disabled devices */ + reg32 = pci_read_config32(dev, DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + + pci_write_config32(dev, DEVEN, reg32); + + /* TODO: Toggle GPU power */ +}
void pch_enable_lpc(void) { @@ -65,7 +95,9 @@ read_spd(&spd[2], 0x51, id_only); }
-void mainboard_early_init(int s3resume) { +void mainboard_early_init(int s3resume) +{ + hybrid_graphics_init(); }
void mainboard_config_superio(void) diff --git a/src/mainboard/lenovo/t430/devicetree.cb b/src/mainboard/lenovo/t430/devicetree.cb index 0a121b7..d43c0c9 100644 --- a/src/mainboard/lenovo/t430/devicetree.cb +++ b/src/mainboard/lenovo/t430/devicetree.cb @@ -150,6 +150,17 @@ register "eventd_enable" = "0xff" register "evente_enable" = "0x0d" end + chip drivers/lenovo/hybrid_graphics + device pnp ff.f on end # dummy + + register "detect_gpio" = "21" + + register "has_panel_hybrid_gpio" = "1" + register "panel_hybrid_gpio" = "52" + register "panel_integrated_lvl" = "1" + + register "has_backlight_gpio" = "0" + end end device pci 1f.2 on # SATA Controller 1 subsystemid 0x17aa 0x21f3 diff --git a/src/mainboard/lenovo/t430/romstage.c b/src/mainboard/lenovo/t430/romstage.c index eb2d29e..c1be93c 100644 --- a/src/mainboard/lenovo/t430/romstage.c +++ b/src/mainboard/lenovo/t430/romstage.c @@ -18,6 +18,37 @@ #include <northbridge/intel/sandybridge/raminit_native.h> #include <southbridge/intel/bd82x6x/pch.h> #include <ec/lenovo/pmh7/pmh7.h> +#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h> +#include <northbridge/intel/sandybridge/sandybridge.h> +#include <device/device.h> +#include <device/pci.h> + +static void hybrid_graphics_init(void) +{ + struct device *dev; + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + if (!dev) + return; + + /* Hide disabled devices */ + reg32 = pci_read_config32(dev, DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + + pci_write_config32(dev, DEVEN, reg32); + + /* TODO: Toggle GPU power */ +}
void pch_enable_lpc(void) { @@ -57,6 +88,7 @@
void mainboard_early_init(int s3resume) { + hybrid_graphics_init(); }
void mainboard_config_superio(void) diff --git a/src/mainboard/lenovo/t520/devicetree.cb b/src/mainboard/lenovo/t520/devicetree.cb index 0065799..11f7b51 100644 --- a/src/mainboard/lenovo/t520/devicetree.cb +++ b/src/mainboard/lenovo/t520/devicetree.cb @@ -133,6 +133,17 @@ register "eventd_enable" = "0xff" register "evente_enable" = "0x0d" end + chip drivers/lenovo/hybrid_graphics + device pnp ff.f on end # dummy + + register "detect_gpio" = "21" + + register "has_panel_hybrid_gpio" = "1" + register "panel_hybrid_gpio" = "52" + register "panel_integrated_lvl" = "1" + + register "has_backlight_gpio" = "0" + end end # LPC bridge device pci 1f.2 on end # SATA Controller 1 device pci 1f.3 on # SMBUS controller diff --git a/src/mainboard/lenovo/t520/romstage.c b/src/mainboard/lenovo/t520/romstage.c index f84bc0d..154423e 100644 --- a/src/mainboard/lenovo/t520/romstage.c +++ b/src/mainboard/lenovo/t520/romstage.c @@ -35,6 +35,36 @@ #include <arch/cpu.h> #include <cpu/x86/msr.h> #include <cbfs.h> +#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h> +#include <device/device.h> +#include <device/pci.h> + +static void hybrid_graphics_init(void) +{ + struct device *dev; + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + if (!dev) + return; + + /* Hide disabled devices */ + reg32 = pci_read_config32(dev, DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + + pci_write_config32(dev, DEVEN, reg32); + + /* TODO: Toggle GPU power */ +}
void pch_enable_lpc(void) { @@ -79,7 +109,9 @@ read_spd (&spd[2], 0x51, id_only); }
-void mainboard_early_init(int s3resume) { +void mainboard_early_init(int s3resume) +{ + hybrid_graphics_init(); }
void mainboard_config_superio(void) diff --git a/src/mainboard/lenovo/t530/devicetree.cb b/src/mainboard/lenovo/t530/devicetree.cb index 2047a78..1ba060b 100644 --- a/src/mainboard/lenovo/t530/devicetree.cb +++ b/src/mainboard/lenovo/t530/devicetree.cb @@ -140,6 +140,17 @@ register "eventd_enable" = "0xff" register "evente_enable" = "0x0d" end + chip drivers/lenovo/hybrid_graphics + device pnp ff.f on end # dummy + + register "detect_gpio" = "21" + + register "has_panel_hybrid_gpio" = "1" + register "panel_hybrid_gpio" = "52" + register "panel_integrated_lvl" = "1" + + register "has_backlight_gpio" = "0" + end end # LPC bridge device pci 1f.2 on end # SATA Controller 1 device pci 1f.3 on diff --git a/src/mainboard/lenovo/t530/romstage.c b/src/mainboard/lenovo/t530/romstage.c index c454ec7..d1b7ec1 100644 --- a/src/mainboard/lenovo/t530/romstage.c +++ b/src/mainboard/lenovo/t530/romstage.c @@ -22,6 +22,37 @@ #include <console/console.h> #include <northbridge/intel/sandybridge/raminit_native.h> #include <southbridge/intel/bd82x6x/pch.h> +#include <northbridge/intel/sandybridge/sandybridge.h> +#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h> +#include <device/device.h> +#include <device/pci.h> + +static void hybrid_graphics_init(void) +{ + struct device *dev; + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + dev = dev_find_slot(0, PCI_DEVFN(0, 0)); + if (!dev) + return; + + /* Hide disabled devices */ + reg32 = pci_read_config32(dev, DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + + pci_write_config32(dev, DEVEN, reg32); + + /* TODO: Toggle GPU power */ +}
void pch_enable_lpc(void) { @@ -66,7 +97,9 @@ read_spd (&spd[2], 0x51, id_only); }
-void mainboard_early_init(int s3resume) { +void mainboard_early_init(int s3resume) +{ + hybrid_graphics_init(); }
void mainboard_config_superio(void)