[U-Boot] [PATCH v3] drivers: usb: xhci-fsl: Implement Erratum A-010151 for FSL USB3 controller
Marek Vasut
marex at denx.de
Wed Sep 14 23:21:38 CEST 2016
On 09/14/2016 07:15 AM, Sriram Dash wrote:
> Currently the controller by default enables the Receive Detect feature in P3
> mode in USB 3.0 PHY. However, USB 3.0 PHY does not reliably support receive
> detection in P3 mode.
> Enabling the USB3 controller to configure USB in P2 mode whenever the Receive
> Detect feature is required.
>
> Signed-off-by: Sriram Dash <sriram.dash at nxp.com>
> Signed-off-by: Rajesh Bhagat <rajesh.bhagat at nxp.com>
> ---
> Changes in v3:
> - Fixing conflicts and repost
Changelog of this verbosity is completely useless.
> Changes in v2:
> - Do Soc ver checking for applying erratum
>
> drivers/usb/common/fsl-errata.c | 26 ++++++++++++++++++++++++++
> drivers/usb/host/xhci-dwc3.c | 5 +++++
> drivers/usb/host/xhci-fsl.c | 8 ++++++++
> include/fsl_usb.h | 1 +
> include/linux/usb/dwc3.h | 2 ++
> 5 files changed, 42 insertions(+)
>
> diff --git a/drivers/usb/common/fsl-errata.c b/drivers/usb/common/fsl-errata.c
> index 183bf2b..f2bffba 100644
> --- a/drivers/usb/common/fsl-errata.c
> +++ b/drivers/usb/common/fsl-errata.c
> @@ -190,4 +190,30 @@ bool has_erratum_a008751(void)
> return false;
> }
>
> +bool has_erratum_a010151(void)
> +{
> + u32 svr = get_svr();
> + u32 soc = SVR_SOC_VER(svr);
> +
> + switch (soc) {
> +#ifdef CONFIG_ARM64
> + case SVR_LS2080A:
> + case SVR_LS2085A:
> + case SVR_LS1046A:
> + case SVR_LS1012A:
> + return IS_SVR_REV(svr, 1, 0);
> + case SVR_LS1043A:
> + return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1);
> +#endif
> +#ifdef CONFIG_LS102XA
> + case SOC_VER_LS1020:
> + case SOC_VER_LS1021:
> + case SOC_VER_LS1022:
> + case SOC_VER_SLS1020:
> + return IS_SVR_REV(svr, 2, 0);
> +#endif
> + }
> + return false;
> +}
> +
> #endif
> diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
> index 33961cd..adbd9b5 100644
> --- a/drivers/usb/host/xhci-dwc3.c
> +++ b/drivers/usb/host/xhci-dwc3.c
> @@ -97,3 +97,8 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
> setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL |
> GFLADJ_30MHZ(val));
> }
> +
> +void dwc3_set_rxdetect_power_mode(struct dwc3 *dwc3_reg, u32 val)
> +{
> + setbits_le32(&dwc3_reg->g_usb3pipectl[0], val);
So what would happen if I wanted to clean some bits instead ?
Why do you even need a dedicated function to write a single register?
> +}
> diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c
> index 0e3e056..9297ced 100644
> --- a/drivers/usb/host/xhci-fsl.c
> +++ b/drivers/usb/host/xhci-fsl.c
> @@ -84,6 +84,14 @@ static int fsl_xhci_core_init(struct fsl_xhci *fsl_xhci)
> /* Change beat burst and outstanding pipelined transfers requests */
> fsl_xhci_set_beat_burst_length(fsl_xhci->dwc3_reg);
>
> + /*
> + * A-010151: USB controller to configure USB in P2 mode
> + * whenever the Receive Detect feature is required
> + */
> + if (has_erratum_a010151())
> + dwc3_set_rxdetect_power_mode(fsl_xhci->dwc3_reg,
> + DWC3_GUSB3PIPECTL_DISRXDETP3);
Can't you parse these errata infos from device tree ?
> return ret;
> }
>
> diff --git a/include/fsl_usb.h b/include/fsl_usb.h
> index fc72fb9..73235b8 100644
> --- a/include/fsl_usb.h
> +++ b/include/fsl_usb.h
> @@ -95,5 +95,6 @@ bool has_erratum_a007792(void);
> bool has_erratum_a005697(void);
> bool has_erratum_a004477(void);
> bool has_erratum_a008751(void);
> +bool has_erratum_a010151(void);
> #endif
> #endif /*_ASM_FSL_USB_H_ */
> diff --git a/include/linux/usb/dwc3.h b/include/linux/usb/dwc3.h
> index 6d1e365..f68cdd2 100644
> --- a/include/linux/usb/dwc3.h
> +++ b/include/linux/usb/dwc3.h
> @@ -184,6 +184,7 @@ struct dwc3 { /* offset: 0xC100 */
>
> /* Global USB3 PIPE Control Register */
> #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31)
> +#define DWC3_GUSB3PIPECTL_DISRXDETP3 (1 << 28)
> #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17)
>
> /* Global TX Fifo Size Register */
> @@ -205,5 +206,6 @@ 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 dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val);
> +void dwc3_set_rxdetect_power_mode(struct dwc3 *dwc3_reg, u32 val);
> #endif
> #endif /* __DWC3_H_ */
>
--
Best regards,
Marek Vasut
More information about the U-Boot
mailing list