From: Nehal Bakulchandra Shah <nehal-bakulchandra.s...@amd.com>

On some platform of AMD, S3 fails with HCE and SRE errors.To fix this,
sparse controller enable bit has to be disabled.

Signed-off-by: Nehal Bakulchandra Shah <nehal-bakulchandra.s...@amd.com>
---
 drivers/usb/host/xhci-pci.c | 12 ++++++++++++
 drivers/usb/host/xhci.h     |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 3feaafebfe58..865a16e6c1ed 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -160,6 +160,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;
 
@@ -371,6 +374,15 @@ static int xhci_pci_probe(struct pci_dev *dev, const 
struct pci_device_id *id)
        /* USB 2.0 roothub is stored in the PCI device now. */
        hcd = dev_get_drvdata(&dev->dev);
        xhci = hcd_to_xhci(hcd);
+
+       if (xhci->quirks & XHCI_DISABLE_SPARSE) {
+               u32 reg;
+
+               reg = readl(hcd->regs + 0xC12C);
+               reg &=  ~BIT(17);
+               writel(reg, hcd->regs + 0xC12C);
+       }
+
        xhci->shared_hcd = usb_create_shared_hcd(&xhci_pci_hc_driver, &dev->dev,
                                                 pci_name(dev), hcd);
        if (!xhci->shared_hcd) {
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index ea1754f185a2..ea966d70f1ee 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1874,6 +1874,7 @@ struct xhci_hcd {
 #define XHCI_RESET_PLL_ON_DISCONNECT   BIT_ULL(34)
 #define XHCI_SNPS_BROKEN_SUSPEND    BIT_ULL(35)
 #define XHCI_RENESAS_FW_QUIRK  BIT_ULL(36)
+#define XHCI_DISABLE_SPARSE    BIT_ULL(37)
 
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
-- 
2.25.1

Reply via email to