public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
From: Tony Lindgren <tony@atomide.com>
To: Paul Walmsley <paul@pwsan.com>
Cc: linux-omap@vger.kernel.org, tero.kristo@nokia.com,
	khilman@deeprootsystems.com, k.kooi@student.utwente.nl,
	peter.de-schrijver@nokia.com
Subject: Re: [PATCH] OMAP2/3 clock: fix DPLL rate calculation
Date: Fri, 5 Dec 2008 16:19:58 -0800	[thread overview]
Message-ID: <20081206001956.GP9714@atomide.com> (raw)
In-Reply-To: <alpine.DEB.2.00.0812010040460.31066@utopia.booyaka.com>

* Paul Walmsley <paul@pwsan.com> [081130 23:44]:
> 
> From: Tero Kristo <tero.kristo@nokia.com>
> 
> Noncore dpll can enter autoidle state, in which case the rate calculation
> fails.  Fixed by checking dpll mode instead of idle status.
> 
> Also, previously, the OMAP2xxx code returned the wrong value for the
> DPLL rate under some conditions.  Move the CORE_CLK rate recalculation
> to clock24xx.c:omap2xxx_clk_get_core_rate().
> 
> This patch is a collaboration between Tero Kristo <tero.kristo@nokia.com> 
> and Paul Walmsley <paul@pwsan.com>.  Thanks to Peter de Schrijver 
> <peter.de-schrijver@nokia.com> for help debugging and Kevin Hilman 
> <khilman@deeprootsystems.com> for reporting the OMAP2 build problems with 
> an earlier version of this patch.

Pushing to l-o tree today.

Tony

> 
> Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Peter de Schrijver <peter.de-schrijver@nokia.com>
> ---
>  arch/arm/mach-omap2/clock.c             |   21 +++++++----------
>  arch/arm/mach-omap2/clock.h             |   15 ++++++++++++
>  arch/arm/mach-omap2/clock24xx.c         |   39 +++++++++++++++++++++----------
>  arch/arm/mach-omap2/clock24xx.h         |    4 ++-
>  arch/arm/mach-omap2/clock34xx.c         |    7 +++---
>  arch/arm/mach-omap2/sdrc2xxx.c          |    2 ++
>  arch/arm/plat-omap/include/mach/clock.h |   13 +++-------
>  7 files changed, 62 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
> index 42af286..e7fa9b0 100644
> --- a/arch/arm/mach-omap2/clock.c
> +++ b/arch/arm/mach-omap2/clock.c
> @@ -71,10 +71,6 @@
>  #define DPLL_FINT_UNDERFLOW		-1
>  #define DPLL_FINT_INVALID		-2
>  
> -/* 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
> -
>  /* Bitmask to isolate the register type of clk.enable_reg */
>  #define PRCM_REGTYPE_MASK		0xf0
>  /* various CM register type options */
> @@ -267,19 +263,20 @@ u32 omap2_get_dpll_rate(struct clk *clk)
>  		return 0;
>  
>  	/* Return bypass rate if DPLL is bypassed */
> -	v = cm_read_mod_reg(clk->prcm_mod, dd->idlest_reg);
> -	v &= dd->idlest_mask;
> -	v >>= __ffs(dd->idlest_mask);
> +	v = cm_read_mod_reg(clk->prcm_mod, dd->control_reg);
> +	v &= dd->enable_mask;
> +	v >>= __ffs(dd->enable_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;
> +		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
> +		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
> +			return clk->parent->rate;
>  
>  	} else if (cpu_is_omap34xx()) {
>  
> -		if (!v)
> +		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
> +		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
>  			return dd->bypass_clk->rate;
>  
>  	}
> diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
> index bcb0c03..c95e48c 100644
> --- a/arch/arm/mach-omap2/clock.h
> +++ b/arch/arm/mach-omap2/clock.h
> @@ -21,6 +21,21 @@
>  /* The maximum error between a target DPLL rate and the rounded rate in Hz */
>  #define DEFAULT_DPLL_RATE_TOLERANCE	50000
>  
> +/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
> +#define CORE_CLK_SRC_32K		0x0
> +#define CORE_CLK_SRC_DPLL		0x1
> +#define CORE_CLK_SRC_DPLL_X2		0x2
> +
> +/* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */
> +#define OMAP2XXX_EN_DPLL_LPBYPASS		0x1
> +#define OMAP2XXX_EN_DPLL_FRBYPASS		0x2
> +#define OMAP2XXX_EN_DPLL_LOCKED			0x3
> +
> +/* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
> +#define OMAP3XXX_EN_DPLL_LPBYPASS		0x5
> +#define OMAP3XXX_EN_DPLL_FRBYPASS		0x6
> +#define OMAP3XXX_EN_DPLL_LOCKED			0x7
> +
>  int omap2_clk_init(void);
>  int omap2_clk_enable(struct clk *clk);
>  void omap2_clk_disable(struct clk *clk);
> diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
> index 32f6632..4bd21dd 100644
> --- a/arch/arm/mach-omap2/clock24xx.c
> +++ b/arch/arm/mach-omap2/clock24xx.c
> @@ -60,19 +60,32 @@ static struct clk *sclk;
>   * Omap24xx specific clock functions
>   *-------------------------------------------------------------------------*/
>  
> -/* This actually returns the rate of core_ck, not dpll_ck. */
> -static u32 omap2_get_dpll_rate_24xx(struct clk *tclk)
> +/**
> + * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
> + * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
> + *
> + * Returns the CORE_CLK rate.  CORE_CLK can have one of three rate
> + * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
> + * (the latter is unusual).  This currently should be called with
> + * struct clk *dpll_ck, which is a composite clock of dpll_ck and
> + * core_ck.
> + */
> +static u32 omap2xxx_clk_get_core_rate(struct clk *clk)
>  {
> -	long long dpll_clk;
> -	u8 amult;
> +	long long core_clk;
> +	u32 v;
>  
> -	dpll_clk = omap2_get_dpll_rate(tclk);
> +	core_clk = omap2_get_dpll_rate(clk);
>  
> -	amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
> -	amult &= OMAP24XX_CORE_CLK_SRC_MASK;
> -	dpll_clk *= amult;
> +	v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
> +	v &= OMAP24XX_CORE_CLK_SRC_MASK;
> +
> +	if (v == CORE_CLK_SRC_32K)
> +		core_clk = 32768;
> +	else
> +		core_clk *= v;
>  
> -	return dpll_clk;
> +	return core_clk;
>  }
>  
>  static int omap2_enable_osc_ck(struct clk *clk)
> @@ -164,7 +177,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
>  
>  static void omap2_dpllcore_recalc(struct clk *clk)
>  {
> -	clk->rate = omap2_get_dpll_rate_24xx(clk);
> +	clk->rate = omap2xxx_clk_get_core_rate(clk);
>  
>  	propagate_rate(clk);
>  }
> @@ -179,7 +192,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
>  	int ret = -EINVAL;
>  
>  	local_irq_save(flags);
> -	cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
> +	cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
>  	mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
>  	mult &= OMAP24XX_CORE_CLK_SRC_MASK;
>  
> @@ -319,7 +332,7 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
>  	}
>  
>  	curr_prcm_set = prcm;
> -	cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
> +	cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
>  
>  	if (prcm->dpll_speed == cur_rate / 2) {
>  		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
> @@ -535,7 +548,7 @@ int __init omap2_clk_init(void)
>  	}
>  
>  	/* Check the MPU rate set by bootloader */
> -	clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
> +	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
>  	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
>  		if (!(prcm->flags & cpu_mask))
>  			continue;
> diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
> index 724bcb0..929a257 100644
> --- a/arch/arm/mach-omap2/clock24xx.h
> +++ b/arch/arm/mach-omap2/clock24xx.h
> @@ -673,8 +673,8 @@ static struct dpll_data dpll_dd = {
>  	.mult_div1_reg		= CM_CLKSEL1,
>  	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
>  	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
> -	.idlest_reg		= CM_IDLEST,
> -	.idlest_mask		= OMAP24XX_ST_CORE_CLK_MASK,
> +	.control_reg		= CM_CLKEN,
> +	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
>  	.max_multiplier		= 1024,
>  	.min_divider		= 1,
>  	.max_divider		= 16,
> diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
> index b8b4494..6c41112 100644
> --- a/arch/arm/mach-omap2/clock34xx.c
> +++ b/arch/arm/mach-omap2/clock34xx.c
> @@ -604,10 +604,11 @@ static void omap3_clkoutx2_recalc(struct clk *clk)
>  
>  	dd = pclk->dpll_data;
>  
> -	WARN_ON(!dd->idlest_reg || !dd->idlest_mask);
> +	WARN_ON(!dd->enable_mask);
>  
> -	v = cm_read_mod_reg(pclk->prcm_mod, dd->idlest_reg) & dd->idlest_mask;
> -	if (!v)
> +	v = cm_read_mod_reg(pclk->prcm_mod, dd->control_reg) & dd->enable_mask;
> +	v >>= __ffs(dd->enable_mask);
> +	if (v != OMAP3XXX_EN_DPLL_LOCKED)
>  		clk->rate = clk->parent->rate;
>  	else
>  		clk->rate = clk->parent->rate * 2;
> diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c
> index 0723e59..479dc8c 100644
> --- a/arch/arm/mach-omap2/sdrc2xxx.c
> +++ b/arch/arm/mach-omap2/sdrc2xxx.c
> @@ -28,6 +28,8 @@
>  #include <mach/clock.h>
>  #include <mach/sram.h>
>  
> +#include "clock.h"
> +
>  #include "prm.h"
>  
>  #include <mach/sdrc.h>
> diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
> index 4eef580..e793616 100644
> --- a/arch/arm/plat-omap/include/mach/clock.h
> +++ b/arch/arm/plat-omap/include/mach/clock.h
> @@ -42,14 +42,14 @@ struct dpll_data {
>  	u8			min_divider;
>  	u8			max_divider;
>  	u32			max_tolerance;
> -	u16			idlest_reg;
> -	u32			idlest_mask;
>  	struct clk		*bypass_clk;
> +	u16			control_reg;
> +	u32			enable_mask;
>  #  if defined(CONFIG_ARCH_OMAP3)
> +	u16			idlest_reg;
> +	u32			idlest_mask;
>  	u32			freqsel_mask;
>  	u8			modes;
> -	u16			control_reg;
> -	u32			enable_mask;
>  	u8			auto_recal_bit;
>  	u8			recal_en_bit;
>  	u8			recal_st_bit;
> @@ -175,9 +175,4 @@ extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
>  #define CLK_REG_IN_PRM		(1 << 0)
>  #define CLK_REG_IN_SCM		(1 << 1)
>  
> -/* CM_CLKSEL2_PLL.CORE_CLK_SRC options (24XX) */
> -#define CORE_CLK_SRC_32K		0
> -#define CORE_CLK_SRC_DPLL		1
> -#define CORE_CLK_SRC_DPLL_X2		2
> -
>  #endif
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

      reply	other threads:[~2008-12-06  0:20 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-01  7:43 [PATCH] OMAP2/3 clock: fix DPLL rate calculation Paul Walmsley
2008-12-06  0:19 ` Tony Lindgren [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081206001956.GP9714@atomide.com \
    --to=tony@atomide.com \
    --cc=k.kooi@student.utwente.nl \
    --cc=khilman@deeprootsystems.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.com \
    --cc=peter.de-schrijver@nokia.com \
    --cc=tero.kristo@nokia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox