usb: chipidea: imx: improve the over current handling
Subsystems (4)
PATCH 1/1 usb: chipidea: imx: improve the over current handling
The current OC (Over Current) handling does not consider the default and bootloader OC setting well, in this commit, we reset OC setting according to dts value:
- If property "disable-over-current" is set, we will disable OC at code; otherwise, we will enable OC.
- Since most of USB power control chips are low active for OC, we keep "over-current-active-high" property unchanging to reduce users effort. If this property is set, we set OC polarity as high explicitly; otherwise, we set it as low explicitly.
Cc stable <[email protected]>
Cc Peter Chen <[email protected]>
Cc Uwe Kleine-König <[email protected]>
Cc Matthew Starr <[email protected]>
Signed-off-by Peter Chen <[email protected]>
--- drivers/usb/chipidea/ci_hdrc_imx.c | 2 +- drivers/usb/chipidea/ci_hdrc_imx.h | 3 ++- drivers/usb/chipidea/usbmisc_imx.c | 27 ++++++++++++++++++++++----- 3 files changed, 25 insertions(+), 7 deletions(-)
Signature · 1 line
2.14.1
drivers/usb/chipidea/ci_hdrc_imx.c +1 -1
@@ -140,7 +140,7 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) data->disable_oc =1 ;if (of_find_property (np,"over-current-active-high" ,NULL )) - data->oc_polarity =1 ; + data->oc_polarity_high =1 ;if (of_find_property (np,"external-vbus-divider" ,NULL )) data->evdo =1 ;
drivers/usb/chipidea/ci_hdrc_imx.h +2 -1
@@ -11,7 +11,8 @@ struct imx_usbmisc_data {int index; unsigned int disable_oc:1; /* over current detect disabled */ - unsigned int oc_polarity:1; /* over current polarity if oc enabled */ +/* over current polarity high if oc enabled */ + unsigned int oc_polarity_high:1; unsigned int evdo:1; /* set external vbus divider option */ unsigned int ulpi:1; /* connected to an ULPI phy */ unsigned int hsic:1; /* HSIC controlller */
drivers/usb/chipidea/usbmisc_imx.c +22 -5
@@ -135,15 +135,26 @@ static int usbmisc_imx25_init(struct imx_usbmisc_data *data) val =readl (usbmisc->base); val &= ~(MX25_OTG_SIC_MASK |MX25_OTG_PP_BIT ); val |= (MX25_EHCI_INTERFACE_DIFF_UNI &MX25_EHCI_INTERFACE_MASK ) <<MX25_OTG_SIC_SHIFT ; - val |= (MX25_OTG_PM_BIT |MX25_OTG_OCPOL_BIT ); + val |=MX25_OTG_PM_BIT ; +if (data->oc_polarity_high) +/* High active */ + val |=MX25_OTG_OCPOL_BIT ; +else + val &= ~MX25_OTG_OCPOL_BIT ; +writel (val, usbmisc->base);break ;case 1 : val =readl (usbmisc->base); val &= ~(MX25_H1_SIC_MASK |MX25_H1_PP_BIT |MX25_H1_IPPUE_UP_BIT ); val |= (MX25_EHCI_INTERFACE_SINGLE_UNI &MX25_EHCI_INTERFACE_MASK ) <<MX25_H1_SIC_SHIFT ; - val |= (MX25_H1_PM_BIT |MX25_H1_OCPOL_BIT |MX25_H1_TLL_BIT | + val |= (MX25_H1_PM_BIT |MX25_H1_TLL_BIT |MX25_H1_USBTE_BIT |MX25_H1_IPPUE_DOWN_BIT ); +if (data->oc_polarity_high) +/* High active */ + val |=MX25_H1_OCPOL_BIT ; +else + val &= ~MX25_H1_OCPOL_BIT ;writel (val, usbmisc->base);
@@ -356,12 +367,14 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) reg =readl (usbmisc->base + data->index *4 );if (data->disable_oc) { reg |=MX6_BM_OVER_CUR_DIS ; - }else if (data->oc_polarity ==1 ) { + }else if (data->oc_polarity_high ==1 ) {/* High active */ reg &= ~(MX6_BM_OVER_CUR_DIS |MX6_BM_OVER_CUR_POLARITY ); }else { - reg &= ~(MX6_BM_OVER_CUR_DIS ); + reg &= ~MX6_BM_OVER_CUR_DIS ; + reg |=MX6_BM_OVER_CUR_POLARITY ; } +writel (reg, usbmisc->base + data->index *4 );/* SoC non-burst setting */
@@ -552,10 +565,14 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) reg =readl (usbmisc->base);if (data->disable_oc) { reg |=MX6_BM_OVER_CUR_DIS ; - }else if (data->oc_polarity ==1 ) { + }else if (data->oc_polarity_high ==1 ) {/* High active */ reg &= ~(MX6_BM_OVER_CUR_DIS |MX6_BM_OVER_CUR_POLARITY ); + }else { + reg &= ~MX6_BM_OVER_CUR_DIS ; + reg |=MX6_BM_OVER_CUR_POLARITY ; } +writel (reg, usbmisc->base); reg =readl (usbmisc->base +MX7D_USBNC_USB_CTRL2 );