From 5919ba42ed0ce5b1b13717514698444232c6036c Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 26 Dec 2015 08:35:08 +0100 Subject: drivers/lenovo: Add hybrid graphics driver Add a universal hybrid graphics driver compatible with all supported lenovo devices. Hybrid graphics allows to connect the display panel to either of one GPUs. As there are only two GPUs one GPIO needs to be toggled. In case the discrete GPU is activated the panel is routed to it. On deactivation the panel is routed to the integrated GPU. On lenovo laptops the dGPU is always connected to PEG10 and it is save to disable the PEG slot on dGPU deactivation. Use common gpio.c for southbridge I82801IX. Tested on Lenovo T520 using Nvidia NVS 5200m. Removed Lenovo T430s from the list of supported devices, as the T430s only supports "muxless Optimus". Depends on change id: Iccc6d254bafb927b6470704cec7c9dd7528e2c68 Ibb54c03fd83a529d1ceccfb2c33190e7d42224d8 I8bd981c4696c174152cf41caefa6c083650d283a Iaf0c2f941f2625a5547f9cba79da1b173da6f295 I994114734fa931926c34ed04305cddfbeb429b62 Change-Id: I9b80b31a7749bdf893ed3b772a6505c9f29a56d1 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/12896 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth Reviewed-by: Philipp Deppenwiese --- src/drivers/lenovo/Kconfig | 13 ++++ src/drivers/lenovo/Makefile.inc | 1 + src/drivers/lenovo/hybrid_graphics.c | 125 ++++++++++++++++++++++++++++++++ src/mainboard/lenovo/t400/Kconfig | 1 + src/mainboard/lenovo/t400/cmos.default | 1 + src/mainboard/lenovo/t400/cmos.layout | 3 + src/mainboard/lenovo/t420/cmos.default | 1 + src/mainboard/lenovo/t420/cmos.layout | 5 +- src/mainboard/lenovo/t420s/Kconfig | 1 + src/mainboard/lenovo/t420s/cmos.default | 1 + src/mainboard/lenovo/t420s/cmos.layout | 5 +- src/mainboard/lenovo/t520/Kconfig | 1 + src/mainboard/lenovo/t520/cmos.default | 1 + src/mainboard/lenovo/t520/cmos.layout | 5 +- src/mainboard/lenovo/t530/Kconfig | 1 + src/mainboard/lenovo/t530/cmos.default | 1 + src/mainboard/lenovo/t530/cmos.layout | 6 +- src/southbridge/intel/i82801ix/Kconfig | 1 + 18 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 src/drivers/lenovo/hybrid_graphics.c 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 -- cgit v1.2.3