skylake: ACPI: Clean up and fix XHCI ACPI Device

- Remove the old workarounds for XHCI from broadwell
- Add PMC device to expose bits needed for XHCI workarounds
- Implement the new workarounds for XHCI, the first will set
a bit in the XHCI MMIO and the second will send a message
to the PMC if a bit is set indicating the workaround is available.
- Clean up the HS/SS port defines and remove unnecessary
methods to determine the port count since we only support SPT-LP.

BUG=chrome-os-partner:44622,chrome-os-partner:44518
BRANCH=none
TEST=build and boot on glados, verify that D0 and D3 can be
made to work (by disabling unused USB and the misbehaving camera)

Change-Id: I535c9d22308c45a3b9bf7e4045c3d01481acc19c
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: a945f8bc2976d57373be2305c5da40a5691f1e88
Original-Change-Id: I7a57051c0a5c4f5408c2d6ff0aecf660100a1aec
Original-Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/295950
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11537
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Duncan Laurie 2015-08-27 17:09:02 -07:00 committed by Patrick Georgi
parent bf31983836
commit e32da955b3
3 changed files with 174 additions and 261 deletions

View File

@ -40,6 +40,9 @@
/* PCR Access */
#include "pcr.asl"
/* PMC 0:1f.2 */
#include "pmc.asl"
/* Serial IO */
#include "serialio.asl"

View File

@ -0,0 +1,45 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2015 Google Inc.
*
* 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.
*/
Device (PMC)
{
Name (_ADR, 0x001f0002)
Name (_DDN, "Power Management Controller")
OperationRegion (PMCP, PCI_Config, 0x00, 0x100)
Field (PMCP, AnyAcc, NoLock, Preserve)
{
Offset (0x48),
, 12,
PWRM, 20, /* PWRMBASE */
}
OperationRegion (PMCM, SystemMemory, ShiftLeft (PWRM, 12), 0x3f)
Field (PMCM, DWordAcc, NoLock, Preserve)
{
Offset (0x1c), /* PCH_PM_STS */
, 24,
PMFS, 1, /* PMC_MSG_FULL_STS */
Offset (0x20),
MPMC, 32, /* MTPMC */
Offset (0x24), /* PCH_PM_STS2 */
, 20,
UWAB, 1, /* USB2 Workaround Available */
}
}

View File

@ -2,7 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2014 Google Inc.
* Copyright (C) 2015 Google Inc.
* Copyright (C) 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
@ -25,297 +25,162 @@ Device (XHCI)
{
Name (_ADR, 0x00140000)
Name (PLSD, 5) /* Port Link State - RxDetect */
Name (PLSP, 7) /* Port Link State - Polling */
Name (_PRW, Package () { GPE0_PME_B0, 3 })
Method (_DSW, 3)
{
Store (Arg0, PMEE)
}
Name (_S3D, 3) /* D3 supported in S3 */
Name (_S4D, 3) /* D3 supported in S4 */
Name (_S0W, 3) /* D3 can wake device in S0 */
Name (_S3W, 3) /* D3 can wake system from S3 */
Name (_S4W, 3) /* D3 can wake system from S4 */
OperationRegion (XPRT, PCI_Config, 0x00, 0x100)
Field (XPRT, AnyAcc, NoLock, Preserve)
{
Offset (0x0),
DVID, 16,
DVID, 16, /* VENDORID */
Offset (0x10),
, 16,
XMEM, 16, /* MEM_BASE */
Offset (0x74),
D0D3, 2,
D0D3, 2, /* POWERSTATE */
, 6,
PMEE, 1, /* PME_EN */
, 6,
PMES, 1, /* PME_STS */
Offset (0xA8),
, 13,
MW13, 1,
MW14, 1,
, 17,
Offset (0xb0),
, 13,
MB13, 1,
MB14, 1,
, 17,
Offset (0xd0),
PR2, 32, /* USB2PR */
PR2M, 32, /* USB2PRM */
PR3, 32, /* USB3PR */
PR3M, 32, /* USB3PRM */
}
Method (USRA,0){
Return(11)
}
Method (SSPA,0){
Return (13)
}
/* Clear status bits */
Method (LPCL, 0, Serialized)
{
OperationRegion (XREG, SystemMemory,
ShiftLeft (^XMEM, 16), 0x600)
Add (ShiftLeft (XMEM, 16), 0x8000), 0x200)
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,
Offset (0x1c4), /* USB2PMCTRL */
, 2,
UPSW, 2, /* U2PSUSPGP */
}
/* 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)
Method (_PSC, 0, Serialized)
{
Return (^D0D3)
}
Method (_PS0, 0, Serialized)
{
If (LEqual (^DVID, 0xFFFF)) {
Return
}
If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
Return
}
/* If device is in D3, set back to D0 */
If (LEqual (^D0D3, 3)) {
Store (Zero, ^D0D3)
Store (^D0D3, Local0)
}
/* Disable USB2 PHY SUS Well Power Gating */
Store (Zero, ^UPSW)
/*
* Apply USB2 PHPY Power Gating workaround if needed.
*/
If (^^PMC.UWAB) {
/* Write to MTPMC to have PMC disable power gating */
Store (1, ^^PMC.MPMC)
/* Wait for PCH_PM_STS.MSG_FULL_STS to be 0 */
Store (10, Local0)
While (^^PMC.PMFS) {
If (LNot (Local0)) {
Break
}
Decrement (Local0)
Sleep (10)
}
}
}
Method (_PS3, 0, Serialized)
{
If (LEqual (^DVID, 0xFFFF)) {
Return
}
If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
Return
}
Name (_PRW, Package(){ 0x6d, 3 })
/* Clear PME Status */
Store (1, ^PMES)
/* Leave USB ports on for to allow Wake from USB */
/* Enable PME */
Store (1, ^PMEE)
Method (_S3D,0) /* Highest D State in S3 State*/
{
Return (3)
/* If device is in D3, set back to D0 */
If (LEqual (^D0D3, 3)) {
Store (Zero, ^D0D3)
Store (^D0D3, Local0)
}
Method (_S4D,0) /* Highest D State in S4 State*/
{
Return (3)
/* Enable USB2 PHY SUS Well Power Gating in D0/D0i2/D0i3/D3 */
Store (3, ^UPSW)
/* Now put device in D3 */
Store (3, ^D0D3)
Store (^D0D3, Local0)
/*
* Apply USB2 PHPY Power Gating workaround if needed.
* This code assumes XDCI is disabled, if it is enabled
* then this must also check if it is in D3 state too.
*/
If (^^PMC.UWAB) {
/* Write to MTPMC to have PMC enable power gating */
Store (3, ^^PMC.MPMC)
/* Wait for PCH_PM_STS.MSG_FULL_STS to be 0 */
Store (10, Local0)
While (^^PMC.PMFS) {
If (LNot (Local0)) {
Break
}
Device (HS01)
{
Name(_ADR, 0x01)
Decrement (Local0)
Sleep (10)
}
Device (HS02)
{
Name(_ADR, 0x02)
}
Device (HS03)
{
Name(_ADR, 0x03)
}
Device (HS04)
{
Name(_ADR, 0x04)
}
Device (HS05)
{
Name(_ADR, 0x05)
}
Device (HS06)
{
Name(_ADR, 0x06)
}
Device (HS07)
{
Name(_ADR, 0x07)
}
Device (HS08)
{
Name(_ADR, 0x08)
}
Device (HS09)
{
Name(_ADR, 0x09)
}
Device (HS10)
{
Name(_ADR, 0x10)
}
Device (USR1)
{
Method(_ADR) { Return (Add(USRA(),0)) }
}
Device (USR2)
{
Method(_ADR) { Return (Add(USRA(),1)) }
}
Device (SS01)
{
Method(_ADR) { Return (Add(SSPA(),0)) }
}
Device (SS02)
{
Method(_ADR) { Return (Add(SSPA(),1)) }
}
Device (SS03)
{
Method(_ADR) { Return (Add(SSPA(),2)) }
}
Device (SS04)
{
Method(_ADR) { Return (Add(SSPA(),3)) }
}
Device (SS05)
{
Method(_ADR) { Return (Add(SSPA(),4)) }
}
Device (SS06)
{
Method(_ADR) { Return (Add(SSPA(),5)) }
}
}
/* Root Hub for Skylake-LP PCH */
Device (RHUB)
{
Name (_ADR, Zero)
/* USB2 */
Device (HS01) { Name (_ADR, 1) }
Device (HS02) { Name (_ADR, 2) }
Device (HS03) { Name (_ADR, 3) }
Device (HS04) { Name (_ADR, 4) }
Device (HS05) { Name (_ADR, 5) }
Device (HS06) { Name (_ADR, 6) }
Device (HS07) { Name (_ADR, 7) }
Device (HS08) { Name (_ADR, 8) }
Device (HS09) { Name (_ADR, 9) }
Device (HS10) { Name (_ADR, 10) }
/* USBr */
Device (USR1) { Name (_ADR, 11) }
Device (USR2) { Name (_ADR, 12) }
/* USB3 */
Device (SS01) { Name (_ADR, 13) }
Device (SS02) { Name (_ADR, 14) }
Device (SS03) { Name (_ADR, 15) }
Device (SS04) { Name (_ADR, 16) }
Device (SS05) { Name (_ADR, 17) }
Device (SS06) { Name (_ADR, 18) }
}
}