public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree
@ 2008-09-16 12:16 Paul Walmsley
  2008-09-16 12:16 ` [PATCH 1/6] OMAP2/3 clock: convert dpll_data.idlest_bit to idlest_mask Paul Walmsley
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Paul Walmsley @ 2008-09-16 12:16 UTC (permalink / raw)
  To: linux-omap

Previously, the OMAP3 clock tree handled DPLL bypass rate
recalculation by dynamically switching clock parents depending on the
DPLL bypass state.  It used the clksel mechanism for this.
Unfortunately, this does not actually work.  The clock code expects
the clock's parent to be the one set in the struct clk, causing kernel
messages similar to:

clock: Could not find fieldval 0 for clock iva2_ck parent dpll2_m2_ck

This patch series moves DPLL bypass rate computation into
omap2_get_dpll_rate(), and removes most of the bypass clocks in the clock tree.
It also converts the bypass tests in the code to use the DPLL IDLEST bits
rather than the DPLL CLKEN bits.

Problem reported by Ramesh Gupta Guntha <x0023949@ti.com>.

Bypass rate recalculation verified with DPLL1 on 3430SDP, which
has bypass support built into its clock code.  Boot-tested on 2430SDP.

---

  text    data     bss     dec     hex filename
3458200  160384  106600 3725184  38d780 vmlinux.3430sdp.orig
3457748  160200  106600 3724548  38d504 vmlinux.3430sdp

 arch/arm/mach-omap2/clock.c             |   45 +++++++-
 arch/arm/mach-omap2/clock24xx.c         |    4 +
 arch/arm/mach-omap2/clock24xx.h         |    2 
 arch/arm/mach-omap2/clock34xx.c         |   60 +++++++---
 arch/arm/mach-omap2/clock34xx.h         |  179 +++----------------------------
 arch/arm/plat-omap/include/mach/clock.h |    4 -
 6 files changed, 105 insertions(+), 189 deletions(-)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] OMAP2/3 clock: convert dpll_data.idlest_bit to idlest_mask
  2008-09-16 12:16 [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree Paul Walmsley
@ 2008-09-16 12:16 ` Paul Walmsley
  2008-09-16 12:16 ` [PATCH 2/6] OMAP3 clock: add idlest_reg, idlest_mask for DPLL3 Paul Walmsley
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Walmsley @ 2008-09-16 12:16 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

Convert struct dpll_data.idlest_bit field to idlest_mask.  Needed since
later patches are converting the DPLL bypass state test to use the IDLEST
registers, and OMAP2 uses two bits for DPLL IDLEST rather than one.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c         |    6 ++----
 arch/arm/mach-omap2/clock34xx.h         |    8 ++++----
 arch/arm/plat-omap/include/mach/clock.h |    4 ++--
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 152d095..c5765bf 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -78,14 +78,12 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
 	const struct dpll_data *dd;
 	int i = 0;
 	int ret = -EINVAL;
-	u32 idlest_mask;
 
 	dd = clk->dpll_data;
 
-	state <<= dd->idlest_bit;
-	idlest_mask = 1 << dd->idlest_bit;
+	state <<= __ffs(dd->idlest_mask);
 
-	while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) &&
+	while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
 	       i < MAX_DPLL_WAIT_TRIES) {
 		i++;
 		udelay(1);
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 41f91f8..044a3ff 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -310,7 +310,7 @@ static struct dpll_data dpll1_dd = {
 	.autoidle_reg	= _OMAP34XX_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
 	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
 	.idlest_reg	= _OMAP34XX_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_bit	= OMAP3430_ST_MPU_CLK_SHIFT,
+	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
 	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
@@ -382,7 +382,7 @@ static struct dpll_data dpll2_dd = {
 	.autoidle_reg	= _OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
 	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
 	.idlest_reg	= _OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_bit	= OMAP3430_ST_IVA2_CLK_SHIFT,
+	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
 	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
@@ -628,7 +628,7 @@ static struct dpll_data dpll4_dd = {
 	.autoidle_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
 	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
 	.idlest_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_bit	= OMAP3430_ST_PERIPH_CLK_SHIFT,
+	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
 	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
@@ -968,7 +968,7 @@ static struct dpll_data dpll5_dd = {
 	.autoidle_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
 	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
 	.idlest_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-	.idlest_bit	= OMAP3430ES2_ST_PERIPH2_CLK_SHIFT,
+	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
 	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
index c6762e9..666f52b 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -41,6 +41,8 @@ struct dpll_data {
 	u16			max_multiplier;
 	u8			max_divider;
 	u32			max_tolerance;
+	void __iomem		*idlest_reg;
+	u32			idlest_mask;
 #  if defined(CONFIG_ARCH_OMAP3)
 	u32			freqsel_mask;
 	u8			modes;
@@ -51,8 +53,6 @@ struct dpll_data {
 	u8			recal_st_bit;
 	void __iomem		*autoidle_reg;
 	u32			autoidle_mask;
-	void __iomem		*idlest_reg;
-	u8			idlest_bit;
 #  endif
 };
 



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] OMAP3 clock: add idlest_reg, idlest_mask for DPLL3
  2008-09-16 12:16 [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree Paul Walmsley
  2008-09-16 12:16 ` [PATCH 1/6] OMAP2/3 clock: convert dpll_data.idlest_bit to idlest_mask Paul Walmsley
@ 2008-09-16 12:16 ` Paul Walmsley
  2008-09-16 12:16 ` [PATCH 3/6] OMAP2/3 clock: move DPLL bypass rate calculation into omap2_get_dpll_rate() Paul Walmsley
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Walmsley @ 2008-09-16 12:16 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

DPLL3 dpll_data was missing idlest_* fields - add them.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 044a3ff..19c3881 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -441,6 +441,8 @@ static struct dpll_data dpll3_dd = {
 	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
 	.autoidle_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
 	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
+	.idlest_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
 	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/6] OMAP2/3 clock: move DPLL bypass rate calculation into omap2_get_dpll_rate()
  2008-09-16 12:16 [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree Paul Walmsley
  2008-09-16 12:16 ` [PATCH 1/6] OMAP2/3 clock: convert dpll_data.idlest_bit to idlest_mask Paul Walmsley
  2008-09-16 12:16 ` [PATCH 2/6] OMAP3 clock: add idlest_reg, idlest_mask for DPLL3 Paul Walmsley
@ 2008-09-16 12:16 ` Paul Walmsley
  2008-09-16 12:16 ` [PATCH 4/6] OMAP3 clock: omap3_clkoutx2_recalc() should test DPLL IDLEST to determine if DPLL is bypassed Paul Walmsley
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Walmsley @ 2008-09-16 12:16 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

Removes the clksel-based DPLL rate handling from the OMAP3 clock tree.
In its place, omap2_get_dpll_rate() now has code to determine whether the DPLL
is bypassed.  This obsoletes several clocks, which are removed by this patch.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock.c     |   45 +++++++++-
 arch/arm/mach-omap2/clock24xx.c |    4 +
 arch/arm/mach-omap2/clock24xx.h |    2 
 arch/arm/mach-omap2/clock34xx.h |  169 +++------------------------------------
 4 files changed, 58 insertions(+), 162 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 5f48e14..a2211fb 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -60,6 +60,10 @@
 #define DPLL_ROUNDING_VAL		((DPLL_SCALE_BASE / 2) * \
 					 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
 
+/* Some OMAP2xxx CM_CLKSEL_PLL.ST_CORE_CLK bits - for omap2_get_dpll_rate() */
+#define ST_CORE_CLK_REF			0x1
+#define ST_CORE_CLK_32K			0x3
+
 u8 cpu_mask;
 
 /*-------------------------------------------------------------------------
@@ -137,22 +141,51 @@ void omap2_init_clksel_parent(struct clk *clk)
 	return;
 }
 
-/* Returns the DPLL rate */
+/**
+ * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
+ * @clk: struct clk * of a DPLL
+ *
+ * DPLLs can be locked or bypassed - basically, enabled or disabled.
+ * When locked, the DPLL output depends on the M and N values.  When
+ * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
+ * or sys_clk.  Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
+ * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
+ * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
+ * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
+ * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
+ * if the clock @clk is not a DPLL.
+ */
 u32 omap2_get_dpll_rate(struct clk *clk)
 {
 	long long dpll_clk;
-	u32 dpll_mult, dpll_div, dpll;
+	u32 dpll_mult, dpll_div, v;
 	struct dpll_data *dd;
 
 	dd = clk->dpll_data;
-	/* REVISIT: What do we return on error? */
 	if (!dd)
 		return 0;
 
-	dpll = __raw_readl(dd->mult_div1_reg);
-	dpll_mult = dpll & dd->mult_mask;
+	/* Return bypass rate if DPLL is bypassed */
+	v = __raw_readl(dd->idlest_reg) & dd->idlest_mask;
+	v >>= __ffs(dd->idlest_mask);
+	if (cpu_is_omap24xx()) {
+
+		if (v == ST_CORE_CLK_REF)
+			return clk->parent->rate; /* sys_clk */
+		else if (v == ST_CORE_CLK_32K)
+			return 32768;
+
+	} else if (cpu_is_omap34xx()) {
+
+		if (!v)
+			return clk->parent->rate;
+
+	}
+
+	v = __raw_readl(dd->mult_div1_reg);
+	dpll_mult = v & dd->mult_mask;
 	dpll_mult >>= __ffs(dd->mult_mask);
-	dpll_div = dpll & dd->div1_mask;
+	dpll_div = v & dd->div1_mask;
 	dpll_div >>= __ffs(dd->div1_mask);
 
 	dpll_clk = (long long)clk->parent->rate * dpll_mult;
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index c26d9d8..ddb6429 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -535,8 +535,10 @@ static void __init omap2_clk_rewrite_base(struct clk *clk)
 {
 	omap2_clk_check_reg(clk->flags, &clk->clksel_reg);
 	omap2_clk_check_reg(clk->flags, &clk->enable_reg);
-	if (clk->dpll_data)
+	if (clk->dpll_data) {
 		omap2_clk_check_reg(0, &clk->dpll_data->mult_div1_reg);
+		omap2_clk_check_reg(0, &clk->dpll_data->idlest_reg);
+	}
 }
 
 int __init omap2_clk_init(void)
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
index 63349fa..775d08b 100644
--- a/arch/arm/mach-omap2/clock24xx.h
+++ b/arch/arm/mach-omap2/clock24xx.h
@@ -682,6 +682,8 @@ static struct dpll_data dpll_dd = {
 	.mult_div1_reg		= _CM_REG_OFFSET(PLL_MOD, CM_CLKSEL1),
 	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
 	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
+	.idlest_reg		= _CM_REG_OFFSET(PLL_MOD, CM_IDLEST),
+	.idlest_mask		= OMAP24XX_ST_CORE_CLK_MASK,
 	.max_multiplier		= 1024,
 	.max_divider		= 16,
 	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 19c3881..3ee60bc 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -257,16 +257,6 @@ static struct clk sys_clkout1 = {
 
 /* CM CLOCKS */
 
-static const struct clksel_rate dpll_bypass_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dpll_locked_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
 static const struct clksel_rate div16_dpll_rates[] = {
 	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
 	{ .div = 2, .val = 2, .flags = RATE_IN_343X },
@@ -527,40 +517,22 @@ static struct clk dpll3_m2_ck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
-static const struct clksel core_ck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll3_m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk core_ck = {
 	.name		= "core_ck",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.clksel		= core_ck_clksel,
+	.parent		= &dpll3_m2_ck,
 	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
 				PARENT_CONTROLS_CLOCK,
 	.clkdm		= { .name = "cm_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel dpll3_m2x2_ck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll3_x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
+	.recalc		= &followparent_recalc,
 };
 
 static struct clk dpll3_m2x2_ck = {
 	.name		= "dpll3_m2x2_ck",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.clksel		= dpll3_m2x2_ck_clksel,
+	.parent		= &dpll3_x2_ck,
 	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
 				PARENT_CONTROLS_CLOCK,
 	.clkdm		= { .name = "dpll3_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 /* The PWRDN bit is apparently only available on 3430ES2 and above */
@@ -594,23 +566,13 @@ static struct clk dpll3_m3x2_ck = {
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
-static const struct clksel emu_core_alwon_ck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk emu_core_alwon_ck = {
 	.name		= "emu_core_alwon_ck",
 	.parent		= &dpll3_m3x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.clksel		= emu_core_alwon_ck_clksel,
 	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
 				PARENT_CONTROLS_CLOCK,
 	.clkdm		= { .name = "dpll3_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 /* DPLL4 */
@@ -693,12 +655,6 @@ static struct clk dpll4_m2x2_ck = {
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
-static const struct clksel omap_96m_alwon_fck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 /*
  * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
  * PRM_96M_ALWON_(F)CLK.  Two clocks then emerge from the PRM:
@@ -708,14 +664,10 @@ static const struct clksel omap_96m_alwon_fck_clksel[] = {
 static struct clk omap_96m_alwon_fck = {
 	.name		= "omap_96m_alwon_fck",
 	.parent		= &dpll4_m2x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= omap_96m_alwon_fck_clksel,
 	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
 				PARENT_CONTROLS_CLOCK,
 	.clkdm		= { .name = "prm_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 static struct clk cm_96m_fck = {
@@ -782,25 +734,6 @@ static struct clk dpll4_m3x2_ck = {
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
-static const struct clksel virt_omap_54m_fck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
-static struct clk virt_omap_54m_fck = {
-	.name		= "virt_omap_54m_fck",
-	.parent		= &dpll4_m3x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= virt_omap_54m_fck_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
-	.clkdm		= { .name = "dpll4_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
-};
-
 static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
 	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
 	{ .div = 0 }
@@ -812,7 +745,7 @@ static const struct clksel_rate omap_54m_alt_rates[] = {
 };
 
 static const struct clksel omap_54m_clksel[] = {
-	{ .parent = &virt_omap_54m_fck, .rates = omap_54m_d4m3x2_rates },
+	{ .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
 	{ .parent = &sys_altclk,    .rates = omap_54m_alt_rates },
 	{ .parent = NULL }
 };
@@ -1007,25 +940,6 @@ static struct clk dpll5_m2_ck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
-static const struct clksel omap_120m_fck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll5_m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_120m_fck = {
-	.name		= "omap_120m_fck",
-	.parent		= &dpll5_m2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-	.clksel_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
-	.clksel		= omap_120m_fck_clksel,
-	.flags		= CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
-	.clkdm		= { .name = "dpll5_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
-};
-
 /* CM EXTERNAL CLOCK OUTPUTS */
 
 static const struct clksel_rate clkout2_src_core_rates[] = {
@@ -1132,29 +1046,13 @@ static struct clk dpll1_fck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
-/*
- * MPU clksel:
- * If DPLL1 is locked, mpu_ck derives from DPLL1; otherwise, mpu_ck
- * derives from the high-frequency bypass clock originating from DPLL3,
- * called 'dpll1_fck'
- */
-static const struct clksel mpu_clksel[] = {
-	{ .parent = &dpll1_fck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk mpu_ck = {
 	.name		= "mpu_ck",
 	.parent		= &dpll1_x2m2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.clksel_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.clksel		= mpu_clksel,
 	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
 				PARENT_CONTROLS_CLOCK,
 	.clkdm		= { .name = "mpu_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 /* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
@@ -1210,32 +1108,15 @@ static struct clk dpll2_fck = {
 	.recalc		= &omap2_clksel_recalc,
 };
 
-/*
- * IVA2 clksel:
- * If DPLL2 is locked, iva2_ck derives from DPLL2; otherwise, iva2_ck
- * derives from the high-frequency bypass clock originating from DPLL3,
- * called 'dpll2_fck'
- */
-
-static const struct clksel iva2_clksel[] = {
-	{ .parent = &dpll2_fck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll2_m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk iva2_ck = {
 	.name		= "iva2_ck",
 	.parent		= &dpll2_m2_ck,
 	.init		= &omap2_init_clksel_parent,
 	.enable_reg	= _OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD,
-					  OMAP3430_CM_IDLEST_PLL),
-	.clksel_mask	= OMAP3430_ST_IVA2_CLK_MASK,
-	.clksel		= iva2_clksel,
 	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
 	.clkdm		= { .name = "iva2_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 /* Common interface clocks */
@@ -1467,7 +1348,7 @@ static struct clk ts_fck = {
 
 static struct clk usbtll_fck = {
 	.name		= "usbtll_fck",
-	.parent		= &omap_120m_fck,
+	.parent		= &dpll5_m2_ck,
 	.enable_reg	= _OMAP34XX_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
 	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
 	.flags		= CLOCK_IN_OMAP3430ES2,
@@ -2203,24 +2084,14 @@ static struct clk des1_ick = {
 };
 
 /* DSS */
-static const struct clksel dss1_alwon_fck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk dss1_alwon_fck = {
 	.name		= "dss1_alwon_fck",
 	.parent		= &dpll4_m4x2_ck,
-	.init		= &omap2_init_clksel_parent,
 	.enable_reg	= _OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= dss1_alwon_fck_clksel,
 	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm		= { .name = "dss_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 static struct clk dss_tv_fck = {
@@ -2266,24 +2137,14 @@ static struct clk dss_ick = {
 
 /* CAM */
 
-static const struct clksel cam_mclk_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk cam_mclk = {
 	.name		= "cam_mclk",
 	.parent		= &dpll4_m5x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= cam_mclk_clksel,
 	.enable_reg	= _OMAP34XX_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
 	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm		= { .name = "cam_clkdm" },
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 static struct clk cam_ick = {
@@ -2311,7 +2172,7 @@ static struct clk csi2_96m_fck = {
 
 static struct clk usbhost_120m_fck = {
 	.name		= "usbhost_120m_fck",
-	.parent		= &omap_120m_fck,
+	.parent		= &dpll5_m2_ck,
 	.enable_reg	= _OMAP34XX_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
 	.flags		= CLOCK_IN_OMAP3430ES2,
@@ -2360,7 +2221,7 @@ static const struct clksel_rate usim_120m_rates[] = {
 
 static const struct clksel usim_clksel[] = {
 	{ .parent = &omap_96m_fck,	.rates = usim_96m_rates },
-	{ .parent = &omap_120m_fck,	.rates = usim_120m_rates },
+	{ .parent = &dpll5_m2_ck,	.rates = usim_120m_rates },
 	{ .parent = &sys_ck,		.rates = div2_rates },
 	{ .parent = NULL },
 };
@@ -3172,7 +3033,6 @@ static struct clk *onchip_34xx_clks[] __initdata = {
 	&omap_96m_alwon_fck,
 	&omap_96m_fck,
 	&cm_96m_fck,
-	&virt_omap_54m_fck,
 	&omap_54m_fck,
 	&omap_48m_fck,
 	&omap_12m_fck,
@@ -3189,7 +3049,6 @@ static struct clk *onchip_34xx_clks[] __initdata = {
 	&emu_per_alwon_ck,
 	&dpll5_ck,
 	&dpll5_m2_ck,
-	&omap_120m_fck,
 	&clkout2_src_ck,
 	&sys_clkout2,
 	&corex2_fck,



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/6] OMAP3 clock: omap3_clkoutx2_recalc() should test DPLL IDLEST to determine if DPLL is bypassed
  2008-09-16 12:16 [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree Paul Walmsley
                   ` (2 preceding siblings ...)
  2008-09-16 12:16 ` [PATCH 3/6] OMAP2/3 clock: move DPLL bypass rate calculation into omap2_get_dpll_rate() Paul Walmsley
@ 2008-09-16 12:16 ` Paul Walmsley
  2008-09-16 12:16 ` [PATCH 5/6] OMAP3 clock: DPLLs should enter bypass if new rate is sys_ck Paul Walmsley
  2008-09-16 12:16 ` [PATCH 6/6] OMAP3 clock: recalculate DPLL subtree after bypass entry/exit Paul Walmsley
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Walmsley @ 2008-09-16 12:16 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

Convert the DPLL bypass test in omap3_clkoutx2_recalc() to test DPLL IDLEST
bits rather than the CM_CLKEN register.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index c5765bf..6963f2e 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -577,11 +577,10 @@ static void omap3_clkoutx2_recalc(struct clk *clk)
 
 	dd = pclk->dpll_data;
 
-	WARN_ON(!dd->control_reg || !dd->enable_mask);
+	WARN_ON(!dd->idlest_reg || !dd->idlest_mask);
 
-	v = __raw_readl(dd->control_reg) & dd->enable_mask;
-	v >>= __ffs(dd->enable_mask);
-	if (v != DPLL_LOCKED)
+	v = __raw_readl(dd->idlest_reg) & dd->idlest_mask;
+	if (!v)
 		clk->rate = clk->parent->rate;
 	else
 		clk->rate = clk->parent->rate * 2;



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/6] OMAP3 clock: DPLLs should enter bypass if new rate is sys_ck
  2008-09-16 12:16 [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree Paul Walmsley
                   ` (3 preceding siblings ...)
  2008-09-16 12:16 ` [PATCH 4/6] OMAP3 clock: omap3_clkoutx2_recalc() should test DPLL IDLEST to determine if DPLL is bypassed Paul Walmsley
@ 2008-09-16 12:16 ` Paul Walmsley
  2008-09-16 12:16 ` [PATCH 6/6] OMAP3 clock: recalculate DPLL subtree after bypass entry/exit Paul Walmsley
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Walmsley @ 2008-09-16 12:16 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

This patch causes a DPLL to enter bypass when it is instructed to set
its rate to that of the parent clock.  Previously this was only possible
after setting the DPLL rate, then disabling and re-enabling it.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c |   35 ++++++++++++++++++++++++-----------
 1 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 6963f2e..a2b8d1e 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -371,13 +371,17 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
  * @clk: struct clk * of DPLL to set
  * @rate: rounded target rate
  *
- * Program the DPLL with the rounded target rate.  Returns -EINVAL upon
- * error, or 0 upon success.
+ * Set the DPLL CLKOUT to the target rate.  If the DPLL can enter
+ * low-power bypass, and the target rate is the sys_clk rate, then
+ * configure the DPLL for bypass.  Otherwise, round the target rate if
+ * it hasn't been done already, then program and lock the DPLL.
+ * Returns -EINVAL upon error, or 0 upon success.
  */
 static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
 {
 	u16 freqsel;
 	struct dpll_data *dd;
+	int ret;
 
 	if (!clk || !rate)
 		return -EINVAL;
@@ -389,18 +393,27 @@ static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
 	if (rate == omap2_get_dpll_rate(clk))
 		return 0;
 
-	if (dd->last_rounded_rate != rate)
-		omap2_dpll_round_rate(clk, rate);
+	if (clk->parent->rate == rate &&
+	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
 
-	if (dd->last_rounded_rate == 0)
-		return -EINVAL;
+		ret = _omap3_noncore_dpll_bypass(clk);
+
+	} else {
+
+		if (dd->last_rounded_rate != rate)
+			omap2_dpll_round_rate(clk, rate);
 
-	freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
-	if (!freqsel)
-		WARN_ON(1);
+		if (dd->last_rounded_rate == 0)
+			return -EINVAL;
 
-	omap3_noncore_dpll_program(clk, dd->last_rounded_m, dd->last_rounded_n,
-				   freqsel);
+		freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
+		if (!freqsel)
+			WARN_ON(1);
+
+		ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
+						 dd->last_rounded_n, freqsel);
+
+	}
 
 	omap3_dpll_recalc(clk);
 



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/6] OMAP3 clock: recalculate DPLL subtree after bypass entry/exit
  2008-09-16 12:16 [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree Paul Walmsley
                   ` (4 preceding siblings ...)
  2008-09-16 12:16 ` [PATCH 5/6] OMAP3 clock: DPLLs should enter bypass if new rate is sys_ck Paul Walmsley
@ 2008-09-16 12:16 ` Paul Walmsley
  5 siblings, 0 replies; 7+ messages in thread
From: Paul Walmsley @ 2008-09-16 12:16 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

The DPLL's rate changes when it enters or leaves bypass, so the DPLL's
rate and the rates of all dependent clocks need to be recalculated
when this happens.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index a2b8d1e..6dbaac6 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -180,7 +180,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
 }
 
 /*
- * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
+ * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
  * @clk: pointer to a DPLL struct clk
  *
  * Instructs a non-CORE DPLL to enter low-power bypass mode.  In
@@ -270,15 +270,21 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
 static int omap3_noncore_dpll_enable(struct clk *clk)
 {
 	int r;
+	long rate;
 
 	if (clk == &dpll3_ck)
 		return -EINVAL;
 
-	if (clk->parent->rate == omap2_get_dpll_rate(clk))
+	rate = omap2_get_dpll_rate(clk);
+
+	if (clk->parent->rate == rate)
 		r = _omap3_noncore_dpll_bypass(clk);
 	else
 		r = _omap3_noncore_dpll_lock(clk);
 
+	if (!r)
+		clk->rate = rate;
+
 	return r;
 }
 
@@ -397,6 +403,8 @@ static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
 	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
 
 		ret = _omap3_noncore_dpll_bypass(clk);
+		if (!ret)
+			clk->rate = rate;
 
 	} else {
 



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-09-16 12:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-16 12:16 [PATCH 0/6] OMAP2/3 clock: revise DPLL bypass handling in clock tree Paul Walmsley
2008-09-16 12:16 ` [PATCH 1/6] OMAP2/3 clock: convert dpll_data.idlest_bit to idlest_mask Paul Walmsley
2008-09-16 12:16 ` [PATCH 2/6] OMAP3 clock: add idlest_reg, idlest_mask for DPLL3 Paul Walmsley
2008-09-16 12:16 ` [PATCH 3/6] OMAP2/3 clock: move DPLL bypass rate calculation into omap2_get_dpll_rate() Paul Walmsley
2008-09-16 12:16 ` [PATCH 4/6] OMAP3 clock: omap3_clkoutx2_recalc() should test DPLL IDLEST to determine if DPLL is bypassed Paul Walmsley
2008-09-16 12:16 ` [PATCH 5/6] OMAP3 clock: DPLLs should enter bypass if new rate is sys_ck Paul Walmsley
2008-09-16 12:16 ` [PATCH 6/6] OMAP3 clock: recalculate DPLL subtree after bypass entry/exit Paul Walmsley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox