]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
drivers: usb: fsl: Implement Erratum A-009116 for XHCI controller
authorNikhil Badola <nikhil.badola@freescale.com>
Tue, 23 Jun 2015 03:47:49 +0000 (09:17 +0530)
committerMarek Vasut <marex@denx.de>
Wed, 22 Jul 2015 06:55:45 +0000 (08:55 +0200)
This adjusts (micro)frame length to appropriate value thus
avoiding USB devices to time out over a longer run

Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
drivers/usb/host/xhci-dwc3.c
drivers/usb/host/xhci-fsl.c
include/linux/usb/dwc3.h

index 67147cb6278093c905d0939b5ae6ee5a515b413b..c722c504adaac3a969d61bae6b3426b38eabc26a 100644 (file)
@@ -89,3 +89,9 @@ int dwc3_core_init(struct dwc3 *dwc3_reg)
 
        return 0;
 }
+
+void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
+{
+       setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL |
+                       GFLADJ_30MHZ(val));
+}
index 385422aed657160356791215d25411f99a858627..6781b94851e02b11b0cee02b9af79bb259c48b93 100644 (file)
@@ -58,6 +58,9 @@ static int fsl_xhci_core_init(struct fsl_xhci *fsl_xhci)
        /* We are hard-coding DWC3 core to Host Mode */
        dwc3_set_mode(fsl_xhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
 
+       /* Set GFLADJ_30MHZ as 20h as per XHCI spec default value */
+       dwc3_set_fladj(fsl_xhci->dwc3_reg, GFLADJ_30MHZ_DEFAULT);
+
        return ret;
 }
 
index ba7f31495ff1b00144a849f1583816de11e1ce31..dd934a0e65ede0dadacafbcd3f1296ee8f0f025f 100644 (file)
@@ -109,7 +109,11 @@ struct dwc3 {                                      /* offset: 0xC100 */
 
        u32 g_hwparams8;
 
-       u32 reserved4[63];
+       u32 reserved4[11];
+
+       u32 g_fladj;
+
+       u32 reserved5[51];
 
        u32 d_cfg;
        u32 d_ctl;
@@ -118,15 +122,15 @@ struct dwc3 {                                     /* offset: 0xC100 */
        u32 d_gcmdpar;
        u32 d_gcmd;
 
-       u32 reserved5[2];
+       u32 reserved6[2];
 
        u32 d_alepena;
 
-       u32 reserved6[55];
+       u32 reserved7[55];
 
        struct d_physical_endpoint d_phy_ep_cmd[32];
 
-       u32 reserved7[128];
+       u32 reserved8[128];
 
        u32 o_cfg;
        u32 o_ctl;
@@ -134,7 +138,7 @@ struct dwc3 {                                       /* offset: 0xC100 */
        u32 o_evten;
        u32 o_sts;
 
-       u32 reserved8[3];
+       u32 reserved9[3];
 
        u32 adp_cfg;
        u32 adp_ctl;
@@ -143,7 +147,7 @@ struct dwc3 {                                       /* offset: 0xC100 */
 
        u32 bc_cfg;
 
-       u32 reserved9;
+       u32 reserved10;
 
        u32 bc_evt;
        u32 bc_evten;
@@ -191,10 +195,16 @@ struct dwc3 {                                     /* offset: 0xC100 */
 #define DWC3_DCTL_CSFTRST                      (1 << 30)
 #define DWC3_DCTL_LSFTRST                      (1 << 29)
 
+/* Global Frame Length Adjustment Register */
+#define GFLADJ_30MHZ_REG_SEL                   (1 << 7)
+#define GFLADJ_30MHZ(n)                                ((n) & 0x3f)
+#define GFLADJ_30MHZ_DEFAULT                   0x20
+
 #ifdef CONFIG_USB_XHCI_DWC3
 void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode);
 void dwc3_core_soft_reset(struct dwc3 *dwc3_reg);
 int dwc3_core_init(struct dwc3 *dwc3_reg);
 void usb_phy_reset(struct dwc3 *dwc3_reg);
+void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val);
 #endif
 #endif /* __DWC3_H_ */