From 3bfe3404df32ca226c624be0435c640bf1ebeae7 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Tue, 18 Oct 2016 14:25:25 -0700 Subject: intel/skylake: Add support to enable wake-on-usb attach/detach Three things are required to enable wake-on-usb: 1. 5V to USB ports should be enabled in S3. 2. ASL file needs to have appropriate wake bit set. 3. XHCI controller should have the wake on attach/detach bit set for the corresponding port in PORTSCN register. Only part missing was #3. This CL adds support to allow mainboard to define a bitmap in devicetree corresponding to the ports that it wants to enable wake-on-usb feature. Based on the bitmap, wake on attach/detach bits in PORTSCN would be set by xhci.asl for the appropriate ports. BUG=chrome-os-partner:58734 BRANCH=None TEST=Verified that with port 5 enabled, chell wakes up from S3 on usb attach/detach. Change-Id: I40a22a450e52f74a0ab93ebb8170555d834ebdaf Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/17056 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Aaron Durbin --- src/soc/intel/skylake/acpi.c | 4 +++ src/soc/intel/skylake/acpi/globalnvs.asl | 2 ++ src/soc/intel/skylake/acpi/xhci.asl | 51 ++++++++++++++++++++++++++++++++ src/soc/intel/skylake/chip.h | 6 ++++ src/soc/intel/skylake/include/soc/nvs.h | 4 ++- src/soc/intel/skylake/include/soc/usb.h | 7 +++++ 6 files changed, 73 insertions(+), 1 deletion(-) (limited to 'src/soc/intel') diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index 28a0a6e7b6..d83c74b5a2 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -198,6 +198,10 @@ static void acpi_create_gnvs(global_nvs_t *gnvs) /* Fill in the Wifi Region id */ gnvs->cid1 = wifi_regulatory_domain(); + + /* Set USB2/USB3 wake enable bitmaps. */ + gnvs->u2we = config->usb2_wake_enable_bitmap; + gnvs->u3we = config->usb3_wake_enable_bitmap; } unsigned long acpi_fill_mcfg(unsigned long current) diff --git a/src/soc/intel/skylake/acpi/globalnvs.asl b/src/soc/intel/skylake/acpi/globalnvs.asl index 2bff7d3cf9..ab3c63ca8f 100644 --- a/src/soc/intel/skylake/acpi/globalnvs.asl +++ b/src/soc/intel/skylake/acpi/globalnvs.asl @@ -64,6 +64,8 @@ Field (GNVS, ByteAcc, NoLock, Preserve) NHLA, 64, // 0x31 - NHLT Address NHLL, 32, // 0x39 - NHLT Length CID1, 16, // 0x3d - Wifi Country Identifier + U2WE, 16, // 0x3f - USB2 Wake Enable Bitmap + U3WE, 8, // 0x41 - USB3 Wake Enable Bitmap /* ChromeOS specific */ Offset (0x100), diff --git a/src/soc/intel/skylake/acpi/xhci.asl b/src/soc/intel/skylake/acpi/xhci.asl index 1a1c6e32cb..96f3b6a6e5 100644 --- a/src/soc/intel/skylake/acpi/xhci.asl +++ b/src/soc/intel/skylake/acpi/xhci.asl @@ -15,6 +15,55 @@ * GNU General Public License for more details. */ +/* + * USB Port Wake Enable (UPWE) on usb attach/detach + * Arg0 - Port Number + * Arg1 - Port 1 Status and control offset + * Arg2 - xHCI Memory-mapped address + */ +Method (UPWE, 3, Serialized) +{ + /* Local0 = Arg1 + ((Arg0 - 1) * 0x10) */ + Add (Arg1, Multiply (Subtract (Arg0, 1), 0x10), Local0) + + /* Map ((XMEM << 16) + Local0 in PSCR */ + OperationRegion (PSCR, SystemMemory, + Add (ShiftLeft (Arg2, 16), Local0), 0x10) + Field (PSCR, AnyAcc, NoLock, Preserve) + { + , 25, + UPCE, 1, + UPDE, 1, + } + Store (One, UPCE) + Store (One, UPDE) +} + +/* + * USB Wake Enable Setup (UWES) + * Arg0 - Port enable bitmap + * Arg1 - Port 1 Status and control offset + * Arg2 - xHCI Memory-mapped address + */ +Method (UWES, 3, Serialized) +{ + Store (Arg0, Local0) + + While (One) { + FindSetRightBit (Local0, Local1) + If (LEqual (Local1, Zero)) { + Break + } + UPWE (Local1, Arg1, Arg2) + /* + * Clear the lowest set bit in Local0 since it was + * processed. + * Local0 = Local0 & (Local0 - 1) + */ + And (Local0, Subtract (Local0, 1), Local0) + } +} + /* XHCI Controller 0:14.0 */ Device (XHCI) @@ -26,6 +75,8 @@ Device (XHCI) Method (_DSW, 3) { Store (Arg0, PMEE) + UWES (And (\U2WE, 0x3FF), 0x480, XMEM) + UWES (And (\U3WE, 0x3F), 0x540, XMEM) } Name (_S3D, 3) /* D3 supported in S3 */ diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index 00393b2492..5a4e85bf00 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -395,6 +395,12 @@ struct soc_intel_skylake_config { /* Use custom SD card detect GPIO configuration */ struct acpi_gpio sdcard_cd_gpio; + + /* Wake Enable Bitmap for USB2 ports */ + u16 usb2_wake_enable_bitmap; + + /* Wake Enable Bitmap for USB3 ports */ + u8 usb3_wake_enable_bitmap; }; typedef struct soc_intel_skylake_config config_t; diff --git a/src/soc/intel/skylake/include/soc/nvs.h b/src/soc/intel/skylake/include/soc/nvs.h index f9d5b71880..cb3b2c6ee5 100644 --- a/src/soc/intel/skylake/include/soc/nvs.h +++ b/src/soc/intel/skylake/include/soc/nvs.h @@ -54,7 +54,9 @@ typedef struct { u64 nhla; /* 0x31 - NHLT Address */ u32 nhll; /* 0x39 - NHLT Length */ u16 cid1; /* 0x3d - Wifi Country Identifier */ - u8 unused[193]; + u16 u2we; /* 0x3f - USB2 Wake Enable Bitmap */ + u8 u3we; /* 0x41 - USB3 Wake Enable Bitmap */ + u8 unused[190]; /* ChromeOS specific (0x100 - 0xfff) */ chromeos_acpi_t chromeos; diff --git a/src/soc/intel/skylake/include/soc/usb.h b/src/soc/intel/skylake/include/soc/usb.h index e5b0495f05..a18e79ce66 100644 --- a/src/soc/intel/skylake/include/soc/usb.h +++ b/src/soc/intel/skylake/include/soc/usb.h @@ -169,4 +169,11 @@ struct usb3_port_config { .tx_downscale_amp = 0x00, \ } +/* + * Set bit corresponding to USB port in wake enable bitmap. Bit 0 corresponds + * to Port 1, Bit n corresponds to Port (n+1). This bitmap is later used to + * decide what ports need to set PORTSCN/PORTSCXUSB3 register bits. + */ +#define USB_PORT_WAKE_ENABLE(x) (1 << (x - 1)) + #endif -- cgit v1.2.3