Timothy Pearson (tpearson@raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9316
-gerrit
commit c969f683fc8c3b256bb86319adc67f04eaa60210 Author: Timothy Pearson tpearson@raptorengineeringinc.com Date: Sun Apr 5 17:54:08 2015 -0500
mainboards/lenovo: Copy X200 board to T400 for future expansion
Change-Id: If2d48b84fe7bd7b144e96171e54067891e3c4e2e Signed-off-by: Timothy Pearson tpearson@raptorengineeringinc.com --- src/mainboard/lenovo/t400/Kconfig | 49 ++++++ src/mainboard/lenovo/t400/Kconfig.name | 2 + src/mainboard/lenovo/t400/Makefile.inc | 20 +++ src/mainboard/lenovo/t400/acpi/dock.asl | 73 ++++++++ src/mainboard/lenovo/t400/acpi/ec.asl | 1 + src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl | 86 ++++++++++ src/mainboard/lenovo/t400/acpi/gpe.asl | 29 ++++ src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl | 110 ++++++++++++ src/mainboard/lenovo/t400/acpi/platform.asl | 206 +++++++++++++++++++++++ src/mainboard/lenovo/t400/acpi/superio.asl | 0 src/mainboard/lenovo/t400/acpi_tables.c | 91 ++++++++++ src/mainboard/lenovo/t400/board_info.txt | 5 + src/mainboard/lenovo/t400/cmos.default | 16 ++ src/mainboard/lenovo/t400/cmos.layout | 146 ++++++++++++++++ src/mainboard/lenovo/t400/cstates.c | 41 +++++ src/mainboard/lenovo/t400/devicetree.cb | 203 ++++++++++++++++++++++ src/mainboard/lenovo/t400/dock.c | 65 +++++++ src/mainboard/lenovo/t400/dock.h | 26 +++ src/mainboard/lenovo/t400/dsdt.asl | 59 +++++++ src/mainboard/lenovo/t400/fadt.c | 158 +++++++++++++++++ src/mainboard/lenovo/t400/hda_verb.c | 51 ++++++ src/mainboard/lenovo/t400/mainboard.c | 70 ++++++++ src/mainboard/lenovo/t400/mptable.c | 1 + src/mainboard/lenovo/t400/romstage.c | 205 ++++++++++++++++++++++ src/mainboard/lenovo/t400/smihandler.c | 75 +++++++++ 25 files changed, 1788 insertions(+)
diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig new file mode 100644 index 0000000..392ce692 --- /dev/null +++ b/src/mainboard/lenovo/t400/Kconfig @@ -0,0 +1,49 @@ +if BOARD_LENOVO_T400 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select SYSTEM_TYPE_LAPTOP + select CPU_INTEL_SOCKET_BGA956 + select NORTHBRIDGE_INTEL_GM45 + select SOUTHBRIDGE_INTEL_I82801IX + select EC_LENOVO_PMH7 + select EC_LENOVO_H8 + select NO_UART_ON_SUPERIO + select DRIVERS_ICS_954309 + select BOARD_ROMSIZE_KB_8192 + select DRIVERS_GENERIC_IOAPIC + select HAVE_MP_TABLE + select HAVE_ACPI_TABLES + select EC_ACPI + select HAVE_OPTION_TABLE + select HAVE_CMOS_DEFAULT + select HAVE_ACPI_RESUME + select MAINBOARD_HAS_NATIVE_VGA_INIT + select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG + select INTEL_INT15 + +config MAINBOARD_DIR + string + default lenovo/t400 + +config MAINBOARD_PART_NUMBER + string + default "ThinkPad T400" + +config MMCONF_BASE_ADDRESS + hex + default 0xf0000000 + +config USBDEBUG_HCD_INDEX + int + default 2 + +config MAX_CPUS + int + default 2 + +config CBFS_SIZE + hex + default 0x200000 + +endif # BOARD_LENOVO_T400 diff --git a/src/mainboard/lenovo/t400/Kconfig.name b/src/mainboard/lenovo/t400/Kconfig.name new file mode 100644 index 0000000..56a575e --- /dev/null +++ b/src/mainboard/lenovo/t400/Kconfig.name @@ -0,0 +1,2 @@ +config BOARD_LENOVO_T400 + bool "ThinkPad T400" diff --git a/src/mainboard/lenovo/t400/Makefile.inc b/src/mainboard/lenovo/t400/Makefile.inc new file mode 100644 index 0000000..4eb1216 --- /dev/null +++ b/src/mainboard/lenovo/t400/Makefile.inc @@ -0,0 +1,20 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2012 secunet Security Networks AG +## +## 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. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +ramstage-y += dock.c diff --git a/src/mainboard/lenovo/t400/acpi/dock.asl b/src/mainboard/lenovo/t400/acpi/dock.asl new file mode 100644 index 0000000..605836b --- /dev/null +++ b/src/mainboard/lenovo/t400/acpi/dock.asl @@ -0,0 +1,73 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle svens@stackframe.org + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +Scope (_SB) +{ + Device(DOCK) + { + Name(_HID, "ACPI0003") + Name(_UID, 0x00) + Name(_PCL, Package() { _SB } ) + + Method(_DCK, 1, NotSerialized) + { + if (Arg0) { + /* connect dock */ + Store (1, \GP28) + Store (1, _SB.PCI0.LPCB.EC.DKR1) + } else { + /* disconnect dock */ + Store (0, \GP28) + Store (0, _SB.PCI0.LPCB.EC.DKR1) + } + Xor(Arg0, _SB.PCI0.LPCB.EC.DKR1, Local0) + Return (Local0) + } + + Method(_STA, 0, NotSerialized) + { + Return (_SB.PCI0.LPCB.EC.DKR1) + } + } +} + +Scope(_SB.PCI0.LPCB.EC) +{ + Method(_Q18, 0, NotSerialized) + { + Notify(_SB.DOCK, 3) + } + + Method(_Q45, 0, NotSerialized) + { + Notify(_SB.DOCK, 3) + } + + Method(_Q58, 0, NotSerialized) + { + Notify(_SB.DOCK, 0) + } + + Method(_Q37, 0, NotSerialized) + { + Notify(_SB.DOCK, 0) + } +} diff --git a/src/mainboard/lenovo/t400/acpi/ec.asl b/src/mainboard/lenovo/t400/acpi/ec.asl new file mode 100644 index 0000000..c3569e8 --- /dev/null +++ b/src/mainboard/lenovo/t400/acpi/ec.asl @@ -0,0 +1 @@ +#include <ec/lenovo/h8/acpi/ec.asl> diff --git a/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl b/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl new file mode 100644 index 0000000..83c7762 --- /dev/null +++ b/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl @@ -0,0 +1,86 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* This is board specific information: IRQ routing for the + * gm45 + */ + + +// PCI Interrupt Routing +Method(_PRT) +{ + If (PICM) { + Return (Package() { + // PCIe Graphics 0:1.0 + Package() { 0x0001ffff, 0, 0, 16 }, + // Onboard graphics (IGD) 0:2.0 + Package() { 0x0002ffff, 0, 0, 16 }, + // USB and EHCI 0:1a.x + Package() { 0x001affff, 0, 0, 16 }, + Package() { 0x001affff, 1, 0, 17 }, + Package() { 0x001affff, 2, 0, 18 }, + // High Definition Audio 0:1b.0 + Package() { 0x001bffff, 0, 0, 16 }, + // PCIe Root Ports 0:1c.x + Package() { 0x001cffff, 0, 0, 16 }, + // USB and EHCI 0:1d.x + Package() { 0x001dffff, 0, 0, 16 }, + Package() { 0x001dffff, 1, 0, 17 }, + Package() { 0x001dffff, 2, 0, 18 }, + // FIXME + // CardBus/IEEE1394 0:1e.2, 0:1e.3 + // Package() { 0x001effff, 0, 0, 22 }, + // Package() { 0x001effff, 1, 0, 20 }, + // LPC device 0:1f.0 + Package() { 0x001fffff, 0, 0, 16 }, + Package() { 0x001fffff, 1, 0, 17 }, + Package() { 0x001fffff, 2, 0, 18 } + }) + } Else { + Return (Package() { + // PCIe Graphics 0:1.0 + Package() { 0x0001ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + // Onboard graphics (IGD) 0:2.0 + Package() { 0x0002ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + // USB and EHCI 0:1a.x + Package() { 0x001affff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001affff, 1, _SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x001affff, 2, _SB.PCI0.LPCB.LNKC, 0 }, + // High Definition Audio 0:1b.0 + Package() { 0x001bffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + // PCIe Root Ports 0:1c.x + Package() { 0x001cffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + // USB and EHCI 0:1d.x + Package() { 0x001dffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001dffff, 1, _SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x001dffff, 2, _SB.PCI0.LPCB.LNKC, 0 }, + // FIXME + // CardBus/IEEE1394 0:1e.2, 0:1e.3 + // Package() { 0x001effff, 0, _SB.PCI0.LPCB.LNKG, 0 }, + // Package() { 0x001effff, 1, _SB.PCI0.LPCB.LNKE, 0 }, + // LPC device 0:1f.0 + Package() { 0x001fffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001fffff, 1, _SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x001fffff, 2, _SB.PCI0.LPCB.LNKC, 0 } + }) + } +} + diff --git a/src/mainboard/lenovo/t400/acpi/gpe.asl b/src/mainboard/lenovo/t400/acpi/gpe.asl new file mode 100644 index 0000000..3120caf --- /dev/null +++ b/src/mainboard/lenovo/t400/acpi/gpe.asl @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle svens@stackframe.org + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +Scope (_GPE) +{ + Method(_L18, 0, NotSerialized) + { + /* Read EC register to clear wake status */ + Store(_SB.PCI0.LPCB.EC.WAKE, Local0) + } +} diff --git a/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl b/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl new file mode 100644 index 0000000..325f13c --- /dev/null +++ b/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl @@ -0,0 +1,110 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* This is board specific information: IRQ routing for the + * 0:1e.0 PCI bridge of the ICH9 + */ + +/* TODO: which slots are actually relevant? */ +If (PICM) { + Return (Package() { + // PCI Slot 1 routes ABCD + Package() { 0x0000ffff, 0, 0, 16}, + Package() { 0x0000ffff, 1, 0, 17}, + Package() { 0x0000ffff, 2, 0, 18}, + Package() { 0x0000ffff, 3, 0, 19}, + + // PCI Slot 2 routes BCDA + Package() { 0x0001ffff, 0, 0, 17}, + Package() { 0x0001ffff, 1, 0, 18}, + Package() { 0x0001ffff, 2, 0, 19}, + Package() { 0x0001ffff, 3, 0, 16}, + + // PCI Slot 3 routes CDAB + Package() { 0x0002ffff, 0, 0, 18}, + Package() { 0x0002ffff, 1, 0, 19}, + Package() { 0x0002ffff, 2, 0, 16}, + Package() { 0x0002ffff, 3, 0, 17}, + + // PCI Slot 4 routes ABCD + Package() { 0x0003ffff, 0, 0, 16}, + Package() { 0x0003ffff, 1, 0, 17}, + Package() { 0x0003ffff, 2, 0, 18}, + Package() { 0x0003ffff, 3, 0, 19}, + + // PCI Slot 5 routes ABCD + Package() { 0x0004ffff, 0, 0, 16}, + Package() { 0x0004ffff, 1, 0, 17}, + Package() { 0x0004ffff, 2, 0, 18}, + Package() { 0x0004ffff, 3, 0, 19}, + + // PCI Slot 6 routes BCDA + Package() { 0x0005ffff, 0, 0, 17}, + Package() { 0x0005ffff, 1, 0, 18}, + Package() { 0x0005ffff, 2, 0, 19}, + Package() { 0x0005ffff, 3, 0, 16}, + + // FIXME: what's this supposed to mean? (adopted from ich7) + //Package() { 0x0008ffff, 0, 0, 20}, + }) +} Else { + Return (Package() { + // PCI Slot 1 routes ABCD + Package() { 0x0000ffff, 0, _SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0000ffff, 1, _SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0000ffff, 2, _SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0000ffff, 3, _SB.PCI0.LPCB.LNKD, 0}, + + // PCI Slot 2 routes BCDA + Package() { 0x0001ffff, 0, _SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0001ffff, 1, _SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0001ffff, 2, _SB.PCI0.LPCB.LNKD, 0}, + Package() { 0x0001ffff, 3, _SB.PCI0.LPCB.LNKA, 0}, + + // PCI Slot 3 routes CDAB + Package() { 0x0002ffff, 0, _SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0002ffff, 1, _SB.PCI0.LPCB.LNKD, 0}, + Package() { 0x0002ffff, 2, _SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0002ffff, 3, _SB.PCI0.LPCB.LNKB, 0}, + + // PCI Slot 4 routes ABCD + Package() { 0x0003ffff, 0, _SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0003ffff, 1, _SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0003ffff, 2, _SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0003ffff, 3, _SB.PCI0.LPCB.LNKD, 0}, + + // PCI Slot 5 routes ABCD + Package() { 0x0004ffff, 0, _SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0004ffff, 1, _SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0004ffff, 2, _SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0004ffff, 3, _SB.PCI0.LPCB.LNKD, 0}, + + // PCI Slot 6 routes BCDA + Package() { 0x0005ffff, 0, _SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0005ffff, 1, _SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0005ffff, 2, _SB.PCI0.LPCB.LNKD, 0}, + Package() { 0x0005ffff, 3, _SB.PCI0.LPCB.LNKA, 0}, + + // FIXME + // Package() { 0x0008ffff, 0, _SB.PCI0.LPCB.LNKE, 0}, + }) +} + diff --git a/src/mainboard/lenovo/t400/acpi/platform.asl b/src/mainboard/lenovo/t400/acpi/platform.asl new file mode 100644 index 0000000..2aa556f --- /dev/null +++ b/src/mainboard/lenovo/t400/acpi/platform.asl @@ -0,0 +1,206 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* These come from the dynamically created CPU SSDT */ +External(PDC0) +External(PDC1) + +/* The APM port can be used for generating software SMIs */ + +OperationRegion (APMP, SystemIO, 0xb2, 2) +Field (APMP, ByteAcc, NoLock, Preserve) +{ + APMC, 8, // APM command + APMS, 8 // APM status +} + +/* Port 80 POST */ + +OperationRegion (POST, SystemIO, 0x80, 1) +Field (POST, ByteAcc, Lock, Preserve) +{ + DBG0, 8 +} + +/* SMI I/O Trap */ +Method(TRAP, 1, Serialized) +{ + Store (Arg0, SMIF) // SMI Function + Store (0, TRP0) // Generate trap + Return (SMIF) // Return value of SMI handler +} + +/* The _PIC method is called by the OS to choose between interrupt + * routing via the i8259 interrupt controller or the APIC. + * + * _PIC is called with a parameter of 0 for i8259 configuration and + * with a parameter of 1 for Local Apic/IOAPIC configuration. + */ + +Method(_PIC, 1) +{ + // Remember the OS' IRQ routing choice. + Store(Arg0, PICM) +} + +/* The _PTS method (Prepare To Sleep) is called before the OS is + * entering a sleep state. The sleep state number is passed in Arg0 + */ + +Method(_PTS,1) +{ + // Call a trap so SMI can prepare for Sleep as well. + // TRAP(0x55) +} + +/* The _WAK method is called on system wakeup */ + +Method(_WAK,1) +{ + // CPU specific part + + // Notify PCI Express slots in case a card + // was inserted while a sleep state was active. + + // Are we going to S3? + If (LEqual(Arg0, 3)) { + // .. + } + + // Are we going to S4? + If (LEqual(Arg0, 4)) { + // .. + } + + // TODO: Windows XP SP2 P-State restore + + // TODO: Return Arg0 as second value if S-Arg0 was entered + // before. + + Return(Package(){0,0}) +} + +// Power notification + +External (_PR_.CP00, DeviceObj) +External (_PR_.CP01, DeviceObj) + +Method (PNOT) +{ + If (MPEN) { + If(And(PDC0, 0x08)) { + Notify (_PR_.CP00, 0x80) // _PPC + + If (And(PDC0, 0x10)) { + Sleep(100) + Notify(_PR_.CP00, 0x81) // _CST + } + } + + If(And(PDC1, 0x08)) { + Notify (_PR_.CP01, 0x80) // _PPC + If (And(PDC1, 0x10)) { + Sleep(100) + Notify(_PR_.CP01, 0x81) // _CST + } + } + + } Else { // UP + Notify (_PR_.CP00, 0x80) + Sleep(0x64) + Notify(_PR_.CP00, 0x81) + } + +} + +/* System Bus */ + +Scope(_SB) +{ + /* This method is placed on the top level, so we can make sure it's the + * first executed _INI method. + */ + Method(_INI, 0) + { + /* The DTS data in NVS is probably not up to date. + * Update temperature values and make sure AP thermal + * interrupts can happen + */ + + // TRAP(71) // TODO + + /* Determine the Operating System and save the value in OSYS. + * We have to do this in order to be able to work around + * certain windows bugs. + * + * OSYS value | Operating System + * -----------+------------------ + * 2000 | Windows 2000 + * 2001 | Windows XP(+SP1) + * 2002 | Windows XP SP2 + * 2006 | Windows Vista + * ???? | Windows 7 + */ + + /* Let's assume we're running at least Windows 2000 */ + Store (2000, OSYS) + + If (CondRefOf(_OSI, Local0)) { + /* Linux answers _OSI with "True" for a couple of + * Windows version queries. But unlike Windows it + * needs a Video repost, so let's determine whether + * we're running Linux. + */ + + If (_OSI("Linux")) { + Store (1, LINX) + } + + If (_OSI("Windows 2001")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001 SP1")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001 SP2")) { + Store (2002, OSYS) + } + + If (_OSI("Windows 2006")) { + Store (2006, OSYS) + } + } + + /* And the OS workarounds start right after we know what we're + * running: Windows XP SP1 needs to have C-State coordination + * enabled in SMM. + */ + If (LAnd(LEqual(OSYS, 2001), MPEN)) { + // TRAP(61) // TODO + } + + /* SMM power state and C4-on-C3 settings need to be updated */ + // TRAP(43) // TODO + } +} + diff --git a/src/mainboard/lenovo/t400/acpi/superio.asl b/src/mainboard/lenovo/t400/acpi/superio.asl new file mode 100644 index 0000000..e69de29 diff --git a/src/mainboard/lenovo/t400/acpi_tables.c b/src/mainboard/lenovo/t400/acpi_tables.c new file mode 100644 index 0000000..77491dc --- /dev/null +++ b/src/mainboard/lenovo/t400/acpi_tables.c @@ -0,0 +1,91 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <string.h> +#include <console/console.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/acpi.h> +#include <arch/acpigen.h> +#include <arch/smp/mpspec.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +#include "southbridge/intel/i82801ix/nvs.h" +void acpi_create_gnvs(global_nvs_t *gnvs) +{ + memset((void *)gnvs, 0, sizeof(*gnvs)); + gnvs->apic = 1; + gnvs->mpen = 1; /* Enable Multi Processing */ + + /* Enable both COM ports */ + gnvs->cmap = 0x01; + gnvs->cmbp = 0x01; + + /* IGD Displays */ + gnvs->ndid = 0; /* Will use default of 0x00000400. */ + gnvs->did[0] = 0x80000100; + gnvs->did[1] = 0x80000240; + gnvs->did[2] = 0x80000410; + gnvs->did[3] = 0x80000410; + gnvs->did[4] = 0x00000005; +} + +unsigned long acpi_fill_madt(unsigned long current) +{ + /* Local APICs */ + current = acpi_create_madt_lapics(current); + + /* IOAPIC */ + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + 2, IO_APIC_ADDR, 0); + + /* LAPIC_NMI */ + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 0, + MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 1, MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + + /* INT_SRC_OVR */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE); + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL); + + + return current; +} + +unsigned long acpi_fill_slit(unsigned long current) +{ + // Not implemented + return current; +} + +unsigned long acpi_fill_srat(unsigned long current) +{ + /* No NUMA, no SRAT */ + return current; +} diff --git a/src/mainboard/lenovo/t400/board_info.txt b/src/mainboard/lenovo/t400/board_info.txt new file mode 100644 index 0000000..60496f5 --- /dev/null +++ b/src/mainboard/lenovo/t400/board_info.txt @@ -0,0 +1,5 @@ +Category: laptop +ROM package: SOIC-16 +ROM protocol: SPI +ROM socketed: n +Flashrom support: n diff --git a/src/mainboard/lenovo/t400/cmos.default b/src/mainboard/lenovo/t400/cmos.default new file mode 100644 index 0000000..67b8920 --- /dev/null +++ b/src/mainboard/lenovo/t400/cmos.default @@ -0,0 +1,16 @@ +boot_option=Fallback +last_boot=Fallback +baud_rate=115200 +debug_level=Spew +power_on_after_fail=Disable +volume=0x3 +first_battery=Primary +bluetooth=Enable +wwan=Enable +wlan=Enable +trackpoint=Enable +fn_ctrl_swap=Disable +sticky_fn=Disable +power_management_beeps=Enable +low_battery_beep=Enable +sata_mode=AHCI diff --git a/src/mainboard/lenovo/t400/cmos.layout b/src/mainboard/lenovo/t400/cmos.layout new file mode 100644 index 0000000..fbb2293 --- /dev/null +++ b/src/mainboard/lenovo/t400/cmos.layout @@ -0,0 +1,146 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2007-2008 coresystems GmbH +# 2012 secunet Security Networks AG +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +# ----------------------------------------------------------------- +entries + +# ----------------------------------------------------------------- +# Status Register A +# ----------------------------------------------------------------- +# Status Register B +# ----------------------------------------------------------------- +# Status Register C +#96 4 r 0 status_c_rsvd +#100 1 r 0 uf_flag +#101 1 r 0 af_flag +#102 1 r 0 pf_flag +#103 1 r 0 irqf_flag +# ----------------------------------------------------------------- +# Status Register D +#104 7 r 0 status_d_rsvd +#111 1 r 0 valid_cmos_ram +# ----------------------------------------------------------------- +# Diagnostic Status Register +#112 8 r 0 diag_rsvd1 + +# ----------------------------------------------------------------- +0 120 r 0 reserved_memory +#120 240 r 0 unused + +# ----------------------------------------------------------------- +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +385 1 e 4 last_boot +388 4 r 0 reboot_bits +#390 2 r 0 unused? + +# ----------------------------------------------------------------- +# coreboot config options: console +392 3 e 5 baud_rate +395 4 e 6 debug_level +#399 1 r 0 unused + +# coreboot config options: EC +400 8 h 0 volume + +# coreboot config options: southbridge +408 1 e 10 sata_mode +409 2 e 7 power_on_after_fail + +# coreboot config options: EC +411 1 e 9 first_battery +412 1 e 1 bluetooth +413 1 e 1 wwan +414 1 e 1 wlan +415 1 e 1 trackpoint +416 1 e 1 fn_ctrl_swap +417 1 e 1 sticky_fn + +# coreboot config options: bootloader +418 512 s 0 boot_devices +930 8 h 0 boot_default + +938 1 e 1 power_management_beeps +939 1 e 1 low_battery_beep +940 1 e 1 uwb + +# coreboot config options: northbridge +941 3 e 11 gfx_uma_size + +#944 2 r 0 unused + +# coreboot config options: check sums +984 16 h 0 check_sum +#1000 24 r 0 unused + +# ram initialization internal data +1024 128 r 0 read_training_results + +# ----------------------------------------------------------------- + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 1 Emergency +6 2 Alert +6 3 Critical +6 4 Error +6 5 Warning +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Disable +7 1 Enable +7 2 Keep +8 0 No +8 1 Yes +9 0 Secondary +9 1 Primary +10 0 AHCI +10 1 Compatible +11 0 32M +11 1 48M +11 2 64M +11 3 128M +11 5 96M +11 6 160M + +# ----------------------------------------------------------------- +checksums + +checksum 392 983 984 + diff --git a/src/mainboard/lenovo/t400/cstates.c b/src/mainboard/lenovo/t400/cstates.c new file mode 100644 index 0000000..aacfc31 --- /dev/null +++ b/src/mainboard/lenovo/t400/cstates.c @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 secunet Security Networks AG + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <arch/acpigen.h> +#include <device/device.h> /* fix for i82801ix.h */ +#include <southbridge/intel/i82801ix/i82801ix.h> + +static acpi_cstate_t cst_entries[] = { + { + /* acpi C1 / cpu C1 */ + 1, 0x01, 1000, + { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0, 0 } + }, + { + /* acpi C2 / cpu C2 */ + 2, 0x01, 500, + { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0x10, 0 } + }, +}; + +int get_cst_entries(acpi_cstate_t **entries) +{ + *entries = cst_entries; + return ARRAY_SIZE(cst_entries); +} diff --git a/src/mainboard/lenovo/t400/devicetree.cb b/src/mainboard/lenovo/t400/devicetree.cb new file mode 100644 index 0000000..cc27d25 --- /dev/null +++ b/src/mainboard/lenovo/t400/devicetree.cb @@ -0,0 +1,203 @@ +chip northbridge/intel/gm45 + + register "gfx.use_spread_spectrum_clock" = "1" + register "gfx.lvds_dual_channel" = "0" + register "gfx.link_frequency_270_mhz" = "1" + register "gfx.lvds_num_lanes" = "4" + + device cpu_cluster 0 on + chip cpu/intel/socket_BGA956 + device lapic 0 on end + end + chip cpu/intel/model_1067x + # Magic APIC ID to locate this chip + device lapic 0xACAC off end + + # Enable Super LFM + register "slfm" = "1" + + # Enable C5, C6 + register "c5" = "1" + register "c6" = "1" + end + end + + device domain 0 on + device pci 00.0 on + subsystemid 0x17aa 0x20e0 + end # host bridge + device pci 02.0 on # VGA + subsystemid 0x17aa 0x20e4 + ioapic_irq 2 INTA 0x10 + end + device pci 02.1 on + subsystemid 0x17aa 0x20e4 + end # Display + device pci 03.0 on + subsystemid 0x17aa 0x20e6 + end # ME + device pci 03.1 off end # ME + device pci 03.2 off end # ME + device pci 03.3 off end # ME + chip southbridge/intel/i82801ix + register "pirqa_routing" = "0x0b" + register "pirqb_routing" = "0x0b" + register "pirqc_routing" = "0x0b" + register "pirqd_routing" = "0x0b" + register "pirqe_routing" = "0x80" + register "pirqf_routing" = "0x80" + register "pirqg_routing" = "0x80" + register "pirqh_routing" = "0x80" + + register "gpi8_routing" = "2" + register "gpe0_en" = "0x01000000" + register "gpi1_routing" = "2" + + # Set AHCI mode, enable ports 1 and 2. + register "sata_port_map" = "0x03" + register "sata_clock_request" = "0" + register "sata_traffic_monitor" = "0" + + # Set c-state support + register "c4onc3_enable" = "0" + register "c5_enable" = "1" + register "c6_enable" = "1" + + # Set thermal throttling to 75%. + register "throttle_duty" = "THTL_75_0" + + # Enable PCIe ports 1,2,4 as slots (Mini * PCIe). + register "pcie_slot_implemented" = "0xb" + # Set power limits to 10 * 10^0 watts. + # Maybe we should set less for Mini PCIe. + register "pcie_power_limits" = "{ { 10, 0 }, { 10, 0 }, { 0, 0 }, { 10, 0 }, { 0, 0 }, { 0, 0 } }" + register "pcie_hotplug_map" = "{ 0, 0, 0, 1, 0, 0, 0, 0 }" + + chip drivers/generic/ioapic + register "have_isa_interrupts" = "1" + register "irq_on_fsb" = "1" + register "enable_virtual_wire" = "1" + register "base" = "(void *)0xfec00000" + device ioapic 2 on end + end + + device pci 19.0 on end # LAN + device pci 1a.0 on # UHCI + subsystemid 0x17aa 0x20f0 + ioapic_irq 2 INTA 0x10 + end + device pci 1a.1 on # UHCI + subsystemid 0x17aa 0x20f0 + ioapic_irq 2 INTB 0x11 + end + device pci 1a.2 on # UHCI + subsystemid 0x17aa 0x20f0 + ioapic_irq 2 INTC 0x12 + end + device pci 1a.7 on # EHCI + subsystemid 0x17aa 0x20f1 + ioapic_irq 2 INTC 0x12 + end + device pci 1b.0 on # HD Audio + subsystemid 0x17aa 0x20f2 + ioapic_irq 2 INTA 0x10 + end + device pci 1c.0 on # PCIe Port #1 + subsystemid 0x17aa 0x20f3 # WWAN + ioapic_irq 2 INTA 0x10 + end + device pci 1c.1 on + subsystemid 0x17aa 0x20f3 # WLAN + end # PCIe Port #2 + device pci 1c.2 on + subsystemid 0x17aa 0x20f3 # UWB + end # PCIe Port #3 + device pci 1c.3 on + subsystemid 0x17aa 0x20f3 # Expresscard + end # PCIe Port #4 + device pci 1c.4 off end # PCIe Port #5 + device pci 1c.5 off end # PCIe Port #6 + device pci 1d.0 on # UHCI + subsystemid 0x17aa 0x20f0 + ioapic_irq 2 INTA 0x10 + end + device pci 1d.1 on # UHCI + subsystemid 0x17aa 0x20f0 + ioapic_irq 2 INTB 0x11 + end + device pci 1d.2 on # UHCI + subsystemid 0x17aa 0x20f0 + ioapic_irq 2 INTC 0x12 + end + device pci 1d.7 on # EHCI + subsystemid 0x17aa 0x20f1 + ioapic_irq 2 INTA 0x10 + end + device pci 1e.0 on # PCI + subsystemid 0x17aa 0x20f4 + end + device pci 1f.0 on # LPC bridge + subsystemid 0x17aa 0x20f5 + chip ec/lenovo/pmh7 + device pnp ff.1 on # dummy + end + register "backlight_enable" = "0x01" + register "dock_event_enable" = "0x01" + end + + chip ec/lenovo/h8 + device pnp ff.2 on # dummy + io 0x60 = 0x62 + io 0x62 = 0x66 + io 0x64 = 0x1600 + io 0x66 = 0x1604 + end + + register "config0" = "0xa6" + register "config1" = "0x04" + register "config2" = "0xa0" + register "config3" = "0x01" + + register "beepmask0" = "0xfe" + register "beepmask1" = "0x96" + register "has_power_management_beeps" = "1" + register "has_uwb" = "1" + + register "event2_enable" = "0xff" + register "event3_enable" = "0xff" + register "event4_enable" = "0xf4" + register "event5_enable" = "0x3c" + register "event6_enable" = "0x80" + register "event7_enable" = "0x01" + register "event8_enable" = "0x01" + register "event9_enable" = "0xff" + register "eventa_enable" = "0xff" + register "eventb_enable" = "0xff" + register "eventc_enable" = "0xff" + register "eventd_enable" = "0xff" + end + end + device pci 1f.2 on # SATA/IDE 1 + subsystemid 0x17aa 0x20f8 + ioapic_irq 2 INTB 0x11 + 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 + device pci 1f.5 off end # SATA/IDE 2 + device pci 1f.6 off end # Thermal + end + end +end diff --git a/src/mainboard/lenovo/t400/dock.c b/src/mainboard/lenovo/t400/dock.c new file mode 100644 index 0000000..6f9e953 --- /dev/null +++ b/src/mainboard/lenovo/t400/dock.c @@ -0,0 +1,65 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Sven Schnelle svens@stackframe.org + * Copyright (C) 2013 Vladimir Serbinenko phcoder@gmail.com + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#define __SIMPLE_DEVICE__ +#include <console/console.h> +#include <arch/io.h> +#include <device/device.h> +#include <device/pci.h> +#include <delay.h> +#include "dock.h" +#include "southbridge/intel/i82801ix/i82801ix.h" +#include "ec/lenovo/h8/h8.h" +#include <ec/acpi/ec.h> + +#define LPC_DEV PCI_DEV(0, 0x1f, 0) + +void h8_mainboard_init_dock (void) +{ + if (dock_present()) { + printk(BIOS_DEBUG, "dock is connected\n"); + dock_connect(); + } else + printk(BIOS_DEBUG, "dock is not connected\n"); +} + +void dock_connect(void) +{ + u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc; + ec_set_bit(0x02, 0); + outl(inl(gpiobase + 0x0c) | (1 << 28), gpiobase + 0x0c); +} + +void dock_disconnect(void) +{ + u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc; + ec_clr_bit(0x02, 0); + outl(inl(gpiobase + 0x0c) & ~(1 << 28), gpiobase + 0x0c); +} + +int dock_present(void) +{ + u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc; + u8 st = inb(gpiobase + 0x0c); + + return ((st >> 2) & 7) != 7; +} diff --git a/src/mainboard/lenovo/t400/dock.h b/src/mainboard/lenovo/t400/dock.h new file mode 100644 index 0000000..e888583 --- /dev/null +++ b/src/mainboard/lenovo/t400/dock.h @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Sven Schnelle svens@stackframe.org + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef THINKPAD_X200_DOCK_H +#define THINKPAD_X200_DOCK_H + +extern void dock_connect(void); +extern void dock_disconnect(void); +extern int dock_present(void); +#endif diff --git a/src/mainboard/lenovo/t400/dsdt.asl b/src/mainboard/lenovo/t400/dsdt.asl new file mode 100644 index 0000000..0409e66 --- /dev/null +++ b/src/mainboard/lenovo/t400/dsdt.asl @@ -0,0 +1,59 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#define THINKPAD_EC_GPE 17 +#define BRIGHTNESS_UP _SB.PCI0.GFX0.LCD0.INCB +#define BRIGHTNESS_DOWN _SB.PCI0.GFX0.LCD0.DECB +#define ACPI_VIDEO_DEVICE _SB.PCI0.GFX0 +#define DISPLAY_DEVICE_2_IS_LCD_SCREEN 1 + +DefinitionBlock( + "dsdt.aml", + "DSDT", + 0x03, // DSDT revision: ACPI v3.0 + "COREv4", // OEM id + "COREBOOT", // OEM table id + 0x20090419 // OEM revision +) +{ + // Some generic macros + #include "acpi/platform.asl" + + // global NVS and variables + #include <southbridge/intel/i82801ix/acpi/globalnvs.asl> + + // General Purpose Events + #include "acpi/gpe.asl" + + Scope (_SB) { + Device (PCI0) + { + #include <northbridge/intel/gm45/acpi/gm45.asl> + #include <southbridge/intel/i82801ix/acpi/ich9.asl> + } + } + + /* Chipset specific sleep states */ + #include <southbridge/intel/i82801ix/acpi/sleepstates.asl> + + /* Dock support code */ + #include "acpi/dock.asl" +} diff --git a/src/mainboard/lenovo/t400/fadt.c b/src/mainboard/lenovo/t400/fadt.c new file mode 100644 index 0000000..fef9721 --- /dev/null +++ b/src/mainboard/lenovo/t400/fadt.c @@ -0,0 +1,158 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 coresystems GmbH + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <string.h> +#include <device/pci.h> +#include <arch/acpi.h> +#include <cpu/x86/smm.h> + +void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) +{ + acpi_header_t *header = &(fadt->header); + u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe; + + memset((void *) fadt, 0, sizeof(acpi_fadt_t)); + memcpy(header->signature, "FACP", 4); + header->length = sizeof(acpi_fadt_t); + header->revision = 3; + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->asl_compiler_id, ASLC, 4); + header->asl_compiler_revision = 0; + + fadt->firmware_ctrl = (unsigned long) facs; + fadt->dsdt = (unsigned long) dsdt; + fadt->model = 0x00; + fadt->preferred_pm_profile = PM_MOBILE; + fadt->sci_int = 0x9; + fadt->smi_cmd = APM_CNT; + fadt->acpi_enable = APM_CNT_ACPI_ENABLE; + fadt->acpi_disable = APM_CNT_ACPI_DISABLE; + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = APM_CNT_PST_CONTROL; + + fadt->pm1a_evt_blk = pmbase; + fadt->pm1b_evt_blk = 0x0; + fadt->pm1a_cnt_blk = pmbase + 0x4; + fadt->pm1b_cnt_blk = 0x0; + fadt->pm2_cnt_blk = pmbase + 0x50; + fadt->pm_tmr_blk = pmbase + 0x8; + fadt->gpe0_blk = pmbase + 0x20; + fadt->gpe1_blk = 0; + + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; /* Upper word is reserved and + Linux complains about 32 bit. */ + fadt->pm2_cnt_len = 1; + fadt->pm_tmr_len = 4; + fadt->gpe0_blk_len = 16; + fadt->gpe1_blk_len = 0; + fadt->gpe1_base = 0; + fadt->cst_cnt = APM_CNT_CST_CONTROL; + fadt->p_lvl2_lat = 1; + fadt->p_lvl3_lat = 0x39; + fadt->flush_size = 0; + fadt->flush_stride = 0; + fadt->duty_offset = 1; + fadt->duty_width = 3; + fadt->day_alrm = 0xd; + fadt->mon_alrm = 0x00; + fadt->century = 0x32; + fadt->iapc_boot_arch = 0x00; + fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | + ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE | + ACPI_FADT_DOCKING_SUPPORTED | ACPI_FADT_RESET_REGISTER | + ACPI_FADT_PLATFORM_CLOCK; + + fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->reset_reg.bit_width = 8; + fadt->reset_reg.bit_offset = 0; + fadt->reset_reg.resv = 0; + fadt->reset_reg.addrl = 0xcf9; + fadt->reset_reg.addrh = 0; + fadt->reset_value = 0x06; + + fadt->x_firmware_ctl_l = 0; /* Set X_FIRMWARE_CTRL only if FACS is */ + fadt->x_firmware_ctl_h = 0; /* above 4GB. If X_FIRMWARE_CTRL is set, */ + /* then FIRMWARE_CTRL must be zero. */ + fadt->x_dsdt_l = (unsigned long)dsdt; + fadt->x_dsdt_h = 0; + + fadt->x_pm1a_evt_blk.space_id = 1; + fadt->x_pm1a_evt_blk.bit_width = 32; + fadt->x_pm1a_evt_blk.bit_offset = 0; + fadt->x_pm1a_evt_blk.resv = 0; + fadt->x_pm1a_evt_blk.addrl = pmbase; + fadt->x_pm1a_evt_blk.addrh = 0x0; + + fadt->x_pm1b_evt_blk.space_id = 0; + fadt->x_pm1b_evt_blk.bit_width = 0; + fadt->x_pm1b_evt_blk.bit_offset = 0; + fadt->x_pm1b_evt_blk.resv = 0; + fadt->x_pm1b_evt_blk.addrl = 0x0; + fadt->x_pm1b_evt_blk.addrh = 0x0; + + fadt->x_pm1a_cnt_blk.space_id = 1; + fadt->x_pm1a_cnt_blk.bit_width = 16; /* Upper word is reserved and + Linux complains about 32 bit. */ + fadt->x_pm1a_cnt_blk.bit_offset = 0; + fadt->x_pm1a_cnt_blk.resv = 0; + fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4; + fadt->x_pm1a_cnt_blk.addrh = 0x0; + + fadt->x_pm1b_cnt_blk.space_id = 0; + fadt->x_pm1b_cnt_blk.bit_width = 0; + fadt->x_pm1b_cnt_blk.bit_offset = 0; + fadt->x_pm1b_cnt_blk.resv = 0; + fadt->x_pm1b_cnt_blk.addrl = 0x0; + fadt->x_pm1b_cnt_blk.addrh = 0x0; + + fadt->x_pm2_cnt_blk.space_id = 1; + fadt->x_pm2_cnt_blk.bit_width = 8; + fadt->x_pm2_cnt_blk.bit_offset = 0; + fadt->x_pm2_cnt_blk.resv = 0; + fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50; + fadt->x_pm2_cnt_blk.addrh = 0x0; + + fadt->x_pm_tmr_blk.space_id = 1; + fadt->x_pm_tmr_blk.bit_width = 32; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.resv = 0; + fadt->x_pm_tmr_blk.addrl = pmbase + 0x8; + fadt->x_pm_tmr_blk.addrh = 0x0; + + fadt->x_gpe0_blk.space_id = 1; + fadt->x_gpe0_blk.bit_width = 128; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.resv = 0; + fadt->x_gpe0_blk.addrl = pmbase + 0x20; + fadt->x_gpe0_blk.addrh = 0x0; + + fadt->x_gpe1_blk.space_id = 0; + fadt->x_gpe1_blk.bit_width = 0; + fadt->x_gpe1_blk.bit_offset = 0; + fadt->x_gpe1_blk.resv = 0; + fadt->x_gpe1_blk.addrl = 0x0; + fadt->x_gpe1_blk.addrh = 0x0; + + header->checksum = + acpi_checksum((void *) fadt, header->length); +} diff --git a/src/mainboard/lenovo/t400/hda_verb.c b/src/mainboard/lenovo/t400/hda_verb.c new file mode 100644 index 0000000..c1cd542 --- /dev/null +++ b/src/mainboard/lenovo/t400/hda_verb.c @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * 2012 secunet Security Networks AG + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <device/azalia_device.h> + +const u32 cim_verb_data[] = { + /* coreboot specific header */ + 0x14f15051, // Conexant CX20561 (Hermosa) + 0x17aa20ff, // Subsystem ID + 0x00000008, // Number of entries + + /* Pin Widget Verb Table */ + + AZALIA_PIN_CFG(0, 0x16, 0x042140f0), + AZALIA_PIN_CFG(0, 0x17, 0x61a190f0), + AZALIA_PIN_CFG(0, 0x18, 0x04a190f0), + AZALIA_PIN_CFG(0, 0x19, 0x612140f0), + AZALIA_PIN_CFG(0, 0x1a, 0x901701f0), + AZALIA_PIN_CFG(0, 0x1b, 0x40f001f0), + AZALIA_PIN_CFG(0, 0x1c, 0x40f001f0), + AZALIA_PIN_CFG(0, 0x1d, 0x90a601f0) +}; + +const u32 pc_beep_verbs[] = { + 0x00170500, /* power up codec */ + 0x01470500, /* power up speakers */ + 0x01470100, /* select lout1 (input 0x0) for speakers */ + 0x01470740, /* enable speakers output */ + 0x00b37517, /* unmute beep (mixer's input 0x5), set amp 0dB */ + 0x00c37100, /* unmute mixer in lout1 (lout1 input 0x1) */ + 0x00c3b015, /* set lout1 output volume -15dB */ + 0x0143b000, /* unmute speakers */ +}; +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/lenovo/t400/mainboard.c b/src/mainboard/lenovo/t400/mainboard.c new file mode 100644 index 0000000..5354834 --- /dev/null +++ b/src/mainboard/lenovo/t400/mainboard.c @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 secunet Security Networks AG + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> +#include <stdlib.h> +#include <arch/io.h> +#include <device/device.h> +#include <console/console.h> +#include <drivers/intel/gma/int15.h> +#include <pc80/keyboard.h> +#include <ec/acpi/ec.h> +#include <smbios.h> +#include <string.h> +#include <version.h> +#include <ec/lenovo/pmh7/pmh7.h> +#include <ec/acpi/ec.h> +#include <ec/lenovo/h8/h8.h> + +#include "cstates.c" /* Include it, as the linker won't find + the overloaded weak function in there. */ + +const char *smbios_mainboard_bios_version(void) +{ + static char *s = NULL; + + /* Satisfy thinkpad_acpi. */ + if (strlen(CONFIG_LOCALVERSION)) + return "CBET4000 " CONFIG_LOCALVERSION; + + if (s != NULL) + return s; + s = strconcat("CBET4000 ", coreboot_version); + return s; +} + +static void mainboard_init(device_t dev) +{ + /* This sneaked in here, because X200 SuperIO chip isn't really + connected to anything and hence we don't init it. + */ + pc_keyboard_init(); +} + +static void mainboard_enable(device_t dev) +{ + install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_CENTERING, GMA_INT15_BOOT_DISPLAY_DEFAULT, 2); + + dev->ops->init = mainboard_init; +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; + diff --git a/src/mainboard/lenovo/t400/mptable.c b/src/mainboard/lenovo/t400/mptable.c new file mode 100644 index 0000000..f1839f0 --- /dev/null +++ b/src/mainboard/lenovo/t400/mptable.c @@ -0,0 +1 @@ +/* dummy file */ diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c new file mode 100644 index 0000000..5f50f32 --- /dev/null +++ b/src/mainboard/lenovo/t400/romstage.c @@ -0,0 +1,205 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 secunet Security Networks AG + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +// __PRE_RAM__ means: use "unsigned" for device, not a struct. + +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/tsc.h> +#include <cbmem.h> +#include <lib.h> +#include <pc80/mc146818rtc.h> +#include <console/console.h> +#include <southbridge/intel/i82801ix/i82801ix.h> +#include <northbridge/intel/gm45/gm45.h> +#include <cpu/intel/romstage.h> + +#define LPC_DEV PCI_DEV(0, 0x1f, 0) +#define MCH_DEV PCI_DEV(0, 0, 0) + +static void default_southbridge_gpio_setup(void) +{ + outl(0x197e23fe, DEFAULT_GPIOBASE + GP_IO_USE_SEL); + outl(0xe1a66dfe, DEFAULT_GPIOBASE + GP_IO_SEL); + outl(0xe3faef3f, DEFAULT_GPIOBASE + GP_LVL); + + /* Disable blink [31:0]. */ + outl(0x00000000, DEFAULT_GPIOBASE + GPO_BLINK); + /* Set input inversion [31:0]. */ + outl(0x00000102, DEFAULT_GPIOBASE + GPI_INV); + + /* Enable GPIOs [60:32]. */ + outl(0x030306f6, DEFAULT_GPIOBASE + GP_IO_USE_SEL2); + /* Set input/output mode [60:32] (0 == out, 1 == in). */ + outl(0x1f55f9f1, DEFAULT_GPIOBASE + GP_IO_SEL2); + /* Set gpio levels [60:32]. */ + outl(0x1dffff53, DEFAULT_GPIOBASE + GP_LVL2); +} + +static void early_lpc_setup(void) +{ + /* Set up SuperIO LPC forwards */ + + /* Configure serial IRQs.*/ + pci_write_config8(LPC_DEV, D31F0_SERIRQ_CNTL, 0xd0); + /* Map COMa on 0x3f8, COMb on 0x2f8. */ + pci_write_config16(LPC_DEV, D31F0_LPC_IODEC, 0x0010); + pci_write_config16(LPC_DEV, D31F0_LPC_EN, 0x3f0f); + pci_write_config32(LPC_DEV, D31F0_GEN1_DEC, 0x7c1601); + pci_write_config32(LPC_DEV, D31F0_GEN2_DEC, 0xc15e1); + pci_write_config32(LPC_DEV, D31F0_GEN3_DEC, 0x1c1681); +} + +void main(unsigned long bist) +{ + sysinfo_t sysinfo; + int s3resume = 0; + int cbmem_initted; + u16 reg16; + + /* basic northbridge setup, including MMCONF BAR */ + gm45_early_init(); + + if (bist == 0) + enable_lapic(); + + /* First, run everything needed for console output. */ + i82801ix_early_init(); + early_lpc_setup(); + console_init(); + printk(BIOS_DEBUG, "running main(bist = %lu)\n", bist); + + reg16 = pci_read_config16(LPC_DEV, D31F0_GEN_PMCON_3); + pci_write_config16(LPC_DEV, D31F0_GEN_PMCON_3, reg16); + if ((MCHBAR16(SSKPD_MCHBAR) == 0xCAFE) && !(reg16 & (1 << 9))) { + printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); + gm45_early_reset(); + } + + default_southbridge_gpio_setup(); + + /* ASPM related setting, set early by original BIOS. */ + DMIBAR16(0x204) &= ~(3 << 10); + + /* Check for S3 resume. */ + const u32 pm1_cnt = inl(DEFAULT_PMBASE + 0x04); + if (((pm1_cnt >> 10) & 7) == 5) { +#if CONFIG_HAVE_ACPI_RESUME + printk(BIOS_DEBUG, "Resume from S3 detected.\n"); + s3resume = 1; + /* Clear SLP_TYPE. This will break stage2 but + * we care for that when we get there. + */ + outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + 0x04); +#else + printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n"); +#endif + } + + /* RAM initialization */ + enter_raminit_or_reset(); + memset(&sysinfo, 0, sizeof(sysinfo)); + sysinfo.spd_map[0] = 0x50; + sysinfo.spd_map[2] = 0x51; + sysinfo.enable_igd = 1; + sysinfo.enable_peg = 0; + get_gmch_info(&sysinfo); + raminit(&sysinfo, s3resume); + + const u32 deven = pci_read_config32(MCH_DEV, D0F0_DEVEN); + /* Disable D4F0 (unknown signal controller). */ + pci_write_config32(MCH_DEV, D0F0_DEVEN, deven & ~0x4000); + + init_pm(&sysinfo, 0); + + i82801ix_dmi_setup(); + gm45_late_init(sysinfo.stepping); + i82801ix_dmi_poll_vc1(); + + MCHBAR16(SSKPD_MCHBAR) = 0xCAFE; + /* Enable ethernet. */ + RCBA32(0x3414) &= ~0x20; + + RCBA32(0x0238) = 0x00543210; + RCBA32(0x0240) = 0x009c0b02; + RCBA32(0x0244) = 0x00a20b1a; + RCBA32(0x0248) = 0x005402cb; + RCBA32(0x0254) = 0x00470966; + RCBA32(0x0258) = 0x00470473; + RCBA32(0x0260) = 0x00e90825; + RCBA32(0x0278) = 0x00bc0efb; + RCBA32(0x027c) = 0x00c00f0b; + RCBA32(0x0280) = 0x00670000; + RCBA32(0x0284) = 0x006d0000; + RCBA32(0x0288) = 0x00600b4e; + RCBA32(0x1e10) = 0x00020800; + RCBA32(0x1e18) = 0x36ea00a0; + RCBA32(0x1e80) = 0x000c0801; + RCBA32(0x1e84) = 0x000200f0; + RCBA32(0x2028) = 0x04c8f95e; + RCBA32(0x202c) = 0x055c095e; + RCBA32(0x204c) = 0x001ffc00; + RCBA32(0x2050) = 0x00100fff; + RCBA32(0x2090) = 0x37000000; + RCBA32(0x20b0) = 0x0c000000; + RCBA32(0x20d0) = 0x09000000; + RCBA32(0x20f0) = 0x05000000; + RCBA32(0x3400) = 0x0000001c; + RCBA32(0x3410) = 0x00100461; + RCBA32(0x3414) = 0x00000000; + RCBA32(0x341c) = 0xbf4f001f; + RCBA32(0x3420) = 0x00000000; + RCBA32(0x3430) = 0x00000001; + + init_iommu(); + + /* FIXME: make a proper SMBUS mux support. */ + outl(inl(DEFAULT_GPIOBASE + 0x38) & ~0x400, DEFAULT_GPIOBASE + 0x38); + + cbmem_initted = !cbmem_recovery(s3resume); +#if CONFIG_HAVE_ACPI_RESUME + /* If there is no high memory area, we didn't boot before, so + * this is not a resume. In that case we just create the cbmem toc. + */ + if (s3resume && cbmem_initted) { + void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME); + + /* copy 1MB - 64K to high tables ram_base to prevent memory corruption + * through stage 2. We could keep stuff like stack and heap in high tables + * memory completely, but that's a wonderful clean up task for another + * day. + */ + if (resume_backup_memory) + memcpy(resume_backup_memory, (void *)CONFIG_RAMBASE, HIGH_MEMORY_SAVE); + + /* Magic for S3 resume */ + pci_write_config32(PCI_DEV(0, 0, 0), D0F0_SKPD, SKPAD_ACPI_S3_MAGIC); + } else { + /* Magic for S3 resume */ + pci_write_config32(PCI_DEV(0, 0, 0), D0F0_SKPD, SKPAD_NORMAL_BOOT_MAGIC); + } +#endif + printk(BIOS_SPEW, "exit main()\n"); +} + diff --git a/src/mainboard/lenovo/t400/smihandler.c b/src/mainboard/lenovo/t400/smihandler.c new file mode 100644 index 0000000..baa038e --- /dev/null +++ b/src/mainboard/lenovo/t400/smihandler.c @@ -0,0 +1,75 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <arch/io.h> +#include <console/console.h> +#include <cpu/x86/smm.h> +#include <southbridge/intel/i82801ix/nvs.h> +#include <southbridge/intel/i82801ix/i82801ix.h> +#include <ec/acpi/ec.h> + +/* The southbridge SMI handler checks whether gnvs has a + * valid pointer before calling the trap handler + */ +extern global_nvs_t *gnvs; + +int mainboard_io_trap_handler(int smif) +{ + switch (smif) { + case 0x99: + printk(BIOS_DEBUG, "Sample\n"); + gnvs->smif = 0; + break; + default: + return 0; + } + + /* On success, the IO Trap Handler returns 0 + * On failure, the IO Trap Handler returns a value != 0 + * + * For now, we force the return value to 0 and log all traps to + * see what's going on. + */ + //gnvs->smif = 0; + return 1; +} + +void mainboard_smi_gpi(u32 gpi_sts) +{ + if (gpi_sts & (1 << 1)) { + printk(BIOS_DEBUG, "EC/SMI\n"); + /* TODO */ + } +} + +int mainboard_smi_apmc(u8 apmc) +{ + switch (apmc) { + case APM_CNT_ACPI_ENABLE: + send_ec_command(0x05); /* Set_SMI_Disable */ + send_ec_command(0xaa); /* Set_ACPI_Enable */ + break; + + case APM_CNT_ACPI_DISABLE: + send_ec_command(0x04); /* Set_SMI_Enable */ + send_ec_command(0xab); /* Set_ACPI_Disable */ + break; + } + return 0; +}