mb/lenovo/r500: Add mainboard

Tested:
- Ethernet NIC
- Wifi RFKill
- USB
- LVDS, VGA with libgfxinit
- Booting with dock attached (COM1)
- Keyboard, trackpoint
- SeaBIOS 1.12
- S3 resume
- Tested in descriptor mode, with vendor FD and ME
- Add VBT to ACPI OPregion

Untested:
- SATA (likely works)
- Trackpad (my cable is broken, likely works)
- Displayport (likely works)
- Descriptorless mode
- DVD drive
- Extra battery
- model with ATI GPU

Does not work:
- Dock hotplug
- Quad core CPU (hangs during AP init, probably needs hardware mod)
- Hotplugging the expresscard slot (works with 'echo 1 | sudo tee
/sys/bus/pci/rescan')

TODO:
- proper dock support
- documentation

note: This board was hard to flash, I had to desolder the flash.

TESTED: on a R500 with an Intel iGPU, SeaBIOS 1.12, Debian 9,
Linux 4.9 from USB

Change-Id: I9e129b2e916acdf2b8534fa9d8d2cfc8f64f5815
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/28644
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
This commit is contained in:
Arthur Heymans 2018-09-16 18:55:28 +02:00 committed by Patrick Georgi
parent 86fa2792b9
commit 03180212b7
14 changed files with 261 additions and 40 deletions

View File

@ -1,5 +1,5 @@
if BOARD_LENOVO_T400 || BOARD_LENOVO_T500 || BOARD_LENOVO_R400 \ if BOARD_LENOVO_T400 || BOARD_LENOVO_T500 || BOARD_LENOVO_R400 \
|| BOARD_LENOVO_W500 || BOARD_LENOVO_W500 || BOARD_LENOVO_R500
config BOARD_SPECIFIC_OPTIONS config BOARD_SPECIFIC_OPTIONS
def_bool y def_bool y
@ -11,7 +11,8 @@ config BOARD_SPECIFIC_OPTIONS
select EC_LENOVO_H8 select EC_LENOVO_H8
select H8_HAS_BAT_TRESHOLDS_IMPL select H8_HAS_BAT_TRESHOLDS_IMPL
select H8_DOCK_EARLY_INIT select H8_DOCK_EARLY_INIT
select BOARD_ROMSIZE_KB_8192 select BOARD_ROMSIZE_KB_8192 if !BOARD_LENOVO_R500
select BOARD_ROMSIZE_KB_4096 if BOARD_LENOVO_R500
select DRIVERS_GENERIC_IOAPIC select DRIVERS_GENERIC_IOAPIC
select HAVE_MP_TABLE select HAVE_MP_TABLE
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES
@ -24,20 +25,31 @@ config BOARD_SPECIFIC_OPTIONS
select SUPERIO_NSC_PC87384 select SUPERIO_NSC_PC87384
select DRIVERS_LENOVO_HYBRID_GRAPHICS select DRIVERS_LENOVO_HYBRID_GRAPHICS
select MAINBOARD_HAS_LIBGFXINIT select MAINBOARD_HAS_LIBGFXINIT
select MAINBOARD_USES_IFD_GBE_REGION select MAINBOARD_USES_IFD_GBE_REGION if !BOARD_LENOVO_R500
select INTEL_GMA_HAVE_VBT select INTEL_GMA_HAVE_VBT
config MAINBOARD_DIR config MAINBOARD_DIR
string string
default lenovo/t400 default lenovo/t400
config VARIANT_DIR
string
default "t400" if BOARD_LENOVO_T400 || BOARD_LENOVO_T500 \
|| BOARD_LENOVO_R400 || BOARD_LENOVO_W500
default "r500" if BOARD_LENOVO_R500
config MAINBOARD_PART_NUMBER config MAINBOARD_PART_NUMBER
string string
default "ThinkPad T400" if BOARD_LENOVO_T400 default "ThinkPad T400" if BOARD_LENOVO_T400
default "ThinkPad T500" if BOARD_LENOVO_T500 default "ThinkPad T500" if BOARD_LENOVO_T500
default "ThinkPad R400" if BOARD_LENOVO_R400 default "ThinkPad R400" if BOARD_LENOVO_R400
default "ThinkPad R500" if BOARD_LENOVO_R500
default "ThinkPad W500" if BOARD_LENOVO_W500 default "ThinkPad W500" if BOARD_LENOVO_W500
config OVERRIDE_DEVICETREE
string
default "variants/$(CONFIG_VARIANT_DIR)/overridetree.cb"
config USBDEBUG_HCD_INDEX config USBDEBUG_HCD_INDEX
int int
default 2 default 2
@ -54,4 +66,7 @@ config ONBOARD_VGA_IS_PRIMARY
bool bool
default y default y
config INTEL_GMA_VBT_FILE
default "src/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/data.vbt"
endif # BOARD_LENOVO_T400 endif # BOARD_LENOVO_T400

View File

@ -7,5 +7,8 @@ config BOARD_LENOVO_T500
config BOARD_LENOVO_R400 config BOARD_LENOVO_R400
bool "ThinkPad R400" bool "ThinkPad R400"
config BOARD_LENOVO_R500
bool "ThinkPad R500"
config BOARD_LENOVO_W500 config BOARD_LENOVO_W500
bool "ThinkPad W500" bool "ThinkPad W500"

View File

@ -13,9 +13,10 @@
## GNU General Public License for more details. ## GNU General Public License for more details.
## ##
romstage-y += gpio.c
romstage-y += dock.c romstage-y += dock.c
subdirs-y += variants/$(VARIANT_DIR)/
ramstage-y += dock.c ramstage-y += dock.c
ramstage-y += cstates.c ramstage-y += cstates.c
ramstage-y += blc.c ramstage-y += blc.c

View File

@ -211,46 +211,12 @@ chip northbridge/intel/gm45
io 0x60 = 0x1620 io 0x60 = 0x1620
end end
end 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" = "22"
register "panel_integrated_lvl" = "0"
register "has_backlight_gpio" = "1"
register "backlight_gpio" = "19"
register "backlight_integrated_lvl" = "0"
register "has_dgpu_power_gpio" = "1"
register "dgpu_power_gpio" = "49"
register "dgpu_power_off_lvl" = "0"
register "has_thinker1" = "0"
end
end end
device pci 1f.2 on # SATA/IDE 1 device pci 1f.2 on # SATA/IDE 1
subsystemid 0x17aa 0x20f8 subsystemid 0x17aa 0x20f8
ioapic_irq 2 INTB 0x11 ioapic_irq 2 INTB 0x11
end end
device pci 1f.3 on # SMBus device pci 1f.3 on end # SMBus
subsystemid 0x17aa 0x20f9
ioapic_irq 2 INTC 0x12
# eeprom, 8 virtual devices, same chip
chip drivers/i2c/at24rf08c
device i2c 54 on end
device i2c 55 on end
device i2c 56 on end
device i2c 57 on end
device i2c 5c on end
device i2c 5d on end
device i2c 5e on end
device i2c 5f on end
end
end
device pci 1f.5 off end # SATA/IDE 2 device pci 1f.5 off end # SATA/IDE 2
device pci 1f.6 off end # Thermal device pci 1f.6 off end # Thermal
end end

View File

@ -18,6 +18,7 @@
#define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB #define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB
#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB
#define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0
#define EC_LENOVO_H8_ME_WORKAROUND 1
#include <arch/acpi.h> #include <arch/acpi.h>
DefinitionBlock( DefinitionBlock(

View File

@ -75,7 +75,21 @@ void mb_pre_raminit_setup(sysinfo_t *sysinfo)
else else
dock_info(); dock_info();
hybrid_graphics_init(sysinfo); if (CONFIG(BOARD_LENOVO_R500)) {
int use_integrated = get_gpio(21);
printk(BIOS_DEBUG, "R500 variant found with an %s GPU\n",
use_integrated ? "integrated" : "discrete");
if (use_integrated) {
sysinfo->enable_igd = 1;
sysinfo->enable_peg = 0;
} else {
sysinfo->enable_igd = 0;
sysinfo->enable_peg = 1;
}
} else {
hybrid_graphics_init(sysinfo);
}
} }
void mb_post_raminit_setup(void) void mb_post_raminit_setup(void)

View File

@ -0,0 +1 @@
romstage-y += gpio.c

Binary file not shown.

View File

@ -0,0 +1,131 @@
/*
* This file is part of the coreboot project.
*
* 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 <southbridge/intel/common/gpio.h>
static const struct pch_gpio_set1 pch_gpio_set1_mode = {
.gpio1 = GPIO_MODE_GPIO,
.gpio2 = GPIO_MODE_GPIO,
.gpio3 = GPIO_MODE_GPIO,
.gpio4 = GPIO_MODE_GPIO,
.gpio5 = GPIO_MODE_GPIO,
.gpio6 = GPIO_MODE_GPIO,
.gpio7 = GPIO_MODE_GPIO,
.gpio8 = GPIO_MODE_GPIO,
.gpio9 = GPIO_MODE_GPIO,
.gpio12 = GPIO_MODE_GPIO,
.gpio13 = GPIO_MODE_GPIO,
.gpio17 = GPIO_MODE_GPIO,
.gpio18 = GPIO_MODE_GPIO,
.gpio19 = GPIO_MODE_GPIO,
.gpio20 = GPIO_MODE_GPIO,
.gpio21 = GPIO_MODE_GPIO,
.gpio22 = GPIO_MODE_GPIO,
.gpio24 = GPIO_MODE_GPIO,
.gpio27 = GPIO_MODE_GPIO,
.gpio28 = GPIO_MODE_GPIO,
};
static const struct pch_gpio_set1 pch_gpio_set1_direction = {
.gpio1 = GPIO_DIR_INPUT,
.gpio2 = GPIO_DIR_INPUT,
.gpio3 = GPIO_DIR_INPUT,
.gpio4 = GPIO_DIR_INPUT,
.gpio5 = GPIO_DIR_INPUT,
.gpio6 = GPIO_DIR_INPUT,
.gpio7 = GPIO_DIR_INPUT,
.gpio8 = GPIO_DIR_INPUT,
.gpio9 = GPIO_DIR_OUTPUT,
.gpio12 = GPIO_DIR_OUTPUT,
.gpio13 = GPIO_DIR_INPUT,
.gpio17 = GPIO_DIR_INPUT,
.gpio18 = GPIO_DIR_OUTPUT,
.gpio19 = GPIO_DIR_INPUT,
.gpio20 = GPIO_DIR_OUTPUT,
.gpio21 = GPIO_DIR_INPUT,
.gpio22 = GPIO_DIR_INPUT,
.gpio24 = GPIO_DIR_OUTPUT,
.gpio27 = GPIO_DIR_OUTPUT,
.gpio28 = GPIO_DIR_OUTPUT,
};
static const struct pch_gpio_set1 pch_gpio_set1_level = {
.gpio9 = GPIO_LEVEL_HIGH,
.gpio12 = GPIO_LEVEL_LOW,
.gpio18 = GPIO_LEVEL_HIGH,
.gpio20 = GPIO_LEVEL_HIGH,
.gpio24 = GPIO_LEVEL_HIGH,
.gpio27 = GPIO_LEVEL_LOW,
.gpio28 = GPIO_LEVEL_LOW,
};
static const struct pch_gpio_set1 pch_gpio_set1_invert = {
.gpio1 = GPIO_INVERT,
.gpio8 = GPIO_INVERT,
};
static const struct pch_gpio_set1 pch_gpio_set1_blink = {
};
static const struct pch_gpio_set2 pch_gpio_set2_mode = {
.gpio33 = GPIO_MODE_GPIO,
.gpio34 = GPIO_MODE_GPIO,
.gpio36 = GPIO_MODE_GPIO,
.gpio37 = GPIO_MODE_GPIO,
.gpio38 = GPIO_MODE_GPIO,
.gpio39 = GPIO_MODE_GPIO,
.gpio41 = GPIO_MODE_GPIO,
.gpio42 = GPIO_MODE_GPIO,
.gpio48 = GPIO_MODE_GPIO,
.gpio49 = GPIO_MODE_GPIO,
.gpio56 = GPIO_MODE_GPIO,
.gpio57 = GPIO_MODE_GPIO,
};
static const struct pch_gpio_set2 pch_gpio_set2_direction = {
.gpio33 = GPIO_DIR_OUTPUT,
.gpio34 = GPIO_DIR_OUTPUT,
.gpio36 = GPIO_DIR_INPUT,
.gpio37 = GPIO_DIR_INPUT,
.gpio38 = GPIO_DIR_INPUT,
.gpio39 = GPIO_DIR_INPUT,
.gpio41 = GPIO_DIR_OUTPUT,
.gpio42 = GPIO_DIR_OUTPUT,
.gpio48 = GPIO_DIR_INPUT,
.gpio49 = GPIO_DIR_OUTPUT,
.gpio56 = GPIO_DIR_INPUT,
.gpio57 = GPIO_DIR_INPUT,
};
static const struct pch_gpio_set2 pch_gpio_set2_level = {
.gpio33 = GPIO_LEVEL_HIGH,
.gpio34 = GPIO_LEVEL_LOW,
.gpio41 = GPIO_LEVEL_HIGH,
.gpio42 = GPIO_LEVEL_HIGH,
.gpio49 = GPIO_LEVEL_HIGH,
};
const struct pch_gpio_map mainboard_gpio_map = {
.set1 = {
.mode = &pch_gpio_set1_mode,
.direction = &pch_gpio_set1_direction,
.level = &pch_gpio_set1_level,
.blink = &pch_gpio_set1_blink,
.invert = &pch_gpio_set1_invert,
},
.set2 = {
.mode = &pch_gpio_set2_mode,
.direction = &pch_gpio_set2_direction,
.level = &pch_gpio_set2_level,
},
};

View File

@ -0,0 +1,45 @@
chip northbridge/intel/gm45
device domain 0 on
device pci 03.0 off end
chip southbridge/intel/i82801ix
register "sata_clock_request" = "1"
# Enable PCIe ports 1,2,4,5,6 as slots (Mini * PCIe).
register "pcie_slot_implemented" = "0x3b"
# Set power limits to 10 * 10^0 watts.
# Maybe we should set less for Mini PCIe.
register "pcie_power_limits" = "{ { 41, 0 }, { 41, 0 }, { 0, 0 }, { 41, 0 }, { 41, 0 }, { 41, 0 } }"
register "pcie_hotplug_map" = "{ 0, 0, 0, 0, 0, 1, 0, 0 }"
device pci 19.0 off end # LAN
device pci 1c.2 off end # PCIe Port #3
device pci 1c.4 on # PCIe Port #5
subsystemid 0x17aa 0x20f3
end
device pci 1c.5 on # PCIe Port #6
subsystemid 0x17aa 0x20f3 # Ethernet NIC
end
device pci 1f.0 on # LPC bridge
subsystemid 0x17aa 0x20f5
chip ec/lenovo/h8
register "config1" = "0x05"
register "config3" = "0x40"
register "event6_enable" = "0x87"
register "event7_enable" = "0x09"
register "event8_enable" = "0x5b"
register "eventa_enable" = "0x83"
register "eventb_enable" = "0x00"
end
end
device pci 1f.3 on # SMBus
subsystemid 0x17aa 0x20f9
ioapic_irq 2 INTC 0x12
# eeprom, 4 virtual devices, same chip
chip drivers/i2c/at24rf08c
device i2c 54 on end
device i2c 55 on end
device i2c 56 on end
device i2c 57 on end
end
end
end
end
end

View File

@ -0,0 +1 @@
romstage-y += gpio.c

View File

@ -0,0 +1,43 @@
chip northbridge/intel/gm45
device domain 0 on
chip southbridge/intel/i82801ix
device pci 1f.0 on # LPC bridge
subsystemid 0x17aa 0x20f5
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" = "22"
register "panel_integrated_lvl" = "0"
register "has_backlight_gpio" = "1"
register "backlight_gpio" = "19"
register "backlight_integrated_lvl" = "0"
register "has_dgpu_power_gpio" = "1"
register "dgpu_power_gpio" = "49"
register "dgpu_power_off_lvl" = "0"
register "has_thinker1" = "0"
end
end
device pci 1f.3 on # SMBus
subsystemid 0x17aa 0x20f9
ioapic_irq 2 INTC 0x12
# eeprom, 8 virtual devices, same chip
chip drivers/i2c/at24rf08c
device i2c 54 on end
device i2c 55 on end
device i2c 56 on end
device i2c 57 on end
device i2c 5c on end
device i2c 5d on end
device i2c 5e on end
device i2c 5f on end
end
end
end
end
end