Skip to content

Commit

Permalink
usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC
Browse files Browse the repository at this point in the history
commit 2a63281 upstream.

On some platform of AMD, S3 fails with HCE and SRE errors. To fix this,
need to disable a bit which is enable in sparse controller.

Cc: stable@vger.kernel.org #v4.19+
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sandeep Singh <sandeep.singh@amd.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20201028203124.375344-3-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Sandeep Singh authored and gregkh committed Nov 5, 2020
1 parent c964d38 commit 2600a13
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
17 changes: 17 additions & 0 deletions drivers/usb/host/xhci-pci.c
Expand Up @@ -21,6 +21,8 @@
#define SSIC_PORT_CFG2_OFFSET 0x30
#define PROG_DONE (1 << 30)
#define SSIC_PORT_UNUSED (1 << 31)
#define SPARSE_DISABLE_BIT 17
#define SPARSE_CNTL_ENABLE 0xC12C

/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
Expand Down Expand Up @@ -149,6 +151,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
(pdev->device == 0x15e0 || pdev->device == 0x15e1))
xhci->quirks |= XHCI_SNPS_BROKEN_SUSPEND;

if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x15e5)
xhci->quirks |= XHCI_DISABLE_SPARSE;

if (pdev->vendor == PCI_VENDOR_ID_AMD)
xhci->quirks |= XHCI_TRUST_TX_LENGTH;

Expand Down Expand Up @@ -467,6 +472,15 @@ static void xhci_pme_quirk(struct usb_hcd *hcd)
readl(reg);
}

static void xhci_sparse_control_quirk(struct usb_hcd *hcd)
{
u32 reg;

reg = readl(hcd->regs + SPARSE_CNTL_ENABLE);
reg &= ~BIT(SPARSE_DISABLE_BIT);
writel(reg, hcd->regs + SPARSE_CNTL_ENABLE);
}

static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
Expand All @@ -486,6 +500,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
if (xhci->quirks & XHCI_SSIC_PORT_UNUSED)
xhci_ssic_port_unused_quirk(hcd, true);

if (xhci->quirks & XHCI_DISABLE_SPARSE)
xhci_sparse_control_quirk(hcd);

ret = xhci_suspend(xhci, do_wakeup);
if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED))
xhci_ssic_port_unused_quirk(hcd, false);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/host/xhci.h
Expand Up @@ -1873,6 +1873,7 @@ struct xhci_hcd {
#define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33)
#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34)
#define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35)
#define XHCI_DISABLE_SPARSE BIT_ULL(38)

unsigned int num_active_eps;
unsigned int limit_active_eps;
Expand Down

0 comments on commit 2600a13

Please sign in to comment.