Message ID | 8d5e1a9ea7207845069104f967e0e1ae558c0624.1555672441.git.arturp@synopsys.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | usb: dwc2: Fix and improve power saving modes. | expand |
Hi, On Fri, Apr 19, 2019 at 11:53 AM Artur Petrosyan <Arthur.Petrosyan@synopsys.com> wrote: > > Before changing to connector B exiting from Partial > Power Down is required. > > - Added exiting from Partial Power Down mode when > connector ID status changes to "connId B". > Because if connector ID status changed to B connector > while core was in partial power down mode, HANG would > accrue from a soft reset. > > Signed-off-by: Artur Petrosyan <arturp@synopsys.com> > --- > drivers/usb/dwc2/hcd.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c > index 8367902a47eb..54450fa352cf 100644 > --- a/drivers/usb/dwc2/hcd.c > +++ b/drivers/usb/dwc2/hcd.c > @@ -3348,6 +3348,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) > wf_otg); > u32 count = 0; > u32 gotgctl; > + u32 pcgcctl; > unsigned long flags; > > dev_dbg(hsotg->dev, "%s()\n", __func__); > @@ -3387,6 +3388,23 @@ static void dwc2_conn_id_status_change(struct work_struct *work) > if (count > 250) > dev_err(hsotg->dev, > "Connection id status change timed out\n"); > + > + if (hsotg->params.power_down == > + DWC2_POWER_DOWN_PARAM_PARTIAL && > + hsotg->lx_state == DWC2_L2) { > + pcgcctl = dwc2_readl(hsotg, PCGCTL); > + pcgcctl &= ~PCGCTL_STOPPCLK; > + dwc2_writel(hsotg, pcgcctl, PCGCTL); > + > + pcgcctl = dwc2_readl(hsotg, PCGCTL); > + pcgcctl &= ~PCGCTL_PWRCLMP; > + dwc2_writel(hsotg, pcgcctl, PCGCTL); > + > + pcgcctl = dwc2_readl(hsotg, PCGCTL); > + pcgcctl &= ~PCGCTL_RSTPDWNMODULE; > + dwc2_writel(hsotg, pcgcctl, PCGCTL); You really need to read it over and over? ...and you really can't just write this all at once? ...if this really needs to be separate steps, do you need a delay between them or can they just happen as fast as possible? As far as I can tell from the programming guide I've seen, you: 1. Don't need to read it over and over again. 2. Should delay 10 PHY clock cycles after the writes -Doug
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 8367902a47eb..54450fa352cf 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3348,6 +3348,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) wf_otg); u32 count = 0; u32 gotgctl; + u32 pcgcctl; unsigned long flags; dev_dbg(hsotg->dev, "%s()\n", __func__); @@ -3387,6 +3388,23 @@ static void dwc2_conn_id_status_change(struct work_struct *work) if (count > 250) dev_err(hsotg->dev, "Connection id status change timed out\n"); + + if (hsotg->params.power_down == + DWC2_POWER_DOWN_PARAM_PARTIAL && + hsotg->lx_state == DWC2_L2) { + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_STOPPCLK; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_PWRCLMP; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_RSTPDWNMODULE; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + } + hsotg->op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false); dwc2_enable_global_interrupts(hsotg);
Before changing to connector B exiting from Partial Power Down is required. - Added exiting from Partial Power Down mode when connector ID status changes to "connId B". Because if connector ID status changed to B connector while core was in partial power down mode, HANG would accrue from a soft reset. Signed-off-by: Artur Petrosyan <arturp@synopsys.com> --- drivers/usb/dwc2/hcd.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)