summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Zinoviev <me@ch1p.com>2018-08-30 02:18:48 +0300
committerPatrick Georgi <pgeorgi@google.com>2018-09-05 10:04:20 +0000
commit384e9aed8c477922c960e2cbd429bd3a15b371de (patch)
treefd46db5b106df1a26c6e6fd5e93d1e1569924733
parentce1af8b0bf8569ad2d0ebc7bc7b0babe1579c7f2 (diff)
mb/lenovo: Support dual graphics for xx20/xx30 ThinkPads
Add CMOS option that allows to use both integrated and discrete GPU. Tested on ThinkPad W530. Change-Id: I8842fef0fa1235eb91abf6b7e655ed4d8598adc7 Signed-off-by: Evgeny Zinoviev <me@ch1p.com> Reviewed-on: https://review.coreboot.org/28393 Reviewed-by: Patrick Rudolph <siro@das-labor.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/drivers/lenovo/hybrid_graphics/romstage.c16
-rw-r--r--src/ec/lenovo/pmh7/pmh7.c21
-rw-r--r--src/ec/lenovo/pmh7/pmh7.h2
-rw-r--r--src/mainboard/lenovo/t420/cmos.layout1
-rw-r--r--src/mainboard/lenovo/t420/romstage.c3
-rw-r--r--src/mainboard/lenovo/t420s/cmos.layout1
-rw-r--r--src/mainboard/lenovo/t420s/romstage.c3
-rw-r--r--src/mainboard/lenovo/t430/cmos.layout1
-rw-r--r--src/mainboard/lenovo/t430/romstage.c3
-rw-r--r--src/mainboard/lenovo/t430s/cmos.default1
-rw-r--r--src/mainboard/lenovo/t430s/cmos.layout3
-rw-r--r--src/mainboard/lenovo/t430s/romstage.c18
-rw-r--r--src/mainboard/lenovo/t520/romstage.c3
-rw-r--r--src/mainboard/lenovo/t530/cmos.layout1
-rw-r--r--src/mainboard/lenovo/t530/romstage.c3
15 files changed, 66 insertions, 14 deletions
diff --git a/src/drivers/lenovo/hybrid_graphics/romstage.c b/src/drivers/lenovo/hybrid_graphics/romstage.c
index 8814916872..35cb384301 100644
--- a/src/drivers/lenovo/hybrid_graphics/romstage.c
+++ b/src/drivers/lenovo/hybrid_graphics/romstage.c
@@ -20,7 +20,6 @@
#include <southbridge/intel/common/gpio.h>
#include <ec/lenovo/pmh7/pmh7.h>
#include <console/console.h>
-#include <delay.h>
#include "hybrid_graphics.h"
#include "chip.h"
@@ -87,18 +86,9 @@ void early_hybrid_graphics(bool *enable_igd, bool *enable_peg)
set_gpio(config->dgpu_power_gpio,
config->dgpu_power_off_lvl);
} else if (config->has_thinker1) {
- const size_t power_en = !!(pmh7_register_read(0x50) & 0x08);
- if (*enable_peg && !power_en) {
- pmh7_register_clear_bit(0x50, 7); // DGPU_RST
- pmh7_register_set_bit(0x50, 3); // DGPU_PWR
- mdelay(10);
- pmh7_register_set_bit(0x50, 7); // DGPU_RST
- mdelay(50);
- } else if (!*enable_peg && power_en) {
- pmh7_register_clear_bit(0x50, 7); // DGPU_RST
- udelay(100);
- pmh7_register_clear_bit(0x50, 3); // DGPU_PWR
- }
+ bool power_en = pmh7_dgpu_power_state();
+ if (*enable_peg != power_en)
+ pmh7_dgpu_power_enable(!power_en);
} else {
printk(BIOS_ERR, "Hybrid graphics:"
" FIXME: dGPU power handling not implemented\n");
diff --git a/src/ec/lenovo/pmh7/pmh7.c b/src/ec/lenovo/pmh7/pmh7.c
index b160fd0bc1..f7b798be33 100644
--- a/src/ec/lenovo/pmh7/pmh7.c
+++ b/src/ec/lenovo/pmh7/pmh7.c
@@ -19,6 +19,7 @@
#include <device/pnp.h>
#include <stdlib.h>
#include <pc80/mc146818rtc.h>
+#include <delay.h>
#include "pmh7.h"
#include "chip.h"
@@ -64,6 +65,26 @@ void pmh7_ultrabay_power_enable(int onoff)
pmh7_register_set_bit(0x62, 0);
}
+void pmh7_dgpu_power_enable(int onoff)
+{
+ if (onoff) {
+ pmh7_register_clear_bit(0x50, 7); // DGPU_RST
+ pmh7_register_set_bit(0x50, 3); // DGPU_PWR
+ mdelay(10);
+ pmh7_register_set_bit(0x50, 7); // DGPU_RST
+ mdelay(50);
+ } else {
+ pmh7_register_clear_bit(0x50, 7); // DGPU_RST
+ udelay(100);
+ pmh7_register_clear_bit(0x50, 3); // DGPU_PWR
+ }
+}
+
+bool pmh7_dgpu_power_state(void)
+{
+ return (pmh7_register_read(0x50) & 0x08) == 8;
+}
+
void pmh7_register_set_bit(int reg, int bit)
{
char val;
diff --git a/src/ec/lenovo/pmh7/pmh7.h b/src/ec/lenovo/pmh7/pmh7.h
index d486ceb041..a641fce0fa 100644
--- a/src/ec/lenovo/pmh7/pmh7.h
+++ b/src/ec/lenovo/pmh7/pmh7.h
@@ -35,5 +35,7 @@ void pmh7_dock_event_enable(int onoff);
void pmh7_touchpad_enable(int onoff);
void pmh7_ultrabay_power_enable(int onoff);
void pmh7_trackpoint_enable(int onoff);
+void pmh7_dgpu_power_enable(int onoff);
+bool pmh7_dgpu_power_state(void);
#endif /* EC_LENOVO_PMH7_H */
diff --git a/src/mainboard/lenovo/t420/cmos.layout b/src/mainboard/lenovo/t420/cmos.layout
index 5a9e570c3f..f55c2037d5 100644
--- a/src/mainboard/lenovo/t420/cmos.layout
+++ b/src/mainboard/lenovo/t420/cmos.layout
@@ -129,6 +129,7 @@ enumerations
11 6 224M
12 0 Integrated Only
12 1 Discrete Only
+12 2 Dual Graphics
13 0 Disable
13 1 AC and battery
13 2 AC only
diff --git a/src/mainboard/lenovo/t420/romstage.c b/src/mainboard/lenovo/t420/romstage.c
index 36e83a3c72..bef256200e 100644
--- a/src/mainboard/lenovo/t420/romstage.c
+++ b/src/mainboard/lenovo/t420/romstage.c
@@ -30,6 +30,9 @@ static void hybrid_graphics_init(void)
early_hybrid_graphics(&igd, &peg);
+ if (peg && igd)
+ return;
+
/* Hide disabled devices */
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
diff --git a/src/mainboard/lenovo/t420s/cmos.layout b/src/mainboard/lenovo/t420s/cmos.layout
index f395c0c808..2be55f67c7 100644
--- a/src/mainboard/lenovo/t420s/cmos.layout
+++ b/src/mainboard/lenovo/t420s/cmos.layout
@@ -129,6 +129,7 @@ enumerations
11 6 224M
12 0 Integrated Only
12 1 Discrete Only
+12 2 Dual Graphics
13 0 Disable
13 1 AC and battery
13 2 AC only
diff --git a/src/mainboard/lenovo/t420s/romstage.c b/src/mainboard/lenovo/t420s/romstage.c
index 55011cf2e2..be8052c3ba 100644
--- a/src/mainboard/lenovo/t420s/romstage.c
+++ b/src/mainboard/lenovo/t420s/romstage.c
@@ -32,6 +32,9 @@ static void hybrid_graphics_init(void)
early_hybrid_graphics(&igd, &peg);
+ if (peg && igd)
+ return;
+
/* Hide disabled devices */
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
diff --git a/src/mainboard/lenovo/t430/cmos.layout b/src/mainboard/lenovo/t430/cmos.layout
index 2b687c296b..1b50e7fa74 100644
--- a/src/mainboard/lenovo/t430/cmos.layout
+++ b/src/mainboard/lenovo/t430/cmos.layout
@@ -128,6 +128,7 @@ enumerations
11 6 224M
12 0 Integrated Only
12 1 Discrete Only
+12 2 Dual Graphics
13 0 Disable
13 1 AC and battery
13 2 AC only
diff --git a/src/mainboard/lenovo/t430/romstage.c b/src/mainboard/lenovo/t430/romstage.c
index 94679df0a6..90d0886af1 100644
--- a/src/mainboard/lenovo/t430/romstage.c
+++ b/src/mainboard/lenovo/t430/romstage.c
@@ -30,6 +30,9 @@ static void hybrid_graphics_init(void)
early_hybrid_graphics(&igd, &peg);
+ if (peg && igd)
+ return;
+
/* Hide disabled devices */
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
diff --git a/src/mainboard/lenovo/t430s/cmos.default b/src/mainboard/lenovo/t430s/cmos.default
index 979f132863..3e1f130ce4 100644
--- a/src/mainboard/lenovo/t430s/cmos.default
+++ b/src/mainboard/lenovo/t430s/cmos.default
@@ -13,4 +13,5 @@ fn_ctrl_swap=Disable
sticky_fn=Disable
trackpoint=Enable
backlight=Both
+enable_dual_graphics=Disable
usb_always_on=Disable
diff --git a/src/mainboard/lenovo/t430s/cmos.layout b/src/mainboard/lenovo/t430s/cmos.layout
index 538e624350..97d97ed349 100644
--- a/src/mainboard/lenovo/t430s/cmos.layout
+++ b/src/mainboard/lenovo/t430s/cmos.layout
@@ -76,7 +76,8 @@ entries
# coreboot config options: northbridge
432 3 e 11 gfx_uma_size
-#435 5 r 0 unused
+435 1 e 1 enable_dual_graphics
+#436 4 r 0 unused
440 8 h 0 volume
# SandyBridge MRC Scrambler Seed values
diff --git a/src/mainboard/lenovo/t430s/romstage.c b/src/mainboard/lenovo/t430s/romstage.c
index 3f6d9f2836..633ba3f142 100644
--- a/src/mainboard/lenovo/t430s/romstage.c
+++ b/src/mainboard/lenovo/t430s/romstage.c
@@ -15,12 +15,14 @@
* GNU General Public License for more details.
*/
+#include <option.h>
#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 <ec/lenovo/pmh7/pmh7.h>
void pch_enable_lpc(void)
{
@@ -64,6 +66,22 @@ void mainboard_get_spd(spd_raw_data *spd, bool id_only) {
}
void mainboard_early_init(int s3resume) {
+ u8 enable_peg;
+ if (get_option(&enable_peg, "enable_dual_graphics") != CB_SUCCESS)
+ enable_peg = 0;
+
+ bool power_en = pmh7_dgpu_power_state();
+
+ if (enable_peg != power_en)
+ pmh7_dgpu_power_enable(!power_en);
+
+ if (!enable_peg) {
+ // Hide disabled dGPU device
+ u32 reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
+ reg32 &= ~DEVEN_PEG10;
+
+ pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32);
+ }
}
void mainboard_config_superio(void)
diff --git a/src/mainboard/lenovo/t520/romstage.c b/src/mainboard/lenovo/t520/romstage.c
index 328ae37abd..4fcd651b6a 100644
--- a/src/mainboard/lenovo/t520/romstage.c
+++ b/src/mainboard/lenovo/t520/romstage.c
@@ -42,6 +42,9 @@ static void hybrid_graphics_init(void)
early_hybrid_graphics(&igd, &peg);
+ if (peg && igd)
+ return;
+
/* Hide disabled devices */
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
diff --git a/src/mainboard/lenovo/t530/cmos.layout b/src/mainboard/lenovo/t530/cmos.layout
index 9a099f5b3a..3400a4d4c7 100644
--- a/src/mainboard/lenovo/t530/cmos.layout
+++ b/src/mainboard/lenovo/t530/cmos.layout
@@ -129,6 +129,7 @@ enumerations
11 6 224M
12 0 Integrated Only
12 1 Discrete Only
+12 2 Dual Graphics
13 0 Disable
13 1 AC and battery
13 2 AC only
diff --git a/src/mainboard/lenovo/t530/romstage.c b/src/mainboard/lenovo/t530/romstage.c
index ba7a229a0d..88e07c1712 100644
--- a/src/mainboard/lenovo/t530/romstage.c
+++ b/src/mainboard/lenovo/t530/romstage.c
@@ -34,6 +34,9 @@ static void hybrid_graphics_init(void)
early_hybrid_graphics(&igd, &peg);
+ if (peg && igd)
+ return;
+
/* Hide disabled devices */
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);