Vladimir Serbinenko (phcoder@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3462
-gerrit
commit 63a81ce736e15904ff6dbb5795876981f4c5678c Author: Vladimir Serbinenko phcoder@gmail.com Date: Thu Nov 14 19:11:19 2013 +0100
Lenovo X201 support (mobo part)
Lenovo X201 is a recent laptop by lenovo based on nehalem chipset and representing good value for both geeks and less-geeks alike. This commit allows to run it without factory BIOS.
Was extensively tested on my X201.
Issues - S3 doesn't work - No expresscard hotplug - Sometimes Gnome starts to think that battery is 10 time larger than real Information from sysfs remains correct. - On my X201 there due to recent hardware failure thermal management doesn't work with either coreboot or original BIOS. Before this hardware fault happened thermal management worked under coreboot as well.
Requires descriptor.bin (bytes 0-0x2fff from original ROM) and me.bin (bytes 0x3000-0x500000 from original ROM) in 3rdparty/mainboard/lenovo/x201.
Change-Id: I4f82e7c33b899a165693d6fec4eeb932b2c627bd Signed-off-by: Vladimir Serbinenko phcoder@gmail.com --- src/mainboard/lenovo/Kconfig | 6 + src/mainboard/lenovo/x201/Kconfig | 59 +++ src/mainboard/lenovo/x201/Makefile.inc | 24 + src/mainboard/lenovo/x201/acpi/dock.asl | 82 ++++ src/mainboard/lenovo/x201/acpi/ec.asl | 26 ++ src/mainboard/lenovo/x201/acpi/gpe.asl | 30 ++ src/mainboard/lenovo/x201/acpi/mainboard.asl | 0 .../lenovo/x201/acpi/nehalem_pci_irqs.asl | 86 ++++ src/mainboard/lenovo/x201/acpi/platform.asl | 184 ++++++++ src/mainboard/lenovo/x201/acpi/superio.asl | 51 +++ src/mainboard/lenovo/x201/acpi/video.asl | 111 +++++ src/mainboard/lenovo/x201/acpi_tables.c | 283 ++++++++++++ src/mainboard/lenovo/x201/cmos.default | 11 + src/mainboard/lenovo/x201/cmos.layout | 137 ++++++ src/mainboard/lenovo/x201/devicetree.cb | 148 ++++++ src/mainboard/lenovo/x201/dock.c | 62 +++ src/mainboard/lenovo/x201/dock.h | 28 ++ src/mainboard/lenovo/x201/dsdt.asl | 94 ++++ src/mainboard/lenovo/x201/fadt.c | 160 +++++++ src/mainboard/lenovo/x201/gma.c | 508 +++++++++++++++++++++ src/mainboard/lenovo/x201/gpio.h | 416 +++++++++++++++++ src/mainboard/lenovo/x201/irq_tables.c | 61 +++ src/mainboard/lenovo/x201/mainboard.c | 282 ++++++++++++ src/mainboard/lenovo/x201/mptable.c | 82 ++++ src/mainboard/lenovo/x201/romstage.c | 413 +++++++++++++++++ src/mainboard/lenovo/x201/smi.h | 27 ++ src/mainboard/lenovo/x201/smihandler.c | 210 +++++++++ 27 files changed, 3581 insertions(+)
diff --git a/src/mainboard/lenovo/Kconfig b/src/mainboard/lenovo/Kconfig index 8ee2778..bae1e53 100644 --- a/src/mainboard/lenovo/Kconfig +++ b/src/mainboard/lenovo/Kconfig @@ -12,6 +12,11 @@ config BOARD_LENOVO_X60 ThinkPad X60s (Model 1702, 1703) ThinkPad X60 (Model 1709)
+config BOARD_LENOVO_X201 + bool "ThinkPad X201" + help + Lenovo X201 laptop. + config BOARD_LENOVO_T60 bool "ThinkPad T60 / T60p" help @@ -23,6 +28,7 @@ config BOARD_LENOVO_T60 endchoice
source "src/mainboard/lenovo/x60/Kconfig" +source "src/mainboard/lenovo/x201/Kconfig" source "src/mainboard/lenovo/t60/Kconfig"
config MAINBOARD_VENDOR diff --git a/src/mainboard/lenovo/x201/Kconfig b/src/mainboard/lenovo/x201/Kconfig new file mode 100644 index 0000000..c0b8117 --- /dev/null +++ b/src/mainboard/lenovo/x201/Kconfig @@ -0,0 +1,59 @@ +if BOARD_LENOVO_X201 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select ARCH_X86 + select NORTHBRIDGE_INTEL_NEHALEM + select SOUTHBRIDGE_INTEL_IBEXPEAK + select SOUTHBRIDGE_RICOH_RL5C476 + select SUPERIO_NSC_PC87382 + select SUPERIO_NSC_PC87392 + select EC_LENOVO_PMH7 + select EC_LENOVO_H8 + select DRIVERS_ICS_954309 + select HAVE_OPTION_TABLE + select HAVE_CMOS_DEFAULT + select HAVE_PIRQ_TABLE + select HAVE_MP_TABLE + select MMCONF_SUPPORT + select GFXUMA + select BOARD_ROMSIZE_KB_8192 + select CHANNEL_XOR_RANDOMIZATION + select HAVE_ACPI_TABLES + select HAVE_ACPI_RESUME + select EARLY_CBMEM_INIT + select HAVE_USBDEBUG_OPTIONS + +config MAINBOARD_DIR + string + default lenovo/x201 + +config MAINBOARD_PART_NUMBER + string + default "3626EN1" + +config MAINBOARD_VERSION + string + default "ThinkPad X201" + +config MAINBOARD_VENDOR + string + default "LENOVO" + +config MMCONF_BASE_ADDRESS + hex + default 0xe0000000 + +config IRQ_SLOT_COUNT + int + default 18 + +config MAX_CPUS + int + default 4 + +config CPU_ADDR_BITS + int + default 36 + +endif diff --git a/src/mainboard/lenovo/x201/Makefile.inc b/src/mainboard/lenovo/x201/Makefile.inc new file mode 100644 index 0000000..9055c9e --- /dev/null +++ b/src/mainboard/lenovo/x201/Makefile.inc @@ -0,0 +1,24 @@ +## +## 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 +## + +smm-$(CONFIG_HAVE_SMI_HANDLER) += dock.c +romstage-y += dock.c +ramstage-y += dock.c +ramstage-y += gma.c + diff --git a/src/mainboard/lenovo/x201/acpi/dock.asl b/src/mainboard/lenovo/x201/acpi/dock.asl new file mode 100644 index 0000000..732ee90 --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi/dock.asl @@ -0,0 +1,82 @@ +/* + * 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 + */ + +#include "smi.h" + +Scope (_SB) +{ + Device(DOCK) + { + Name(_HID, "ACPI0003") + Name(_UID, 0x00) + Name(_PCL, Package() { _SB } ) + + Method(_DCK, 1, NotSerialized) + { + if (Arg0) { + /* connect dock */ + Store (1, _SB.PCI0.LPCB.EC.DKR1) + Store (1, _SB.PCI0.LPCB.EC.DKR2) + Store (1, _SB.PCI0.LPCB.EC.DKR3) + } else { + /* disconnect dock */ + Store (0, _SB.PCI0.LPCB.EC.DKR1) + Store (0, _SB.PCI0.LPCB.EC.DKR2) + Store (0, _SB.PCI0.LPCB.EC.DKR3) + } + 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(_Q50, 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/x201/acpi/ec.asl b/src/mainboard/lenovo/x201/acpi/ec.asl new file mode 100644 index 0000000..4b3e72c --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi/ec.asl @@ -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 + */ + +#include <ec/lenovo/h8/acpi/ec.asl> + +Scope(_SB.PCI0.LPCB.EC) +{ +} diff --git a/src/mainboard/lenovo/x201/acpi/gpe.asl b/src/mainboard/lenovo/x201/acpi/gpe.asl new file mode 100644 index 0000000..b160b50 --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi/gpe.asl @@ -0,0 +1,30 @@ +/* + * 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 + */ + +#include "smi.h" +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/x201/acpi/mainboard.asl b/src/mainboard/lenovo/x201/acpi/mainboard.asl new file mode 100644 index 0000000..e69de29 diff --git a/src/mainboard/lenovo/x201/acpi/nehalem_pci_irqs.asl b/src/mainboard/lenovo/x201/acpi/nehalem_pci_irqs.asl new file mode 100644 index 0000000..3e9e1b3 --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi/nehalem_pci_irqs.asl @@ -0,0 +1,86 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Vladimir Serbinenko + * + * 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. + */ + + +// PCI Interrupt Routing +Method(_PRT) +{ + If (PICM) { + Return (Package() { + Package() { 0x0001ffff, 0, 0, 0x10 }, + Package() { 0x0002ffff, 0, 0, 0x10 }, // VGA + Package() { 0x0003ffff, 0, 0, 0x10 }, + Package() { 0x0016ffff, 0, 0, 0x10 }, // ME + Package() { 0x0016ffff, 1, 0, 0x11 }, // ME + Package() { 0x0016ffff, 2, 0, 0x12 }, // ME + Package() { 0x0016ffff, 3, 0, 0x13 }, // ME + Package() { 0x0019ffff, 0, 0, 0x14 }, // Ethernet + Package() { 0x001affff, 0, 0, 0x14 }, // USB + Package() { 0x001affff, 1, 0, 0x15 }, // USB + Package() { 0x001affff, 2, 0, 0x16 }, // USB + Package() { 0x001affff, 3, 0, 0x17 }, // USB + Package() { 0x001bffff, 1, 0, 0x11 }, // Audio + Package() { 0x001cffff, 0, 0, 0x14 }, // PCI bridge + Package() { 0x001cffff, 1, 0, 0x15 }, // PCI bridge + Package() { 0x001cffff, 2, 0, 0x16 }, // PCI bridge + Package() { 0x001cffff, 3, 0, 0x17 }, // PCI bridge + Package() { 0x001dffff, 0, 0, 0x10 }, // USB + Package() { 0x001dffff, 1, 0, 0x11 }, // USB + Package() { 0x001dffff, 2, 0, 0x12 }, // USB + Package() { 0x001dffff, 3, 0, 0x13 }, // USB + Package() { 0x001fffff, 0, 0, 0x17 }, // LPC + Package() { 0x001fffff, 1, 0, 0x10 }, // IDE + Package() { 0x001fffff, 2, 0, 0x11 }, // SATA + Package() { 0x001fffff, 3, 0, 0x13 } // SMBUS + }) + } Else { + Return (Package() { + Package() { 0x0001ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x0002ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, // VGA + Package() { 0x0003ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x0016ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, // ME + Package() { 0x0016ffff, 1, _SB.PCI0.LPCB.LNKB, 0 }, // ME + Package() { 0x0016ffff, 2, _SB.PCI0.LPCB.LNKC, 0 }, // ME + Package() { 0x0016ffff, 3, _SB.PCI0.LPCB.LNKD, 0 }, // ME + Package() { 0x0019ffff, 0, _SB.PCI0.LPCB.LNKE, 0 }, // Ethernet + Package() { 0x001affff, 0, _SB.PCI0.LPCB.LNKE, 0 }, // USB + Package() { 0x001affff, 1, _SB.PCI0.LPCB.LNKF, 0 }, // USB + Package() { 0x001affff, 2, _SB.PCI0.LPCB.LNKG, 0 }, // USB + Package() { 0x001affff, 3, _SB.PCI0.LPCB.LNKH, 0 }, // USB + Package() { 0x001bffff, 1, _SB.PCI0.LPCB.LNKB, 0 }, // Audio + Package() { 0x001cffff, 0, _SB.PCI0.LPCB.LNKE, 0 }, // PCI + Package() { 0x001cffff, 1, _SB.PCI0.LPCB.LNKF, 0 }, // PCI + Package() { 0x001cffff, 2, _SB.PCI0.LPCB.LNKG, 0 }, // PCI + Package() { 0x001cffff, 3, _SB.PCI0.LPCB.LNKH, 0 }, // PCI + Package() { 0x001dffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, // USB + Package() { 0x001dffff, 1, _SB.PCI0.LPCB.LNKB, 0 }, // USB + Package() { 0x001dffff, 2, _SB.PCI0.LPCB.LNKC, 0 }, // USB + Package() { 0x001dffff, 3, _SB.PCI0.LPCB.LNKD, 0 }, // USB + Package() { 0x001fffff, 0, _SB.PCI0.LPCB.LNKH, 0 }, // LPC + Package() { 0x001fffff, 1, _SB.PCI0.LPCB.LNKA, 0 }, // IDE + Package() { 0x001fffff, 2, _SB.PCI0.LPCB.LNKB, 0 }, // SATA + Package() { 0x001fffff, 3, _SB.PCI0.LPCB.LNKD, 0 } // SMBus + }) + } +} diff --git a/src/mainboard/lenovo/x201/acpi/platform.asl b/src/mainboard/lenovo/x201/acpi/platform.asl new file mode 100644 index 0000000..ac45401 --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi/platform.asl @@ -0,0 +1,184 @@ +/* + * 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) +{ + _SB.PCI0.LPCB.EC.MUTE(1) + _SB.PCI0.LPCB.EC.USBP(0) +} + +/* 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 + + Return(Package(){0,0}) +} + +/* 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)) { + 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 2001.1")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001.1 SP1")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2006")) { + Store (2006, OSYS) + } + + If (_OSI("Windows 2006.1")) { + Store (2006, OSYS) + } + + If (_OSI("Windows 2006 SP1")) { + Store (2006, OSYS) + } + + If (_OSI("Windows 2009")) { + Store (2009, OSYS) + } + + If (_OSI("Windows 2012")) { + Store (2012, 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/x201/acpi/superio.asl b/src/mainboard/lenovo/x201/acpi/superio.asl new file mode 100644 index 0000000..9b201b0 --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi/superio.asl @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2013 Vladimir Serbinenko + * + * 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 + */ + Device (PS2K) // Keyboard + { + Name(_HID, EISAID("PNP0303")) + Name(_CID, EISAID("PNP030B")) + + Name(_CRS, ResourceTemplate() + { + IO (Decode16, 0x60, 0x60, 0x01, 0x01) + IO (Decode16, 0x64, 0x64, 0x01, 0x01) + IRQ (Edge, ActiveHigh, Exclusive) { 0x01 } // IRQ 1 + }) + + Method (_STA, 0) + { + Return (0xf) + } + } + + Device (PS2M) // Mouse + { + Name(_HID, EISAID("PNP0F13")) + Name(_CRS, ResourceTemplate() + { + IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12 + }) + + Method(_STA, 0) + { + Return (0xf) + } + } diff --git a/src/mainboard/lenovo/x201/acpi/video.asl b/src/mainboard/lenovo/x201/acpi/video.asl new file mode 100644 index 0000000..6d20a70 --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi/video.asl @@ -0,0 +1,111 @@ +/* + * 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 + */ + +#include "smi.h" + +Scope (_SB.PCI0.GFX0) +{ + Device (LCD0) + { + Name (_ADR, 0x0400) + Name (BRCT, 0) + + Name (BRIG, Package (0x12) + { + 0x61, + 0x61, + 0x2, + 0x4, + 0x5, + 0x7, + 0x9, + 0xb, + 0xd, + 0x11, + 0x14, + 0x17, + 0x1c, + 0x20, + 0x27, + 0x31, + 0x41, + 0x61, + }) + + Method (_BCL, 0, NotSerialized) + { + Store (1, BRCT) + Return (BRIG) + } + + Method (_BCM, 1, NotSerialized) + { + Store (ShiftLeft (Arg0, 4), ^^BCLV) + Store (0x80000000, ^^CR1) + Store (0x061a061a, ^^CR2) + } + Method (_BQC, 0, NotSerialized) + { + Store (^^BCLV, Local0) + ShiftRight (Local0, 4, Local0) + Return (Local0) + } + + Method(BRID, 1, NotSerialized) + { + Store (Match (BRIG, MEQ, Arg0, MTR, Zero, 2), Local0) + If (LEqual (Local0, Ones)) + { + Return (0x11) + } + Return (Local0) + } + + /* Using Notify is the right way. But Windows doesn't handle it well. + So use both method in a way to avoid double action. */ + Method (DECB, 0, NotSerialized) + { + If (BRCT) { + Notify (LCD0, 0x87) + } Else { + Store (BRID (_BQC ()), Local0) + If (LNotEqual (Local0, 2)) + { + Decrement (Local0) + } + _BCM (DerefOf (Index (BRIG, Local0))) + } + } + Method (INCB, 0, NotSerialized) + { + If (BRCT) { + Notify (LCD0, 0x86) + } Else { + Store (BRID (_BQC ()), Local0) + If (LNotEqual (Local0, 0x11)) + { + Increment (Local0) + } + _BCM (DerefOf (Index (BRIG, Local0))) + } + } + } +} diff --git a/src/mainboard/lenovo/x201/acpi_tables.c b/src/mainboard/lenovo/x201/acpi_tables.c new file mode 100644 index 0000000..37fd12a --- /dev/null +++ b/src/mainboard/lenovo/x201/acpi_tables.c @@ -0,0 +1,283 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * 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 + */ + +#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> + +extern const unsigned char AmlCode[]; +#if CONFIG_HAVE_ACPI_SLIC +unsigned long acpi_create_slic(unsigned long current); +#endif + +#include "southbridge/intel/i82801gx/nvs.h" +static 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 = 3; + 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, + 1, IO_APIC_ADDR, 0); + + /* INT_SRC_OVR */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, + MP_IRQ_POLARITY_DEFAULT | + MP_IRQ_TRIGGER_DEFAULT); + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 9, 9, + MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_LEVEL); + + /* 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); + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 2, MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 3, MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + return current; +} + +unsigned long acpi_fill_ssdt_generator(unsigned long current, + const char *oem_table_id) +{ + generate_cpu_entries(); + return (unsigned long)(acpigen_get_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; +} + +void smm_setup_structures(void *gnvs, void *tcg, void *smi1); + +#define ALIGN_CURRENT current = (ALIGN(current, 16)) +unsigned long write_acpi_tables(unsigned long start) +{ + unsigned long current; + int i; + acpi_rsdp_t *rsdp; + acpi_rsdt_t *rsdt; + acpi_xsdt_t *xsdt; + acpi_hpet_t *hpet; + acpi_madt_t *madt; + acpi_mcfg_t *mcfg; + acpi_fadt_t *fadt; + acpi_facs_t *facs; +#if CONFIG_HAVE_ACPI_SLIC + acpi_header_t *slic; +#endif + acpi_header_t *ssdt; + acpi_header_t *dsdt; + void *gnvs; + + current = start; + + /* Align ACPI tables to 16byte */ + ALIGN_CURRENT; + + printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); + + /* We need at least an RSDP and an RSDT Table */ + rsdp = (acpi_rsdp_t *) current; + current += sizeof(acpi_rsdp_t); + ALIGN_CURRENT; + rsdt = (acpi_rsdt_t *) current; + current += sizeof(acpi_rsdt_t); + ALIGN_CURRENT; + xsdt = (acpi_xsdt_t *) current; + current += sizeof(acpi_xsdt_t); + ALIGN_CURRENT; + + /* clear all table memory */ + memset((void *)start, 0, current - start); + + acpi_write_rsdp(rsdp, rsdt, xsdt); + acpi_write_rsdt(rsdt); + acpi_write_xsdt(xsdt); + + /* + * We explicitly add these tables later on: + */ + printk(BIOS_DEBUG, "ACPI: * HPET\n"); + + hpet = (acpi_hpet_t *) current; + current += sizeof(acpi_hpet_t); + ALIGN_CURRENT; + acpi_create_hpet(hpet); + acpi_add_table(rsdp, hpet); + + /* If we want to use HPET Timers Linux wants an MADT */ + printk(BIOS_DEBUG, "ACPI: * MADT\n"); + + madt = (acpi_madt_t *) current; + acpi_create_madt(madt); + current += madt->header.length; + ALIGN_CURRENT; + acpi_add_table(rsdp, madt); + + printk(BIOS_DEBUG, "ACPI: * MCFG\n"); + mcfg = (acpi_mcfg_t *) current; + acpi_create_mcfg(mcfg); + current += mcfg->header.length; + ALIGN_CURRENT; + acpi_add_table(rsdp, mcfg); + + printk(BIOS_DEBUG, "ACPI: * FACS\n"); + facs = (acpi_facs_t *) current; + current += sizeof(acpi_facs_t); + ALIGN_CURRENT; + acpi_create_facs(facs); + + dsdt = (acpi_header_t *) current; + memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); + current += dsdt->length; + memcpy(dsdt, &AmlCode, dsdt->length); + + /* Fix up global NVS region for SMI handler. The GNVS region lives + * in the (high) table area. The low memory map looks like this: + * + * 0x00000000 - 0x000003ff Real Mode IVT + * 0x00000020 - 0x0000019c Low MP Table (XXX conflict?) + * 0x00000400 - 0x000004ff BDA (somewhat unused) + * 0x00000500 - 0x0000052f Moved GDT + * 0x00000530 - 0x00000b64 coreboot table + * 0x0007c000 - 0x0007dfff OS boot sector (unused?) + * 0x0007e000 - 0x0007ffff free to use (so no good for acpi+smi) + * 0x00080000 - 0x0009fbff usable ram + * 0x0009fc00 - 0x0009ffff EBDA (unused?) + * 0x000a0000 - 0x000bffff VGA memory + * 0x000c0000 - 0x000cffff VGA option rom + * 0x000d0000 - 0x000dffff free for other option roms? + * 0x000e0000 - 0x000fffff SeaBIOS? (conflict with low tables:) + * 0x000f0000 - 0x000f03ff PIRQ table + * 0x000f0400 - 0x000f66?? ACPI tables + * 0x000f66?? - 0x000f???? DMI tables + */ + + ALIGN_CURRENT; + + /* Pack GNVS into the ACPI table area */ + for (i = 0; i < dsdt->length; i++) { + if (*(u32 *) (((u32) dsdt) + i) == 0xC0DEBABE) { + printk(BIOS_DEBUG, + "ACPI: Patching up global NVS in DSDT at offset 0x%04x -> 0x%08x\n", + i, (u32) current); + *(u32 *) (((u32) dsdt) + i) = current; // 0x92 bytes + break; + } + } + + /* And fill it */ + acpi_create_gnvs((global_nvs_t *) current); + + /* Keep pointer around */ + gnvs = (void *)current; + + current += 0x100; + ALIGN_CURRENT; + + /* And tell SMI about it */ + smm_setup_structures(gnvs, NULL, NULL); + + /* We patched up the DSDT, so we need to recalculate the checksum */ + dsdt->checksum = 0; + dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); + + printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, + dsdt->length); + +#if CONFIG_HAVE_ACPI_SLIC + printk(BIOS_DEBUG, "ACPI: * SLIC\n"); + slic = (acpi_header_t *) current; + current += acpi_create_slic(current); + ALIGN_CURRENT; + acpi_add_table(rsdp, slic); +#endif + + printk(BIOS_DEBUG, "ACPI: * FADT\n"); + fadt = (acpi_fadt_t *) current; + current += sizeof(acpi_fadt_t); + ALIGN_CURRENT; + + acpi_create_fadt(fadt, facs, dsdt); + acpi_add_table(rsdp, fadt); + + printk(BIOS_DEBUG, "ACPI: * SSDT\n"); + ssdt = (acpi_header_t *) current; + acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); + current += ssdt->length; + acpi_add_table(rsdp, ssdt); + ALIGN_CURRENT; + + printk(BIOS_DEBUG, "current = %lx\n", current); + printk(BIOS_INFO, "ACPI: done.\n"); + + /* Enable Dummy DCC ON# for DVI */ + printk(BIOS_DEBUG, "Laptop handling...\n"); + outb(inb(0x60f) & ~(1 << 5), 0x60f); + + return current; +} diff --git a/src/mainboard/lenovo/x201/cmos.default b/src/mainboard/lenovo/x201/cmos.default new file mode 100644 index 0000000..4577e70 --- /dev/null +++ b/src/mainboard/lenovo/x201/cmos.default @@ -0,0 +1,11 @@ +boot_option=Fallback +last_boot=Fallback +baud_rate=115200 +debug_level=Spew +power_on_after_fail=Enable +nmi=Enable +volume=0x3 +first_battery=Primary +bluetooth=Enable +wwan=Enable +touchpad=Enable diff --git a/src/mainboard/lenovo/x201/cmos.layout b/src/mainboard/lenovo/x201/cmos.layout new file mode 100644 index 0000000..7308e66 --- /dev/null +++ b/src/mainboard/lenovo/x201/cmos.layout @@ -0,0 +1,137 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007-2008 coresystems GmbH +## Copyright (C) 2013 Vladimir Serbinenko +## +## 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 + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +# ----------------------------------------------------------------- +# Status Register A +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +# ----------------------------------------------------------------- +# Status Register B +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +# ----------------------------------------------------------------- +# 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 264 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 + +400 8 h 0 volume + +# coreboot config options: southbridge +408 1 e 1 nmi +409 2 e 7 power_on_after_fail + +# coreboot config options: EC +411 1 e 8 first_battery +412 1 e 1 bluetooth +413 1 e 1 wwan +414 1 e 1 touchpad +#415 569 r 0 unused + +# coreboot config options: check sums +984 16 h 0 check_sum +#1000 24 r 0 amd_reserved + +# ----------------------------------------------------------------- + +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 Secondary +8 1 Primary +# ----------------------------------------------------------------- +checksums + +checksum 392 415 984 + + diff --git a/src/mainboard/lenovo/x201/devicetree.cb b/src/mainboard/lenovo/x201/devicetree.cb new file mode 100644 index 0000000..e17bf41 --- /dev/null +++ b/src/mainboard/lenovo/x201/devicetree.cb @@ -0,0 +1,148 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007-2009 coresystems GmbH +## 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 +## + +chip northbridge/intel/nehalem + + + # Enable DisplayPort Hotplug with 6ms pulse + register "gpu_dp_d_hotplug" = "0x06" + + # Enable Panel as LVDS and configure power delays + register "gpu_panel_port_select" = "0" # LVDS + register "gpu_panel_power_cycle_delay" = "3" + register "gpu_panel_power_up_delay" = "250" + register "gpu_panel_power_down_delay" = "250" + register "gpu_panel_power_backlight_on_delay" = "2500" + register "gpu_panel_power_backlight_off_delay" = "2500" + register "gpu_cpu_backlight" = "0x58d" + register "gpu_pch_backlight" = "0x061a061a" + + 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" = "0x05" + register "config2" = "0xa0" + register "config3" = "0x01" + + register "beepmask0" = "0xfe" + register "beepmask1" = "0x96" + + 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 "eventc_enable" = "0x3c" + register "event8_enable" = "0x01" + register "event9_enable" = "0xff" + register "eventa_enable" = "0xff" + register "eventb_enable" = "0xff" + register "eventc_enable" = "0xff" + register "eventd_enable" = "0xff" + + register "wlan_enable" = "0x01" + register "trackpoint_enable" = "0x03" + end + + device cpu_cluster 0 on + chip cpu/intel/model_206ax + device lapic 0 on end + end + end + + device domain 0 on + device pci 00.0 on # Host bridge + subsystemid 0x17aa 0x2193 + end + device pci 02.0 on # VGA controller + subsystemid 0x17aa 0x215a + end + chip southbridge/intel/bd82x6x + register "pirqa_routing" = "0x0b" + register "pirqb_routing" = "0x0b" + register "pirqc_routing" = "0x0b" + register "pirqd_routing" = "0x0b" + register "pirqe_routing" = "0x0b" + register "pirqf_routing" = "0x0b" + register "pirqg_routing" = "0x0b" + register "pirqh_routing" = "0x0b" + + # GPI routing + # 0 No effect (default) + # 1 SMI# (if corresponding ALT_GPI_SMI_EN bit is also set) + # 2 SCI (if corresponding GPIO_EN bit is also set) + register "gpi1_routing" = "2" + register "gpi13_routing" = "2" + + register "sata_ahci" = "0x1" + register "sata_port_map" = "0x33" + + register "gpe0_en" = "0x20022046" + register "alt_gp_smi_en" = "0x0000" + + device pci 16.2 on # IDE/SATA + subsystemid 0x17aa 0x2161 + end + + device pci 19.0 on # Ethernet + subsystemid 0x17aa 0x2153 + end + + device pci 1a.0 on # USB2 EHCI + subsystemid 0x17aa 0x2163 + end + +# register "c4onc3_enable" = "1" + device pci 1b.0 on # Audio Controller + subsystemid 0x17aa 0x215e + end + device pci 1d.0 on # USB2 EHCI + subsystemid 0x17aa 0x2163 + end + device pci 1f.0 on # PCI-LPC bridge + subsystemid 0x17aa 0x2166 + end + device pci 1f.2 on # IDE/SATA + subsystemid 0x17aa 0x2168 + end + device pci 1f.3 on # SMBUS + subsystemid 0x17aa 0x2167 + end + end + chip southbridge/ricoh/rl5c476 + end + end +end diff --git a/src/mainboard/lenovo/x201/dock.c b/src/mainboard/lenovo/x201/dock.c new file mode 100644 index 0000000..b315fda --- /dev/null +++ b/src/mainboard/lenovo/x201/dock.c @@ -0,0 +1,62 @@ +/* + * 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 + */ + +#include <console/console.h> +#include <arch/io.h> +#include <device/device.h> +#include <device/pci.h> +#if !defined (__PRE_RAM__) && !defined (__SMM__) +#define PCI_DEV(bus, dev, fn) dev_find_slot (bus, PCI_DEVFN (dev, fn)) +#endif +#include <delay.h> +#include "dock.h" +#include "southbridge/intel/bd82x6x/pch.h" +#include <ec/acpi/ec.h> + +int dock_connect(void) +{ + ec_set_bit(0x02, 0); + ec_set_bit(0x1a, 0); + ec_set_bit(0xfe, 4); + return 0; +} + +void dock_disconnect(void) +{ + ec_clr_bit(0x02, 0); + ec_clr_bit(0x1a, 0); + ec_clr_bit(0xfe, 4); +} + +int dock_present(void) +{ + u16 gpiobase = pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc; + u8 st = inb(gpiobase + 0x0c); + printk(BIOS_DEBUG, "GPIO status is 0x%x\n", st); + + return !((st >> 3) & 1); +} + +int dock_ultrabay_device_present(void) +{ + return 0; +} diff --git a/src/mainboard/lenovo/x201/dock.h b/src/mainboard/lenovo/x201/dock.h new file mode 100644 index 0000000..141ae48 --- /dev/null +++ b/src/mainboard/lenovo/x201/dock.h @@ -0,0 +1,28 @@ +/* + * 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_X60_DOCK_H +#define THINKPAD_X60_DOCK_H + +extern int dock_connect(void); +extern void dock_disconnect(void); +extern int dock_present(void); +extern int dlpc_init(void); +extern int dock_ultrabay_device_present(void); +#endif diff --git a/src/mainboard/lenovo/x201/dsdt.asl b/src/mainboard/lenovo/x201/dsdt.asl new file mode 100644 index 0000000..12b23ce --- /dev/null +++ b/src/mainboard/lenovo/x201/dsdt.asl @@ -0,0 +1,94 @@ +/* + * 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 + */ + +DefinitionBlock( + "dsdt.aml", + "DSDT", + 0x03, // DSDT revision: ACPI v3.0 + "COREv4", // OEM id + "COREBOOT", // OEM table id + 0x20130325 // OEM revision +) +{ + // Some generic macros + #include "acpi/platform.asl" + + // global NVS and variables + #include <southbridge/intel/bd82x6x/acpi/globalnvs.asl> + + // General Purpose Events + #include "acpi/gpe.asl" + + // mainboard specific devices + #include "acpi/mainboard.asl" + + #include <cpu/intel/model_206ax/acpi/cpu.asl> + + Scope (_SB) { + Device (PCI0) + { + #include <northbridge/intel/nehalem/acpi/nehalem.asl> + #include <southbridge/intel/bd82x6x/acpi/pch.asl> + } + Device (UNCR) + { + Name (_BBN, 0xFF) + Name (_ADR, 0x00) + Name (RID, 0x00) + Name (_HID, EisaId ("PNP0A03")) + Name (_CRS, ResourceTemplate () + { + WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, // Granularity + 0x00FF, // Range Minimum + 0x00FF, // Range Maximum + 0x0000, // Translation Offset + 0x0001, // Length + ,, ) + }) + Device (SAD) + { + Name (_ADR, 0x01) + Name (RID, 0x00) + OperationRegion (SADC, PCI_Config, 0x00, 0x0100) + Field (SADC, DWordAcc, NoLock, Preserve) + { + Offset (0x40), + PAM0, 8, + PAM1, 8, + PAM2, 8, + PAM3, 8, + PAM4, 8, + PAM5, 8, + PAM6, 8 + } + } + } + } + + #include "acpi/video.asl" + + /* Chipset specific sleep states */ + #include <southbridge/intel/i82801gx/acpi/sleepstates.asl> + + // Dock support code + #include "acpi/dock.asl" +} diff --git a/src/mainboard/lenovo/x201/fadt.c b/src/mainboard/lenovo/x201/fadt.c new file mode 100644 index 0000000..0639026 --- /dev/null +++ b/src/mainboard/lenovo/x201/fadt.c @@ -0,0 +1,160 @@ +/* + * 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> + +/* FIXME: This needs to go into a separate .h file + * to be included by the ich7 smi handler, ich7 smi init + * code and the mainboard fadt. + */ + +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; + fadt->pm2_cnt_len = 1; + fadt->pm_tmr_len = 4; + fadt->gpe0_blk_len = 0x10; + 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 = 0x23; + 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; + + fadt->reset_reg.space_id = 0; + fadt->reset_reg.bit_width = 0; + fadt->reset_reg.bit_offset = 0; + fadt->reset_reg.resv = 0; + fadt->reset_reg.addrl = 0x0; + fadt->reset_reg.addrh = 0x0; + + fadt->reset_value = 0; + fadt->x_firmware_ctl_l = (unsigned long)facs; + fadt->x_firmware_ctl_h = 0; + 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 = 32; + 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/x201/gma.c b/src/mainboard/lenovo/x201/gma.c new file mode 100644 index 0000000..f5347e0 --- /dev/null +++ b/src/mainboard/lenovo/x201/gma.c @@ -0,0 +1,508 @@ +#include <arch/io.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> + +#include "northbridge/intel/nehalem/nehalem.h" + +unsigned char fake_vbt[] = { + 0x24, 0x56, 0x42, 0x54, 0x20, 0x49, 0x52, 0x4f, 0x4e, 0x4c, 0x41, 0x4b, + 0x45, 0x2d, 0x4d, 0x4f, + 0x42, 0x49, 0x4c, 0x45, 0x64, 0x00, 0x30, 0x00, 0x8e, 0x0f, 0x48, 0x00, + 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x49, 0x4f, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x42, 0x4c, + 0x4f, 0x43, 0x4b, 0x20, + 0x9c, 0x00, 0x16, 0x00, 0x5e, 0x0f, 0xfe, 0xea, 0x00, 0x00, 0x64, 0x01, + 0x01, 0x0f, 0x0d, 0x32, + 0x30, 0x32, 0x36, 0x44, 0x43, 0x49, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x6c, + 0x28, 0x52, 0x29, 0x49, + 0x72, 0x6f, 0x6e, 0x6c, 0x61, 0x6b, 0x65, 0x20, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x20, 0x50, + 0x43, 0x49, 0x20, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x53, + 0x56, 0x47, 0x41, 0x20, 0x42, 0x49, 0x4f, 0x53, 0x0d, 0x0a, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x20, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x32, 0x30, 0x32, 0x36, + 0x20, 0x50, 0x43, 0x20, + 0x31, 0x34, 0x2e, 0x33, 0x34, 0x20, 0x20, 0x30, 0x39, 0x2f, 0x32, 0x38, + 0x20, 0x2f, 0x32, 0x30, + 0x31, 0x30, 0x20, 0x20, 0x32, 0x32, 0x3a, 0x32, 0x30, 0x3a, 0x35, 0x32, + 0x0d, 0x0a, 0x44, 0x45, + 0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x20, + 0x4f, 0x52, 0x20, 0x44, + 0x49, 0x53, 0x41, 0x53, 0x53, 0x45, 0x4d, 0x42, 0x4c, 0x59, 0x20, 0x50, + 0x52, 0x4f, 0x48, 0x49, + 0x42, 0x49, 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x6f, + 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, + 0x32, 0x30, 0x30, 0x30, + 0x2d, 0x32, 0x30, 0x30, 0x33, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x6c, 0x20, + 0x43, 0x6f, 0x72, 0x70, + 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x20, 0x52, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x00, + 0xc0, 0x03, 0x08, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x05, 0x00, 0x07, 0x03, 0x00, 0x01, 0x19, 0xfe, + 0x32, 0x00, 0x44, 0x04, + 0x40, 0x06, 0x04, 0x02, 0x09, 0x01, 0x08, 0x0a, 0x02, 0x08, 0x0c, 0x04, + 0x08, 0x03, 0x01, 0x02, + 0x05, 0x01, 0x04, 0x0d, 0x01, 0x04, 0x0b, 0x01, 0x02, 0x07, 0x01, 0x04, + 0x15, 0x01, 0x04, 0x45, + 0x01, 0x04, 0x0e, 0x04, 0x08, 0x46, 0x04, 0x40, 0x28, 0x20, 0x08, 0x48, + 0x40, 0x08, 0x10, 0x00, + 0x02, 0x0d, 0x01, 0x02, 0x04, 0x00, 0x00, 0x21, 0x08, 0x00, 0x22, 0x10, + 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xcd, 0x04, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xc6, + 0x68, 0x00, 0x20, 0x00, + 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xe3, 0x08, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x20, 0x01, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, + 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x03, 0x01, 0x00, 0x00, 0x04, 0x1c, 0x00, 0x30, 0x32, 0x34, 0x36, 0x38, + 0x3a, 0x3c, 0x40, 0x42, + 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, + 0x80, 0x81, 0x82, 0x83, + 0x84, 0x1a, 0x00, 0xfe, 0xad, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x30, 0x00, 0xbf, + 0x06, 0x1e, 0x00, 0x59, + 0x03, 0x28, 0x00, 0x86, 0x03, 0x02, 0x00, 0x90, 0x03, 0x38, 0x00, 0xd1, + 0x03, 0xc8, 0x00, 0x1f, + 0x06, 0x30, 0x00, 0x52, 0x06, 0x18, 0x00, 0x6d, 0x06, 0x18, 0x00, 0x88, + 0x06, 0x18, 0x00, 0x8b, + 0x07, 0x08, 0x00, 0xcf, 0x07, 0x12, 0x00, 0xe1, 0x07, 0x12, 0x00, 0xf3, + 0x07, 0x12, 0x00, 0x05, + 0x08, 0x12, 0x00, 0x1a, 0x08, 0x0a, 0x00, 0x24, 0x08, 0x0a, 0x00, 0x2e, + 0x08, 0x0a, 0x00, 0x38, + 0x08, 0x0a, 0x00, 0x45, 0x08, 0x0a, 0x00, 0x4f, 0x08, 0x0a, 0x00, 0x59, + 0x08, 0x0a, 0x00, 0x63, + 0x08, 0x0a, 0x00, 0x75, 0x08, 0x0a, 0x00, 0x7f, 0x08, 0x0a, 0x00, 0x89, + 0x08, 0x0a, 0x00, 0x93, + 0x08, 0x0a, 0x00, 0x9d, 0x08, 0x0a, 0x00, 0xa7, 0x08, 0x0a, 0x00, 0xb1, + 0x08, 0x0a, 0x00, 0xbb, + 0x08, 0x0a, 0x00, 0xc5, 0x08, 0x0a, 0x00, 0xcf, 0x08, 0x0a, 0x00, 0xd9, + 0x08, 0x0a, 0x00, 0xe3, + 0x08, 0x0a, 0x00, 0xed, 0x08, 0x0a, 0x00, 0xf7, 0x08, 0x0a, 0x00, 0x01, + 0x09, 0x0a, 0x00, 0x0b, + 0x09, 0x0a, 0x00, 0x06, 0x5d, 0x00, 0xfc, 0xff, 0x02, 0x80, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x07, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x04, 0x00, 0x8e, 0x29, 0x00, 0x80, 0x9c, 0x01, 0x07, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9c, 0x11, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x07, 0x07, 0x00, 0xfe, 0xff, 0xce, 0x18, 0x00, 0xff, + 0xff, 0x08, 0x3d, 0x00, + 0xfc, 0xff, 0x02, 0x40, 0xf0, 0x04, 0x00, 0x01, 0x00, 0x00, 0x01, 0x44, + 0xf0, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, + 0xf0, 0x04, 0x00, 0x00, + 0x00, 0x03, 0x03, 0x50, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xf0, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x58, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x0a, 0xcb, 0x00, + 0x0a, 0x80, 0x04, 0x60, 0x03, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x00, + 0x05, 0x58, 0x02, 0xff, + 0xff, 0xff, 0xbf, 0xff, 0xff, 0x00, 0x05, 0xc0, 0x03, 0xff, 0xff, 0xff, + 0xbf, 0xff, 0xff, 0x80, + 0x07, 0xa0, 0x05, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x40, 0x07, 0x70, 0x05, 0xff, 0xff, 0xff, 0xbf, 0xff, + 0xff, 0x00, 0x07, 0x40, + 0x05, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x80, 0x02, 0xe0, 0x01, 0xff, + 0x1b, 0xfe, 0x07, 0xff, + 0xff, 0x20, 0x03, 0x58, 0x02, 0xff, 0x1b, 0xfe, 0x07, 0xff, 0xff, 0x00, + 0x04, 0x00, 0x03, 0xff, + 0x1b, 0xfe, 0x07, 0xff, 0xff, 0x40, 0x06, 0xb0, 0x04, 0xff, 0x1b, 0xff, + 0x07, 0xff, 0xff, 0x00, + 0x08, 0x00, 0x06, 0xff, 0xdb, 0xff, 0x07, 0xff, 0xff, 0x00, 0x05, 0x00, + 0x04, 0xff, 0x1b, 0xfe, + 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0b, + 0xc7, 0x00, 0x21, 0x40, + 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x05, 0x70, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x02, 0x05, 0x72, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x11, 0x00, 0x4a, 0x00, 0x04, 0x00, + 0x03, 0x08, 0x3c, 0x84, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x0d, 0x03, 0x00, + 0xf7, 0x03, 0xc8, 0x0e, + 0x09, 0x00, 0x01, 0x90, 0x05, 0x5a, 0x00, 0xec, 0x05, 0x2d, 0x00, 0x0f, + 0x8b, 0x00, 0x09, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x00, + 0x10, 0x00, 0x03, 0x08, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x08, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x08, 0x00, 0x40, 0x00, + 0x00, 0x40, 0x08, 0x00, 0x20, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, + 0x00, 0x03, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x08, 0x00, 0x04, + 0x00, 0x00, 0x04, 0x08, + 0x00, 0x40, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x03, 0x01, 0x00, 0x00, + 0x01, 0x08, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x01, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x04, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x01, 0x00, 0x00, 0x01, + 0x08, 0x00, 0x00, 0x08, + 0x00, 0x02, 0x00, 0x00, 0x01, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x08, + 0x00, 0x00, 0x00, 0x00, + 0x11, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x0c, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, + 0x00, 0x0f, 0x02, 0x09, + 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x14, 0x9e, 0x00, + 0x06, 0x1a, 0x03, 0xff, 0x00, 0x03, 0xe0, 0x01, 0x07, 0x3c, 0x40, 0x0b, + 0x00, 0xc0, 0x30, 0xe0, + 0x14, 0x10, 0x18, 0x48, 0x36, 0x00, 0x05, 0xa3, 0x10, 0x00, 0x00, 0x18, + 0x03, 0xff, 0xc0, 0x03, + 0x58, 0x02, 0x07, 0x3c, 0xc8, 0x11, 0xc0, 0x00, 0x31, 0x58, 0x18, 0x20, + 0x20, 0x60, 0x36, 0x00, + 0x05, 0xa3, 0x10, 0x00, 0x00, 0x18, 0x03, 0xff, 0x00, 0x05, 0x20, 0x03, + 0x07, 0x3c, 0x9e, 0x20, + 0x00, 0x90, 0x51, 0x20, 0x1f, 0x30, 0x48, 0x80, 0x36, 0x00, 0x05, 0xa3, + 0x10, 0x00, 0x00, 0x18, + 0x03, 0xff, 0x00, 0x03, 0xe0, 0x01, 0x07, 0x32, 0x2c, 0x09, 0x00, 0xa0, + 0x30, 0xe0, 0x1a, 0x10, + 0x18, 0x10, 0x36, 0x00, 0x05, 0xa3, 0x10, 0x00, 0x00, 0x18, 0x03, 0xff, + 0xc0, 0x03, 0x58, 0x02, + 0x07, 0x32, 0xb2, 0x0d, 0xc0, 0xa0, 0x30, 0x58, 0x1a, 0x20, 0x18, 0x10, + 0x36, 0x00, 0x05, 0xa3, + 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3c, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x16, 0x4b, + 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x84, 0x0e, 0x00, 0x00, 0x4c, 0x46, 0x50, 0x5f, + 0x50, 0x61, 0x6e, 0x65, + 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, + 0x65, 0x6c, 0x4e, 0x61, + 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, + 0x61, 0x6d, 0x65, 0x4c, + 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, + 0x17, 0x48, 0x00, 0x64, + 0x19, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x2a, 0x00, 0x98, 0x51, 0x00, 0x30, 0x40, 0x30, 0x70, 0x13, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0xa8, 0x2f, 0x78, 0xe0, 0x51, 0x1a, 0x26, 0x40, 0x58, + 0x98, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x48, 0x3f, 0x40, 0x30, 0x62, 0xb0, 0x32, + 0x40, 0x40, 0xc0, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x18, 0x28, 0x00, 0x36, 0x7f, + 0x03, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x36, 0x7f, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x36, 0x7f, + 0x01, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x36, 0x7f, 0x06, 0x00, + 0x04, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x19, 0x28, 0x00, 0x19, 0x00, 0xfa, 0x00, 0xfa, 0x00, 0x19, + 0x00, 0x90, 0x01, 0x20, + 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xc8, 0x00, 0x40, 0x00, 0x40, + 0x00, 0x40, 0x00, 0x40, + 0x00, 0x2c, 0x01, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x2c, + 0x01, 0x1a, 0x02, 0x00, + 0x00, 0x40, 0x1b, 0xc8, 0x00, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, + 0x01, 0x88, 0x13, 0xd0, + 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, + 0x00, 0xd0, 0x07, 0xf4, + 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, + 0x13, 0xd0, 0x07, 0x0a, + 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, + 0x07, 0xf4, 0x01, 0x88, + 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, + 0x07, 0x0a, 0x00, 0xd0, + 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, + 0x01, 0x88, 0x13, 0xd0, + 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, + 0x00, 0xd0, 0x07, 0xf4, + 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, + 0x13, 0xd0, 0x07, 0x0a, + 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, + 0x07, 0xf4, 0x01, 0x88, + 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, + 0x07, 0x0a, 0x00, 0xd0, + 0x07, 0xf4, 0x01, 0x88, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x18, 0x00, + 0x01, 0x00, 0x73, 0x00, 0x54, 0x05, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0x29, 0x94, 0x00, 0x03, + 0xf2, 0x09, 0x20, 0x18, + 0x0a, 0x12, 0x2a, 0x0a, 0x0a, 0x34, 0x0a, 0x20, 0x5a, 0x0a, 0x12, 0x6c, + 0x0a, 0x0a, 0x76, 0x0a, + 0x20, 0x9c, 0x0a, 0x12, 0xae, 0x0a, 0x0a, 0xb8, 0x0a, 0x20, 0xde, 0x0a, + 0x12, 0xf0, 0x0a, 0x0a, + 0xfa, 0x0a, 0x20, 0x20, 0x0b, 0x12, 0x32, 0x0b, 0x0a, 0x3c, 0x0b, 0x20, + 0x62, 0x0b, 0x12, 0x74, + 0x0b, 0x0a, 0x7e, 0x0b, 0x20, 0xa4, 0x0b, 0x12, 0xb6, 0x0b, 0x0a, 0xc0, + 0x0b, 0x20, 0xe6, 0x0b, + 0x12, 0xf8, 0x0b, 0x0a, 0x02, 0x0c, 0x20, 0x28, 0x0c, 0x12, 0x3a, 0x0c, + 0x0a, 0x44, 0x0c, 0x20, + 0x6a, 0x0c, 0x12, 0x7c, 0x0c, 0x0a, 0x86, 0x0c, 0x20, 0xac, 0x0c, 0x12, + 0xbe, 0x0c, 0x0a, 0xc8, + 0x0c, 0x20, 0xee, 0x0c, 0x12, 0x00, 0x0d, 0x0a, 0x0a, 0x0d, 0x20, 0x30, + 0x0d, 0x12, 0x42, 0x0d, + 0x0a, 0x4c, 0x0d, 0x20, 0x72, 0x0d, 0x12, 0x84, 0x0d, 0x0a, 0x8e, 0x0d, + 0x20, 0xb4, 0x0d, 0x12, + 0xc6, 0x0d, 0x0a, 0xd0, 0x0d, 0x20, 0xf6, 0x0d, 0x12, 0x08, 0x0e, 0x0a, + 0x12, 0x0e, 0x0d, 0x2a, + 0xf0, 0x04, 0x80, 0x02, 0xe0, 0x01, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x08, 0x72, + 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x10, 0x72, + 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0xd6, 0x09, 0x80, 0x90, + 0x20, 0xe0, 0x1d, 0x10, + 0x08, 0x60, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, + 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, 0x20, 0x03, 0x80, 0x11, 0x0e, 0x00, + 0x00, 0x03, 0x00, 0x00, + 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, + 0x10, 0x72, 0x0c, 0x00, 0x03, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x12, 0x1b, + 0x00, 0x80, 0x50, 0x20, + 0x14, 0x30, 0x18, 0x20, 0x44, 0x00, 0x05, 0xa3, 0x10, 0x00, 0x00, 0x1f, + 0x30, 0xae, 0x11, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa0, 0x05, 0x84, 0x03, 0x80, 0x11, + 0x0e, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, + 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, 0x03, 0x0f, 0x27, 0x00, 0xff, 0xff, + 0xf0, 0x1c, 0xa0, 0xa0, + 0x50, 0x84, 0x1a, 0x30, 0x18, 0x10, 0x36, 0x00, 0x05, 0xa3, 0x10, 0x00, + 0x00, 0x18, 0x30, 0xae, + 0x14, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x05, 0x20, 0x03, + 0x80, 0x11, 0x0e, 0x00, + 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, + 0x0c, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, 0x03, 0x0f, 0x27, 0x00, + 0xff, 0xff, 0x64, 0x19, + 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, + 0x30, 0xae, 0x31, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x05, + 0x20, 0x03, 0x80, 0x11, + 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x0c, 0x72, + 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, 0x03, 0x0f, + 0x27, 0x00, 0xff, 0xff, + 0xc7, 0x1b, 0x00, 0xa0, 0x50, 0x20, 0x17, 0x30, 0x30, 0x20, 0x36, 0x00, + 0x05, 0xa3, 0x10, 0x00, + 0x00, 0x18, 0x30, 0xae, 0x11, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x05, 0x20, 0x03, + 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, + 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, + 0x03, 0x0f, 0x27, 0x00, + 0xff, 0xff, 0xc0, 0x1b, 0x00, 0xab, 0x50, 0x20, 0x10, 0x30, 0x34, 0x40, + 0x33, 0x00, 0x05, 0xa3, + 0x10, 0x00, 0x00, 0x19, 0x30, 0xae, 0x11, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x05, + 0x20, 0x03, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, + 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, + 0x0c, 0x00, 0x03, 0x0f, + 0x27, 0x00, 0xff, 0xff, 0xcc, 0x1b, 0x00, 0xa1, 0x50, 0x20, 0x17, 0x30, + 0x31, 0x20, 0x36, 0x00, + 0x05, 0xa3, 0x10, 0x00, 0x00, 0x19, 0x30, 0xae, 0x10, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x2d, 0x12, + 0x00, 0x05, 0x00, 0x03, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x08, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, + 0x10, 0x72, 0x0c, 0x00, + 0x03, 0x0f, 0x27, 0x00, 0xff, 0xff, 0xa9, 0x1a, 0x00, 0xa0, 0x50, 0x00, + 0x0a, 0x30, 0x30, 0x20, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x90, + 0x08, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x90, 0x06, 0x1a, 0x04, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, + 0x00, 0x00, 0x08, 0x72, + 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x10, 0x72, + 0x0c, 0x00, 0x03, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x7c, 0x2e, 0x90, 0xa0, + 0x60, 0x1a, 0x1e, 0x40, + 0x30, 0x20, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, + 0x04, 0x90, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x80, 0x07, 0xb0, 0x04, 0x80, 0x11, 0x0e, 0x00, + 0x3c, 0x03, 0x00, 0x00, + 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, + 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x28, 0x3c, + 0x80, 0xa0, 0x70, 0xb0, + 0x23, 0x40, 0x30, 0x20, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, + 0x36, 0x7f, 0x05, 0x90, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x03, 0x80, 0x11, + 0x0e, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, + 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, + 0x64, 0x19, 0x00, 0x40, + 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0x36, 0x7f, + 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x03, + 0x80, 0x11, 0x0e, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, + 0x0c, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, 0x03, 0x0f, 0x27, 0x00, + 0xff, 0xff, 0x64, 0x19, + 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, + 0x36, 0x7f, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, + 0x00, 0x03, 0x80, 0x11, + 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x0c, 0x72, + 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, 0x03, 0x0f, + 0x27, 0x00, 0xff, 0xff, + 0x64, 0x19, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x05, 0x20, 0x03, + 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, + 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, 0x0c, 0x00, + 0x03, 0x0f, 0x27, 0x00, + 0xff, 0xff, 0xea, 0x1a, 0x00, 0xa0, 0x50, 0x20, 0x17, 0x30, 0x0c, 0x30, + 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x05, + 0x58, 0x02, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, + 0x0c, 0x00, 0xc4, 0x09, + 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, 0x10, 0x72, + 0x0c, 0x00, 0x03, 0x0f, + 0x27, 0x00, 0xff, 0xff, 0x06, 0x18, 0x00, 0x70, 0x51, 0x58, 0x15, 0x20, + 0x38, 0x80, 0x13, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x08, 0x00, 0x06, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, + 0x08, 0x72, 0x0c, 0x00, + 0xc4, 0x09, 0xfa, 0x00, 0x0c, 0x72, 0x0c, 0x00, 0xc4, 0x09, 0xfa, 0x00, + 0x10, 0x72, 0x0c, 0x00, + 0x03, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x29, 0x40, 0x00, 0x60, 0x80, 0x00, + 0x13, 0x60, 0x10, 0x10, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, + 0x10, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4d, + 0x50, 0x57, 0x58, 0x47, 0x41, 0x32, 0x32, 0x30, 0x4e, 0x49, 0x54, 0x00, + 0x4d, 0x50, 0x57, 0x58, + 0x47, 0x41, 0x2b, 0x32, 0x35, 0x30, 0x4e, 0x49, 0x54, 0x43, 0x5f, 0x44, + 0x42, 0x34, 0x30, 0x30, + 0x4e, 0x49, 0x54, 0x00, 0x00, 0x00, 0x43, 0x5f, 0x4d, 0x54, 0x50, 0x33, + 0x30, 0x30, 0x4e, 0x49, + 0x54, 0x00, 0x00, 0x43, 0x5f, 0x50, 0x50, 0x32, 0x32, 0x30, 0x4e, 0x49, + 0x54, 0x00, 0x00, 0x00, + 0x4d, 0x50, 0x43, 0x5f, 0x43, 0x43, 0x46, 0x4c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x61, 0x6e, 0x65, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2b, 0x61, 0x00, 0x06, 0x4e, 0xdc, 0x00, 0x00, 0x58, 0xaa, + 0x4a, 0x71, 0x02, 0x04, + 0x58, 0xaa, 0x4a, 0xa5, 0x00, 0x04, 0x58, 0xaa, 0x4a, 0x96, 0x00, 0x02, + 0x58, 0xaa, 0x4a, 0x5a, + 0x00, 0x04, 0x58, 0xaa, 0x4a, 0xff, 0x00, 0x05, 0x58, 0xaa, 0x4a, 0xa5, + 0x00, 0x16, 0x58, 0xaa, + 0x4e, 0xdc, 0x00, 0x00, 0x58, 0xaa, 0x4e, 0xdc, 0x00, 0x00, 0x58, 0xaa, + 0x4e, 0xdc, 0x00, 0x00, + 0x58, 0xaa, 0x4e, 0xdc, 0x00, 0x00, 0x58, 0xaa, 0x4e, 0xdc, 0x00, 0x00, + 0x58, 0xaa, 0x4e, 0xdc, + 0x00, 0x00, 0x58, 0xaa, 0x4e, 0xdc, 0x00, 0x00, 0x58, 0xaa, 0x4e, 0xdc, + 0x00, 0x00, 0x58, 0xaa, + 0x4e, 0xdc, 0x00, 0x00, 0x58, 0xaa, 0x2c, 0x15, 0x00, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; diff --git a/src/mainboard/lenovo/x201/gpio.h b/src/mainboard/lenovo/x201/gpio.h new file mode 100644 index 0000000..40b1de0 --- /dev/null +++ b/src/mainboard/lenovo/x201/gpio.h @@ -0,0 +1,416 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Vladimir Serbinenko + * + * 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 STUMPY_GPIO_H +#define STUMPY_GPIO_H + +#include "southbridge/intel/bd82x6x/gpio.h" + +/* + * GPIO SET 1 includes GPIO0 to GPIO31 + */ +const struct pch_gpio_set1 pch_gpio_set1_mode = { + .gpio0 = GPIO_MODE_GPIO, + .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_NATIVE, + .gpio10 = GPIO_MODE_GPIO, + .gpio11 = GPIO_MODE_NATIVE, + .gpio12 = GPIO_MODE_NATIVE, + .gpio13 = GPIO_MODE_GPIO, + .gpio14 = GPIO_MODE_NATIVE, + .gpio15 = GPIO_MODE_GPIO, + .gpio16 = GPIO_MODE_GPIO, + .gpio17 = GPIO_MODE_GPIO, + .gpio18 = GPIO_MODE_NATIVE, + .gpio19 = GPIO_MODE_NATIVE, + .gpio20 = GPIO_MODE_NATIVE, + .gpio21 = GPIO_MODE_GPIO, + .gpio22 = GPIO_MODE_GPIO, + .gpio23 = GPIO_MODE_NATIVE, + .gpio24 = GPIO_MODE_GPIO, + .gpio25 = GPIO_MODE_NATIVE, + .gpio26 = GPIO_MODE_NATIVE, + .gpio27 = GPIO_MODE_GPIO, + .gpio28 = GPIO_MODE_GPIO, + .gpio29 = GPIO_MODE_NATIVE, + .gpio30 = GPIO_MODE_NATIVE, + .gpio31 = GPIO_MODE_NATIVE, +}; + +const struct pch_gpio_set1 pch_gpio_set1_reset = { + .gpio0 = GPIO_RESET_PWROK, + .gpio1 = GPIO_RESET_PWROK, + .gpio2 = GPIO_RESET_PWROK, + .gpio3 = GPIO_RESET_PWROK, + .gpio4 = GPIO_RESET_PWROK, + .gpio5 = GPIO_RESET_PWROK, + .gpio6 = GPIO_RESET_PWROK, + .gpio7 = GPIO_RESET_PWROK, + .gpio8 = GPIO_RESET_PWROK, + .gpio9 = GPIO_RESET_PWROK, + .gpio10 = GPIO_RESET_PWROK, + .gpio11 = GPIO_RESET_PWROK, + .gpio12 = GPIO_RESET_PWROK, + .gpio13 = GPIO_RESET_PWROK, + .gpio14 = GPIO_RESET_PWROK, + .gpio15 = GPIO_RESET_PWROK, + .gpio16 = GPIO_RESET_PWROK, + .gpio17 = GPIO_RESET_PWROK, + .gpio18 = GPIO_RESET_PWROK, + .gpio19 = GPIO_RESET_PWROK, + .gpio20 = GPIO_RESET_PWROK, + .gpio21 = GPIO_RESET_PWROK, + .gpio22 = GPIO_RESET_PWROK, + .gpio23 = GPIO_RESET_PWROK, + .gpio24 = GPIO_RESET_RSMRST, + .gpio25 = GPIO_RESET_PWROK, + .gpio26 = GPIO_RESET_PWROK, + .gpio27 = GPIO_RESET_PWROK, + .gpio28 = GPIO_RESET_PWROK, + .gpio29 = GPIO_RESET_PWROK, + .gpio30 = GPIO_RESET_RSMRST, + .gpio31 = GPIO_RESET_PWROK, +}; + +const struct pch_gpio_set1 pch_gpio_set1_direction = { + .gpio0 = GPIO_DIR_INPUT, + .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_OUTPUT, + .gpio9 = GPIO_DIR_INPUT, + .gpio10 = GPIO_DIR_OUTPUT, + .gpio11 = GPIO_DIR_INPUT, + .gpio12 = GPIO_DIR_OUTPUT, + .gpio13 = GPIO_DIR_INPUT, + .gpio14 = GPIO_DIR_INPUT, + .gpio15 = GPIO_DIR_OUTPUT, + .gpio16 = GPIO_DIR_INPUT, + .gpio17 = GPIO_DIR_INPUT, + .gpio18 = GPIO_DIR_INPUT, + .gpio19 = GPIO_DIR_INPUT, + .gpio20 = GPIO_DIR_INPUT, + .gpio21 = GPIO_DIR_INPUT, + .gpio22 = GPIO_DIR_OUTPUT, + .gpio23 = GPIO_DIR_INPUT, + .gpio24 = GPIO_DIR_INPUT, + .gpio25 = GPIO_DIR_INPUT, + .gpio26 = GPIO_DIR_INPUT, + .gpio27 = GPIO_DIR_OUTPUT, + .gpio28 = GPIO_DIR_OUTPUT, + .gpio29 = GPIO_DIR_OUTPUT, + .gpio30 = GPIO_DIR_OUTPUT, + .gpio31 = GPIO_DIR_INPUT, +}; + +const struct pch_gpio_set1 pch_gpio_set1_level = { + .gpio0 = GPIO_LEVEL_HIGH, + .gpio1 = GPIO_LEVEL_HIGH, + .gpio2 = GPIO_LEVEL_HIGH, + .gpio3 = GPIO_LEVEL_HIGH, + .gpio4 = GPIO_LEVEL_HIGH, + .gpio5 = GPIO_LEVEL_HIGH, + .gpio6 = GPIO_LEVEL_HIGH, + .gpio7 = GPIO_LEVEL_HIGH, + .gpio8 = GPIO_LEVEL_HIGH, + .gpio9 = GPIO_LEVEL_HIGH, + .gpio10 = GPIO_LEVEL_HIGH, + .gpio11 = GPIO_LEVEL_HIGH, + .gpio12 = GPIO_LEVEL_HIGH, + .gpio13 = GPIO_LEVEL_HIGH, + .gpio14 = GPIO_LEVEL_HIGH, + .gpio15 = GPIO_LEVEL_HIGH, + .gpio16 = GPIO_LEVEL_HIGH, + .gpio17 = GPIO_LEVEL_HIGH, + .gpio18 = GPIO_LEVEL_HIGH, + .gpio19 = GPIO_LEVEL_HIGH, + .gpio20 = GPIO_LEVEL_HIGH, + .gpio21 = GPIO_LEVEL_HIGH, + .gpio22 = GPIO_LEVEL_HIGH, + .gpio23 = GPIO_LEVEL_HIGH, + .gpio24 = GPIO_LEVEL_HIGH, + .gpio25 = GPIO_LEVEL_HIGH, + .gpio26 = GPIO_LEVEL_HIGH, + .gpio27 = GPIO_LEVEL_HIGH, + .gpio28 = GPIO_LEVEL_HIGH, + .gpio29 = GPIO_LEVEL_HIGH, + .gpio30 = GPIO_LEVEL_HIGH, + .gpio31 = GPIO_LEVEL_HIGH, +}; + +const struct pch_gpio_set1 pch_gpio_set1_blink = { + .gpio0 = GPIO_NO_BLINK, + .gpio1 = GPIO_NO_BLINK, + .gpio2 = GPIO_NO_BLINK, + .gpio3 = GPIO_NO_BLINK, + .gpio4 = GPIO_NO_BLINK, + .gpio5 = GPIO_NO_BLINK, + .gpio6 = GPIO_NO_BLINK, + .gpio7 = GPIO_NO_BLINK, + .gpio8 = GPIO_NO_BLINK, + .gpio9 = GPIO_NO_BLINK, + .gpio10 = GPIO_NO_BLINK, + .gpio11 = GPIO_NO_BLINK, + .gpio12 = GPIO_NO_BLINK, + .gpio13 = GPIO_NO_BLINK, + .gpio14 = GPIO_NO_BLINK, + .gpio15 = GPIO_NO_BLINK, + .gpio16 = GPIO_NO_BLINK, + .gpio17 = GPIO_NO_BLINK, + .gpio18 = GPIO_NO_BLINK, + .gpio19 = GPIO_NO_BLINK, + .gpio20 = GPIO_NO_BLINK, + .gpio21 = GPIO_NO_BLINK, + .gpio22 = GPIO_NO_BLINK, + .gpio23 = GPIO_NO_BLINK, + .gpio24 = GPIO_NO_BLINK, + .gpio25 = GPIO_NO_BLINK, + .gpio26 = GPIO_NO_BLINK, + .gpio27 = GPIO_NO_BLINK, + .gpio28 = GPIO_NO_BLINK, + .gpio29 = GPIO_NO_BLINK, + .gpio30 = GPIO_NO_BLINK, + .gpio31 = GPIO_NO_BLINK, +}; + +const struct pch_gpio_set1 pch_gpio_set1_invert = { + .gpio0 = GPIO_NO_INVERT, + .gpio1 = GPIO_INVERT, + .gpio2 = GPIO_INVERT, + .gpio3 = GPIO_NO_INVERT, + .gpio4 = GPIO_NO_INVERT, + .gpio5 = GPIO_NO_INVERT, + .gpio6 = GPIO_INVERT, + .gpio7 = GPIO_INVERT, + .gpio8 = GPIO_NO_INVERT, + .gpio9 = GPIO_NO_INVERT, + .gpio10 = GPIO_NO_INVERT, + .gpio11 = GPIO_NO_INVERT, + .gpio12 = GPIO_NO_INVERT, + .gpio13 = GPIO_INVERT, + .gpio14 = GPIO_NO_INVERT, + .gpio15 = GPIO_NO_INVERT, + .gpio16 = GPIO_INVERT, + .gpio17 = GPIO_NO_INVERT, + .gpio18 = GPIO_NO_INVERT, + .gpio19 = GPIO_NO_INVERT, + .gpio20 = GPIO_NO_INVERT, + .gpio21 = GPIO_NO_INVERT, + .gpio22 = GPIO_NO_INVERT, + .gpio23 = GPIO_NO_INVERT, + .gpio24 = GPIO_NO_INVERT, + .gpio25 = GPIO_NO_INVERT, + .gpio26 = GPIO_NO_INVERT, + .gpio27 = GPIO_NO_INVERT, + .gpio28 = GPIO_NO_INVERT, + .gpio29 = GPIO_NO_INVERT, + .gpio30 = GPIO_NO_INVERT, + .gpio31 = GPIO_NO_INVERT, +}; + +/* + * GPIO SET 2 includes GPIO32 to GPIO63 + */ + +const struct pch_gpio_set2 pch_gpio_set2_mode = { + .gpio32 = GPIO_MODE_NATIVE, + .gpio33 = GPIO_MODE_GPIO, + .gpio34 = GPIO_MODE_GPIO, + .gpio35 = GPIO_MODE_GPIO, + .gpio36 = GPIO_MODE_GPIO, + .gpio37 = GPIO_MODE_GPIO, + .gpio38 = GPIO_MODE_GPIO, + .gpio39 = GPIO_MODE_GPIO, + .gpio40 = GPIO_MODE_NATIVE, + .gpio41 = GPIO_MODE_GPIO, + .gpio42 = GPIO_MODE_GPIO, + .gpio43 = GPIO_MODE_NATIVE, + .gpio44 = GPIO_MODE_NATIVE, + .gpio45 = GPIO_MODE_NATIVE, + .gpio46 = GPIO_MODE_NATIVE, + .gpio47 = GPIO_MODE_NATIVE, + .gpio48 = GPIO_MODE_GPIO, + .gpio49 = GPIO_MODE_GPIO, + .gpio50 = GPIO_MODE_GPIO, + .gpio51 = GPIO_MODE_NATIVE, + .gpio52 = GPIO_MODE_GPIO, + .gpio53 = GPIO_MODE_GPIO, + .gpio54 = GPIO_MODE_GPIO, + .gpio55 = GPIO_MODE_NATIVE, + .gpio56 = GPIO_MODE_NATIVE, + .gpio57 = GPIO_MODE_GPIO, + .gpio58 = GPIO_MODE_NATIVE, + .gpio59 = GPIO_MODE_NATIVE, + .gpio60 = GPIO_MODE_NATIVE, + .gpio61 = GPIO_MODE_NATIVE, + .gpio62 = GPIO_MODE_NATIVE, + .gpio63 = GPIO_MODE_NATIVE, +}; + +const struct pch_gpio_set2 pch_gpio_set2_direction = { + .gpio32 = GPIO_DIR_OUTPUT, + .gpio33 = GPIO_DIR_OUTPUT, + .gpio34 = GPIO_DIR_INPUT, + .gpio35 = GPIO_DIR_OUTPUT, + .gpio36 = GPIO_DIR_INPUT, + .gpio37 = GPIO_DIR_INPUT, + .gpio38 = GPIO_DIR_INPUT, + .gpio39 = GPIO_DIR_INPUT, + .gpio40 = GPIO_DIR_INPUT, + .gpio41 = GPIO_DIR_OUTPUT, + .gpio42 = GPIO_DIR_OUTPUT, + .gpio43 = GPIO_DIR_INPUT, + .gpio44 = GPIO_DIR_INPUT, + .gpio45 = GPIO_DIR_INPUT, + .gpio46 = GPIO_DIR_INPUT, + .gpio47 = GPIO_DIR_INPUT, + .gpio48 = GPIO_DIR_INPUT, + .gpio49 = GPIO_DIR_OUTPUT, + .gpio50 = GPIO_DIR_OUTPUT, + .gpio51 = GPIO_DIR_OUTPUT, + .gpio52 = GPIO_DIR_OUTPUT, + .gpio53 = GPIO_DIR_OUTPUT, + .gpio54 = GPIO_DIR_OUTPUT, + .gpio55 = GPIO_DIR_OUTPUT, + .gpio56 = GPIO_DIR_INPUT, + .gpio57 = GPIO_DIR_INPUT, + .gpio58 = GPIO_DIR_OUTPUT, + .gpio59 = GPIO_DIR_INPUT, + .gpio60 = GPIO_DIR_INPUT, + .gpio61 = GPIO_DIR_OUTPUT, + .gpio62 = GPIO_DIR_OUTPUT, + .gpio63 = GPIO_DIR_OUTPUT, +}; + +const struct pch_gpio_set2 pch_gpio_set2_level = { + .gpio32 = GPIO_LEVEL_HIGH, + .gpio33 = GPIO_LEVEL_HIGH, + .gpio34 = GPIO_LEVEL_HIGH, + .gpio35 = GPIO_LEVEL_HIGH, + .gpio36 = GPIO_LEVEL_HIGH, + .gpio37 = GPIO_LEVEL_HIGH, + .gpio38 = GPIO_LEVEL_HIGH, + .gpio39 = GPIO_LEVEL_HIGH, + .gpio40 = GPIO_LEVEL_HIGH, + .gpio41 = GPIO_LEVEL_HIGH, + .gpio42 = GPIO_LEVEL_HIGH, + .gpio43 = GPIO_LEVEL_HIGH, + .gpio44 = GPIO_LEVEL_HIGH, + .gpio45 = GPIO_LEVEL_HIGH, + .gpio46 = GPIO_LEVEL_HIGH, + .gpio47 = GPIO_LEVEL_HIGH, + .gpio48 = GPIO_LEVEL_HIGH, + .gpio49 = GPIO_LEVEL_HIGH, + .gpio50 = GPIO_LEVEL_HIGH, + .gpio51 = GPIO_LEVEL_HIGH, + .gpio52 = GPIO_LEVEL_HIGH, + .gpio53 = GPIO_LEVEL_LOW, + .gpio54 = GPIO_LEVEL_LOW, + .gpio55 = GPIO_LEVEL_HIGH, + .gpio56 = GPIO_LEVEL_LOW, + .gpio57 = GPIO_LEVEL_HIGH, + .gpio58 = GPIO_LEVEL_LOW, + .gpio59 = GPIO_LEVEL_LOW, + .gpio60 = GPIO_LEVEL_LOW, + .gpio61 = GPIO_LEVEL_LOW, + .gpio62 = GPIO_LEVEL_LOW, + .gpio63 = GPIO_LEVEL_LOW, +}; + +/* + * GPIO SET 3 includes GPIO64 to GPIO75 + */ + +const struct pch_gpio_set3 pch_gpio_set3_mode = { + .gpio64 = GPIO_MODE_NATIVE, + .gpio65 = GPIO_MODE_NATIVE, + .gpio66 = GPIO_MODE_NATIVE, + .gpio67 = GPIO_MODE_NATIVE, + .gpio68 = GPIO_MODE_NATIVE, + .gpio69 = GPIO_MODE_NATIVE, + .gpio70 = GPIO_MODE_NATIVE, + .gpio71 = GPIO_MODE_NATIVE, + .gpio72 = GPIO_MODE_NATIVE, + .gpio73 = GPIO_MODE_NATIVE, + .gpio74 = GPIO_MODE_NATIVE, + .gpio75 = GPIO_MODE_NATIVE, +}; + +const struct pch_gpio_set3 pch_gpio_set3_direction = { + .gpio64 = GPIO_DIR_OUTPUT, + .gpio65 = GPIO_DIR_OUTPUT, + .gpio66 = GPIO_DIR_OUTPUT, + .gpio67 = GPIO_DIR_OUTPUT, + .gpio68 = GPIO_DIR_OUTPUT, + .gpio69 = GPIO_DIR_OUTPUT, + .gpio70 = GPIO_DIR_OUTPUT, + .gpio71 = GPIO_DIR_OUTPUT, + .gpio72 = GPIO_DIR_INPUT, + .gpio73 = GPIO_DIR_INPUT, + .gpio74 = GPIO_DIR_INPUT, + .gpio75 = GPIO_DIR_INPUT, +}; + +const struct pch_gpio_set3 pch_gpio_set3_level = { + .gpio64 = GPIO_LEVEL_LOW, + .gpio65 = GPIO_LEVEL_LOW, + .gpio66 = GPIO_LEVEL_LOW, + .gpio67 = GPIO_LEVEL_LOW, + .gpio68 = GPIO_LEVEL_LOW, + .gpio69 = GPIO_LEVEL_LOW, + .gpio70 = GPIO_LEVEL_LOW, + .gpio71 = GPIO_LEVEL_LOW, + .gpio72 = GPIO_LEVEL_LOW, + .gpio73 = GPIO_LEVEL_LOW, + .gpio74 = GPIO_LEVEL_LOW, + .gpio75 = GPIO_LEVEL_LOW, +}; + +const struct pch_gpio_map x201_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, + }, + .set3 = { + .mode = &pch_gpio_set3_mode, + .direction = &pch_gpio_set3_direction, + .level = &pch_gpio_set3_level, + }, +}; + +#endif diff --git a/src/mainboard/lenovo/x201/irq_tables.c b/src/mainboard/lenovo/x201/irq_tables.c new file mode 100644 index 0000000..bf8574f --- /dev/null +++ b/src/mainboard/lenovo/x201/irq_tables.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2013 Vladimir Serbinenko + * + * 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/pirq_routing.h> + +static const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32 + 16 * 16, + 0x00, (0x1f << 3) | 0x0, + 0x0000, + 0x8086, 0x3b07, + 0x00000000, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* u8 rfu[11] */ + 0x20,/* Checksum (has to be set to some value that + * would give 0 after the sum of all bytes + * for this structure (including checksum). + */ + { + /* bus, dev | fn, { link, bitmap }, { link, bitmap }, { link, bitmap }, { link, bitmap }, slot, rfu */ + { 0x00, (0x00 << 3) | 0x0, { { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x03, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x01 << 3) | 0x0, { { 0x01, 0x1cf8 }, { 0x00, 0xdef8 }, { 0x00, 0xdef8 }, { 0x00, 0xdef8 }, }, 0x00, 0x00 }, + { 0x00, (0x02 << 3) | 0x0, { { 0x01, 0x1cf8 }, { 0x00, 0xdef8 }, { 0x00, 0xdef8 }, { 0x00, 0xdef8 }, }, 0x00, 0x00 }, + { 0x00, (0x16 << 3) | 0x0, { { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x03, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x19 << 3) | 0x0, { { 0x05, 0x1cf8 }, { 0x00, 0xdef8 }, { 0x00, 0xdef8 }, { 0x00, 0xdef8 }, }, 0x00, 0x00 }, + { 0x00, (0x1a << 3) | 0x0, { { 0x05, 0x1cf8 }, { 0x06, 0x1cf8 }, { 0x07, 0x1cf8 }, { 0x08, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1b << 3) | 0x0, { { 0x00, 0xdef8 }, { 0x02, 0x1cf8 }, { 0x00, 0xdef8 }, { 0x00, 0xdef8 }, }, 0x00, 0x00 }, + { 0x00, (0x1c << 3) | 0x0, { { 0x05, 0x1cf8 }, { 0x06, 0x1cf8 }, { 0x07, 0x1cf8 }, { 0x08, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1c << 3) | 0x3, { { 0x05, 0x1cf8 }, { 0x06, 0x1cf8 }, { 0x07, 0x1cf8 }, { 0x08, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1c << 3) | 0x4, { { 0x05, 0x1cf8 }, { 0x06, 0x1cf8 }, { 0x07, 0x1cf8 }, { 0x08, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1d << 3) | 0x0, { { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x03, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1e << 3) | 0x0, { { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x03, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1f << 3) | 0x0, { { 0x08, 0x1cf8 }, { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1f << 3) | 0x2, { { 0x08, 0x1cf8 }, { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1f << 3) | 0x3, { { 0x08, 0x1cf8 }, { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + { 0x00, (0x1f << 3) | 0x6, { { 0x08, 0x1cf8 }, { 0x01, 0x1cf8 }, { 0x02, 0x1cf8 }, { 0x04, 0x1cf8 }, }, 0x00, 0x00 }, + } +}; + +unsigned long write_pirq_routing_table(unsigned long addr) +{ + return copy_pirq_routing_table(addr, &intel_irq_routing_table); +} diff --git a/src/mainboard/lenovo/x201/mainboard.c b/src/mainboard/lenovo/x201/mainboard.c new file mode 100644 index 0000000..572542e --- /dev/null +++ b/src/mainboard/lenovo/x201/mainboard.c @@ -0,0 +1,282 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * 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 + */ + +#include <console/console.h> +#include <device/device.h> +#include <arch/io.h> +#include <delay.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <ec/lenovo/pmh7/pmh7.h> +#include <ec/acpi/ec.h> +#include <ec/lenovo/h8/h8.h> +#include <northbridge/intel/nehalem/nehalem.h> +#include <southbridge/intel/bd82x6x/pch.h> + +#include <pc80/mc146818rtc.h> +#include "dock.h" +#include <arch/x86/include/arch/acpigen.h> +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE +#include <x86emu/regs.h> +#include <arch/interrupt.h> +#endif +#include <pc80/keyboard.h> +#include <cpu/x86/lapic.h> +#include <device/pci.h> +#include <smbios.h> + +static acpi_cstate_t cst_entries[] = { + {1, 1, 1000, {0x7f, 1, 2, {0}, 1, 0}}, + {2, 1, 500, {0x01, 8, 0, {0}, DEFAULT_PMBASE + LV2, 0}}, + {2, 17, 250, {0x01, 8, 0, {0}, DEFAULT_PMBASE + LV3, 0}}, +}; + +int get_cst_entries(acpi_cstate_t ** entries) +{ + *entries = cst_entries; + return ARRAY_SIZE(cst_entries); +} + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE + +static int int15_handler(void) +{ + switch ((X86_EAX & 0xffff)) { + /* Get boot display. */ + case 0x5f35: + X86_EAX = 0x5f; +#if 0 + /* DisplayPort */ + X86_ECX = 0x4; + /* VGA */ + X86_ECX = 0x1; +#endif + /* LCD */ + X86_ECX = 0x8; + + return 1; + case 0x5f40: + X86_EAX = 0x5f; + X86_ECX = 0x2; + return 1; + default: + printk(BIOS_WARNING, "Unknown INT15 function %04x!\n", + X86_EAX & 0xffff); + return 0; + } +} +#endif + +static void rcba_config(void) +{ +#if 0 +#if 0 + u32 reg32; + + /* + * GFX INTA -> PIRQA (MSI) + * D28IP_P1IP WLAN INTA -> PIRQB + * D28IP_P4IP ETH0 INTB -> PIRQC (MSI) + * D29IP_E1P EHCI1 INTA -> PIRQD + * D26IP_E2P EHCI2 INTA -> PIRQB + * D31IP_SIP SATA INTA -> PIRQA (MSI) + * D31IP_SMIP SMBUS INTC -> PIRQH + * D31IP_TTIP THRT INTB -> PIRQG + * D27IP_ZIP HDA INTA -> PIRQG (MSI) + * + * LIGHTSENSOR -> PIRQE (Edge Triggered) + * TRACKPAD -> PIRQF (Edge Triggered) + */ + /* Device interrupt pin register (board specific) */ + RCBA32(D31IP) = (INTD << D31IP_TTIP) | (INTC << D31IP_SIP2) | + (INTD << D31IP_UNKIP) | (INTA << D31IP_SMIP) | (INTB << D31IP_SIP); + RCBA32(D30IP) = (NOINT << D30IP_PIP); + RCBA32(D29IP) = 0x40043214; //(INTA << D29IP_E1P); + RCBA32(D28IP) = 0x00014321; //(INTA << D28IP_P1IP) | (INTC << D28IP_P3IP) | + // (INTB << D28IP_P4IP); + RCBA32(D27IP) = 0x00000002; //(INTA << D27IP_ZIP); + RCBA32(D26IP) = 0x30003214; //(INTA << D26IP_E2P); + RCBA32(D25IP) = (NOINT << D25IP_LIP); + RCBA32(D22IP) = (NOINT << D22IP_MEI1IP); +#endif + RCBA32(0x30fc) = 0x00000000; + (void)RCBA32(0x30fc); + RCBA32(0x3100) = 0x04341200; + (void)RCBA32(0x3100); + RCBA32(0x3104) = 0x00000000; + (void)RCBA32(0x3104); + RCBA32(0x3108) = 0x40043214; + (void)RCBA32(0x3108); + RCBA32(0x310c) = 0x00014321; + (void)RCBA32(0x310c); + RCBA32(0x3110) = 0x00000002; + (void)RCBA32(0x3110); + RCBA32(0x3114) = 0x30003214; + (void)RCBA32(0x3114); + RCBA32(0x311c) = 0x00000002; + (void)RCBA32(0x311c); + RCBA32(0x3120) = 0x00000000; + (void)RCBA32(0x3120); + RCBA32(0x3124) = 0x00002321; + (void)RCBA32(0x3124); + RCBA32(0x313c) = 0x00000000; + (void)RCBA32(0x313c); + RCBA32(0x3140) = 0x00003107; + (void)RCBA32(0x3140); + RCBA32(0x3144) = 0x76543210; + (void)RCBA32(0x3144); + RCBA32(0x3148) = 0x00000010; + (void)RCBA32(0x3148); + RCBA32(0x314c) = 0x00007654; + (void)RCBA32(0x314c); + RCBA32(0x3150) = 0x00000004; + (void)RCBA32(0x3150); + RCBA32(0x3158) = 0x00000000; + (void)RCBA32(0x3158); + RCBA32(0x315c) = 0x00003210; + (void)RCBA32(0x315c); + RCBA32(0x31fc) = 0x03000000; + (void)RCBA32(0x31fc); + +#if 0 + /* Device interrupt route registers */ + DIR_ROUTE(D31IR, PIRQA, PIRQG, PIRQH, PIRQB); + DIR_ROUTE(D29IR, PIRQD, PIRQE, PIRQG, PIRQH); + DIR_ROUTE(D28IR, PIRQB, PIRQC, PIRQD, PIRQE); + DIR_ROUTE(D27IR, PIRQG, PIRQH, PIRQA, PIRQB); + DIR_ROUTE(D26IR, PIRQB, PIRQC, PIRQD, PIRQA); + DIR_ROUTE(D25IR, PIRQA, PIRQB, PIRQC, PIRQD); + DIR_ROUTE(D22IR, PIRQA, PIRQB, PIRQC, PIRQD); + /* Enable IOAPIC (generic) */ + RCBA16(OIC) = 0x0100; + /* PCH BWG says to read back the IOAPIC enable register */ + (void)RCBA16(OIC); + /* Disable unused devices (board specific) */ + reg32 = RCBA32(FD); + reg32 |= PCH_DISABLE_ALWAYS; + RCBA32(FD) = reg32; +#endif + +#if 0 + RCBA32(0x3418) = 0x16e61fe1; + (void)RCBA32(0x3418); +#endif +#endif +} + +const char *smbios_mainboard_version(void) +{ + return "Lenovo X201"; +} + +static void mainboard_enable(device_t dev) +{ + device_t dev0; + u16 pmbase; + + printk(BIOS_SPEW, "starting SPI configure\n"); + + /* Configure SPI. */ + RCBA32(0x3800) = 0x07ff0500; + RCBA32(0x3804) = 0x3f046008; + RCBA32(0x3808) = 0x0058efc0; + RCBA32(0x384c) = 0x92000000; + RCBA32(0x3850) = 0x00000a0b; + RCBA32(0x3858) = 0x07ff0500; + RCBA32(0x385c) = 0x04ff0003; + RCBA32(0x3860) = 0x00020001; + RCBA32(0x3864) = 0x00000fff; + RCBA32(0x3874) = 0; + RCBA32(0x3890) = 0xf8400000; + RCBA32(0x3894) = 0x143b5006; + RCBA32(0x3898) = 0x05200302; + RCBA32(0x389c) = 0x0601209f; + RCBA32(0x38b0) = 0x00000004; + RCBA32(0x38b4) = 0x03040002; + RCBA32(0x38c0) = 0x00000007; + RCBA32(0x38c4) = 0x00802005; + RCBA32(0x38c8) = 0x00002005; + RCBA32(0x3804) = 0x3f04e008; + + printk(BIOS_SPEW, "SPI configured\n"); + + pmbase = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), + PMBASE) & 0xff80; + + printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase); + + outl(0, pmbase + SMI_EN); + + enable_lapic(); + pci_write_config32(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), GPIO_BASE, + DEFAULT_GPIOBASE | 1); + pci_write_config8(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), GPIO_CNTL, + 0x10); + + rcba_config(); + +#ifdef DISABLED + ec_clr_bit(0x03, 2); + + if (inb(0x164c) & 0x08) { + ec_set_bit(0x03, 2); + ec_write(0x0c, 0x88); + } +#endif + /* If we're resuming from suspend, blink suspend LED */ + dev0 = dev_find_slot(0, PCI_DEVFN(0, 0)); + if (dev0 && pci_read_config32(dev0, SKPAD) == SKPAD_ACPI_S3_MAGIC) + ec_write(0x0c, 0xc7); + +#ifdef DISABLED + idedev = dev_find_slot(0, PCI_DEVFN(0x1f, 1)); + if (idedev && idedev->chip_info && dock_ultrabay_device_present()) { + struct southbridge_intel_i82801gx_config *config = + idedev->chip_info; + config->ide_enable_primary = 1; + /* enable Ultrabay power */ + outb(inb(0x1628) | 0x01, 0x1628); + ec_write(0x0c, 0x84); + } else { + /* disable Ultrabay power */ + outb(inb(0x1628) & ~0x01, 0x1628); + ec_write(0x0c, 0x04); + } +#endif + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE + /* Install custom int15 handler for VGA OPROM */ + mainboard_interrupt_handlers(0x15, &int15_handler); +#endif + + /* This sneaked in here, because X201 SuperIO chip isn't really + connected to anything and hence we don't init it. + */ + pc_keyboard_init(0); +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; diff --git a/src/mainboard/lenovo/x201/mptable.c b/src/mainboard/lenovo/x201/mptable.c new file mode 100644 index 0000000..84364a0 --- /dev/null +++ b/src/mainboard/lenovo/x201/mptable.c @@ -0,0 +1,82 @@ +/* generated by MPTable, version 2.0.15*/ +/* as modified by RGM for coreboot */ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <arch/ioapic.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +#define INTA 0x00 +#define INTB 0x01 +#define INTC 0x02 +#define INTD 0x03 + +static void *smp_write_config_table(void *v) +{ + struct mp_config_table *mc; + int isa_bus; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + + mptable_init(mc, LOCAL_APIC_ADDR); + + smp_write_processors(mc); + + mptable_write_buses(mc, NULL, &isa_bus); + /* I/O APICs: APIC ID Version State Address */ + smp_write_ioapic(mc, 0x2, 0x20, 0xfec00000); + + mptable_add_isa_interrupts(mc, isa_bus, 0x2, 0); + + /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ + smp_write_intsrc(mc, mp_ExtINT, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 0x3, 0x0, + 0x2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x1, 0x2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x0, 0x2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x3, 0x2, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x4, 0x2, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x5, 0x2, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x6, 0x2, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x7, 0x2, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x8, 0x2, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0x9, 0x2, 0x9); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0xa, 0x2, 0xa); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0xb, 0x2, 0xb); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0xc, 0x2, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0xd, 0x2, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0xe, 0x2, 0xe); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, + 0x3, 0xf, 0x2, 0xf); + /* Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ + smp_write_lintsrc(mc, mp_ExtINT, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 0x3, 0x0, + MP_APIC_ALL, 0x0); + smp_write_lintsrc(mc, mp_NMI, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 0x3, 0x0, + MP_APIC_ALL, 0x1); + + return mptable_finalize(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr, 0); + return (unsigned long)smp_write_config_table(v); +} diff --git a/src/mainboard/lenovo/x201/romstage.c b/src/mainboard/lenovo/x201/romstage.c new file mode 100644 index 0000000..9bf0254 --- /dev/null +++ b/src/mainboard/lenovo/x201/romstage.c @@ -0,0 +1,413 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * 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 + */ + +// __PRE_RAM__ means: use "unsigned" for device, not a struct. + +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pnp_def.h> +#include <cpu/x86/lapic.h> +#include <lib.h> +#include <pc80/mc146818rtc.h> +#include <console/console.h> +#include <cpu/x86/bist.h> +#include <ec/acpi/ec.h> +#include <delay.h> +#include <timestamp.h> + +#include "gpio.h" +#include "dock.h" +#include "arch/early_variables.h" +#include "southbridge/intel/ibexpeak/pch.h" +#include "southbridge/intel/bd82x6x/gpio.h" +#include "northbridge/intel/nehalem/nehalem.h" + +#include "northbridge/intel/nehalem/raminit.h" +#include "southbridge/intel/bd82x6x/pch.h" +#include "southbridge/intel/bd82x6x/gpio.h" +#include "southbridge/intel/bd82x6x/me.h" + +static void pch_enable_lpc(void) +{ + /* Parrot EC Decode Range Port60/64, Port62/66 */ + /* Enable EC, PS/2 Keyboard/Mouse */ + pci_write_config16(PCH_LPC_DEV, LPC_EN, + CNF2_LPC_EN | CNF1_LPC_EN | MC_LPC_EN | KBC_LPC_EN | + COMA_LPC_EN); + + pci_write_config32(PCH_LPC_DEV, LPC_GEN1_DEC, 0x7c1601); + pci_write_config32(PCH_LPC_DEV, LPC_GEN2_DEC, 0xc15e1); + pci_write_config32(PCH_LPC_DEV, LPC_GEN3_DEC, 0x1c1681); + pci_write_config32(PCH_LPC_DEV, LPC_GEN4_DEC, (0x68 & ~3) | 0x00040001); + + pci_write_config16(PCH_LPC_DEV, LPC_IO_DEC, 0x10); + + pci_write_config32(PCH_LPC_DEV, 0xd0, 0x0); + pci_write_config32(PCH_LPC_DEV, 0xdc, 0x0); + + pci_write_config8(PCH_LPC_DEV, GEN_PMCON_3, + (pci_read_config8(PCH_LPC_DEV, GEN_PMCON_3) & ~2) | 1); + + pci_write_config32(PCH_LPC_DEV, ETR3, + pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR); +} + +static void rcba_config(void) +{ + static const u32 rcba_dump3[] = { + /* 30fc */ 0x00000000, + /* 3100 */ 0x04341200, 0x00000000, 0x40043214, 0x00014321, + /* 3110 */ 0x00000002, 0x30003214, 0x00000001, 0x00000002, + /* 3120 */ 0x00000000, 0x00002321, 0x00000000, 0x00000000, + /* 3130 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3140 */ 0x00003107, 0x76543210, 0x00000010, 0x00007654, + /* 3150 */ 0x00000004, 0x00000000, 0x00000000, 0x00003210, + /* 3160 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3170 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3180 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3190 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31f0 */ 0x00000000, 0x00000000, 0x00000000, 0x03000000, + /* 3200 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3210 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3220 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3230 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3240 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3250 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3260 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3270 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3280 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3290 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3300 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3310 */ 0x02060100, 0x0000000f, 0x01020000, 0x80000000, + /* 3320 */ 0x00000000, 0x04000000, 0x00000000, 0x00000000, + /* 3330 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3340 */ 0x000fffff, 0x00000000, 0x00000000, 0x00000000, + /* 3350 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3360 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3370 */ 0x00000000, 0x00000000, 0x7f8fdfff, 0x00000000, + /* 3380 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3390 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 33a0 */ 0x00003900, 0x00000000, 0x00000000, 0x00000000, + /* 33b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 33c0 */ 0x00010000, 0x00000000, 0x00000000, 0x0001004b, + /* 33d0 */ 0x06000008, 0x00010000, 0x00000000, 0x00000000, + /* 33e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 33f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3400 */ 0x0000001c, 0x00000080, 0x00000000, 0x00000000, + /* 3410 */ 0x00000c61, 0x00000000, 0x16e61fe1, 0xbf4f001f, + /* 3420 */ 0x00000000, 0x00060010, 0x0000001d, 0x00000000, + /* 3430 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3440 */ 0xdeaddeed, 0x00000000, 0x00000000, 0x00000000, + /* 3450 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3460 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3470 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3480 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3490 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3500 */ 0x20000557, 0x2000055f, 0x2000074b, 0x2000074b, + /* 3510 */ 0x20000557, 0x2000014b, 0x2000074b, 0x2000074b, + /* 3520 */ 0x2000074b, 0x2000074b, 0x2000055f, 0x2000055f, + /* 3530 */ 0x20000557, 0x2000055f, 0x00000000, 0x00000000, + /* 3540 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3550 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3560 */ 0x00000001, 0x000026a3, 0x00040002, 0x01000052, + /* 3570 */ 0x02000772, 0x16000f8f, 0x1800ff4f, 0x0001d630, + /* 3580 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3590 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35a0 */ 0xfc000201, 0x3c000201, 0x00000000, 0x00000000, + /* 35b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3600 */ 0x0a001f00, 0x00000000, 0x00000000, 0x00000001, + /* 3610 */ 0x00010000, 0x00000000, 0x00000000, 0x00000000, + /* 3600 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3610 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3620 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3630 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3640 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3650 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3660 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3670 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3680 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3690 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36b0 */ 0x00000000, 0x089c0018, 0x00000000, 0x00000000, + /* 36c0 */ 0x11111111, 0x00000000, 0x00000000, 0x00000000, + /* 36d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3710 */ 0x00000000, 0x4e564d49, 0x00000000, 0x00000000, + }; + unsigned i; + for (i = 0; i < sizeof(rcba_dump3) / 4; i++) { + RCBA32(4 * i + 0x30fc) = rcba_dump3[i]; + (void)RCBA32(4 * i + 0x30fc); + } +} + +#include <cbmem.h> + +static void +setup_smbus_5c (void) +{ + u16 t3; + + if (MCHBAR8(0x2ca8) == 0) { + t3 = inw(DEFAULT_GPIOBASE | 0x38); + outw(t3 & ~0x400, DEFAULT_GPIOBASE | 0x38); + smbus_read_byte(0x5c, 0x06); + smbus_write_byte(0x5c, 0x06, 0x8f); + + smbus_read_byte(0x5c, 0x07); + smbus_write_byte(0x5c, 0x07, 0x8f); + + outw(t3 | 0x400, DEFAULT_GPIOBASE | 0x38); + } + + t3 = inw(DEFAULT_GPIOBASE | 0x38); + outw(t3 & ~0x400, DEFAULT_GPIOBASE | 0x38); + + smbus_read_byte(0x57, 0x55); + outw(t3 | 0x400, DEFAULT_GPIOBASE | 0x38); +} + +#if CONFIG_COLLECT_TIMESTAMPS +tsc_t before_spd CAR_GLOBAL, after_spd CAR_GLOBAL, before_training CAR_GLOBAL, + after_training CAR_GLOBAL; +#endif + +static inline void write_acpi32(u32 addr, u32 val) +{ + outl(val, DEFAULT_PMBASE | addr); +} + +static inline void write_acpi16(u32 addr, u16 val) +{ + outw(val, DEFAULT_PMBASE | addr); +} + +static inline u32 read_acpi32(u32 addr) +{ + return inl(DEFAULT_PMBASE | addr); +} + +static inline u16 read_acpi16(u32 addr) +{ + return inw(DEFAULT_PMBASE | addr); +} + +void main(unsigned long bist) +{ + u32 reg32; + int s3resume = 0; +#if CONFIG_COLLECT_TIMESTAMPS + tsc_t start_romstage_time; + tsc_t before_dram_time; + tsc_t after_dram_time; + tsc_t base_time = rdtsc(); +#endif + +#if CONFIG_COLLECT_TIMESTAMPS + start_romstage_time = base_time; +#endif + + if (bist == 0) + enable_lapic(); + + /* Force PCIRST# */ + pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, SBR); + pci_write_config16(PCI_DEV(0, 0, 0), BCTRL, SBR); + udelay(200 * 1000); + pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, 0); + pci_write_config16(PCI_DEV(0, 0, 0), BCTRL, 0); + + /* Enable USB Power. */ + ec_set_bit(0x3b, 4); + + pch_enable_lpc(); + + /* Enable GPIOs */ + pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1); + pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10); + + setup_pch_gpios(&x201_gpio_map); + + nehalem_early_initialization(NEHALEM_MOBILE); + + /* This should probably go away. Until now it is required + * and mainboard specific + */ + rcba_config(); + + console_init(); + + /* Halt if there was a built in self test failure */ + report_bist_failure(bist); + + /* Read PM1_CNT */ + reg32 = inl(DEFAULT_PMBASE + 0x04); + printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32); + if (((reg32 >> 10) & 7) == 5) { + u8 reg8; + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2); + printk(BIOS_DEBUG, "a2: %02x\n", reg8); + if (!(reg8 & 0x20)) { + outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04); + printk(BIOS_DEBUG, "Bad resume from S3 detected.\n"); + } else { +#if CONFIG_HAVE_ACPI_RESUME + printk(BIOS_DEBUG, "Resume from S3 detected.\n"); + s3resume = 1; +#else + printk(BIOS_DEBUG, + "Resume from S3 detected, but disabled.\n"); +#endif + } + } + + /* Enable SMBUS. */ + enable_smbus(); + + setup_smbus_5c (); + + outb((inb(DEFAULT_GPIOBASE | 0x3a) & ~0x2) | 0x20, + DEFAULT_GPIOBASE | 0x3a); + outb(0x50, 0x15ec); + outb(inb(0x15ee) & 0x70, 0x15ee); + + write_acpi16(0x2, 0x0); + write_acpi32(0x28, 0x0); + write_acpi32(0x2c, 0x0); + if (!s3resume) { + read_acpi32(0x4); + read_acpi32(0x20); + read_acpi32(0x34); + write_acpi16(0x0, 0x900); + write_acpi32(0x20, 0xffff7ffe); + write_acpi32(0x34, 0x56974); + pci_write_config8(PCH_LPC_DEV, GEN_PMCON_3, + pci_read_config8(PCH_LPC_DEV, GEN_PMCON_3) | 2); + } + +#if CONFIG_COLLECT_TIMESTAMPS + before_dram_time = rdtsc(); +#endif + + raminit(s3resume); +#if CONFIG_COLLECT_TIMESTAMPS + after_dram_time = rdtsc(); +#endif + + intel_early_me_status(); + + if (s3resume) { + /* Clear SLP_TYPE. This will break stage2 but + * we care for that when we get there. + */ + reg32 = inl(DEFAULT_PMBASE + 0x04); + outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04); + } +#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_reinit()) { + void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME); +#if 0 + s3_checksum(); +#endif + /* for (i = 0; i < 65536; i++) + if (read8 (i) != read8 (i + 0x100000)) + printk (BIOS_ERR, "Corruption at %x: %x vs %x\n", i, + read8 (i), read8 (i + 0x100000)); */ + + /* 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); +#if 0 + printk(BIOS_ERR, "move: %x, %x, %x\n", + (unsigned)resume_backup_memory, (unsigned)CONFIG_RAMBASE, + (unsigned)HIGH_MEMORY_SAVE); + + s = 0; + for (j = 0; j < 0x100000; j += 4) + s += ((u32 *) resume_backup_memory)[j / 4]; + if (((u8 *) (72 << 20))[1] != s % 255) { + printk(BIOS_ERR, "MiB 1 (copy) corrupted %x vs %x\n", + ((u8 *) (72 << 20))[1], s % 255); + } else + printk(BIOS_ERR, "MiB 1 (copy) ok %x == %x\n", + ((u8 *) (72 << 20))[1], s % 255); +#endif + /* Magic for S3 resume */ + pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d); + } else if (s3resume) { + printk(BIOS_ERR, "Failed S3 resume.\n"); + ram_check(0x100000, 0x200000); + + /* Failed S3 resume, reset to come up cleanly */ + outb(0xe, 0xcf9); + hlt(); + } else { + pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafebabe); + quick_ram_check(); + } +#endif + +#if CONFIG_COLLECT_TIMESTAMPS + timestamp_init(base_time); + timestamp_add(TS_START_ROMSTAGE, start_romstage_time); + timestamp_add(TS_BEFORE_INITRAM, before_dram_time); + timestamp_add(101, before_spd); + timestamp_add(102, after_spd); + timestamp_add(103, before_training); + timestamp_add(104, after_training); + timestamp_add(TS_AFTER_INITRAM, after_dram_time); + timestamp_add_now(TS_END_ROMSTAGE); +#endif +} diff --git a/src/mainboard/lenovo/x201/smi.h b/src/mainboard/lenovo/x201/smi.h new file mode 100644 index 0000000..c5f48a1 --- /dev/null +++ b/src/mainboard/lenovo/x201/smi.h @@ -0,0 +1,27 @@ +/* + * 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 MAINBOARD_LENOVO_X60_SMI_H +#define MAINBOARD_LENOVO_X60_SMI_H + +#define SMI_DOCK_CONNECT 0x01 +#define SMI_DOCK_DISCONNECT 0x02 +#define SMI_SAVE_CMOS 0x03 + +#endif diff --git a/src/mainboard/lenovo/x201/smihandler.c b/src/mainboard/lenovo/x201/smihandler.c new file mode 100644 index 0000000..edc93f5 --- /dev/null +++ b/src/mainboard/lenovo/x201/smihandler.c @@ -0,0 +1,210 @@ +/* + * 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/i82801gx/nvs.h" +#include "southbridge/intel/i82801gx/i82801gx.h" +#include <ec/acpi/ec.h> +#include <pc80/mc146818rtc.h> +#include <ec/lenovo/h8/h8.h> +#include <delay.h> +#include "dock.h" +#include "smi.h" + +/* The southbridge SMI handler checks whether gnvs has a + * valid pointer before calling the trap handler + */ +extern global_nvs_t *gnvs; + +static void mainboard_smm_init(void) +{ + printk(BIOS_DEBUG, "initializing SMI\n"); + /* Enable 0x1600/0x1600 register pair */ + ec_set_bit(0x00, 0x05); +} + +static void mainboard_smi_save_cmos(void) +{ + u8 val; + u8 tmp70, tmp72; + + tmp70 = inb(0x70); + tmp72 = inb(0x72); + + val = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4); + set_option("tft_brightness", &val); + val = ec_read(H8_VOLUME_CONTROL); + set_option("volume", &val); + + outb(tmp70, 0x70); + outb(tmp72, 0x72); +} + +int mainboard_io_trap_handler(int smif) +{ + static int smm_initialized; + + if (!smm_initialized) { + mainboard_smm_init(); + smm_initialized = 1; + } + + switch (smif) { + case SMI_DOCK_CONNECT: + ec_clr_bit(0x03, 2); + udelay(250000); + if (!dock_connect()) { + ec_set_bit(0x03, 2); + /* set dock LED to indicate status */ + ec_write(0x0c, 0x09); + ec_write(0x0c, 0x88); + } else { + /* blink dock LED to indicate failure */ + ec_write(0x0c, 0x08); + ec_write(0x0c, 0xc9); + } + break; + + case SMI_DOCK_DISCONNECT: + ec_clr_bit(0x03, 2); + dock_disconnect(); + break; + + case SMI_SAVE_CMOS: + mainboard_smi_save_cmos(); + break; + default: + return 0; + } + + /* On success, the IO Trap Handler returns 1 + * On failure, the IO Trap Handler returns a value != 1 */ + return 1; +} + +static void mainboard_smi_brightness_up(void) +{ + u8 value; + + if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) < 0xf0) + pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf); +} + +static void mainboard_smi_brightness_down(void) +{ + u8 value; + + if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) > 0x10) + pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, + (value - 0x10) & 0xf0); +} + +static void mainboard_smi_handle_ec_sci(void) +{ + u8 status = inb(EC_SC); + u8 event; + + if (!(status & EC_SCI_EVT)) + return; + + event = ec_query(); + printk(BIOS_DEBUG, "EC event %02x\n", event); + + switch (event) { + /* brightness up */ + case 0x14: + mainboard_smi_brightness_up(); + mainboard_smi_save_cmos(); + break; + /* brightness down */ + case 0x15: + mainboard_smi_brightness_down(); + mainboard_smi_save_cmos(); + break; + /* Fn-F9 key */ + case 0x18: + /* Power loss */ + case 0x27: + /* Undock Key */ + case 0x50: + mainboard_io_trap_handler(SMI_DOCK_DISCONNECT); + break; + /* Dock Event */ + case 0x37: + case 0x58: + mainboard_io_trap_handler(SMI_DOCK_CONNECT); + break; + default: + break; + } +} + +void mainboard_smi_gpi(u16 gpi) +{ + if (gpi & (1 << 12)) + mainboard_smi_handle_ec_sci(); +} + +int mainboard_smi_apmc(u8 data) +{ + u16 pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc; + u8 tmp; + + printk(BIOS_DEBUG, "%s: pmbase %04X, data %02X\n", __func__, pmbase, + data); + + if (!pmbase) + return 0; + + switch (data) { + case APM_CNT_ACPI_ENABLE: + /* use 0x1600/0x1604 to prevent races with userspace */ + ec_set_ports(0x1604, 0x1600); + /* route H8SCI to SCI */ + outw(inw(ALT_GP_SMI_EN) & ~0x1000, pmbase + ALT_GP_SMI_EN); + tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb); + tmp &= ~0x03; + tmp |= 0x02; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp); + /* discard all events, and enable attention */ + ec_write(0x80, 0x01); + break; + case APM_CNT_ACPI_DISABLE: + /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't + provide a EC query function */ + ec_set_ports(0x66, 0x62); + /* route H8SCI# to SMI */ + outw(inw(pmbase + ALT_GP_SMI_EN) | 0x1000, + pmbase + ALT_GP_SMI_EN); + tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb); + tmp &= ~0x03; + tmp |= 0x01; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp); + /* discard all events, and enable attention */ + ec_write(0x80, 0x01); + break; + default: + break; + } + return 0; +}