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

Commit a19c6663 authored by Vikram Mulukutla's avatar Vikram Mulukutla
Browse files

clk: qcom: clock-pll: Account for "transient" PLL locks



On the MSM8994, the four Veyron PLLs seem to exhibit
a peculiar problem where the lock detect bit is set
early and then "flips back", i.e. the lock is lost
again. Around 50us later, the lock detect bit is set
again, and is then stable.

Workaround this problem by increasing the delay after
setting RESET_NL to 50us. Furthermore, in the lock
detection loop, after a lock is detected, delay for 1us
and check again - if the lock bit is not set, continue
the loop until it is set.

Change-Id: I01b50ee67afc510eedea2f3d310aa0e35f7d504a
Signed-off-by: default avatarVikram Mulukutla <markivx@codeaurora.org>
parent 069f11cb
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -289,9 +289,14 @@ static int variable_rate_pll_clk_enable(struct clk *c)
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* 5us delay mandated by HPG. Use 10 to be sure. */
	/*
	 * 5us delay mandated by HPG. However, put in a 50us delay here.
	 * This is to address possible locking issues with the PLL exhibit
	 * early "transient" locks about 16us from this point. With this
	 * higher delay, we avoid running into those transients.
	 */
	mb();
	udelay(10);
	udelay(50);

	/* Clear test control bits */
	if (pll->test_ctl_lo_reg && pll->vals.test_ctl_lo_val &&
@@ -300,8 +305,16 @@ static int variable_rate_pll_clk_enable(struct clk *c)

	/* Wait for pll to lock. */
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & lockmask)
		if (readl_relaxed(PLL_STATUS_REG(pll)) & lockmask) {
			udelay(1);
			/*
			 * Check again to be sure. This is to avoid
			 * breaking too early if there is a "transient"
			 * lock.
			 */
			if ((readl_relaxed(PLL_STATUS_REG(pll)) & lockmask))
				break;
		}
		udelay(1);
	}