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); }