summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikhil Badola <nikhil.badola@freescale.com>2015-03-26 03:44:00 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-09-25 07:25:26 (GMT)
commit14265e30867ed963f0550d5aefeb9f2532bdadcf (patch)
tree61cc9e7d61e34f2ae2456d45776149ea9c9a47a3
parent4e01addf7075dfd7d87468d1b99bfa73f4e6c6f2 (diff)
downloadlinux-14265e30867ed963f0550d5aefeb9f2532bdadcf.tar.xz
usb: dwc3: Implement workaround for Erratum A009116
Write fladj register adjusts (micro)frame length to appropriate value thus avoiding USB 2.0 devices to time-out over a longer run Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com> Signed-off-by: yinbo.zhu <yinbo.zhu@nxp.com>
-rw-r--r--drivers/usb/dwc3/core.c11
-rw-r--r--drivers/usb/dwc3/core.h4
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ab12822..89c3808 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1132,6 +1132,7 @@ static int dwc3_probe(struct platform_device *pdev)
int ret;
void __iomem *regs;
+ struct device_node *node = dev->of_node;
void *mem;
mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
@@ -1154,6 +1155,11 @@ static int dwc3_probe(struct platform_device *pdev)
dwc->xhci_resources[0].flags = res->flags;
dwc->xhci_resources[0].name = res->name;
+ if (node) {
+ dwc->configure_gfladj =
+ of_property_read_bool(node, "configure-gfladj");
+ }
+
res->start += DWC3_GLOBALS_REGS_START;
/*
@@ -1265,6 +1271,11 @@ static int dwc3_probe(struct platform_device *pdev)
if (ret < 0)
goto err1;
+ /* Adjust Frame Length */
+ if (dwc->configure_gfladj)
+ dwc3_writel(dwc->regs, DWC3_GFLADJ, GFLADJ_30MHZ_REG_SEL |
+ GFLADJ_30MHZ(GFLADJ_30MHZ_DEFAULT));
+
pm_runtime_forbid(dev);
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b835b69..dced3b8 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -314,6 +314,10 @@
/* Global Frame Length Adjustment Register */
#define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7)
#define DWC3_GFLADJ_30MHZ_MASK 0x3f
+#define GFLADJ_30MHZ_REG_SEL (1 << 7)
+#define GFLADJ_30MHZ(n) ((n) & 0x3f)
+#define GFLADJ_30MHZ_DEFAULT 0x20
+
/* Global User Control Register 2 */
#define DWC3_GUCTL2_RST_ACTBITLATER (1 << 14)