Message ID | 20190218112310.17860-5-chenyu56@huawei.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add support for usb on Hikey960 | expand |
On Mon, Feb 18, 2019 at 1:23 PM Yu Chen <chenyu56@huawei.com> wrote: > > There are tow quirks for DesignWare USB3 DRD Core of Hisilicon Kirin Soc. > 1)SPLIT_BOUNDARY_DISABLE should be set for Host mode > 2)A GCTL soft reset should be executed when switch mode Thus, it must be two patches, no? > +static void dwc3_gctl_core_soft_reset(struct dwc3 *dwc) > +{ > + u32 reg; > + > + reg = dwc3_readl(dwc->regs, DWC3_GCTL); > + reg |= (DWC3_GCTL_CORESOFTRESET); Redundant parens. > + dwc3_writel(dwc->regs, DWC3_GCTL, reg); > + > + reg = dwc3_readl(dwc->regs, DWC3_GCTL); > + reg &= ~(DWC3_GCTL_CORESOFTRESET); Ditto. > + dwc3_writel(dwc->regs, DWC3_GCTL, reg); > +} > +static void dwc3_complete(struct device *dev) > +{ > + struct dwc3 *dwc = dev_get_drvdata(dev); > + u32 reg; Indentation style is different to the other functions in the same patch. Use simple space here. > + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && > + dwc->dis_split_quirk) { > + dev_dbg(dwc->dev, "set DWC3_GUCTL3_SPLITDISABLE\n"); > + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); > + reg |= DWC3_GUCTL3_SPLITDISABLE; > + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); > + } > +} > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -269,7 +269,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, > { > const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; > struct dwc3 *dwc = dep->dwc; > - u32 timeout = 1000; > + u32 timeout = 5000; I don't see anything about this change in commit message. Moreoever, it looks like it must be a separate logical change with its own description. > u32 saved_config = 0; > u32 reg;
Hi, On 2019/2/18 20:21, Andy Shevchenko wrote: > On Mon, Feb 18, 2019 at 1:23 PM Yu Chen <chenyu56@huawei.com> wrote: >> >> There are tow quirks for DesignWare USB3 DRD Core of Hisilicon Kirin Soc. >> 1)SPLIT_BOUNDARY_DISABLE should be set for Host mode >> 2)A GCTL soft reset should be executed when switch mode > > Thus, it must be two patches, no? > >> +static void dwc3_gctl_core_soft_reset(struct dwc3 *dwc) >> +{ >> + u32 reg; >> + >> + reg = dwc3_readl(dwc->regs, DWC3_GCTL); > >> + reg |= (DWC3_GCTL_CORESOFTRESET); > > Redundant parens. > >> + dwc3_writel(dwc->regs, DWC3_GCTL, reg); >> + >> + reg = dwc3_readl(dwc->regs, DWC3_GCTL); > >> + reg &= ~(DWC3_GCTL_CORESOFTRESET); > > Ditto. > >> + dwc3_writel(dwc->regs, DWC3_GCTL, reg); >> +} > >> +static void dwc3_complete(struct device *dev) >> +{ > >> + struct dwc3 *dwc = dev_get_drvdata(dev); >> + u32 reg; > > Indentation style is different to the other functions in the same patch. > Use simple space here. > >> + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && >> + dwc->dis_split_quirk) { >> + dev_dbg(dwc->dev, "set DWC3_GUCTL3_SPLITDISABLE\n"); >> + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); >> + reg |= DWC3_GUCTL3_SPLITDISABLE; >> + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); >> + } >> +} > >> --- a/drivers/usb/dwc3/gadget.c >> +++ b/drivers/usb/dwc3/gadget.c >> @@ -269,7 +269,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, >> { >> const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; >> struct dwc3 *dwc = dep->dwc; > >> - u32 timeout = 1000; >> + u32 timeout = 5000; > > I don't see anything about this change in commit message. Moreoever, > it looks like it must be a separate logical change with its own > description. > >> u32 saved_config = 0; >> u32 reg; > > I will separate these changes into different patches. Thanks!
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index a1b126f90261..017b0527f6ab 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -112,11 +112,25 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) dwc->current_dr_role = mode; } +static void dwc3_gctl_core_soft_reset(struct dwc3 *dwc) +{ + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg |= (DWC3_GCTL_CORESOFTRESET); + dwc3_writel(dwc->regs, DWC3_GCTL, reg); + + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg &= ~(DWC3_GCTL_CORESOFTRESET); + dwc3_writel(dwc->regs, DWC3_GCTL, reg); +} + static void __dwc3_set_mode(struct work_struct *work) { struct dwc3 *dwc = work_to_dwc(work); unsigned long flags; int ret; + u32 reg; if (dwc->dr_mode != USB_DR_MODE_OTG) return; @@ -156,6 +170,10 @@ static void __dwc3_set_mode(struct work_struct *work) dwc3_set_prtcap(dwc, dwc->desired_dr_role); + /* Execute a GCTL Core Soft Reset when switch mode */ + if (dwc->gctl_reset_quirk) + dwc3_gctl_core_soft_reset(dwc); + spin_unlock_irqrestore(&dwc->lock, flags); switch (dwc->desired_dr_role) { @@ -169,6 +187,11 @@ static void __dwc3_set_mode(struct work_struct *work) phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); phy_calibrate(dwc->usb2_generic_phy); + if (dwc->dis_split_quirk) { + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); + reg |= DWC3_GUCTL3_SPLITDISABLE; + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); + } } break; case DWC3_GCTL_PRTCAP_DEVICE: @@ -1306,6 +1329,11 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->dis_metastability_quirk = device_property_read_bool(dev, "snps,dis_metastability_quirk"); + dwc->dis_split_quirk = device_property_read_bool(dev, + "snps,dis-split-quirk"); + dwc->gctl_reset_quirk = device_property_read_bool(dev, + "snps,gctl-reset-quirk"); + dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; @@ -1825,10 +1853,25 @@ static int dwc3_resume(struct device *dev) return 0; } + +static void dwc3_complete(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + u32 reg; + + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && + dwc->dis_split_quirk) { + dev_dbg(dwc->dev, "set DWC3_GUCTL3_SPLITDISABLE\n"); + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); + reg |= DWC3_GUCTL3_SPLITDISABLE; + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); + } +} #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops dwc3_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) + .complete = dwc3_complete, SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, dwc3_runtime_idle) }; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index df876418cb78..402b3c29eb26 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -136,6 +136,7 @@ #define DWC3_GEVNTCOUNT(n) (0xc40c + ((n) * 0x10)) #define DWC3_GHWPARAMS8 0xc600 +#define DWC3_GUCTL3 0xc60c #define DWC3_GFLADJ 0xc630 /* Device Registers */ @@ -370,6 +371,9 @@ /* Global User Control Register 2 */ #define DWC3_GUCTL2_RST_ACTBITLATER BIT(14) +/* Global User Control Register 3 */ +#define DWC3_GUCTL3_SPLITDISABLE BIT(14) + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) @@ -1210,6 +1214,9 @@ struct dwc3 { unsigned dis_metastability_quirk:1; + unsigned dis_split_quirk:1; + unsigned gctl_reset_quirk:1; + u16 imod_interval; }; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 07bd31bb2f8a..21c0072cdf38 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -269,7 +269,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, { const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; struct dwc3 *dwc = dep->dwc; - u32 timeout = 1000; + u32 timeout = 5000; u32 saved_config = 0; u32 reg;
There are tow quirks for DesignWare USB3 DRD Core of Hisilicon Kirin Soc. 1)SPLIT_BOUNDARY_DISABLE should be set for Host mode 2)A GCTL soft reset should be executed when switch mode Cc: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: Felipe Balbi <balbi@kernel.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: John Stultz <john.stultz@linaro.org> Cc: Binghui Wang <wangbinghui@hisilicon.com> Signed-off-by: Yu Chen <chenyu56@huawei.com> --- v2: * Fix data type of reg from int to u32. --- --- drivers/usb/dwc3/core.c | 43 +++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 7 +++++++ drivers/usb/dwc3/gadget.c | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-)