[PATCH D 10/11] OMAP2/3 clock: clean up omap2_clk_wait_ready()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Simplify omap2_clk_wait_ready() to use the new idlest_bit field in
struct clk, rather than a hunk of conditionals.

Others who have contributed to the patches in this rollup by reporting
bugs, testing, or reviewing include:
- Anand Gadiyar <gadiyar@xxxxxx>
- Koen Kooi <k.kooi@xxxxxxxxxxxxxxxxxx>
- Dirk Behme <dirk.behme@xxxxxxxxxxxxxx>
- Igor Stoppa <igor.stoppa@xxxxxxxxx>
- Richard Woodruff <r-woodruff2@xxxxxx>
- Jouni Högander <jouni.hogander@xxxxxxxxx>

More information can be found at the original source commits below.

linux-omap source commits are 999ccb505e4fa5720add74589fe747affcd7aa81,
f4c458db2b615037f7c1fd91d238f6420e7b8f77,
e2d8a430aab87fdc47b7f01de804e17b8960042d,
201fb6b950b41a798aa54ee78588ac68aed28a0a,
205f37af718984ec67444bccc888cd575531bce1,
0fe3bd3fb03ab35063b1d17070b24bfa007896c3,
3fa8636974ca1c04797781fb300c2e29ec18c3a8,
6f55ed7c13d655189da305207cf323041e4bcc4d, and
fd183f64d5325d727124d88c50b401a7da9c89c1.

Signed-off-by: Paul Walmsley <paul@xxxxxxxxx>
Signed-off-by: Tony Lindgren <tony@xxxxxxxxxxx>
Cc: Anand Gadiyar <gadiyar@xxxxxx>
Cc: Koen Kooi <k.kooi@xxxxxxxxxxxxxxxxxx>
Cc: Dirk Behme <dirk.behme@xxxxxxxxxxxxxx>
Cc: Igor Stoppa <igor.stoppa@xxxxxxxxx>
Cc: Richard Woodruff <r-woodruff2@xxxxxx>
Cc: Jouni Högander <jouni.hogander@xxxxxxxxx>
---
 arch/arm/mach-omap2/clock.c     |   93 ++++++++++++++++++++-------------------
 arch/arm/mach-omap2/clock.h     |    3 +
 arch/arm/mach-omap2/clock24xx.c |   10 ----
 3 files changed, 51 insertions(+), 55 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index dff4eaa..0cd4761 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -70,6 +70,13 @@
 #define DPLL_FINT_UNDERFLOW		-1
 #define DPLL_FINT_INVALID		-2
 
+/* Bitmask to isolate the register type of clk.enable_reg */
+#define PRCM_REGTYPE_MASK		0xf0
+/* various CM register type options */
+#define CM_FCLKEN_REGTYPE		0x00
+#define CM_ICLKEN_REGTYPE		0x10
+#define CM_IDLEST_REGTYPE		0x20
+
 u8 cpu_mask;
 
 /*-------------------------------------------------------------------------
@@ -300,17 +307,18 @@ void omap2_fixed_divisor_recalc(struct clk *clk)
 
 /**
  * omap2_wait_clock_ready - wait for clock to enable
- * @reg: physical address of clock IDLEST register
+ * @prcm_mod: CM submodule offset from CM_BASE (e.g., "MPU_MOD")
+ * @reg_index: offset of CM register address from prcm_mod
  * @mask: value to mask against to determine if the clock is active
  * @name: name of the clock (for printk)
  *
  * Returns 1 if the clock enabled in time, or 0 if it failed to enable
  * in roughly MAX_CLOCK_ENABLE_WAIT microseconds.
  */
-int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
+int omap2_wait_clock_ready(s16 prcm_mod, u16 reg_index, u32 mask,
+			   const char *name)
 {
-	int i = 0;
-	int ena = 0;
+	int i = 0, ena = 0;
 
 	/*
 	 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
@@ -322,7 +330,7 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
 		ena = 0;
 
 	/* Wait for lock */
-	while (((__raw_readl(reg) & mask) != ena) &&
+	while (((cm_read_mod_reg(prcm_mod, reg_index) & mask) != ena) &&
 	       (i++ < MAX_CLOCK_ENABLE_WAIT)) {
 		udelay(1);
 	}
@@ -333,61 +341,56 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
 		printk(KERN_ERR "Clock %s didn't enable in %d tries\n",
 		       name, MAX_CLOCK_ENABLE_WAIT);
 
-
 	return (i < MAX_CLOCK_ENABLE_WAIT) ? 1 : 0;
 };
 
 
 /*
- * Note: We don't need special code here for INVERT_ENABLE
- * for the time being since INVERT_ENABLE only applies to clocks enabled by
- * CM_CLKEN_PLL
+ * omap2_clk_wait_ready - wait for a OMAP module to come out of target idle
+ * @clk: struct clk * recently enabled to indicate the module to test
+ *
+ * Wait for an OMAP module with a target idle state bit to come out of
+ * idle once both its interface clock and primary functional clock are
+ * both enabled.  Any register read or write to the device before it
+ * returns from idle will cause an abort.  Not all modules have target
+ * idle state bits (for example, DSS and CAM on OMAP24xx); so we don't
+ * wait for those.  No return value.
+ *
+ * We don't need special code here for INVERT_ENABLE for the time
+ * being since INVERT_ENABLE only applies to clocks enabled by
+ * CM_CLKEN_PLL.
+ *
+ * REVISIT: This function is misnamed: it should be something like
+ * "omap2_module_wait_ready", and in the long-term, it does not belong
+ * in the clock framework. It also shouldn't be doing register
+ * arithmetic to determine the companion clock.
  */
 static void omap2_clk_wait_ready(struct clk *clk)
 {
-	void __iomem *other_reg, *st_reg;
-	u16 reg;
-	u32 bit;
+	u16 other_reg, idlest_reg;
+	u32 other_bit;
 
-	/*
-	 * REVISIT: This code is pretty ugly.  It would be nice to generalize
-	 * it and pull it into struct clk itself somehow.
-	 */
-	reg = clk->enable_reg;
-	if (((reg & 0xff) >= CM_FCLKEN1) &&
-	    ((reg & 0xff) <= OMAP24XX_CM_FCLKEN2))
-		other_reg = (void __iomem *)((reg & ~0xf0) | 0x10); /* CM_ICLKEN* */
-	else if (((reg & 0xff) >= CM_ICLKEN1) &&
-		 ((reg & 0xff) <= OMAP24XX_CM_ICLKEN4))
-		other_reg = (void __iomem *)((reg & ~0xf0) | 0x00); /* CM_FCLKEN* */
-	else
+	if (!(clk->flags & WAIT_READY))
 		return;
 
-	/* REVISIT: What are the appropriate exclusions for 34XX? */
-	/* No check for DSS or cam clocks */
-	if (cpu_is_omap24xx() && (reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */
-		if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT ||
-		    clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT ||
-		    clk->enable_bit == OMAP24XX_EN_CAM_SHIFT)
-			return;
-	}
+	/* If we are enabling an iclk, also test the fclk; and vice versa */
+	other_bit = 1 << clk->enable_bit;
+	other_reg = clk->enable_reg & ~PRCM_REGTYPE_MASK;
 
-	/* REVISIT: What are the appropriate exclusions for 34XX? */
-	/* OMAP3: ignore DSS-mod clocks */
-	if (cpu_is_omap34xx() &&
-	    ((reg & ~0xff) == cm_read_mod_reg(OMAP3430_DSS_MOD, 0) ||
-	     (((reg & ~0xff) == cm_read_mod_reg(CORE_MOD, 0)) &&
-	      clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
-		return;
+	if (clk->enable_reg & CM_ICLKEN_REGTYPE)
+		other_reg |= CM_FCLKEN_REGTYPE;
+	else
+		other_reg |= CM_ICLKEN_REGTYPE;
 
-	/* Check if both functional and interface clocks
-	 * are running. */
-	bit = 1 << clk->enable_bit;
-	if (!(__raw_readl(other_reg) & bit))
+	/* Ensure functional and interface clocks are running. */
+	if (!(cm_read_mod_reg(clk->prcm_mod, other_reg) & other_bit))
 		return;
-	st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */
 
-	omap2_wait_clock_ready(st_reg, bit, clk->name);
+	idlest_reg = other_reg & ~PRCM_REGTYPE_MASK;
+	idlest_reg |= CM_IDLEST_REGTYPE;
+
+	omap2_wait_clock_ready(clk->prcm_mod, idlest_reg, 1 << clk->idlest_bit,
+			       clk->name);
 }
 
 /* Enables clock without considering parent dependencies or use count
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 4dbd582..faff95e 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -64,7 +64,8 @@ void omap2_fixed_divisor_recalc(struct clk *clk);
 long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
 int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
 u32 omap2_get_dpll_rate(struct clk *clk);
-int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
+int omap2_wait_clock_ready(s16 prcm_mod, u16 idlest_reg, u32 cval,
+			   const char *name);
 void omap2_clk_prepare_for_reboot(void);
 
 extern u8 cpu_mask;
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index 2047c06..e66287f 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -107,7 +107,6 @@ static void omap2_disable_osc_ck(struct clk *clk)
 static int omap2_clk_fixed_enable(struct clk *clk)
 {
 	u32 cval, apll_mask;
-	void __iomem *idlest;
 
 	apll_mask = EN_APLL_LOCKED << clk->enable_bit;
 
@@ -125,14 +124,7 @@ static int omap2_clk_fixed_enable(struct clk *clk)
 	else if (clk == &apll54_ck)
 		cval = OMAP24XX_ST_54M_APLL;
 
-	if (cpu_is_omap242x())
-		idlest = (__force void __iomem *)OMAP2420_CM_REGADDR(PLL_MOD,
-								CM_IDLEST);
-	else
-		idlest = (__force void __iomem *)OMAP2430_CM_REGADDR(PLL_MOD,
-								CM_IDLEST);
-
-	omap2_wait_clock_ready(idlest, cval, clk->name);
+	omap2_wait_clock_ready(PLL_MOD, CM_IDLEST, cval, clk->name);
 
 	/*
 	 * REVISIT: Should we return an error code if omap2_wait_clock_ready()


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux