diff options
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r-- | drivers/usb/dwc3/core.c | 104 |
1 files changed, 68 insertions, 36 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c9bb93a2c81e..1d85c42b9c67 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -168,7 +168,6 @@ static void __dwc3_set_mode(struct work_struct *work) otg_set_vbus(dwc->usb2_phy->otg, true); 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); } break; case DWC3_GCTL_PRTCAP_DEVICE: @@ -252,12 +251,25 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) reg |= DWC3_DCTL_CSFTRST; dwc3_writel(dwc->regs, DWC3_DCTL, reg); + /* + * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit + * is cleared only after all the clocks are synchronized. This can + * take a little more than 50ms. Set the polling rate at 20ms + * for 10 times instead. + */ + if (dwc3_is_usb31(dwc) && dwc->revision >= DWC3_USB31_REVISION_190A) + retries = 10; + do { reg = dwc3_readl(dwc->regs, DWC3_DCTL); if (!(reg & DWC3_DCTL_CSFTRST)) goto done; - udelay(1); + if (dwc3_is_usb31(dwc) && + dwc->revision >= DWC3_USB31_REVISION_190A) + msleep(20); + else + udelay(1); } while (--retries); phy_exit(dwc->usb3_generic_phy); @@ -267,11 +279,11 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) done: /* - * For DWC_usb31 controller, once DWC3_DCTL_CSFTRST bit is cleared, - * we must wait at least 50ms before accessing the PHY domain - * (synchronization delay). DWC_usb31 programming guide section 1.3.2. + * For DWC_usb31 controller 1.80a and prior, once DCTL.CSFRST bit + * is cleared, we must wait at least 50ms before accessing the PHY + * domain (synchronization delay). */ - if (dwc3_is_usb31(dwc)) + if (dwc3_is_usb31(dwc) && dwc->revision <= DWC3_USB31_REVISION_180A) msleep(50); return 0; @@ -300,8 +312,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); dft = reg & DWC3_GFLADJ_30MHZ_MASK; - if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj, - "request value same as default, ignoring\n")) { + if (dft != dwc->fladj) { reg &= ~DWC3_GFLADJ_30MHZ_MASK; reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj; dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); @@ -555,8 +566,11 @@ static int dwc3_core_ulpi_init(struct dwc3 *dwc) */ static int dwc3_phy_setup(struct dwc3 *dwc) { + unsigned int hw_mode; u32 reg; + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); /* @@ -574,6 +588,14 @@ static int dwc3_phy_setup(struct dwc3 *dwc) if (dwc->revision > DWC3_REVISION_194A) reg |= DWC3_GUSB3PIPECTL_SUSPHY; + /* + * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be cleared after + * power-on reset, and it can be set after core initialization, which is + * after device soft-reset during initialization. + */ + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD) + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; + if (dwc->u2ss_inp3_quirk) reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; @@ -657,6 +679,14 @@ static int dwc3_phy_setup(struct dwc3 *dwc) if (dwc->revision > DWC3_REVISION_194A) reg |= DWC3_GUSB2PHYCFG_SUSPHY; + /* + * For DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared after + * power-on reset, and it can be set after core initialization, which is + * after device soft-reset during initialization. + */ + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD) + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; + if (dwc->dis_u2_susphy_quirk) reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; @@ -686,8 +716,7 @@ static void dwc3_core_exit(struct dwc3 *dwc) usb_phy_set_suspend(dwc->usb3_phy, 1); phy_power_off(dwc->usb2_generic_phy); phy_power_off(dwc->usb3_generic_phy); - clk_bulk_disable(dwc->num_clks, dwc->clks); - clk_bulk_unprepare(dwc->num_clks, dwc->clks); + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); reset_control_assert(dwc->reset); } @@ -813,8 +842,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc) * result = 1, means INCRx burst mode supported. * result > 1, means undefined length burst mode supported. */ - ntype = device_property_read_u32_array(dev, - "snps,incr-burst-type-adjustment", NULL, 0); + ntype = device_property_count_u32(dev, "snps,incr-burst-type-adjustment"); if (ntype <= 0) return; @@ -893,9 +921,12 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc) */ static int dwc3_core_init(struct dwc3 *dwc) { + unsigned int hw_mode; u32 reg; int ret; + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); + /* * Write Linux Version Code to our GUID register so it's easy to figure * out which kernel version a bug was found. @@ -931,6 +962,21 @@ static int dwc3_core_init(struct dwc3 *dwc) if (ret) goto err0a; + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && + dwc->revision > DWC3_REVISION_194A) { + if (!dwc->dis_u3_susphy_quirk) { + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); + reg |= DWC3_GUSB3PIPECTL_SUSPHY; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); + } + + if (!dwc->dis_u2_susphy_quirk) { + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg |= DWC3_GUSB2PHYCFG_SUSPHY; + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + } + } + dwc3_core_setup_global_control(dwc); dwc3_core_num_eps(dwc); @@ -1166,7 +1212,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) dev_err(dev, "failed to initialize host\n"); return ret; } - phy_calibrate(dwc->usb2_generic_phy); break; case USB_DR_MODE_OTG: INIT_WORK(&dwc->drd_work, __dwc3_set_mode); @@ -1201,6 +1246,9 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) /* do nothing */ break; } + + /* de-assert DRVVBUS for HOST and OTG mode */ + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); } static void dwc3_get_properties(struct dwc3 *dwc) @@ -1310,8 +1358,7 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; - dwc->hird_threshold = hird_threshold - | (dwc->is_utmi_l1_suspend << 4); + dwc->hird_threshold = hird_threshold; dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd; dwc->rx_max_burst_prd = rx_max_burst_prd; @@ -1436,7 +1483,7 @@ static int dwc3_probe(struct platform_device *pdev) if (dev->of_node) { dwc->num_clks = ARRAY_SIZE(dwc3_core_clks); - ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks); + ret = devm_clk_bulk_get(dev, dwc->num_clks, dwc->clks); if (ret == -EPROBE_DEFER) return ret; /* @@ -1449,16 +1496,12 @@ static int dwc3_probe(struct platform_device *pdev) ret = reset_control_deassert(dwc->reset); if (ret) - goto put_clks; + return ret; - ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); + ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks); if (ret) goto assert_reset; - ret = clk_bulk_enable(dwc->num_clks, dwc->clks); - if (ret) - goto unprepare_clks; - if (!dwc3_core_is_valid(dwc)) { dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); ret = -ENODEV; @@ -1531,13 +1574,9 @@ err1: pm_runtime_disable(&pdev->dev); disable_clks: - clk_bulk_disable(dwc->num_clks, dwc->clks); -unprepare_clks: - clk_bulk_unprepare(dwc->num_clks, dwc->clks); + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); assert_reset: reset_control_assert(dwc->reset); -put_clks: - clk_bulk_put(dwc->num_clks, dwc->clks); return ret; } @@ -1560,7 +1599,6 @@ static int dwc3_remove(struct platform_device *pdev) dwc3_free_event_buffers(dwc); dwc3_free_scratch_buffers(dwc); - clk_bulk_put(dwc->num_clks, dwc->clks); return 0; } @@ -1574,14 +1612,10 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc) if (ret) return ret; - ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); + ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks); if (ret) goto assert_reset; - ret = clk_bulk_enable(dwc->num_clks, dwc->clks); - if (ret) - goto unprepare_clks; - ret = dwc3_core_init(dwc); if (ret) goto disable_clks; @@ -1589,9 +1623,7 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc) return 0; disable_clks: - clk_bulk_disable(dwc->num_clks, dwc->clks); -unprepare_clks: - clk_bulk_unprepare(dwc->num_clks, dwc->clks); + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); assert_reset: reset_control_assert(dwc->reset); |