| /* |
| * 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 Cougar Point USB support */ |
| |
| // EHCI Controller 0:1d.0 |
| |
| Device (EHCI) |
| { |
| Name(_ADR, 0x001d0000) |
| |
| Name (PRWH, Package(){ 0x0d, 3 }) // LPT-H |
| Name (PRWL, Package(){ 0x6d, 3 }) // LPT-LP |
| |
| Method (_PRW, 0) { // Power Resources for Wake |
| If (\ISLP ()) { |
| Return (PRWL) |
| } Else { |
| Return (PRWH) |
| } |
| } |
| |
| // Leave USB ports on for to allow Wake from USB |
| |
| Method(_S3D,0) // Highest D State in S3 State |
| { |
| Return (2) |
| } |
| |
| Method(_S4D,0) // Highest D State in S4 State |
| { |
| Return (2) |
| } |
| |
| Device (HUB7) |
| { |
| Name (_ADR, 0x00000000) |
| |
| // How many are there? |
| Device (PRT1) { Name (_ADR, 1) } // USB Port 0 |
| Device (PRT2) { Name (_ADR, 2) } // USB Port 1 |
| Device (PRT3) { Name (_ADR, 3) } // USB Port 2 |
| Device (PRT4) { Name (_ADR, 4) } // USB Port 3 |
| Device (PRT5) { Name (_ADR, 5) } // USB Port 4 |
| Device (PRT6) { Name (_ADR, 6) } // USB Port 5 |
| } |
| } |
| |
| // XHCI Controller 0:14.0 |
| |
| Device (XHCI) |
| { |
| Name (_ADR, 0x00140000) |
| |
| Name (PLSD, 5) // Port Link State - RxDetect |
| Name (PLSP, 7) // Port Link State - Polling |
| |
| OperationRegion (XPRT, PCI_Config, 0x00, 0x100) |
| Field (XPRT, AnyAcc, NoLock, Preserve) |
| { |
| Offset (0x0), |
| DVID, 16, |
| Offset (0x10), |
| , 16, |
| XMEM, 16, // MEM_BASE |
| Offset (0x74), |
| D0D3, 2, |
| , 6, |
| PMEE, 1, // PME_EN |
| , 6, |
| PMES, 1, // PME_STS |
| Offset (0xb0), |
| , 13, |
| MB13, 1, |
| MB14, 1, |
| Offset (0xd0), |
| PR2R, 32, // USB2PR |
| PR2M, 32, // USB2PRM |
| PR3R, 32, // USB3PR |
| PR3M, 32, // USB3PRM |
| } |
| |
| // Clear status bits |
| Method (LPCL, 0, Serialized) |
| { |
| OperationRegion (XREG, SystemMemory, |
| ShiftLeft (^XMEM, 16), 0x600) |
| Field (XREG, DWordAcc, Lock, Preserve) |
| { |
| Offset (0x510), // PORTSCNUSB3[0] |
| PSC0, 32, |
| Offset (0x520), // PORTSCNUSB3[1] |
| PSC1, 32, |
| Offset (0x530), // PORTSCNUSB3[2] |
| PSC2, 32, |
| Offset (0x540), // PORTSCNUSB3[3] |
| PSC3, 32, |
| } |
| |
| // Port Enabled/Disabled (Bit 1) |
| Name (PEDB, ShiftLeft (1, 1)) |
| |
| // Change Status (Bits 23:17) |
| Name (CHST, ShiftLeft (0x7f, 17)) |
| |
| // Port 0 |
| And (PSC0, Not (PEDB), Local0) |
| Or (Local0, CHST, PSC0) |
| |
| // Port 1 |
| And (PSC1, Not (PEDB), Local0) |
| Or (Local0, CHST, PSC1) |
| |
| // Port 2 |
| And (PSC2, Not (PEDB), Local0) |
| Or (Local0, CHST, PSC2) |
| |
| // Port 3 |
| And (PSC3, Not (PEDB), Local0) |
| Or (Local0, CHST, PSC3) |
| } |
| |
| Method (LPS0, 0, Serialized) |
| { |
| OperationRegion (XREG, SystemMemory, |
| ShiftLeft (^XMEM, 16), 0x600) |
| Field (XREG, DWordAcc, Lock, Preserve) |
| { |
| Offset (0x510), // PORTSCNUSB3 |
| , 5, |
| PLS1, 4, // [8:5] Port Link State |
| PPR1, 1, // [9] Port Power |
| , 7, |
| CSC1, 1, // [17] Connect Status Change |
| , 1, |
| WRC1, 1, // [19] Warm Port Reset Change |
| , 11, |
| WPR1, 1, // [31] Warm Port Reset |
| Offset (0x520), // PORTSCNUSB3 |
| , 5, |
| PLS2, 4, // [8:5] Port Link State |
| PPR2, 1, // [9] Port Power |
| , 7, |
| CSC2, 1, // [17] Connect Status Change |
| , 1, |
| WRC2, 1, // [19] Warm Port Reset Change |
| , 11, |
| WPR2, 1, // [31] Warm Port Reset |
| Offset (0x530), // PORTSCNUSB3 |
| , 5, |
| PLS3, 4, // [8:5] Port Link State |
| PPR3, 1, // [9] Port Power |
| , 7, |
| CSC3, 1, // [17] Connect Status Change |
| , 1, |
| WRC3, 1, // [19] Warm Port Reset Change |
| , 11, |
| WPR3, 1, // [31] Warm Port Reset |
| Offset (0x540), // PORTSCNUSB3 |
| , 5, |
| PLS4, 4, // [8:5] Port Link State |
| PPR4, 1, // [9] Port Power |
| , 7, |
| CSC4, 1, // [17] Connect Status Change |
| , 1, |
| WRC4, 1, // [19] Warm Port Reset Change |
| , 11, |
| WPR4, 1, // [31] Warm Port Reset |
| } |
| |
| // Wait for all powered ports to finish polling |
| Store (10, Local0) |
| While (LOr (LOr (LAnd (LEqual (PPR1, 1), LEqual (PLS1, PLSP)), |
| LAnd (LEqual (PPR2, 1), LEqual (PLS2, PLSP))), |
| LOr (LAnd (LEqual (PPR3, 1), LEqual (PLS3, PLSP)), |
| LAnd (LEqual (PPR4, 1), LEqual (PLS4, PLSP))))) |
| { |
| If (LEqual (Local0, 0)) { |
| Break |
| } |
| Decrement (Local0) |
| Stall (10) |
| } |
| |
| // For each USB3 Port: |
| // If port is disconnected (PLS=5 PP=1 CSC=0) |
| // 1) Issue warm reset (WPR=1) |
| // 2) Poll for warm reset complete (WRC=0) |
| // 3) Write 1 to port status to clear |
| |
| // Local# indicate if port is reset |
| Store (0, Local1) |
| Store (0, Local2) |
| Store (0, Local3) |
| Store (0, Local4) |
| |
| If (LAnd (LEqual (PLS1, PLSD), |
| LAnd (LEqual (CSC1, 0), LEqual (PPR1, 1)))) { |
| Store (1, WPR1) // Issue warm reset |
| Store (1, Local1) |
| } |
| If (LAnd (LEqual (PLS2, PLSD), |
| LAnd (LEqual (CSC2, 0), LEqual (PPR2, 1)))) { |
| Store (1, WPR2) // Issue warm reset |
| Store (1, Local2) |
| } |
| If (LAnd (LEqual (PLS3, PLSD), |
| LAnd (LEqual (CSC3, 0), LEqual (PPR3, 1)))) { |
| Store (1, WPR3) // Issue warm reset |
| Store (1, Local3) |
| } |
| If (LAnd (LEqual (PLS4, PLSD), |
| LAnd (LEqual (CSC4, 0), LEqual (PPR4, 1)))) { |
| Store (1, WPR4) // Issue warm reset |
| Store (1, Local4) |
| } |
| |
| // Poll for warm reset complete on all ports that were reset |
| Store (10, Local0) |
| While (LOr (LOr (LAnd (LEqual (Local1, 1), LEqual (WRC1, 0)), |
| LAnd (LEqual (Local2, 1), LEqual (WRC2, 0))), |
| LOr (LAnd (LEqual (Local3, 1), LEqual (WRC3, 0)), |
| LAnd (LEqual (Local4, 1), LEqual (WRC4, 0))))) |
| { |
| If (LEqual (Local0, 0)) { |
| Break |
| } |
| Decrement (Local0) |
| Stall (10) |
| } |
| |
| // Clear status bits in all ports |
| LPCL () |
| } |
| |
| Method (_PSC, 0, NotSerialized) |
| { |
| Return (^D0D3) |
| } |
| |
| Method (_PS0, 0, Serialized) |
| { |
| If (LEqual (^DVID, 0xFFFF)) { |
| Return () |
| } |
| If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) { |
| Return () |
| } |
| |
| OperationRegion (XREG, SystemMemory, |
| Add (ShiftLeft (^XMEM, 16), 0x8000), 0x200) |
| Field (XREG, DWordAcc, Lock, Preserve) |
| { |
| Offset (0x0e0), // AUX Reset Control 1 |
| , 15, |
| AX15, 1, |
| Offset (0x154), // AUX Domain PM Control Register 2 |
| , 31, |
| CLK2, 1, |
| Offset (0x16c), // AUX Clock Control |
| , 2, |
| CLK0, 1, |
| , 11, |
| CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable |
| } |
| |
| // If device is in D3, set back to D0 |
| Store (^D0D3, Local0) |
| if (LEqual (Local0, 3)) { |
| Store (0, ^D0D3) |
| } |
| |
| If (\ISLP ()) { |
| // Clear PCI 0xB0[14:13] |
| Store (0, ^MB13) |
| Store (0, ^MB14) |
| |
| // Clear MMIO 0x816C[14,2] |
| Store (0, CLK0) |
| Store (0, CLK1) |
| } |
| |
| // Set MMIO 0x8154[31] |
| Store (1, CLK2) |
| |
| If (\ISLP ()) { |
| // Handle per-port reset if needed |
| LPS0 () |
| |
| // Set MMIO 0x80e0[15] |
| Store (1, AX15) |
| } |
| |
| Return () |
| } |
| |
| Method (_PS3, 0, Serialized) |
| { |
| If (LEqual (^DVID, 0xFFFF)) { |
| Return () |
| } |
| If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) { |
| Return () |
| } |
| |
| OperationRegion (XREG, SystemMemory, |
| Add (ShiftLeft (^XMEM, 16), 0x8000), 0x200) |
| Field (XREG, DWordAcc, Lock, Preserve) |
| { |
| Offset (0x0e0), // AUX Reset Control 1 |
| , 15, |
| AX15, 1, |
| Offset (0x154), // AUX Domain PM Control Register 2 |
| , 31, |
| CLK2, 1, |
| Offset (0x16c), // AUX Clock Control |
| , 2, |
| CLK0, 1, |
| , 11, |
| CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable |
| } |
| |
| Store (1, ^PMES) // Clear PME Status |
| Store (1, ^PMEE) // Enable PME |
| |
| // If device is in D3, set back to D0 |
| Store (^D0D3, Local0) |
| if (LEqual (Local0, 3)) { |
| Store (0, ^D0D3) |
| } |
| |
| If (\ISLP ()) { |
| // Set PCI 0xB0[14:13] |
| Store (1, ^MB13) |
| Store (1, ^MB14) |
| |
| // Set MMIO 0x816C[14,2] |
| Store (1, CLK0) |
| Store (1, CLK1) |
| } |
| |
| // Clear MMIO 0x8154[31] |
| Store (0, CLK2) |
| |
| If (\ISLP ()) { |
| // Clear MMIO 0x80e0[15] |
| Store (0, AX15) |
| } |
| |
| // Put device in D3 |
| Store (3, ^D0D3) |
| |
| Return () |
| } |
| |
| Name (PRWH, Package(){ 0x0d, 3 }) // LPT-H |
| Name (PRWL, Package(){ 0x6d, 3 }) // LPT-LP |
| |
| Method (_PRW, 0) { // Power Resources for Wake |
| If (\ISLP ()) { |
| Return (PRWL) |
| } Else { |
| Return (PRWH) |
| } |
| } |
| |
| // Leave USB ports on for to allow Wake from USB |
| |
| Method(_S3D,0) // Highest D State in S3 State |
| { |
| Return (3) |
| } |
| |
| Method(_S4D,0) // Highest D State in S4 State |
| { |
| Return (3) |
| } |
| |
| Device (HUB7) |
| { |
| Name (_ADR, 0x00000000) |
| |
| // How many are there? |
| Device (PRT1) { Name (_ADR, 1) } // USB Port 0 |
| Device (PRT2) { Name (_ADR, 2) } // USB Port 1 |
| Device (PRT3) { Name (_ADR, 3) } // USB Port 2 |
| Device (PRT4) { Name (_ADR, 4) } // USB Port 3 |
| Device (PRT5) { Name (_ADR, 5) } // USB Port 4 |
| Device (PRT6) { Name (_ADR, 6) } // USB Port 5 |
| } |
| } |
| |