Intel ICH7 updates
authorStefan Reinauer <stepan@coresystems.de>
Tue, 21 Jul 2009 21:50:34 +0000 (21:50 +0000)
committerStefan Reinauer <stepan@openbios.org>
Tue, 21 Jul 2009 21:50:34 +0000 (21:50 +0000)
- code restructuring (move ich7 out of i945)
- ACPI fixes
- major SMI handler updates
- make sure SMBus lives where we expect it
- try to get usb debug working

Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4456 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

20 files changed:
src/southbridge/intel/i82801gx/acpi/globalnvs.asl [new file with mode: 0644]
src/southbridge/intel/i82801gx/acpi/ich7.asl
src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl [new file with mode: 0644]
src/southbridge/intel/i82801gx/acpi/ich7_audio.asl
src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl
src/southbridge/intel/i82801gx/acpi/ich7_pci.asl
src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl
src/southbridge/intel/i82801gx/acpi/sleepstates.asl [new file with mode: 0644]
src/southbridge/intel/i82801gx/i82801gx.h
src/southbridge/intel/i82801gx/i82801gx_ac97.c
src/southbridge/intel/i82801gx/i82801gx_lpc.c
src/southbridge/intel/i82801gx/i82801gx_nvs.h
src/southbridge/intel/i82801gx/i82801gx_pci.c
src/southbridge/intel/i82801gx/i82801gx_power.h [new file with mode: 0644]
src/southbridge/intel/i82801gx/i82801gx_sata.c
src/southbridge/intel/i82801gx/i82801gx_smbus.c
src/southbridge/intel/i82801gx/i82801gx_smi.c
src/southbridge/intel/i82801gx/i82801gx_smihandler.c
src/southbridge/intel/i82801gx/i82801gx_usb_debug.c
src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c

diff --git a/src/southbridge/intel/i82801gx/acpi/globalnvs.asl b/src/southbridge/intel/i82801gx/acpi/globalnvs.asl
new file mode 100644 (file)
index 0000000..368e906
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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
+ */
+
+/* Global Variables */
+
+Name(\PICM, 0)         // IOAPIC/8259
+Name(\DSEN, 1)         // Display Output Switching Enable
+
+/* Global ACPI memory region. This region is used for passing information 
+ * between coreboot (aka "the system bios"), ACPI, and the SMI handler.
+ * Since we don't know where this will end up in memory at ACPI compile time,
+ * we have to fix it up in coreboot's ACPI creation phase.
+ */
+
+
+OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0x100)
+Field (GNVS, ByteAcc, NoLock, Preserve)
+{
+       /* Miscellaneous */
+       Offset (0x00),
+       OSYS,   16,     // 0x00 - Operating System
+       SMIF,    8,     // 0x02 - SMI function
+       PRM0,    8,     // 0x03 - SMI function parameter
+       PRM1,    8,     // 0x04 - SMI function parameter
+       SCIF,    8,     // 0x05 - SCI function
+       PRM2,    8,     // 0x06 - SCI function parameter
+       PRM3,    8,     // 0x07 - SCI function parameter
+       LCKF,    8,     // 0x08 - Global Lock function for EC
+       PRM4,    8,     // 0x09 - Lock function parameter
+       PRM5,    8,     // 0x0a - Lock function parameter
+       P80D,   32,     // 0x0b - Debug port (IO 0x80) value
+       LIDS,    8,     // 0x0f - LID state (open = 1)
+       PWRS,    8,     // 0x10 - Power State (AC = 1)
+       DBGS,    8,     // 0x11 - Debug State
+       LINX,    8,     // 0x12 - Linux OS
+       DCKN,    8,     // 0x13 - PCIe docking state
+       /* Thermal policy */
+       Offset (0x14),
+       ACTT,    8,     // 0x14 - active trip point
+       PSVT,    8,     // 0x15 - passive trip point
+       TC1V,    8,     // 0x16 - passive trip point TC1
+       TC2V,    8,     // 0x17 - passive trip point TC2
+       TSPV,    8,     // 0x18 - passive trip point TSP
+       CRTT,    8,     // 0x19 - critical trip point
+       DTSE,    8,     // 0x1a - Digital Thermal Sensor enable
+       DTS1,    8,     // 0x1b - DT sensor 1
+       DTS2,    8,     // 0x1c - DT sensor 2
+       /* Battery Support */
+       Offset (0x1e),
+       BNUM,    8,     // 0x1e - number of batteries
+       B0SC,    8,     // 0x1f - BAT0 stored capacity
+       B1SC,    8,     // 0x20 - BAT1 stored capacity
+       B2SC,    8,     // 0x21 - BAT2 stored capacity
+       B0SS,    8,     // 0x22 - BAT0 stored status
+       B1SS,    8,     // 0x23 - BAT1 stored status
+       B2SS,    8,     // 0x24 - BAT2 stored status
+       /* Processor Identification */
+       Offset (0x28),
+       APIC,    8,     // 0x28 - APIC Enabled by coreboot
+       MPEN,    8,     // 0x29 - Multi Processor Enable
+       PCP0,    8,     // 0x2a - PDC CPU/CORE 0
+       PCP1,    8,     // 0x2b - PDC CPU/CORE 1
+       PPCM,    8,     // 0x2c - Max. PPC state
+       /* Super I/O & CMOS config */
+       Offset (0x32),
+       NATP,    8,     // 0x32 - ...
+       /* Integrated Graphics Device */
+       Offset (0x3c),
+       IGDS,    8,     // 0x3c - IGD state (primary = 1)
+       TLST,    8,     // 0x3d - Display Toggle List pointer
+       CADL,    8,     // 0x3e - Currently Attached Devices List
+       PADL,    8,     // 0x3f - Previously Attached Devices List
+       CSTE,   16,     // 0x40 - Current display state
+       NSTE,   16,     // 0x42 - Next display state
+       SSTE,   16,     // 0x44 - Set display state
+       Offset (0x46),
+       NDID,    8,     // 0x46 - Number of Device IDs
+       DID1,   32,     // 0x47 - Device ID 1
+       DID2,   32,     // 0x4b - Device ID 2
+       DID3,   32,     // 0x4f - Device ID 3
+       DID4,   32,     // 0x53 - Device ID 4
+       DID5,   32,     // 0x57 - Device ID 5
+       /* Backlight Control */
+       Offset (0x64),
+       BLCS,    8,     // 0x64 - Backlight control possible?
+       BRTL,    8,     // 0x65 - Brightness Level
+       ODDS,    8,     // 0x66
+       /* Ambient Light Sensors */
+       Offset (0x6e),
+       ALSE,    8,     // 0x6e - ALS enable
+       ALAF,    8,     // 0x6f - Ambient light adjustment factor
+       LLOW,    8,     // 0x70 - LUX Low
+       LHIH,    8,     // 0x71 - LUX High
+       /* EMA */
+       Offset (0x78),
+       EMAE,    8,     // 0x78 - EMA enable
+       EMAP,   16,     // 0x79 - EMA pointer
+       EMAL,   16,     // 0x7b - EMA length
+       /* MEF */
+       Offset (0x82),
+       MEFE,    8,     // 0x82 - MEF enable
+       /* TPM support */
+       Offset (0x8c),
+       TPMP,    8,     // 0x8c - TPM
+       TPME,    8,     // 0x8d - TPM enable
+       /* SATA */
+       Offset (0x96),
+       GTF0,   56,     // 0x96 - GTF task file buffer for port 0
+       GTF1,   56,     // 0x9d - GTF task file buffer for port 1
+       GTF2,   56,     // 0xa4 - GTF task file buffer for port 2
+       IDEM,    8,     // 0xab - IDE mode (compatible / enhanced)
+       IDET,    8,     // 0xac - IDE
+       /* IGD OpRegion */
+       Offset (0xb4),
+       ASLB,   32,     // 0xb4 - IGD OpRegion Base Address
+       IBTT,    8,     // 0xb8 - IGD boot panel device
+       IPAT,    8,     // 0xb9 - IGD panel type cmos option
+       ITVF,    8,     // 0xba - IGD TV format cmos option
+       ITVM,    8,     // 0xbb - IGD TV minor format option
+       IPSC,    8,     // 0xbc - IGD panel scaling
+       IBLC,    8,     // 0xbd - IGD BLC config
+       IBIA,    8,     // 0xbe - IGD BIA config
+       ISSC,    8,     // 0xbf - IGD SSC config
+       I409,    8,     // 0xc0 - IGD 0409 modified settings
+       I509,    8,     // 0xc1 - IGD 0509 modified settings
+       I609,    8,     // 0xc2 - IGD 0609 modified settings
+       I709,    8,     // 0xc3 - IGD 0709 modified settings
+       IDMM,    8,     // 0xc4 - IGD DVMT Mode
+       IDMS,    8,     // 0xc5 - IGD DVMT memory size
+       IF1E,    8,     // 0xc6 - IGD function 1 enable
+       HVCO,    8,     // 0xc7 - IGD HPLL VCO
+       NXD1,   32,     // 0xc8 - IGD _DGS next DID1
+       NXD2,   32,     // 0xcc - IGD _DGS next DID2
+       NXD3,   32,     // 0xd0 - IGD _DGS next DID3
+       NXD4,   32,     // 0xd4 - IGD _DGS next DID4
+       NXD5,   32,     // 0xd8 - IGD _DGS next DID5
+       NXD6,   32,     // 0xdc - IGD _DGS next DID6
+       NXD7,   32,     // 0xe0 - IGD _DGS next DID7
+       NXD8,   32,     // 0xe4 - IGD _DGS next DID8
+       /* Mainboard Specific (TODO move elsewhere) */
+       Offset (0xf0),
+       DOCK,    8,     // 0xf0 - Docking Status
+}
index 2e7233d9480457c3d5618cf7fbd7791572aacdc4..dd3bc87e2f01db4da664005c4ee3a44e74631ad0 100644 (file)
@@ -92,7 +92,8 @@ Scope(\)
                Offset(0x38),   // GPIO Level 2
                , 5,
                GP37, 1,        // PATA_PWR_EN
-               , 2,
+               GP38, 1,        // Battery / Power (?)
+               GP39, 1,        // ??
                GL05, 8,
                GL06, 8,
                GL07, 8
@@ -100,7 +101,7 @@ Scope(\)
 
 
        // ICH7 Root Complex Register Block. Memory Mapped through RCBA)
-       OperationRegion(RCRB, SystemMemory, 0xfff1000, 0x4000)
+       OperationRegion(RCRB, SystemMemory, 0xfed1c000, 0x4000)
        Field(RCRB, DWordAcc, Lock, Preserve)
        {
                Offset(0x0000), // Backbone
@@ -111,12 +112,22 @@ Scope(\)
                , 5,
                HPTE, 1,        // Address Enable
                Offset(0x3418), // FD (Function Disable)
-               , 1,
+               , 1,            // Reserved
                PATD, 1,        // PATA disable
                SATD, 1,        // SATA disable
                SMBD, 1,        // SMBUS disable
                HDAD, 1,        // Azalia disable
-               , 11,           // ... FIXME
+               A97D, 1,        // AC'97 disable
+               M97D, 1,        // AC'97 disable
+               ILND, 1,        // Internal LAN disable
+               US1D, 1,        // UHCI #1 disable
+               US2D, 1,        // UHCI #2 disable
+               US3D, 1,        // UHCI #3 disable
+               US4D, 1,        // UHCI #4 disable
+               , 2,            // Reserved
+               LPBD, 1,        // LPC bridge disable
+               EHCD, 1,        // EHCI disable
+               Offset(0x341a), // FD Root Ports
                RP1D, 1,        // Root Port 1 disable
                RP2D, 1,        // Root Port 2 disable
                RP3D, 1,        // Root Port 3 disable
@@ -139,6 +150,9 @@ Include ("../../../southbridge/intel/i82801gx/acpi/ich7_usb.asl")
 // PCI Bridge
 Include ("../../../southbridge/intel/i82801gx/acpi/ich7_pci.asl")
 
+// AC97 Audio and Modem
+Include ("../../../southbridge/intel/i82801gx/acpi/ich7_ac97.asl")
+
 // LPC Bridge
 Include ("../../../southbridge/intel/i82801gx/acpi/ich7_lpc.asl")
 
diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl b/src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl
new file mode 100644 (file)
index 0000000..7f76ccc
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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
+ */
+
+/* Intel i82801G AC'97 Audio and Modem */
+
+// Intel AC'97 Audio 0:1e.2
+
+Device (AUD0)
+{
+       Name (_ADR, 0x001e0002)
+}
+
+// Intel AC'97 Modem 0:1e.3
+
+Device (MODM)
+{
+       Name (_ADR, 0x001e0003)
+       
+       Name (_PRW, Package(){ 5, 4 })
+}
+
+
index 01ae8c58ecc648ecd40f648027ab655780fae937..5b8b386c394a5356840b664a1ecc2973b47839a0 100644 (file)
@@ -27,6 +27,10 @@ Device (HDEF)
 {
        Name (_ADR, 0x001b0000)
 
-       Name (_PRW, Package(){ 13, 4 })
+       // Power Resources for Wake
+       Name (_PRW, Package(){ 
+               5,  // Bit 5 of GPE
+               4   // Can wake from S4 state.
+       })
 }
 
index 80ba6e73bfba2267de99c9e3ea6c43a0c3d6de2d..d5705396ce5715753b60e12fbd09707f5e1ba031 100644 (file)
@@ -68,7 +68,7 @@ Device (LPCB)
                })
        }
 
-       Device (FWHD)           // Firmware Hub
+       Device (FWH           // Firmware Hub
        {
                Name (_HID, EISAID("INT0800"))
                Name (_CRS, ResourceTemplate()
@@ -80,7 +80,7 @@ Device (LPCB)
        Device (HPET)
        {
                Name (_HID, EISAID("PNP0103"))
-               Name (_CID, EISAID("PNP0C01"))
+               Name (_CID, 0x010CD041)
 
                Name(BUF0, ResourceTemplate()
                {
@@ -92,18 +92,32 @@ Device (LPCB)
                        If (HPTE) {
                                // Note: Ancient versions of Windows don't want
                                // to see the HPET in order to work right
-                               // Return (0xb) // Enable and don't show device
-
-                               Return (0xf)    // Enable and show device
+                               If (LGreaterEqual(OSYS, 2001)) {
+                                       Return (0xf)    // Enable and show device
+                               } Else {
+                                       Return (0xb)    // Enable and don't show device
+                               }
                        }
 
                        Return (0x0)    // Not enabled, don't show.
                }
 
-               Method (_CRS, 0, Serialized)
+               Method (_CRS, 0, Serialized) // Current resources
                {
-                       // Here we could do crazy stuff like move the HPET. Why
-                       // should we?
+                       If (HPTE) {
+                               CreateDWordField(BUF0, \_SB.PCI0.LPCB.HPET.FED0._BAS, HPT0)
+                               If (Lequal(HPAS, 1)) {
+                                       Store(0xfed01000, HPT0)
+                               }
+
+                               If (Lequal(HPAS, 2)) {
+                                       Store(0xfed02000, HPT0)
+                               }
+
+                               If (Lequal(HPAS, 3)) {
+                                       Store(0xfed03000, HPT0)
+                               }
+                       }
 
                        Return (BUF0)
                }
@@ -130,7 +144,7 @@ Device (LPCB)
                        IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
                        IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
                        IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
-                       IO (Decode16, 0x4d0, 0x4b0, 0x01, 0x02)
+                       IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
                        IRQNoFlags () { 2 }
                })
        }
@@ -145,7 +159,7 @@ Device (LPCB)
                })
        }
 
-       Device(MISC)    // Various other devices
+       Device(LDRC)    // LPC device: Resource consumption
        {
                Name (_HID, EISAID("PNP0C02"))
                Name (_UID, 2)
@@ -153,18 +167,18 @@ Device (LPCB)
                {
                        IO (Decode16, 0x2e, 0x2e, 0x1, 0x02)            // First SuperIO
                        IO (Decode16, 0x4e, 0x4e, 0x1, 0x02)            // Second SuperIO
-                       IO (Decode16, 0x61, 0x61, 0x1, 0x1)             // NMI Status
-                       IO (Decode16, 0x63, 0x63, 0x1, 0x1)             // CPU Reserved
-                       IO (Decode16, 0x65, 0x65, 0x1, 0x1)             // CPU Reserved
-                       IO (Decode16, 0x67, 0x67, 0x1, 0x1)             // CPU Reserved
-                       IO (Decode16, 0x80, 0x80, 0x1, 0x1)             // Port 80 Post
-                       IO (Decode16, 0x92, 0x92, 0x1, 0x1)             // CPU Reserved
+                       IO (Decode16, 0x61, 0x61, 0x1, 0x01)            // NMI Status
+                       IO (Decode16, 0x63, 0x63, 0x1, 0x01)            // CPU Reserved
+                       IO (Decode16, 0x65, 0x65, 0x1, 0x01)            // CPU Reserved
+                       IO (Decode16, 0x67, 0x67, 0x1, 0x01)            // CPU Reserved
+                       IO (Decode16, 0x80, 0x80, 0x1, 0x01)            // Port 80 Post
+                       IO (Decode16, 0x92, 0x92, 0x1, 0x01)            // CPU Reserved
                        IO (Decode16, 0xb2, 0xb2, 0x1, 0x02)            // SWSMI
-                       IO (Decode16, 0x680, 0x680, 0x1, 0x70)          // IO ???
+                       // IO (Decode16, 0x680, 0x680, 0x1, 0x70)       // IO ???
                        IO (Decode16, 0x800, 0x800, 0x1, 0x10)          // ACPI I/O trap
                        IO (Decode16, 0x0500, 0x0500, 0x1, 0x80)        // ICH7-M ACPI
-                       IO (Decode16, 0x1180, 0x1180, 0x1, 0x40)        // ICH7-M GPIO
-                       IO (Decode16, 0x1640, 0x1640, 0x1, 0x10)        // IO ???
+                       IO (Decode16, 0x0480, 0x0480, 0x1, 0x40)        // ICH7-M GPIO
+                       // IO (Decode16, 0x1640, 0x1640, 0x1, 0x10)     // IO ???
                })
        }
 
@@ -194,12 +208,19 @@ Device (LPCB)
        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
@@ -209,5 +230,36 @@ Device (LPCB)
                {
                        IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12
                })
+
+               Method(_STA, 0)
+               {
+                       Return (0xf)
+               }
+       }
+
+       Device (FDC0)           // Floppy controller
+       {
+               Name (_HID, EisaId ("PNP0700"))
+               Method (_STA, 0, NotSerialized)
+               {
+                       Return (0x0f) // FIXME
+               }
+
+               Name(_CRS, ResourceTemplate()
+               {
+                       IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
+                       IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
+                       IRQNoFlags () {6}
+                       DMA (Compatibility, NotBusMaster, Transfer8) {2}
+               })
+
+               Name(_PRS, ResourceTemplate()
+               {
+                       IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
+                       IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
+                       IRQNoFlags () {6}
+                       DMA (Compatibility, NotBusMaster, Transfer8) {2}
+               })
+
        }
 }
index bcdf084e37bf201a40eb297953913ce431cf4566..775a34dfe80c3202b7079599926d4473c5b9d800 100644 (file)
@@ -43,6 +43,24 @@ Device (PCIB)
                Name (_PRW, Package(){ 11, 4 })
        }
 
+       Device (SLT6)
+       {
+               Name (_ADR, 0x00050000)
+               Name (_PRW, Package(){ 11, 4 })
+       }
+
+       Device (LANC)
+       {
+               Name (_ADR, 0x00080000)
+               Name (_PRW, Package(){ 11, 3 })
+       }
+
+       Device (LANR)
+       {
+               Name (_ADR, 0x00000000)
+               Name (_PRW, Package(){ 11, 3 })
+       }
+
        // TODO: How many slots, where?
 
        // PCI Interrupt Routing.
@@ -52,47 +70,7 @@ Device (PCIB)
 
        Method (_PRT)
        {
-               If (PICM) {
-                       Return (Package() {
-                               // PCI Slot 1 routes FGHE
-                               Package() { 0x0000ffff, 0, 0, 16}, /* Firewire */
-                               Package() { 0x0000ffff, 1, 0, 22},
-                               Package() { 0x0000ffff, 2, 0, 23},
-                               Package() { 0x0000ffff, 3, 0, 20},
-
-                               // PCI Slot 2 routes GFEH (but is EFGH now, because that actually works)
-                               Package() { 0x0001ffff, 0, 0, 20},
-                               Package() { 0x0001ffff, 1, 0, 21},
-                               Package() { 0x0001ffff, 2, 0, 22},
-                               Package() { 0x0001ffff, 3, 0, 23},
-
-                               // PCI Slot 3 routes CDBA
-                               Package() { 0x0002ffff, 0, 0, 18},
-                               Package() { 0x0002ffff, 1, 0, 19},
-                               Package() { 0x0002ffff, 2, 0, 17},
-                               Package() { 0x0002ffff, 3, 0, 16}
-                       })
-               } Else {
-                       Return (Package() {
-                               // PCI Slot 1 routes FGHE
-                               Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKF, 0},
-                               Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKE, 0},
-                               Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKH, 0},
-                               Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKG, 0},
-
-                               // PCI Slot 2 routes GFEH
-                               Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKG, 0},
-                               Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKF, 0},
-                               Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKE, 0},
-                               Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKH, 0},
-
-                               // PCI Slot 3 routes CDBA
-                               Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKC, 0},
-                               Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKD, 0},
-                               Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKB, 0},
-                               Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
-                       })
-               }
+               Include ("acpi/ich7_pci_irqs.asl")
        }
 
 }
index d0779b75c3a25623c540bc85899a70db97026028..6b1009c24a9e371ab318df0ff97d260933a52c3b 100644 (file)
@@ -33,7 +33,8 @@ Device (SBUS)
                I2CE,   1
        }
 
-       OperationRegion (SMBI, SystemIO, 0x500, 0x20)
+       /*
+       OperationRegion (SMBI, SystemIO, 0x400, 0x20)
        Field (SMBI, ByteAcc, NoLock, Preserve)
        {
                HSTS,   8,      // Host Status
@@ -236,6 +237,7 @@ Device (SBUS)
 
                Return (0xffff)
        }
+       */
 
        // Todo: Does anyone ever use these?
        // Missing: Read / Write Word
diff --git a/src/southbridge/intel/i82801gx/acpi/sleepstates.asl b/src/southbridge/intel/i82801gx/acpi/sleepstates.asl
new file mode 100644 (file)
index 0000000..6159585
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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
+ */
+
+Name(\_S0, Package(4){0x0,0x0,0,0})
+Name(\_S1, Package(4){0x1,0x0,0,0})
+Name(\_S3, Package(4){0x5,0x0,0,0})
+Name(\_S4, Package(4){0x6,0x0,0,0})
+Name(\_S5, Package(4){0x7,0x0,0,0})
+
index a1771230fc8022eaf60a8d61853e700bcf069656..19472ed1f9d9b00f293b038d4832413aa055672c 100644 (file)
 #ifndef SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H
 #define SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H
 
+/* __ROMCC__ is set by auto.c to make sure
+ * none of the stage2 data structures are included.
+ */
+#ifndef __ROMCC__
 #include "chip.h"
 extern void i82801gx_enable(device_t dev);
+#endif
+
+/* PCI Configuration Space (D31:F0): LPC */
 
 #define SERIRQ_CNTL            0x64
 
@@ -58,7 +65,31 @@ extern void i82801gx_enable(device_t dev);
 #define IDE_TIM_PRI            0x40    /* IDE timings, primary */
 #define   IDE_DECODE_ENABLE    (1 << 15)
 #define   IDE_SITRE            (1 << 14)
+#define   IDE_ISP_5_CLOCKS     (0 << 12)
+#define   IDE_ISP_4_CLOCKS     (1 << 12)
+#define   IDE_ISP_3_CLOCKS     (2 << 12)
+#define   IDE_RCT_4_CLOCKS     (0 <<  8)
+#define   IDE_RCT_3_CLOCKS     (1 <<  8)
+#define   IDE_RCT_2_CLOCKS     (2 <<  8)
+#define   IDE_RCT_1_CLOCKS     (3 <<  8)
+#define   IDE_DTE1             (1 <<  7)
+#define   IDE_PPE1             (1 <<  6)
+#define   IDE_IE1              (1 <<  5)
+#define   IDE_TIME1            (1 <<  4)
+#define   IDE_DTE0             (1 <<  3)
+#define   IDE_PPE0             (1 <<  2)
+#define   IDE_IE0              (1 <<  1)
+#define   IDE_TIME0            (1 <<  0)
 #define IDE_TIM_SEC            0x42    /* IDE timings, secondary */
+
+#define IDE_SDMA_CNT           0x48    /* Synchronous DMA control */
+#define   IDE_SSDE1            (1 <<  3)
+#define   IDE_SSDE0            (1 <<  2)
+#define   IDE_PSDE1            (1 <<  1)
+#define   IDE_PSDE0            (1 <<  0)
+
+#define IDE_SDMA_TIM           0x4a
+
 #define IDE_CONFIG             0x54    /* IDE I/O Configuration Register */
 #define   SIG_MODE_NORMAL      (0 << 16)
 #define   SIG_MODE_TRISTATE    (1 << 16)
@@ -78,12 +109,13 @@ extern void i82801gx_enable(device_t dev);
 #define HST_EN                 (1 << 0)
 
 /* SMBus I/O bits.
- * TODO: It does not matter where we put the SMBus IO base, as long as we keep
- * consistent and don't interfere with other devices. Stage2 will relocate 
- * this anyways. But it's a general problem we have not solved in the brightest
- * possible way.
+ * It does not matter where we put the SMBus I/O base, as long as we 
+ * keep it consistent and don't interfere with other devices.  Stage2
+ * will relocate this anyways.
+ * Our solution is to have SMB initialization move the I/O to SMBUS_IO_BASE
+ * again. But handling static BARs is a generic problem that should be 
+ * solved in the device allocator.
  */
-/* #define SMBUS_IO_BASE 0x1000 */
 #define SMBUS_IO_BASE          0x0400
 
 #define SMBHSTSTAT             0x0
@@ -103,4 +135,124 @@ extern void i82801gx_enable(device_t dev);
 /* HPET, if present */
 #define HPET_ADDR              0xfed0000
 
+/* Southbridge IO BARs */
+
+/* TODO Make sure these don't get changed by stage2 */
+#define GPIOBASE               0x48
+#define DEFAULT_GPIOBASE       0x480
+
+#define PMBASE         0x40
+#define DEFAULT_PMBASE 0x500
+
+/* Root Complex Register Block */
+#define RCBA           0xf0
+#define DEFAULT_RCBA           0xfed1c000
+
+#define RCBA8(x) *((volatile u8 *)(DEFAULT_RCBA + x))
+#define RCBA16(x) *((volatile u16 *)(DEFAULT_RCBA + x))
+#define RCBA32(x) *((volatile u32 *)(DEFAULT_RCBA + x))
+
+#define VCH            0x0000  /* 32bit */
+#define VCAP1          0x0004  /* 32bit */
+#define VCAP2          0x0008  /* 32bit */
+#define PVC            0x000c  /* 16bit */
+#define PVS            0x000e  /* 16bit */
+
+#define V0CAP          0x0010  /* 32bit */
+#define V0CTL          0x0014  /* 32bit */
+#define V0STS          0x001a  /* 16bit */
+
+#define V1CAP          0x001c  /* 32bit */
+#define V1CTL          0x0020  /* 32bit */
+#define V1STS          0x0026  /* 16bit */
+
+#define RCTCL          0x0100  /* 32bit */
+#define ESD            0x0104  /* 32bit */
+#define ULD            0x0110  /* 32bit */
+#define ULBA           0x0118  /* 64bit */
+
+#define RP1D           0x0120  /* 32bit */
+#define RP1BA          0x0128  /* 64bit */
+#define RP2D           0x0130  /* 32bit */
+#define RP2BA          0x0138  /* 64bit */
+#define RP3D           0x0140  /* 32bit */
+#define RP3BA          0x0148  /* 64bit */
+#define RP4D           0x0150  /* 32bit */
+#define RP4BA          0x0158  /* 64bit */
+#define HDD            0x0160  /* 32bit */
+#define HDBA           0x0168  /* 64bit */
+#define RP5D           0x0170  /* 32bit */
+#define RP5BA          0x0178  /* 64bit */
+#define RP6D           0x0180  /* 32bit */
+#define RP6BA          0x0188  /* 64bit */
+
+#define ILCL           0x01a0  /* 32bit */
+#define LCAP           0x01a4  /* 32bit */
+#define LCTL           0x01a8  /* 16bit */
+#define LSTS           0x01aa  /* 16bit */
+
+#define RPC            0x0224  /* 32bit */
+#define RPFN           0x0238  /* 32bit */
+
+#define TRSR           0x1e00  /*  8bit */
+#define TRCR           0x1e10  /* 64bit */
+#define TWDR           0x1e18  /* 64bit */
+
+#define IOTR0          0x1e80  /* 64bit */
+#define IOTR1          0x1e88  /* 64bit */
+#define IOTR2          0x1e90  /* 64bit */
+#define IOTR3          0x1e98  /* 64bit */
+
+#define TCTL           0x3000  /*  8bit */
+
+#define D31IP          0x3100  /* 32bit */
+#define D30IP          0x3104  /* 32bit */
+#define D29IP          0x3108  /* 32bit */
+#define D28IP          0x310c  /* 32bit */
+#define D27IP          0x3110  /* 32bit */
+#define D31IR          0x3140  /* 16bit */
+#define D30IR          0x3142  /* 16bit */
+#define D29IR          0x3144  /* 16bit */
+#define D28IR          0x3146  /* 16bit */
+#define D27IR          0x3148  /* 16bit */
+#define OIC            0x31ff  /*  8bit */
+
+#define RC             0x3400  /* 32bit */
+#define HPTC           0x3404  /* 32bit */
+#define GCS            0x3410  /* 32bit */
+#define BUC            0x3414  /* 32bit */
+#define FD             0x3418  /* 32bit */
+#define CG             0x341c  /* 32bit */
+
+/* Function Disable (FD) register values.
+ * Setting a bit disables the corresponding
+ * feature.
+ * Not all features might be disabled on
+ * all chipsets. Esp. ICH-7U is picky.
+ */
+#define FD_PCIE6       (1 << 21)
+#define FD_PCIE5       (1 << 20)
+#define FD_PCIE4       (1 << 19)
+#define FD_PCIE3       (1 << 18)
+#define FD_PCIE2       (1 << 17)
+#define FD_PCIE1       (1 << 16)
+#define FD_EHCI                (1 << 15)
+#define FD_LPCB                (1 << 14)
+
+/* UHCI must be disabled from 4 downwards.
+ * If UHCI controllers get disabled, EHCI
+ * must know about it, too! */
+#define FD_UHCI4       (1 << 11)
+#define FD_UHCI34      (1 << 10) | FD_UHCI4
+#define FD_UHCI234     (1 <<  9) | FD_UHCI3
+#define FD_UHCI1234    (1 <<  8) | FD_UHCI2
+
+#define FD_INTLAN      (1 <<  7)
+#define FD_ACMOD       (1 <<  6)
+#define FD_ACAUD       (1 <<  5)
+#define FD_HDAUD       (1 <<  4)
+#define FD_SMBUS       (1 <<  3)
+#define FD_SATA                (1 <<  2)
+#define FD_PATA                (1 <<  1)
+
 #endif                         /* SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H */
index e78b1eb28218290a8ff42a0c2df36e0e7ffdbe79..f447de60f14f20d5089ba34bcf74061044036183 100644 (file)
@@ -251,6 +251,21 @@ static void ac97_modem_init(struct device *dev)
        }
 }
 
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+       if (!vendor || !device) {
+               pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+                               pci_read_config32(dev, PCI_VENDOR_ID));
+       } else {
+               pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+                               ((device & 0xffff) << 16) | (vendor & 0xffff));
+       }
+}
+
+static struct pci_operations ac97_pci_ops = {
+       .set_subsystem    = ac97_set_subsystem,
+};
+
 static struct device_operations ac97_audio_ops = {
        .read_resources         = pci_dev_read_resources,
        .set_resources          = pci_dev_set_resources,
@@ -258,6 +273,7 @@ static struct device_operations ac97_audio_ops = {
        .init                   = ac97_audio_init,
        .scan_bus               = 0,
        .enable                 = i82801gx_enable,
+       .ops_pci                = &ac97_pci_ops,
 };
 
 static struct device_operations ac97_modem_ops = {
@@ -267,6 +283,7 @@ static struct device_operations ac97_modem_ops = {
        .init                   = ac97_modem_init,
        .scan_bus               = 0,
        .enable                 = i82801gx_enable,
+       .ops_pci                = &ac97_pci_ops,
 };
 
 /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
index ca2b409321ce75943bf93ec6b3803ad364e3dab7..f42471f3ef1a3be4652ea72c6d9677d4f7f35ceb 100644 (file)
 #include <pc80/i8259.h>
 #include <arch/io.h>
 #include "i82801gx.h"
+#include "i82801gx_power.h"
 
-#include "../../../northbridge/intel/i945/ich7.h"
+#define NMI_OFF        0
 
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON  1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-#define NMI_OFF 0
+#define ENABLE_ACPI_MODE_IN_COREBOOT   0
+#define TEST_SMM_FLASH_LOCKDOWN                0
 
 typedef struct southbridge_intel_i82801gx_config config_t;
 
@@ -78,7 +73,9 @@ static void i82801gx_enable_apic(struct device *dev)
        volatile u32 *ioapic_index = (volatile u32 *)0xfec00000;
        volatile u32 *ioapic_data = (volatile u32 *)0xfec00010;
 
-       /* Enable ACPI I/O and power management. */
+       /* Enable ACPI I/O and power management. 
+        * Set SCI IRQ to IRQ9
+        */
        pci_write_config8(dev, ACPI_CNTL, 0x80);
 
        *ioapic_index = 0;
@@ -109,6 +106,27 @@ static void i82801gx_enable_serial_irqs(struct device *dev)
                          (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
 }
 
+/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ * PIRQ[n]_ROUT[7] - PIRQ Routing Control
+ * 0x80 - The PIRQ is not routed.
+ */
+
 static void i82801gx_pirq_init(device_t dev)
 {
        device_t irq_dev;
@@ -180,10 +198,14 @@ static void i82801gx_gpi_routing(device_t dev)
        pci_write_config32(dev, 0xb8, reg32);
 }
 
+extern u8 acpi_slp_type;
+
 static void i82801gx_power_options(device_t dev)
 {
        u8 reg8;
-       u16 reg16;
+       u16 reg16, pmbase;
+       u32 reg32;
+       char *state;
 
        int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
        int nmi_option;
@@ -195,16 +217,28 @@ static void i82801gx_power_options(device_t dev)
         get_option(&pwr_on, "power_on_after_fail");
        reg8 = pci_read_config8(dev, GEN_PMCON_3);
        reg8 &= 0xfe;
-       if (pwr_on) {
-               reg8 &= ~1;
-       } else {
+       switch (pwr_on) {
+       case MAINBOARD_POWER_OFF:
                reg8 |= 1;
+               state = "off";
+               break;
+       case MAINBOARD_POWER_ON:
+               reg8 &= ~1;
+               state = "on";
+               break;
+       case MAINBOARD_POWER_KEEP:
+               reg8 &= ~1;
+               state = "state keep";
+               break;
+       default:
+               state = "undefined";
        }
+
        reg8 |= (3 << 4);       /* avoid #S4 assertions */
        reg8 &= ~(1 << 3);      /* minimum asssertion is 1 to 2 RTCCLK */
 
        pci_write_config8(dev, GEN_PMCON_3, reg8);
-       printk_info("Set power %s after power failure.\n", pwr_on ? "on" : "off");
+       printk_info("Set power %s after power failure.\n", state);
 
        /* Set up NMI on errors. */
        reg8 = inb(0x61);
@@ -226,15 +260,27 @@ static void i82801gx_power_options(device_t dev)
        }
        outb(reg8, 0x70);
 
-       // Enable CPU_SLP# and Intel Speedstep, set SMI# rate down
+       /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
        reg16 = pci_read_config16(dev, GEN_PMCON_1);
        reg16 &= ~((3 << 0) | (1 << 10));
        reg16 |= (1 << 3) | (1 << 5);
-       reg16 |= (1 << 2); // CLKRUN_EN
+       reg16 |= (1 << 2);                      // CLKRUN_EN
        pci_write_config16(dev, GEN_PMCON_1, reg16);
 
        // Set the board's GPI routing.
        i82801gx_gpi_routing(dev);
+
+       /* Set up power management block and determine sleep mode */
+       pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
+       reg32 = inl(pmbase + 0x04); // PM1_CNT
+#if HAVE_ACPI_RESUME
+       acpi_slp_type = (((reg32 >> 10) & 7) == 5) ? 3 : 0;
+       printk_debug("PM1_CNT: 0x%08x --> acpi_sleep_type: %x\n", 
+                       reg32, acpi_slp_type);
+#endif
+       reg32 |= (1 << 1); // enable C3->C0 transition on bus master
+       reg32 |= 1; // SCI_EN
+       outl(reg32, pmbase + 0x04);
 }
 
 static void i82801gx_configure_cstates(device_t dev)
@@ -273,9 +319,10 @@ static void enable_hpet(void)
 {
        u32 reg32;
        
-       /* Leave HPET at default address, but enable it */
+       /* Move HPET to default address 0xfed00000 and enable it */
        reg32 = RCBA32(0x3404);
        reg32 |= (1 << 7); // HPET Address Enable
+       reg32 &= ~(3 << 0);
        RCBA32(0x3404) = reg32;
 }
 
@@ -467,6 +514,13 @@ static struct device_operations device_ops = {
        .ops_pci                = &pci_ops,
 };
 
+/* 82801GH (ICH7 DH) */
+static const struct pci_driver ich7_dh_lpc __pci_driver = {
+       .ops    = &device_ops,
+       .vendor = PCI_VENDOR_ID_INTEL,
+       .device = 0x27b0,
+};
+
 /* 82801GB/GR (ICH7/ICH7R) */
 static const struct pci_driver ich7_ich7r_lpc __pci_driver = {
        .ops    = &device_ops,
index 3f01f2ace9213774c15d78891dbabfd94738edef..7f245dd11afb4552904c752288b9f8c9813a6243 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the coreboot project.
  *
- * Copyright (C) 2008 coresystems GmbH
+ * 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
  */
 
 typedef struct {
-       u16     osys;
-       u8      smif;
-       u8      prm0;
-       u8      prm1;
-       u8      scif;
-       u8      prm2;
-       u8      prm3;
-       u8      lckf;
-       u8      prm4;
-       u8      prm5;
-       u32     p80d;
-       u8      lids;
-       u8      pwrs;
-       u8      dbgs;
-       u8      linxs;
-       u8      rsvd;
-       u8      actt;
-       u8      psvt;
-       u8      tc1v;
-       u8      tc2v;
-       u8      tspv;
-       u8      crtt;
-       u8      dtse;
-       u8      dts1;
-       u8      dts2;
+       /* Miscellaneous */
+       u16     osys; /* 0x00 - Operating System */
+       u8      smif; /* 0x02 - SMI function call ("TRAP") */
+       u8      prm0; /* 0x03 - SMI function call parameter */
+       u8      prm1; /* 0x04 - SMI function call parameter */
+       u8      scif; /* 0x05 - SCI function call (via _L00) */
+       u8      prm2; /* 0x06 - SCI function call parameter */
+       u8      prm3; /* 0x07 - SCI function call parameter */
+       u8      lckf; /* 0x08 - Global Lock function for EC */
+       u8      prm4; /* 0x09 - Lock function parameter */
+       u8      prm5; /* 0x0a - Lock function parameter */
+       u32     p80d; /* 0x0b - Debug port (IO 0x80) value */
+       u8      lids; /* 0x0f - LID state (open = 1) */
+       u8      pwrs; /* 0x10 - Power state (AC = 1) */
+       u8      dbgs; /* 0x11 - Debug state */
+       u8      linx; /* 0x12 - Linux OS */
+       u8      dckn; /* 0x13 - PCIe docking state */
+       /* Thermal policy */
+       u8      actt; /* 0x14 - active trip point */
+       u8      psvt; /* 0x15 - passive trip point */
+       u8      tc1v; /* 0x16 - passive trip point TC1 */
+       u8      tc2v; /* 0x17 - passive trip point TC2 */
+       u8      tspv; /* 0x18 - passive trip point TSP */
+       u8      crtt; /* 0x19 - critical trip point */
+       u8      dtse; /* 0x1a - Digital Thermal Sensor enable */
+       u8      dts1; /* 0x1b - DT sensor 1 */
+       u8      dts2; /* 0x1c - DT sensor 2 */
        u8      rsvd2;
-       u8      bnum;
-       u8      b0sc, b1sc, b2sc;
-       u8      b0ss, b1ss, b2ss;
+       /* Battery Support */
+       u8      bnum; /* 0x1e - number of batteries */
+       u8      b0sc, b1sc, b2sc; /* 0x1f-0x21 - stored capacity */
+       u8      b0ss, b1ss, b2ss; /* 0x22-0x24 - stored status */
        u8      rsvd3[3];
-       u8      apic;
-       u8      mpen;
-       u8      bten;
-       u8      ppcm;
-       u8      pcp0;
-       u8      pcp1;
-       u8      rsvd4[4];
-       u8      natp;
+       /* Processor Identification */
+       u8      apic; /* 0x28 - APIC enabled */
+       u8      mpen; /* 0x29 - MP capable/enabled */
+       u8      pcp0; /* 0x2a - PDC CPU/CORE 0 */
+       u8      pcp1; /* 0x2b - PDC CPU/CORE 1 */
+       u8      ppcm; /* 0x2c - Max. PPC state */
+       u8      rsvd4[5];
+       /* Super I/O & CMOS config */
+       u8      natp; /* 0x32 - SIO type */
        u8      cmap;
        u8      cmbp;
        u8      lptp;
@@ -67,42 +71,69 @@ typedef struct {
        u8      rtcf;
        u8      util;
        u8      acin;
-       u8      igds;
-       u8      tlst;
-       u8      cadl;
-       u8      padl;
-       u16     cste;
-       u16     pste;
-       u16     nste;
-       u16     sste;
-       u8      ndid;
-       u32     did1;
-       u32     did2;
-       u32     did3;
-       u32     did4;
-       u32     did5;
-       u8      rsvd5[0xb];
+       /* Integrated Graphics Device */
+       u8      igds; /* 0x3c - IGD state */
+       u8      tlst; /* 0x3d - Display Toggle List Pointer */
+       u8      cadl; /* 0x3e - currently attached devices */
+       u8      padl; /* 0x3f - previously attached devices */
+       u16     cste; /* 0x40 - current display state */
+       u16     nste; /* 0x42 - next display state */
+       u16     sste; /* 0x44 - set display state */
+       u8      ndid; /* 0x46 - number of device ids */
+       u32     did[5]; /* 0x47 - 5b device id 1..5 */
+       u8      rsvd5[0x9];
+       /* Backlight Control */
+       u8      blcs; /* 0x64 - Backlight Control possible */
        u8      brtl;
        u8      odds;
-       u8      alse;
+       u8      rsvd6[0x7];
+       /* Ambient Light Sensors*/
+       u8      alse; /* 0x6e - ALS enable */
        u8      alaf;
        u8      llow;
        u8      lhih;
-       u8      rsvd6;
-       u8      emae;
+       u8      rsvd7[0x6];
+       /* EMA */
+       u8      emae; /* 0x78 - EMA enable */
        u16     emap;
        u16     emal;
-       u8      rsvd7;
-       u8      mefe;
-       u8      igps;
-       u8      rsvd8[2];
-       u8      tpmp;
+       u8      rsvd8[0x5];
+       /* MEF */
+       u8      mefe; /* 0x82 - MEF enable */
+       u8      rsvd9[0x9];
+       /* TPM support */
+       u8      tpmp; /* 0x8c - TPM */
        u8      tpme;
-       u8      rsvd9[8];
-       u8      gtf0[7];
+       u8      rsvd10[8];
+       /* SATA */
+       u8      gtf0[7]; /* 0x96 - GTF task file buffer for port 0 */
+       u8      gtf1[7];
        u8      gtf2[7];
        u8      idem;
        u8      idet;
-       u8      dock;
-} global_nvs_t;
+       u8      rsvd11[7];
+       /* IGD OpRegion (not implemented yet) */
+       u32     aslb; /* 0xb4 - IGD OpRegion Base Address */
+       u8      ibtt;
+       u8      ipat;
+       u8      itvf;
+       u8      itvm;
+       u8      ipsc;
+       u8      iblc;
+       u8      ibia;
+       u8      issc;
+       u8      i409;
+       u8      i509;
+       u8      i609;
+       u8      i709;
+       u8      idmm;
+       u8      idms;
+       u8      if1e;
+       u8      hvco;
+       u32     nxd[8];
+       u8      rsvd12[8];
+       /* Mainboard specific */
+       u8      dock; /* 0xf0 - Docking Status */
+       u8      rsvd13[15];
+} __attribute__((packed)) global_nvs_t;
 
index bf252ec37e606bb3907b433b0a8ba670cb90518e..2e1a251e37c8c4a1ac0f10a77b359dbcb9775cfe 100644 (file)
@@ -81,7 +81,7 @@ static void ich_pci_dev_enable_resources(struct device *dev)
 
        command = pci_read_config16(dev, PCI_COMMAND);
        command |= dev->command;
-#if PCI_BRIDGE_UPDATE_COMMAND
+#ifdef PCI_BRIDGE_UPDATE_COMMAND
        /* If we write to PCI_COMMAND, on some systems 
         * this will cause the ROM and APICs not being visible
         * anymore.
diff --git a/src/southbridge/intel/i82801gx/i82801gx_power.h b/src/southbridge/intel/i82801gx/i82801gx_power.h
new file mode 100644 (file)
index 0000000..d2eb8b4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#define MAINBOARD_POWER_OFF    0
+#define MAINBOARD_POWER_ON     1
+#define MAINBOARD_POWER_KEEP   2
+
+#ifndef MAINBOARD_POWER_ON_AFTER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_FAIL MAINBOARD_POWER_ON
+#endif
+
index 0f092e9204e03e26c4613f0566d994512ffeb131..74ba823f34f24584376deada22d10ac4df189548 100644 (file)
@@ -35,8 +35,10 @@ static void sata_init(struct device *dev)
 
        printk_debug("i82801gx_sata: initializing...\n");
 
-       if (config == NULL)
+       if (config == NULL) {
                printk_err("i82801gx_sata: error: device not in Config.lb!\n");
+               return;
+       }
 
        /* SATA configuration */
 
@@ -55,12 +57,15 @@ static void sata_init(struct device *dev)
                pci_write_config8(dev, 0x09, 0x80);
 
                /* Set timings */
-               pci_write_config16(dev, IDE_TIM_PRI, 0x8000);
-               pci_write_config16(dev, IDE_TIM_SEC, 0xa307);
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
 
                /* Sync DMA */
-               pci_write_config16(dev, 0x48, 0x0004);
-               pci_write_config16(dev, 0x4a, 0x0200);
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
 
                /* Set IDE I/O Configuration */
                reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
@@ -84,12 +89,15 @@ static void sata_init(struct device *dev)
                pci_write_config8(dev, INTR_LN, 0x0a);
 
                /* Set timings */
-               pci_write_config16(dev, IDE_TIM_PRI, 0xa307);
-               pci_write_config16(dev, IDE_TIM_SEC, 0x8000);
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
 
                /* Sync DMA */
-               pci_write_config16(dev, 0x48, 0x0001);
-               pci_write_config16(dev, 0x4a, 0x0001);
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
 
                /* Set IDE I/O Configuration */
                reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
@@ -126,12 +134,16 @@ static void sata_init(struct device *dev)
                pci_write_config8(dev, INTR_LN, 0xff);
        
                /* Set timings */
-               pci_write_config16(dev, IDE_TIM_PRI, 0xa307);
-               pci_write_config16(dev, IDE_TIM_SEC, 0xe303);
+               pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+                               IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+                               IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+               pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+                               IDE_SITRE | IDE_ISP_3_CLOCKS | 
+                               IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
        
                /* Sync DMA */
-               pci_write_config16(dev, 0x48, 0x0005);
-               pci_write_config16(dev, 0x4a, 0x0201);
+               pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
+               pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
        
                /* Set IDE I/O Configuration */
                reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
index e9f9c7d9186a5c9c6d7bcb0e4dafb0329f68f5c8..ee9f47e811522be8be799cd18f47d787c8cbe359 100644 (file)
 #include "i82801gx.h"
 #include "i82801gx_smbus.h"
  
+#define SMB_BASE 0x20
+static void smbus_init(struct device *dev)
+{
+       u32 smb_base;
+
+       smb_base = pci_read_config32(dev, SMB_BASE);
+       printk_debug("Initializing SMBus device:\n");
+       printk_debug("  Old SMBUS Base Address: 0x%04x\n", smb_base);
+       pci_write_config32(dev, SMB_BASE, 0x00000401);
+       smb_base = pci_read_config32(dev, SMB_BASE);
+       printk_debug("  New SMBUS Base Address: 0x%04x\n", smb_base);
+}
+
 static int lsmbus_read_byte(device_t dev, u8 address)
 {
        u16 device;
@@ -65,7 +78,7 @@ static struct device_operations smbus_ops = {
        .read_resources         = pci_dev_read_resources,
        .set_resources          = pci_dev_set_resources,
        .enable_resources       = pci_dev_enable_resources,
-       .init                   = 0,
+       .init                   = smbus_init,
        .scan_bus               = scan_static_bus,
        .enable                 = i82801gx_enable,
        .ops_smbus_bus          = &lops_smbus_bus,
index ccbb7334e57646ce65fcf025b9397a764d1b7f09..636d2eb3af9162c9566aebd4121c51fa1cdb2aba 100644 (file)
 #include <cpu/x86/cache.h>
 #include <cpu/x86/smm.h>
 #include <string.h>
-#include "chip.h"
-
-// Future TODO: Move to i82801gx directory
-#include "../../../northbridge/intel/i945/ich7.h"
+#include "i82801gx.h"
 
 extern unsigned char smm[];
 extern unsigned int smm_len;
@@ -318,8 +315,12 @@ void smm_install(void)
 
 void smm_init(void)
 {
+       // FIXME is this a race condition?
        smm_relocate();
        smm_install();
+
+       // We're done. Make sure SMIs can happen!
+       smi_set_eos();
 }
 
 void smm_lock(void)
@@ -333,3 +334,13 @@ void smm_lock(void)
                        D_LCK | G_SMRAME | C_BASE_SEG);
 }
 
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+       /* The GDT or coreboot table is going to live here. But a long time
+        * after we relocated the GNVS, so this is not troublesome.
+        */
+       *(u32 *)0x500 = (u32)gnvs;
+       *(u32 *)0x504 = (u32)tcg;
+       *(u32 *)0x508 = (u32)smi1;
+       outb(0xea, 0xb2);
+}
index d2826c6aca6b019073f613106fd7c38fee40fe3a..94207d0e4dc580cb201201fbb2f476fb649cfde1 100644 (file)
  * MA 02110-1301 USA
  */
 
+#include <types.h>
 #include <arch/io.h>
 #include <arch/romcc_io.h>
 #include <console/console.h>
 #include <cpu/x86/cache.h>
 #include <cpu/x86/smm.h>
-//#include "chip.h"
-
-// Future TODO: Move to i82801gx directory
-#include "../../../northbridge/intel/i945/ich7.h"
+#include "i82801gx.h"
+#include "i82801gx_power.h"
 
 #define DEBUG_SMI
 
 #define APM_CNT                0xb2
-#define APM_STS                0xb3
+#define   CST_CONTROL  0x85 // 0x85 crashes the box
+#define   PST_CONTROL  0x80 // 0x80 crashes the box
 #define   ACPI_DISABLE 0x1e
 #define   ACPI_ENABLE  0xe1
+#define   GNVS_UPDATE   0xea
+#define APM_STS                0xb3
 
 /* I945 */
 #define SMRAM          0x9d
 #define PM1_STS                0x00
 #define PM1_EN         0x02
 #define PM1_CNT                0x04
+#define   SLP_EN       (1 << 13)
+#define   SLP_TYP      (7 << 10)
+#define   GBL_RLS      (1 << 2)
+#define   BM_RLD       (1 << 1)
+#define   SCI_EN       (1 << 0)
 #define PM1_TMR                0x08
 #define PROC_CNT       0x10
 #define LV2            0x14
@@ -56,6 +63,7 @@
 #define PM2_CNT                0x20 // mobile only
 #define GPE0_STS       0x28
 #define GPE0_EN                0x2c
+#define   PME_B0_EN    (1 << 13)
 #define SMI_EN         0x30
 #define   EL_SMI_EN     (1 << 25) // Intel Quick Resume Technology
 #define   INTEL_USB2_EN         (1 << 18) // Intel-Specific USB2 SMI logic
 /* While we read PMBASE dynamically in case it changed, let's
  * initialize it with a sane value
  */
-static u16 pmbase = DEFAULT_PMBASE;
+u16 pmbase = DEFAULT_PMBASE;
+
+/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
+ * by coreboot.
+ */
+global_nvs_t *gnvs = (global_nvs_t *)0x0;
+void *tcg = (void *)0x0;
+void *smi1 = (void *)0x0;
 
 /**
  * @brief read and clear PM1_STS 
@@ -235,7 +250,6 @@ static void dump_tco_status(u32 tco_sts)
        printk_debug("\n");
 }
 
-
 /* We are using PCIe accesses for now
  *  1. the chipset can do it
  *  2. we don't need to worry about how we leave 0xcf8/0xcfc behind
@@ -244,12 +258,10 @@ static void dump_tco_status(u32 tco_sts)
 
 int southbridge_io_trap_handler(int smif)
 {
-       global_nvs_t *gnvs = (global_nvs_t *)0xc00;
-
        switch (smif) {
        case 0x32:
                printk_debug("OS Init\n");
-               //gnvs->smif = 0;
+               gnvs->smif = 0;
                break;
        default:
                /* Not handled */
@@ -278,141 +290,337 @@ void southbridge_smi_set_eos(void)
        outb(reg8, pmbase + SMI_EN);
 }
 
-/**
- * @brief Interrupt handler for SMI#
- *
- * @param smm_revision revision of the smm state save map
- */
 
-void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
 {
        u8 reg8;
-       u16 pmctrl;
-       u16 pm1_sts;
-       u32 smi_sts, gpe0_sts, tco_sts;
+       u32 reg32;
+       u8 slp_typ;
+       /* FIXME: the power state on boot should be read from 
+        * CMOS or even better from GNVS. Right now it's hard
+        * coded at compile time.
+        */
+       u8 s5pwr = MAINBOARD_POWER_ON_AFTER_FAIL;
 
-       pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
-       printk_spew("SMI#: pmbase = 0x%04x\n", pmbase);
+       /* First, disable further SMIs */
+       reg8 = inb(pmbase + SMI_EN);
+       reg8 &= ~SLP_SMI_EN;
+       outb(reg8, pmbase + SMI_EN);
 
-       /* We need to clear the SMI status registers, or we won't see what's
-        * happening in the following calls.
-        */
-       smi_sts = reset_smi_status();
-       dump_smi_status(smi_sts);
+       /* Figure out SLP_TYP */
+       reg32 = inl(pmbase + PM1_CNT);
+       printk_spew("SMI#: SLP = 0x%08x\n", reg32);
+       slp_typ = (reg32 >> 10) & 7;
 
-       if (smi_sts & (1 << 21)) { // MONITOR
-               global_nvs_t *gnvs = (global_nvs_t *)0xc00;
-               int i;
-               u32 reg32;
+       /* Next, do the deed.
+        */
 
-               reg32 = RCBA32(0x1e00); // TRSR - Trap Status Register
+       switch (slp_typ) {
+       case 0: printk_debug("SMI#: Entering S0 (On)\n"); break;
+       case 1: printk_debug("SMI#: Entering S1 (Assert STPCLK#)\n"); break;
+       case 5:
+               printk_debug("SMI#: Entering S3 (Suspend-To-RAM)\n");
+               /* Invalidate the cache before going to S3 */
+               wbinvd();
+               break;
+       case 6: printk_debug("SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
+       case 7:
+               printk_debug("SMI#: Entering S5 (Soft Power off)\n");
 #if 0
-               /* Comment in for some useful debug */
-               for (i=0; i<4; i++) {
-                       if (reg32 & (1 << i)) {
-                               printk_debug("  io trap #%d\n", i);
-                       }
-               }
+               /* Set PME_B0_EN before going to S5 */
+               reg32 = inl(pmbase + GPE0_EN);
+               reg32 |= PME_B0_EN;
+               outl(reg32, pmbase + GPE0_EN);
 #endif
-               RCBA32(0x1e00) = reg32; // TRSR
+               /* Should we keep the power state after a power loss?
+                * In case the setting is "ON" or "OFF" we don't have
+                * to do anything. But if it's "KEEP" we have to switch
+                * to "OFF" before entering S5.
+                */
+               if (s5pwr == MAINBOARD_POWER_KEEP) {
+                       reg8 = pcie_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
+                       reg8 |= 1;
+                       pcie_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
+               }
+               break;
+       default: printk_debug("SMI#: ERROR: SLP_TYP reserved\n"); break;
+       }
 
-               reg32 = RCBA32(0x1e10);
+       /* Write back to the SLP register to cause the originally intended
+        * event again. We need to set BIT13 (SLP_EN) though to make the 
+        * sleep happen.
+        */
+       outl(reg32 | SLP_EN, pmbase + PM1_CNT);
 
-               if ((reg32 & 0xfffc) != 0x808) {
-                       printk_debug("  trapped io address = 0x%x\n", reg32 & 0xfffc);
-                       printk_debug("  AHBE = %x\n", (reg32 >> 16) & 0xf);
-                       printk_debug("  read/write: %s\n", (reg32 & (1 << 24)) ? "read" :
-                               "write");
-               }
+       /* In most sleep states, the code flow of this function ends at
+        * the line above. However, if we entered sleep state S1 and wake
+        * up again, we will continue to execute code in this function.
+        */
+       reg32 = inl(pmbase + PM1_CNT);
+       if (reg32 & SCI_EN) {
+               /* The OS is not an ACPI OS, so we set the state to S0 */
+               reg32 &= ~(SLP_EN | SLP_TYP);
+               outl(reg32, pmbase + PM1_CNT);
+       }
+}
 
-               if (!(reg32 & (1 << 24))) {
-                       /* Write Cycle */
-                       reg32 = RCBA32(0x1e18);
-                       printk_debug("  iotrap written data = 0x%08x\n", reg32);
+static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
+{
+       u32 pmctrl;
+       u8 reg8;
 
-               }
+       /* Emulate B2 register as the FADT / Linux expects it */
 
-               if (gnvs->smif)
-                       io_trap_handler(gnvs->smif); // call function smif
+       reg8 = inb(APM_CNT);
+       switch (reg8) {
+       case CST_CONTROL:
+               /* Calling this function seems to cause
+                * some kind of race condition in Linux
+                * and causes a kernel oops
+                */
+               printk_debug("C-state control\n");
+               break;
+       case PST_CONTROL:
+               /* Calling this function seems to cause
+                * some kind of race condition in Linux
+                * and causes a kernel oops
+                */
+               printk_debug("P-state control\n");
+               break;
+       case ACPI_DISABLE:
+               pmctrl = inl(pmbase + PM1_CNT);
+               pmctrl &= ~SCI_EN;
+               outl(pmctrl, pmbase + PM1_CNT);
+               printk_debug("SMI#: ACPI disabled.\n");
+               break;
+       case ACPI_ENABLE:
+               pmctrl = inl(pmbase + PM1_CNT);
+               pmctrl |= SCI_EN;
+               outl(pmctrl, pmbase + PM1_CNT);
+               printk_debug("SMI#: ACPI enabled.\n");
+               break;
+       case GNVS_UPDATE:
+               gnvs = *(global_nvs_t **)0x500;
+               tcg  = *(void **)0x504;
+               smi1 = *(void **)0x508;
+               printk_debug("SMI#: Setting up structures to %p, %p, %p\n", gnvs, tcg, smi1);
+               break;
+       default:
+               printk_debug("SMI#: Unknown function APM_CNT=%02x\n", reg8);
        }
+}
 
-       if (smi_sts & (1 << 13)) { // TCO
-               tco_sts = reset_tco_status();
-               dump_tco_status(tco_sts);
+static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save)
+{
+       u16 pm1_sts;
 
-               if (tco_sts & (1 << 8)) { // BIOSWR
-                       u8 bios_cntl;
-
-                       bios_cntl = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
-
-                       if (bios_cntl & 1) {
-                               /* BWE is RW, so the SMI was caused by a
-                                * write to BWE, not by a write to the BIOS
-                                */
-
-                               /* This is the place where we notice someone
-                                * is trying to tinker with the BIOS. We are
-                                * trying to be nice and just ignore it. A more
-                                * resolute answer would be to power down the
-                                * box.
-                                */
-                               printk_debug("Switching back to RO\n");
-                               pcie_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
-                       } /* No else for now? */
-               }
+       pm1_sts = reset_pm1_status();
+       dump_pm1_status(pm1_sts);
+}
+
+static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save)
+{
+       u32 gpe0_sts;
+
+       gpe0_sts = reset_gpe0_status();
+       dump_gpe0_status(gpe0_sts);
+}
+
+static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save)
+{
+       u32 reg32;
+
+       reg32 = inl(pmbase + SMI_EN);
+
+       /* Are periodic SMIs enabled? */
+       if ((reg32 & MCSMI_EN) == 0)
+               return;
+
+       printk_debug("Microcontroller SMI.\n");
+}
+
+
+
+static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save)
+{
+       u32 tco_sts;
+
+       tco_sts = reset_tco_status();
+
+       /* Any TCO event? */
+       if (!tco_sts)
+               return;
+
+       if (tco_sts & (1 << 8)) { // BIOSWR
+               u8 bios_cntl;
+
+               bios_cntl = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
+
+               if (bios_cntl & 1) {
+                       /* BWE is RW, so the SMI was caused by a
+                        * write to BWE, not by a write to the BIOS
+                        */
+
+                       /* This is the place where we notice someone
+                        * is trying to tinker with the BIOS. We are
+                        * trying to be nice and just ignore it. A more
+                        * resolute answer would be to power down the
+                        * box.
+                        */
+                       printk_debug("Switching back to RO\n");
+                       pcie_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
+               } /* No else for now? */
+       } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
+               /* Handle TCO timeout */
+               printk_debug("TCO Timeout.\n");
+       } else if (!tco_sts) {
+               dump_tco_status(tco_sts);
        }
+}
+
+static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save)
+{
+       u32 reg32;
+
+       reg32 = inl(pmbase + SMI_EN);
+
+       /* Are periodic SMIs enabled? */
+       if ((reg32 & PERIODIC_EN) == 0)
+               return;
+
+       printk_debug("Periodic SMI.\n");
+}
+
+static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save)
+{
+#define IOTRAP(x) (trap_sts & (1 << x))
+       u32 trap_sts, trap_cycle;
+       u32 data, mask = 0;
+       int i;
 
-       if (smi_sts & (1 << 8)) { // PM1
-               pm1_sts = reset_pm1_status();
-               dump_pm1_status(pm1_sts);
+       trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
+       RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
+
+       trap_cycle = RCBA32(0x1e10);
+       for (i=16; i<20; i++) {
+               if (trap_cycle & (1 << i))
+                       mask |= (0xff << ((i - 16) << 2));
        }
 
-       if (smi_sts & (1 << 9)) { // GPE0
-               gpe0_sts = reset_gpe0_status();
-               dump_gpe0_status(gpe0_sts);
+
+       /* IOTRAP(3) SMI function call */
+       if (IOTRAP(3)) {
+               if (gnvs && gnvs->smif)
+                       io_trap_handler(gnvs->smif); // call function smif
+               return;
        }
 
-       if (smi_sts & (1 << 5)) { // APM
-               /* Emulate B2 register as the FADT / Linux expects it */
-
-               reg8 = inb(0xb2);
-               switch (reg8) {
-               case ACPI_DISABLE:
-                       pmctrl = inw(pmbase + 0x04);
-                       pmctrl |= (1 << 0);
-                       outw(pmctrl, pmbase + 0x04);
-                       printk_debug("SMI#: ACPI disabled.\n");
-                       break;
-               case ACPI_ENABLE:
-                       pmctrl = inw(pmbase + 0x04);
-                       pmctrl &= ~(1 << 0);
-                       outw(pmctrl, pmbase + 0x04);
-                       printk_debug("SMI#: ACPI enabled.\n");
-                       break;
+       /* IOTRAP(2) currently unused
+        * IOTRAP(1) currently unused */
+
+       /* IOTRAP(0) SMIC */
+       if (IOTRAP(0)) {
+               if (!(trap_cycle & (1 << 24))) { // It's a write
+                       printk_debug("SMI1 command\n");
+                       data = RCBA32(0x1e18);
+                       data &= mask;
+                       // if (smi1)
+                       //      southbridge_smi_command(data);
+                       // return;
                }
+               // Fall through to debug
        }
 
-       if (smi_sts & (1 << 4)) { // SLP_SMI
-               u32 reg32;
+       printk_debug("  trapped io address = 0x%x\n", trap_cycle & 0xfffc);
+       for (i=0; i < 4; i++) if(IOTRAP(i)) printk_debug("  TRAPĀ = %d\n", i);
+       printk_debug("  AHBE = %x\n", (trap_cycle >> 16) & 0xf);
+       printk_debug("  MASK = 0x%08x\n", mask);
+       printk_debug("  read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write");
 
-               /* First, disable further SMIs */
-               reg8 = inb(pmbase + SMI_EN);
-               reg8 &= ~SLP_SMI_EN;
-               outb(reg8, pmbase + SMI_EN);
+       if (!(trap_cycle & (1 << 24))) {
+               /* Write Cycle */
+               data = RCBA32(0x1e18);
+               printk_debug("  iotrap written data = 0x%08x\n", data);
+       }
+#undef IOTRAP
+}
 
-               /* Next, do the deed, we should change
-                * power on after power loss bits here
-                * if we're going to S5
-                */
+typedef void (*smi_handler)(unsigned int node, 
+               smm_state_save_area_t *state_save);
+
+smi_handler southbridge_smi[32] = {
+       NULL,                     //  [0] reserved
+       NULL,                     //  [1] reserved
+       NULL,                     //  [2] BIOS_STS
+       NULL,                     //  [3] LEGACY_USB_STS
+       southbridge_smi_sleep,    //  [4] SLP_SMI_STS
+       southbridge_smi_apmc,     //  [5] APM_STS
+       NULL,                     //  [6] SWSMI_TMR_STS
+       NULL,                     //  [7] reserved
+       southbridge_smi_pm1,      //  [8] PM1_STS
+       southbridge_smi_gpe0,     //  [9] GPE0_STS
+       NULL,                     // [10] GPI_STS
+       southbridge_smi_mc,       // [11] MCSMI_STS
+       NULL,                     // [12] DEVMON_STS
+       southbridge_smi_tco,      // [13] TCO_STS
+       southbridge_smi_periodic, // [14] PERIODIC_STS
+       NULL,                     // [15] SERIRQ_SMI_STS
+       NULL,                     // [16] SMBUS_SMI_STS
+       NULL,                     // [17] LEGACY_USB2_STS
+       NULL,                     // [18] INTEL_USB2_STS
+       NULL,                     // [19] reserved
+       NULL,                     // [20] PCI_EXP_SMI_STS
+       southbridge_smi_monitor,  // [21] MONITOR_STS
+       NULL,                     // [22] reserved
+       NULL,                     // [23] reserved
+       NULL,                     // [24] reserved
+       NULL,                     // [25] EL_SMI_STS
+       NULL,                     // [26] SPI_STS
+       NULL,                     // [27] reserved
+       NULL,                     // [28] reserved
+       NULL,                     // [29] reserved
+       NULL,                     // [30] reserved
+       NULL                      // [31] reserved 
+};
 
-               /* Write back to the SLP register to cause the
-                * originally intended event again. We need to set BIT13
-                * (SLP_EN) though to make the sleep happen.
-                */
-               reg32 = inl(pmbase + 0x04);
-               printk_debug("SMI#: SLP = 0x%08x\n", reg32);
-               printk_debug("SMI#: Powering off.\n");
-               outl(reg32 | (1 << 13), pmbase + 0x04);
+/**
+ * @brief Interrupt handler for SMI#
+ *
+ * @param smm_revision revision of the smm state save map
+ */
+
+void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+{
+       int i, dump = 0;
+       u32 smi_sts;
+
+       /* Update global variable pmbase */
+       pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
+
+       /* We need to clear the SMI status registers, or we won't see what's
+        * happening in the following calls.
+        */
+       smi_sts = reset_smi_status();
+       
+       /* Filter all non-enabled SMI events */
+       // FIXME Double check, this clears MONITOR
+       // smi_sts &= inl(pmbase + SMI_EN);
+
+       /* Call SMI sub handler for each of the status bits */
+       for (i = 0; i < 31; i++) {
+               if (smi_sts & (1 << i)) { 
+                       if (southbridge_smi[i])
+                               southbridge_smi[i](node, state_save);
+                       else {
+                               printk_debug("SMI_STS[%d] occured, but no "
+                                               "handler available.\n", i);
+                               dump = 1;
+                       }
+               }
+       }
+
+       if(dump) {
+               dump_smi_status(smi_sts);
        }
 
 }
index be524cabaa6f2bce8fee0fba9db9a8c23c5c3b17..9460a34c2f2db036aad17a8f788dde9aa853f560 100644 (file)
 #define EHCI_BAR               0xFEF00000
 // These could be read from DEBUG_BASE (0:1d.7 R 0x5A 16bit)
 #define EHCI_BAR_INDEX         0x10
+
+#define EHCI_CONFIG_FLAG       0x40
+#define EHCI_PORTSC            0x44
 #define EHCI_DEBUG_OFFSET      0xA0
 
-static void set_debug_port(unsigned port)
+void set_debug_port(unsigned port)
 {
-       // Nothing for now?
+       u32 dbgctl;
+
+       printk_debug("Enabling OWNER_CNT\n");
+       dbgctl = readl(EHCI_BAR + EHCI_DEBUG_OFFSET);
+       dbgctl |= (1 << 30);
+       writel(dbgctl, EHCI_BAR + EHCI_DEBUG_OFFSET);
+
 }
 
 static void i82801gx_enable_usbdebug_direct(unsigned port)
 {
        pci_write_config32(PCI_DEV(0, 0x1d, 7), EHCI_BAR_INDEX, EHCI_BAR);
        pci_write_config8(PCI_DEV(0, 0x1d, 7), 0x04, 0x2); // Memory Space Enable
+       set_debug_port(port);
 }
 
index 39a5799ed9ed47e6466f46fddfddc07879bcbb94..90ef28ae3a30719168a4174fe5f20df7379498e9 100644 (file)
@@ -31,7 +31,7 @@
 static void usb_ehci_init(struct device *dev)
 {
        struct resource *res;
-       u8 *base;
+       u32 base;
        u32 reg32;
        u8 reg8;
 
@@ -52,9 +52,9 @@ static void usb_ehci_init(struct device *dev)
 
        /* Clear any pending port changes */
        res = find_resource(dev, 0x10);
-       base =(u8 *)res->base;
-       reg32 = readl(base + 0x24) | (1 << 2);
-       writel(base + 0x24, reg32);
+       base = res->base;
+       reg32 = readl((u8 *)base + 0x24) | (1 << 2);
+       writel(reg32, (u8 *)base + 0x24);
 
        /* workaround */
        reg8 = pci_read_config8(dev, 0x84);
@@ -115,7 +115,7 @@ static struct pci_operations lops_pci = {
 
 static struct device_operations usb_ehci_ops = {
        .read_resources         = pci_dev_read_resources,
-       .set_resources          = pci_dev_set_resources,
+       .set_resources          = usb_ehci_set_resources,
        .enable_resources       = pci_dev_enable_resources,
        .init                   = usb_ehci_init,
        .scan_bus               = 0,