Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d719425 authored by Jack Pham's avatar Jack Pham
Browse files

usb: phy: msm-hsusb: Correctly set RETENABLEN bit



Clean up the setting of the RETENABLEN bit. We need to consider
several different revisions of the PHY which all have slightly
different implementations of this hardware signal.

Version < 10020061:
- RETENABLEN bit is located in the HS_PHY_CTRL register. Clear it
  to enable retention mode when entering suspend.

Version 10020061:
- There are two known revisions with different behavior. The newer
  one adds PLLBTUNE and PLLITUNE fields to the HS_PHY_CTRL_COMMON
  register. The PLLITUNE[1] bit actually is tied to the RETENABLEN
  input signal on the PHY, so it must be set when entering suspend.
  Currently the only way to check is if the device tree parameter
  "qcom,set-pllbtune" is present.
- Otherwise if PLL{B,I}TUNE are not present set the
  HS_PHY_CTRL_COMMON RETENABLEN bit directly.

Version 10060000:
- Uses the HS_PHY_CTRL_COMMON RETENABLEN bit directly.

Finally, move the setting of this bit outside of the multi-port
handling loop, since it's only set once per PHY.

Change-Id: I203bb9364c1c4c3d96d3c512ba631d29a8b3375e
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent c3e072e1
Loading
Loading
Loading
Loading
+46 −34
Original line number Diff line number Diff line
@@ -332,18 +332,16 @@ static int msm_hsphy_init(struct usb_phy *uphy)
					SEC_UTMI_FREE_CLK_GFM_SEL1);

	if (phy->core_ver >= MSM_CORE_VER_120) {
		if (phy->set_pllbtune) {
		val = readl_relaxed(phy->base + HS_PHY_CTRL_COMMON_REG);
		val |= COMMON_OTGDISABLE0 | COMMON_OTGTUNE0_DEFAULT |
			COMMON_COMMONONN | FSEL_DEFAULT | COMMON_RETENABLEN;

		if (phy->set_pllbtune) {
			val |= COMMON_PLLBTUNE | COMMON_CLKCORE;
			val &= ~COMMON_FSEL;
			writel_relaxed(val, phy->base + HS_PHY_CTRL_COMMON_REG);
		} else {
			writel_relaxed(COMMON_OTGDISABLE0 |
				COMMON_OTGTUNE0_DEFAULT |
				COMMON_COMMONONN | FSEL_DEFAULT |
				COMMON_RETENABLEN,
				phy->base + HS_PHY_CTRL_COMMON_REG);
		}

		writel_relaxed(val, phy->base + HS_PHY_CTRL_COMMON_REG);
	}

	/*
@@ -412,22 +410,6 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
					HS_PHY_CTRL_REG(i),
					(USB2_SUSPEND_N_SEL | USB2_SUSPEND_N),
					USB2_SUSPEND_N_SEL);
			/*
			 * Enable PHY retention
			 * RETENABLEN bit is not available on few platforms.
			 */
			if (!chg_connected) {
				if (phy->set_pllbtune)
					msm_usb_write_readback(phy->base,
						HS_PHY_CTRL_COMMON_REG,
						COMMON_PLLITUNE_1,
						COMMON_PLLITUNE_1);
				else
					msm_usb_write_readback(phy->base,
						HS_PHY_CTRL_REG(i),
						RETENABLEN, 0);
				phy->lpm_flags |= PHY_RETENTIONED;
			}
			}

			if (!phy->ext_vbus_id)
@@ -439,6 +421,30 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
					(OTGSESSVLDHV_INTEN | IDHV_INTEN),
					(OTGSESSVLDHV_INTEN | IDHV_INTEN));
		}

		/* Enable PHY retention */
		if (!host && !chg_connected) {
			if (phy->core_ver == MSM_CORE_VER_120 &&
					phy->set_pllbtune)
				/*
				 * On this particular revision the PLLITUNE[1]
				 * bit acts as the control for the RETENABLEN
				 * PHY signal.
				 */
				msm_usb_write_readback(phy->base,
					HS_PHY_CTRL_COMMON_REG,
					COMMON_PLLITUNE_1, COMMON_PLLITUNE_1);
			else if (phy->core_ver >= MSM_CORE_VER_120)
				msm_usb_write_readback(phy->base,
					HS_PHY_CTRL_COMMON_REG,
					COMMON_RETENABLEN, 0);
			else
				msm_usb_write_readback(phy->base,
					HS_PHY_CTRL_REG(0),
					RETENABLEN, 0);
			phy->lpm_flags |= PHY_RETENTIONED;
		}

		/* can turn off regulators if disconnected in device mode */
		if (phy->lpm_flags & PHY_RETENTIONED && !phy->cable_connected) {
			if (phy->ext_vbus_id) {
@@ -462,6 +468,21 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
				msm_hsusb_ldo_enable(phy, 1);
				phy->lpm_flags &= ~PHY_PWR_COLLAPSED;
			}

			/* Disable PHY retention */
			if (phy->core_ver == MSM_CORE_VER_120 &&
					phy->set_pllbtune)
				msm_usb_write_readback(phy->base,
					HS_PHY_CTRL_COMMON_REG,
					COMMON_PLLITUNE_1, 0);
			else if (phy->core_ver >= MSM_CORE_VER_120)
				msm_usb_write_readback(phy->base,
					HS_PHY_CTRL_COMMON_REG,
					COMMON_RETENABLEN, COMMON_RETENABLEN);
			else
				msm_usb_write_readback(phy->base,
					HS_PHY_CTRL_REG(0),
					RETENABLEN, RETENABLEN);
			phy->lpm_flags &= ~PHY_RETENTIONED;
		}

@@ -476,6 +497,7 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
						FSEL_MASK, FSEL_DEFAULT);
			}
		}

		for (i = 0; i < phy->num_ports; i++) {
			if (!phy->ext_vbus_id)
				/* Disable HV interrupts */
@@ -497,16 +519,6 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
						ALT_INTERRUPT_EN_REG(i),
						DPDMHV_INT_MASK, 0);
			if (!host) {
				/* Disable PHY retention */
				if (phy->set_pllbtune)
					msm_usb_write_readback(phy->base,
						HS_PHY_CTRL_COMMON_REG,
						COMMON_PLLITUNE_1, 0);
				else
					msm_usb_write_readback(phy->base,
						HS_PHY_CTRL_REG(i),
						RETENABLEN, RETENABLEN);

				/* Bring PHY out of suspend */
				msm_usb_write_readback(phy->base,
						HS_PHY_CTRL_REG(i),