diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/drivers/lenovo/Kconfig | 12 | ||||
-rw-r--r-- | src/drivers/lenovo/Makefile.inc | 1 | ||||
-rw-r--r-- | src/drivers/lenovo/hybrid_graphics.c | 114 | ||||
-rw-r--r-- | src/mainboard/lenovo/t420/Kconfig | 1 | ||||
-rw-r--r-- | src/mainboard/lenovo/t420/devicetree.cb | 14 | ||||
-rw-r--r-- | src/mainboard/lenovo/t420/romstage.c | 28 | ||||
-rw-r--r-- | src/mainboard/lenovo/t420s/devicetree.cb | 14 | ||||
-rw-r--r-- | src/mainboard/lenovo/t420s/romstage.c | 32 | ||||
-rw-r--r-- | src/mainboard/lenovo/t430/devicetree.cb | 14 | ||||
-rw-r--r-- | src/mainboard/lenovo/t430/romstage.c | 28 | ||||
-rw-r--r-- | src/mainboard/lenovo/t520/devicetree.cb | 14 | ||||
-rw-r--r-- | src/mainboard/lenovo/t520/romstage.c | 30 | ||||
-rw-r--r-- | src/mainboard/lenovo/t530/devicetree.cb | 14 | ||||
-rw-r--r-- | src/mainboard/lenovo/t530/romstage.c | 31 |
14 files changed, 216 insertions, 131 deletions
diff --git a/src/drivers/lenovo/Kconfig b/src/drivers/lenovo/Kconfig index 38b86da3aa..f20f3b2229 100644 --- a/src/drivers/lenovo/Kconfig +++ b/src/drivers/lenovo/Kconfig @@ -27,15 +27,3 @@ 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 66f8594bf9..c50db5b8be 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 802823acdc..0000000000 --- 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/Kconfig b/src/mainboard/lenovo/t420/Kconfig index 784d38a303..c0b475270f 100644 --- a/src/mainboard/lenovo/t420/Kconfig +++ b/src/mainboard/lenovo/t420/Kconfig @@ -22,6 +22,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MAINBOARD_HAS_LPC_TPM select MAINBOARD_HAS_LIBGFXINIT select GFX_GMA_INTERNAL_IS_LVDS + select DRIVERS_LENOVO_HYBRID_GRAPHICS # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE diff --git a/src/mainboard/lenovo/t420/devicetree.cb b/src/mainboard/lenovo/t420/devicetree.cb index deb62b7166..3b4e6ab9b5 100644 --- a/src/mainboard/lenovo/t420/devicetree.cb +++ b/src/mainboard/lenovo/t420/devicetree.cb @@ -162,6 +162,20 @@ chip northbridge/intel/sandybridge 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" + register "has_dgpu_power_gpio" = "0" + + register "has_thinker1" = "1" + 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 94b8d62504..9f178ea741 100644 --- a/src/mainboard/lenovo/t420/romstage.c +++ b/src/mainboard/lenovo/t420/romstage.c @@ -18,6 +18,33 @@ #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) +{ + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + /* Hide disabled devices */ + reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + else + /* Disable IGD VGA decode, no GTT or GFX stolen */ + pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2); + + pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32); +} void pch_enable_lpc(void) { @@ -65,6 +92,7 @@ void mainboard_get_spd(spd_raw_data *spd, bool id_only) 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 3224322654..366d36fe75 100644 --- a/src/mainboard/lenovo/t420s/devicetree.cb +++ b/src/mainboard/lenovo/t420s/devicetree.cb @@ -154,6 +154,20 @@ chip northbridge/intel/sandybridge 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" + register "has_dgpu_power_gpio" = "0" + + register "has_thinker1" = "1" + 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 d7f1c23eff..ad49637e2c 100644 --- a/src/mainboard/lenovo/t420s/romstage.c +++ b/src/mainboard/lenovo/t420s/romstage.c @@ -17,10 +17,36 @@ #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) +{ + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + /* Hide disabled devices */ + reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + else + /* Disable IGD VGA decode, no GTT or GFX stolen */ + pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2); + + pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32); +} void pch_enable_lpc(void) { @@ -65,7 +91,9 @@ void mainboard_get_spd(spd_raw_data *spd, bool id_only) { 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 0a121b70fe..d112ad4e92 100644 --- a/src/mainboard/lenovo/t430/devicetree.cb +++ b/src/mainboard/lenovo/t430/devicetree.cb @@ -150,6 +150,20 @@ chip northbridge/intel/sandybridge 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" + register "has_dgpu_power_gpio" = "0" + + register "has_thinker1" = "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 eb2d29e8cf..eb558ac1b8 100644 --- a/src/mainboard/lenovo/t430/romstage.c +++ b/src/mainboard/lenovo/t430/romstage.c @@ -18,6 +18,33 @@ #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) +{ + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + /* Hide disabled devices */ + reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + else + /* Disable IGD VGA decode, no GTT or GFX stolen */ + pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2); + + pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32); +} void pch_enable_lpc(void) { @@ -57,6 +84,7 @@ const struct southbridge_usb_port mainboard_usb_ports[] = { 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 0065799dd6..6df2644d02 100644 --- a/src/mainboard/lenovo/t520/devicetree.cb +++ b/src/mainboard/lenovo/t520/devicetree.cb @@ -133,6 +133,20 @@ chip northbridge/intel/sandybridge 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" + register "has_dgpu_power_gpio" = "0" + + register "has_thinker1" = "1" + 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 f84bc0de6b..b5ea17cbac 100644 --- a/src/mainboard/lenovo/t520/romstage.c +++ b/src/mainboard/lenovo/t520/romstage.c @@ -35,6 +35,32 @@ #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) +{ + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + /* Hide disabled devices */ + reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + else + /* Disable IGD VGA decode, no GTT or GFX stolen */ + pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2); + + pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32); +} void pch_enable_lpc(void) { @@ -79,7 +105,9 @@ void mainboard_get_spd(spd_raw_data *spd, bool id_only) { 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 2047a78ea8..b784898eec 100644 --- a/src/mainboard/lenovo/t530/devicetree.cb +++ b/src/mainboard/lenovo/t530/devicetree.cb @@ -140,6 +140,20 @@ chip northbridge/intel/sandybridge 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" + register "has_dgpu_power_gpio" = "0" + + register "has_thinker1" = "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 c454ec7c1d..cd2e0e108c 100644 --- a/src/mainboard/lenovo/t530/romstage.c +++ b/src/mainboard/lenovo/t530/romstage.c @@ -22,6 +22,33 @@ #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) +{ + bool peg, igd; + u32 reg32; + + early_hybrid_graphics(&igd, &peg); + + /* Hide disabled devices */ + reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN); + reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); + + if (peg) + reg32 |= DEVEN_PEG10; + + if (igd) + reg32 |= DEVEN_IGD; + else + /* Disable IGD VGA decode, no GTT or GFX stolen */ + pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2); + + pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32); +} void pch_enable_lpc(void) { @@ -66,7 +93,9 @@ void mainboard_get_spd(spd_raw_data *spd, bool id_only) { 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) |