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;