[PATCH v3] xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc

2018-10-30 Thread Cherian, George
Implement workaround for ThunderX2 Errata-129 (documented in
CN99XX Known Issues" available at Cavium support site).
As per ThunderX2errata-129, USB 2 device may come up as USB 1
if a connection to a USB 1 device is followed by another connection to
a USB 2 device, the link will come up as USB 1 for the USB 2 device.

Resolution: Reset the PHY after the USB 1 device is disconnected.
The PHY reset sequence is done using private registers in XHCI register
space. After the PHY is reset we check for the PLL lock status and retry
the operation if it fails. From our tests, retrying 4 times is sufficient.

Add a new quirk flag XHCI_RESET_PLL_ON_DISCONNECT to invoke the workaround
in handle_xhci_port_status().

Signed-off-by: George Cherian 
---
 drivers/usb/host/xhci-pci.c  |  5 +
 drivers/usb/host/xhci-ring.c | 35 ++-
 drivers/usb/host/xhci.h  |  1 +
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 51dd8e0..334c009 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -231,6 +231,11 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
 
+   if ((pdev->vendor == PCI_VENDOR_ID_BROADCOM ||
+pdev->vendor == PCI_VENDOR_ID_CAVIUM) &&
+pdev->device == 0x9026)
+   xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT;
+
if (xhci->quirks & XHCI_RESET_ON_RESUME)
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"QUIRK: Resetting on resume");
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f0a99aa..b434869 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1517,6 +1517,35 @@ static void handle_device_notification(struct xhci_hcd 
*xhci,
usb_wakeup_notification(udev->parent, udev->portnum);
 }
 
+/*
+ * Quirk hanlder for errata seen on Cavium ThunderX2 processor XHCI
+ * Controller.
+ * As per ThunderX2errata-129 USB 2 device may come up as USB 1
+ * If a connection to a USB 1 device is followed by another connection
+ * to a USB 2 device.
+ *
+ * Reset the PHY after the USB device is disconnected if device speed
+ * is less than HCD_USB3.
+ * Retry the reset sequence max of 4 times checking the PLL lock status.
+ *
+ */
+static void xhci_cavium_reset_phy_quirk(struct xhci_hcd *xhci)
+{
+   struct usb_hcd *hcd = xhci_to_hcd(xhci);
+   u32 pll_lock_check;
+   u32 retry_count = 4;
+
+   do {
+   /* Assert PHY reset */
+   writel(0x6F, hcd->regs + 0x1048);
+   udelay(10);
+   /* De-assert the PHY reset */
+   writel(0x7F, hcd->regs + 0x1048);
+   udelay(200);
+   pll_lock_check = readl(hcd->regs + 0x1070);
+   } while (!(pll_lock_check & 0x1) && --retry_count);
+}
+
 static void handle_port_status(struct xhci_hcd *xhci,
union xhci_trb *event)
 {
@@ -1642,8 +1671,12 @@ static void handle_port_status(struct xhci_hcd *xhci,
goto cleanup;
}
 
-   if (hcd->speed < HCD_USB3)
+   if (hcd->speed < HCD_USB3) {
xhci_test_and_clear_bit(xhci, port, PORT_PLC);
+   if ((xhci->quirks & XHCI_RESET_PLL_ON_DISCONNECT) &&
+   (portsc & PORT_CSC) && !(portsc & PORT_CONNECT))
+   xhci_cavium_reset_phy_quirk(xhci);
+   }
 
 cleanup:
/* Update event ring dequeue pointer before dropping the lock */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6230a57..004b832 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1846,6 +1846,7 @@ struct xhci_hcd {
 #define XHCI_SUSPEND_DELAY BIT_ULL(30)
 #define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31)
 #define XHCI_ZERO_64B_REGS BIT_ULL(32)
+#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(33)
 
unsigned intnum_active_eps;
unsigned intlimit_active_eps;
-- 
1.8.3.1



[PATCH v2] xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc

2018-10-29 Thread Cherian, George
Implement workaround for ThunderX2 Errata-129 (documented in
CN99XX Known Issues" available at Cavium support site).
As per ThunderX2errata-129, USB 2 device may come up as USB 1
if a connection to a USB 1 device is followed by another connection to
a USB 2 device, the link will come up as USB 1 for the USB 2 device.

Resolution: Reset the PHY after the USB 1 device is disconnected.
The PHY reset sequence is done using private registers in XHCI register
space. After the PHY is reset we check for the PLL lock status and retry
the operation if it fails. From our tests, retrying 4 times is sufficient.

Add a new quirk flag XHCI_RESET_PLL_ON_DISCONNECT to invoke the workaround
in handle_xhci_port_status().

Signed-off-by: George Cherian 
---
 drivers/usb/host/xhci-pci.c  |  5 +
 drivers/usb/host/xhci-ring.c | 35 ++-
 drivers/usb/host/xhci.h  |  1 +
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 51dd8e0..334c009 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -231,6 +231,11 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
 
+   if ((pdev->vendor == PCI_VENDOR_ID_BROADCOM ||
+pdev->vendor == PCI_VENDOR_ID_CAVIUM) &&
+pdev->device == 0x9026)
+   xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT;
+
if (xhci->quirks & XHCI_RESET_ON_RESUME)
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"QUIRK: Resetting on resume");
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f0a99aa..342dd5ac 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1517,6 +1517,35 @@ static void handle_device_notification(struct xhci_hcd 
*xhci,
usb_wakeup_notification(udev->parent, udev->portnum);
 }
 
+/*
+ * Quirk hanlder for errata seen on Cavium ThunderX2 processor XHCI
+ * Controller.
+ * As per ThunderX2errata-129 USB 2 device may come up as USB 1
+ * If a connection to a USB 1 device is followed by another connection
+ * to a USB 2 device.
+ *
+ * Reset the PHY after the USB device is disconnected if device speed
+ * is less than HCD_USB3.
+ * Retry the reset sequence max of 4 times checking the PLL lock status.
+ *
+ */
+static void xhci_handle_tx2_wrapper_reset(struct xhci_hcd *xhci)
+{
+   struct usb_hcd *hcd = xhci_to_hcd(xhci);
+   u32 pll_lock_check;
+   u32 retry_count = 4;
+
+   do {
+   /* Assert PHY reset */
+   writel(0x6F, hcd->regs + 0x1048);
+   udelay(10);
+   /* De-assert the PHY reset */
+   writel(0x7F, hcd->regs + 0x1048);
+   udelay(200);
+   pll_lock_check = readl(hcd->regs + 0x1070);
+   } while (!(pll_lock_check & 0x1) && --retry_count);
+}
+
 static void handle_port_status(struct xhci_hcd *xhci,
union xhci_trb *event)
 {
@@ -1642,8 +1671,12 @@ static void handle_port_status(struct xhci_hcd *xhci,
goto cleanup;
}
 
-   if (hcd->speed < HCD_USB3)
+   if (hcd->speed < HCD_USB3) {
xhci_test_and_clear_bit(xhci, port, PORT_PLC);
+   if ((portsc & PORT_CSC) && !(portsc & 0x1) &&
+   (xhci->quirks & XHCI_RESET_PLL_ON_DISCONNECT))
+   xhci_handle_tx2_wrapper_reset(xhci);
+   }
 
 cleanup:
/* Update event ring dequeue pointer before dropping the lock */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6230a57..004b832 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1846,6 +1846,7 @@ struct xhci_hcd {
 #define XHCI_SUSPEND_DELAY BIT_ULL(30)
 #define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31)
 #define XHCI_ZERO_64B_REGS BIT_ULL(32)
+#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(33)
 
unsigned intnum_active_eps;
unsigned intlimit_active_eps;
-- 
1.8.3.1



[PATCH] xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc

2018-10-27 Thread Cherian, George
Implement workaround for ThunderX2 Errata-129 (documented in
CN99XX Known Issues" available at Cavium support site).
As per ThunderX2errata-129, USB-2.0 device may come up as USB-1.0
If a connection to a USB-1.0 device is followed by another connection
to a USB-2.0 device, the link will come up as USB-1.0 for the USB-2.0
device.

Resolution: Reset the PHY after the USB1.0 device is disconnected.
The PHY reset sequence is done using private registers in XHCI register
space. After the PHY is reset we check for the PLL lock status and retry
the operation if it fails. From our tests, retrying 4 times is sufficient.

Add a new quirk flag XHCI_RESET_PLL_ON_DISCONNECT to invoke the workaround
in handle_xhci_port_status().

Signed-off-by: George Cherian 
---
 drivers/usb/host/xhci-pci.c  |  5 +
 drivers/usb/host/xhci-ring.c | 35 ++-
 drivers/usb/host/xhci.h  |  1 +
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 51dd8e0..334c009 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -231,6 +231,11 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
 
+   if ((pdev->vendor == PCI_VENDOR_ID_BROADCOM ||
+pdev->vendor == PCI_VENDOR_ID_CAVIUM) &&
+pdev->device == 0x9026)
+   xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT;
+
if (xhci->quirks & XHCI_RESET_ON_RESUME)
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"QUIRK: Resetting on resume");
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f0a99aa..f342cbd 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1517,6 +1517,35 @@ static void handle_device_notification(struct xhci_hcd 
*xhci,
usb_wakeup_notification(udev->parent, udev->portnum);
 }
 
+/*
+ * Quirk hanlder for errata seen on Cavium ThunderX2 processor XHCI
+ * Controller.
+ * As per ThunderX2errata-129 USB2.0 device may come up as USB1.0
+ * If a connection to a USB1.0 device is followed by another connection
+ * to a USB2.0 device.
+ *
+ * Reset the PHY after the USB device is disconnected if device speed
+ * is less than HCD_USB3.
+ * Retry the reset sequence max of 4 times checking the PLL lock status.
+ *
+ */
+static void xhci_handle_tx2_wrapper_reset(struct xhci_hcd *xhci)
+{
+   struct usb_hcd *hcd = xhci_to_hcd(xhci);
+   u32 pll_lock_check;
+   u32 retry_count = 4;
+
+   do {
+   /* Assert PHY reset */
+   writel(0x6F, hcd->regs + 0x1048);
+   udelay(10);
+   /* De-assert the PHY reset */
+   writel(0x7F, hcd->regs + 0x1048);
+   udelay(200);
+   pll_lock_check = readl(hcd->regs + 0x1070);
+   } while (!(pll_lock_check & 0x1) && --retry_count);
+}
+
 static void handle_port_status(struct xhci_hcd *xhci,
union xhci_trb *event)
 {
@@ -1642,8 +1671,12 @@ static void handle_port_status(struct xhci_hcd *xhci,
goto cleanup;
}
 
-   if (hcd->speed < HCD_USB3)
+   if (hcd->speed < HCD_USB3) {
xhci_test_and_clear_bit(xhci, port, PORT_PLC);
+   if ((portsc & PORT_CSC) && !(portsc & 0x1) &&
+   (xhci->quirks & XHCI_RESET_PLL_ON_DISCONNECT))
+   xhci_handle_tx2_wrapper_reset(xhci);
+   }
 
 cleanup:
/* Update event ring dequeue pointer before dropping the lock */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6230a57..004b832 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1846,6 +1846,7 @@ struct xhci_hcd {
 #define XHCI_SUSPEND_DELAY BIT_ULL(30)
 #define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31)
 #define XHCI_ZERO_64B_REGS BIT_ULL(32)
+#define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(33)
 
unsigned intnum_active_eps;
unsigned intlimit_active_eps;
-- 
1.8.3.1



RE: [PATCH 3/3] usb: dwc3: omap Modify dwc3_omap_readl/writel with offsets

2013-05-28 Thread Cherian, George


> -Original Message-
> From: Balbi, Felipe
> Sent: Tuesday, May 28, 2013 11:02 PM
> To: Cherian, George
> Cc: Balbi, Felipe; linux-usb@vger.kernel.org; linux-o...@vger.kernel.org;
> linux-ker...@vger.kernel.org; gre...@linuxfoundation.org
> Subject: Re: [PATCH 3/3] usb: dwc3: omap Modify dwc3_omap_readl/writel
> with offsets
> 
> Hi,
> 
> On Mon, May 27, 2013 at 01:32:57PM +0530, George Cherian wrote:
> > This patch modifies dwc3_omap_readl/writel calls to accomodate
> > both OMAP5 and AM437x reg maps (It uses the cached register offsets).
> > Also renames OMAP5 IRQ1 as IRQMISC, IRQ1 bits as IRQMISC bits.
> >
> > Signed-off-by: George Cherian 
> 
> can you change this patch a bit so that it adds wrappers around
> dwc3_omap_*() ? The idea is the have the code look like:
> 
> static u32 dwc3_omap_read_utmi_status(struct dwc3_omap *omap)
> {
>   return dwc3_omap_readl(omap->base,
> USBOTGSS_UTMI_OTG_STATUS +
>   omap->utmi_otg_offset);
> }
> 
> (likewise for write and for all other offsets, of course)
> 
> that way, reading/writing to registers which need the offset will be
> less error-prone and th driver will look a little nicer.

Yes , I will do it in next version.
> 
> --
> Balbi
-George
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 1/4] usb: dwc3: gadget: free trb pool only from epnum 2

2013-05-27 Thread Cherian, George


> -Original Message-
> From: Cherian, George
> Sent: Monday, May 27, 2013 2:36 PM
> To: linux-usb@vger.kernel.org; linux-o...@vger.kernel.org; linux-
> ker...@vger.kernel.org
> Cc: Balbi, Felipe; gre...@linuxfoundation.org; Cherian, George
> Subject: [PATCH 1/4] usb: dwc3: gadget: free trb pool only from epnum 2

Please read [PATCH 1/4] as [PATCH 1/1].
> 
> we never allocate a TRB pool for physical endpoints
> 0 and 1 so trying to free it (a invalid TRB pool pointer)
> will lead us in a warning while removing dwc3.ko module.
> 
> In order to fix the situation, all we have to do is skip
> dwc3_free_trb_pool() for physical endpoints 0 and 1 just
> as we while deleting endpoints from the endpoints list.
> 
> Signed-off-by: George Cherian 
> Signed-off-by: Felipe Balbi 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html