msm: clock: Add handoff functions for most PLL clock types
This allows PLL clock state to be handed off, similar to what's
done for other branch and RCG clock types.
This currently omits a handoff function for clk_ops_hdmi_pll,
which has a significantly different implementation. It will be
added at a later time.
Change-Id: I9e74737134c515abc0baff5d990217fd136a7266
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 6972302..7aed579 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -363,11 +363,22 @@
return false;
}
+static enum handoff pll4_clk_handoff(struct clk *clk)
+{
+ struct msm_rpm_iv_pair iv = { MSM_RPM_ID_PLL_4 };
+ int rc = msm_rpm_get_status(&iv, 1);
+ if (rc < 0 || !iv.value)
+ return HANDOFF_DISABLED_CLK;
+
+ return HANDOFF_ENABLED_CLK;
+}
+
static struct clk_ops clk_ops_pll4 = {
.enable = pll4_clk_enable,
.disable = pll4_clk_disable,
.get_parent = pll4_clk_get_parent,
.is_local = pll4_clk_is_local,
+ .handoff = pll4_clk_handoff,
};
static struct fixed_clk pll4_clk = {
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index 48a3409..d839911 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -110,12 +110,22 @@
return !!(readl_relaxed(PLL_STATUS_REG(pll)) & pll->status_mask);
}
+static enum handoff pll_vote_clk_handoff(struct clk *clk)
+{
+ struct pll_vote_clk *pll = to_pll_vote_clk(clk);
+ if (readl_relaxed(PLL_EN_REG(pll)) & pll->en_mask)
+ return HANDOFF_ENABLED_CLK;
+
+ return HANDOFF_DISABLED_CLK;
+}
+
struct clk_ops clk_ops_pll_vote = {
.enable = pll_vote_clk_enable,
.disable = pll_vote_clk_disable,
.auto_off = pll_vote_clk_disable,
.is_enabled = pll_vote_clk_is_enabled,
.get_parent = pll_vote_clk_get_parent,
+ .handoff = pll_vote_clk_handoff,
};
static void __pll_clk_enable_reg(void __iomem *mode_reg)
@@ -181,6 +191,18 @@
spin_unlock_irqrestore(&pll_reg_lock, flags);
}
+static enum handoff local_pll_clk_handoff(struct clk *clk)
+{
+ struct pll_clk *pll = to_pll_clk(clk);
+ u32 mode = readl_relaxed(PLL_MODE_REG(pll));
+ u32 mask = PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL;
+
+ if ((mode & mask) == mask)
+ return HANDOFF_ENABLED_CLK;
+
+ return HANDOFF_DISABLED_CLK;
+}
+
static struct clk *local_pll_clk_get_parent(struct clk *clk)
{
struct pll_clk *pll = to_pll_clk(clk);
@@ -281,6 +303,7 @@
.enable = local_pll_clk_enable,
.disable = local_pll_clk_disable,
.auto_off = local_pll_clk_disable,
+ .handoff = local_pll_clk_handoff,
.get_parent = local_pll_clk_get_parent,
};