From 3e583e6ceeef44df3f14caf1567bdbd1e9672c71 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Mon, 4 May 2020 17:34:11 -0700 Subject: [PATCH] usb: phy: Reset and initialize HSPHY in host mode when EUD is enable EUD HUB functionality is relevant into USB device mode only. Hence when using USB host mode, continue performing reset and initialization functionality with HSPHY even though EUD is enable. If EUD is enable while starting host mode, re-enable EUD whie exiting host mode. Change-Id: Ifc2a105d8a02511dd2fc58be5fbc788d46546ba0 Signed-off-by: Mayank Rana --- drivers/usb/dwc3/dwc3-msm.c | 4 ++-- drivers/usb/phy/phy-msm-snps-hs.c | 35 ++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 03cc12943df9..d944d17b8d0f 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -4582,11 +4582,11 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) if (on) { dev_dbg(mdwc->dev, "%s: turn on host\n", __func__); - + mdwc->hs_phy->flags |= PHY_HOST_MODE; + dbg_event(0xFF, "hs_phy_flag:%x", mdwc->hs_phy->flags); pm_runtime_get_sync(mdwc->dev); dbg_event(0xFF, "StrtHost gync", atomic_read(&mdwc->dev->power.usage_count)); - mdwc->hs_phy->flags |= PHY_HOST_MODE; if (dwc->maximum_speed >= USB_SPEED_SUPER) { mdwc->ss_phy->flags |= PHY_HOST_MODE; usb_phy_notify_connect(mdwc->ss_phy, diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c index ff349d65be58..f95628713994 100644 --- a/drivers/usb/phy/phy-msm-snps-hs.c +++ b/drivers/usb/phy/phy-msm-snps-hs.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #define USB2_PHY_USB_PHY_UTMI_CTRL0 (0x3c) #define OPMODE_MASK (0x3 << 3) @@ -82,7 +84,9 @@ struct msm_hsphy { struct usb_phy phy; void __iomem *base; + phys_addr_t eud_reg; void __iomem *eud_enable_reg; + bool re_enable_eud; struct clk *ref_clk_src; struct clk *cfg_ahb_clk; @@ -331,18 +335,28 @@ static void hsusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt, } } +#define EUD_EN2 BIT(0) static int msm_hsphy_init(struct usb_phy *uphy) { struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy); int ret; - u32 rcal_code = 0; + u32 rcal_code = 0, eud_csr_reg = 0; - dev_dbg(uphy->dev, "%s\n", __func__); - - if (phy->eud_enable_reg && readl_relaxed(phy->eud_enable_reg)) { - dev_err(phy->phy.dev, "eud is enabled\n"); - ret = msm_hsphy_enable_power(phy, true); - return ret; + dev_dbg(uphy->dev, "%s phy_flags:0x%x\n", __func__, phy->phy.flags); + if (phy->eud_enable_reg) { + eud_csr_reg = readl_relaxed(phy->eud_enable_reg); + if (eud_csr_reg & EUD_EN2) { + dev_dbg(phy->phy.dev, "csr:0x%x eud is enabled\n", + eud_csr_reg); + /* if in host mode, disable EUD */ + if (phy->phy.flags & PHY_HOST_MODE) { + qcom_scm_io_writel(phy->eud_reg, 0x0); + phy->re_enable_eud = true; + } else { + ret = msm_hsphy_enable_power(phy, true); + return ret; + } + } } ret = msm_hsphy_enable_power(phy, true); @@ -486,6 +500,12 @@ suspend: } else {/* Cable disconnect */ mutex_lock(&phy->phy_lock); dev_dbg(uphy->dev, "phy->flags:0x%x\n", phy->phy.flags); + if (phy->re_enable_eud) { + dev_dbg(uphy->dev, "re-enabling EUD\n"); + qcom_scm_io_writel(phy->eud_reg, 0x1); + phy->re_enable_eud = false; + } + if (!phy->dpdm_enable) { if (!(phy->phy.flags & EUD_SPOOF_DISCONNECT)) { dev_dbg(uphy->dev, "turning off clocks/ldo\n"); @@ -703,6 +723,7 @@ static int msm_hsphy_probe(struct platform_device *pdev) dev_err(dev, "err getting eud_enable_reg address\n"); return PTR_ERR(phy->eud_enable_reg); } + phy->eud_reg = res->start; } /* ref_clk_src is needed irrespective of SE_CLK or DIFF_CLK usage */