drivers: usb: fsl: Implement Erratum A-009116 for XHCI controller

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>
master
Nikhil Badola 10 years ago committed by Marek Vasut
parent 7e5a32fcf3
commit 667f4dd90f
  1. 6
      drivers/usb/host/xhci-dwc3.c
  2. 3
      drivers/usb/host/xhci-fsl.c
  3. 22
      include/linux/usb/dwc3.h

@ -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));
}

@ -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;
}

@ -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_ */

Loading…
Cancel
Save