diff --git a/src/drivers/lenovo/Kconfig b/src/drivers/lenovo/Kconfig index f20f3b2229..f8eddf2a80 100644 --- a/src/drivers/lenovo/Kconfig +++ b/src/drivers/lenovo/Kconfig @@ -27,3 +27,16 @@ config DIGITIZER_ABSENT 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 c50db5b8be..66f8594bf9 100644 --- a/src/drivers/lenovo/Makefile.inc +++ b/src/drivers/lenovo/Makefile.inc @@ -1 +1,2 @@ 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 new file mode 100644 index 0000000000..9b46646e4b --- /dev/null +++ b/src/drivers/lenovo/hybrid_graphics.c @@ -0,0 +1,125 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015-2016 Patrick Rudolph + * Copyright (C) 2015 Timothy Pearson , 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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, +}; + +static const unsigned short pci_device_ids_amd[] = { + 0x9591, /* ATI Mobility Radeon HD 3650 Lenovo T500/W500 */ + 0x95c4, /* ATI Mobility Radeon HD 3470 Lenovo T400/R400 */ + 0 }; + +static const struct pci_driver hybrid_peg_amd __pci_driver = { + .ops = &hybrid_graphics_ops, + .vendor = PCI_VENDOR_ID_ATI, + .devices = pci_device_ids_amd, +}; diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig index d74a813bd6..a444bf879e 100644 --- a/src/mainboard/lenovo/t400/Kconfig +++ b/src/mainboard/lenovo/t400/Kconfig @@ -22,6 +22,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG select INTEL_INT15 select SUPERIO_NSC_PC87382 + select DRIVERS_LENOVO_HYBRID_GRAPHICS config MAINBOARD_DIR string diff --git a/src/mainboard/lenovo/t400/cmos.default b/src/mainboard/lenovo/t400/cmos.default index ac9f96d73c..98ce970278 100644 --- a/src/mainboard/lenovo/t400/cmos.default +++ b/src/mainboard/lenovo/t400/cmos.default @@ -13,3 +13,4 @@ sticky_fn=Disable power_management_beeps=Enable low_battery_beep=Enable sata_mode=AHCI +hybrid_graphics_mode=Integrated Only \ No newline at end of file diff --git a/src/mainboard/lenovo/t400/cmos.layout b/src/mainboard/lenovo/t400/cmos.layout index 0c124585bb..b0131f6d0b 100644 --- a/src/mainboard/lenovo/t400/cmos.layout +++ b/src/mainboard/lenovo/t400/cmos.layout @@ -78,6 +78,7 @@ entries # coreboot config options: northbridge 941 3 e 11 gfx_uma_size +944 2 e 12 hybrid_graphics_mode # coreboot config options: EC 952 8 h 0 volume @@ -132,6 +133,8 @@ enumerations 11 3 128M 11 5 96M 11 6 160M +12 0 Integrated Only +12 1 Discrete Only # ----------------------------------------------------------------- checksums diff --git a/src/mainboard/lenovo/t420/cmos.default b/src/mainboard/lenovo/t420/cmos.default index 1b8e212894..3a82c979dc 100644 --- a/src/mainboard/lenovo/t420/cmos.default +++ b/src/mainboard/lenovo/t420/cmos.default @@ -14,3 +14,4 @@ fn_ctrl_swap=Disable sticky_fn=Disable trackpoint=Enable hyper_threading=Enable +hybrid_graphics_mode=Integrated Only \ No newline at end of file diff --git a/src/mainboard/lenovo/t420/cmos.layout b/src/mainboard/lenovo/t420/cmos.layout index bf0f195425..58a4abeaf6 100644 --- a/src/mainboard/lenovo/t420/cmos.layout +++ b/src/mainboard/lenovo/t420/cmos.layout @@ -77,7 +77,8 @@ entries # coreboot config options: northbridge 432 3 e 11 gfx_uma_size -#435 5 r 0 unused +435 2 e 12 hybrid_graphics_mode +#437 3 r 0 unused 440 8 h 0 volume @@ -135,6 +136,8 @@ enumerations 11 4 160M 11 5 192M 11 6 224M +12 0 Integrated Only +12 1 Discrete Only # ----------------------------------------------------------------- checksums diff --git a/src/mainboard/lenovo/t420s/Kconfig b/src/mainboard/lenovo/t420s/Kconfig index 935e659e0e..feacb51170 100644 --- a/src/mainboard/lenovo/t420s/Kconfig +++ b/src/mainboard/lenovo/t420s/Kconfig @@ -18,6 +18,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15 select SANDYBRIDGE_IVYBRIDGE_LVDS select MAINBOARD_HAS_LPC_TPM + select DRIVERS_LENOVO_HYBRID_GRAPHICS # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE diff --git a/src/mainboard/lenovo/t420s/cmos.default b/src/mainboard/lenovo/t420s/cmos.default index 1b8e212894..3a82c979dc 100644 --- a/src/mainboard/lenovo/t420s/cmos.default +++ b/src/mainboard/lenovo/t420s/cmos.default @@ -14,3 +14,4 @@ fn_ctrl_swap=Disable sticky_fn=Disable trackpoint=Enable hyper_threading=Enable +hybrid_graphics_mode=Integrated Only \ No newline at end of file diff --git a/src/mainboard/lenovo/t420s/cmos.layout b/src/mainboard/lenovo/t420s/cmos.layout index 43628406a1..3521849cde 100644 --- a/src/mainboard/lenovo/t420s/cmos.layout +++ b/src/mainboard/lenovo/t420s/cmos.layout @@ -77,7 +77,8 @@ entries # coreboot config options: northbridge 432 3 e 11 gfx_uma_size -#435 5 r 0 unused +435 2 e 12 hybrid_graphics_mode +#437 3 r 0 unused 440 8 h 0 volume @@ -135,6 +136,8 @@ enumerations 11 4 160M 11 5 192M 11 6 224M +12 0 Integrated Only +12 1 Discrete Only # ----------------------------------------------------------------- checksums diff --git a/src/mainboard/lenovo/t520/Kconfig b/src/mainboard/lenovo/t520/Kconfig index c70581a4fb..ee5dd8163a 100644 --- a/src/mainboard/lenovo/t520/Kconfig +++ b/src/mainboard/lenovo/t520/Kconfig @@ -18,6 +18,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_INT15 select SANDYBRIDGE_IVYBRIDGE_LVDS select MAINBOARD_HAS_LPC_TPM + select DRIVERS_LENOVO_HYBRID_GRAPHICS # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE diff --git a/src/mainboard/lenovo/t520/cmos.default b/src/mainboard/lenovo/t520/cmos.default index 00e8863145..ad7dcf54d3 100644 --- a/src/mainboard/lenovo/t520/cmos.default +++ b/src/mainboard/lenovo/t520/cmos.default @@ -15,3 +15,4 @@ sticky_fn=Disable trackpoint=Enable hyper_threading=Enable backlight=Both +hybrid_graphics_mode=Integrated Only \ No newline at end of file diff --git a/src/mainboard/lenovo/t520/cmos.layout b/src/mainboard/lenovo/t520/cmos.layout index 2cf362956c..044c3107a5 100644 --- a/src/mainboard/lenovo/t520/cmos.layout +++ b/src/mainboard/lenovo/t520/cmos.layout @@ -77,7 +77,8 @@ entries # coreboot config options: northbridge 432 3 e 11 gfx_uma_size -#435 5 r 0 unused +435 2 e 12 hybrid_graphics_mode +#437 3 r 0 unused 440 8 h 0 volume # SandyBridge MRC Scrambler Seed values @@ -134,6 +135,8 @@ enumerations 11 4 160M 11 5 192M 11 6 224M +12 0 Integrated Only +12 1 Discrete Only # ----------------------------------------------------------------- checksums diff --git a/src/mainboard/lenovo/t530/Kconfig b/src/mainboard/lenovo/t530/Kconfig index c1d06256a8..085711b7ab 100644 --- a/src/mainboard/lenovo/t530/Kconfig +++ b/src/mainboard/lenovo/t530/Kconfig @@ -20,6 +20,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_DO_NATIVE_VGA_INIT # default to native vga init select ENABLE_VMX select MAINBOARD_HAS_LPC_TPM + select DRIVERS_LENOVO_HYBRID_GRAPHICS # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE diff --git a/src/mainboard/lenovo/t530/cmos.default b/src/mainboard/lenovo/t530/cmos.default index 00e8863145..ad7dcf54d3 100644 --- a/src/mainboard/lenovo/t530/cmos.default +++ b/src/mainboard/lenovo/t530/cmos.default @@ -15,3 +15,4 @@ sticky_fn=Disable trackpoint=Enable hyper_threading=Enable backlight=Both +hybrid_graphics_mode=Integrated Only \ No newline at end of file diff --git a/src/mainboard/lenovo/t530/cmos.layout b/src/mainboard/lenovo/t530/cmos.layout index e21c197d42..0e28bddb3b 100644 --- a/src/mainboard/lenovo/t530/cmos.layout +++ b/src/mainboard/lenovo/t530/cmos.layout @@ -77,7 +77,8 @@ entries # coreboot config options: northbridge 432 3 e 11 gfx_uma_size -#435 5 r 0 unused +435 2 e 12 hybrid_graphics_mode +#437 3 r 0 unused 440 8 h 0 volume @@ -135,6 +136,9 @@ enumerations 11 4 160M 11 5 192M 11 6 224M +12 0 Integrated Only +12 1 Discrete Only + # ----------------------------------------------------------------- checksums diff --git a/src/southbridge/intel/i82801ix/Kconfig b/src/southbridge/intel/i82801ix/Kconfig index 2822774271..b3e5069b37 100644 --- a/src/southbridge/intel/i82801ix/Kconfig +++ b/src/southbridge/intel/i82801ix/Kconfig @@ -23,6 +23,7 @@ config SOUTHBRIDGE_INTEL_I82801IX select USE_WATCHDOG_ON_BOOT select HAVE_SMI_HANDLER select HAVE_USBDEBUG_OPTIONS + select SOUTHBRIDGE_INTEL_COMMON_GPIO if SOUTHBRIDGE_INTEL_I82801IX