From: Devdutt Patnaik Date: Tue, 21 Jun 2016 00:09:37 +0000 (-0700) Subject: usb: dwc3: Determine connection speed for HS PHY X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4d0a155ed7773832119d62f9450a338d0fd078ec;p=sagit-ice-cold%2Fkernel_xiaomi_msm8998.git usb: dwc3: Determine connection speed for HS PHY DP/DM linestate is needed by the QUSB2 PHY driver to configure the polarity of DP/DM transition triggers for exiting low power mode. This was previously available via the QUSB2PHY_PORT_UTMI_STATUS PHY register which is now deprecated. In order to correctly determine the interrupt polarity we need to pass the current operating speed to the QUSB2 PHY driver. The PHY driver uses mode, speed and cable connection status to determine the linestate and configure interrupt polarities for wake up. Add logic to determine operating speed for host and device mode cases. Change-Id: Iaede1269f514a314bd9717a33100f748e7753b2a Signed-off-by: Devdutt Patnaik --- diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index f9c0b6a04224..1f597143ceb8 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1794,6 +1794,36 @@ static void dwc3_msm_bus_vote_w(struct work_struct *w) dev_err(mdwc->dev, "Failed to reset bus bw vote %d\n", ret); } +static void dwc3_set_phy_speed_flags(struct dwc3_msm *mdwc) +{ + struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); + int i, num_ports; + u32 reg; + + mdwc->hs_phy->flags &= ~(PHY_HSFS_MODE | PHY_LS_MODE); + if (mdwc->in_host_mode) { + reg = dwc3_msm_read_reg(mdwc->base, USB3_HCSPARAMS1); + num_ports = HCS_MAX_PORTS(reg); + for (i = 0; i < num_ports; i++) { + reg = dwc3_msm_read_reg(mdwc->base, + USB3_PORTSC + i*0x10); + if (reg & PORT_PE) { + if (DEV_HIGHSPEED(reg) || DEV_FULLSPEED(reg)) + mdwc->hs_phy->flags |= PHY_HSFS_MODE; + else if (DEV_LOWSPEED(reg)) + mdwc->hs_phy->flags |= PHY_LS_MODE; + } + } + } else { + if (dwc->gadget.speed == USB_SPEED_HIGH || + dwc->gadget.speed == USB_SPEED_FULL) + mdwc->hs_phy->flags |= PHY_HSFS_MODE; + else if (dwc->gadget.speed == USB_SPEED_LOW) + mdwc->hs_phy->flags |= PHY_LS_MODE; + } +} + + static int dwc3_msm_suspend(struct dwc3_msm *mdwc) { int ret, i; @@ -1867,6 +1897,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) /* disable power event irq, hs and ss phy irq is used as wake up src */ disable_irq(mdwc->pwr_event_irq); + dwc3_set_phy_speed_flags(mdwc); /* Suspend HS PHY */ usb_phy_set_suspend(mdwc->hs_phy, 1); @@ -2016,6 +2047,7 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) mdwc->lpm_flags &= ~MDWC3_SS_PHY_SUSPEND; } + mdwc->hs_phy->flags &= ~(PHY_HSFS_MODE | PHY_LS_MODE); /* Resume HS PHY */ usb_phy_set_suspend(mdwc->hs_phy, 0); diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 89effb61d153..44b6222db9a3 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -176,6 +176,8 @@ struct msm_usb_cable { #define DEVICE_IN_SS_MODE BIT(5) #define PHY_LANE_A BIT(6) #define PHY_LANE_B BIT(7) +#define PHY_HSFS_MODE BIT(8) +#define PHY_LS_MODE BIT(9) #define USB_NUM_BUS_CLOCKS 3