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

Commit b2f6a1cd authored by Manu Gautam's avatar Manu Gautam Committed by Gerrit - the friendly Code Review server
Browse files

usb: phy-msm-qusb-v2: Reset PLL only if not locked on resume



Driver currently unconditionally resets PLL while entering
suspend state. As per hardware databook PLL need not to be
reset across every suspend/resume. Driver should reset it
only if PLL fails to lock on resume which must be checked
using DEBUG_CTRL2 register.

Change-Id: I4cb544dd8ad94af9270746f67ad872ff1b77e2b0
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent 2b10bef6
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -141,7 +141,9 @@
			 0x198 /* PLL_BIAS_CONTROL_2 */
			 0x228 /* QUSB2PHY_SQ_CTRL1 */
			 0x22c /* QUSB2PHY_SQ_CTRL2 */
			 0x27c>; /* QUSB2PHY_DEBUG_CTRL1 */
			 0x27c /* QUSB2PHY_DEBUG_CTRL1 */
			 0x280 /* QUSB2PHY_DEBUG_CTRL2 */
			 0x2a0>; /* QUSB2PHY_STAT5 */

		qcom,qusb-phy-init-seq =
			/* <value reg_offset> */
@@ -431,7 +433,9 @@
			 0x198 /* PLL_BIAS_CONTROL_2 */
			 0x228 /* QUSB2PHY_SQ_CTRL1 */
			 0x22c /* QUSB2PHY_SQ_CTRL2 */
			 0x27c>; /* QUSB2PHY_DEBUG_CTRL1 */
			 0x27c /* QUSB2PHY_DEBUG_CTRL1 */
			 0x280 /* QUSB2PHY_DEBUG_CTRL2 */
			 0x2a0>; /* QUSB2PHY_STAT5 */

		qcom,qusb-phy-init-seq =
			/* <value reg_offset> */
+41 −13
Original line number Diff line number Diff line
@@ -76,6 +76,12 @@
/* PERIPH_SS_PHY_REFGEN_NORTH_BG_CTRL register bits */
#define BANDGAP_BYPASS			BIT(0)

/* DEBUG_CTRL2 register value to program VSTATUS MUX for PHY status */
#define DEBUG_CTRL2_MUX_PLL_LOCK_STATUS	0x4

/* STAT5 register bits */
#define VSTATUS_PLL_LOCK_STATUS_MASK	BIT(0)

enum qusb_phy_reg {
	PORT_TUNE1,
	PLL_COMMON_STATUS_ONE,
@@ -87,6 +93,8 @@ enum qusb_phy_reg {
	SQ_CTRL1,
	SQ_CTRL2,
	DEBUG_CTRL1,
	DEBUG_CTRL2,
	STAT5,
	USB2_PHY_REG_MAX,
};

@@ -470,6 +478,18 @@ static void qusb_phy_reset(struct qusb_phy *qphy)
							__func__);
}

static bool qusb_phy_pll_locked(struct qusb_phy *qphy)
{
	u32 val;

	writel_relaxed(DEBUG_CTRL2_MUX_PLL_LOCK_STATUS,
		       qphy->base + qphy->phy_reg[DEBUG_CTRL2]);

	val = readl_relaxed(qphy->base + qphy->phy_reg[STAT5]);

	return (val & VSTATUS_PLL_LOCK_STATUS_MASK);
}

static void qusb_phy_host_init(struct usb_phy *phy)
{
	u8 reg;
@@ -748,18 +768,12 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
			writel_relaxed(intr_mask,
				qphy->base + qphy->phy_reg[INTR_CTRL]);

			/* hold core PLL into reset */
			writel_relaxed(CORE_PLL_EN_FROM_RESET |
				CORE_RESET | CORE_RESET_MUX,
				qphy->base +
				qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);

			if (linestate & (LINESTATE_DP | LINESTATE_DM)) {
				/* enable phy auto-resume */
				writel_relaxed(0x91,
					qphy->base + qphy->phy_reg[TEST1]);
				/* flush the previous write before next write */
				wmb();
				/* Delay recommended between TEST1 writes */
				usleep_range(10, 20);
				writel_relaxed(0x90,
					qphy->base + qphy->phy_reg[TEST1]);
			}
@@ -788,12 +802,26 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
			writel_relaxed(0x00,
				qphy->base + qphy->phy_reg[INTR_CTRL]);

			/* Reset PLL if needed */
			if (!qusb_phy_pll_locked(qphy)) {
				dev_dbg(phy->dev, "%s: reset PLL\n", __func__);
				/* hold core PLL into reset */
				writel_relaxed(CORE_PLL_EN_FROM_RESET |
					CORE_RESET | CORE_RESET_MUX,
					qphy->base +
					qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);

				/* Wait for PLL to get reset */
				usleep_range(10, 20);

				/* bring core PLL out of reset */
			writel_relaxed(CORE_PLL_EN_FROM_RESET, qphy->base +
				writel_relaxed(CORE_PLL_EN_FROM_RESET,
					qphy->base +
					qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);

				/* Makes sure that above write goes through */
				wmb();
			}
		} else { /* Cable connect case */
			qusb_phy_enable_clocks(qphy, true);
		}