summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/southbridge/intel/lynxpoint/acpi/usb.asl37
-rw-r--r--src/southbridge/intel/lynxpoint/pch.h2
-rw-r--r--src/southbridge/intel/lynxpoint/usb_xhci.c11
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 c22dbb80bc..2fe67506b8 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 6e1b10ca86..339636742b 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 f866c4faba..500b57803a 100644
--- a/src/southbridge/intel/lynxpoint/usb_xhci.c
+++ b/src/southbridge/intel/lynxpoint/usb_xhci.c
@@ -61,7 +61,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);
}