Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4448
-gerrit
commit 0d1694fd6a1431940f8a1d9dc8b4746babd203e6
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Thu Aug 8 14:12:20 2013 -0700
lynxpoint: XHCI: Don't put device in D3 in _PS0 Method
The end of the _PS0 method that is supposed to transition the
XHCI device to D0 state is instead putting it in D3 state.
This triggers a PME_B0 GPE which causes a Notify to the XHCI
ACPI Device in the kernel and that increments the wakeup counter
and causes aborted suspends.
Instead if we just leave the device in D0 where it should be
after executing this function then the PME_B0 is not generated
and the kernel does not see a wakeup on XHCI.
Similarly I changed the _PS3 method to always put the device in
D3 at the end of the method, rather than depending on the state
to be D3 at the start.
Before this change the kernel would see the following sequence
when trying to suspend when the XHCI controller is in D3cold:
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS0] (Node ffff88017802bf28)
kernel: evmisc-0169 [07] ev_queue_notify_reques: Dispatching Notify on [XHCI] (Device) Value 0x02 (Device Wake) Node ffff88017802bc30
kernel: evmisc-0169 [07] ev_queue_notify_reques: Dispatching Notify on [EHCI] (Device) Value 0x02 (Device Wake) Node ffff88017802b8e8
kernel: evmisc-0169 [07] ev_queue_notify_reques: Dispatching Notify on [HDEF] (Device) Value 0x02 (Device Wake) Node ffff88017802b1b8
kernel: xhci_hcd 0000:00:14.0: power state changed by ACPI to D0
kernel: xhci_hcd 0000:00:14.0: PME# disabled
kernel: xhci_hcd 0000:00:14.0: enabling bus mastering
kernel: xhci_hcd 0000:00:14.0: setting latency timer to 64
kernel: PM: Wakeup pending, aborting suspend
kernel: last active wakeup source: 0000:00:14.0
Now it does not get a notification (due to PME_B0) when going to D0
on the way into suspend. XHCI goes from D3cold to D0 (in order to
be able to read mmio) and then back to D3hot before suspend.
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS0] (Node ffff88017802bf28)
kernel: xhci_hcd 0000:00:14.0: power state changed by ACPI to D0
kernel: xhci_hcd 0000:00:14.0: PME# disabled
kernel: xhci_hcd 0000:00:14.0: enabling bus mastering
kernel: xhci_hcd 0000:00:14.0: setting latency timer to 64
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._S3D] (Node ffff88017802c000)
kernel: xhci_hcd 0000:00:14.0: PME# enabled
kernel: xhci_hcd 0000:00:14.0: System wakeup enabled by ACPI
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS3] (Node ffff88017802bf50)
kernel: xhci_hcd 0000:00:14.0: power state changed by ACPI to D3hot
Change-Id: Id5cd28eede2b27d97640047feb17349ae4ab79b7
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/65236
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/southbridge/intel/lynxpoint/acpi/usb.asl | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/southbridge/intel/lynxpoint/acpi/usb.asl b/src/southbridge/intel/lynxpoint/acpi/usb.asl
index 2fe6750..9c9b6b0 100644
--- a/src/southbridge/intel/lynxpoint/acpi/usb.asl
+++ b/src/southbridge/intel/lynxpoint/acpi/usb.asl
@@ -309,11 +309,6 @@ Device (XHCI)
Store (1, AX15)
}
- // Put device in D3 if it was there originally
- If (LEqual (Local0, 3)) {
- Store (3, ^D0D3)
- }
-
Return ()
}
@@ -371,9 +366,7 @@ Device (XHCI)
}
// Put device in D3
- If (LEqual (Local0, 3)) {
- Store (3, ^D0D3)
- }
+ Store (3, ^D0D3)
Return ()
}
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4473
-gerrit
commit 12845d880eccb0df53cb04c9702de88f9af461e9
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Tue Aug 13 13:32:28 2013 -0700
lynxpoint: Fix an issue clearing port change status bits
The coreboot and ACPI code that clears USB3 PORTSC change status
bits was not properly preserving the state of the PED (port enabled
or disabled) status bit, and it could write 0 back to this field
which would disable the port.
Additionally add back the code that resets disconnected USB3 ports
on the way into suspend (as stated in the BWG) but take care to
clear the PME status bit so we don't immediately wake.
suspend/resume with USB3 devices
1) suspend with no devices, plug in while suspended, then resume
and verify that the devices are detected
2) suspend with USB3 devices inserted, then suspend and resume
and verify that the devices are detected
3) suspend with USB3 devices inserted, then remove the devices
while suspended, resume and ensure they can be detected again
when inserted after resume
Change-Id: Ic7e8d375dfe645cf0dc1f041c3a3d09d0ead1a51
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/65733
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
Commit-Queue: Aaron Durbin <adurbin(a)chromium.org>
---
src/southbridge/intel/lynxpoint/acpi/usb.asl | 37 +++++++++++++++++++---------
src/southbridge/intel/lynxpoint/pch.h | 2 ++
src/southbridge/intel/lynxpoint/usb_xhci.c | 11 ++++++++-
3 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/src/southbridge/intel/lynxpoint/acpi/usb.asl b/src/southbridge/intel/lynxpoint/acpi/usb.asl
index c22dbb8..2fe6750 100644
--- a/src/southbridge/intel/lynxpoint/acpi/usb.asl
+++ b/src/southbridge/intel/lynxpoint/acpi/usb.asl
@@ -106,23 +106,36 @@ Device (XHCI)
Field (XREG, DWordAcc, Lock, Preserve)
{
Offset (0x510), // PORTSCNUSB3[0]
- , 17,
- CLR1, 7, // Status Change bits 23:17
+ PSC0, 32,
Offset (0x520), // PORTSCNUSB3[1]
- , 17,
- CLR2, 7, // Status Change Bits 23:17
+ PSC1, 32,
Offset (0x530), // PORTSCNUSB3[2]
- , 17,
- CLR3, 7, // Status Change Bits 23:17
+ PSC2, 32,
Offset (0x540), // PORTSCNUSB3[3]
- , 17,
- CLR4, 7, // Status Change Bits 23:17
+ PSC3, 32,
}
- Store (0x7f, CLR1)
- Store (0x7f, CLR2)
- Store (0x7f, CLR3)
- Store (0x7f, CLR4)
+ // 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)
diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
index 6e1b10c..3396367 100644
--- a/src/southbridge/intel/lynxpoint/pch.h
+++ b/src/southbridge/intel/lynxpoint/pch.h
@@ -366,6 +366,7 @@ int early_pch_init(const void *gpio_map,
#define PWR_CTL_SET_D0 0x0
#define PWR_CTL_SET_D3 0x3
#define PWR_CTL_ENABLE_PME (1 << 8)
+#define PWR_CTL_STATUS_PME (1 << 15)
/* EHCI Memory Registers */
#define EHCI_USB_CMD 0x20
@@ -397,6 +398,7 @@ int early_pch_init(const void *gpio_map,
#define XHCI_USB3_PORTSC_WOE (1 << 27) /* Wake on Overcurrent */
#define XHCI_USB3_PORTSC_WRC (1 << 19) /* Warm Reset Complete */
#define XHCI_USB3_PORTSC_LWS (1 << 16) /* Link Write Strobe */
+#define XHCI_USB3_PORTSC_PED (1 << 1) /* Port Enabled/Disabled */
#define XHCI_USB3_PORTSC_WPR (1 << 31) /* Warm Port Reset */
#define XHCI_USB3_PORTSC_PLS (0xf << 5) /* Port Link State */
#define XHCI_PLSR_DISABLED (4 << 5) /* Port is disabled */
diff --git a/src/southbridge/intel/lynxpoint/usb_xhci.c b/src/southbridge/intel/lynxpoint/usb_xhci.c
index 1e81065..212dec6 100644
--- a/src/southbridge/intel/lynxpoint/usb_xhci.c
+++ b/src/southbridge/intel/lynxpoint/usb_xhci.c
@@ -63,7 +63,12 @@ static int usb_xhci_port_count_usb3(device_t dev)
static void usb_xhci_reset_status_usb3(u32 mem_base, int port)
{
u32 portsc = mem_base + XHCI_USB3_PORTSC(port);
- write32(portsc, read32(portsc) | XHCI_USB3_PORTSC_CHST);
+ u32 status = read32(portsc);
+ /* Do not set Port Enabled/Disabled field */
+ status &= ~XHCI_USB3_PORTSC_PED;
+ /* Clear all change status bits */
+ status |= XHCI_USB3_PORTSC_CHST;
+ write32(portsc, status);
}
static void usb_xhci_reset_port_usb3(u32 mem_base, int port)
@@ -178,6 +183,9 @@ void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ)
reg32 &= ~((1 << 14) | (1 << 2));
write32(mem_base + 0x816c, reg32);
+ /* Reset disconnected USB3 ports */
+ usb_xhci_reset_usb3(dev, 0);
+
/* Set MMIO 0x80e0[15] */
reg32 = read32(mem_base + 0x80e0);
reg32 |= (1 << 15);
@@ -186,6 +194,7 @@ void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ)
/* Set D3Hot state and enable PME */
pci_or_config16(dev, XHCI_PWR_CTL_STS, PWR_CTL_SET_D3);
+ pci_or_config16(dev, XHCI_PWR_CTL_STS, PWR_CTL_STATUS_PME);
pci_or_config16(dev, XHCI_PWR_CTL_STS, PWR_CTL_ENABLE_PME);
}
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4409
-gerrit
commit ed1eec1a20b1602b0c8cf104eab64860c99b3f6a
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Tue Jul 30 16:15:14 2013 -0700
lynxpoint: XHCI: Advertise D3 as lowest wake state
The recommended value in docs is D2, but lynxpoint XHCI does not even
support D2 state which causes the kernel to think this device cannot
be used as a wake source:
kernel: xhci_hcd 0000:00:14.0: System wakeup enabled by ACPI
kernel: ACPI: Device does not support D2
kernel: xhci_hcd 0000:00:14.0: System wakeup disabled by ACPI
Additionally this means the kernel will never put the device into D3
state by itself. There is SMI code that will put the device into D3
before suspend so advertising D3 here should be correct.
With this change the kernel will put the controller into D3 on suspend
and back to D0 on resume, including executing the ACPI methods
for _PS0/_PS3 that contain chipset specific workarounds.
In addition add a _PSC method to directly return the D state from the
device registers. With ALL USB devices removed the XHCI controller
goes into D3 state and the kernel can have a hard time determining
the state of the device at boot.
A kernel compiled with CONFIG_ACPI_DEBUG=y and module parameters
acpi.debug_layer=0x7f acpi.debug_level=0x2f can be used to see
what ACPI methods are executed:
kernel: xhci_hcd 0000:00:14.0: System wakeup enabled by ACPI
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS3] (Node ffff8801000a7f50)
kernel: ACPI: Preparing to enter system sleep state S3
...
kernel: ACPI: Waking up from system sleep state S3
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS0] (Node ffff8801000a7f28)
kernel: xhci_hcd 0000:00:14.0: power state changed by ACPI to D0
Change-Id: Ic64040eb4dd1947a1e2f0ee253a64be683e0ec70
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
meld with s3d
Change-Id: Ic6789720c4efe661dcb03a4afce8d88115854472
Reviewed-on: https://gerrit.chromium.org/gerrit/63916
Tested-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
Commit-Queue: Duncan Laurie <dlaurie(a)chromium.org>
---
src/southbridge/intel/lynxpoint/acpi/usb.asl | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/southbridge/intel/lynxpoint/acpi/usb.asl b/src/southbridge/intel/lynxpoint/acpi/usb.asl
index 1a0ad34..c22dbb8 100644
--- a/src/southbridge/intel/lynxpoint/acpi/usb.asl
+++ b/src/southbridge/intel/lynxpoint/acpi/usb.asl
@@ -238,6 +238,11 @@ Device (XHCI)
LPCL ()
}
+ Method (_PSC, 0, NotSerialized)
+ {
+ Return (^D0D3)
+ }
+
Method (_PS0, 0, Serialized)
{
If (LEqual (^DVID, 0xFFFF)) {
@@ -375,12 +380,12 @@ Device (XHCI)
Method(_S3D,0) // Highest D State in S3 State
{
- Return (2)
+ Return (3)
}
Method(_S4D,0) // Highest D State in S4 State
{
- Return (2)
+ Return (3)
}
Device (HUB7)
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4407
-gerrit
commit 3674484fff17c8bed24800482590fad436bdcc7f
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Tue Jul 30 16:05:55 2013 -0700
lynxpoint: Route all USB ports to XHCI in finalize step
This commit adds a new Kconfig option for the LynxPoint
southbridge that will have coreboot route all of the USB
ports to the XHCI controller in the finalize step (i.e.
after the bootloader) and disable the EHCI controller(s).
Additionally when doing this the XHCI USB3 ports need
to be put into an expected state on resume in order to make
the kernel state machine happy.
Part of this could also be done in depthcharge but there
are also some resume-time steps required so it makes sense
to keep it all together in coreboot.
This can theoretically save ~100mW at runtime.
Verify that the EHCI controller is not found in Linux and
that booting from USB still works.
Change-Id: I3ddfecc0ab12a4302e6034ea8d13ccd8ea2a655d
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/63802
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/cpu/x86/smm.h | 1 +
src/southbridge/intel/lynxpoint/Kconfig | 7 +++
src/southbridge/intel/lynxpoint/pch.h | 1 +
src/southbridge/intel/lynxpoint/smihandler.c | 7 +++
src/southbridge/intel/lynxpoint/usb_xhci.c | 90 ++++++++++++++++++++++++++++
5 files changed, 106 insertions(+)
diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h
index 607c0f0..feb50ec 100644
--- a/src/include/cpu/x86/smm.h
+++ b/src/include/cpu/x86/smm.h
@@ -372,6 +372,7 @@ typedef struct {
#define APM_CNT_ACPI_ENABLE 0xe1
#define APM_CNT_MBI_UPDATE 0xeb
#define APM_CNT_GNVS_UPDATE 0xea
+#define APM_CNT_FINALIZE 0xcb
#define APM_STS 0xb3
/* SMI handler function prototypes */
diff --git a/src/southbridge/intel/lynxpoint/Kconfig b/src/southbridge/intel/lynxpoint/Kconfig
index 28ebdb6..5ff00db 100644
--- a/src/southbridge/intel/lynxpoint/Kconfig
+++ b/src/southbridge/intel/lynxpoint/Kconfig
@@ -76,4 +76,11 @@ config ME_MBP_CLEAR_LATE
finalize step. This can speed up boot time if the ME takes
a long time to indicate this status.
+config FINALIZE_USB_ROUTE_XHCI
+ bool "Route all ports to XHCI controller in finalize step"
+ default y
+ help
+ If you set this option to y, the USB ports will be routed
+ to the XHCI controller during the finalize SMM callback.
+
endif
diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
index c16c009..6e1b10c 100644
--- a/src/southbridge/intel/lynxpoint/pch.h
+++ b/src/southbridge/intel/lynxpoint/pch.h
@@ -92,6 +92,7 @@ void intel_pch_finalize_smm(void);
void usb_ehci_sleep_prepare(device_t dev, u8 slp_typ);
void usb_ehci_disable(device_t dev);
void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ);
+void usb_xhci_route_all(void);
#endif
diff --git a/src/southbridge/intel/lynxpoint/smihandler.c b/src/southbridge/intel/lynxpoint/smihandler.c
index e920cfe..d1e9bbc 100644
--- a/src/southbridge/intel/lynxpoint/smihandler.c
+++ b/src/southbridge/intel/lynxpoint/smihandler.c
@@ -135,8 +135,10 @@ static void southbridge_smi_sleep(void)
mainboard_smi_sleep(slp_typ-2);
/* USB sleep preparations */
+#if !CONFIG_FINALIZE_USB_ROUTE_XHCI
usb_ehci_sleep_prepare(PCH_EHCI1_DEV, slp_typ);
usb_ehci_sleep_prepare(PCH_EHCI2_DEV, slp_typ);
+#endif
usb_xhci_sleep_prepare(PCH_XHCI_DEV, slp_typ);
#if CONFIG_ELOG_GSMI
@@ -314,6 +316,11 @@ static void southbridge_smi_apmc(void)
printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
}
break;
+ case APM_CNT_FINALIZE:
+#if CONFIG_FINALIZE_USB_ROUTE_XHCI
+ usb_xhci_route_all();
+#endif
+ break;
#if CONFIG_ELOG_GSMI
case ELOG_GSMI_APM_CNT:
southbridge_smi_gsmi();
diff --git a/src/southbridge/intel/lynxpoint/usb_xhci.c b/src/southbridge/intel/lynxpoint/usb_xhci.c
index b699916..e7f7039 100644
--- a/src/southbridge/intel/lynxpoint/usb_xhci.c
+++ b/src/southbridge/intel/lynxpoint/usb_xhci.c
@@ -189,6 +189,47 @@ void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ)
pci_or_config16(dev, XHCI_PWR_CTL_STS, PWR_CTL_ENABLE_PME);
}
+/* Route all ports to XHCI controller */
+void usb_xhci_route_all(void)
+{
+ u32 port_mask, route;
+ u16 reg16;
+
+ /* Skip if EHCI is already disabled */
+ if (RCBA32(FD) & PCH_DISABLE_EHCI1)
+ return;
+
+ /* Set D0 state */
+ reg16 = pci_read_config16(PCH_XHCI_DEV, XHCI_PWR_CTL_STS);
+ reg16 &= ~PWR_CTL_SET_MASK;
+ reg16 |= PWR_CTL_SET_D0;
+ pci_write_config16(PCH_XHCI_DEV, XHCI_PWR_CTL_STS, reg16);
+
+ /* Set USB3 superspeed enable */
+ port_mask = pci_read_config32(PCH_XHCI_DEV, XHCI_USB3PRM);
+ route = pci_read_config32(PCH_XHCI_DEV, XHCI_USB3PR);
+ route &= ~XHCI_USB3PR_SSEN;
+ route |= XHCI_USB3PR_SSEN & port_mask;
+ pci_write_config32(PCH_XHCI_DEV, XHCI_USB3PR, route);
+
+ /* Route USB2 ports to XHCI controller */
+ port_mask = pci_read_config32(PCH_XHCI_DEV, XHCI_USB2PRM);
+ route = pci_read_config32(PCH_XHCI_DEV, XHCI_USB2PR);
+ route &= ~XHCI_USB2PR_HCSEL;
+ route |= XHCI_USB2PR_HCSEL & port_mask;
+ pci_write_config32(PCH_XHCI_DEV, XHCI_USB2PR, route);
+
+ /* Disable EHCI controller */
+ usb_ehci_disable(PCH_EHCI1_DEV);
+
+ /* LynxPoint-H has a second EHCI controller */
+ if (!pch_is_lp())
+ usb_ehci_disable(PCH_EHCI2_DEV);
+
+ /* Reset and clear port change status */
+ usb_xhci_reset_usb3(PCH_XHCI_DEV, 1);
+}
+
#else /* !__SMM__ */
static void usb_xhci_clock_gating(device_t dev)
@@ -237,6 +278,49 @@ static void usb_xhci_clock_gating(device_t dev)
pci_write_config32(dev, 0xa4, reg32);
}
+/* Re-enable ports that are disabled */
+static void usb_xhci_enable_ports_usb3(device_t dev)
+{
+#if CONFIG_FINALIZE_USB_ROUTE_XHCI
+ int port;
+ u32 portsc, status, disabled;
+ u32 mem_base = usb_xhci_mem_base(dev);
+ int port_count = usb_xhci_port_count_usb3(dev);
+
+ if (!mem_base || !port_count)
+ return;
+
+ /* Get port disable override map */
+ disabled = pci_read_config32(dev, XHCI_USB3PDO);
+
+ for (port = 0; port < port_count; port++) {
+ /* Skip overridden ports */
+ if (disabled & (1 << port))
+ continue;
+ portsc = mem_base + XHCI_USB3_PORTSC(port);
+ status = read32(portsc) & XHCI_USB3_PORTSC_PLS;
+
+ switch (status) {
+ case XHCI_PLSR_RXDETECT:
+ /* Clear change status */
+ printk(BIOS_DEBUG, "usb_xhci reset port %d\n", port);
+ usb_xhci_reset_status_usb3(mem_base, port);
+ break;
+ case XHCI_PLSR_DISABLED:
+ default:
+ /* Transition to enabled */
+ printk(BIOS_DEBUG, "usb_xhci enable port %d\n", port);
+ usb_xhci_reset_port_usb3(mem_base, port);
+ status = read32(portsc);
+ status &= ~XHCI_USB3_PORTSC_PLS;
+ status |= XHCI_PLSW_ENABLE | XHCI_USB3_PORTSC_LWS;
+ write32(portsc, status);
+ break;
+ }
+ }
+#endif
+}
+
static void usb_xhci_init(device_t dev)
{
struct resource *bar0 = find_resource(dev, PCI_BASE_ADDRESS_0);
@@ -305,6 +389,12 @@ static void usb_xhci_init(device_t dev)
reg32 &= ~(1 << 23); /* unsupported request */
reg32 |= (1 << 31);
pci_write_config32(dev, 0x40, reg32);
+
+#if CONFIG_HAVE_ACPI_RESUME
+ /* Enable ports that are disabled before returning to OS */
+ if (acpi_slp_type == 3)
+ usb_xhci_enable_ports_usb3(dev);
+#endif
}
static void usb_xhci_set_subsystem(device_t dev, unsigned vendor,
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4448
-gerrit
commit 1a6b8f72c85eda47829777c2665fa220385f7cb4
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Thu Aug 8 14:12:20 2013 -0700
lynxpoint: XHCI: Don't put device in D3 in _PS0 Method
The end of the _PS0 method that is supposed to transition the
XHCI device to D0 state is instead putting it in D3 state.
This triggers a PME_B0 GPE which causes a Notify to the XHCI
ACPI Device in the kernel and that increments the wakeup counter
and causes aborted suspends.
Instead if we just leave the device in D0 where it should be
after executing this function then the PME_B0 is not generated
and the kernel does not see a wakeup on XHCI.
Similarly I changed the _PS3 method to always put the device in
D3 at the end of the method, rather than depending on the state
to be D3 at the start.
Before this change the kernel would see the following sequence
when trying to suspend when the XHCI controller is in D3cold:
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS0] (Node ffff88017802bf28)
kernel: evmisc-0169 [07] ev_queue_notify_reques: Dispatching Notify on [XHCI] (Device) Value 0x02 (Device Wake) Node ffff88017802bc30
kernel: evmisc-0169 [07] ev_queue_notify_reques: Dispatching Notify on [EHCI] (Device) Value 0x02 (Device Wake) Node ffff88017802b8e8
kernel: evmisc-0169 [07] ev_queue_notify_reques: Dispatching Notify on [HDEF] (Device) Value 0x02 (Device Wake) Node ffff88017802b1b8
kernel: xhci_hcd 0000:00:14.0: power state changed by ACPI to D0
kernel: xhci_hcd 0000:00:14.0: PME# disabled
kernel: xhci_hcd 0000:00:14.0: enabling bus mastering
kernel: xhci_hcd 0000:00:14.0: setting latency timer to 64
kernel: PM: Wakeup pending, aborting suspend
kernel: last active wakeup source: 0000:00:14.0
Now it does not get a notification (due to PME_B0) when going to D0
on the way into suspend. XHCI goes from D3cold to D0 (in order to
be able to read mmio) and then back to D3hot before suspend.
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS0] (Node ffff88017802bf28)
kernel: xhci_hcd 0000:00:14.0: power state changed by ACPI to D0
kernel: xhci_hcd 0000:00:14.0: PME# disabled
kernel: xhci_hcd 0000:00:14.0: enabling bus mastering
kernel: xhci_hcd 0000:00:14.0: setting latency timer to 64
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._S3D] (Node ffff88017802c000)
kernel: xhci_hcd 0000:00:14.0: PME# enabled
kernel: xhci_hcd 0000:00:14.0: System wakeup enabled by ACPI
kernel: ACPI: Execute Method [\_SB_.PCI0.XHCI._PS3] (Node ffff88017802bf50)
kernel: xhci_hcd 0000:00:14.0: power state changed by ACPI to D3hot
Change-Id: Id5cd28eede2b27d97640047feb17349ae4ab79b7
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/65236
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/southbridge/intel/lynxpoint/acpi/usb.asl | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/southbridge/intel/lynxpoint/acpi/usb.asl b/src/southbridge/intel/lynxpoint/acpi/usb.asl
index 2fe6750..9c9b6b0 100644
--- a/src/southbridge/intel/lynxpoint/acpi/usb.asl
+++ b/src/southbridge/intel/lynxpoint/acpi/usb.asl
@@ -309,11 +309,6 @@ Device (XHCI)
Store (1, AX15)
}
- // Put device in D3 if it was there originally
- If (LEqual (Local0, 3)) {
- Store (3, ^D0D3)
- }
-
Return ()
}
@@ -371,9 +366,7 @@ Device (XHCI)
}
// Put device in D3
- If (LEqual (Local0, 3)) {
- Store (3, ^D0D3)
- }
+ Store (3, ^D0D3)
Return ()
}