diff options
author | Patrick Georgi <patrick.georgi@secunet.com> | 2012-11-06 11:05:38 +0100 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2012-11-27 09:17:05 +0100 |
commit | 021b7033fb578258844bf8ecad9f2d34b16b674b (patch) | |
tree | 836aea10485b00d3e93a8af99e73ba25f85a2aec | |
parent | e72a8a3047c535bda03aecce2eca134608d1a93c (diff) |
roda/rk9: New mainboard
Roda RK9 is a notebook based on the GM45/ICH9 platform using DDR3 memory.
http://roda-computer.com/products/notebooks/rk9/
Tested with various Linux versions, known to work:
- 2x4GB RAM
- IGD
- HD Audio
- UHCI, EHCI
- AHCI
- NIC
- PCI
- PS/2 keyboard
- serial console
- ACPI lid switch
- ACPI battery/AC events
- power off, reboot
Change-Id: I7299dccbff2eea3544363fdd4f49f05aa3dae7bc
Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com>
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: http://review.coreboot.org/1691
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
25 files changed, 3038 insertions, 0 deletions
diff --git a/src/mainboard/roda/Kconfig b/src/mainboard/roda/Kconfig index ba4b6ec13a..b70ce33421 100644 --- a/src/mainboard/roda/Kconfig +++ b/src/mainboard/roda/Kconfig @@ -6,9 +6,13 @@ choice config BOARD_RODA_RK886EX bool "RK886EX" +config BOARD_RODA_RK9 + bool "RK9" + endchoice source "src/mainboard/roda/rk886ex/Kconfig" +source "src/mainboard/roda/rk9/Kconfig" config MAINBOARD_VENDOR string diff --git a/src/mainboard/roda/rk9/Kconfig b/src/mainboard/roda/rk9/Kconfig new file mode 100644 index 0000000000..dd9e940220 --- /dev/null +++ b/src/mainboard/roda/rk9/Kconfig @@ -0,0 +1,46 @@ +if BOARD_RODA_RK9 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select ARCH_X86 + select CPU_INTEL_SOCKET_BGA956 + select NORTHBRIDGE_INTEL_GM45 + select SOUTHBRIDGE_INTEL_I82801IX + select SUPERIO_SMSC_LPC47N227 + select MMCONF_SUPPORT + select BOARD_ROMSIZE_KB_4096 + select RTL8168_ROM_DISABLE + select DRIVERS_GENERIC_IOAPIC + select HAVE_MP_TABLE + select CARDBUS_PLUGIN_SUPPORT + select BOARD_HAS_FADT + select HAVE_ACPI_TABLES + #select HAVE_ACPI_RESUME + select EC_ACPI + select HAVE_OPTION_TABLE + +config MAINBOARD_DIR + string + default roda/rk9 + +config MAINBOARD_PART_NUMBER + string + default "RK9" + +config MMCONF_BASE_ADDRESS + hex + default 0xf0000000 + +config IRQ_SLOT_COUNT + int + default 18 + +config MAX_CPUS + int + default 2 + +config MAX_PHYSICAL_CPUS + int + default 1 + +endif # BOARD_RODA_RK9 diff --git a/src/mainboard/roda/rk9/Makefile.inc b/src/mainboard/roda/rk9/Makefile.inc new file mode 100644 index 0000000000..27feaab07a --- /dev/null +++ b/src/mainboard/roda/rk9/Makefile.inc @@ -0,0 +1,21 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2012 secunet Security Networks AG +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +driver-$(CONFIG_CARDBUS_PLUGIN_SUPPORT) += ti_pci7xx1.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c diff --git a/src/mainboard/roda/rk9/acpi/battery.asl b/src/mainboard/roda/rk9/acpi/battery.asl new file mode 100644 index 0000000000..3eb9b14e49 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/battery.asl @@ -0,0 +1,232 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 coresystems GmbH + * Copyright (C) 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +Name(\CBA1, 0x60) +Name(\CBA2, 0x60) + +/* ACPI doesn't care if capacity is given in mWh or mAh, + but it has to be consistent */ + +Device (BAT1) +{ + Name(_HID, EisaId("PNP0C0A")) + Name(_UID, 1) + + Name(_PCL, Package(){ _SB }) + Name(PSTA, 0x1f) + + /* battery information */ + Name(PBIF, Package() { + 0x01, // power unit + 0x01, // design capacity (mWh/mAh), updated by UPBI + 0x01, // last full charge capacity (mWh/mAh), updated by UPBI + 0x01, // battery technology: "rechargeable" + 0x01, // design voltage (mV), updated by UPBI + 0x0294, // design capacity of warning (mWh/mAh) + 0x014a, // design capacity of low (mWh/mAh) + 0x42, // battery capacity granularity between low and warning + 0x42, // battery capacity granularity between warning and full + "BAT1", // Name + "001 ", // Number + "LION", // Type + "JSE" // Vendor + }) + /* battery status */ + /* dummy values, filled in by UPBS */ + Name(PBST, Package() { + 0x00, // battery state + // bit0: discharging + // bit1: charging + // bit2: critical energy state + 0x01, // battery present rate (mW/mA) + 0x01, // remaining capacity (mW/mA) + 0x01 // battery present voltage (mV) + }) + + /* Status */ + Method(_STA, 0) + { + If(\_SB.PCI0.LPCB.EC0.ECON) { + If(\_SB.PCI0.LPCB.EC0.B1PR) { + If(\_SB.PCI0.LPCB.EC0.B1CH) { + Return(0x1f) + } + } + } + Return(0x0f) + } + + /* Battery Info */ + Method(_BIF, 0) + { + If(\_SB.PCI0.LPCB.EC0.ECON) { + Store (\_SB.PCI0.LPCB.EC0.B1DW, Index(PBIF, 1)) + Store (\_SB.PCI0.LPCB.EC0.B1FW, Index(PBIF, 2)) + Store (\_SB.PCI0.LPCB.EC0.B1DV, Index(PBIF, 4)) + } + + Return(PBIF) + } + + /* Battery Status */ + Method(_BST, 0) + { + If(\_SB.PCI0.LPCB.EC0.ECON) { + Store (\_SB.PCI0.LPCB.EC0.B1PW, Local0) + If (LGreaterEqual (Local0, 0x8000)) { + Subtract (0x10000, Local0, Local0) + } + Store (Local0, Index(PBST, 1)) + Store (\_SB.PCI0.LPCB.EC0.B1PV, Index(PBST, 3)) + + Store (\_SB.PCI0.LPCB.EC0.B1RW, Index(PBST, 2)) + + If (\_SB.PCI0.LPCB.EC0.ACCH) { + If (\_SB.PCI0.LPCB.EC0.B1CH) { + If (\_SB.PCI0.LPCB.EC0.B1CG) { + Store (2, Index(PBST, 0)) + } + } + } Else { + If (\_SB.PCI0.LPCB.EC0.B1LO) { + Store (5, Index(PBST, 0)) + } Else { + Store (1, Index(PBST, 0)) + } + } + } + + Return(PBST) + } + +} + +Device (BAT2) +{ + Name(_HID, EisaId("PNP0C0A")) + Name(_UID, 2) + + Name(_PCL, Package(){ _SB }) + Name(PSTA, 0x1f) + + /* battery information */ + Name(PBIF, Package() { + 0x01, // power unit + 0x01, // design capacity (mWh/mAh), updated by UPBI + 0x01, // last full charge capacity (mWh/mAh), updated by UPBI + 0x01, // battery technology: "rechargeable" + 0x01, // design voltage (mV), updated by UPBI + 0x0294, // design capacity of warning (mWh/mAh) + 0x014a, // design capacity of low (mWh/mAh) + 0x42, // battery capacity granularity between low and warning + 0x42, // battery capacity granularity between warning and full + "BAT1", // Name + "002 ", // Number + "LION", // Type + "JSE" // Vendor + }) + /* battery status */ + /* dummy values, filled in by UPBS */ + Name(PBST, Package() { + 0x00, // battery state + // bit0: discharging + // bit1: charging + // bit2: critical energy state + 0x01, // battery present rate (mW/mA) + 0x01, // remaining capacity (mW/mA) + 0x01 // battery present voltage (mV) + }) + + /* Status */ + Method(_STA, 0) + { + If(\_SB.PCI0.LPCB.EC0.ECON) { + If(\_SB.PCI0.LPCB.EC0.B2PR) { + If(\_SB.PCI0.LPCB.EC0.B2CH) { + Return(0x1f) + } + } + } + Return(0x0f) + } + + /* Battery Info */ + Method(_BIF, 0) + { + If(\_SB.PCI0.LPCB.EC0.ECON) { + Store (\_SB.PCI0.LPCB.EC0.B2DW, Index(PBIF, 1)) + Store (\_SB.PCI0.LPCB.EC0.B2FW, Index(PBIF, 2)) + Store (\_SB.PCI0.LPCB.EC0.B2DV, Index(PBIF, 4)) + } + + Return(PBIF) + } + + /* Battery Status */ + Method(_BST, 0) + { + If(\_SB.PCI0.LPCB.EC0.ECON) { + Store (\_SB.PCI0.LPCB.EC0.B2PW, Local0) + If (LGreaterEqual (Local0, 0x8000)) { + Subtract (0x10000, Local0, Local0) + } + Store (Local0, Index(PBST, 1)) + Store (\_SB.PCI0.LPCB.EC0.B2PV, Index(PBST, 3)) + + Store (\_SB.PCI0.LPCB.EC0.B2RW, Index(PBST, 2)) + + If (\_SB.PCI0.LPCB.EC0.ACCH) { + If (\_SB.PCI0.LPCB.EC0.B2CH) { + If (\_SB.PCI0.LPCB.EC0.B2CG) { + Store (2, Index(PBST, 0)) + } + } + } Else { + If (\_SB.PCI0.LPCB.EC0.B2LO) { + Store (5, Index(PBST, 0)) + } Else { + Store (1, Index(PBST, 0)) + } + } + } + + Return(PBST) + } + +} + +Device (ADP1) +{ + Name (_HID, "ACPI0003") + Method (_PSR, 0) + { + Store (\_SB.PCI0.LPCB.EC0.ACCH, PWRS) + Stall (0x02) + Return (PWRS) + } + + Method (_PCL, 0) + { + Return (_SB) + } +} + diff --git a/src/mainboard/roda/rk9/acpi/ec.asl b/src/mainboard/roda/rk9/acpi/ec.asl new file mode 100644 index 0000000000..3e6cb98cc2 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/ec.asl @@ -0,0 +1,197 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +Device(EC0) +{ + Name (_HID, EISAID("PNP0C09")) + Name (_UID, 1) + + Name (_GPE, 23) // GPI07 / GPE23 -> Runtime SCI + Name (ECON, 0) + Name (QEVT, 0) + + OperationRegion(ERAM, EmbeddedControl, 0x00, 0xff) + Field (ERAM, ByteAcc, NoLock, Preserve) + { + Offset(0xb1), + CPWR, 1, + ACCH, 1, // AC connected (charger present) + B1PR, 1, // battery 1 present + B2PR, 1, // battery 2 present + B1CH, 1, // battery 1 charged + B2CH, 1, // battery 2 charged + Offset(0xb2), + B1CG, 1, // battery 1 charging + B2CG, 1, // battery 2 charging + B1LO, 1, // battery 1 low + B2LO, 1, // battery 2 low + Offset(0xb3), + B1DW, 16, // battery 1 design capacity + B1FW, 16, // battery 1 last full charge capacity + B1DV, 16, // battery 1 design voltage + B1PW, 16, // battery 1 present capacity + Offset(0xbd), + B1PV, 16, // battery 1 present voltage + Offset(0xc1), + B2DW, 16, // battery 2 design capacity + B2FW, 16, // battery 2 last full charge capacity + B2DV, 16, // battery 2 design voltage + B2PW, 16, // battery 2 present capacity + Offset(0xcb), + B2PV, 16, // battery 2 present voltage + Offset(0xcf), + FDDI, 1, // floppy on lpt indicator? + LIDC, 1, // LID switch + Offset(0xd0), + TCPU, 8, // T_CPU in deg Celcius + Offset(0xd6), + /* exact purpose of these three is guessed, + but it's something about cooling */ + ALRL, 1, // active cooling low limit + ALRH, 1, // active cooling high limit + ALRC, 1, // active cooling clear + Offset(0xe8), + B1RW, 16, // battery 1 remaining capacity + B2RW, 16, // battery 2 remaining capacity + } + + Method (_CRS, 0) + { + Name (ECMD, ResourceTemplate() + { + IO (Decode16, 0x62, 0x62, 1, 1) + IO (Decode16, 0x66, 0x66, 1, 1) + }) + + Return (ECMD) + } + + Method (_REG, 2) + { + // This method is needed by Windows XP/2000 for + // EC initialization before a driver is loaded + + If (LEqual(Arg0, 0x03)) { + Store (Arg1, ECON) + } + } + + // EC Query methods + + Method (_Q11, 0) + { + Store("_Q11: Fn-F8 (Sleep Button) pressed", Debug) + Notify(SLPB, 0x80) + } + + Method (_Q30, 0) + { + Store("_Q30: AC In", Debug) + Notify(ADP1, 0x80) // Tell the Power Adapter + PNOT() // and the CPU and Battery + } + + Method (_Q31, 0) + { + Store("_Q31: AC Out", Debug) + Notify(ADP1, 0x80) // Tell the Power Adapter + PNOT() // and the CPU and Battery + } + + Method (_Q32, 0) + { + Store("_Q32: Bat1 In", Debug) + Notify(BAT1, 0x81) + } + + Method (_Q33, 0) + { + Store("_Q33: Bat1 Out", Debug) + Notify(BAT1, 0x81) + } + + Method (_Q34, 0) + { + Store("_Q34: Bat2 In", Debug) + Notify(BAT2, 0x81) + } + + Method (_Q35, 0) + { + Store("_Q35: Bat2 Out", Debug) + Notify(BAT2, 0x81) + } + + Method (_Q36, 0) + { + Store("_Q36: Bat1 Low Power", Debug) + Notify(BAT1, 0x80) + } + + Method (_Q37, 0) + { + Store("_Q37: Bat1 Full Charge", Debug) + Notify(BAT1, 0x80) + } + + Method (_Q38, 0) + { + Store("_Q38: Bat2 Low Power", Debug) + Notify(BAT2, 0x80) + } + + Method (_Q39, 0) + { + Store("_Q39: Bat2 Full Charge", Debug) + Notify(BAT2, 0x80) + } + + Method (_Q40, 0) + { + Store("_Q40: LID Open/Close", Debug) + Notify(LID0, 0x80) + } + + Method (_Q41, 0) + { + Store("_Q41: Floppy on Parallel Port: Call the Museum!", Debug) + } + + Method (_Q50, 0) + { + Store("_Q50: Processor is hot", Debug) + Notify(\_TZ.THRM, 0x80) + } + + Method (_Q51, 0) + { + Store("_Q51: Processor is boiling", Debug) + Notify(\_TZ.THRM, 0x80) + } + + Method (_Q52, 0) + { + Store("_Q52: Processor is burning", Debug) + Notify(\_TZ.THRM, 0x80) + } + +} diff --git a/src/mainboard/roda/rk9/acpi/gm45_pci_irqs.asl b/src/mainboard/roda/rk9/acpi/gm45_pci_irqs.asl new file mode 100644 index 0000000000..83c7762601 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/gm45_pci_irqs.asl @@ -0,0 +1,86 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* This is board specific information: IRQ routing for the + * gm45 + */ + + +// PCI Interrupt Routing +Method(_PRT) +{ + If (PICM) { + Return (Package() { + // PCIe Graphics 0:1.0 + Package() { 0x0001ffff, 0, 0, 16 }, + // Onboard graphics (IGD) 0:2.0 + Package() { 0x0002ffff, 0, 0, 16 }, + // USB and EHCI 0:1a.x + Package() { 0x001affff, 0, 0, 16 }, + Package() { 0x001affff, 1, 0, 17 }, + Package() { 0x001affff, 2, 0, 18 }, + // High Definition Audio 0:1b.0 + Package() { 0x001bffff, 0, 0, 16 }, + // PCIe Root Ports 0:1c.x + Package() { 0x001cffff, 0, 0, 16 }, + // USB and EHCI 0:1d.x + Package() { 0x001dffff, 0, 0, 16 }, + Package() { 0x001dffff, 1, 0, 17 }, + Package() { 0x001dffff, 2, 0, 18 }, + // FIXME + // CardBus/IEEE1394 0:1e.2, 0:1e.3 + // Package() { 0x001effff, 0, 0, 22 }, + // Package() { 0x001effff, 1, 0, 20 }, + // LPC device 0:1f.0 + Package() { 0x001fffff, 0, 0, 16 }, + Package() { 0x001fffff, 1, 0, 17 }, + Package() { 0x001fffff, 2, 0, 18 } + }) + } Else { + Return (Package() { + // PCIe Graphics 0:1.0 + Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + // Onboard graphics (IGD) 0:2.0 + Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + // USB and EHCI 0:1a.x + Package() { 0x001affff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001affff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x001affff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, + // High Definition Audio 0:1b.0 + Package() { 0x001bffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + // PCIe Root Ports 0:1c.x + Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + // USB and EHCI 0:1d.x + Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001dffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x001dffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, + // FIXME + // CardBus/IEEE1394 0:1e.2, 0:1e.3 + // Package() { 0x001effff, 0, \_SB.PCI0.LPCB.LNKG, 0 }, + // Package() { 0x001effff, 1, \_SB.PCI0.LPCB.LNKE, 0 }, + // LPC device 0:1f.0 + Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x001fffff, 2, \_SB.PCI0.LPCB.LNKC, 0 } + }) + } +} + diff --git a/src/mainboard/roda/rk9/acpi/gpe.asl b/src/mainboard/roda/rk9/acpi/gpe.asl new file mode 100644 index 0000000000..58540063da --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/gpe.asl @@ -0,0 +1,120 @@ +/* + * 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 + */ + +Scope (_GPE) +{ + /* The event numbers correspond to the bit numbers in the + * GPE0_EN register PMBASE + 0x28. + */ + /* IMO we don't need empty Methods here. If we don't specify + one and don't set the GPE0_EN bit Linux won't neither enable + it. - Nico */ + + // Thermal Event - original BIOS doesn't have it + Method (_L00, 0) + { + /* FIXME: We should enable throttling here. */ + } + + // Hot Plug + Method (_L01, 0) + { + + } + + // USB1 + Method (_L03, 0) + { + + } + + // USB2 + Method (_L04, 0) + { + + } + + // USB5 + Method (_L05, 0) + { + + } + + // _L06 TCOSCI + + // SMBus Wake Status + Method (_L07, 0) + { + + } + + // COM1/COM2 (RI) + Method (_L08, 0) + { + + } + + // PCIe + Method (_L09, 0) + { + + } + + // _L0A BatLow / Quick Resume + + // PME + Method (_L0B, 0) + { + + } + + // USB3 + Method (_L0C, 0) + { + + } + + // PME B0 + Method (_L0D, 0) + { + + } + + // USB4 + Method (_L0E, 0) + { + + } + + // _L10 - _L1f: GPIn + + // GPI8 + Method (_L18, 0) + { + + } + + // USB6 + Method (_L20, 0) + { + + } +} diff --git a/src/mainboard/roda/rk9/acpi/ich9_pci_irqs.asl b/src/mainboard/roda/rk9/acpi/ich9_pci_irqs.asl new file mode 100644 index 0000000000..325f13cc2e --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/ich9_pci_irqs.asl @@ -0,0 +1,110 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* This is board specific information: IRQ routing for the + * 0:1e.0 PCI bridge of the ICH9 + */ + +/* TODO: which slots are actually relevant? */ +If (PICM) { + Return (Package() { + // PCI Slot 1 routes ABCD + Package() { 0x0000ffff, 0, 0, 16}, + Package() { 0x0000ffff, 1, 0, 17}, + Package() { 0x0000ffff, 2, 0, 18}, + Package() { 0x0000ffff, 3, 0, 19}, + + // PCI Slot 2 routes BCDA + Package() { 0x0001ffff, 0, 0, 17}, + Package() { 0x0001ffff, 1, 0, 18}, + Package() { 0x0001ffff, 2, 0, 19}, + Package() { 0x0001ffff, 3, 0, 16}, + + // PCI Slot 3 routes CDAB + Package() { 0x0002ffff, 0, 0, 18}, + Package() { 0x0002ffff, 1, 0, 19}, + Package() { 0x0002ffff, 2, 0, 16}, + Package() { 0x0002ffff, 3, 0, 17}, + + // PCI Slot 4 routes ABCD + Package() { 0x0003ffff, 0, 0, 16}, + Package() { 0x0003ffff, 1, 0, 17}, + Package() { 0x0003ffff, 2, 0, 18}, + Package() { 0x0003ffff, 3, 0, 19}, + + // PCI Slot 5 routes ABCD + Package() { 0x0004ffff, 0, 0, 16}, + Package() { 0x0004ffff, 1, 0, 17}, + Package() { 0x0004ffff, 2, 0, 18}, + Package() { 0x0004ffff, 3, 0, 19}, + + // PCI Slot 6 routes BCDA + Package() { 0x0005ffff, 0, 0, 17}, + Package() { 0x0005ffff, 1, 0, 18}, + Package() { 0x0005ffff, 2, 0, 19}, + Package() { 0x0005ffff, 3, 0, 16}, + + // FIXME: what's this supposed to mean? (adopted from ich7) + //Package() { 0x0008ffff, 0, 0, 20}, + }) +} Else { + Return (Package() { + // PCI Slot 1 routes ABCD + Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0}, + + // PCI Slot 2 routes BCDA + Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKD, 0}, + Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKA, 0}, + + // PCI Slot 3 routes CDAB + Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKD, 0}, + Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKB, 0}, + + // PCI Slot 4 routes ABCD + Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0003ffff, 1, \_SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0003ffff, 2, \_SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0003ffff, 3, \_SB.PCI0.LPCB.LNKD, 0}, + + // PCI Slot 5 routes ABCD + Package() { 0x0004ffff, 0, \_SB.PCI0.LPCB.LNKA, 0}, + Package() { 0x0004ffff, 1, \_SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0004ffff, 2, \_SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0004ffff, 3, \_SB.PCI0.LPCB.LNKD, 0}, + + // PCI Slot 6 routes BCDA + Package() { 0x0005ffff, 0, \_SB.PCI0.LPCB.LNKB, 0}, + Package() { 0x0005ffff, 1, \_SB.PCI0.LPCB.LNKC, 0}, + Package() { 0x0005ffff, 2, \_SB.PCI0.LPCB.LNKD, 0}, + Package() { 0x0005ffff, 3, \_SB.PCI0.LPCB.LNKA, 0}, + + // FIXME + // Package() { 0x0008ffff, 0, \_SB.PCI0.LPCB.LNKE, 0}, + }) +} + diff --git a/src/mainboard/roda/rk9/acpi/mainboard.asl b/src/mainboard/roda/rk9/acpi/mainboard.asl new file mode 100644 index 0000000000..0837ed3130 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/mainboard.asl @@ -0,0 +1,44 @@ +/* + * 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 + */ + +Device (LID0) +{ + Name(_HID, EisaId("PNP0C0D")) + Method(_LID, 0) + { + Return (\_SB.PCI0.LPCB.EC0.LIDC) + } +} + +Device (SLPB) +{ + Name(_HID, EisaId("PNP0C0E")) +} + +Device (PWRB) +{ + Name(_HID, EisaId("PNP0C0C")) + + // Wake + Name(_PRW, Package(){0x18, 0x04}) +} + +#include "acpi/battery.asl" diff --git a/src/mainboard/roda/rk9/acpi/platform.asl b/src/mainboard/roda/rk9/acpi/platform.asl new file mode 100644 index 0000000000..b85433f798 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/platform.asl @@ -0,0 +1,209 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* These come from the dynamically created CPU SSDT */ +External(PDC0) +External(PDC1) + +/* The APM port can be used for generating software SMIs */ + +OperationRegion (APMP, SystemIO, 0xb2, 2) +Field (APMP, ByteAcc, NoLock, Preserve) +{ + APMC, 8, // APM command + APMS, 8 // APM status +} + +/* Port 80 POST */ + +OperationRegion (POST, SystemIO, 0x80, 1) +Field (POST, ByteAcc, Lock, Preserve) +{ + DBG0, 8 +} + +/* SMI I/O Trap */ +Method(TRAP, 1, Serialized) +{ + Store (Arg0, SMIF) // SMI Function + Store (0, TRP0) // Generate trap + Return (SMIF) // Return value of SMI handler +} + +/* The _PIC method is called by the OS to choose between interrupt + * routing via the i8259 interrupt controller or the APIC. + * + * _PIC is called with a parameter of 0 for i8259 configuration and + * with a parameter of 1 for Local Apic/IOAPIC configuration. + */ + +Method(_PIC, 1) +{ + // Remember the OS' IRQ routing choice. + Store(Arg0, PICM) +} + +/* The _PTS method (Prepare To Sleep) is called before the OS is + * entering a sleep state. The sleep state number is passed in Arg0 + */ + +Method(_PTS,1) +{ + // Call a trap so SMI can prepare for Sleep as well. + // TRAP(0x55) +} + +/* The _WAK method is called on system wakeup */ + +Method(_WAK,1) +{ + // CPU specific part + + // Notify PCI Express slots in case a card + // was inserted while a sleep state was active. + + // Are we going to S3? + If (LEqual(Arg0, 3)) { + // .. + } + + // Are we going to S4? + If (LEqual(Arg0, 4)) { + // .. + } + + // TODO: Windows XP SP2 P-State restore + + // TODO: Return Arg0 as second value if S-Arg0 was entered + // before. + + Return(Package(){0,0}) +} + +// Power notification + +External (\_PR_.CPU0, DeviceObj) +External (\_PR_.CPU1, DeviceObj) + +Method (PNOT) +{ + If (MPEN) { + If(And(PDC0, 0x08)) { + Notify (\_PR_.CPU0, 0x80) // _PPC + + If (And(PDC0, 0x10)) { + Sleep(100) + Notify(\_PR_.CPU0, 0x81) // _CST + } + } + + If(And(PDC1, 0x08)) { + Notify (\_PR_.CPU1, 0x80) // _PPC + If (And(PDC1, 0x10)) { + Sleep(100) + Notify(\_PR_.CPU1, 0x81) // _CST + } + } + + } Else { // UP + Notify (\_PR_.CPU0, 0x80) + Sleep(0x64) + Notify(\_PR_.CPU0, 0x81) + } + + // Notify the Batteries + Notify(BAT1, 0x80) // Execute BAT1 _BST + Notify(BAT2, 0x80) // Execute BAT2 _BST +} + +/* System Bus */ + +Scope(\_SB) +{ + /* This method is placed on the top level, so we can make sure it's the + * first executed _INI method. + */ + Method(_INI, 0) + { + /* The DTS data in NVS is probably not up to date. + * Update temperature values and make sure AP thermal + * interrupts can happen + */ + + // TRAP(71) // TODO + + /* Determine the Operating System and save the value in OSYS. + * We have to do this in order to be able to work around + * certain windows bugs. + * + * OSYS value | Operating System + * -----------+------------------ + * 2000 | Windows 2000 + * 2001 | Windows XP(+SP1) + * 2002 | Windows XP SP2 + * 2006 | Windows Vista + * ???? | Windows 7 + */ + + /* Let's assume we're running at least Windows 2000 */ + Store (2000, OSYS) + + If (CondRefOf(_OSI, Local0)) { + /* Linux answers _OSI with "True" for a couple of + * Windows version queries. But unlike Windows it + * needs a Video repost, so let's determine whether + * we're running Linux. + */ + + If (_OSI("Linux")) { + Store (1, LINX) + } + + If (_OSI("Windows 2001")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001 SP1")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001 SP2")) { + Store (2002, OSYS) + } + + If (_OSI("Windows 2006")) { + Store (2006, OSYS) + } + } + + /* And the OS workarounds start right after we know what we're + * running: Windows XP SP1 needs to have C-State coordination + * enabled in SMM. + */ + If (LAnd(LEqual(OSYS, 2001), MPEN)) { + // TRAP(61) // TODO + } + + /* SMM power state and C4-on-C3 settings need to be updated */ + // TRAP(43) // TODO + } +} + diff --git a/src/mainboard/roda/rk9/acpi/superio.asl b/src/mainboard/roda/rk9/acpi/superio.asl new file mode 100644 index 0000000000..174f2f1062 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/superio.asl @@ -0,0 +1,368 @@ +/* + * 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 + */ + +/* SMSC LPC47N227 */ + +Device (SIO1) +{ + Name (_HID, EISAID("PNP0A05")) + Name (_UID, 1) + + OperationRegion(SIOR, SystemIO, 0x2e, 0x02) + Field (SIOR, ByteAcc, Nolock, Preserve) + { + INDX, 8, + DATA, 8 + } + + Mutex (SIOM, 0x00) + + Method (READ, 3) + { + Acquire (SIOM, 0xffff) + If (LEqual(Arg0, 0)) { + Store (0x55, INDX) + Store (Arg1, INDX) + Store (DATA, Local1) + Store (0xaa, INDX) + } + And (Local1, Arg2, Local1) + Release(SIOM) + Return(Local1) + } + + Method (WRIT, 3) + { + Acquire (SIOM, 0xffff) + If (LEqual(Arg0, 0)) { + Store (0x55, INDX) + Store (Arg1, INDX) + Store (Arg2, DATA) + Store (0xaa, INDX) + } + Release(SIOM) + } + + Device (COMA) + { + Name(_HID, EISAID("PNP0501")) + Name(_UID, 1) + Name(_PRW, Package() { 0x08, 0x03 }) + + /* Device Status */ + Method (_STA, 0) + { + // Device disabled by coreboot? + If (LEqual(CMAP, 0)) { + Return (0) + } + + // Is the hardware enabled? + Store (READ(0, 0x24, 0xff), Local0) + If (LEqual(Local0, 0)) { + Return (0xd) + } Else { + // Power Enabled? + Store (READ(0, 0x02, 0x08), Local0) + If (LEqual(Local0, 0)) { + Return (0x0d) + } Else { + Return (0x0f) + } + } + } + + /* Device Disable */ + Method (_DIS, 0) + { + WRIT(0, 0x24, 0x00) + + Store(READ(0, 0x28, 0x0f), Local0) + WRIT(0, 0x28, Local0) + + Store(READ(0, 0x02, 0xff), Local0) + Not(0x08, Local1) + And(Local0, Local1, Local0) + WRIT(0, 0x02, Local0) + } + + /* Possible Resource Settings */ + Name(_PRS, ResourceTemplate() { + StartDependentFn(0, 1) { + IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8) + IRQNoFlags() { 4 } + } EndDependentFn() + }) + + /* Current Resource Settings */ + Method(_CRS, 0) + { + Name(NONE, ResourceTemplate() { + IO(Decode16, 0x000, 0x000, 0x0, 0x1) + IRQNoFlags() { } + }) + + Name(RSRC, ResourceTemplate() { + IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8, _IOA) + IRQNoFlags(_IRA) { 4 } + }) + + And (_STA(), 0x02, Local0) + If (LEqual(Local0, 0)) { + Return(NONE) + } + + CreateWordField(RSRC, + \_SB.PCI0.LPCB.SIO1.COMA._CRS._IOA._MIN, IOMN) + CreateWordField(RSRC, + \_SB.PCI0.LPCB.SIO1.COMA._CRS._IOA._MAX, IOMX) + CreateWordField(RSRC, + \_SB.PCI0.LPCB.SIO1.COMA._CRS._IRA._INT, IRQ) + + /* I/O Base */ + Store (READ(0, 0x24, 0xfe), Local0) + ShiftLeft(Local0, 0x02, Local0) + Store(Local0, IOMN) + Store(Local0, IOMX) + + /* Interrupt */ + Store(READ(0, 0x28, 0xf0), Local0) + ShiftRight(Local0, 4, Local0) + ShiftLeft(1, Local0, IRQ) + Return(RSRC) + } + + /* Set Resource Settings */ + Method(_SRS, 1) + { + CreateByteField(Arg0, 0x02, IOLO) + CreateByteField(Arg0, 0x03, IOHI) + CreateByteField(Arg0, 0x09, IRQL) + + WRIT(0, 0x24, 0) + FindSetRightBit(IRQL, Local0) + Decrement(Local0) + ShiftLeft(Local0, 4, Local0) + + Store(READ(0, 0x28, 0x0f), Local1) + Or(Local0, Local1, Local0) + WRIT(0, 0x28, Local0) + + Store(IOLO, Local0) + ShiftRight(Local0, 2, Local0) + And(Local0, 0xfe, Local0) + + Store(IOHI, Local1) + ShiftLeft(Local1, 6, Local1) + Or (Local0, Local1, Local0) + WRIT(0, 0x24, Local0) + + Store(READ(0, 0x02, 0xff), Local0) + Or(Local0, 0x08, Local0) + WRIT(0, 0x02, Local0) + + Store(READ(0, 0x07, 0xff), Local0) + Not(0x40, Local1) + And (Local0, Local1, Local0) + WRIT(0, 0x07, Local0) + } + + + /* D0 state - Line drivers are on */ + Method (_PS0, 0) + { + Store(READ(0, 0x02, 0xff), Local0) + Or(Local0, 0x08, Local0) + WRIT(0, 0x02, Local0) + + Store (READ(0, 0x07, 0xff), Local0) + Not(0x40, Local1) + And(Local0, Local1, Local0) + WRIT(0, 0x07, Local0) + } + + /* D3 State - Line drivers are off */ + Method(_PS3, 0) + { + Store(READ(0, 0x02, 0xff), Local0) + Not(0x08, Local1) + And(Local0, Local1, Local0) + WRIT(0, 0x02, Local0) + } + } + + Device (COMB) + { + Name(_HID, EISAID("PNP0501")) + Name(_UID, 2) + Name(_PRW, Package() { 0x08, 0x03 }) + + /* Device Status */ + Method (_STA, 0) + { + // Device disabled by coreboot? + If (LEqual(CMBP, 0)) { + Return (0) + } + + /* IRDA? */ + Store(READ(0, 0x0c, 0x38), Local0) + If (LNotEqual(Local0, Zero)) { + Return (0) + } + + // Is the hardware enabled? + Store (READ(0, 0x25, 0xff), Local0) + If (LEqual(Local0, 0)) { + Return (0xd) + } Else { + // Power Enabled? + Store (READ(0, 0x02, 0x80), Local0) + If (LEqual(Local0, 0)) { + Return (0x0d) + } Else { + Return (0x0f) + } + } + } + + /* Device Disable */ + Method (_DIS, 0) + { + WRIT(0, 0x25, 0x00) + + Store(READ(0, 0x28, 0xf0), Local0) + WRIT(0, 0x28, Local0) + + Store(READ(0, 0x02, 0xff), Local0) + Not(0x80, Local1) + And(Local0, Local1, Local0) + WRIT(0, 0x02, Local0) + } + + /* Possible Resource Settings */ + Name(_PRS, ResourceTemplate() { + StartDependentFn(0, 1) { + IO(Decode16, 0x2f8, 0x2f8, 0x8, 0x8) + IRQNoFlags() { 3 } + } EndDependentFn() + }) + + /* Current Resource Settings */ + Method(_CRS, 0) + { + Name(NONE, ResourceTemplate() { + IO(Decode16, 0x000, 0x000, 0x0, 0x1) + IRQNoFlags() { } + }) + + Name(RSRC, ResourceTemplate() { + IO(Decode16, 0x2f8, 0x2f8, 0x8, 0x8, _IOB) + IRQNoFlags(_IRB) { 3 } + }) + + And (_STA(), 0x02, Local0) + If (LEqual(Local0, 0)) { + Return(NONE) + } + + CreateWordField(RSRC, + \_SB.PCI0.LPCB.SIO1.COMA._CRS._IOA._MIN, IOMN) + CreateWordField(RSRC, + \_SB.PCI0.LPCB.SIO1.COMA._CRS._IOA._MAX, IOMX) + CreateWordField(RSRC, + \_SB.PCI0.LPCB.SIO1.COMA._CRS._IRA._INT, IRQ) + + /* I/O Base */ + Store (READ(0, 0x25, 0xfe), Local0) + ShiftLeft(Local0, 0x02, Local0) + Store(Local0, IOMN) + Store(Local0, IOMX) + + /* Interrupt */ + Store(READ(0, 0x28, 0x0f), Local0) + ShiftLeft(1, Local0, IRQ) + Return(RSRC) + } + + /* Set Resource Settings */ + Method(_SRS, 1) + { + CreateByteField(Arg0, 0x02, IOLO) + CreateByteField(Arg0, 0x03, IOHI) + CreateByteField(Arg0, 0x09, IRQL) + + WRIT(0, 0x25, 0) + FindSetRightBit(IRQL, Local0) + Decrement(Local0) + + Store(READ(0, 0x28, 0xf0), Local1) + Or(Local0, Local1, Local0) + WRIT(0, 0x28, Local0) + + Store(IOLO, Local0) + ShiftRight(Local0, 2, Local0) + And(Local0, 0xfe, Local0) + + Store(IOHI, Local1) + ShiftLeft(Local1, 6, Local1) + Or (Local0, Local1, Local0) + WRIT(0, 0x25, Local0) + + Store(READ(0, 0x0c, 0xff), Local0) + Not(0x38, Local1) + And(Local0, Local1, Local0) + WRIT(0, 0x0c, Local0) + + Store(READ(0, 0x02, 0xff), Local0) + Or(Local0, 0x80, Local0) + WRIT(0, 0x02, Local0) + + Store(READ(0, 0x07, 0xff), Local0) + Not(0x20, Local1) + And (Local0, Local1, Local0) + WRIT(0, 0x07, Local0) + } + + /* D0 state - Line drivers are on */ + Method (_PS0, 0) + { + Store(READ(0, 0x02, 0xff), Local0) + Or(Local0, 0x80, Local0) + WRIT(0, 0x02, Local0) + + Store (READ(0, 0x07, 0xff), Local0) + Not(0x20, Local1) + And(Local0, Local1, Local0) + WRIT(0, 0x07, Local0) + } + + /* D3 State - Line drivers are off */ + Method(_PS3, 0) + { + Store(READ(0, 0x02, 0xff), Local0) + Not(0x80, Local1) + And(Local0, Local1, Local0) + WRIT(0, 0x02, Local0) + } + } +} + diff --git a/src/mainboard/roda/rk9/acpi/thermal.asl b/src/mainboard/roda/rk9/acpi/thermal.asl new file mode 100644 index 0000000000..4cd888251a --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/thermal.asl @@ -0,0 +1,115 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +// Thermal Zone + +Scope (\_TZ) +{ + /* degree Celcius to deci-Kelvin (ACPI temperature unit) */ + Method(C2dK, 1) { + Add (2732, Multiply (Arg0, 10), Local0) + Return (Local0) + } + + ThermalZone (THRM) + { + + // FIXME these could/should be read from the + // GNVS area, so they can be controlled by + // coreboot + Name(TC1V, 0x04) + Name(TC2V, 0x03) + Name(TSPV, 0x96) + + // At which temperature should the OS start + // active cooling? + Method (_AC0, 0, Serialized) + { + Return (C2dK(120)) // Value for Rocky + } + + // Critical shutdown temperature + Method (_CRT, 0, Serialized) + { + Return (C2dK(155)) // Value for Rocky + } + + // CPU throttling start temperature + Method (_PSV, 0, Serialized) + { + Return (C2dK(105)) // Value for Rocky + } + + // Get DTS Temperature + Method (_TMP, 0, Serialized) + { + If (\_SB.PCI0.LPCB.EC0.ALRC) { + Store(0, \_SB.PCI0.LPCB.EC0.ALRC) + Return(_AC0()) + } + + If (\_SB.PCI0.LPCB.EC0.ALRL) { + Store(0, THRO) + Store(0, \_SB.PCI0.LPCB.EC0.ALRL) + } + + If (\_SB.PCI0.LPCB.EC0.ALRH) { + Store(1, THRO) + Store(0, \_SB.PCI0.LPCB.EC0.ALRH) + } + + /* vendor BIOS reports 0K if TCPU >= 128 deg C ?!? */ + Return (C2dK(\_SB.PCI0.LPCB.EC0.TCPU)) + } + + + // Processors used for active cooling + Method (_PSL, 0, Serialized) + { + If (MPEN) { + Return (Package() {\_PR.CPU0, \_PR.CPU1}) + } + Return (Package() {\_PR.CPU0}) + } + + // TC1 value for passive cooling + Method (_TC1, 0, Serialized) + { + Return (TC1V) + } + + // TC2 value for passive cooling + Method (_TC2, 0, Serialized) + { + Return (TC2V) + } + + // Sampling period for passive cooling + Method (_TSP, 0, Serialized) + { + Return (TSPV) + } + + + } +} + diff --git a/src/mainboard/roda/rk9/acpi/video.asl b/src/mainboard/roda/rk9/acpi/video.asl new file mode 100644 index 0000000000..507a390d27 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi/video.asl @@ -0,0 +1,45 @@ +/* + * 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 + */ + +// Brightness write +Method (BRTW, 1, Serialized) +{ + // TODO +} + +// Hot Key Display Switch +Method (HKDS, 1, Serialized) +{ + // TODO +} + +// Lid Switch Display Switch +Method (LSDS, 1, Serialized) +{ + // TODO +} + +// Brightness Notification +Method(BRTN,1,Serialized) +{ + // TODO (no displays defined yet) +} + diff --git a/src/mainboard/roda/rk9/acpi_tables.c b/src/mainboard/roda/rk9/acpi_tables.c new file mode 100644 index 0000000000..6e6cd727c5 --- /dev/null +++ b/src/mainboard/roda/rk9/acpi_tables.c @@ -0,0 +1,313 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <string.h> +#include <console/console.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/acpi.h> +#include <arch/acpigen.h> +#include <arch/smp/mpspec.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +extern const unsigned char AmlCode[]; +#if CONFIG_HAVE_ACPI_SLIC +unsigned long acpi_create_slic(unsigned long current); +#endif + +#include "southbridge/intel/i82801ix/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 = 0; /* Will use default of 0x00000400. */ + gnvs->did[0] = 0x80000100; + gnvs->did[1] = 0x80000240; + gnvs->did[2] = 0x80000410; + gnvs->did[3] = 0x80000410; + gnvs->did[4] = 0x00000005; +} + +static void acpi_create_intel_hpet(acpi_hpet_t * hpet) +{ +#define HPET_ADDR 0xfed00000ULL + acpi_header_t *header = &(hpet->header); + acpi_addr_t *addr = &(hpet->addr); + + memset((void *) hpet, 0, sizeof(acpi_hpet_t)); + + /* fill out header fields */ + memcpy(header->signature, "HPET", 4); + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->asl_compiler_id, ASLC, 4); + + header->length = sizeof(acpi_hpet_t); + header->revision = 1; + + /* fill out HPET address */ + addr->space_id = 0; /* Memory */ + addr->bit_width = 64; + addr->bit_offset = 0; + addr->addrl = HPET_ADDR & 0xffffffff; + addr->addrh = HPET_ADDR >> 32; + + hpet->id = 0x8086a201; /* Intel */ + hpet->number = 0x00; + hpet->min_tick = 0x0080; + + header->checksum = + acpi_checksum((void *) hpet, sizeof(acpi_hpet_t)); +} + +unsigned long acpi_fill_madt(unsigned long current) +{ + /* Local APICs */ + current = acpi_create_madt_lapics(current); + + /* IOAPIC */ + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + 2, IO_APIC_ADDR, 0); + + /* LAPIC_NMI */ + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 0, + MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 1, MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + + /* INT_SRC_OVR */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE); + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL); + + + return current; +} + +unsigned long acpi_fill_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_IOMMU + acpi_dmar_t *dmar; +#endif +#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_intel_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); + +#if CONFIG_IOMMU + printk(BIOS_DEBUG, "ACPI: * DMAR\n"); + dmar = (acpi_dmar_t *) current; + acpi_create_dmar(dmar); + current += dmar->header.length; + ALIGN_CURRENT; + acpi_add_table(rsdp, dmar); +#endif + + 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; + +#if CONFIG_HAVE_SMI_HANDLER + /* And tell SMI about it */ + smm_setup_structures(gnvs, NULL, NULL); +#endif + + /* 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"); + + return current; +} diff --git a/src/mainboard/roda/rk9/cmos.layout b/src/mainboard/roda/rk9/cmos.layout new file mode 100644 index 0000000000..5c82567931 --- /dev/null +++ b/src/mainboard/roda/rk9/cmos.layout @@ -0,0 +1,141 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2007-2008 coresystems GmbH +# 2012 secunet Security Networks AG +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2 of +# the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +# ----------------------------------------------------------------- +entries + +#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 + +# coreboot config options: cpu +#400 8 r 0 unused + +# coreboot config options: southbridge +#408 8 r 0 unused + +# coreboot config options: bootloader +416 512 s 0 boot_devices +928 8 h 0 boot_default +936 1 e 8 cmos_defaults_loaded +#937 7 r 0 unused + +# coreboot config options: check sums +984 16 h 0 check_sum +#1000 24 r 0 unused + +# ram initialization internal data +1024 128 r 0 read_training_results + +# ----------------------------------------------------------------- + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 1 Emergency +6 2 Alert +6 3 Critical +6 4 Error +6 5 Warning +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Disable +7 1 Enable +7 2 Keep +8 0 No +8 1 Yes + +# ----------------------------------------------------------------- +checksums + +checksum 392 983 984 + diff --git a/src/mainboard/roda/rk9/cstates.c b/src/mainboard/roda/rk9/cstates.c new file mode 100644 index 0000000000..ab0de7602b --- /dev/null +++ b/src/mainboard/roda/rk9/cstates.c @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <arch/acpigen.h> +#include <device/device.h> /* fix for i82801ix.h */ +#include <southbridge/intel/i82801ix/i82801ix.h> + +static acpi_cstate_t cst_entries[] = { + { + /* acpi C1 / cpu C1 */ + 1, 0x01, 1000, + { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0, 0 } + }, + { + /* acpi C2 / cpu C2 */ + 2, 0x01, 500, + { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0x10, 0 } + }, +}; + +int get_cst_entries(acpi_cstate_t **entries) +{ + *entries = cst_entries; + return ARRAY_SIZE(cst_entries); +} diff --git a/src/mainboard/roda/rk9/devicetree.cb b/src/mainboard/roda/rk9/devicetree.cb new file mode 100644 index 0000000000..002f595626 --- /dev/null +++ b/src/mainboard/roda/rk9/devicetree.cb @@ -0,0 +1,152 @@ +chip northbridge/intel/gm45 + device lapic_cluster 0 on + chip cpu/intel/socket_BGA956 + device lapic 0 on end + end + chip cpu/intel/model_1067x + # Magic APIC ID to locate this chip + device lapic 0xACAC off end + + # Enable Super LFM + register "slfm" = "1" + + # Enable C5, C6 + register "c5" = "1" + register "c6" = "1" + end + end + + device pci_domain 0 on + subsystemid 0x4352 0x8986 + device pci 00.0 on end # host bridge + device pci 02.0 on # VGA + ioapic_irq 2 INTA 0x10 + end + device pci 02.1 on end # Display + device pci 03.0 off end # ME + device pci 03.1 off end # ME + device pci 03.2 off end # ME + device pci 03.3 off end # ME + chip southbridge/intel/i82801ix + register "pirqa_routing" = "0x0b" + register "pirqb_routing" = "0x0b" + register "pirqc_routing" = "0x0b" + register "pirqd_routing" = "0x0b" + register "pirqe_routing" = "0x80" + register "pirqf_routing" = "0x80" + register "pirqg_routing" = "0x80" + register "pirqh_routing" = "0x80" + + register "gpi8_routing" = "2" + register "gpi7_routing" = "2" + register "gpe0_en" = "0x01800042" + register "gpi1_routing" = "1" + register "alt_gp_smi_en" = "0x0002" + + # Set AHCI mode, enable ports 1 and 2. + register "sata_ahci" = "1" + register "sata_port_map" = "0x03" + register "sata_clock_request" = "0" + register "sata_traffic_monitor" = "0" + + # Set c-state support + register "c4onc3_enable" = "0" + register "c5_enable" = "1" + register "c6_enable" = "1" + + # Set thermal throttling to 75%. + register "throttle_duty" = "THTL_75_0" + + # Enable PCIe ports 1 and 5 as slots (Mini * PCIe). + register "pcie_slot_implemented" = "0x11" + # Set power limits to 10 * 10^0 watts. + # Maybe we should set less for Mini PCIe. + register "pcie_power_limits" = "{ { 10, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 10, 0 }, { 0, 0 } }" + + chip drivers/generic/ioapic + register "have_isa_interrupts" = "1" + register "irq_on_fsb" = "1" + register "enable_virtual_wire" = "1" + register "base" = "0xfec00000" + device ioapic 2 on end + end + + device pci 19.0 off end # LAN + device pci 1a.0 on # UHCI + ioapic_irq 2 INTA 0x10 + end + device pci 1a.1 on # UHCI + ioapic_irq 2 INTB 0x11 + end + device pci 1a.2 on # UHCI + ioapic_irq 2 INTC 0x12 + end + device pci 1a.7 on # EHCI + ioapic_irq 2 INTC 0x12 + end + device pci 1b.0 on # HD Audio + ioapic_irq 2 INTA 0x10 + end + device pci 1c.0 on # PCIe Port #1 + ioapic_irq 2 INTA 0x10 + end + device pci 1c.1 off end # PCIe Port #2 + device pci 1c.2 off end # PCIe Port #3 + device pci 1c.3 off end # PCIe Port #4 + device pci 1c.4 on # PCIe Port #5 + ioapic_irq 2 INTA 0x10 + device pci 00.0 on end # Realtek 8168B + end + device pci 1c.5 off end # PCIe Port #6 + device pci 1d.0 on # UHCI + ioapic_irq 2 INTA 0x10 + end + device pci 1d.1 on # UHCI + ioapic_irq 2 INTB 0x11 + end + device pci 1d.2 on # UHCI + ioapic_irq 2 INTC 0x12 + end + device pci 1d.7 on # EHCI + ioapic_irq 2 INTA 0x10 + end + device pci 1e.0 on # PCI + device pci 03.0 on # TI Cardbus + ioapic_irq 2 INTA 0x10 + end + device pci 03.1 on # TI Cardbus + ioapic_irq 2 INTB 0x11 + end + device pci 03.2 off end # TI FireWire OHC + device pci 03.3 off end # unconnected FlashMedia + device pci 03.4 off end # unconnected SD-Card + end + device pci 1f.0 on # LPC bridge + chip superio/smsc/lpc47n227 + device pnp 2e.1 on # Parallel port + io 0x60 = 0x378 + irq 0x70 = 5 + end + device pnp 2e.2 on # COM1 + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on # COM2 + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.5 off # Keyboard+Mouse + end + end + end + device pci 1f.2 on # SATA/IDE 1 + ioapic_irq 2 INTB 0x11 + end + device pci 1f.3 on # SMBus + ioapic_irq 2 INTC 0x12 + end + device pci 1f.5 off end # SATA/IDE 2 + device pci 1f.6 off end # Thermal + end + end +end diff --git a/src/mainboard/roda/rk9/dsdt.asl b/src/mainboard/roda/rk9/dsdt.asl new file mode 100644 index 0000000000..a240b1779e --- /dev/null +++ b/src/mainboard/roda/rk9/dsdt.asl @@ -0,0 +1,56 @@ +/* + * 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 + 0x20090419 // OEM revision +) +{ + // Some generic macros + #include "acpi/platform.asl" + + // global NVS and variables + #include <southbridge/intel/i82801ix/acpi/globalnvs.asl> + + // General Purpose Events + #include "acpi/gpe.asl" + + // mainboard specific devices + #include "acpi/mainboard.asl" + + // Thermal Zone + #include "acpi/thermal.asl" + + Scope (\_SB) { + Device (PCI0) + { + #include <northbridge/intel/gm45/acpi/gm45.asl> + #include <southbridge/intel/i82801ix/acpi/ich9.asl> + } + } + + /* Chipset specific sleep states */ + #include <southbridge/intel/i82801ix/acpi/sleepstates.asl> +} diff --git a/src/mainboard/roda/rk9/fadt.c b/src/mainboard/roda/rk9/fadt.c new file mode 100644 index 0000000000..fef97214a7 --- /dev/null +++ b/src/mainboard/roda/rk9/fadt.c @@ -0,0 +1,158 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <string.h> +#include <device/pci.h> +#include <arch/acpi.h> +#include <cpu/x86/smm.h> + +void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) +{ + acpi_header_t *header = &(fadt->header); + u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe; + + memset((void *) fadt, 0, sizeof(acpi_fadt_t)); + memcpy(header->signature, "FACP", 4); + header->length = sizeof(acpi_fadt_t); + header->revision = 3; + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->asl_compiler_id, ASLC, 4); + header->asl_compiler_revision = 0; + + fadt->firmware_ctrl = (unsigned long) facs; + fadt->dsdt = (unsigned long) dsdt; + fadt->model = 0x00; + fadt->preferred_pm_profile = PM_MOBILE; + fadt->sci_int = 0x9; + fadt->smi_cmd = APM_CNT; + fadt->acpi_enable = APM_CNT_ACPI_ENABLE; + fadt->acpi_disable = APM_CNT_ACPI_DISABLE; + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = APM_CNT_PST_CONTROL; + + fadt->pm1a_evt_blk = pmbase; + fadt->pm1b_evt_blk = 0x0; + fadt->pm1a_cnt_blk = pmbase + 0x4; + fadt->pm1b_cnt_blk = 0x0; + fadt->pm2_cnt_blk = pmbase + 0x50; + fadt->pm_tmr_blk = pmbase + 0x8; + fadt->gpe0_blk = pmbase + 0x20; + fadt->gpe1_blk = 0; + + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; /* Upper word is reserved and + Linux complains about 32 bit. */ + fadt->pm2_cnt_len = 1; + fadt->pm_tmr_len = 4; + fadt->gpe0_blk_len = 16; + fadt->gpe1_blk_len = 0; + fadt->gpe1_base = 0; + fadt->cst_cnt = APM_CNT_CST_CONTROL; + fadt->p_lvl2_lat = 1; + fadt->p_lvl3_lat = 0x39; + fadt->flush_size = 0; + fadt->flush_stride = 0; + fadt->duty_offset = 1; + fadt->duty_width = 3; + fadt->day_alrm = 0xd; + fadt->mon_alrm = 0x00; + fadt->century = 0x32; + fadt->iapc_boot_arch = 0x00; + fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | + ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE | + ACPI_FADT_DOCKING_SUPPORTED | ACPI_FADT_RESET_REGISTER | + ACPI_FADT_PLATFORM_CLOCK; + + fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->reset_reg.bit_width = 8; + fadt->reset_reg.bit_offset = 0; + fadt->reset_reg.resv = 0; + fadt->reset_reg.addrl = 0xcf9; + fadt->reset_reg.addrh = 0; + fadt->reset_value = 0x06; + + fadt->x_firmware_ctl_l = 0; /* Set X_FIRMWARE_CTRL only if FACS is */ + fadt->x_firmware_ctl_h = 0; /* above 4GB. If X_FIRMWARE_CTRL is set, */ + /* then FIRMWARE_CTRL must be zero. */ + fadt->x_dsdt_l = (unsigned long)dsdt; + fadt->x_dsdt_h = 0; + + fadt->x_pm1a_evt_blk.space_id = 1; + fadt->x_pm1a_evt_blk.bit_width = 32; + fadt->x_pm1a_evt_blk.bit_offset = 0; + fadt->x_pm1a_evt_blk.resv = 0; + fadt->x_pm1a_evt_blk.addrl = pmbase; + fadt->x_pm1a_evt_blk.addrh = 0x0; + + fadt->x_pm1b_evt_blk.space_id = 0; + fadt->x_pm1b_evt_blk.bit_width = 0; + fadt->x_pm1b_evt_blk.bit_offset = 0; + fadt->x_pm1b_evt_blk.resv = 0; + fadt->x_pm1b_evt_blk.addrl = 0x0; + fadt->x_pm1b_evt_blk.addrh = 0x0; + + fadt->x_pm1a_cnt_blk.space_id = 1; + fadt->x_pm1a_cnt_blk.bit_width = 16; /* Upper word is reserved and + Linux complains about 32 bit. */ + fadt->x_pm1a_cnt_blk.bit_offset = 0; + fadt->x_pm1a_cnt_blk.resv = 0; + fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4; + fadt->x_pm1a_cnt_blk.addrh = 0x0; + + fadt->x_pm1b_cnt_blk.space_id = 0; + fadt->x_pm1b_cnt_blk.bit_width = 0; + fadt->x_pm1b_cnt_blk.bit_offset = 0; + fadt->x_pm1b_cnt_blk.resv = 0; + fadt->x_pm1b_cnt_blk.addrl = 0x0; + fadt->x_pm1b_cnt_blk.addrh = 0x0; + + fadt->x_pm2_cnt_blk.space_id = 1; + fadt->x_pm2_cnt_blk.bit_width = 8; + fadt->x_pm2_cnt_blk.bit_offset = 0; + fadt->x_pm2_cnt_blk.resv = 0; + fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50; + fadt->x_pm2_cnt_blk.addrh = 0x0; + + fadt->x_pm_tmr_blk.space_id = 1; + fadt->x_pm_tmr_blk.bit_width = 32; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.resv = 0; + fadt->x_pm_tmr_blk.addrl = pmbase + 0x8; + fadt->x_pm_tmr_blk.addrh = 0x0; + + fadt->x_gpe0_blk.space_id = 1; + fadt->x_gpe0_blk.bit_width = 128; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.resv = 0; + fadt->x_gpe0_blk.addrl = pmbase + 0x20; + fadt->x_gpe0_blk.addrh = 0x0; + + fadt->x_gpe1_blk.space_id = 0; + fadt->x_gpe1_blk.bit_width = 0; + fadt->x_gpe1_blk.bit_offset = 0; + fadt->x_gpe1_blk.resv = 0; + fadt->x_gpe1_blk.addrl = 0x0; + fadt->x_gpe1_blk.addrh = 0x0; + + header->checksum = + acpi_checksum((void *) fadt, header->length); +} diff --git a/src/mainboard/roda/rk9/hda_verb.h b/src/mainboard/roda/rk9/hda_verb.h new file mode 100644 index 0000000000..f99d097be6 --- /dev/null +++ b/src/mainboard/roda/rk9/hda_verb.h @@ -0,0 +1,74 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define PIN_CFG(pin, val) \ + (pin << 20) | ( 0x71c << 8) | (val & 0xff), \ + (pin << 20) | ( 0x71d << 8) | ((val >> 8) & 0xff), \ + (pin << 20) | ( 0x71e << 8) | ((val >> 16) & 0xff), \ + (pin << 20) | ( 0x71f << 8) | ((val >> 24) & 0xff), \ + +static const u32 mainboard_cim_verb_data[] = { + /* coreboot specific header */ + 0x10ec0262, // Codec Vendor / Device ID: Realtek ALC262 + 0x43528986, // Subsystem ID + 0x0000000c, // Number of entries + + /* Pin Widget Verb Table */ + + /* Pin Complex (NID 0x11), S/PDIF-OUT2: not connected */ + PIN_CFG(0x11, 0x411111f0) + /* Pin Complex (NID 0x14), LINE_OUT (port D): Speakers */ + PIN_CFG(0x14, 0x99130110) + /* Pin Complex (NID 0x15), HP_OUT (port A): Head phones */ + PIN_CFG(0x15, 0x0121411f) + /* Pin Complex (NID 0x16), MONO-OUT: not connected */ + PIN_CFG(0x16, 0x411111f0) + /* Pin Complex (NID 0x18), MIC1 (port B): Microphone */ + PIN_CFG(0x18, 0x01a19920) + /* Pin Complex (NID 0x19), MIC2 (port F): not connected */ + PIN_CFG(0x19, 0x411111f0) + /* Pin Complex (NID 0x1a), LINE1 (port C): Line-In */ + PIN_CFG(0x1a, 0x01813121) + /* Pin Complex (NID 0x1b), LINE2 (port E): MDC */ + PIN_CFG(0x1b, 0x9983012f) + /* Pin Complex (NID 0x1c), CD_IN */ + PIN_CFG(0x1c, 0x593301f0) + /* Pin Complex (NID 0x1d), PCBEEP */ + PIN_CFG(0x1d, 0x4014022d) + /* Pin Complex (NID 0x1e), S/PDIF-OUT: not connected */ + PIN_CFG(0x1e, 0x411111f0) + /* Pin Complex (NID 0x1f), S/PDIF-IN: not connected */ + PIN_CFG(0x1f, 0x411111f0) +}; +extern const u32 *cim_verb_data; +extern u32 cim_verb_data_size; + +static const u32 mainboard_pc_beep_verbs[] = { + 0x00170500, /* power up codec */ + 0x01470500, /* power up speakers */ + 0x01470100, /* select lout1 (input 0x0) for speakers */ + 0x01470740, /* enable speakers output */ + 0x00b37517, /* unmute beep (mixer's input 0x5), set amp 0dB */ + 0x00c37100, /* unmute mixer in lout1 (lout1 input 0x1) */ + 0x00c3b015, /* set lout1 output volume -15dB */ + 0x0143b000, /* unmute speakers */ +}; +extern const u32 * pc_beep_verbs; +extern u32 pc_beep_verbs_size; diff --git a/src/mainboard/roda/rk9/mainboard.c b/src/mainboard/roda/rk9/mainboard.c new file mode 100644 index 0000000000..5b4285c6dc --- /dev/null +++ b/src/mainboard/roda/rk9/mainboard.c @@ -0,0 +1,147 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> +#include <stdlib.h> +#include <arch/io.h> +//#include <pc80/mc146818rtc.h> +#include <device/device.h> +#include <console/console.h> +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL +#include <x86emu/x86emu.h> +#endif +#include <pc80/keyboard.h> +#include <ec/acpi/ec.h> +#include "hda_verb.h" + +#if CONFIG_GENERATE_ACPI_TABLES +#include "cstates.c" /* Include it, as the linker won't find + the overloaded weak function in there. */ +#endif + + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL +static int int15_handler(void) +{ + enum { + BOOT_DISPLAY_DEFAULT = 0, + BOOT_DISPLAY_CRT = (1 << 0), + BOOT_DISPLAY_TV = (1 << 1), + BOOT_DISPLAY_EFP = (1 << 2), + BOOT_DISPLAY_LFP = (1 << 3), + BOOT_DISPLAY_CRT2 = (1 << 4), + BOOT_DISPLAY_TV2 = (1 << 5), + BOOT_DISPLAY_EFP2 = (1 << 6), + BOOT_DISPLAY_LFP2 = (1 << 7), + }; + enum { + PANEL_FIT_DEFAULT = 0, + PANEL_FIT_CENTERING = (1 << 0), + PANEL_FIT_TXT_STRETCH = (1 << 1), + PANEL_FIT_GFX_STRETCH = (1 << 2), + }; + + switch (M.x86.R_AX) { + case 0x5f34: + /* Set Panel Fitting Hook */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = PANEL_FIT_CENTERING; + break; + case 0x5f35: + /* Boot Display Device Hook */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = BOOT_DISPLAY_DEFAULT; /* Select automatically. */ + break; + case 0x5f40: + /* Boot Panel Type Hook */ + /* Contrary to what EMGD's user's guide says, + this _alters_ the behavior of the Video BIOS. */ + /* LCD panel type is SIO GPIO40-43. + It's controlled by a DIP switch but was always + set to 4 while only values of 5 and 6 worked. */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = (inb(0x60f) & 0x0f) + 1; + break; + case 0x5f70: + /* Sandybridge boards return 0 here. */ + case 0x5f14: + case 0x5f21: + case 0x5f22: + case 0x5f49: + /* No documentation found. */ + default: + /* Interrupt was not handled. */ + printk(BIOS_DEBUG, + "%s: AX=%04x BX=%04x CX=%04x DX=%04x\n", __func__, + M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); + return 0; + } + + /* Interrupt handled. */ + return 1; +} + +static void int15_install(void) +{ + typedef int (* yabel_handleIntFunc)(void); + extern yabel_handleIntFunc yabel_intFuncArray[256]; + yabel_intFuncArray[0x15] = int15_handler; +} +#endif + +static void verb_setup(void) +{ + cim_verb_data = mainboard_cim_verb_data; + cim_verb_data_size = sizeof(mainboard_cim_verb_data); + pc_beep_verbs = mainboard_pc_beep_verbs; + pc_beep_verbs_size = ARRAY_SIZE(mainboard_pc_beep_verbs); +} + +static void ec_setup(void) +{ + /* Thermal limits? Values are from ectool's ram dump. */ + ec_write(0xd1, 0x57); /* CPUH */ + ec_write(0xd2, 0xc9); /* CPUL */ + ec_write(0xd4, 0x64); /* SYSH */ + ec_write(0xd5, 0xc9); /* SYSL */ + + send_ec_command(0x04); /* Set_SMI_Enable */ + send_ec_command(0xab); /* Set_ACPI_Disable */ + send_ec_command(0xac); /* Clr_SYS_Flag? well, why not? */ + send_ec_command(0xad); /* Set_Thml_Value */ +} + +static void mainboard_enable(device_t dev) +{ + ec_setup(); + verb_setup(); +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL// || CONFIG_PCI_OPTION_ROM_RUN_REALMODE + /* Install custom int15 handler for VGA OPROM */ + int15_install(); +#endif + + /* We have no driver for the embedded controller since the firmware + does most of the job. Hence, initialize keyboards here. */ + pc_keyboard_init(NULL); +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; + diff --git a/src/mainboard/roda/rk9/mainboard_smi.c b/src/mainboard/roda/rk9/mainboard_smi.c new file mode 100644 index 0000000000..8a87cd993b --- /dev/null +++ b/src/mainboard/roda/rk9/mainboard_smi.c @@ -0,0 +1,76 @@ +/* + * 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 <arch/romcc_io.h> +#include <console/console.h> +#include <cpu/x86/smm.h> +#include <southbridge/intel/i82801ix/nvs.h> +#include <southbridge/intel/i82801ix/i82801ix.h> +#include <ec/acpi/ec.h> + +/* The southbridge SMI handler checks whether gnvs has a + * valid pointer before calling the trap handler + */ +extern global_nvs_t *gnvs; + +int mainboard_io_trap_handler(int smif) +{ + switch (smif) { + case 0x99: + printk(BIOS_DEBUG, "Sample\n"); + gnvs->smif = 0; + break; + default: + return 0; + } + + /* On success, the IO Trap Handler returns 0 + * On failure, the IO Trap Handler returns a value != 0 + * + * For now, we force the return value to 0 and log all traps to + * see what's going on. + */ + //gnvs->smif = 0; + return 1; +} + +void mainboard_smi_gpi(u16 gpi_sts) +{ + if (gpi_sts & (1 << 1)) { + printk(BIOS_DEBUG, "EC/SMI\n"); + /* TODO */ + } +} + +int mainboard_smi_apmc(u8 apmc) +{ + switch (apmc) { + case APM_CNT_ACPI_ENABLE: + send_ec_command(0x05); /* Set_SMI_Disable */ + send_ec_command(0xaa); /* Set_ACPI_Enable */ + break; + + case APM_CNT_ACPI_DISABLE: + send_ec_command(0x04); /* Set_SMI_Enable */ + send_ec_command(0xab); /* Set_ACPI_Disable */ + break; + } + return 0; +} diff --git a/src/mainboard/roda/rk9/mptable.c b/src/mainboard/roda/rk9/mptable.c new file mode 100644 index 0000000000..f1839f03c8 --- /dev/null +++ b/src/mainboard/roda/rk9/mptable.c @@ -0,0 +1 @@ +/* dummy file */ diff --git a/src/mainboard/roda/rk9/romstage.c b/src/mainboard/roda/rk9/romstage.c new file mode 100644 index 0000000000..c6ca078dc1 --- /dev/null +++ b/src/mainboard/roda/rk9/romstage.c @@ -0,0 +1,211 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +// __PRE_RAM__ means: use "unsigned" for device, not a struct. + +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/tsc.h> +#include <cbmem.h> +#include <lib.h> +#include <pc80/mc146818rtc.h> +#include <console/console.h> +#include <southbridge/intel/i82801ix/i82801ix.h> +#include <northbridge/intel/gm45/gm45.h> +#include <superio/smsc/lpc47n227/early_serial.c> + +#define LPC_DEV PCI_DEV(0, 0x1f, 0) +#define SERIAL_DEV PNP_DEV(0x2e, LPC47N227_SP1) + +static void default_southbridge_gpio_setup(void) +{ + /* Enable GPIOs [31:0]. */ + outl(0x197e7dfe, DEFAULT_GPIOBASE + 0x00); + /* Set input/output mode [31:0] (0 == out, 1 == in). */ + outl(0xe0ea43fe, DEFAULT_GPIOBASE + 0x04); + /* Set gpio levels [31:0]. orig: 0x01140800 (~SATA0, ~SATA1, GSM, BT, + WLAN, ~ANTMUX, ~GPIO12, + ~SUSPWR, SMBALERT) */ + outl(0x00000800, DEFAULT_GPIOBASE + 0x0c); + + /* Disable blink [31:0]. */ + outl(0x00000000, DEFAULT_GPIOBASE + 0x18); + /* Set input inversion [31:0]. */ + outl(0x00000182, DEFAULT_GPIOBASE + 0x2c); + + /* Enable GPIOs [60:32]. */ + outl(0x130300fe, DEFAULT_GPIOBASE + 0x30); + /* Set input/output mode [60:32] (0 == out, 1 == in). */ + outl(0x0e55ffb0, DEFAULT_GPIOBASE + 0x34); + /* Set gpio levels [60:32]. orig: 0x10020046 (LNKALERT, ~ATAIO, + DMITERM, TXT, ~CLKSATA, + GPS, AUDIO) */ + outl(0x10020042, DEFAULT_GPIOBASE + 0x38); +} + +static void early_lpc_setup(void) +{ + /* Set up SuperIO LPC forwards */ + + /* Configure serial IRQs.*/ + pci_write_config8(LPC_DEV, D31F0_SERIRQ_CNTL, 0xd0); + /* Map COMa on 0x3f8, COMb on 0x2f8. */ + pci_write_config16(LPC_DEV, D31F0_LPC_IODEC, 0x0010); + /* Enable COMa, COMb, Kbd, SuperIO at 0x2e, MCs at 0x4e and 0x62/66. */ + pci_write_config16(LPC_DEV, D31F0_LPC_EN, 0x3c03); +} + +static void default_superio_gpio_setup(void) +{ + /* Original settings: + idx 30 31 32 33 34 35 36 37 38 39 + val 60 00 00 40 00 ff 00 e0 00 80 + def 00 00 00 00 00 00 00 00 00 80 + + Values: + GP1 GP2 GP3 GP4 + fd 17 88 14 + */ + const device_t sio = PNP_DEV(0x2e, 0); + + /* Enter super-io's configuration state. */ + pnp_enter_conf_state(sio); + + /* Set lpc47n227's runtime register block's base address. */ + pnp_write_config(sio, 0x30, 0x600 >> 4); + + /* Set GP23 to alternate function. */ + pnp_write_config(sio, 0x33, 0x40); + + /* Set GP30 - GP37 to output mode: COM control */ + pnp_write_config(sio, 0x35, 0xff); + + /* Set GP45 - GP47 to output mode. */ + pnp_write_config(sio, 0x37, 0xe0); + + /* Set nIO_PME to open drain. */ + pnp_write_config(sio, 0x39, 0x80); + + /* Exit configuration state. */ + pnp_exit_conf_state(sio); + + + /* Enable decoding of 0x600-0x60f through lpc. */ + pci_write_config32(LPC_DEV, D31F0_GEN1_DEC, 0x000c0601); + + /* Set GPIO output values: */ + outb(0x88, 0x600 + 0xb + 3); /* GP30 - GP37 */ + outb(0x10, 0x600 + 0xb + 4); /* GP40 - GP47 */ +} + +void main(unsigned long bist) +{ + sysinfo_t sysinfo; + int s3resume = 0; + u16 reg16; + + /* basic northbridge setup, including MMCONF BAR */ + gm45_early_init(); + + if (bist == 0) + enable_lapic(); + + /* First, run everything needed for console output. */ + i82801ix_early_init(); + early_lpc_setup(); + default_superio_gpio_setup(); + lpc47n227_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); + console_init(); + printk(BIOS_DEBUG, "running main(bist = %lu)\n", bist); + + reg16 = pci_read_config16(LPC_DEV, D31F0_GEN_PMCON_3); + pci_write_config16(LPC_DEV, D31F0_GEN_PMCON_3, reg16); + if ((MCHBAR16(SSKPD_MCHBAR) == 0xCAFE) && !(reg16 & (1 << 9))) { + printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); + gm45_early_reset(); + } + + default_southbridge_gpio_setup(); + + /* ASPM related setting, set early by original BIOS. */ + DMIBAR16(0x204) &= ~(3 << 10); + + /* Check for S3 resume. */ + const u32 pm1_cnt = inl(DEFAULT_PMBASE + 0x04); + if (((pm1_cnt >> 10) & 7) == 5) { +#if CONFIG_HAVE_ACPI_RESUME + printk(BIOS_DEBUG, "Resume from S3 detected.\n"); + s3resume = 1; + /* Clear SLP_TYPE. This will break stage2 but + * we care for that when we get there. + */ + outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + 0x04); +#else + printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n"); +#endif + } + + /* RAM initialization */ + enter_raminit_or_reset(); + get_gmch_info(&sysinfo); + raminit(&sysinfo, s3resume); + + raminit_thermal(&sysinfo); + init_igd(&sysinfo, 0, 1); /* Enable IGD, disable PEG. */ + init_pm(&sysinfo); + + i82801ix_dmi_setup(); + gm45_late_init(sysinfo.stepping); + i82801ix_dmi_poll_vc1(); + + MCHBAR16(SSKPD_MCHBAR) = 0xCAFE; + + init_iommu(); + +#if CONFIG_HAVE_ACPI_RESUME + /* Start address of high memory tables */ + unsigned long high_ram_base = get_top_of_ram() - HIGH_MEMORY_SIZE; + + /* 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((u64)high_ram_base)) { + void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME); + + /* copy 1MB - 64K to high tables ram_base to prevent memory corruption + * through stage 2. We could keep stuff like stack and heap in high tables + * memory completely, but that's a wonderful clean up task for another + * day. + */ + if (resume_backup_memory) + memcpy(resume_backup_memory, (void *)CONFIG_RAMBASE, HIGH_MEMORY_SAVE); + + /* Magic for S3 resume */ + pci_write_config32(PCI_DEV(0, 0, 0), D0F0_SKPD, SKPAD_ACPI_S3_MAGIC); + } +#endif + printk(BIOS_SPEW, "exit main()\n"); +} + diff --git a/src/mainboard/roda/rk9/ti_pci7xx1.c b/src/mainboard/roda/rk9/ti_pci7xx1.c new file mode 100644 index 0000000000..8acc90f9e7 --- /dev/null +++ b/src/mainboard/roda/rk9/ti_pci7xx1.c @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/cardbus.h> + +static void pci7xx1_enable(struct device *const dev) +{ + printk(BIOS_DEBUG, "%s: TI PCI7xx1 media controller\n", __func__); + if (PCI_FUNC(dev->path.pci.devfn) == 0) { + const uint16_t secondary = dev->bus->secondary; + const unsigned slot = PCI_SLOT(dev->path.pci.devfn); + + int fn; + + /* Hide functions based on devicetree info. */ + u16 gcr = pci_read_config16(dev, 0x86); + for (fn = 5; fn > 0; --fn) { + const struct device *const d = + dev_find_slot(secondary, PCI_DEVFN(slot, fn)); + if (!d || d->enabled) continue; + printk(BIOS_DEBUG, + "%s: Hiding function #%d.\n", __func__, fn); + switch (fn) { + case 1: gcr |= 1 << 4; break; /* CardBus B */ + case 2: gcr |= 1 << 3; break; /* OHCI 1394 */ + case 3: gcr |= 1 << 5; break; /* Flash media */ + case 4: gcr |= 1 << 6; break; /* SD card */ + case 5: gcr |= 1 << 7; break; /* Smart Card */ + } + } + pci_write_config16(dev, 0x86, gcr); + } +} + +static struct device_operations device_ops = { + .read_resources = cardbus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = cardbus_enable_resources, + .init = 0, + .scan_bus = pci_scan_bridge, + .enable = pci7xx1_enable, + .reset_bus = pci_bus_reset, +}; + +static const struct pci_driver ti_pci7xx1 __pci_driver = { + .ops = &device_ops, + .vendor = 0x104c, + .device = 0x8031, +}; + |