msm: clock-pll: Support dynamically mapped register space
Clock controller registers may be dynamically mapped into
memory in some clock drivers. Since those drivers are still
expected to re-use clock-pll code, support dynamically
mapped register spaces.
Change-Id: Iaf07f213d2bef64a68564b698a2536e611d724bd
Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index eb980e8..e83f17a 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -36,6 +36,13 @@
#define PLL_RESET_N BIT(2)
#define PLL_MODE_MASK BM(3, 0)
+#define PLL_EN_REG(x) ((x)->base ? (*(x)->base + (u32)((x)->en_reg)) : \
+ ((x)->en_reg))
+#define PLL_STATUS_REG(x) ((x)->base ? (*(x)->base + (u32)((x)->status_reg)) : \
+ ((x)->status_reg))
+#define PLL_MODE_REG(x) ((x)->base ? (*(x)->base + (u32)((x)->mode_reg)) : \
+ ((x)->mode_reg))
+
static DEFINE_SPINLOCK(pll_reg_lock);
int pll_vote_clk_enable(struct clk *clk)
@@ -45,13 +52,13 @@
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
spin_lock_irqsave(&pll_reg_lock, flags);
- ena = readl_relaxed(pll->en_reg);
+ ena = readl_relaxed(PLL_EN_REG(pll));
ena |= pll->en_mask;
- writel_relaxed(ena, pll->en_reg);
+ writel_relaxed(ena, PLL_EN_REG(pll));
spin_unlock_irqrestore(&pll_reg_lock, flags);
/* Wait until PLL is enabled */
- while ((readl_relaxed(pll->status_reg) & pll->status_mask) == 0)
+ while ((readl_relaxed(PLL_STATUS_REG(pll)) & pll->status_mask) == 0)
cpu_relax();
return 0;
@@ -64,9 +71,9 @@
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
spin_lock_irqsave(&pll_reg_lock, flags);
- ena = readl_relaxed(pll->en_reg);
+ ena = readl_relaxed(PLL_EN_REG(pll));
ena &= ~(pll->en_mask);
- writel_relaxed(ena, pll->en_reg);
+ writel_relaxed(ena, PLL_EN_REG(pll));
spin_unlock_irqrestore(&pll_reg_lock, flags);
}
@@ -79,7 +86,7 @@
int pll_vote_clk_is_enabled(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
- return !!(readl_relaxed(pll->status_reg) & pll->status_mask);
+ return !!(readl_relaxed(PLL_STATUS_REG(pll)) & pll->status_mask);
}
struct clk_ops clk_ops_pll_vote = {
@@ -126,7 +133,7 @@
struct pll_clk *pll = to_pll_clk(clk);
spin_lock_irqsave(&pll_reg_lock, flags);
- __pll_clk_enable_reg(pll->mode_reg);
+ __pll_clk_enable_reg(PLL_MODE_REG(pll));
spin_unlock_irqrestore(&pll_reg_lock, flags);
return 0;
@@ -149,7 +156,7 @@
* the bypass mode, and assert the reset.
*/
spin_lock_irqsave(&pll_reg_lock, flags);
- __pll_clk_disable_reg(pll->mode_reg);
+ __pll_clk_disable_reg(PLL_MODE_REG(pll));
spin_unlock_irqrestore(&pll_reg_lock, flags);
}
@@ -166,10 +173,10 @@
struct pll_clk *pll = to_pll_clk(clk);
spin_lock_irqsave(&pll_reg_lock, flags);
- mode = readl_relaxed(pll->mode_reg);
+ mode = readl_relaxed(PLL_MODE_REG(pll));
/* De-assert active-low PLL reset. */
mode |= PLL_RESET_N;
- writel_relaxed(mode, pll->mode_reg);
+ writel_relaxed(mode, PLL_MODE_REG(pll));
/*
* H/W requires a 5us delay between disabling the bypass and
@@ -180,7 +187,7 @@
/* Disable PLL bypass mode. */
mode |= PLL_BYPASSNL;
- writel_relaxed(mode, pll->mode_reg);
+ writel_relaxed(mode, PLL_MODE_REG(pll));
/* Wait until PLL is locked. */
mb();
@@ -188,7 +195,7 @@
/* Enable PLL output. */
mode |= PLL_OUTCTRL;
- writel_relaxed(mode, pll->mode_reg);
+ writel_relaxed(mode, PLL_MODE_REG(pll));
/* Ensure that the write above goes through before returning. */
mb();
@@ -285,7 +292,7 @@
pll_control->pll[PLL_BASE + pll_id].votes |= BIT(1);
if (!pll_control->pll[PLL_BASE + pll_id].on) {
- __pll_clk_enable_reg(pll->mode_reg);
+ __pll_clk_enable_reg(PLL_MODE_REG(pll));
pll_control->pll[PLL_BASE + pll_id].on = 1;
}
@@ -303,7 +310,7 @@
pll_control->pll[PLL_BASE + pll_id].votes &= ~BIT(1);
if (pll_control->pll[PLL_BASE + pll_id].on
&& !pll_control->pll[PLL_BASE + pll_id].votes) {
- __pll_clk_disable_reg(pll->mode_reg);
+ __pll_clk_disable_reg(PLL_MODE_REG(pll));
pll_control->pll[PLL_BASE + pll_id].on = 0;
}
@@ -314,7 +321,7 @@
{
struct pll_shared_clk *pll = to_pll_shared_clk(clk);
- return readl_relaxed(pll->mode_reg) & BIT(0);
+ return readl_relaxed(PLL_MODE_REG(pll)) & BIT(0);
}
static enum handoff pll_clk_handoff(struct clk *clk)
@@ -327,7 +334,7 @@
* Wait for the PLLs to be initialized and then read their frequency.
*/
do {
- pll_lval = readl_relaxed(pll->mode_reg + 4) & 0x3ff;
+ pll_lval = readl_relaxed(PLL_MODE_REG(pll) + 4) & 0x3ff;
cpu_relax();
udelay(50);
} while (pll_lval == 0);
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index 7de81c9..26bfc68 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -40,6 +40,7 @@
unsigned int id;
void __iomem *const mode_reg;
struct clk c;
+ void *const __iomem *base;
};
extern struct clk_ops clk_pll_ops;
@@ -75,6 +76,7 @@
struct clk *parent;
struct clk c;
+ void *const __iomem *base;
};
extern struct clk_ops clk_ops_pll_vote;
@@ -95,6 +97,7 @@
struct clk *parent;
struct clk c;
+ void *const __iomem *base;
};
extern struct clk_ops clk_ops_local_pll;