summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/lenovo/Kconfig12
-rw-r--r--src/drivers/lenovo/Makefile.inc1
-rw-r--r--src/drivers/lenovo/hybrid_graphics.c114
-rw-r--r--src/mainboard/lenovo/t420/Kconfig1
-rw-r--r--src/mainboard/lenovo/t420/devicetree.cb14
-rw-r--r--src/mainboard/lenovo/t420/romstage.c28
-rw-r--r--src/mainboard/lenovo/t420s/devicetree.cb14
-rw-r--r--src/mainboard/lenovo/t420s/romstage.c32
-rw-r--r--src/mainboard/lenovo/t430/devicetree.cb14
-rw-r--r--src/mainboard/lenovo/t430/romstage.c28
-rw-r--r--src/mainboard/lenovo/t520/devicetree.cb14
-rw-r--r--src/mainboard/lenovo/t520/romstage.c30
-rw-r--r--src/mainboard/lenovo/t530/devicetree.cb14
-rw-r--r--src/mainboard/lenovo/t530/romstage.c31
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)