blob: 9c9b6b0b65bff35c416da59674838bc70453b13c [file] [log] [blame]
/*
* 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
}
}