From 805c7cc16e2a321b733743233cf3930c4e7df70d Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Thu, 15 Oct 2020 21:24:47 +0530 Subject: [PATCH] usb: dwc3: Write necessary registers for dual port enablement In line with the sequence for primary port, update proper fields of DWC3_GUSB2PHYCFG and DWC3_GUSB3PIPECTL registers for the second port of the dual port controller. Update other registers as required. While at it, also avoid enabling SSPHY autosuspend if dis_u3_susphy_quirk is set. Change-Id: Ib79dba4c6d854fa2bf33a1b7cecf06f988250662 Signed-off-by: Ajay Agarwal Signed-off-by: Harsh Agarwal --- drivers/usb/dwc3/core.c | 12 ++++++++ drivers/usb/dwc3/dwc3-msm.c | 56 +++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index f17fe5d6b456..593169ef81f6 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -613,6 +613,10 @@ static int dwc3_phy_setup(struct dwc3 *dwc) u32 reg; reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); + if (dwc->dual_port) { + if (reg != dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(1))) + dev_warn(dwc->dev, "Reset values of pipectl registers are different!\n"); + } /* * Make sure UX_EXIT_PX is cleared as that causes issues with some @@ -664,8 +668,14 @@ static int dwc3_phy_setup(struct dwc3 *dwc) DWC3_GUSB3PIPECTL_P3EXSIGP2); dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); + if (dwc->dual_port) + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(1), reg); reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + if (dwc->dual_port) { + if (reg != dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(1))) + dev_warn(dwc->dev, "Reset values of usb2phycfg registers are different!\n"); + } /* Select the HS PHY interface */ switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) { @@ -728,6 +738,8 @@ static int dwc3_phy_setup(struct dwc3 *dwc) reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + if (dwc->dual_port) + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(1), reg); return 0; } diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index f93605dec987..e7785ffc3c9a 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -2560,6 +2560,12 @@ static void dwc3_en_sleep_mode(struct dwc3_msm *mdwc) reg |= DWC3_GUSB2PHYCFG_ENBLSLPM; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0), reg); + if (mdwc->dual_port) { + reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(1)); + reg |= DWC3_GUSB2PHYCFG_ENBLSLPM; + dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(1), reg); + } + reg = dwc3_msm_read_reg(mdwc->base, DWC3_GUCTL1); reg |= DWC3_GUCTL1_L1_SUSP_THRLD_EN_FOR_HOST; dwc3_msm_write_reg(mdwc->base, DWC3_GUCTL1, reg); @@ -3171,6 +3177,14 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse, reg |= DWC3_GUSB3PIPECTL_DISRXDETU3; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), reg); + + if (mdwc->dual_port) { + reg = dwc3_msm_read_reg(mdwc->base, + DWC3_GUSB3PIPECTL(1)); + reg |= DWC3_GUSB3PIPECTL_DISRXDETU3; + dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(1), + reg); + } } /* indicate phy about SS mode */ dwc3_msm_is_superspeed(mdwc); @@ -3356,6 +3370,14 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) reg &= ~DWC3_GUSB3PIPECTL_DISRXDETU3; dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), reg); + + if (mdwc->dual_port) { + reg = dwc3_msm_read_reg(mdwc->base, + DWC3_GUSB3PIPECTL(1)); + reg &= ~DWC3_GUSB3PIPECTL_DISRXDETU3; + dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(1), + reg); + } } } @@ -5135,8 +5157,14 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) } mdwc->in_host_mode = true; - dwc3_msm_write_reg_field(mdwc->base, DWC3_GUSB3PIPECTL(0), - DWC3_GUSB3PIPECTL_SUSPHY, 1); + if (!dwc->dis_u3_susphy_quirk) { + dwc3_msm_write_reg_field(mdwc->base, DWC3_GUSB3PIPECTL(0), + DWC3_GUSB3PIPECTL_SUSPHY, 1); + if (mdwc->dual_port) { + dwc3_msm_write_reg_field(mdwc->base, DWC3_GUSB3PIPECTL(1), + DWC3_GUSB3PIPECTL_SUSPHY, 1); + } + } /* Reduce the U3 exit handshake timer from 8us to approximately * 300ns to avoid lfps handshake interoperability issues @@ -5148,9 +5176,21 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) dwc3_msm_write_reg_field(mdwc->base, DWC31_LINK_LU3LFPSRXTIM(0), GEN1_U3_EXIT_RSP_RX_CLK_MASK, 5); - dev_dbg(mdwc->dev, "LU3:%08x\n", + dev_dbg(mdwc->dev, "link0 LU3:%08x\n", dwc3_msm_read_reg(mdwc->base, DWC31_LINK_LU3LFPSRXTIM(0))); + + if (mdwc->dual_port) { + dwc3_msm_write_reg_field(mdwc->base, + DWC31_LINK_LU3LFPSRXTIM(1), + GEN2_U3_EXIT_RSP_RX_CLK_MASK, 6); + dwc3_msm_write_reg_field(mdwc->base, + DWC31_LINK_LU3LFPSRXTIM(1), + GEN1_U3_EXIT_RSP_RX_CLK_MASK, 5); + dev_dbg(mdwc->dev, "link1 LU3:%08x\n", + dwc3_msm_read_reg(mdwc->base, + DWC31_LINK_LU3LFPSRXTIM(1))); + } } /* xHCI should have incremented child count as necessary */ @@ -5199,8 +5239,14 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) #endif dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); - dwc3_msm_write_reg_field(mdwc->base, DWC3_GUSB3PIPECTL(0), - DWC3_GUSB3PIPECTL_SUSPHY, 0); + if (!dwc->dis_u3_susphy_quirk) { + dwc3_msm_write_reg_field(mdwc->base, DWC3_GUSB3PIPECTL(0), + DWC3_GUSB3PIPECTL_SUSPHY, 0); + if (mdwc->dual_port) { + dwc3_msm_write_reg_field(mdwc->base, DWC3_GUSB3PIPECTL(1), + DWC3_GUSB3PIPECTL_SUSPHY, 0); + } + } mdwc->in_host_mode = false; /* wait for LPM, to ensure h/w is reset after stop_host */