All of lore.kernel.org
 help / color / mirror / Atom feed
From: ambresh <a0393775@ti.com>
To: "Gurav , Pramod" <pramod.gurav@ti.com>
Cc: "linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>,
	"Reddy, Teerth" <teerth@ti.com>,
	"Sripathy, Vishwanath" <vishwanath.bs@ti.com>
Subject: Re: [PATCH v4 1/2] OMAP3: SDRC: Dynamic Calculation of SDRC stall latency during DVFS
Date: Thu, 18 Mar 2010 12:45:43 +0530	[thread overview]
Message-ID: <4BA1D31F.3070809@ti.com> (raw)
In-Reply-To: <1268888148-10983-2-git-send-email-pramod.gurav@ti.com>

Gurav , Pramod wrote:
> From: Teerth Reddy <teerth@ti.com>
> 
> 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.
> 
> The wait time for L3 clock stabilization is calculated using the formula
>         = 4*REFCLK + 8*CLKOUTX2,
> which uses the M, N and M2 read from the registers.
> Since this gives slightly less value, 2us is added as buffer for safety.
> This works fine for omap3.
> 
> Signed-off-by: Teerth Reddy <teerth@ti.com>
> Signed-off-by: Pramod Gurav <pramod.gurav@ti.com>
> Signed-off-by: Vishwanath Sripathy <vishwanath.bs@ti.com>
> 
> ---
>  arch/arm/mach-omap2/clkt34xx_dpll3m2.c |   54 +++++++++++++++++++++++++++-----
>  arch/arm/mach-omap2/clock34xx.h        |    2 +
>  arch/arm/mach-omap2/clock3xxx.c        |    2 +-
>  arch/arm/mach-omap2/clock3xxx.h        |    1 +
>  arch/arm/mach-omap2/clock3xxx_data.c   |   13 ++++++++
>  arch/arm/mach-omap2/sram34xx.S         |    8 +++++
>  arch/arm/plat-omap/include/plat/sram.h |    4 ++
>  arch/arm/plat-omap/sram.c              |   51 ++++++++++++++++++++++++++++++
>  8 files changed, 126 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
> index b2b1e37..29421b1 100644
> --- a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
> +++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
> @@ -24,13 +24,21 @@
>  #include <plat/clock.h>
>  #include <plat/sram.h>
>  #include <plat/sdrc.h>
> +#include <plat/prcm.h>
>  
>  #include "clock.h"
>  #include "clock3xxx.h"
>  #include "clock34xx.h"
>  #include "sdrc.h"
>  
> -#define CYCLES_PER_MHZ			1000000
> +#define		CYCLES_PER_MHZ		1000000
> +
> +#define		DPLL_M_MASK		0x7ff
> +#define		DPLL_N_MASK		0x7f
> +#define		DPLL_M2_MASK		0x1f
> +#define		SHIFT_DPLL_M		16
> +#define		SHIFT_DPLL_N		8
> +#define		SHIFT_DPLL_M2		27
>  
>  /*
>   * CORE DPLL (DPLL3) M2 divider rate programming functions
> @@ -56,6 +64,11 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
>  	struct omap_sdrc_params *sdrc_cs0;
>  	struct omap_sdrc_params *sdrc_cs1;
>  	int ret;
> +	u32 clk_sel_regval;
> +	u32 core_dpll_mul_m, core_dpll_div_n, core_dpll_clkoutdiv_m2;
> +	u32 sys_clk_rate, sdrc_clk_stab;
> +	u32 refclk, clkoutx2, switch_latency;
> +	unsigned int delay_sram;
>  
>  	if (!clk || !rate)
>  		return -EINVAL;
> @@ -79,16 +92,41 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
>  		unlock_dll = 1;
>  	}
>  
> +	clk_sel_regval = __raw_readl(clk->clksel_reg);
> +
> +	/* Get the M, N and M2 values required for getting sdrc clk stab */
> +	core_dpll_mul_m = (clk_sel_regval >> SHIFT_DPLL_M) & DPLL_M_MASK;
> +	core_dpll_div_n = (clk_sel_regval >> SHIFT_DPLL_N) & DPLL_N_MASK;
> +	core_dpll_clkoutdiv_m2 = (clk_sel_regval >> SHIFT_DPLL_M2) &
> +							DPLL_M2_MASK;
> +	sys_clk_rate = clk_get_rate(sys_ck_p);
> +
> +	sys_clk_rate = sys_clk_rate / CYCLES_PER_MHZ;
> +
> +	/* wait time for L3 clk stabilization = 4*REFCLK + 8*CLKOUTX2 */
> +	refclk = (4 * (core_dpll_div_n + 1)) / sys_clk_rate;
> +	clkoutx2 = ((core_dpll_div_n + 1) * core_dpll_clkoutdiv_m2) /
> +					(sys_clk_rate * core_dpll_mul_m * 2);
> +	switch_latency =  refclk + 8 * clkoutx2;
> +
> +	/* Adding 2us to sdrc clk stab */
> +	sdrc_clk_stab =  switch_latency + 2;
> +
> +	delay_sram = delay_sram_val();
> +
>  	/*
> -	 * 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_clk_stab * _mpurate) / (delay_sram * 2));
> +
> +	pr_debug("m = %d, n = %d, m2 =%d\n", core_dpll_mul_m, core_dpll_div_n,
> +						core_dpll_clkoutdiv_m2);
> +	pr_debug("switch_latency = %d, sys_clk_rate = %d, cycles = %d\n",
> +					switch_latency, sys_clk_rate, c);
>  
>  	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 628e8de..a9f2204 100644
> --- a/arch/arm/mach-omap2/clock34xx.h
> +++ b/arch/arm/mach-omap2/clock34xx.h
> @@ -12,4 +12,6 @@ extern const struct clkops clkops_omap3430es2_ssi_wait;
>  extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
>  extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
>  
> +unsigned int delay_sram_val(void);
> +
>  #endif
> diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
> index a447c4d..ce84a98 100644
> --- a/arch/arm/mach-omap2/clock3xxx.c
> +++ b/arch/arm/mach-omap2/clock3xxx.c
> @@ -38,7 +38,7 @@
>  #define DPLL5_FREQ_FOR_USBHOST		120000000
>  
>  /* needed by omap3_core_dpll_m2_set_rate() */
> -struct clk *sdrc_ick_p, *arm_fck_p;
> +struct clk *sdrc_ick_p, *arm_fck_p, *sys_ck_p;
>  
>  int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
>  {
> diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h
> index 8bbeeaf..475d0c7 100644
> --- a/arch/arm/mach-omap2/clock3xxx.h
> +++ b/arch/arm/mach-omap2/clock3xxx.h
> @@ -15,6 +15,7 @@ void omap3_clk_lock_dpll5(void);
>  
>  extern struct clk *sdrc_ick_p;
>  extern struct clk *arm_fck_p;
> +extern struct clk *sys_ck_p;
>  
>  extern const struct clkops clkops_noncore_dpll_ops;
>  
> diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
> index 57522de..280adff 100644
> --- a/arch/arm/mach-omap2/clock3xxx_data.c
> +++ b/arch/arm/mach-omap2/clock3xxx_data.c
> @@ -22,6 +22,7 @@
>  
>  #include <plat/control.h>
>  #include <plat/clkdev_omap.h>
> +#include <plat/sram.h>
>  
>  #include "clock.h"
>  #include "clock3xxx.h"
> @@ -57,6 +58,8 @@
>  static struct clk dpll1_fck;
>  static struct clk dpll2_fck;
>  
> +static unsigned int delay_sram;
> +
>  /* PRM CLOCKS */
>  
>  /* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
> @@ -3598,6 +3601,16 @@ int __init omap3xxx_clk_init(void)
>  	/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
>  	sdrc_ick_p = clk_get(NULL, "sdrc_ick");
>  	arm_fck_p = clk_get(NULL, "arm_fck");
> +	sys_ck_p = clk_get(NULL, "sys_ck");
> +
> +	/* Measure sram delay */
> +	delay_sram = measure_sram_delay(10000);
> +	pr_debug("SRAM delay: %d\n", delay_sram);
>  
>  	return 0;
>  }
> +
> +unsigned int delay_sram_val(void)
> +{
> +	return delay_sram;
> +}
> diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
> index de99ba2..5a1631f 100644
> --- a/arch/arm/mach-omap2/sram34xx.S
> +++ b/arch/arm/mach-omap2/sram34xx.S
> @@ -313,3 +313,11 @@ core_m2_mask_val:
>  ENTRY(omap3_sram_configure_core_dpll_sz)
>  	.word	. - omap3_sram_configure_core_dpll
>  
> +ENTRY(__sram_wait_delay)
> +	subs    r0, r0, #1		@ loop till counter = 0
> +	bne     __sram_wait_delay
> +
> +	mov     pc, lr
> +
> +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..dd294a8 100644
> --- a/arch/arm/plat-omap/include/plat/sram.h
> +++ b/arch/arm/plat-omap/include/plat/sram.h
> @@ -69,6 +69,10 @@ 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 void __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 51f4dfb..a83d422 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/io.h>
>  #include <plat/control.h>
>  
>  #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
> @@ -437,11 +440,59 @@ static inline int omap34xx_sram_init(void)
>  }
>  #endif
>  
> +#ifdef CONFIG_ARCH_OMAP3
> +void (*_omap3_sram_delay)(unsigned int);
> +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;
> +	unsigned int start = 0, end = 0;
> +
> +	omap_dm_timer_init();
> +	gpt = omap_dm_timer_request();
> +	if (!gpt) {
> +		pr_err("Could not get the gptimer\n");
> +		return -1;
> +	}
> +
> +	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);
> +	start = omap_dm_timer_read_counter(gpt);
> +	_omap3_sram_delay(loop);
> +	end = omap_dm_timer_read_counter(gpt);
> +	diff = end - start;
> +	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) / (loop * 2));
> +
> +	error_gain = mpurate / gt_rate;
> +	delay_sram = delay_sram + error_gain;

Cosmetic changes:

         error_gain = mpurate / gt_rate;
         delay_sram = (error_gain * diff) / (loop);
         delay_sram += error_gain;

Thanks,
Ambresh

> +
> +	return delay_sram;
> +}
> +#endif
> +
>  int __init omap_sram_init(void)
>  {
>  	omap_detect_sram();
>  	omap_map_sram();
>  
> +#ifdef CONFIG_ARCH_OMAP3
> +	_omap3_sram_delay = omap_sram_push(__sram_wait_delay,
> +						__sram_wait_delay_sz);
> +#endif
> +
>  	if (!(cpu_class_is_omap2()))
>  		omap1_sram_init();
>  	else if (cpu_is_omap242x())


  parent reply	other threads:[~2010-03-18  7:15 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-18  4:55 [PATCH 0/2] OMAP3: Dynamic Calculation of SDRC stall latency during DVFS Pramod Gurav
2010-03-18  4:55 ` [PATCH v4 1/2] OMAP3: SDRC: " Pramod Gurav
2010-03-18  4:55   ` [PATCH v2 2/2] OMAP3630 SDRC: Change in DVFS Latency Formula for OMAP3630 Pramod Gurav
2010-03-18  7:17     ` ambresh
2010-03-19 13:17       ` Sripathy, Vishwanath
2010-03-23  2:49         ` ambresh
2010-03-18  6:17   ` [PATCH v4 1/2] OMAP3: SDRC: Dynamic Calculation of SDRC stall latency during DVFS G, Manjunath Kondaiah
2010-03-18 14:48     ` Kevin Hilman
2010-03-18  7:15   ` ambresh [this message]
2010-03-19 13:15     ` Sripathy, Vishwanath
2010-03-21 13:24       ` ambresh
2010-03-18 15:09   ` Kevin Hilman
  -- strict thread matches above, loose matches on Subject: below --
2010-04-01 17:16 [PATCH V4 0/2] OMAP3: " Pramod Gurav
2010-04-01 17:16 ` [PATCH v4 1/2] OMAP3: SDRC: " Pramod Gurav

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=4BA1D31F.3070809@ti.com \
    --to=a0393775@ti.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=pramod.gurav@ti.com \
    --cc=teerth@ti.com \
    --cc=vishwanath.bs@ti.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.