Loading drivers/usb/dwc3/core.c +61 −62 Original line number Diff line number Diff line Loading @@ -111,20 +111,16 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode) } /** * dwc3_core_soft_reset_after_phy_init - Issues core soft reset * and PHY reset for HW versions which require core reset after * PHY initialization and reset * Peforms initialization of HS and SS PHYs. * If used as a part of POR or init sequence it is recommended * that we should perform hard reset of the PHYs prior to invoking * this function. * @dwc: pointer to our context structure */ static int dwc3_core_soft_reset_after_phy_init(struct dwc3 *dwc) static int dwc3_init_usb_phys(struct dwc3 *dwc) { u32 reg; int ret; /* Reset PHYs */ usb_phy_reset(dwc->usb3_phy); usb_phy_reset(dwc->usb2_phy); /* Bring up PHYs */ ret = usb_phy_init(dwc->usb2_phy); if (ret) { Loading @@ -139,85 +135,90 @@ static int dwc3_core_soft_reset_after_phy_init(struct dwc3 *dwc) return ret; } /* Put Core in Reset */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT); /* Take Core out of reset state */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT); return 0; } /** * dwc3_core_soft_reset - Issues core soft reset and PHY reset * Peforms core soft reset and PHY soft reset of HS and SS PHYs. * If used as a part of POR or init sequence it is recommended * that we should perform hard reset and init of the PHYs prior * to invoking this function. * @dwc: pointer to our context structure */ static int dwc3_core_soft_reset(struct dwc3 *dwc) static void dwc3_core_and_phy_soft_reset(struct dwc3 *dwc) { u32 reg; int ret; if (dwc->core_reset_after_phy_init) return dwc3_core_soft_reset_after_phy_init(dwc); /* Before Resetting PHY, put Core in Reset */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); /* Bring up PHYs */ ret = usb_phy_init(dwc->usb2_phy); if (ret) { pr_err("%s: usb_phy_init(dwc->usb2_phy) returned %d\n", __func__, ret); return ret; } ret = usb_phy_init(dwc->usb3_phy); if (ret) { pr_err("%s: usb_phy_init(dwc->usb3_phy) returned %d\n", __func__, ret); return ret; } dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT); /* Assert USB3 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); /* Assert USB2 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); mdelay(100); msleep(100); /* Clear USB3 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); if (dwc->revision >= DWC3_REVISION_270A) { reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); reg |= DWC3_GUSB3PIPECTL_DELAYP1TRANS; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); } /* Assert USB2 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); msleep(100); /* Clear USB2 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); mdelay(100); msleep(100); /* After PHYs are stable we can take Core out of reset state */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); msleep(100); } /** * dwc3_core_soft_reset - Issues core soft reset and PHY reset * @dwc: pointer to our context structure */ static int dwc3_core_reset(struct dwc3 *dwc) { int ret; /* Reset PHYs */ usb_phy_reset(dwc->usb2_phy); usb_phy_reset(dwc->usb3_phy); /* Initialize PHYs */ ret = dwc3_init_usb_phys(dwc); if (ret) { pr_err("%s: dwc3_init_phys returned %d\n", __func__, ret); return ret; } dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT); /* Perform core and PHY soft reset */ dwc3_core_and_phy_soft_reset(dwc); dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT); return 0; Loading Loading @@ -400,7 +401,7 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) * * Returns 0 on success otherwise negative errno. */ static int dwc3_core_init(struct dwc3 *dwc) int dwc3_core_init(struct dwc3 *dwc) { unsigned long timeout; u32 reg; Loading @@ -415,6 +416,11 @@ static int dwc3_core_init(struct dwc3 *dwc) } dwc->revision = reg; ret = dwc3_core_reset(dwc); if (ret) goto err0; /* issue device SoftReset too */ timeout = jiffies + msecs_to_jiffies(500); dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); Loading @@ -432,10 +438,6 @@ static int dwc3_core_init(struct dwc3 *dwc) cpu_relax(); } while (true); ret = dwc3_core_soft_reset(dwc); if (ret) goto err0; reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; reg &= ~DWC3_GCTL_DISSCRAMBLE; Loading Loading @@ -619,9 +621,6 @@ static int dwc3_probe(struct platform_device *pdev) return -ENOMEM; } dwc->core_reset_after_phy_init = of_property_read_bool(node, "snps,core-reset-after-phy-init"); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); host_only_mode = of_property_read_bool(node, "snps,host-only-mode"); dwc->ssphy_clear_auto_suspend_on_disconnect = Loading drivers/usb/dwc3/core.h +7 −1 Original line number Diff line number Diff line Loading @@ -165,6 +165,10 @@ /* Bit fields */ /* Global SoC Bus Configuration Register 1 */ #define DWC3_GSBUSCFG1_PIPETRANSLIMIT_MASK (0x0f << 8) #define DWC3_GSBUSCFG1_PIPETRANSLIMIT(n) ((n) << 8) /* Global Configuration Register */ #define DWC3_GCTL_PWRDNSCALE(n) ((n) << 19) #define DWC3_GCTL_PWRDNSCALEMASK (0xFFF80000) Loading Loading @@ -205,6 +209,7 @@ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) #define DWC3_GUSB3PIPECTL_DELAY_P1P2P3 (7 << 19) #define DWC3_GUSB3PIPECTL_DELAYP1TRANS (1 << 18) #define DWC3_GUSB3PIPECTL_DIS_RXDET_U3_RXDET (1 << 22) #define DWC3_GUSB3PIPECTL_ELASTIC_BUF_MODE (1 << 0) Loading Loading @@ -845,6 +850,7 @@ struct dwc3 { #define DWC3_REVISION_230A 0x5533230a #define DWC3_REVISION_240A 0x5533240a #define DWC3_REVISION_250A 0x5533250a #define DWC3_REVISION_270A 0x5533270a unsigned is_selfpowered:1; unsigned three_stage_setup:1; Loading Loading @@ -891,7 +897,6 @@ struct dwc3 { bool tx_fifo_reduced; bool nominal_elastic_buffer; bool core_reset_after_phy_init; bool err_evt_seen; bool ssphy_clear_auto_suspend_on_disconnect; bool usb3_u1u2_disable; Loading Loading @@ -1098,6 +1103,7 @@ static void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend) { } #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ void dwc3_gadget_restart(struct dwc3 *dwc); int dwc3_core_init(struct dwc3 *dwc); void dwc3_post_host_reset_core_init(struct dwc3 *dwc); int dwc3_event_buffers_setup(struct dwc3 *dwc); Loading drivers/usb/dwc3/dwc3-msm.c +23 −40 Original line number Diff line number Diff line Loading @@ -1028,6 +1028,8 @@ static int dwc3_msm_link_clk_reset(struct dwc3_msm *mdwc, bool assert) dev_dbg(mdwc->dev, "block_reset ASSERT\n"); clk_disable_unprepare(mdwc->ref_clk); clk_disable_unprepare(mdwc->iface_clk); clk_disable_unprepare(mdwc->utmi_clk); clk_disable_unprepare(mdwc->sleep_clk); clk_disable_unprepare(mdwc->core_clk); ret = clk_reset(mdwc->core_clk, CLK_RESET_ASSERT); if (ret) Loading @@ -1037,6 +1039,8 @@ static int dwc3_msm_link_clk_reset(struct dwc3_msm *mdwc, bool assert) ret = clk_reset(mdwc->core_clk, CLK_RESET_DEASSERT); ndelay(200); clk_prepare_enable(mdwc->core_clk); clk_prepare_enable(mdwc->sleep_clk); clk_prepare_enable(mdwc->utmi_clk); clk_prepare_enable(mdwc->ref_clk); clk_prepare_enable(mdwc->iface_clk); if (ret) Loading Loading @@ -1450,46 +1454,8 @@ static void dwc3_start_chg_det(struct dwc3_charger *charger, bool start) static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc) { u32 reg; struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); /* Put Core in Reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg); usb_phy_init(dwc->usb2_phy); /* Assert USB3 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB3PIPECTL(0)); reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), reg); /* Assert USB2 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0), reg); udelay(100); /* Clear USB3 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB3PIPECTL(0)); reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), reg); /* Clear USB2 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)); reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0), reg); udelay(100); /* After PHYs are stable we can take Core out of reset state */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg); udelay(100); dwc3_core_init(dwc); /* Re-configure event buffers */ dwc3_event_buffers_setup(dwc); } Loading Loading @@ -1714,6 +1680,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) mdwc->lpm_flags |= MDWC3_POWER_COLLAPSE; dev_dbg(mdwc->dev, "%s: power collapse\n", __func__); dwc3_msm_config_gdsc(mdwc, 0); clk_disable_unprepare(mdwc->sleep_clk); } clk_disable_unprepare(mdwc->iface_clk); Loading Loading @@ -1832,7 +1799,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) clk_reset(mdwc->phy_com_reset, CLK_RESET_DEASSERT); } clk_prepare_enable(mdwc->utmi_clk); if (mdwc->lpm_flags & MDWC3_PHY_REF_CLK_OFF) { clk_prepare_enable(mdwc->ref_clk); Loading @@ -1848,6 +1814,11 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) mdwc->lpm_flags &= ~MDWC3_CORECLK_OFF; } clk_prepare_enable(mdwc->utmi_clk); if (mdwc->lpm_flags & MDWC3_POWER_COLLAPSE) clk_prepare_enable(mdwc->sleep_clk); usb_phy_set_suspend(mdwc->hs_phy, 0); /* Recover from controller power collapse */ Loading @@ -1862,6 +1833,13 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) return ret; } /* Reset SS PHY */ ret = usb_phy_reset(mdwc->ss_phy); if (ret) { dev_err(mdwc->dev, "ssphy reset failed\n"); return ret; } ret = dwc3_msm_restore_sec_config(mdwc->scm_dev_id); if (ret) return ret; Loading Loading @@ -3146,6 +3124,11 @@ static int dwc3_msm_probe(struct platform_device *pdev) } } /* Perform controller GCC reset */ dwc3_msm_link_clk_reset(mdwc, 1); msleep(20); dwc3_msm_link_clk_reset(mdwc, 0); ret = of_platform_populate(node, NULL, NULL, &pdev->dev); if (ret) { dev_err(&pdev->dev, Loading drivers/usb/dwc3/gadget.c +10 −0 Original line number Diff line number Diff line Loading @@ -2107,6 +2107,16 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) } dwc3_writel(dwc->regs, DWC3_DCFG, reg); /* Programs the number of outstanding pipelined transfer requests * the AXI master pushes to the AXI slave. */ if (dwc->revision >= DWC3_REVISION_270A) { reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1); reg &= ~DWC3_GSBUSCFG1_PIPETRANSLIMIT_MASK; reg |= DWC3_GSBUSCFG1_PIPETRANSLIMIT(0xe); dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg); } dwc->start_config_issued = false; /* Start with SuperSpeed Default */ Loading Loading
drivers/usb/dwc3/core.c +61 −62 Original line number Diff line number Diff line Loading @@ -111,20 +111,16 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode) } /** * dwc3_core_soft_reset_after_phy_init - Issues core soft reset * and PHY reset for HW versions which require core reset after * PHY initialization and reset * Peforms initialization of HS and SS PHYs. * If used as a part of POR or init sequence it is recommended * that we should perform hard reset of the PHYs prior to invoking * this function. * @dwc: pointer to our context structure */ static int dwc3_core_soft_reset_after_phy_init(struct dwc3 *dwc) static int dwc3_init_usb_phys(struct dwc3 *dwc) { u32 reg; int ret; /* Reset PHYs */ usb_phy_reset(dwc->usb3_phy); usb_phy_reset(dwc->usb2_phy); /* Bring up PHYs */ ret = usb_phy_init(dwc->usb2_phy); if (ret) { Loading @@ -139,85 +135,90 @@ static int dwc3_core_soft_reset_after_phy_init(struct dwc3 *dwc) return ret; } /* Put Core in Reset */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT); /* Take Core out of reset state */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT); return 0; } /** * dwc3_core_soft_reset - Issues core soft reset and PHY reset * Peforms core soft reset and PHY soft reset of HS and SS PHYs. * If used as a part of POR or init sequence it is recommended * that we should perform hard reset and init of the PHYs prior * to invoking this function. * @dwc: pointer to our context structure */ static int dwc3_core_soft_reset(struct dwc3 *dwc) static void dwc3_core_and_phy_soft_reset(struct dwc3 *dwc) { u32 reg; int ret; if (dwc->core_reset_after_phy_init) return dwc3_core_soft_reset_after_phy_init(dwc); /* Before Resetting PHY, put Core in Reset */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); /* Bring up PHYs */ ret = usb_phy_init(dwc->usb2_phy); if (ret) { pr_err("%s: usb_phy_init(dwc->usb2_phy) returned %d\n", __func__, ret); return ret; } ret = usb_phy_init(dwc->usb3_phy); if (ret) { pr_err("%s: usb_phy_init(dwc->usb3_phy) returned %d\n", __func__, ret); return ret; } dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT); /* Assert USB3 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); /* Assert USB2 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); mdelay(100); msleep(100); /* Clear USB3 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); if (dwc->revision >= DWC3_REVISION_270A) { reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); reg |= DWC3_GUSB3PIPECTL_DELAYP1TRANS; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); } /* Assert USB2 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); msleep(100); /* Clear USB2 PHY reset */ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); mdelay(100); msleep(100); /* After PHYs are stable we can take Core out of reset state */ reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); msleep(100); } /** * dwc3_core_soft_reset - Issues core soft reset and PHY reset * @dwc: pointer to our context structure */ static int dwc3_core_reset(struct dwc3 *dwc) { int ret; /* Reset PHYs */ usb_phy_reset(dwc->usb2_phy); usb_phy_reset(dwc->usb3_phy); /* Initialize PHYs */ ret = dwc3_init_usb_phys(dwc); if (ret) { pr_err("%s: dwc3_init_phys returned %d\n", __func__, ret); return ret; } dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT); /* Perform core and PHY soft reset */ dwc3_core_and_phy_soft_reset(dwc); dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT); return 0; Loading Loading @@ -400,7 +401,7 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) * * Returns 0 on success otherwise negative errno. */ static int dwc3_core_init(struct dwc3 *dwc) int dwc3_core_init(struct dwc3 *dwc) { unsigned long timeout; u32 reg; Loading @@ -415,6 +416,11 @@ static int dwc3_core_init(struct dwc3 *dwc) } dwc->revision = reg; ret = dwc3_core_reset(dwc); if (ret) goto err0; /* issue device SoftReset too */ timeout = jiffies + msecs_to_jiffies(500); dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); Loading @@ -432,10 +438,6 @@ static int dwc3_core_init(struct dwc3 *dwc) cpu_relax(); } while (true); ret = dwc3_core_soft_reset(dwc); if (ret) goto err0; reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; reg &= ~DWC3_GCTL_DISSCRAMBLE; Loading Loading @@ -619,9 +621,6 @@ static int dwc3_probe(struct platform_device *pdev) return -ENOMEM; } dwc->core_reset_after_phy_init = of_property_read_bool(node, "snps,core-reset-after-phy-init"); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); host_only_mode = of_property_read_bool(node, "snps,host-only-mode"); dwc->ssphy_clear_auto_suspend_on_disconnect = Loading
drivers/usb/dwc3/core.h +7 −1 Original line number Diff line number Diff line Loading @@ -165,6 +165,10 @@ /* Bit fields */ /* Global SoC Bus Configuration Register 1 */ #define DWC3_GSBUSCFG1_PIPETRANSLIMIT_MASK (0x0f << 8) #define DWC3_GSBUSCFG1_PIPETRANSLIMIT(n) ((n) << 8) /* Global Configuration Register */ #define DWC3_GCTL_PWRDNSCALE(n) ((n) << 19) #define DWC3_GCTL_PWRDNSCALEMASK (0xFFF80000) Loading Loading @@ -205,6 +209,7 @@ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) #define DWC3_GUSB3PIPECTL_DELAY_P1P2P3 (7 << 19) #define DWC3_GUSB3PIPECTL_DELAYP1TRANS (1 << 18) #define DWC3_GUSB3PIPECTL_DIS_RXDET_U3_RXDET (1 << 22) #define DWC3_GUSB3PIPECTL_ELASTIC_BUF_MODE (1 << 0) Loading Loading @@ -845,6 +850,7 @@ struct dwc3 { #define DWC3_REVISION_230A 0x5533230a #define DWC3_REVISION_240A 0x5533240a #define DWC3_REVISION_250A 0x5533250a #define DWC3_REVISION_270A 0x5533270a unsigned is_selfpowered:1; unsigned three_stage_setup:1; Loading Loading @@ -891,7 +897,6 @@ struct dwc3 { bool tx_fifo_reduced; bool nominal_elastic_buffer; bool core_reset_after_phy_init; bool err_evt_seen; bool ssphy_clear_auto_suspend_on_disconnect; bool usb3_u1u2_disable; Loading Loading @@ -1098,6 +1103,7 @@ static void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend) { } #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ void dwc3_gadget_restart(struct dwc3 *dwc); int dwc3_core_init(struct dwc3 *dwc); void dwc3_post_host_reset_core_init(struct dwc3 *dwc); int dwc3_event_buffers_setup(struct dwc3 *dwc); Loading
drivers/usb/dwc3/dwc3-msm.c +23 −40 Original line number Diff line number Diff line Loading @@ -1028,6 +1028,8 @@ static int dwc3_msm_link_clk_reset(struct dwc3_msm *mdwc, bool assert) dev_dbg(mdwc->dev, "block_reset ASSERT\n"); clk_disable_unprepare(mdwc->ref_clk); clk_disable_unprepare(mdwc->iface_clk); clk_disable_unprepare(mdwc->utmi_clk); clk_disable_unprepare(mdwc->sleep_clk); clk_disable_unprepare(mdwc->core_clk); ret = clk_reset(mdwc->core_clk, CLK_RESET_ASSERT); if (ret) Loading @@ -1037,6 +1039,8 @@ static int dwc3_msm_link_clk_reset(struct dwc3_msm *mdwc, bool assert) ret = clk_reset(mdwc->core_clk, CLK_RESET_DEASSERT); ndelay(200); clk_prepare_enable(mdwc->core_clk); clk_prepare_enable(mdwc->sleep_clk); clk_prepare_enable(mdwc->utmi_clk); clk_prepare_enable(mdwc->ref_clk); clk_prepare_enable(mdwc->iface_clk); if (ret) Loading Loading @@ -1450,46 +1454,8 @@ static void dwc3_start_chg_det(struct dwc3_charger *charger, bool start) static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc) { u32 reg; struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); /* Put Core in Reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg); usb_phy_init(dwc->usb2_phy); /* Assert USB3 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB3PIPECTL(0)); reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), reg); /* Assert USB2 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0), reg); udelay(100); /* Clear USB3 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB3PIPECTL(0)); reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), reg); /* Clear USB2 PHY reset */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)); reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0), reg); udelay(100); /* After PHYs are stable we can take Core out of reset state */ reg = dwc3_msm_read_reg(mdwc->base, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg); udelay(100); dwc3_core_init(dwc); /* Re-configure event buffers */ dwc3_event_buffers_setup(dwc); } Loading Loading @@ -1714,6 +1680,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) mdwc->lpm_flags |= MDWC3_POWER_COLLAPSE; dev_dbg(mdwc->dev, "%s: power collapse\n", __func__); dwc3_msm_config_gdsc(mdwc, 0); clk_disable_unprepare(mdwc->sleep_clk); } clk_disable_unprepare(mdwc->iface_clk); Loading Loading @@ -1832,7 +1799,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) clk_reset(mdwc->phy_com_reset, CLK_RESET_DEASSERT); } clk_prepare_enable(mdwc->utmi_clk); if (mdwc->lpm_flags & MDWC3_PHY_REF_CLK_OFF) { clk_prepare_enable(mdwc->ref_clk); Loading @@ -1848,6 +1814,11 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) mdwc->lpm_flags &= ~MDWC3_CORECLK_OFF; } clk_prepare_enable(mdwc->utmi_clk); if (mdwc->lpm_flags & MDWC3_POWER_COLLAPSE) clk_prepare_enable(mdwc->sleep_clk); usb_phy_set_suspend(mdwc->hs_phy, 0); /* Recover from controller power collapse */ Loading @@ -1862,6 +1833,13 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) return ret; } /* Reset SS PHY */ ret = usb_phy_reset(mdwc->ss_phy); if (ret) { dev_err(mdwc->dev, "ssphy reset failed\n"); return ret; } ret = dwc3_msm_restore_sec_config(mdwc->scm_dev_id); if (ret) return ret; Loading Loading @@ -3146,6 +3124,11 @@ static int dwc3_msm_probe(struct platform_device *pdev) } } /* Perform controller GCC reset */ dwc3_msm_link_clk_reset(mdwc, 1); msleep(20); dwc3_msm_link_clk_reset(mdwc, 0); ret = of_platform_populate(node, NULL, NULL, &pdev->dev); if (ret) { dev_err(&pdev->dev, Loading
drivers/usb/dwc3/gadget.c +10 −0 Original line number Diff line number Diff line Loading @@ -2107,6 +2107,16 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) } dwc3_writel(dwc->regs, DWC3_DCFG, reg); /* Programs the number of outstanding pipelined transfer requests * the AXI master pushes to the AXI slave. */ if (dwc->revision >= DWC3_REVISION_270A) { reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1); reg &= ~DWC3_GSBUSCFG1_PIPETRANSLIMIT_MASK; reg |= DWC3_GSBUSCFG1_PIPETRANSLIMIT(0xe); dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg); } dwc->start_config_issued = false; /* Start with SuperSpeed Default */ Loading