From 0457b5dce1860709fcce1407e42ae83023b463cd Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 30 Jan 2014 16:33:33 -0800 Subject: [PATCH] baytrail: Fix XHCI controller reset on resume The toggling of XHCIBAR+80E0h[24] appears to cause the XHCI controller to be reset on resume. This causes the kernel to have to reinitialize the controller and all devices. It seems this bit should only be toggled on boot path, in the resume path it should be left as 0. Additionally after routing ports to XHCI don't issue a port reset to the ports in the resume path. BUG=chrome-os-partner:25428 BRANCH=baytrail TEST=build and boot on rambi, suspend/resume and look for usb errors Change-Id: Ie2f02e4eda502fb670265627ed2968e0d47f3530 Signed-off-by: Duncan Laurie Reviewed-on: https://chromium-review.googlesource.com/184500 Reviewed-by: Aaron Durbin --- src/soc/intel/baytrail/xhci.c | 42 +++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/soc/intel/baytrail/xhci.c b/src/soc/intel/baytrail/xhci.c index b6dc2b2037..661d9918f5 100644 --- a/src/soc/intel/baytrail/xhci.c +++ b/src/soc/intel/baytrail/xhci.c @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include #include @@ -86,10 +87,6 @@ const struct reg_script xhci_init_script[] = { REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x8058, ~0x00000100, 0x00110000), /* BAR + 0x8060[25]=1b */ REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x8060, 0x02000000), - /* BAR + 0x80e0[16,9,6]=001b, toggle bit 24=1 */ - REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x00010200, 0x01000040), - /* BAR + 0x80e0 toggle bit 24=0 */ - REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x01000000, 0), /* BAR + 0x80f0[20]=0b */ REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80f0, ~0x00100000, 0), /* BAR + 0x8008[19]=1b (to enable LPM) */ @@ -110,6 +107,28 @@ const struct reg_script xhci_init_script[] = { REG_SCRIPT_END }; +const struct reg_script xhci_init_boot_script[] = { + /* Setup USB3 phy */ + REG_SCRIPT_NEXT(usb3_phy_script), + /* Initialize host controller */ + REG_SCRIPT_NEXT(xhci_init_script), + /* BAR + 0x80e0[16,9,6]=001b, toggle bit 24=1 */ + REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x00010200, 0x01000040), + /* BAR + 0x80e0 toggle bit 24=0 */ + REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x01000000, 0), + REG_SCRIPT_END +}; + +const struct reg_script xhci_init_resume_script[] = { + /* Setup USB3 phy */ + REG_SCRIPT_NEXT(usb3_phy_script), + /* Initialize host controller */ + REG_SCRIPT_NEXT(xhci_init_script), + /* BAR + 0x80e0[16,9,6]=001b, leave bit 24=0 to prevent HC reset */ + REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x01010200, 0x00000040), + REG_SCRIPT_END +}; + const struct reg_script xhci_clock_gating_script[] = { /* ConfigureXhciClockGating() */ /* D20:F0:40[21:19,18,10:8]=000,1,001 (don't write byte 3) */ @@ -165,6 +184,9 @@ static void xhci_route_all(device_t dev) /* Route ports to XHCI controller */ reg_script_run_on_dev(dev, xhci_route_all_script); + if (acpi_slp_type == 3) + return; + /* Reset enabled USB3 ports */ port_disabled = pci_read_config32(dev, XHCI_USB3PDO); for (port = 0; port < BYTM_USB3_PORT_COUNT; port++) { @@ -178,10 +200,6 @@ static void xhci_init(device_t dev) { struct soc_intel_baytrail_config *config = dev->chip_info; struct reg_script xhci_hc_init[] = { - /* Setup USB3 phy */ - REG_SCRIPT_NEXT(usb3_phy_script), - /* Initialize host controller */ - REG_SCRIPT_NEXT(xhci_init_script), /* Initialize clock gating */ REG_SCRIPT_NEXT(xhci_clock_gating_script), /* Finalize XHCCI1 and XHCCI2 */ @@ -203,7 +221,13 @@ static void xhci_init(device_t dev) REG_SCRIPT_END }; - /* Initialize XHCI controller */ + /* Initialize XHCI controller for boot or resume path */ + if (acpi_slp_type == 3) + reg_script_run_on_dev(dev, xhci_init_resume_script); + else + reg_script_run_on_dev(dev, xhci_init_boot_script); + + /* Finalize Initialization */ reg_script_run_on_dev(dev, xhci_hc_init); /* Route all ports to XHCI if requested */