From 14265e30867ed963f0550d5aefeb9f2532bdadcf Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Thu, 26 Mar 2015 09:14:00 +0530 Subject: 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 Signed-off-by: yinbo.zhu 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) -- cgit v0.10.2