* Paul Walmsley <[EMAIL PROTECTED]> [081130 23:44]:
> 
> From: Tero Kristo <[EMAIL PROTECTED]>
> 
> 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 <[EMAIL PROTECTED]> 
> and Paul Walmsley <[EMAIL PROTECTED]>.  Thanks to Peter de Schrijver 
> <[EMAIL PROTECTED]> for help debugging and Kevin Hilman 
> <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]>
> Signed-off-by: Paul Walmsley <[EMAIL PROTECTED]>
> Cc: Kevin Hilman <[EMAIL PROTECTED]>
> Cc: Peter de Schrijver <[EMAIL PROTECTED]>
> ---
>  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 [EMAIL PROTECTED]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to