Message ID | 20230517081907.3410465-2-xu.yang_2@nxp.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 0ac37fbdad7087bbcbbe246a602c248ccfd954ea |
Headers | show |
Series | [1/3] usb: chipidea: imx: remove one duplicated reg define | expand |
On 23-05-17 16:19:06, Xu Yang wrote: > As we use bvalid for vbus wakeup source, to save power when > suspend, turn off the vbus comparator for imx7d and imx8mm. > > Below is this bit description from RM of iMX8MM > "VBUS Valid Comparator Enable: > > This signal controls the USB OTG PHY VBUS Valid comparator which > indicates whether the voltage on the USB_OTG*_VBUS pin is below > the VBUS Valid threshold. The VBUS Valid threshold is nominally > 4.75V on this USB PHY. The VBUS Valid threshold can be adjusted > using the USBNC_OTGn_PHY_CFG1[OTGTUNE0] bit field. Status of the > VBUS Valid comparator, when it is enabled, is reported on the > USBNC_OTGn_PHY_STATUS[VBUS_VLD] bit. > When OTGDISABLE0 (USBNC_USB_OTGx_PHY_CFG2[10])is set to 1'b0 and > DRVVBUS0 is set to 1'b1, the Bandgap circuitry and VBUS Valid > comparator are powered, even in Suspend or Sleep mode. > DRVVBUS0 should be reset to 1'b0 when the internal VBUS Valid comparator > is not required, to reduce quiescent current in Suspend or Sleep mode. > - 0 The VBUS Valid comparator is disabled > - 1 The VBUS Valid comparator is enabled" > > Signed-off-by: Li Jun <jun.li@nxp.com> > Signed-off-by: Xu Yang <xu.yang_2@nxp.com> > --- > drivers/usb/chipidea/usbmisc_imx.c | 35 ++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c > index be939e77719d..9566022a2183 100644 > --- a/drivers/usb/chipidea/usbmisc_imx.c > +++ b/drivers/usb/chipidea/usbmisc_imx.c > @@ -151,6 +151,7 @@ struct usbmisc_ops { > int (*charger_detection)(struct imx_usbmisc_data *data); > /* It's called when system resume from usb power lost */ > int (*power_lost_check)(struct imx_usbmisc_data *data); > + void (*vbus_comparator_on)(struct imx_usbmisc_data *data, bool on); > }; > > struct imx_usbmisc { > @@ -874,6 +875,33 @@ static int imx7d_charger_detection(struct imx_usbmisc_data *data) > return ret; > } > > +static void usbmisc_imx7d_vbus_comparator_on(struct imx_usbmisc_data *data, > + bool on) > +{ > + unsigned long flags; > + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); > + u32 val; > + > + if (data->hsic) > + return; > + > + spin_lock_irqsave(&usbmisc->lock, flags); > + /* > + * Disable VBUS valid comparator when in suspend mode, > + * when OTG is disabled and DRVVBUS0 is asserted case > + * the Bandgap circuitry and VBUS Valid comparator are > + * still powered, even in Suspend or Sleep mode. > + */ > + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); > + if (on) > + val |= MX7D_USB_OTG_PHY_CFG2_DRVVBUS0; > + else > + val &= ~MX7D_USB_OTG_PHY_CFG2_DRVVBUS0; > + > + writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); > + spin_unlock_irqrestore(&usbmisc->lock, flags); > +} > + > static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) > { > struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); > @@ -1017,6 +1045,7 @@ static const struct usbmisc_ops imx7d_usbmisc_ops = { > .set_wakeup = usbmisc_imx7d_set_wakeup, > .charger_detection = imx7d_charger_detection, > .power_lost_check = usbmisc_imx7d_power_lost_check, > + .vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on, > }; > > static const struct usbmisc_ops imx7ulp_usbmisc_ops = { > @@ -1131,6 +1160,9 @@ int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup) > > usbmisc = dev_get_drvdata(data->dev); > > + if (usbmisc->ops->vbus_comparator_on) > + usbmisc->ops->vbus_comparator_on(data, false); > + > if (wakeup && usbmisc->ops->set_wakeup) > ret = usbmisc->ops->set_wakeup(data, true); > if (ret) { > @@ -1184,6 +1216,9 @@ int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup) > goto hsic_set_clk_fail; > } > > + if (usbmisc->ops->vbus_comparator_on) > + usbmisc->ops->vbus_comparator_on(data, true); > + > return 0; > Acked-by: Peter Chen <peter.chen@kernel.org>
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index be939e77719d..9566022a2183 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -151,6 +151,7 @@ struct usbmisc_ops { int (*charger_detection)(struct imx_usbmisc_data *data); /* It's called when system resume from usb power lost */ int (*power_lost_check)(struct imx_usbmisc_data *data); + void (*vbus_comparator_on)(struct imx_usbmisc_data *data, bool on); }; struct imx_usbmisc { @@ -874,6 +875,33 @@ static int imx7d_charger_detection(struct imx_usbmisc_data *data) return ret; } +static void usbmisc_imx7d_vbus_comparator_on(struct imx_usbmisc_data *data, + bool on) +{ + unsigned long flags; + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + u32 val; + + if (data->hsic) + return; + + spin_lock_irqsave(&usbmisc->lock, flags); + /* + * Disable VBUS valid comparator when in suspend mode, + * when OTG is disabled and DRVVBUS0 is asserted case + * the Bandgap circuitry and VBUS Valid comparator are + * still powered, even in Suspend or Sleep mode. + */ + val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); + if (on) + val |= MX7D_USB_OTG_PHY_CFG2_DRVVBUS0; + else + val &= ~MX7D_USB_OTG_PHY_CFG2_DRVVBUS0; + + writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); + spin_unlock_irqrestore(&usbmisc->lock, flags); +} + static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) { struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); @@ -1017,6 +1045,7 @@ static const struct usbmisc_ops imx7d_usbmisc_ops = { .set_wakeup = usbmisc_imx7d_set_wakeup, .charger_detection = imx7d_charger_detection, .power_lost_check = usbmisc_imx7d_power_lost_check, + .vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on, }; static const struct usbmisc_ops imx7ulp_usbmisc_ops = { @@ -1131,6 +1160,9 @@ int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup) usbmisc = dev_get_drvdata(data->dev); + if (usbmisc->ops->vbus_comparator_on) + usbmisc->ops->vbus_comparator_on(data, false); + if (wakeup && usbmisc->ops->set_wakeup) ret = usbmisc->ops->set_wakeup(data, true); if (ret) { @@ -1184,6 +1216,9 @@ int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup) goto hsic_set_clk_fail; } + if (usbmisc->ops->vbus_comparator_on) + usbmisc->ops->vbus_comparator_on(data, true); + return 0; hsic_set_clk_fail: