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>
This commit is contained in:
parent
ce1af8b0bf
commit
384e9aed8c
|
@ -20,7 +20,6 @@
|
||||||
#include <southbridge/intel/common/gpio.h>
|
#include <southbridge/intel/common/gpio.h>
|
||||||
#include <ec/lenovo/pmh7/pmh7.h>
|
#include <ec/lenovo/pmh7/pmh7.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <delay.h>
|
|
||||||
|
|
||||||
#include "hybrid_graphics.h"
|
#include "hybrid_graphics.h"
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
@ -87,18 +86,9 @@ void early_hybrid_graphics(bool *enable_igd, bool *enable_peg)
|
||||||
set_gpio(config->dgpu_power_gpio,
|
set_gpio(config->dgpu_power_gpio,
|
||||||
config->dgpu_power_off_lvl);
|
config->dgpu_power_off_lvl);
|
||||||
} else if (config->has_thinker1) {
|
} else if (config->has_thinker1) {
|
||||||
const size_t power_en = !!(pmh7_register_read(0x50) & 0x08);
|
bool power_en = pmh7_dgpu_power_state();
|
||||||
if (*enable_peg && !power_en) {
|
if (*enable_peg != power_en)
|
||||||
pmh7_register_clear_bit(0x50, 7); // DGPU_RST
|
pmh7_dgpu_power_enable(!power_en);
|
||||||
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
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
printk(BIOS_ERR, "Hybrid graphics:"
|
printk(BIOS_ERR, "Hybrid graphics:"
|
||||||
" FIXME: dGPU power handling not implemented\n");
|
" FIXME: dGPU power handling not implemented\n");
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <device/pnp.h>
|
#include <device/pnp.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <pc80/mc146818rtc.h>
|
#include <pc80/mc146818rtc.h>
|
||||||
|
#include <delay.h>
|
||||||
|
|
||||||
#include "pmh7.h"
|
#include "pmh7.h"
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
@ -64,6 +65,26 @@ void pmh7_ultrabay_power_enable(int onoff)
|
||||||
pmh7_register_set_bit(0x62, 0);
|
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)
|
void pmh7_register_set_bit(int reg, int bit)
|
||||||
{
|
{
|
||||||
char val;
|
char val;
|
||||||
|
|
|
@ -35,5 +35,7 @@ void pmh7_dock_event_enable(int onoff);
|
||||||
void pmh7_touchpad_enable(int onoff);
|
void pmh7_touchpad_enable(int onoff);
|
||||||
void pmh7_ultrabay_power_enable(int onoff);
|
void pmh7_ultrabay_power_enable(int onoff);
|
||||||
void pmh7_trackpoint_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 */
|
#endif /* EC_LENOVO_PMH7_H */
|
||||||
|
|
|
@ -129,6 +129,7 @@ enumerations
|
||||||
11 6 224M
|
11 6 224M
|
||||||
12 0 Integrated Only
|
12 0 Integrated Only
|
||||||
12 1 Discrete Only
|
12 1 Discrete Only
|
||||||
|
12 2 Dual Graphics
|
||||||
13 0 Disable
|
13 0 Disable
|
||||||
13 1 AC and battery
|
13 1 AC and battery
|
||||||
13 2 AC only
|
13 2 AC only
|
||||||
|
|
|
@ -30,6 +30,9 @@ static void hybrid_graphics_init(void)
|
||||||
|
|
||||||
early_hybrid_graphics(&igd, &peg);
|
early_hybrid_graphics(&igd, &peg);
|
||||||
|
|
||||||
|
if (peg && igd)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Hide disabled devices */
|
/* Hide disabled devices */
|
||||||
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
||||||
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
||||||
|
|
|
@ -129,6 +129,7 @@ enumerations
|
||||||
11 6 224M
|
11 6 224M
|
||||||
12 0 Integrated Only
|
12 0 Integrated Only
|
||||||
12 1 Discrete Only
|
12 1 Discrete Only
|
||||||
|
12 2 Dual Graphics
|
||||||
13 0 Disable
|
13 0 Disable
|
||||||
13 1 AC and battery
|
13 1 AC and battery
|
||||||
13 2 AC only
|
13 2 AC only
|
||||||
|
|
|
@ -32,6 +32,9 @@ static void hybrid_graphics_init(void)
|
||||||
|
|
||||||
early_hybrid_graphics(&igd, &peg);
|
early_hybrid_graphics(&igd, &peg);
|
||||||
|
|
||||||
|
if (peg && igd)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Hide disabled devices */
|
/* Hide disabled devices */
|
||||||
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
||||||
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
||||||
|
|
|
@ -128,6 +128,7 @@ enumerations
|
||||||
11 6 224M
|
11 6 224M
|
||||||
12 0 Integrated Only
|
12 0 Integrated Only
|
||||||
12 1 Discrete Only
|
12 1 Discrete Only
|
||||||
|
12 2 Dual Graphics
|
||||||
13 0 Disable
|
13 0 Disable
|
||||||
13 1 AC and battery
|
13 1 AC and battery
|
||||||
13 2 AC only
|
13 2 AC only
|
||||||
|
|
|
@ -30,6 +30,9 @@ static void hybrid_graphics_init(void)
|
||||||
|
|
||||||
early_hybrid_graphics(&igd, &peg);
|
early_hybrid_graphics(&igd, &peg);
|
||||||
|
|
||||||
|
if (peg && igd)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Hide disabled devices */
|
/* Hide disabled devices */
|
||||||
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
||||||
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
||||||
|
|
|
@ -13,4 +13,5 @@ fn_ctrl_swap=Disable
|
||||||
sticky_fn=Disable
|
sticky_fn=Disable
|
||||||
trackpoint=Enable
|
trackpoint=Enable
|
||||||
backlight=Both
|
backlight=Both
|
||||||
|
enable_dual_graphics=Disable
|
||||||
usb_always_on=Disable
|
usb_always_on=Disable
|
||||||
|
|
|
@ -76,7 +76,8 @@ entries
|
||||||
|
|
||||||
# coreboot config options: northbridge
|
# coreboot config options: northbridge
|
||||||
432 3 e 11 gfx_uma_size
|
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
|
440 8 h 0 volume
|
||||||
|
|
||||||
# SandyBridge MRC Scrambler Seed values
|
# SandyBridge MRC Scrambler Seed values
|
||||||
|
|
|
@ -15,12 +15,14 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <option.h>
|
||||||
#include <arch/byteorder.h>
|
#include <arch/byteorder.h>
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <northbridge/intel/sandybridge/raminit_native.h>
|
#include <northbridge/intel/sandybridge/raminit_native.h>
|
||||||
#include <southbridge/intel/bd82x6x/pch.h>
|
#include <southbridge/intel/bd82x6x/pch.h>
|
||||||
|
#include <ec/lenovo/pmh7/pmh7.h>
|
||||||
|
|
||||||
void pch_enable_lpc(void)
|
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) {
|
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)
|
void mainboard_config_superio(void)
|
||||||
|
|
|
@ -42,6 +42,9 @@ static void hybrid_graphics_init(void)
|
||||||
|
|
||||||
early_hybrid_graphics(&igd, &peg);
|
early_hybrid_graphics(&igd, &peg);
|
||||||
|
|
||||||
|
if (peg && igd)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Hide disabled devices */
|
/* Hide disabled devices */
|
||||||
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
||||||
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
||||||
|
|
|
@ -129,6 +129,7 @@ enumerations
|
||||||
11 6 224M
|
11 6 224M
|
||||||
12 0 Integrated Only
|
12 0 Integrated Only
|
||||||
12 1 Discrete Only
|
12 1 Discrete Only
|
||||||
|
12 2 Dual Graphics
|
||||||
13 0 Disable
|
13 0 Disable
|
||||||
13 1 AC and battery
|
13 1 AC and battery
|
||||||
13 2 AC only
|
13 2 AC only
|
||||||
|
|
|
@ -34,6 +34,9 @@ static void hybrid_graphics_init(void)
|
||||||
|
|
||||||
early_hybrid_graphics(&igd, &peg);
|
early_hybrid_graphics(&igd, &peg);
|
||||||
|
|
||||||
|
if (peg && igd)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Hide disabled devices */
|
/* Hide disabled devices */
|
||||||
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);
|
||||||
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);
|
||||||
|
|
Loading…
Reference in New Issue