* Reddy, Teerth <[email protected]> [091223 21:31]:
> From e5e82efbf6f736984668cc5e94d62635ed4de05e Mon Sep 17 00:00:00 2001
> From: Teerth Reddy <[email protected]>
> Date: Wed, 23 Dec 2009 18:40:34 +0530
> Subject: [PATCH] Dynamic Calculation of SDRC clock stabilization delay
> 
> The patch has the changes to calculate the dpll3 clock
> stabilization delay dynamically. The SRAM delay is
> calibrated during bootup using the gptimers and used while
> calculating the stabilization delay. By using the dynamic
> method the dependency on the type of cache being used is
> removed. Hence there is no need of loop based calculation.
> 
> TO DO: However the value of 6us for SDRC to stabilize has
> been hardcoded currently. The formula used to calculate
> this value gives a very small number thus causing
> instability. The right formula will be used which will
> work across all boards.

Why does this patch have "PM" in the subject?

This patch should not have anything to do with the pm branch,
it's obviously clock + SRAM related. All that code is in the
mainline kernel.

Please stop tagging patches as "PM" unless they really are
pm related.

Regards,

Tony

 
> Signed-off-by: Teerth Reddy <[email protected]>
> Signed-off-by: Romit Dasgupta <[email protected]>
> ---
>  arch/arm/mach-omap2/clock34xx.c        |   21 +++++++++------
>  arch/arm/mach-omap2/clock34xx.h        |    2 +
>  arch/arm/mach-omap2/clock34xx_data.c   |    4 +++
>  arch/arm/mach-omap2/sram34xx.S         |   25 ++++++++++++++++++
>  arch/arm/plat-omap/include/plat/sram.h |    5 +++
>  arch/arm/plat-omap/sram.c              |   43 
> ++++++++++++++++++++++++++++++++
>  6 files changed, 91 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
> index d9329e2..6d87419 100644
> --- a/arch/arm/mach-omap2/clock34xx.c
> +++ b/arch/arm/mach-omap2/clock34xx.c
> @@ -56,9 +56,18 @@
>   */
>  #define DPLL5_FREQ_FOR_USBHOST               120000000
>  
> +/*
> + * SDRC_TIME_STABILIZE: Time for SDRC to stabilize in us
> + * TO DO: Use formula to calculate across all platforms
> + */
> +#define              SDRC_TIME_STABILIZE     6
> +
>  /* needed by omap3_core_dpll_m2_set_rate() */
>  struct clk *sdrc_ick_p, *arm_fck_p;
>  
> +/* SRAM delay required for sdrc clk stab delay calculation */
> +unsigned int delay_sram;
> +
>  /**
>   * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
>   * @clk: struct clk * being enabled
> @@ -215,16 +224,10 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, 
> unsigned long rate)
>               unlock_dll = 1;
>       }
>  
> -     /*
> -      * XXX This only needs to be done when the CPU frequency changes
> -      */
> +     /* Calculate the number of MPU cycles to wait for SDRC to stabilize */
> +
>       _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
> -     c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
> -     c += 1;  /* for safety */
> -     c *= SDRC_MPURATE_LOOPS;
> -     c >>= SDRC_MPURATE_SCALE;
> -     if (c == 0)
> -             c = 1;
> +     c = ((SDRC_TIME_STABILIZE * _mpurate) / (delay_sram * 2));
>  
>       pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
>                validrate);
> diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
> index 9a2c07e..1bc5044 100644
> --- a/arch/arm/mach-omap2/clock34xx.h
> +++ b/arch/arm/mach-omap2/clock34xx.h
> @@ -21,4 +21,6 @@ extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
>  extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
>  extern const struct clkops clkops_noncore_dpll_ops;
>  
> +extern unsigned int delay_sram;
> +
>  #endif
> diff --git a/arch/arm/mach-omap2/clock34xx_data.c 
> b/arch/arm/mach-omap2/clock34xx_data.c
> index 8bdcc9c..e5d0941 100644
> --- a/arch/arm/mach-omap2/clock34xx_data.c
> +++ b/arch/arm/mach-omap2/clock34xx_data.c
> @@ -22,6 +22,7 @@
>  
>  #include <plat/control.h>
>  #include <plat/clkdev_omap.h>
> +#include <plat/sram.h>
>  
>  #include "clock.h"
>  #include "clock34xx.h"
> @@ -3285,5 +3286,8 @@ int __init omap2_clk_init(void)
>       sdrc_ick_p = clk_get(NULL, "sdrc_ick");
>       arm_fck_p = clk_get(NULL, "arm_fck");
>  
> +     /* Measure sram delay */
> +     delay_sram = measure_sram_delay(10000);
> +     pr_debug("SRAM delay: %d\n", delay_sram);
>       return 0;
>  }
> diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
> index de99ba2..b4fba50 100644
> --- a/arch/arm/mach-omap2/sram34xx.S
> +++ b/arch/arm/mach-omap2/sram34xx.S
> @@ -68,6 +68,10 @@
>  /* CM_CLKSEL1_PLL bit settings */
>  #define CORE_DPLL_CLKOUT_DIV_SHIFT   0x1b
>  
> +#define      GPTIMER10_TCRR_PHY                      0x48086028
> +
> +#define      GPTIMER10_TCRR  OMAP2_L4_IO_ADDRESS(GPTIMER10_TCRR_PHY)
> +
>  /*
>   * omap3_sram_configure_core_dpll - change DPLL3 M2 divider
>   *
> @@ -313,3 +317,24 @@ core_m2_mask_val:
>  ENTRY(omap3_sram_configure_core_dpll_sz)
>       .word   . - omap3_sram_configure_core_dpll
>  
> +ENTRY(__sram_wait_delay)
> +     stmfd   sp!, {r1-r12, lr}       @ store regs to stack
> +     ldr     r2, gptimer10_counter
> +     ldr     r3, [r2]
> +
> +loop1:
> +     subs    r0, r0, #1
> +     bne     loop1
> +
> +     isb
> +     ldr     r4, [r2]
> +     subs    r5, r4, r3
> +
> +     mov     r0, r5                  @ return value
> +     ldmfd   sp!, {r1-r12, pc}       @ restore regs and return
> +
> +gptimer10_counter:
> +     .word   GPTIMER10_TCRR
> +
> +ENTRY(__sram_wait_delay_sz)
> +     .word   . - __sram_wait_delay
> diff --git a/arch/arm/plat-omap/include/plat/sram.h 
> b/arch/arm/plat-omap/include/plat/sram.h
> index 16a1b45..7d0be2a 100644
> --- a/arch/arm/plat-omap/include/plat/sram.h
> +++ b/arch/arm/plat-omap/include/plat/sram.h
> @@ -69,6 +69,11 @@ extern u32 omap3_sram_configure_core_dpll(
>                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
>  extern unsigned long omap3_sram_configure_core_dpll_sz;
>  
> +extern unsigned int measure_sram_delay(unsigned int);
> +
> +extern u32 __sram_wait_delay(unsigned int);
> +extern unsigned long __sram_wait_delay_sz;
> +
>  #ifdef CONFIG_PM
>  extern void omap_push_sram_idle(void);
>  #else
> diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
> index d8d5094..ddbdaaf 100644
> --- a/arch/arm/plat-omap/sram.c
> +++ b/arch/arm/plat-omap/sram.c
> @@ -30,6 +30,9 @@
>  #include <plat/cpu.h>
>  #include <plat/vram.h>
>  
> +#include <linux/clk.h>
> +#include <plat/dmtimer.h>
> +
>  #include <plat/control.h>
>  
>  #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
> @@ -437,11 +440,51 @@ static inline int omap34xx_sram_init(void)
>  }
>  #endif
>  
> +
> +#ifdef CONFIG_ARCH_OMAP3
> +unsigned long (*_omap3_sram_delay)(unsigned long);
> +unsigned int  measure_sram_delay(unsigned int loop)
> +{
> +     static struct omap_dm_timer *gpt;
> +     unsigned long flags, diff = 0, gt_rate, mpurate;
> +     unsigned int delay_sram, error_gain;
> +
> +     omap_dm_timer_init();
> +     gpt = omap_dm_timer_request_specific(10);
> +     if (!gpt)
> +             pr_err("Could not get the gptimer\n");
> +     omap_dm_timer_set_source(gpt, OMAP_TIMER_SRC_SYS_CLK);
> +
> +     gt_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt));
> +     omap_dm_timer_set_load_start(gpt, 0, 0);
> +
> +     local_irq_save(flags);
> +     diff = _omap3_sram_delay(loop);
> +     local_irq_restore(flags);
> +
> +     omap_dm_timer_stop(gpt);
> +     omap_dm_timer_free(gpt);
> +
> +     mpurate = clk_get_rate(clk_get(NULL, "arm_fck"));
> +
> +     /* calculate the sram delay */
> +     delay_sram = (((mpurate / gt_rate) * diff) / 20000);
> +
> +     error_gain = mpurate / gt_rate;
> +     delay_sram = delay_sram + error_gain;
> +
> +     return delay_sram;
> +}
> +#endif
> +
>  int __init omap_sram_init(void)
>  {
>       omap_detect_sram();
>       omap_map_sram();
>  
> +     _omap3_sram_delay = omap_sram_push(__sram_wait_delay,
> +                                             __sram_wait_delay_sz);
> +
>       if (!(cpu_class_is_omap2()))
>               omap1_sram_init();
>       else if (cpu_is_omap242x())
> --
> 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