diff options
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r-- | drivers/usb/dwc3/core.c | 61 |
1 files changed, 27 insertions, 34 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c9bb93a2c81e..999ce5e84d3c 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; @@ -686,8 +698,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 +824,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; @@ -1166,7 +1176,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); @@ -1310,8 +1319,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 +1444,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 +1457,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 +1535,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 +1560,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 +1573,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 +1584,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); |