diff mbox series

usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC

Message ID 20201023122713.460551-1-Sandeep.Singh@amd.com
State New
Headers show
Series usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC | expand

Commit Message

Sandeep Singh Oct. 23, 2020, 12:27 p.m. UTC
From: Sandeep Singh <sandeep.singh@amd.com>

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.

Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sandeep Singh <sandeep.singh@amd.com>
---
 drivers/usb/host/xhci-pci.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Comments

Greg Kroah-Hartman Oct. 23, 2020, 12:33 p.m. UTC | #1
On Fri, Oct 23, 2020 at 05:57:13PM +0530, Sandeep Singh wrote:
> From: Sandeep Singh <sandeep.singh@amd.com>

> 

> 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.

> 

> Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>

> Signed-off-by: Sandeep Singh <sandeep.singh@amd.com>

> ---

>  drivers/usb/host/xhci-pci.c | 17 +++++++++++++++++

>  1 file changed, 17 insertions(+)

> 

> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c

> index c26c06e5c88c..bf89172c43ca 100644

> --- a/drivers/usb/host/xhci-pci.c

> +++ b/drivers/usb/host/xhci-pci.c

> @@ -23,6 +23,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

> @@ -161,6 +163,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;

>  

> @@ -498,6 +503,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);

> @@ -517,6 +531,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);

> -- 

> 2.25.1

> 


Does this build?  There is no XHCI_DISABLE_SPARSE in the kernel tree at
the moment...

greg k-h
Singh, Sandeep Oct. 23, 2020, 12:40 p.m. UTC | #2
Hi Greg,

On 10/23/2020 6:03 PM, Greg KH wrote:
> [CAUTION: External Email]

>

> On Fri, Oct 23, 2020 at 05:57:13PM +0530, Sandeep Singh wrote:

>> From: Sandeep Singh <sandeep.singh@amd.com>

>>

>> 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.

>>

>> Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>

>> Signed-off-by: Sandeep Singh <sandeep.singh@amd.com>

>> ---

>>   drivers/usb/host/xhci-pci.c | 17 +++++++++++++++++

>>   1 file changed, 17 insertions(+)

>>

>> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c

>> index c26c06e5c88c..bf89172c43ca 100644

>> --- a/drivers/usb/host/xhci-pci.c

>> +++ b/drivers/usb/host/xhci-pci.c

>> @@ -23,6 +23,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

>> @@ -161,6 +163,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;

>>

>> @@ -498,6 +503,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);

>> @@ -517,6 +531,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);

>> --

>> 2.25.1

>>

> Does this build?  There is no XHCI_DISABLE_SPARSE in the kernel tree at

> the moment...


  Sorry i missed adding xhci.h in this patch i will be sending v2 patch.

> greg k-h


Thanks

Sandeep
diff mbox series

Patch

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index c26c06e5c88c..bf89172c43ca 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -23,6 +23,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
@@ -161,6 +163,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;
 
@@ -498,6 +503,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);
@@ -517,6 +531,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);