Re: [PATCH 2/5] clk: notifier handler for dynamic voltage scaling

2013-03-02 Thread Richard Zhao
On Fri, Mar 01, 2013 at 06:55:54PM -0800, Bill Huang wrote:
 On Sat, 2013-03-02 at 04:48 +0800, Mike Turquette wrote:
  Quoting Mike Turquette (2013-03-01 10:22:34)
   Quoting Bill Huang (2013-03-01 01:41:31)
On Thu, 2013-02-28 at 12:49 +0800, Mike Turquette wrote:
 Dynamic voltage and frequency scaling (dvfs) is a common power saving
 technique in many of today's modern processors.  This patch 
 introduces a
 common clk rate-change notifier handler which scales voltage
 appropriately whenever clk_set_rate is called on an affected clock.

I really think clk_enable and clk_disable should also be triggering
notifier call and DVFS should act accordingly since there are cases
drivers won't set clock rate but instead disable its clock directly, do
you agree?
 
   
   Hi Bill,
   
   I'll think about this.  Perhaps a better solution would be to adapt
   these drivers to runtime PM.  Then a call to runtime_pm_put() would
   result in a call to clk_disable(...) and regulator_set_voltage(...).
   
   There is no performance-based equivalent to runtime PM, which is one
   reason why clk_set_rate is a likely entry point into dvfs.  But for
   operations that have nice api's like runtime PM it would be better to
   use those interfaces and not overload the clk.h api unnecessarily.
   
  
  Bill,
  
  I wasn't thinking at all when I wrote this.  Trying to rush to the
  airport I guess...
  
  clk_enable() and clk_disable() must not sleep and all operations are
  done under a spinlock.  So this rules out most use of notifiers.  It is
  expected for some drivers to very aggressively enable/disable clocks in
  interrupt handlers so scaling voltage as a function of clk_{en|dis}able
  calls is also likely out of the question.
 
 Yeah for those existing drivers to call enable/disable clocks in
 interrupt have ruled out this, I didn't think through when I was asking.
  
  Some platforms have chosen to implement voltage scaling in their
  .prepare callbacks.  I personally do not like this and still prefer
  drivers be adapted to runtime pm and let those callbacks handle voltage
  scaling along with clock handling.
Voltage scaling in clock notifiers seems similar. Clock and regulater
embedded code into each other will cause things complicated.
 
 I think different SoC have different mechanisms or constraints on doing
 their DVFS, such as Tegra VDD_CORE rail, it supplies power to many
 devices and as a consequence each device do not have their own power
 rail to control, instead a central driver to handle/control this power
 rail is needed (to set voltage at the maximum of the requested voltage
 from all its sub-devices), so I'm wondering even if every drivers are
 doing DVFS through runtime pm, we're still having hole on knowing
 whether or not clocks of the interested devices are enabled/disabled at
 runtime, I'm not familiar with runtime pm and hence do not know if there
 is a mechanism to handle this, I'll study a bit. Thanks.
  
  Regards,
  Mike
  
 There are three prerequisites to using this feature:
 
 1) the affected clocks must be using the common clk framework
 2) voltage must be scaled using the regulator framework
 3) clock frequency and regulator voltage values must be paired via the
 OPP library

Just a note, Tegra Core won't meet prerequisite #3 since each regulator
voltage values is associated with clocks driving those many sub-HW
blocks in it.
   
   This patch isn't the one and only way to perform dvfs.  It is just a
   helper function for registering notifier handlers for systems that meet
   the above three requirements.  Even if you do not use the OPP library
   there is no reason why you could not register your own rate-change
   notifier handler to implement dvfs using whatever lookup-table you use
   today.
   
   And patches are welcome to extend the usefulness of this helper.  I'd
   like as many people to benefit from this mechanism as possible.
 
 The extension is not so easy for us though since OPP library is assuming
 each device has a 1-1 mapping on its operating frequency and voltage.
Is there someone working on OPP clock/regulator sets support?

Thanks
Richard
   
   At some point we should think hard about DT bindings for these operating
   points...
   
   Regards,
   Mike
 
 
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v7 3/3] clk: basic clock hardware types

2012-03-16 Thread Richard Zhao
[...]
 +static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 + unsigned long *best_parent_rate)
 +{
 + struct clk_divider *divider = to_clk_divider(hw);
 + int i, bestdiv = 0;
 + unsigned long parent_rate, best = 0, now, maxdiv;
 +
 + if (!rate)
 + rate = 1;
 +
 + maxdiv = (1  divider-width);
 +
 + if (divider-flags  CLK_DIVIDER_ONE_BASED)
 + maxdiv--;
 +
 + if (!best_parent_rate) {
 + parent_rate = __clk_get_rate(__clk_get_parent(hw-clk));
 + bestdiv = DIV_ROUND_UP(parent_rate, rate);
 + bestdiv = bestdiv == 0 ? 1 : bestdiv;
 + bestdiv = bestdiv  maxdiv ? maxdiv : bestdiv;
 + return bestdiv;
 + }
 +
 + /*
 +  * The maximum divider we can use without overflowing
 +  * unsigned long in rate * i below
 +  */
 + maxdiv = min(ULONG_MAX / rate, maxdiv);
 +
 + for (i = 1; i = maxdiv; i++) {
 + parent_rate = __clk_round_rate(__clk_get_parent(hw-clk),
 + MULT_ROUND_UP(rate, i));
 + now = parent_rate / i;
 + if (now = rate  now  best) {
 + bestdiv = i;
 + best = now;
 + *best_parent_rate = parent_rate;
Better add  if (now == rate)
break;
There may be more than one hit for (now == rate). We'd better select
smallest div, thus smallest parent_rate.

It's the same comment for v6, but not show stopper.

Thanks
Richard
 + }
 + }
 +
 + if (!bestdiv) {
 + bestdiv = (1  divider-width);
 + if (divider-flags  CLK_DIVIDER_ONE_BASED)
 + bestdiv--;
 + *best_parent_rate = __clk_round_rate(__clk_get_parent(hw-clk), 
 1);
 + }
 +
 + return bestdiv;
 +}
 

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v6 3/3] clk: basic clock hardware types

2012-03-14 Thread Richard Zhao
Hi Mike,

 +static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 + unsigned long *best_parent_rate)
 +{
 + struct clk_divider *divider = to_clk_divider(hw);
 + int i, bestdiv = 0;
 + unsigned long parent_rate, best = 0, now, maxdiv;
 +
 + maxdiv = (1  divider-width);
 +
 + if (divider-flags  CLK_DIVIDER_ONE_BASED)
 + maxdiv--;
 +
 + if (!(__clk_get_flags(hw-clk)  CLK_SET_RATE_PARENT)) {
 + parent_rate = __clk_get_rate(__clk_get_parent(hw-clk));
 + bestdiv = parent_rate / rate;
 + bestdiv = bestdiv == 0 ? 1 : bestdiv;
 + bestdiv = bestdiv  maxdiv ? maxdiv : bestdiv;
 + goto out;
 + }
 +
 + /*
 +  * The maximum divider we can use without overflowing
 +  * unsigned long in rate * i below
 +  */
 + maxdiv = min(ULONG_MAX / rate, maxdiv);
 +
 + for (i = 1; i = maxdiv; i++) {
 + int div;
 + parent_rate = __clk_round_rate(__clk_get_parent(hw-clk),
 + rate * i);
 + div = parent_rate / rate;
 + div = div  maxdiv ? maxdiv : div;
 + div = div  1 ? 1 : div;
 + now = parent_rate / div;
 +
 + if (now = rate  now = best) {
 + bestdiv = div;
 + best = now;
 + *best_parent_rate = parent_rate;
if (now == rate)
break;
we don't need it to loop to end, and smaller parent_rate is better.
 + }
 + }
 +
 + if (!bestdiv) {
 + bestdiv = (1  divider-width);
 + parent_rate = __clk_round_rate(__clk_get_parent(hw-clk), 1);
 + } else {
 + parent_rate = best * bestdiv;
 + }
 +
 +out:
 + if (best_parent_rate)
 + *best_parent_rate = parent_rate;
 +
 + return bestdiv;
 +}


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v6 2/3] clk: introduce the common clock framework

2012-03-10 Thread Richard Zhao
Looks like you didn't take my comments for v5.
http://www.spinics.net/lists/arm-kernel/msg162903.html 

Regards
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v5 0/4] common clk framework

2012-03-08 Thread Richard Zhao
Hello Mike,

The main interface for clk implementer is to register clocks dynamically.
I think it highly depends on clk DT bindings. From the patch Grant sent
out, it looks like he doesn't like one node per clk. So how do we
register clocks dynamically? You have any sample code?

Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v5 3/4] clk: introduce the common clock framework

2012-03-05 Thread Richard Zhao
Hi Mike,

On Sat, Mar 03, 2012 at 12:29:00AM -0800, Mike Turquette wrote:

[snip]

 +static void __clk_disable(struct clk *clk)
 +{
 + if (!clk)
 + return;
 +
 + if (WARN_ON(clk-enable_count == 0))
 + return;
 +
 + if (--clk-enable_count  0)
 + return;
 +
 + if (clk-ops-disable)
 + clk-ops-disable(clk-hw);
 +
 + if (clk-parent)
 + __clk_disable(clk-parent);
if __clk_xxx handle NULL clk, we might not need to check parent here?
There're also many places that checks parent below.
 +}
 +
 +/**
 + * clk_disable - gate a clock
 + * @clk: the clk being gated
 + *
 + * clk_disable must not sleep, which differentiates it from clk_unprepare.  
 In
 + * a simple case, clk_disable can be used instead of clk_unprepare to gate a
 + * clk if the operation is fast and will never sleep.  One example is a
 + * SoC-internal clk which is controlled via simple register writes.  In the
 + * complex case a clk gate operation may require a fast and a slow part.  It 
 is
 + * this reason that clk_unprepare and clk_disable are not mutually exclusive.
 + * In fact clk_disable must be called before clk_unprepare.
 + */
 +void clk_disable(struct clk *clk)
 +{
 + unsigned long flags;
 +
 + spin_lock_irqsave(enable_lock, flags);
 + __clk_disable(clk);
 + spin_unlock_irqrestore(enable_lock, flags);
 +}
 +EXPORT_SYMBOL_GPL(clk_disable);
 +
 +static int __clk_enable(struct clk *clk)
 +{
 + int ret = 0;
 +
 + if (!clk)
 + return 0;
 +
 + if (WARN_ON(clk-prepare_count == 0))
 + return -ESHUTDOWN;
 +
 + if (clk-enable_count == 0) {
 + if (clk-parent)
 + ret = __clk_enable(clk-parent);
ditto
 +
 + if (ret)
 + return ret;
 +
 + if (clk-ops-enable) {
 + ret = clk-ops-enable(clk-hw);
 + if (ret) {
 + __clk_disable(clk-parent);
it's good case that don't check parent is NULL.
 + return ret;
 + }
 + }
 + }
 +
 + clk-enable_count++;
 + return 0;
 +}
 +
 +/**
 + * clk_enable - ungate a clock
 + * @clk: the clk being ungated
 + *
 + * clk_enable must not sleep, which differentiates it from clk_prepare.  In a
 + * simple case, clk_enable can be used instead of clk_prepare to ungate a clk
 + * if the operation will never sleep.  One example is a SoC-internal clk 
 which
 + * is controlled via simple register writes.  In the complex case a clk 
 ungate
 + * operation may require a fast and a slow part.  It is this reason that
 + * clk_enable and clk_prepare are not mutually exclusive.  In fact 
 clk_prepare
 + * must be called before clk_enable.  Returns 0 on success, -EERROR
 + * otherwise.
 + */
 +int clk_enable(struct clk *clk)
 +{
 + unsigned long flags;
 + int ret;
 +
 + spin_lock_irqsave(enable_lock, flags);
 + ret = __clk_enable(clk);
 + spin_unlock_irqrestore(enable_lock, flags);
 +
 + return ret;
 +}
 +EXPORT_SYMBOL_GPL(clk_enable);
 +
 +/**
 + * clk_get_rate - return the rate of clk
 + * @clk: the clk whose rate is being returned
 + *
 + * Simply returns the cached rate of the clk.  Does not query the hardware.  
 If
 + * clk is NULL then returns -EINVAL.
 + */
 +unsigned long clk_get_rate(struct clk *clk)
 +{
 + unsigned long rate;
 +
 + mutex_lock(prepare_lock);
 + rate = __clk_get_rate(clk);
 + mutex_unlock(prepare_lock);
 +
 + return rate;
 +}
 +EXPORT_SYMBOL_GPL(clk_get_rate);
 +
 +/**
 + * __clk_round_rate - round the given rate for a clk
 + * @clk: round the rate of this clock
 + *
 + * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate
 + */
 +unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
 +{
 + if (!clk  !clk-ops-round_rate)
be   || ?
 + return -EINVAL;
 +
 + return clk-ops-round_rate(clk-hw, rate, NULL);
 +}
 +
 +/**
 + * clk_round_rate - round the given rate for a clk
 + * @clk: the clk for which we are rounding a rate
 + * @rate: the rate which is to be rounded
 + *
 + * Takes in a rate as input and rounds it to a rate that the clk can actually
 + * use which is then returned.  If clk doesn't support round_rate operation
 + * then the rate passed in is returned.
 + */
 +long clk_round_rate(struct clk *clk, unsigned long rate)
 +{
 + unsigned long ret = rate;
 +
 + mutex_lock(prepare_lock);
 + if (clk  clk-ops-round_rate)
 + ret = __clk_round_rate(clk, rate);
 + mutex_unlock(prepare_lock);
 +
 + return ret;
If clk is NULL, clk_round_rate and __clk_round_rate return different
values. Do you mean it?
 +}
 +EXPORT_SYMBOL_GPL(clk_round_rate);
 +
 +/**
 + * __clk_notify - call clk notifier chain
 + * @clk: struct clk * that is changing rate
 + * @msg: clk notifier type (see include/linux/clk.h)
 + * @old_rate: old clk rate
 + * @new_rate: new clk 

Re: [PATCH v5 2/4] clk: Kconfig: add entry for HAVE_CLK_PREPARE

2012-03-04 Thread Richard Zhao
On Sat, Mar 03, 2012 at 12:28:59AM -0800, Mike Turquette wrote:
 The common clk framework provides clk_prepare and clk_unprepare
 implementations.  Create an entry for HAVE_CLK_PREPARE so that
 COMMON_CLK can select it.
 
 Signed-off-by: Mike Turquette mturque...@linaro.org
 Signed-off-by: Mike Turquette mturque...@ti.com
 Acked-by: Shawn Guo shawn@linaro.org
 Cc: Jeremy Kerr jeremy.k...@canonical.com
 Cc: Thomas Gleixner t...@linutronix.de
 Cc: Arnd Bergman arnd.bergm...@linaro.org
 Cc: Paul Walmsley p...@pwsan.com
 Cc: Richard Zhao richard.z...@linaro.org
 Cc: Saravana Kannan skan...@codeaurora.org
 Cc: Magnus Damm magnus.d...@gmail.com
 Cc: Rob Herring rob.herr...@calxeda.com
 Cc: Mark Brown broo...@opensource.wolfsonmicro.com
 Cc: Linus Walleij linus.wall...@stericsson.com
 Cc: Stephen Boyd sb...@codeaurora.org
 Cc: Amit Kucheria amit.kuche...@linaro.org
 Cc: Deepak Saxena dsax...@linaro.org
 Cc: Grant Likely grant.lik...@secretlab.ca
 Cc: Andrew Lunn and...@lunn.ch
 ---
  drivers/clk/Kconfig |3 +++
  1 files changed, 3 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
 index 9b3cd08..3912576 100644
 --- a/drivers/clk/Kconfig
 +++ b/drivers/clk/Kconfig
 @@ -8,3 +8,6 @@ config HAVE_CLK_PREPARE
  
  config HAVE_MACH_CLKDEV
   bool
 +
 +config HAVE_CLK_PREPARE
 + bool
We've already had it. redundant?

Thanks
Richard
 -- 
 1.7.5.4
 
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 2/2] cpufreq: OMAP: remove loops_per_jiffy recalculate for smp

2012-02-28 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/omap-cpufreq.c |   36 
 1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5d04c57..17da4c4 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -37,16 +37,6 @@
 
 #include mach/hardware.h
 
-#ifdef CONFIG_SMP
-struct lpj_info {
-   unsigned long   ref;
-   unsigned intfreq;
-};
-
-static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
-static struct lpj_info global_lpj_ref;
-#endif
-
 static struct cpufreq_frequency_table *freq_table;
 static atomic_t freq_table_users = ATOMIC_INIT(0);
 static struct clk *mpu_clk;
@@ -118,32 +108,6 @@ static int omap_target(struct cpufreq_policy *policy,
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
freqs.new = omap_getspeed(policy-cpu);
 
-#ifdef CONFIG_SMP
-   /*
-* Note that loops_per_jiffy is not updated on SMP systems in
-* cpufreq driver. So, update the per-CPU loops_per_jiffy value
-* on frequency transition. We need to update all dependent CPUs.
-*/
-   for_each_cpu(i, policy-cpus) {
-   struct lpj_info *lpj = per_cpu(lpj_ref, i);
-   if (!lpj-freq) {
-   lpj-ref = per_cpu(cpu_data, i).loops_per_jiffy;
-   lpj-freq = freqs.old;
-   }
-
-   per_cpu(cpu_data, i).loops_per_jiffy =
-   cpufreq_scale(lpj-ref, lpj-freq, freqs.new);
-   }
-
-   /* And don't forget to adjust the global one */
-   if (!global_lpj_ref.freq) {
-   global_lpj_ref.ref = loops_per_jiffy;
-   global_lpj_ref.freq = freqs.old;
-   }
-   loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
-   freqs.new);
-#endif
-
/* notifiers */
for_each_cpu(i, policy-cpus) {
freqs.cpu = i;
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 0/2] change lpj in arm smp common code

2012-02-28 Thread Richard Zhao
The two patches were originally in [PATCH V6 0/7] add a generic cpufreq driver.
I seperated them and hope they can go to upstream earlier.

Richard Zhao (2):
  ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp
  cpufreq: OMAP: remove loops_per_jiffy recalculate for smp

 arch/arm/kernel/smp.c  |   54 
 drivers/cpufreq/omap-cpufreq.c |   36 --
 2 files changed, 54 insertions(+), 36 deletions(-)

-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH 1/2] ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp

2012-02-28 Thread Richard Zhao
If CONFIG_SMP, cpufreq skips loops_per_jiffy update, because different
arch has different per-cpu loops_per_jiffy definition.

Signed-off-by: Richard Zhao richard.z...@linaro.org
Acked-by: Russell King rmk+ker...@arm.linux.org.uk
---
 arch/arm/kernel/smp.c |   54 +
 1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index cdeb727..4381bef 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -25,6 +25,7 @@
 #include linux/percpu.h
 #include linux/clockchips.h
 #include linux/completion.h
+#include linux/cpufreq.h
 
 #include linux/atomic.h
 #include asm/cacheflush.h
@@ -599,3 +600,56 @@ int setup_profiling_timer(unsigned int multiplier)
 {
return -EINVAL;
 }
+
+#ifdef CONFIG_CPU_FREQ
+
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq);
+static unsigned long global_l_p_j_ref;
+static unsigned long global_l_p_j_ref_freq;
+
+static int cpufreq_callback(struct notifier_block *nb,
+   unsigned long val, void *data)
+{
+   struct cpufreq_freqs *freq = data;
+   int cpu = freq-cpu;
+
+   if (freq-flags  CPUFREQ_CONST_LOOPS)
+   return NOTIFY_OK;
+
+   if (!per_cpu(l_p_j_ref, cpu)) {
+   per_cpu(l_p_j_ref, cpu) =
+   per_cpu(cpu_data, cpu).loops_per_jiffy;
+   per_cpu(l_p_j_ref_freq, cpu) = freq-old;
+   if (!global_l_p_j_ref) {
+   global_l_p_j_ref = loops_per_jiffy;
+   global_l_p_j_ref_freq = freq-old;
+   }
+   }
+
+   if ((val == CPUFREQ_PRECHANGE   freq-old  freq-new) ||
+   (val == CPUFREQ_POSTCHANGE  freq-old  freq-new) ||
+   (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
+   loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
+   global_l_p_j_ref_freq,
+   freq-new);
+   per_cpu(cpu_data, cpu).loops_per_jiffy =
+   cpufreq_scale(per_cpu(l_p_j_ref, cpu),
+   per_cpu(l_p_j_ref_freq, cpu),
+   freq-new);
+   }
+   return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_notifier = {
+   .notifier_call  = cpufreq_callback,
+};
+
+static int __init register_cpufreq_notifier(void)
+{
+   return cpufreq_register_notifier(cpufreq_notifier,
+   CPUFREQ_TRANSITION_NOTIFIER);
+}
+core_initcall(register_cpufreq_notifier);
+
+#endif
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V6 4/7] cpufreq: add clk-reg cpufreq driver

2012-01-12 Thread Richard Zhao
On Wed, Jan 11, 2012 at 03:22:34PM -0800, Kevin Hilman wrote:
 Richard Zhao richard.z...@linaro.org writes:
 
  The driver get cpu operation point table from device tree cpu0 node,
 
 Since we already have an existing OPP infrastructure in the kernel,
 seems like  this driver should get OPPs by asking the OPP layer.
When I created the patch, there's only omap cpufreq driver using
OPP. If it depends on OPP, it might prevent users who have not
adopted OPP from using the driver.
 
 This approach assumes the OPP layer is static at boot time and not
 changing, however that's not the case in practice.
 
 The OPP layer could be extended to read boot-time OPPs from DT if
 desired, but since the OPPs are also populated/enabled/disabled
 dynamicaly on some platforms (e.g. OMAP), I think the any generic
 CPUfreq driver should use the OPP interface and not DT directly.
 
  and adjusts operating points using clk and regulator APIs.
 
 For a generic driver, the regulator used should also be configurable.
 
 For example, this driver currently assumes a regulator named cpu for
 all instances.   If you had separate clusters with independent voltage
 control, you'd likely have a separate regulator for each cluster.
The driver, for now, assumes all cpu cores uses the same clk and voltage.
It's correct for most arm multi-core SoC.
Do you have real case to need different voltage/clk?
And the regulator will be specified in dts after cpu convert from sys
device to normal device.

Thanks
Richard
 
 Kevin
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V6 0/7] add a generic cpufreq driver

2012-01-09 Thread Richard Zhao
On Fri, Jan 06, 2012 at 08:53:37AM +0800, Richard Zhao wrote:
 On Thu, Jan 05, 2012 at 06:16:54AM +0800, Richard Zhao wrote:
  hi Russell,
  
  May I have your ACK, you merge it?
 Russell, ping
would you have time to look at this patch series?
  
  Thanks
  Richard
  
  ___
  linux-arm-kernel mailing list
  linux-arm-ker...@lists.infradead.org
  http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
  
 
 
 ___
 linaro-dev mailing list
 linaro-dev@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V6 0/7] add a generic cpufreq driver

2012-01-05 Thread Richard Zhao
On Thu, Jan 05, 2012 at 06:16:54AM +0800, Richard Zhao wrote:
 hi Russell,
 
 May I have your ACK, you merge it?
Russell, ping
 
 Thanks
 Richard
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V6 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate for smp

2012-01-05 Thread Richard Zhao
Hi Sascha  Shawn,

Could you look and ack the patch?

Thanks
Richard 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V6 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for smp

2012-01-05 Thread Richard Zhao
Hi Kevin,

Could you please look at and ack the patch if possible?
Sorry, I didn't cc you.

Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V6 0/7] add a generic cpufreq driver

2012-01-04 Thread Richard Zhao
hi Russell,

May I have your ACK, you merge it?

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 3/6] clk: introduce the common clock framework

2012-01-04 Thread Richard Zhao
On Wed, Jan 04, 2012 at 05:01:43PM -0800, Turquette, Mike wrote:
 On Wed, Jan 4, 2012 at 6:32 AM, Rob Herring robherri...@gmail.com wrote:
  On 01/03/2012 08:15 PM, Richard Zhao wrote:
  On Fri, Dec 16, 2011 at 04:45:48PM -0800, Turquette, Mike wrote:
  On Wed, Dec 14, 2011 at 5:18 AM, Thomas Gleixner t...@linutronix.de 
  wrote:
  On Tue, 13 Dec 2011, Mike Turquette wrote:
 
  snip
 
  +/**
  + * clk_init - initialize the data structures in a struct clk
  + * @dev: device initializing this clk, placeholder for now
  + * @clk: clk being initialized
  + *
  + * Initializes the lists in struct clk, queries the hardware for the
  + * parent and rate and sets them both.  Adds the clk to the sysfs tree
  + * topology.
  + *
  + * Caller must populate clk-name and clk-flags before calling
 
  I'm not too happy about this construct. That leaves struct clk and its
  members exposed to the world instead of making it a real opaque
  cookie. I know from my own painful experience, that this will lead to
  random fiddling in that data structure in drivers and arch code just
  because the core code has a shortcoming.
 
  Why can't we make struct clk a real cookie and confine the data
  structure to the core code ?
 
  That would change the init call to something like:
 
  struct clk *clk_init(struct device *dev, const struct clk_hw *hw,
                      struct clk *parent)
 
  And have:
  struct clk_hw {
        struct clk_hw_ops *ops;
        const char        *name;
        unsigned long     flags;
  };
 
  Implementers can do:
  struct my_clk_hw {
        struct clk_hw    hw;
        mydata;
  };
 
  And then change the clk ops callbacks to take struct clk_hw * as an
  argument.
  We have to define static clocks before we adopt DT binding.
  If clk is opaque and allocate memory in clk core, it'll make hard
  to define static clocks. And register/init will pass a long parameter
  list.
 
  DT is not a prerequisite for having dynamically created clocks. You can
  make clock init dynamic without DT.
I can not find clock info at runtime without DT. If I use static info, I
find it was hard/strange to define and register it, using Mike's early patches.
 
 Agreed.
 
  What data goes in struct clk vs. struct clk_hw could change over time.
  So perhaps we can start with some data in clk_hw and plan to move it to
  struct clk later. Even if almost everything ends up in clk_hw initially,
  at least the structure is in place to have common, core-only data
  separate from platform data.
 
 What is the point of this?
 
 The original clk_hw was defined simply as:
 
 struct clk_hw {
 struct clk *clk;
 };
 
 It's only purpose in life was as a handle for navigation between the
 opaque struct clk and the hardware-specific struct my_clk_hw.  struct
 clk_hw is defined in clk.h and everyone can see it.  If we're suddenly
 OK putting clk data in this structure then why bother with an opaque
 struct clk at all?
I think Rob meant one time a step to make it opaque. But it'll make
clk core always changing, easier mess, and let clk driver confused.
 
  What is the actual data you need to be static and accessible to the
  platform code? A ptr to parent clk is the main thing I've seen for
  static initialization. So make the parent ptr be struct clk_hw* and
  allow the platforms to access.
 
 To answer your question on what data we're trying to expose: platform
 code commonly needs the parent pointer and the clk rate (and by
 extension, the rate of the parent).  For debug/error prints it is also
 nice to have the clk name.  Generic clk flags are also conceivably
 something that platform code might want.
 
 I'd like to spin the question around: if we're OK exposing some stuff
 (in your example above, the parent pointer), then what clk data are
 you trying to hide?
 
 Regards,
 Mike
 
 
  Rob
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 4/7] cpufreq: add clk-reg cpufreq driver

2012-01-03 Thread Richard Zhao
Hi Russel,

On 3 January 2012 17:06, Russell King - ARM Linux
li...@arm.linux.org.uk wrote:
 On Mon, Dec 26, 2011 at 09:44:52PM +0800, Richard Zhao wrote:
 On Mon, Dec 26, 2011 at 11:10:30AM +, Mark Brown wrote:
  The *call* is there in the regulator subsystem, it's just that none of
  the drivers back it up with an actual implementation yet.  Which turns
  out to be a good thing as cpufreq can't currently understand variable
  latencies and the governors don't deal well with non-trivial latencies
  anyway.
 but clk API don't have such calls. and many SoCs only adjust clk 
 frequencies, using
 one single voltage.

 That's because it's often not known - especially in the case of PLLs,
 data sheets don't tend to specify how long it takes for the PLL to relock
 after a requested change.  If it's important that the PLL be locked,
 there will be a bit to poll (or they'll cause the CPU itself to stall
 while the PLL is not locked.)

 So, for these kinds of situations, how do you suggest that the clk API
 provides this information?
In latest v6 version, I get clk transition latency from dt property, and get
regulator transition latency from regulator API.
Could you please help review other arm common changes in v6 version?

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 4/7] cpufreq: add clk-reg cpufreq driver

2012-01-03 Thread Richard Zhao
On 3 January 2012 21:47, Russell King - ARM Linux
li...@arm.linux.org.uk wrote:
 On Tue, Jan 03, 2012 at 09:25:30PM +0800, Richard Zhao wrote:
 Hi Russel,

 On 3 January 2012 17:06, Russell King - ARM Linux
 li...@arm.linux.org.uk wrote:
  On Mon, Dec 26, 2011 at 09:44:52PM +0800, Richard Zhao wrote:
  On Mon, Dec 26, 2011 at 11:10:30AM +, Mark Brown wrote:
   The *call* is there in the regulator subsystem, it's just that none of
   the drivers back it up with an actual implementation yet.  Which turns
   out to be a good thing as cpufreq can't currently understand variable
   latencies and the governors don't deal well with non-trivial latencies
   anyway.
  but clk API don't have such calls. and many SoCs only adjust clk 
  frequencies, using
  one single voltage.
 
  That's because it's often not known - especially in the case of PLLs,
  data sheets don't tend to specify how long it takes for the PLL to relock
  after a requested change.  If it's important that the PLL be locked,
  there will be a bit to poll (or they'll cause the CPU itself to stall
  while the PLL is not locked.)
 
  So, for these kinds of situations, how do you suggest that the clk API
  provides this information?
 In latest v6 version, I get clk transition latency from dt property, and get
 regulator transition latency from regulator API.
 Could you please help review other arm common changes in v6 version?

 You didn't get my point: how do you specify a clock transition latency
 for a clock with a PLL when the data sheets don't tell you what that is,
 and they instead give you a bit to poll?
clk-trans-latency is not a MUST property. If the datasheet don't provide it or
you don't want to measure, you may not specify the property. In such case
cpufreq governor ondemand and conservative will not work, because they
can not determine the sample rate without the latency value.

 Do you:

 (a) make up some number and hope that it's representative
No, I always get it from dt.

 (b) not specify any transition latency
It's allowed.

 (c) think about the problem _now_ and define what it means for a clock
    without a transition latency.
It's ondemand/conservative governors that strongly need the latency value.
If user don't want to use it, it's fine.

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 3/6] clk: introduce the common clock framework

2012-01-03 Thread Richard Zhao
On Fri, Dec 16, 2011 at 04:45:48PM -0800, Turquette, Mike wrote:
 On Wed, Dec 14, 2011 at 5:18 AM, Thomas Gleixner t...@linutronix.de wrote:
  On Tue, 13 Dec 2011, Mike Turquette wrote:
  +void __clk_unprepare(struct clk *clk)
  +{
  +     if (!clk)
  +             return;
  +
  +     if (WARN_ON(clk-prepare_count == 0))
  +             return;
  +
  +     if (--clk-prepare_count  0)
  +             return;
  +
  +     WARN_ON(clk-enable_count  0);
 
  So this leaves the clock enable count set. I'm a bit wary about
  that. Shouldn't it either return (including bumping the prepare_count
  again) or call clk_disable() ?
 
 I've hit this in my port of OMAP.  It comes from this simple situation:
 
 driver 1 (adapted for clk_prepare/clk_unprepare):
 clk_prepare(clk);
 clk_enable(clk);
 
 ...
 
 driver2 (not adapted for clk_prepare/clk_unprepare):
 clk_enable(clk);
 
 ...
 
 driver1:
 clk_disable(clk);
 clk_unprepare(clk);
 
 In such a case we don't want to bump the prepare_count, since the
 offending driver2 won't decrement that count.  Also we don't want to
 shut down that clk since driver2 is using it.
 
 Returning after the WARN is maybe OK, but the point of this check is
 really to find code which hasn't yet been made prepare-aware, and the
 current implementation is noisy enough about it.
 
  +/**
  + * clk_get_parent - return the parent of a clk
  + * @clk: the clk whose parent gets returned
  + *
  + * Simply returns clk-parent.  It is up to the caller to hold the
  + * prepare_lock, if desired.  Returns NULL if clk is NULL.
 
  Holding the prepare lock in the caller will deadlock. So it's not a
  real good idea to document it as an option :)
 
 Oops.  That comment is left over from before clk_get_parent held the
 lock.  Will remove.
 
 
  + */
  +struct clk *clk_get_parent(struct clk *clk)
  +{
  +     struct clk *parent;
  +
  +     if (!clk)
  +             return NULL;
  +
  +     mutex_lock(prepare_lock);
 
  +/**
  + * clk_init - initialize the data structures in a struct clk
  + * @dev: device initializing this clk, placeholder for now
  + * @clk: clk being initialized
  + *
  + * Initializes the lists in struct clk, queries the hardware for the
  + * parent and rate and sets them both.  Adds the clk to the sysfs tree
  + * topology.
  + *
  + * Caller must populate clk-name and clk-flags before calling
 
  I'm not too happy about this construct. That leaves struct clk and its
  members exposed to the world instead of making it a real opaque
  cookie. I know from my own painful experience, that this will lead to
  random fiddling in that data structure in drivers and arch code just
  because the core code has a shortcoming.
 
  Why can't we make struct clk a real cookie and confine the data
  structure to the core code ?
 
  That would change the init call to something like:
 
  struct clk *clk_init(struct device *dev, const struct clk_hw *hw,
                      struct clk *parent)
 
  And have:
  struct clk_hw {
        struct clk_hw_ops *ops;
        const char        *name;
        unsigned long     flags;
  };
 
  Implementers can do:
  struct my_clk_hw {
        struct clk_hw    hw;
        mydata;
  };
 
  And then change the clk ops callbacks to take struct clk_hw * as an
  argument.
We have to define static clocks before we adopt DT binding.
If clk is opaque and allocate memory in clk core, it'll make hard
to define static clocks. And register/init will pass a long parameter
list.
 
  So the core code can allocate the clk data structure and you return a
  real opaque cookie. You do the same thing for the basic gated clock in
  one of the next patches, so doing it for struct clk itself is just
  consequent.
 
 The opaque cookie would work if platform code never needs any
 information outside of the data a single clk_hw_whatever provides.
 Unfortunately hardware doesn't make things that easy on us and the
 operations we do for a single clk are affected by the state of other
 clks.
 
 Here is an example I've been using a lot lately: on OMAP we have two
 clock inputs to our PLLs: a bypass clk and reference clk (actually we
 can have more than this).  When changing the PLL rate both clks must
 be enabled, regardless of which clk ends up driving the PLL.  To
 illustrate, the PLL may be driven by clk_ref at 400MHz, and then we
 call clk_set_rate(pll_clk, 19600); which will also leave it
 clocked by clk_ref but at 196MHz.  For this to happen however, the
 clk_bypass had to be enabled during the rate change operation.  Here
 is the relevant .set_rate implementation:
 http://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=blob;f=arch/arm/mach-omap2/dpll3xxx.c;h=b2412574b63829944593c1a7a6eda5fa4350686f;hb=738bde65918ae1ac743b1498801da0b860e2ee32#l461
 
 In order for the OMAP platform code to do this, we have to have two
 things: firstly we need the struct clk so that we can call
 clk_enable/disable and __clk_prepare/unprepare on the ref and bypass
 clks from within .set_rate.  The 

[PATCH V6 5/7] dts/imx6q: add cpufreq property

2011-12-29 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/boot/dts/imx6q.dtsi |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 263e8f3..d89b42d 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -29,6 +29,13 @@
compatible = arm,cortex-a9;
reg = 0;
next-level-cache = L2;
+   cpu-freqs = 99600 79200 39600 19800;
+   cpu-volts =/* min  max */
+   1225000 145 /* 996M */
+   110 145 /* 792M */
+   95  145 /* 396M */
+   85  145; /* 198M */
+   clk-trans-latency = 61036; /* two CLK32 periods */
};
 
cpu@1 {
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V6 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ

2011-12-29 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c44aa97..39cf00a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -595,6 +595,7 @@ comment i.MX6 family:
 
 config SOC_IMX6Q
bool i.MX6 Quad support
+   select ARCH_HAS_CPUFREQ
select ARM_GIC
select CACHE_L2X0
select CPU_V7
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V6 0/7] add a generic cpufreq driver

2011-12-29 Thread Richard Zhao
The driver is based on clock and regulator APIs and  support single core
and multi core ARM SoCs. For multi core, it assume all cores share the
same clock and voltage.

Thanks Arnd, Mark, Jamie, Shawn, Rob, for your review.

Changes in V6:
 - add scaling_available_freqs

Changes in V5:
 - add more comments
 - rename trans-latency to clk-trans-latency, and it only describe clk
   latency. Regulator latency is got from regulator_set_voltage_time.

Changes in v4:
 - add depends on HAVE_CLK  OF  REGULATOR
 - add set_cpu_freq fail check
 - regulator_put wehn module exit
 - add pr_fmt and convert all printk to pr_xxx
 - use voltage range
 - comment and doc fix
 - add cpu_volts value pre-check in module init
 - add helpfull module parameter max_freq
 - remove compatible string check on Arnd's comment.
 - remove generic-cpufreq to clk-reg-cpufreq

Changes in v3:
 - move adjusting smp loops_per_jiffy to arm common code,
   and also adjust global loops_per_jiffy.
 - remove adjusting loops_per_jiffy in imx and omap cpufreq drivers.
 - check compatible generic-cpufreq when module_init
 - change printk to pr_xxx
 - add generic-cpufreq DT binding doc

Changes in v2:
 - add volatage change support
 - change '_' in property name to '-'
 - use initial value to calculate loops_per_jiffy
 - fix reading cpu_volts property bug 
 - let cpufreq_frequency_table_cpuinfo routines handle cpu_freq_khz_max/min
 - don't change freq in arm_cpufreq_exit, because every core share the same 
freq.
 - use unsigned long describe frequency as much as possible. Because clk use
   unsigned long, but cpufreq use unsigned int.

[PATCH V6 1/7] ARM: add cpufreq transiton notifier to adjust
[PATCH V6 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate
[PATCH V6 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for
[PATCH V6 4/7] cpufreq: add clk-reg cpufreq driver
[PATCH V6 5/7] dts/imx6q: add cpufreq property
[PATCH V6 6/7] arm/imx6q: register arm_clk as cpu to clkdev
[PATCH V6 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ

Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V6 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for smp

2011-12-29 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/omap-cpufreq.c |   36 
 1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5d04c57..17da4c4 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -37,16 +37,6 @@
 
 #include mach/hardware.h
 
-#ifdef CONFIG_SMP
-struct lpj_info {
-   unsigned long   ref;
-   unsigned intfreq;
-};
-
-static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
-static struct lpj_info global_lpj_ref;
-#endif
-
 static struct cpufreq_frequency_table *freq_table;
 static atomic_t freq_table_users = ATOMIC_INIT(0);
 static struct clk *mpu_clk;
@@ -118,32 +108,6 @@ static int omap_target(struct cpufreq_policy *policy,
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
freqs.new = omap_getspeed(policy-cpu);
 
-#ifdef CONFIG_SMP
-   /*
-* Note that loops_per_jiffy is not updated on SMP systems in
-* cpufreq driver. So, update the per-CPU loops_per_jiffy value
-* on frequency transition. We need to update all dependent CPUs.
-*/
-   for_each_cpu(i, policy-cpus) {
-   struct lpj_info *lpj = per_cpu(lpj_ref, i);
-   if (!lpj-freq) {
-   lpj-ref = per_cpu(cpu_data, i).loops_per_jiffy;
-   lpj-freq = freqs.old;
-   }
-
-   per_cpu(cpu_data, i).loops_per_jiffy =
-   cpufreq_scale(lpj-ref, lpj-freq, freqs.new);
-   }
-
-   /* And don't forget to adjust the global one */
-   if (!global_lpj_ref.freq) {
-   global_lpj_ref.ref = loops_per_jiffy;
-   global_lpj_ref.freq = freqs.old;
-   }
-   loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
-   freqs.new);
-#endif
-
/* notifiers */
for_each_cpu(i, policy-cpus) {
freqs.cpu = i;
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V6 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-29 Thread Richard Zhao
The driver get cpu operation point table from device tree cpu0 node,
and adjusts operating points using clk and regulator APIs.

It support single core and multi-core ARM SoCs. But currently it assume
all cores share the same frequency and voltage.

Signed-off-by: Richard Zhao richard.z...@linaro.org
Reviewed-by: Jamie Iles ja...@jamieiles.com
Reviewed-by: Mark Brown broo...@opensource.wolfsonmicro.com
Acked-by: Shawn Guo shawn@linaro.org
---
 .../devicetree/bindings/cpufreq/clk-reg-cpufreq|   21 ++
 drivers/cpufreq/Kconfig|   10 +
 drivers/cpufreq/Makefile   |2 +
 drivers/cpufreq/clk-reg-cpufreq.c  |  308 
 4 files changed, 341 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
 create mode 100644 drivers/cpufreq/clk-reg-cpufreq.c

diff --git a/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq 
b/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
new file mode 100644
index 000..e8dc763
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
@@ -0,0 +1,21 @@
+Generic cpufreq driver based on clk and regulator APIs
+
+Required properties in /cpus/cpu@0:
+- cpu-freqs : cpu frequency points it supports, in unit of Hz.
+ Each point takes on cell.
+- cpu-volts : cpu voltage ranges required by the frequency points
+ at the same index, in unit of uV.
+ Each range takes two cells, one for min, the other for max.
+- clk-trans-latency :  cpu clk transition latency, in unit of ns.
+ It takes one cell.
+
+An example:
+cpu@0 {
+   cpu-freqs = 99600 79200 39600 19800;
+   cpu-volts =/* min  max */
+   1225000 145 /* 996M */
+   110 145 /* 792M */
+   95  145 /* 396M */
+   85  145; /* 198M */
+   clk-trans-latency = 61036; /* two CLK32 periods */
+};
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index e24a2a1..95470f1 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -179,6 +179,16 @@ config CPU_FREQ_GOV_CONSERVATIVE
 
  If in doubt, say N.
 
+config CLK_REG_CPUFREQ_DRIVER
+   tristate Generic cpufreq driver using clk and regulator APIs
+   depends on HAVE_CLK  OF  REGULATOR
+   select CPU_FREQ_TABLE
+   help
+ This adds generic CPUFreq driver based on clk and regulator APIs.
+ It assumes all cores of the CPU share the same clock and voltage.
+
+ If in doubt, say N.
+
 menu x86 CPU frequency scaling drivers
 depends on X86
 source drivers/cpufreq/Kconfig.x86
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ce75fcb..2c4eb33 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)   += 
cpufreq_conservative.o
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)   += freq_table.o
 
+obj-$(CONFIG_CLK_REG_CPUFREQ_DRIVER)   += clk-reg-cpufreq.o
+
 
##
 # x86 drivers.
 # Link order matters. K8 is preferred to ACPI because of firmware bugs in early
diff --git a/drivers/cpufreq/clk-reg-cpufreq.c 
b/drivers/cpufreq/clk-reg-cpufreq.c
new file mode 100644
index 000..77c4408
--- /dev/null
+++ b/drivers/cpufreq/clk-reg-cpufreq.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#define pr_fmt(fmt)KBUILD_MODNAME :  fmt
+
+#include linux/module.h
+#include linux/cpufreq.h
+#include linux/clk.h
+#include linux/regulator/consumer.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/of.h
+
+static u32 *cpu_freqs; /* Hz */
+static u32 *cpu_volts; /* uV */
+static u32 trans_latency; /* ns */
+static int cpu_op_nr;
+static unsigned int cur_index;
+
+static struct clk *cpu_clk;
+static struct regulator *cpu_reg;
+static struct cpufreq_frequency_table *freq_table;
+
+static int set_cpu_freq(unsigned long freq, int index, int higher)
+{
+   int ret = 0;
+
+   if (higher  cpu_reg) {
+   ret = regulator_set_voltage(cpu_reg,
+   cpu_volts[index * 2], cpu_volts[index * 2 + 1]);
+   if (ret) {
+   pr_err(set cpu voltage failed!\n);
+   return ret;
+   }
+   }
+
+   ret = clk_set_rate

Re: [PATCH V5 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-28 Thread Richard Zhao
On Wed, Dec 28, 2011 at 11:42:37AM +, Mark Brown wrote:
 On Wed, Dec 28, 2011 at 11:31:29AM +0800, Richard Zhao wrote:
  On Wed, Dec 28, 2011 at 11:14:10AM +0800, Richard Zhao wrote:
 
+   if (cpu_reg) {
+   ret = regulator_is_supported_voltage(cpu_reg,
+   cpu_volts[i * 2], cpu_volts[i * 
2 + 1]);
 
   Is there any reason you didn't export symbol 
   regulator_is_supported_voltage?
   and also it don't have !REGULATOR dummy implementation.
 
  regulator_set_voltage_time and some other functions don't have dummy one
  either.
 
 You can't usefully work with voltages without knowing what the actual
 voltages are - the only sensible stubs we could provide would return
 errors but then any driver using the stubs would probably fail to do
 whatever it was doing.  With enable and disable we can sensibly stub
 things out with an always on regulator.
Sorry, I can not get your point here. Let me describe the problem I met:
 - regulator_is_supported_voltage is not exported. when I build clk-reg-cpufreq
   as kernel module, there's a link error.
 - I saw linux/regulator/consumer.h has some dummy functions if !REGULATOR. I
   tried to make clk-reg-cpufreq driver work even !REGULATOR. I think that's
   why the dummy functions are there. If regulator_get return NULL, it'll avoid
   calling other regulator functions. But regulator_is_supported_voltage and
   regulator_set_voltage_time don't have such dummy ones. Undefined functions.

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V5 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-28 Thread Richard Zhao
There's still a bug that, after rmmod module, cpu0 still has cpufreq
sysfs entry.

cpufreq_unregister_driver can not clean up everything.

unfortunately, I don't have much time to debug cpufreq core.

Log:
root@ubuntu:~# insmod /clk-reg-cpufreq.ko 
clk_reg_cpufreq: regulator cpu get failed.
trying to register driver clk-reg
adding CPU 0
CPU 1 already managed, adding link
CPU 2 already managed, adding link
CPU 3 already managed, adding link
setting new policy for CPU 0: 198000 - 996000 kHz
new min and max freqs are 198000 - 996000 kHz
governor switch
__cpufreq_governor for CPU 0, event 1
governor: change or update limits
__cpufreq_governor for CPU 0, event 3
target for CPU 0: 792000 kHz, relation 0
initialization complete
adding CPU 1
adding CPU 2
adding CPU 3
driver clk-reg up and running
root@ubuntu:~# 
root@ubuntu:~# 
root@ubuntu:~# 
root@ubuntu:~# rmmod clk-reg-cpufreq
unregistering driver clk-reg
unregistering CPU 0
removing link for cpu 1
removing link for cpu 2
removing link for cpu 3
__cpufreq_governor for CPU 0, event 2
last reference is dropped
waiting for dropping of refcount
wait complete
adding CPU 1
Restoring governor userspace for cpu 1
CPU 0 already managed, adding link
CPU 2 already managed, adding link
CPU 3 already managed, adding link
setting new policy for CPU 1: 198000 - 996000 kHz
new min and max freqs are 198000 - 996000 kHz
governor switch
__cpufreq_governor for CPU 1, event 1
governor: change or update limits
__cpufreq_governor for CPU 1, event 3
target for CPU 1: 792000 kHz, relation 0
initialization complete
unregistering CPU 0
removing link
unregistering CPU 1
removing link for cpu 2
removing link for cpu 3
__cpufreq_governor for CPU 1, event 2
last reference is dropped
waiting for dropping of refcount
wait complete
adding CPU 2
Restoring governor userspace for cpu 2
CPU 0 already managed, adding link
CPU 1 already managed, adding link
CPU 3 already managed, adding link
setting new policy for CPU 2: 198000 - 996000 kHz
new min and max freqs are 198000 - 996000 kHz
governor switch
__cpufreq_governor for CPU 2, event 1
governor: change or update limits
__cpufreq_governor for CPU 2, event 3
target for CPU 2: 792000 kHz, relation 0
initialization complete
unregistering CPU 1
removing link
unregistering CPU 2
removing link for cpu 0
removing link for cpu 3
__cpufreq_governor for CPU 2, event 2
last reference is dropped
waiting for dropping of refcount
wait complete
adding CPU 0
Restoring governor userspace for cpu 0
CPU 1 already managed, adding link
CPU 2 already managed, adding link
CPU 3 already managed, adding link
setting new policy for CPU 0: 198000 - 996000 kHz
new min and max freqs are 198000 - 996000 kHz
governor switch
__cpufreq_governor for CPU 0, event 1
governor: change or update limits
__cpufreq_governor for CPU 0, event 3
target for CPU 0: 792000 kHz, relation 0
initialization complete
unregistering CPU 2
removing link
unregistering CPU 3
removing link


Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V5 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for smp

2011-12-27 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/omap-cpufreq.c |   36 
 1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5d04c57..17da4c4 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -37,16 +37,6 @@
 
 #include mach/hardware.h
 
-#ifdef CONFIG_SMP
-struct lpj_info {
-   unsigned long   ref;
-   unsigned intfreq;
-};
-
-static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
-static struct lpj_info global_lpj_ref;
-#endif
-
 static struct cpufreq_frequency_table *freq_table;
 static atomic_t freq_table_users = ATOMIC_INIT(0);
 static struct clk *mpu_clk;
@@ -118,32 +108,6 @@ static int omap_target(struct cpufreq_policy *policy,
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
freqs.new = omap_getspeed(policy-cpu);
 
-#ifdef CONFIG_SMP
-   /*
-* Note that loops_per_jiffy is not updated on SMP systems in
-* cpufreq driver. So, update the per-CPU loops_per_jiffy value
-* on frequency transition. We need to update all dependent CPUs.
-*/
-   for_each_cpu(i, policy-cpus) {
-   struct lpj_info *lpj = per_cpu(lpj_ref, i);
-   if (!lpj-freq) {
-   lpj-ref = per_cpu(cpu_data, i).loops_per_jiffy;
-   lpj-freq = freqs.old;
-   }
-
-   per_cpu(cpu_data, i).loops_per_jiffy =
-   cpufreq_scale(lpj-ref, lpj-freq, freqs.new);
-   }
-
-   /* And don't forget to adjust the global one */
-   if (!global_lpj_ref.freq) {
-   global_lpj_ref.ref = loops_per_jiffy;
-   global_lpj_ref.freq = freqs.old;
-   }
-   loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
-   freqs.new);
-#endif
-
/* notifiers */
for_each_cpu(i, policy-cpus) {
freqs.cpu = i;
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V5 0/7] add a generic cpufreq driver

2011-12-27 Thread Richard Zhao
The driver is based on clock and regulator APIs and  support single core
and multi core ARM SoCs. For multi core, it assume all cores share the
same clock and voltage.

Thanks Arnd, Mark, Jamie, Rob, for your review.

Changes in V5:
 - add more comments
 - rename trans-latency to clk-trans-latency, and it only describe clk
   latency. Regulator latency is got from regulator_set_voltage_time.

Changes in v4:
 - add depends on HAVE_CLK  OF  REGULATOR
 - add set_cpu_freq fail check
 - regulator_put wehn module exit
 - add pr_fmt and convert all printk to pr_xxx
 - use voltage range
 - comment and doc fix
 - add cpu_volts value pre-check in module init
 - add helpfull module parameter max_freq
 - remove compatible string check on Arnd's comment.
 - remove generic-cpufreq to clk-reg-cpufreq

Changes in v3:
 - move adjusting smp loops_per_jiffy to arm common code,
   and also adjust global loops_per_jiffy.
 - remove adjusting loops_per_jiffy in imx and omap cpufreq drivers.
 - check compatible generic-cpufreq when module_init
 - change printk to pr_xxx
 - add generic-cpufreq DT binding doc

Changes in v2:
 - add volatage change support
 - change '_' in property name to '-'
 - use initial value to calculate loops_per_jiffy
 - fix reading cpu_volts property bug 
 - let cpufreq_frequency_table_cpuinfo routines handle cpu_freq_khz_max/min
 - don't change freq in arm_cpufreq_exit, because every core share the same 
freq.
 - use unsigned long describe frequency as much as possible. Because clk use
   unsigned long, but cpufreq use unsigned int.


[PATCH V5 1/7] ARM: add cpufreq transiton notifier to adjust
[PATCH V5 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate
[PATCH V5 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for
[PATCH V5 4/7] cpufreq: add clk-reg cpufreq driver
[PATCH V5 5/7] dts/imx6q: add cpufreq property
[PATCH V5 6/7] arm/imx6q: register arm_clk as cpu to clkdev
[PATCH V5 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ

Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V5 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-27 Thread Richard Zhao
The driver get cpu operation point table from device tree cpu0 node,
and adjusts operating points using clk and regulator APIs.

It support single core and multi-core ARM SoCs. But currently it assume
all cores share the same frequency and voltage.

Signed-off-by: Richard Zhao richard.z...@linaro.org
Reviewed-by: Jamie Iles ja...@jamieiles.com
Reviewed-by: Mark Brown broo...@opensource.wolfsonmicro.com
---
 .../devicetree/bindings/cpufreq/clk-reg-cpufreq|   21 ++
 drivers/cpufreq/Kconfig|   10 +
 drivers/cpufreq/Makefile   |2 +
 drivers/cpufreq/clk-reg-cpufreq.c  |  302 
 4 files changed, 335 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
 create mode 100644 drivers/cpufreq/clk-reg-cpufreq.c

diff --git a/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq 
b/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
new file mode 100644
index 000..e8dc763
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
@@ -0,0 +1,21 @@
+Generic cpufreq driver based on clk and regulator APIs
+
+Required properties in /cpus/cpu@0:
+- cpu-freqs : cpu frequency points it supports, in unit of Hz.
+ Each point takes on cell.
+- cpu-volts : cpu voltage ranges required by the frequency points
+ at the same index, in unit of uV.
+ Each range takes two cells, one for min, the other for max.
+- clk-trans-latency :  cpu clk transition latency, in unit of ns.
+ It takes one cell.
+
+An example:
+cpu@0 {
+   cpu-freqs = 99600 79200 39600 19800;
+   cpu-volts =/* min  max */
+   1225000 145 /* 996M */
+   110 145 /* 792M */
+   95  145 /* 396M */
+   85  145; /* 198M */
+   clk-trans-latency = 61036; /* two CLK32 periods */
+};
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index e24a2a1..95470f1 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -179,6 +179,16 @@ config CPU_FREQ_GOV_CONSERVATIVE
 
  If in doubt, say N.
 
+config CLK_REG_CPUFREQ_DRIVER
+   tristate Generic cpufreq driver using clk and regulator APIs
+   depends on HAVE_CLK  OF  REGULATOR
+   select CPU_FREQ_TABLE
+   help
+ This adds generic CPUFreq driver based on clk and regulator APIs.
+ It assumes all cores of the CPU share the same clock and voltage.
+
+ If in doubt, say N.
+
 menu x86 CPU frequency scaling drivers
 depends on X86
 source drivers/cpufreq/Kconfig.x86
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ce75fcb..2c4eb33 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)   += 
cpufreq_conservative.o
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)   += freq_table.o
 
+obj-$(CONFIG_CLK_REG_CPUFREQ_DRIVER)   += clk-reg-cpufreq.o
+
 
##
 # x86 drivers.
 # Link order matters. K8 is preferred to ACPI because of firmware bugs in early
diff --git a/drivers/cpufreq/clk-reg-cpufreq.c 
b/drivers/cpufreq/clk-reg-cpufreq.c
new file mode 100644
index 000..4b28fdd
--- /dev/null
+++ b/drivers/cpufreq/clk-reg-cpufreq.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#define pr_fmt(fmt)KBUILD_MODNAME :  fmt
+
+#include linux/module.h
+#include linux/cpufreq.h
+#include linux/clk.h
+#include linux/regulator/consumer.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/of.h
+
+static u32 *cpu_freqs; /* Hz */
+static u32 *cpu_volts; /* uV */
+static u32 trans_latency; /* ns */
+static int cpu_op_nr;
+static unsigned int cur_index;
+
+static struct clk *cpu_clk;
+static struct regulator *cpu_reg;
+static struct cpufreq_frequency_table *freq_table;
+
+static int set_cpu_freq(unsigned long freq, int index, int higher)
+{
+   int ret = 0;
+
+   if (higher  cpu_reg) {
+   ret = regulator_set_voltage(cpu_reg,
+   cpu_volts[index * 2], cpu_volts[index * 2 + 1]);
+   if (ret) {
+   pr_err(set cpu voltage failed!\n);
+   return ret;
+   }
+   }
+
+   ret = clk_set_rate(cpu_clk, freq);
+   if (ret

[PATCH V5 1/7] ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp

2011-12-27 Thread Richard Zhao
If CONFIG_SMP, cpufreq skips loops_per_jiffy update, because different
arch has different per-cpu loops_per_jiffy definition.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/kernel/smp.c |   54 +
 1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ef5640b..ac9cadc 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -25,6 +25,7 @@
 #include linux/percpu.h
 #include linux/clockchips.h
 #include linux/completion.h
+#include linux/cpufreq.h
 
 #include linux/atomic.h
 #include asm/cacheflush.h
@@ -631,3 +632,56 @@ int setup_profiling_timer(unsigned int multiplier)
 {
return -EINVAL;
 }
+
+#ifdef CONFIG_CPU_FREQ
+
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq);
+static unsigned long global_l_p_j_ref;
+static unsigned long global_l_p_j_ref_freq;
+
+static int cpufreq_callback(struct notifier_block *nb,
+   unsigned long val, void *data)
+{
+   struct cpufreq_freqs *freq = data;
+   int cpu = freq-cpu;
+
+   if (freq-flags  CPUFREQ_CONST_LOOPS)
+   return NOTIFY_OK;
+
+   if (!per_cpu(l_p_j_ref, cpu)) {
+   per_cpu(l_p_j_ref, cpu) =
+   per_cpu(cpu_data, cpu).loops_per_jiffy;
+   per_cpu(l_p_j_ref_freq, cpu) = freq-old;
+   if (!global_l_p_j_ref) {
+   global_l_p_j_ref = loops_per_jiffy;
+   global_l_p_j_ref_freq = freq-old;
+   }
+   }
+
+   if ((val == CPUFREQ_PRECHANGE   freq-old  freq-new) ||
+   (val == CPUFREQ_POSTCHANGE  freq-old  freq-new) ||
+   (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
+   loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
+   global_l_p_j_ref_freq,
+   freq-new);
+   per_cpu(cpu_data, cpu).loops_per_jiffy =
+   cpufreq_scale(per_cpu(l_p_j_ref, cpu),
+   per_cpu(l_p_j_ref_freq, cpu),
+   freq-new);
+   }
+   return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_notifier = {
+   .notifier_call  = cpufreq_callback,
+};
+
+static int __init register_cpufreq_notifier(void)
+{
+   return cpufreq_register_notifier(cpufreq_notifier,
+   CPUFREQ_TRANSITION_NOTIFIER);
+}
+core_initcall(register_cpufreq_notifier);
+
+#endif
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V5 6/7] arm/imx6q: register arm_clk as cpu to clkdev

2011-12-27 Thread Richard Zhao
cpufreq needs cpu clock to change frequency.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/clock-imx6q.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
index 039a7ab..72acbc2 100644
--- a/arch/arm/mach-imx/clock-imx6q.c
+++ b/arch/arm/mach-imx/clock-imx6q.c
@@ -1911,6 +1911,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, gpmi_io_clk, gpmi_io_clk),
_REGISTER_CLOCK(NULL, usboh3_clk, usboh3_clk),
_REGISTER_CLOCK(NULL, sata_clk, sata_clk),
+   _REGISTER_CLOCK(NULL, cpu, arm_clk),
 };
 
 int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V5 5/7] dts/imx6q: add cpufreq property

2011-12-27 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/boot/dts/imx6q.dtsi |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 263e8f3..d89b42d 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -29,6 +29,13 @@
compatible = arm,cortex-a9;
reg = 0;
next-level-cache = L2;
+   cpu-freqs = 99600 79200 39600 19800;
+   cpu-volts =/* min  max */
+   1225000 145 /* 996M */
+   110 145 /* 792M */
+   95  145 /* 396M */
+   85  145; /* 198M */
+   clk-trans-latency = 61036; /* two CLK32 periods */
};
 
cpu@1 {
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V5 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate for smp

2011-12-27 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/plat-mxc/cpufreq.c |   10 --
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
index c937e75..364793a 100644
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -99,16 +99,6 @@ static int mxc_set_target(struct cpufreq_policy *policy,
 
ret = set_cpu_freq(freq_Hz);
 
-#ifdef CONFIG_SMP
-   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
-* So update it for all CPUs.
-*/
-   for_each_possible_cpu(cpu)
-   per_cpu(cpu_data, cpu).loops_per_jiffy =
-   cpufreq_scale(per_cpu(cpu_data, cpu).loops_per_jiffy,
-   freqs.old, freqs.new);
-#endif
-
for_each_possible_cpu(cpu) {
freqs.cpu = cpu;
cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE);
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V5 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ

2011-12-27 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c44aa97..39cf00a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -595,6 +595,7 @@ comment i.MX6 family:
 
 config SOC_IMX6Q
bool i.MX6 Quad support
+   select ARCH_HAS_CPUFREQ
select ARM_GIC
select CACHE_L2X0
select CPU_V7
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V5 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-27 Thread Richard Zhao
On Tue, Dec 27, 2011 at 11:05:41PM +0800, Shawn Guo wrote:
 Hi Richard,
 
 On Tue, Dec 27, 2011 at 04:24:19PM +0800, Richard Zhao wrote:
  The driver get cpu operation point table from device tree cpu0 node,
  and adjusts operating points using clk and regulator APIs.
  
  It support single core and multi-core ARM SoCs. But currently it assume
  all cores share the same frequency and voltage.
  
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  Reviewed-by: Jamie Iles ja...@jamieiles.com
  Reviewed-by: Mark Brown broo...@opensource.wolfsonmicro.com
  ---
   .../devicetree/bindings/cpufreq/clk-reg-cpufreq|   21 ++
   drivers/cpufreq/Kconfig|   10 +
   drivers/cpufreq/Makefile   |2 +
   drivers/cpufreq/clk-reg-cpufreq.c  |  302 
  
   4 files changed, 335 insertions(+), 0 deletions(-)
   create mode 100644 
  Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
   create mode 100644 drivers/cpufreq/clk-reg-cpufreq.c
  
 
 [...]
 
  +static struct cpufreq_driver clk_reg_cpufreq_driver = {
  +   .flags = CPUFREQ_STICKY,
  +   .verify = clk_reg_verify_speed,
  +   .target = clk_reg_set_target,
  +   .get = clk_reg_get_speed,
  +   .init = clk_reg_cpufreq_init,
  +   .exit = clk_reg_cpufreq_exit,
  +   .name = clk-reg,
  +};
  +
  +static u32 max_freq = UINT_MAX / 1000; /* kHz */
  +module_param(max_freq, uint, 0);
  +MODULE_PARM_DESC(max_freq, max cpu frequency in unit of kHz);
  +
 
 Have you tried to pass this param from kernel cmdline?  What's the
 syntax if we want to pass a 800 MHz max_freq?
clk-reg-cpufreq.max_freq=80
 
 And I played this driver on imx6q with pm-qa [1] cpufreq test suit from
 Linaro PMWG.
 
 ### cpufreq_01:
 ### test the cpufreq framework is available for frequency
 ### 
 https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#cpufreq_01
 ###
 cpufreq_01.0/cpu0: checking 'scaling_available_frequencies' exists...   
 fail
 cpufreq_01.0/cpu1: checking 'scaling_available_frequencies' exists...   
 fail
 cpufreq_01.0/cpu2: checking 'scaling_available_frequencies' exists...   
 fail
 cpufreq_01.0/cpu3: checking 'scaling_available_frequencies' exists...   
 fail
hmm, scaling_available_frequencies is nice-to-have feature. I'm glad to
add it.
 
 ### cpufreq_05:
 ### test 'ondemand' and 'conservative' trigger correctly the configuration 
 directory
 ### 
 https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#cpufreq_05
 ###
 cpufreq_05.0: checking 'ondemand' directory exists...   
 pass
 cpufreq_05.1: checking 'conservative' directory exists...   
 pass
 cpufreq_05.2: checking 'ondemand' directory is not there... 
 pass
 cpufreq_05.3: checking 'conservative' directory is not there... 
 pass
 cpufreq_05.4: checking 'ondemand' directory exists...   
 fail
 cpufreq_05.5: checking 'conservative' directory exists...   
 pass
I past fail part script here:
switch_ondemand cpu0
switch_conservative cpu1
check 'ondemand' directory exists test -d $CPU_PATH/cpufreq/ondemand
check 'conservative' directory exists test -d 
$CPU_PATH/cpufreq/conservative
This driver assume all cpu cores to share the same freq and voltage. The 
affected
cpu is all other cpus. They also share one single governor. The test case does 
not
suit this driver and not for most arm multi-core cpus I guess.
 
 The cpufreq_01 can be easily fixed with the following change.
 
 8-
 @@ -146,6 +150,11 @@ static int clk_reg_cpufreq_exit(struct cpufreq_policy 
 *policy)
 return 0;
  }
 
 +static struct freq_attr *clk_reg_cpufreq_attr[] = {
 +   cpufreq_freq_attr_scaling_available_freqs,
 +   NULL,
 +};
 +
  static struct cpufreq_driver clk_reg_cpufreq_driver = {
 .flags = CPUFREQ_STICKY,
 .verify = clk_reg_verify_speed,
 @@ -153,10 +162,15 @@ static struct cpufreq_driver clk_reg_cpufreq_driver = {
 .get = clk_reg_get_speed,
 .init = clk_reg_cpufreq_init,
 .exit = clk_reg_cpufreq_exit,
 +   .attr = clk_reg_cpufreq_attr,
 .name = clk-reg,
  };
 -8
quite right.

Thanks
Richard
 
 And I have not looked into the second one deeply, but maybe you
 want to :)
 
 -- 
 Regards,
 Shawn
 
 [1] git://git.linaro.org/people/dlezcano/pm-qa.git
 
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V5 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-27 Thread Richard Zhao
Hi Mark,

[...]
 + if (cpu_reg) {
 + ret = regulator_is_supported_voltage(cpu_reg,
 + cpu_volts[i * 2], cpu_volts[i * 2 + 1]);
Is there any reason you didn't export symbol regulator_is_supported_voltage?
and also it don't have !REGULATOR dummy implementation.
 
Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V5 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-27 Thread Richard Zhao
On Wed, Dec 28, 2011 at 11:14:10AM +0800, Richard Zhao wrote:
 Hi Mark,
 
 [...]
  +   if (cpu_reg) {
  +   ret = regulator_is_supported_voltage(cpu_reg,
  +   cpu_volts[i * 2], cpu_volts[i * 2 + 1]);
 Is there any reason you didn't export symbol regulator_is_supported_voltage?
 and also it don't have !REGULATOR dummy implementation.
regulator_set_voltage_time and some other functions don't have dummy one
either.
  
 Thanks
 Richard
 
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-26 Thread Richard Zhao
On Mon, Dec 26, 2011 at 11:10:30AM +, Mark Brown wrote:
 On Sat, Dec 24, 2011 at 11:52:29PM +0800, Richard Zhao wrote:
  On Sat, Dec 24, 2011 at 01:42:29PM +, Mark Brown wrote:
   On Sat, Dec 24, 2011 at 09:28:33PM +0800, Richard Zhao wrote:
 
If you think regulator thansition latency is board specific, then the 
board
dts can overrite it.
 
   We should just query this information from the regulator subsystem
   (there's hooks but currently nothing implements them).  The regulators
   can define their own bindings if they need to read it from device tree,
   most of them should be able to do this as a function of knowing about
   the device.  None of this is specific to cpufreq so cpufreq shouldn't
   have to define its own support for this.
 
  I'd like to query the latency by call clk and regulator APIs. but as you 
  said
  both of them have not implemented it yet. I think, for now, we can use the
 
 The *call* is there in the regulator subsystem, it's just that none of
 the drivers back it up with an actual implementation yet.  Which turns
 out to be a good thing as cpufreq can't currently understand variable
 latencies and the governors don't deal well with non-trivial latencies
 anyway.
but clk API don't have such calls. and many SoCs only adjust clk frequencies, 
using
one single voltage.
 
  property to get the total latency. Once I can get it at runtime, I'll remove
  it. So the definition of trans-latency is just the same as cpufreq 
  transition_latency,
  people get less confused. What do you think?
 
 The problem with device tree is that once you've defined a binding
 you're stuck with it, it's very hard to change - witness all the magic
 number based stuff with the interrupt bindings for example
So what's your suggestion? We can not set transition_latency to set random 
number.

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-24 Thread Richard Zhao
On Fri, Dec 23, 2011 at 01:18:51PM +, Mark Brown wrote:
 On Thu, Dec 22, 2011 at 03:09:10PM +0800, Richard Zhao wrote:
  The driver get cpu operation point table from device tree cpu0 node,
  and adjusts operating points using clk and regulator APIs.
 
 Reviewed-by: Mark Brown broo...@opensource.wolfsonmicro.com
 
Thanks.
 but one nit:
 
  +Required properties in /cpus/cpu@0:
  +- cpu-freqs : cpu frequency points it support, in unit of Hz.
  +- cpu-volts : cpu voltages required by the frequency point at the same 
  index,
  + in unit of uV.
  +- trans-latency :  transition_latency, in unit of ns.
 
 trans-latency should really say what latency is being measured (the CPU
 core only or the whole operation).
dts only descibe hw info. so the transition latency is for hw.
- trans-latency :  transition latency of HW, in unit of ns.

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-24 Thread Richard Zhao
On Sat, Dec 24, 2011 at 01:42:29PM +, Mark Brown wrote:
 On Sat, Dec 24, 2011 at 09:28:33PM +0800, Richard Zhao wrote:
  On Sat, Dec 24, 2011 at 12:24:11PM +, Mark Brown wrote:
 
   - trans-latency :  transition latency of cpu freq and related regulator,
 in unit of ns.
 
  Does it look better?
 
 I think it shouldn't include the regulator part of things.
 
  If you think regulator thansition latency is board specific, then the board
  dts can overrite it.
 
 We should just query this information from the regulator subsystem
 (there's hooks but currently nothing implements them).  The regulators
 can define their own bindings if they need to read it from device tree,
 most of them should be able to do this as a function of knowing about
 the device.  None of this is specific to cpufreq so cpufreq shouldn't
 have to define its own support for this.
I'd like to query the latency by call clk and regulator APIs. but as you said
both of them have not implemented it yet. I think, for now, we can use the
property to get the total latency. Once I can get it at runtime, I'll remove
it. So the definition of trans-latency is just the same as cpufreq 
transition_latency,
people get less confused. What do you think?

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-21 Thread Richard Zhao
On Wed, Dec 21, 2011 at 09:20:46AM +0800, Richard Zhao wrote:
 Hi Mark,
 
 On Tue, Dec 20, 2011 at 11:48:45PM +, Mark Brown wrote:
  On Wed, Dec 21, 2011 at 07:27:03AM +0800, Richard Zhao wrote:
   On Tue, Dec 20, 2011 at 02:59:04PM +, Mark Brown wrote:
  
My comments on the previous version of the patch still apply:
  
 - The voltage ranges being set need to be specified as ranges.
  
   cpu normally need strict voltages. and only proved operating opints
   are allowed to set in dts. If the voltage changes slightly especially
   for high frequency, it's easy to cause unstable.
  
  Clearly there will be limits which get more and more restrictive as the
  frequencies get higher but there will always be at least some play in
  the numbers as one must at a minimum specify tolerance ranges, and at
  lower frequencies the ranges specified will typically get compartively
  large.
 hmm, reasonable. I'll add it in dts. Thanks.
  
  Note also that not all hardware specifies things in terms of a fixed set
  of operating points, sometimes only the minimum voltage specification is
  varied with frequency or sometimes you see maximum and minimum stepping
  independently.
 cpus that don't use freq table is out of scope of this driver.
  
  Further note that if all hardware really does have as tight a set of
  requirements as you suggest then the regulator support in the driver
  needs to be non-optional otherwise a board without software regulator
  control might drop the frequency without also dropping the voltage.
 It's ok to only adjuct freq without changes voltage. You can find many
 arm soc cpufreq drivers don't change voltage.
 If dts specify voltage but don't have such regulator. I'll assume it
 always runs on the initial volatage (highest for most cases).
  
 - Frequencies that can't be supported due to limitations of the
   available supplies shouldn't be exposed to users.
  
   As I said, only proved operation points are allowed.
  
  This statement appears to be unrelated to the comment you're replying
  to.
 I meant the exact voltage can always successfull set. Anyway, I'll add
 regulator_set_voltage return value checking.
  
You also need to define how the core supplies get looked up.
  
   It's pure software. platform uses this driver have to define cpu 
   consumer.
  
  You still need to define this in the binding.
 You mean regulator DT binding? already in ? I'll check it.
Mark, cpu node is not a struct device, sys_device instead. I can not find
regulator via device/dt node. Can I still use the string to get regulator
after converting to DT?

And regulator binding is not on cpufreq git tree.

Thanks
Richard
  
 + pr_info(Generic CPU frequency driver\n);
  
This seems noisy...
  
   Why? Do you think only errors and warnings can print out?
  
  Yes.
 
 Maybe I can remove it. But I'd probably add freq table dump. It's more 
 important.
 Agree?
 
 I checked pr_fmt. Thanks very much. I'll use below and remove __func_.
 #define pr_fmt(fmt) KBUILD_MODNAME :  fmt
 
 
 Thanks
 Richard
  
  ___
  linux-arm-kernel mailing list
  linux-arm-ker...@lists.infradead.org
  http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
  
 
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-21 Thread Richard Zhao
On Wed, Dec 21, 2011 at 01:49:07PM +0100, Kay Sievers wrote:
 On Wed, Dec 21, 2011 at 13:12, Mark Brown
 broo...@opensource.wolfsonmicro.com wrote:
  On Wed, Dec 21, 2011 at 12:44:57PM +0100, Kay Sievers wrote:
 
  We will convert all classes to buses over time time, and have a single
  type of device and a single type of subsystem.
 
  Are there any conversions that have been done already that I can look at
  for reference?
 
 The first step is the conversion from 'sys_device' to 'device', which is here:
   http://git.kernel.org/?p=linux/kernel/git/kay/patches.git;a=tree
 
 That should hit the tree soon, if all works according to plan. All
 sys_devices and sysdev classes will be gone for forever.
Even cpu node is device, I still need to find a way to get it.  I think it's
better have another patch to fix the regulator dt binding in cpu node. I'll
not include it in this patch series.

Richard
 
 The 'class' to 'bus' work is simpler, because the logic in both of
 them is very similar and both use the same 'struct device' already.
 
 We'll need to add some convenience APIs to bus, and add code to make
 sure the converted stuff has compat symlinks in /sys/class when
 needed. Then we can convert-over one 'struct class' to 'struct
 bus_type' after the other until 'struct class' can be deleted.
 
 This work has not yet started, because we are busy with the sys_device
 stuff at the moment.
 
 No new stuff should use 'struct class' or 'struct sys_device', they
 should all start right away with 'struct bus_type'.
 
 Kay

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 1/7] ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp

2011-12-21 Thread Richard Zhao
Hi Russel,

Are the patch #1 #2 #3 ok for you?

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ

2011-12-21 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c44aa97..39cf00a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -595,6 +595,7 @@ comment i.MX6 family:
 
 config SOC_IMX6Q
bool i.MX6 Quad support
+   select ARCH_HAS_CPUFREQ
select ARM_GIC
select CACHE_L2X0
select CPU_V7
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 5/7] dts/imx6q: add cpufreq property

2011-12-21 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/boot/dts/imx6q.dtsi |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 263e8f3..2087db7 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -29,6 +29,13 @@
compatible = arm,cortex-a9;
reg = 0;
next-level-cache = L2;
+   cpu-freqs = 99600 79200 39600 19800;
+   cpu-volts =/* min  max */
+   1225000 145 /* 996M */
+   110 145 /* 792M */
+   95  145 /* 396M */
+   85  145; /* 198M */
+   trans-latency = 61036; /* two CLK32 periods */
};
 
cpu@1 {
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 0/7] add a generic cpufreq driver

2011-12-21 Thread Richard Zhao
Thanks Arnd, Mark, Jamie, Rob, for your review.

Changes in v4:
 - add depends on HAVE_CLK  OF  REGULATOR
 - add set_cpu_freq fail check
 - regulator_put wehn module exit
 - add pr_fmt and convert all printk to pr_xxx
 - use voltage range
 - comment and doc fix
 - add cpu_volts value pre-check in module init
 - add helpfull module parameter max_freq
 - remove compatible string check on Arnd's comment.
 - remove generic-cpufreq to clk-reg-cpufreq

Changes in v3:
 - move adjusting smp loops_per_jiffy to arm common code,
   and also adjust global loops_per_jiffy.
 - remove adjusting loops_per_jiffy in imx and omap cpufreq drivers.
 - check compatible generic-cpufreq when module_init
 - change printk to pr_xxx
 - add generic-cpufreq DT binding doc

Changes in v2:
 - add volatage change support
 - change '_' in property name to '-'
 - use initial value to calculate loops_per_jiffy
 - fix reading cpu_volts property bug 
 - let cpufreq_frequency_table_cpuinfo routines handle cpu_freq_khz_max/min
 - don't change freq in arm_cpufreq_exit, because every core share the same 
freq.
 - use unsigned long describe frequency as much as possible. Because clk use
   unsigned long, but cpufreq use unsigned int.

[PATCH v4 1/7] ARM: add cpufreq transiton notifier to adjust
[PATCH v4 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate
[PATCH v4 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for
[PATCH v4 4/7] cpufreq: add clk-reg cpufreq driver
[PATCH v4 5/7] dts/imx6q: add cpufreq property
[PATCH v4 6/7] arm/imx6q: register arm_clk as cpu to clkdev
[PATCH v4 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for smp

2011-12-21 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/omap-cpufreq.c |   36 
 1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5d04c57..17da4c4 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -37,16 +37,6 @@
 
 #include mach/hardware.h
 
-#ifdef CONFIG_SMP
-struct lpj_info {
-   unsigned long   ref;
-   unsigned intfreq;
-};
-
-static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
-static struct lpj_info global_lpj_ref;
-#endif
-
 static struct cpufreq_frequency_table *freq_table;
 static atomic_t freq_table_users = ATOMIC_INIT(0);
 static struct clk *mpu_clk;
@@ -118,32 +108,6 @@ static int omap_target(struct cpufreq_policy *policy,
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
freqs.new = omap_getspeed(policy-cpu);
 
-#ifdef CONFIG_SMP
-   /*
-* Note that loops_per_jiffy is not updated on SMP systems in
-* cpufreq driver. So, update the per-CPU loops_per_jiffy value
-* on frequency transition. We need to update all dependent CPUs.
-*/
-   for_each_cpu(i, policy-cpus) {
-   struct lpj_info *lpj = per_cpu(lpj_ref, i);
-   if (!lpj-freq) {
-   lpj-ref = per_cpu(cpu_data, i).loops_per_jiffy;
-   lpj-freq = freqs.old;
-   }
-
-   per_cpu(cpu_data, i).loops_per_jiffy =
-   cpufreq_scale(lpj-ref, lpj-freq, freqs.new);
-   }
-
-   /* And don't forget to adjust the global one */
-   if (!global_lpj_ref.freq) {
-   global_lpj_ref.ref = loops_per_jiffy;
-   global_lpj_ref.freq = freqs.old;
-   }
-   loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
-   freqs.new);
-#endif
-
/* notifiers */
for_each_cpu(i, policy-cpus) {
freqs.cpu = i;
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate for smp

2011-12-21 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/plat-mxc/cpufreq.c |   10 --
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
index c937e75..364793a 100644
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -99,16 +99,6 @@ static int mxc_set_target(struct cpufreq_policy *policy,
 
ret = set_cpu_freq(freq_Hz);
 
-#ifdef CONFIG_SMP
-   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
-* So update it for all CPUs.
-*/
-   for_each_possible_cpu(cpu)
-   per_cpu(cpu_data, cpu).loops_per_jiffy =
-   cpufreq_scale(per_cpu(cpu_data, cpu).loops_per_jiffy,
-   freqs.old, freqs.new);
-#endif
-
for_each_possible_cpu(cpu) {
freqs.cpu = cpu;
cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE);
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH v4 4/7] cpufreq: add clk-reg cpufreq driver

2011-12-21 Thread Richard Zhao
The driver get cpu operation point table from device tree cpu0 node,
and adjusts operating points using clk and regulator APIs.

It support single core and multi-core ARM SoCs. But currently it assume
all cores share the same frequency and voltage.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 .../devicetree/bindings/cpufreq/clk-reg-cpufreq|7 +
 drivers/cpufreq/Kconfig|   10 +
 drivers/cpufreq/Makefile   |2 +
 drivers/cpufreq/clk-reg-cpufreq.c  |  289 
 4 files changed, 308 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
 create mode 100644 drivers/cpufreq/clk-reg-cpufreq.c

diff --git a/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq 
b/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
new file mode 100644
index 000..bf07c1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/clk-reg-cpufreq
@@ -0,0 +1,7 @@
+Generic cpufreq driver based on clk and regulator APIs
+
+Required properties in /cpus/cpu@0:
+- cpu-freqs : cpu frequency points it support, in unit of Hz.
+- cpu-volts : cpu voltages required by the frequency point at the same index,
+ in unit of uV.
+- trans-latency :  transition_latency, in unit of ns.
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index e24a2a1..95470f1 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -179,6 +179,16 @@ config CPU_FREQ_GOV_CONSERVATIVE
 
  If in doubt, say N.
 
+config CLK_REG_CPUFREQ_DRIVER
+   tristate Generic cpufreq driver using clk and regulator APIs
+   depends on HAVE_CLK  OF  REGULATOR
+   select CPU_FREQ_TABLE
+   help
+ This adds generic CPUFreq driver based on clk and regulator APIs.
+ It assumes all cores of the CPU share the same clock and voltage.
+
+ If in doubt, say N.
+
 menu x86 CPU frequency scaling drivers
 depends on X86
 source drivers/cpufreq/Kconfig.x86
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ce75fcb..2c4eb33 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)   += 
cpufreq_conservative.o
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)   += freq_table.o
 
+obj-$(CONFIG_CLK_REG_CPUFREQ_DRIVER)   += clk-reg-cpufreq.o
+
 
##
 # x86 drivers.
 # Link order matters. K8 is preferred to ACPI because of firmware bugs in early
diff --git a/drivers/cpufreq/clk-reg-cpufreq.c 
b/drivers/cpufreq/clk-reg-cpufreq.c
new file mode 100644
index 000..c30d2c5
--- /dev/null
+++ b/drivers/cpufreq/clk-reg-cpufreq.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#define pr_fmt(fmt)KBUILD_MODNAME :  fmt
+
+#include linux/module.h
+#include linux/cpufreq.h
+#include linux/clk.h
+#include linux/regulator/consumer.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/of.h
+
+static u32 *cpu_freqs; /* Hz */
+static u32 *cpu_volts; /* uV */
+static u32 trans_latency; /* ns */
+static int cpu_op_nr;
+static unsigned int cur_index;
+
+static struct clk *cpu_clk;
+static struct regulator *cpu_reg;
+static struct cpufreq_frequency_table *freq_table;
+
+static int set_cpu_freq(unsigned long freq, int index, int higher)
+{
+   int ret = 0;
+
+   if (higher  cpu_reg) {
+   ret = regulator_set_voltage(cpu_reg,
+   cpu_volts[index * 2], cpu_volts[index * 2 + 1]);
+   if (ret) {
+   pr_err(set cpu voltage failed!\n);
+   return ret;
+   }
+   }
+
+   ret = clk_set_rate(cpu_clk, freq);
+   if (ret) {
+   if (cpu_reg)
+   regulator_set_voltage(cpu_reg, cpu_volts[cur_index * 2],
+   cpu_volts[cur_index * 2 + 1]);
+   pr_err(cannot set CPU clock rate\n);
+   return ret;
+   }
+
+   if (!higher  cpu_reg) {
+   ret = regulator_set_voltage(cpu_reg,
+   cpu_volts[index * 2], cpu_volts[index * 2 + 1]);
+   if (ret)
+   pr_warn(set cpu voltage failed, might run on
+higher voltage!\n);
+   ret = 0;
+   }
+
+   return ret;
+}
+
+static int clk_reg_verify_speed(struct cpufreq_policy *policy)
+{
+   return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int

Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-20 Thread Richard Zhao
在 2011-12-20 下午11:22,Arnd Bergmann a...@arndb.de写道:

 On Tuesday 20 December 2011, Richard Zhao wrote:
+Generic cpufreq driver
+
+Required properties in /cpus/cpu@0:
+- compatible : generic-cpufreq
   
I'm not convinced this is the best way to do this.  By requiring a
generic-cpufreq compatible string we're encoding Linux driver
information into the hardware description.  The only way I can
see to
avoid this is to provide a generic_clk_cpufreq_init() function
that
platforms can call in their machine init code to use the driver.
  
   Agreed on the compatible string.
  Assume you reject to use compatible string.
   It's putting Linux specifics into DT.
  
   You could flip this around and have the module make a call into the
   kernel to determine whether to initialize or not. Then platforms could
   set a flag to indicate this.
  Could you make it more clear? kernel global variable, macro, or
function?
 
  - Following your idea, I think, we can add in driver/cpufreq/cpufreq.c:
  int (*clk_reg_cpufreq_get_op_table) (struct op_table *tbl, int *size);
  SoC code set the callback. If it's NULL, driver will exit. We can get
rid
  of DT. It'll make cpufreq core dirty, but it's the only file built-in.
 
  - Drop module support. SoC call generic_clk_cpufreq_init as Jamie said.

 I think you don't actually need a compatible property here, as long as
we
 ensure that the cpu-freqs, cpu-volts and trans-latency properties
are
 present in the cpu node if and only if the machine works with this driver
 (why else would you put them there?).
It is more easy for me.
Rob, agree?

Richard

 CPUs are special in the device trees in a number of ways, so I think we
 can treat this as a logical extension. This way, you can still make the
 generic cpufreq driver a loadable module. You don't get module autoloading
 with this structure, but that is already the case because the cpu nodes
 in the device tree are not translated into linux devices.

Arnd
___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-20 Thread Richard Zhao
在 2011-12-20 下午11:13,Rob Herring robherri...@gmail.com写道:

 On 12/19/2011 07:59 PM, Richard Zhao wrote:
  On Mon, Dec 19, 2011 at 09:00:44AM -0600, Rob Herring wrote:
  On 12/19/2011 08:39 AM, Jamie Iles wrote:
  On Mon, Dec 19, 2011 at 10:19:29PM +0800, Richard Zhao wrote:
  On Mon, Dec 19, 2011 at 10:05:12AM +, Jamie Iles wrote:
  Hi Richard,
 
  On Mon, Dec 19, 2011 at 11:21:40AM +0800, Richard Zhao wrote:
  It support single core and multi-core ARM SoCs. But currently it
assume
  all cores share the same frequency and voltage.
 
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  ---
   .../devicetree/bindings/cpufreq/generic-cpufreq|7 +
   drivers/cpufreq/Kconfig|8 +
   drivers/cpufreq/Makefile   |2 +
   drivers/cpufreq/generic-cpufreq.c  |  251

   4 files changed, 268 insertions(+), 0 deletions(-)
   create mode 100644
Documentation/devicetree/bindings/cpufreq/generic-cpufreq
   create mode 100644 drivers/cpufreq/generic-cpufreq.c
 
  diff --git
a/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
  new file mode 100644
  index 000..15dd780
  --- /dev/null
  +++ b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
  @@ -0,0 +1,7 @@
  +Generic cpufreq driver
  +
  +Required properties in /cpus/cpu@0:
  +- compatible : generic-cpufreq
 
  I'm not convinced this is the best way to do this.  By requiring a
  generic-cpufreq compatible string we're encoding Linux driver
  information into the hardware description.  The only way I can see
to
  avoid this is to provide a generic_clk_cpufreq_init() function that
  platforms can call in their machine init code to use the driver.
 
  Agreed on the compatible string.
  Assume you reject to use compatible string.
  It's putting Linux specifics into DT.
 
  You could flip this around and have the module make a call into the
  kernel to determine whether to initialize or not. Then platforms could
  set a flag to indicate this.
  Could you make it more clear? kernel global variable, macro, or
function?

 Any of those. Of course, direct access to variables across modules is
 discouraged, so it would probably be a function that checks a variable.
why not use function pointer? arch that don't use this driver do not have
to set it. if use function, everyone should define it.

  - Following your idea, I think, we can add in driver/cpufreq/cpufreq.c:
  int (*clk_reg_cpufreq_get_op_table) (struct op_table *tbl, int *size);
  SoC code set the callback. If it's NULL, driver will exit. We can get
rid
  of DT. It'll make cpufreq core dirty, but it's the only file built-in.

 But aren't you getting the operating points from the DT? Then you don't
 want to put this code into each platform.
the variable is mainly used to check whether some platform want  to use
this driver. getting ride of dt is side affect.

 
  - Drop module support. SoC call generic_clk_cpufreq_init as Jamie said.
 
 
  It'll prevent the driver from being a kernel module.
 
  Hmm, that's not very nice either!  I guess you _could_ add an
  of_machine_is_compatible() check against a list of compatible machines
  in the driver but that feels a little gross.  Hopefully Rob or Grant
  have a good alternative!
 
 
  What does cpufreq core do if multiple drivers are registered?
  current cpufreq core only support one cpufreq_driver. Others will fail
  except the first time.

 Then whoever gets there first wins. Make your driver register late and
 if someone doesn't want to use it they can register a custom driver
earlier.
this driver did

 Rob

  Perhaps a
  ranking is needed and this would only get enabled if there are no other
  drivers and other conditions like having the clock cpu present are
met.
  We'd better keep cpufreq core simple. For this driver, register
cpufreq_driver
  is the last thing after checking all conditions.
 
 
  Rob
 
  Hi Grant  Rob,
 
  Could you comment?
 
 
  +- cpu-freqs : cpu frequency points it support
  +- cpu-volts : cpu voltages required by the frequency point at the
same index
  +- trans-latency :  transition_latency
  diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
  index e24a2a1..216eecd 100644
  --- a/drivers/cpufreq/Kconfig
  +++ b/drivers/cpufreq/Kconfig
  @@ -179,6 +179,14 @@ config CPU_FREQ_GOV_CONSERVATIVE
 
 If in doubt, say N.
 
  +config GENERIC_CPUFREQ_DRIVER
  +bool Generic cpufreq driver using
clock/regulator/devicetree
  +help
  +  This adds generic CPUFreq driver. It assumes all
  +  cores of the CPU share the same clock and voltage.
  +
  +  If in doubt, say N.
 
  I think this needs dependencies on HAVE_CLK, OF and REGULATOR.
  right, Thanks. I can not check clk before generic clock framework
  come in.
  Added:
 depends on OF  REGULATOR
 select CPU_FREQ_TABLE
 
  You can still use HAVE_CLK

Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-20 Thread Richard Zhao
On Tue, Dec 20, 2011 at 02:59:04PM +, Mark Brown wrote:
 On Mon, Dec 19, 2011 at 11:21:40AM +0800, Richard Zhao wrote:
  It support single core and multi-core ARM SoCs. But currently it assume
  all cores share the same frequency and voltage.
 
 My comments on the previous version of the patch still apply:
 
  - The voltage ranges being set need to be specified as ranges.
cpu normally need strict voltages. and only proved operating opints
are allowed to set in dts. If the voltage changes slightly especially
for high frequency, it's easy to cause unstable.
  - Frequencies that can't be supported due to limitations of the
available supplies shouldn't be exposed to users.
As I said, only proved operation points are allowed.
  - The driver needs to handle errors.
Yes.
 
  +Required properties in /cpus/cpu@0:
  +- compatible : generic-cpufreq
  +- cpu-freqs : cpu frequency points it support
  +- cpu-volts : cpu voltages required by the frequency point at the same 
  index
  +- trans-latency :  transition_latency
 
 You need to define units for all of these, and for the transition
 latency you need to be clear about what's being measured (it looks like
 the CPU time only, not any voltage ramping).
right.
 
 You also need to define how the core supplies get looked up.
It's pure software. platform uses this driver have to define cpu consumer.
 
  +   /* Manual states, that PLL stabilizes in two CLK32 periods */
  +   policy-cpuinfo.transition_latency = trans_latency;
 
 I guess this comment is a cut'n'paste error.
right, thanks.
 
  +
  +   ret = cpufreq_frequency_table_cpuinfo(policy, freq_table);
  +
  +   if (ret  0) {
  +   pr_err(%s: invalid frequency table for cpu %d\n,
  +  __func__, policy-cpu);
 
 You should define pr_fmt to always include __func__ in the messages
 rather than open coding - ensures consistency and is less noisy in the
 code.
I'll check it.
 
  +   pr_info(Generic CPU frequency driver\n);
 
 This seems noisy...
Why? Do you think only errors and warnings can print out?

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-20 Thread Richard Zhao
Hi Mark,

On Tue, Dec 20, 2011 at 11:48:45PM +, Mark Brown wrote:
 On Wed, Dec 21, 2011 at 07:27:03AM +0800, Richard Zhao wrote:
  On Tue, Dec 20, 2011 at 02:59:04PM +, Mark Brown wrote:
 
   My comments on the previous version of the patch still apply:
 
- The voltage ranges being set need to be specified as ranges.
 
  cpu normally need strict voltages. and only proved operating opints
  are allowed to set in dts. If the voltage changes slightly especially
  for high frequency, it's easy to cause unstable.
 
 Clearly there will be limits which get more and more restrictive as the
 frequencies get higher but there will always be at least some play in
 the numbers as one must at a minimum specify tolerance ranges, and at
 lower frequencies the ranges specified will typically get compartively
 large.
hmm, reasonable. I'll add it in dts. Thanks.
 
 Note also that not all hardware specifies things in terms of a fixed set
 of operating points, sometimes only the minimum voltage specification is
 varied with frequency or sometimes you see maximum and minimum stepping
 independently.
cpus that don't use freq table is out of scope of this driver.
 
 Further note that if all hardware really does have as tight a set of
 requirements as you suggest then the regulator support in the driver
 needs to be non-optional otherwise a board without software regulator
 control might drop the frequency without also dropping the voltage.
It's ok to only adjuct freq without changes voltage. You can find many
arm soc cpufreq drivers don't change voltage.
If dts specify voltage but don't have such regulator. I'll assume it
always runs on the initial volatage (highest for most cases).
 
- Frequencies that can't be supported due to limitations of the
  available supplies shouldn't be exposed to users.
 
  As I said, only proved operation points are allowed.
 
 This statement appears to be unrelated to the comment you're replying
 to.
I meant the exact voltage can always successfull set. Anyway, I'll add
regulator_set_voltage return value checking.
 
   You also need to define how the core supplies get looked up.
 
  It's pure software. platform uses this driver have to define cpu consumer.
 
 You still need to define this in the binding.
You mean regulator DT binding? already in ? I'll check it.
 
+   pr_info(Generic CPU frequency driver\n);
 
   This seems noisy...
 
  Why? Do you think only errors and warnings can print out?
 
 Yes.

Maybe I can remove it. But I'd probably add freq table dump. It's more 
important.
Agree?

I checked pr_fmt. Thanks very much. I'll use below and remove __func_.
#define pr_fmt(fmt) KBUILD_MODNAME :  fmt


Thanks
Richard
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-20 Thread Richard Zhao
On Wed, Dec 21, 2011 at 01:32:21AM +, Mark Brown wrote:
 On Wed, Dec 21, 2011 at 09:20:46AM +0800, Richard Zhao wrote:
  On Tue, Dec 20, 2011 at 11:48:45PM +, Mark Brown wrote:
 
   Note also that not all hardware specifies things in terms of a fixed set
   of operating points, sometimes only the minimum voltage specification is
   varied with frequency or sometimes you see maximum and minimum stepping
   independently.
 
  cpus that don't use freq table is out of scope of this driver.
 
 That's not the point - the point is that you may do something like
 specify a defined set of frequencies and just drop the minimum supported
 voltage without altering the maximum supported voltage as the frequency
 gets lower.
What do you mean by drop?
cpu-volts = 
/* min  max */
110 120 /* 1G HZ */
100 120 /* 800M HZ */
90  120 /* 600M HZ */
;
The above sample dts could meet your point?

 
   Further note that if all hardware really does have as tight a set of
   requirements as you suggest then the regulator support in the driver
   needs to be non-optional otherwise a board without software regulator
   control might drop the frequency without also dropping the voltage.
 
  It's ok to only adjuct freq without changes voltage. You can find many
  arm soc cpufreq drivers don't change voltage.
  If dts specify voltage but don't have such regulator. I'll assume it
  always runs on the initial volatage (highest for most cases).
 
 My point exactly; such devices are examples of the policy outlined above
 where only the minimum voltage changes with frequency and the maximum
 voltage is constant.  The cpufreq driver would lower the supported
 voltage when possible but wouldn't actually care if the voltage changes.
accepted seting voltage range. I guess the above sample dts code meet your
point.
 
  - Frequencies that can't be supported due to limitations of the
available supplies shouldn't be exposed to users.
 
As I said, only proved operation points are allowed.
 
   This statement appears to be unrelated to the comment you're replying
   to.
 
  I meant the exact voltage can always successfull set. Anyway, I'll add
 
 This is just not the case.  Regulators don't offer a continuous range of
 voltages, they offer steps of varying sizes which may miss setting some
 voltages, and board designers may choose not to support some of the
 voltage range.
 
  regulator_set_voltage return value checking.
 
 While this is important the driver should also be enumerating the
 supported voltages at probe time and eliminating unsupportable settings
 so that governors aren't constantly trying to set things that can never
 be supported.  The s3c64xx cpufreq driver provides an implementation of
 this.
I'll use regulator_is_supported_voltage pre-check the cpu-volts.
For clock, conditions ((clk_round_rate(cpu-freq)/1000) * 1000 == cpu-freq)
seems too strict. Because cpu clock is SoC dependent, I'll not add the check.
 
  Maybe I can remove it. But I'd probably add freq table dump. It's more 
  important.
  Agree?
 
 That seems like something the core should be doing if
hmm, cpu table dumps it with pr_debug.

Thanks
Richard
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-20 Thread Richard Zhao
On Wed, Dec 21, 2011 at 02:33:36AM +, Mark Brown wrote:
 On Wed, Dec 21, 2011 at 10:24:53AM +0800, Richard Zhao wrote:
  On Wed, Dec 21, 2011 at 01:32:21AM +, Mark Brown wrote:
 
   That's not the point - the point is that you may do something like
   specify a defined set of frequencies and just drop the minimum supported
   voltage without altering the maximum supported voltage as the frequency
   gets lower.
 
  What do you mean by drop?
 
 Drop is a synonym for lower in this context.
 
  cpu-volts = 
  /* min  max */
  110 120 /* 1G HZ */
  100 120 /* 800M HZ */
  90  120 /* 600M HZ */
  ;
  The above sample dts could meet your point?
 
 Yes.
 
   While this is important the driver should also be enumerating the
   supported voltages at probe time and eliminating unsupportable settings
   so that governors aren't constantly trying to set things that can never
   be supported.  The s3c64xx cpufreq driver provides an implementation of
   this.
 
  I'll use regulator_is_supported_voltage pre-check the cpu-volts.
  For clock, conditions ((clk_round_rate(cpu-freq)/1000) * 1000 == cpu-freq)
  seems too strict. Because cpu clock is SoC dependent, I'll not add the 
  check.
 
 The issue that was there for is that there are multiple runtime
 detectable variant clocking configurations which couldn't be switched
 between so the driver needs to select only the rates that can be reached
 from the current configuration.  I'd imagine that might be an issue
 elsewhere.
one case is that, cpu freq is 800M, clock may only reach 799M. I'd rather let
clock code to decide how to handle 800M request. That's why I said
the condition check is too strict.

Thanks
Richard
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-19 Thread Richard Zhao
On Mon, Dec 19, 2011 at 10:05:12AM +, Jamie Iles wrote:
 Hi Richard,
 
 On Mon, Dec 19, 2011 at 11:21:40AM +0800, Richard Zhao wrote:
  It support single core and multi-core ARM SoCs. But currently it assume
  all cores share the same frequency and voltage.
  
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  ---
   .../devicetree/bindings/cpufreq/generic-cpufreq|7 +
   drivers/cpufreq/Kconfig|8 +
   drivers/cpufreq/Makefile   |2 +
   drivers/cpufreq/generic-cpufreq.c  |  251 
  
   4 files changed, 268 insertions(+), 0 deletions(-)
   create mode 100644 
  Documentation/devicetree/bindings/cpufreq/generic-cpufreq
   create mode 100644 drivers/cpufreq/generic-cpufreq.c
  
  diff --git a/Documentation/devicetree/bindings/cpufreq/generic-cpufreq 
  b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
  new file mode 100644
  index 000..15dd780
  --- /dev/null
  +++ b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
  @@ -0,0 +1,7 @@
  +Generic cpufreq driver
  +
  +Required properties in /cpus/cpu@0:
  +- compatible : generic-cpufreq
 
 I'm not convinced this is the best way to do this.  By requiring a 
 generic-cpufreq compatible string we're encoding Linux driver 
 information into the hardware description.  The only way I can see to 
 avoid this is to provide a generic_clk_cpufreq_init() function that 
 platforms can call in their machine init code to use the driver.
It'll prevent the driver from being a kernel module.

Hi Grant  Rob,

Could you comment?

 
  +- cpu-freqs : cpu frequency points it support
  +- cpu-volts : cpu voltages required by the frequency point at the same 
  index
  +- trans-latency :  transition_latency
  diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
  index e24a2a1..216eecd 100644
  --- a/drivers/cpufreq/Kconfig
  +++ b/drivers/cpufreq/Kconfig
  @@ -179,6 +179,14 @@ config CPU_FREQ_GOV_CONSERVATIVE
   
If in doubt, say N.
   
  +config GENERIC_CPUFREQ_DRIVER
  +   bool Generic cpufreq driver using clock/regulator/devicetree
  +   help
  + This adds generic CPUFreq driver. It assumes all
  + cores of the CPU share the same clock and voltage.
  +
  + If in doubt, say N.
 
 I think this needs dependencies on HAVE_CLK, OF and REGULATOR.
right, Thanks. I can not check clk before generic clock framework
come in.
Added:
depends on OF  REGULATOR
select CPU_FREQ_TABLE
 
  +
   menu x86 CPU frequency scaling drivers
   depends on X86
   source drivers/cpufreq/Kconfig.x86
  diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
  index ce75fcb..2dbdab1 100644
  --- a/drivers/cpufreq/Makefile
  +++ b/drivers/cpufreq/Makefile
  @@ -13,6 +13,8 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)   += 
  cpufreq_conservative.o
   # CPUfreq cross-arch helpers
   obj-$(CONFIG_CPU_FREQ_TABLE)   += freq_table.o
   
  +obj-$(CONFIG_GENERIC_CPUFREQ_DRIVER)   += generic-cpufreq.o
  +
   
  ##
   # x86 drivers.
   # Link order matters. K8 is preferred to ACPI because of firmware bugs in 
  early
  diff --git a/drivers/cpufreq/generic-cpufreq.c 
  b/drivers/cpufreq/generic-cpufreq.c
  new file mode 100644
  index 000..781bb9b
  --- /dev/null
  +++ b/drivers/cpufreq/generic-cpufreq.c
  @@ -0,0 +1,251 @@
  +/*
  + * Copyright (C) 2011 Freescale Semiconductor, Inc.
  + */
  +
  +/*
  + * The code contained herein is licensed under the GNU General Public
  + * License. You may obtain a copy of the GNU General Public License
  + * Version 2 or later at the following locations:
  + *
  + * http://www.opensource.org/licenses/gpl-license.html
  + * http://www.gnu.org/copyleft/gpl.html
  + */
  +
  +#include linux/module.h
  +#include linux/cpufreq.h
  +#include linux/clk.h
  +#include linux/regulator/consumer.h
  +#include linux/err.h
  +#include linux/slab.h
  +#include linux/of.h
  +
  +static u32 *cpu_freqs; /* HZ */
  +static u32 *cpu_volts; /* uV */
  +static u32 trans_latency; /* ns */
  +static int cpu_op_nr;
  +
  +static struct clk *cpu_clk;
  +static struct regulator *cpu_reg;
  +static struct cpufreq_frequency_table *freq_table;
  +
  +static int set_cpu_freq(unsigned long freq, int index, int higher)
  +{
  +   int ret = 0;
  +
  +   if (higher  cpu_reg)
  +   regulator_set_voltage(cpu_reg,
  +   cpu_volts[index], cpu_volts[index]);
  +
  +   ret = clk_set_rate(cpu_clk, freq);
  +   if (ret != 0) {
  +   pr_err(generic-cpufreq: cannot set CPU clock rate\n);
  +   return ret;
  +   }
  +
  +   if (!higher  cpu_reg)
  +   regulator_set_voltage(cpu_reg,
  +   cpu_volts[index], cpu_volts[index]);
  +
  +   return ret;
  +}
  +
  +static int generic_verify_speed(struct cpufreq_policy *policy)
  +{
  +   return cpufreq_frequency_table_verify

Re: [PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-19 Thread Richard Zhao
On Mon, Dec 19, 2011 at 09:00:44AM -0600, Rob Herring wrote:
 On 12/19/2011 08:39 AM, Jamie Iles wrote:
  On Mon, Dec 19, 2011 at 10:19:29PM +0800, Richard Zhao wrote:
  On Mon, Dec 19, 2011 at 10:05:12AM +, Jamie Iles wrote:
  Hi Richard,
 
  On Mon, Dec 19, 2011 at 11:21:40AM +0800, Richard Zhao wrote:
  It support single core and multi-core ARM SoCs. But currently it assume
  all cores share the same frequency and voltage.
 
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  ---
   .../devicetree/bindings/cpufreq/generic-cpufreq|7 +
   drivers/cpufreq/Kconfig|8 +
   drivers/cpufreq/Makefile   |2 +
   drivers/cpufreq/generic-cpufreq.c  |  251 
  
   4 files changed, 268 insertions(+), 0 deletions(-)
   create mode 100644 
  Documentation/devicetree/bindings/cpufreq/generic-cpufreq
   create mode 100644 drivers/cpufreq/generic-cpufreq.c
 
  diff --git a/Documentation/devicetree/bindings/cpufreq/generic-cpufreq 
  b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
  new file mode 100644
  index 000..15dd780
  --- /dev/null
  +++ b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
  @@ -0,0 +1,7 @@
  +Generic cpufreq driver
  +
  +Required properties in /cpus/cpu@0:
  +- compatible : generic-cpufreq
 
  I'm not convinced this is the best way to do this.  By requiring a 
  generic-cpufreq compatible string we're encoding Linux driver 
  information into the hardware description.  The only way I can see to 
  avoid this is to provide a generic_clk_cpufreq_init() function that 
  platforms can call in their machine init code to use the driver.
 
 Agreed on the compatible string.
Assume you reject to use compatible string.
 It's putting Linux specifics into DT.
 
 You could flip this around and have the module make a call into the
 kernel to determine whether to initialize or not. Then platforms could
 set a flag to indicate this.
Could you make it more clear? kernel global variable, macro, or function?

- Following your idea, I think, we can add in driver/cpufreq/cpufreq.c:
int (*clk_reg_cpufreq_get_op_table) (struct op_table *tbl, int *size);
SoC code set the callback. If it's NULL, driver will exit. We can get rid
of DT. It'll make cpufreq core dirty, but it's the only file built-in.

- Drop module support. SoC call generic_clk_cpufreq_init as Jamie said.

 
  It'll prevent the driver from being a kernel module.
  
  Hmm, that's not very nice either!  I guess you _could_ add an 
  of_machine_is_compatible() check against a list of compatible machines 
  in the driver but that feels a little gross.  Hopefully Rob or Grant 
  have a good alternative!
  
 
 What does cpufreq core do if multiple drivers are registered?
current cpufreq core only support one cpufreq_driver. Others will fail
except the first time.
 Perhaps a
 ranking is needed and this would only get enabled if there are no other
 drivers and other conditions like having the clock cpu present are met.
We'd better keep cpufreq core simple. For this driver, register cpufreq_driver
is the last thing after checking all conditions.

 
 Rob
 
  Hi Grant  Rob,
 
  Could you comment?
 
 
  +- cpu-freqs : cpu frequency points it support
  +- cpu-volts : cpu voltages required by the frequency point at the same 
  index
  +- trans-latency :  transition_latency
  diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
  index e24a2a1..216eecd 100644
  --- a/drivers/cpufreq/Kconfig
  +++ b/drivers/cpufreq/Kconfig
  @@ -179,6 +179,14 @@ config CPU_FREQ_GOV_CONSERVATIVE
   
 If in doubt, say N.
   
  +config GENERIC_CPUFREQ_DRIVER
  +bool Generic cpufreq driver using clock/regulator/devicetree
  +help
  +  This adds generic CPUFreq driver. It assumes all
  +  cores of the CPU share the same clock and voltage.
  +
  +  If in doubt, say N.
 
  I think this needs dependencies on HAVE_CLK, OF and REGULATOR.
  right, Thanks. I can not check clk before generic clock framework
  come in.
  Added:
 depends on OF  REGULATOR
 select CPU_FREQ_TABLE
  
  You can still use HAVE_CLK.  That symbol has been around for ages and 
  any platform implementing the clk API should select it so it's fine to 
  depend on it even before there is a generic struct clk.
You are right. Thanks.

Richard
  
  Jamie
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-18 Thread Richard Zhao
On Sat, Dec 17, 2011 at 10:29:29AM +0100, Arnd Bergmann wrote:
 On Saturday 17 December 2011 16:00:03 Richard Zhao wrote:
  On Fri, Dec 16, 2011 at 08:32:35AM -0600, Rob Herring wrote:
   On 12/16/2011 04:30 AM, Richard Zhao wrote:
It support single core and multi-core ARM SoCs. But it assume
all cores share the same frequency and voltage.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/Kconfig.arm   |8 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/arm-cpufreq.c |  269 
+
 3 files changed, 278 insertions(+), 0 deletions(-)
 create mode 100644 drivers/cpufreq/arm-cpufreq.c

   
   What makes this specific to ARM and not a generic DT + clk api +
   regulator api driver?
 
  smp loops_per_jiffy update needs arm header asm/cpu.h.
 
 I would suggest to instead change the definition of adjust_jiffies in the
 core so it can be overridden by the architecture, like this
 
 diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
 index 987a165..174584d 100644
 --- a/drivers/cpufreq/cpufreq.c
 +++ b/drivers/cpufreq/cpufreq.c
 @@ -189,6 +189,7 @@ EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
   * systems as each CPU might be scaled differently. So, use the arch
   * per-CPU loops_per_jiffy value wherever possible.
   */
 +#ifndef adjust_jiffies
  #ifndef CONFIG_SMP
  static unsigned long l_p_j_ref;
  static unsigned int  l_p_j_ref_freq;
 @@ -218,7 +219,8 @@ static inline void adjust_jiffies(unsigned long val, 
 struct cpufreq_freqs *ci)
  {
 return;
  }
 -#endif
 +#endif /* CONFIG_SMP */
 +#endif /* adjust_jiffies */
  
  
  /**
 
 
 Then ARM (and any others that want the driver) can provide their own
 implementation and set 
 
 #define adjust_jiffies(val, ci) adjust_jiffies((val), (ci))
 
 to let the core use that instead of the generic UP version.
 
 
 While we're there, we should probably try to fix drivers that use 
 loops_per_jiffy,
 because that is not what they think it is on SMP.
Or let different arch register its different CPUFREQ_TRANSITION_NOTIFIER ?

Thanks
Richard
 
   Arnd
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-18 Thread Richard Zhao
Hi Bryan,

On Fri, Dec 16, 2011 at 11:59:02AM -0800, Bryan Huntsman wrote:
 On 12/16/2011 02:52 AM, Jamie Iles wrote:
 
  +static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
  +static unsigned long l_p_j_ref_freq;
  +
  +static struct clk *cpu_clk;
  
  This assumes that all CPU's share the same clk and run at the same rate.  
  Is that a fair/safe assumption?  I honestly don't know the answer to 
  this so it's just a question!!!
 
 On MSM, cpus independently scale both frequency and voltage.  Our clock
 driver isn't upstream yet.  David Brown has a preliminary version here:
 
 https://www.codeaurora.org/gitweb/quic/kernel/?p=davidb/linux-msm.git;a=shortlog;h=refs/heads/msm-clock-rfc
 
 Once we get our driver upstream, MSM will be an exception and not select
 ARM_GENERIC_CPUFREQ.  We'll probably have a separate msm-cpufreq.c
 driver under drivers/cpufreq/.
Do you have to patch to implement per-cpu udelay? In current code, udelay uses
global loops_per_jiffy.

Thanks
Richard
 
 - Bryan
 
 -- 
 Sent by an employee of the Qualcomm Innovation Center, Inc.
 The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V3 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ

2011-12-18 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c44aa97..39cf00a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -595,6 +595,7 @@ comment i.MX6 family:
 
 config SOC_IMX6Q
bool i.MX6 Quad support
+   select ARCH_HAS_CPUFREQ
select ARM_GIC
select CACHE_L2X0
select CPU_V7
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V3 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for smp

2011-12-18 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/omap-cpufreq.c |   36 
 1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5d04c57..17da4c4 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -37,16 +37,6 @@
 
 #include mach/hardware.h
 
-#ifdef CONFIG_SMP
-struct lpj_info {
-   unsigned long   ref;
-   unsigned intfreq;
-};
-
-static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
-static struct lpj_info global_lpj_ref;
-#endif
-
 static struct cpufreq_frequency_table *freq_table;
 static atomic_t freq_table_users = ATOMIC_INIT(0);
 static struct clk *mpu_clk;
@@ -118,32 +108,6 @@ static int omap_target(struct cpufreq_policy *policy,
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
freqs.new = omap_getspeed(policy-cpu);
 
-#ifdef CONFIG_SMP
-   /*
-* Note that loops_per_jiffy is not updated on SMP systems in
-* cpufreq driver. So, update the per-CPU loops_per_jiffy value
-* on frequency transition. We need to update all dependent CPUs.
-*/
-   for_each_cpu(i, policy-cpus) {
-   struct lpj_info *lpj = per_cpu(lpj_ref, i);
-   if (!lpj-freq) {
-   lpj-ref = per_cpu(cpu_data, i).loops_per_jiffy;
-   lpj-freq = freqs.old;
-   }
-
-   per_cpu(cpu_data, i).loops_per_jiffy =
-   cpufreq_scale(lpj-ref, lpj-freq, freqs.new);
-   }
-
-   /* And don't forget to adjust the global one */
-   if (!global_lpj_ref.freq) {
-   global_lpj_ref.ref = loops_per_jiffy;
-   global_lpj_ref.freq = freqs.old;
-   }
-   loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
-   freqs.new);
-#endif
-
/* notifiers */
for_each_cpu(i, policy-cpus) {
freqs.cpu = i;
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V3 5/7] dts/imx6q: add cpufreq property

2011-12-18 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/boot/dts/imx6q.dtsi |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 263e8f3..80e47b5 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -26,9 +26,12 @@
#size-cells = 0;
 
cpu@0 {
-   compatible = arm,cortex-a9;
+   compatible = arm,cortex-a9, generic-cpufreq;
reg = 0;
next-level-cache = L2;
+   cpu-freqs = 99600 79200 39600 19800;
+   cpu-volts = 1225000 110 95 85;
+   trans-latency = 61036; /* two CLK32 periods */
};
 
cpu@1 {
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V3 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate for smp

2011-12-18 Thread Richard Zhao
arm registered cpufreq transition notifier to recalculate it.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/plat-mxc/cpufreq.c |   10 --
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
index c937e75..364793a 100644
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -99,16 +99,6 @@ static int mxc_set_target(struct cpufreq_policy *policy,
 
ret = set_cpu_freq(freq_Hz);
 
-#ifdef CONFIG_SMP
-   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
-* So update it for all CPUs.
-*/
-   for_each_possible_cpu(cpu)
-   per_cpu(cpu_data, cpu).loops_per_jiffy =
-   cpufreq_scale(per_cpu(cpu_data, cpu).loops_per_jiffy,
-   freqs.old, freqs.new);
-#endif
-
for_each_possible_cpu(cpu) {
freqs.cpu = cpu;
cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE);
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V3 0/7] add a generic cpufreq driver

2011-12-18 Thread Richard Zhao
The driver support single core and multi core ARM SoCs. For multi core,
it assume all cores share the same clock and voltage.

TODO:
 - Add each core seperate freq/volt support (MSM).

Changes in v3:
 - move adjusting smp loops_per_jiffy to arm common code,
   and also adjust global loops_per_jiffy.
 - remove adjusting loops_per_jiffy in imx and omap cpufreq drivers.
 - check compatible generic-cpufreq when module_init
 - change printk to pr_xxx
 - add generic-cpufreq DT binding doc

Changes in v2:
 - add volatage change support
 - change '_' in property name to '-'
 - use initial value to calculate loops_per_jiffy
 - fix reading cpu_volts property bug 
 - let cpufreq_frequency_table_cpuinfo routines handle cpu_freq_khz_max/min
 - don't change freq in arm_cpufreq_exit, because every core share the same 
freq.
 - use unsigned long describe frequency as much as possible. Because clk use
   unsigned long, but cpufreq use unsigned int.
[PATCH V3 1/7] ARM: add cpufreq transiton notifier to adjust
[PATCH V3 2/7] arm/imx: cpufreq: remove loops_per_jiffy recalculate
[PATCH V3 3/7] cpufreq: OMAP: remove loops_per_jiffy recalculate for
[PATCH V3 4/7] cpufreq: add generic cpufreq driver
[PATCH V3 5/7] dts/imx6q: add cpufreq property
[PATCH V3 6/7] arm/imx6q: register arm_clk as cpu to clkdev
[PATCH V3 7/7] arm/imx6q: select ARCH_HAS_CPUFREQ


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V3 1/7] ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp

2011-12-18 Thread Richard Zhao
If CONFIG_SMP, cpufreq skips loops_per_jiffy update, because different
arch has different per-cpu loops_per_jiffy definition.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/kernel/smp.c |   54 +
 1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ef5640b..ac9cadc 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -25,6 +25,7 @@
 #include linux/percpu.h
 #include linux/clockchips.h
 #include linux/completion.h
+#include linux/cpufreq.h
 
 #include linux/atomic.h
 #include asm/cacheflush.h
@@ -631,3 +632,56 @@ int setup_profiling_timer(unsigned int multiplier)
 {
return -EINVAL;
 }
+
+#ifdef CONFIG_CPU_FREQ
+
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq);
+static unsigned long global_l_p_j_ref;
+static unsigned long global_l_p_j_ref_freq;
+
+static int cpufreq_callback(struct notifier_block *nb,
+   unsigned long val, void *data)
+{
+   struct cpufreq_freqs *freq = data;
+   int cpu = freq-cpu;
+
+   if (freq-flags  CPUFREQ_CONST_LOOPS)
+   return NOTIFY_OK;
+
+   if (!per_cpu(l_p_j_ref, cpu)) {
+   per_cpu(l_p_j_ref, cpu) =
+   per_cpu(cpu_data, cpu).loops_per_jiffy;
+   per_cpu(l_p_j_ref_freq, cpu) = freq-old;
+   if (!global_l_p_j_ref) {
+   global_l_p_j_ref = loops_per_jiffy;
+   global_l_p_j_ref_freq = freq-old;
+   }
+   }
+
+   if ((val == CPUFREQ_PRECHANGE   freq-old  freq-new) ||
+   (val == CPUFREQ_POSTCHANGE  freq-old  freq-new) ||
+   (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
+   loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
+   global_l_p_j_ref_freq,
+   freq-new);
+   per_cpu(cpu_data, cpu).loops_per_jiffy =
+   cpufreq_scale(per_cpu(l_p_j_ref, cpu),
+   per_cpu(l_p_j_ref_freq, cpu),
+   freq-new);
+   }
+   return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_notifier = {
+   .notifier_call  = cpufreq_callback,
+};
+
+static int __init register_cpufreq_notifier(void)
+{
+   return cpufreq_register_notifier(cpufreq_notifier,
+   CPUFREQ_TRANSITION_NOTIFIER);
+}
+core_initcall(register_cpufreq_notifier);
+
+#endif
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V3 4/7] cpufreq: add generic cpufreq driver

2011-12-18 Thread Richard Zhao
It support single core and multi-core ARM SoCs. But currently it assume
all cores share the same frequency and voltage.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 .../devicetree/bindings/cpufreq/generic-cpufreq|7 +
 drivers/cpufreq/Kconfig|8 +
 drivers/cpufreq/Makefile   |2 +
 drivers/cpufreq/generic-cpufreq.c  |  251 
 4 files changed, 268 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/generic-cpufreq
 create mode 100644 drivers/cpufreq/generic-cpufreq.c

diff --git a/Documentation/devicetree/bindings/cpufreq/generic-cpufreq 
b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
new file mode 100644
index 000..15dd780
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/generic-cpufreq
@@ -0,0 +1,7 @@
+Generic cpufreq driver
+
+Required properties in /cpus/cpu@0:
+- compatible : generic-cpufreq
+- cpu-freqs : cpu frequency points it support
+- cpu-volts : cpu voltages required by the frequency point at the same index
+- trans-latency :  transition_latency
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index e24a2a1..216eecd 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -179,6 +179,14 @@ config CPU_FREQ_GOV_CONSERVATIVE
 
  If in doubt, say N.
 
+config GENERIC_CPUFREQ_DRIVER
+   bool Generic cpufreq driver using clock/regulator/devicetree
+   help
+ This adds generic CPUFreq driver. It assumes all
+ cores of the CPU share the same clock and voltage.
+
+ If in doubt, say N.
+
 menu x86 CPU frequency scaling drivers
 depends on X86
 source drivers/cpufreq/Kconfig.x86
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ce75fcb..2dbdab1 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)   += 
cpufreq_conservative.o
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)   += freq_table.o
 
+obj-$(CONFIG_GENERIC_CPUFREQ_DRIVER)   += generic-cpufreq.o
+
 
##
 # x86 drivers.
 # Link order matters. K8 is preferred to ACPI because of firmware bugs in early
diff --git a/drivers/cpufreq/generic-cpufreq.c 
b/drivers/cpufreq/generic-cpufreq.c
new file mode 100644
index 000..781bb9b
--- /dev/null
+++ b/drivers/cpufreq/generic-cpufreq.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include linux/module.h
+#include linux/cpufreq.h
+#include linux/clk.h
+#include linux/regulator/consumer.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/of.h
+
+static u32 *cpu_freqs; /* HZ */
+static u32 *cpu_volts; /* uV */
+static u32 trans_latency; /* ns */
+static int cpu_op_nr;
+
+static struct clk *cpu_clk;
+static struct regulator *cpu_reg;
+static struct cpufreq_frequency_table *freq_table;
+
+static int set_cpu_freq(unsigned long freq, int index, int higher)
+{
+   int ret = 0;
+
+   if (higher  cpu_reg)
+   regulator_set_voltage(cpu_reg,
+   cpu_volts[index], cpu_volts[index]);
+
+   ret = clk_set_rate(cpu_clk, freq);
+   if (ret != 0) {
+   pr_err(generic-cpufreq: cannot set CPU clock rate\n);
+   return ret;
+   }
+
+   if (!higher  cpu_reg)
+   regulator_set_voltage(cpu_reg,
+   cpu_volts[index], cpu_volts[index]);
+
+   return ret;
+}
+
+static int generic_verify_speed(struct cpufreq_policy *policy)
+{
+   return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int generic_get_speed(unsigned int cpu)
+{
+   return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int generic_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+   struct cpufreq_freqs freqs;
+   unsigned long freq_Hz;
+   int cpu;
+   int ret = 0;
+   unsigned int index;
+
+   cpufreq_frequency_table_target(policy, freq_table,
+   target_freq, relation, index);
+   freq_Hz = clk_round_rate(cpu_clk, cpu_freqs[index]);
+   freq_Hz = freq_Hz ? freq_Hz : cpu_freqs[index];
+   freqs.old = clk_get_rate(cpu_clk) / 1000;
+   freqs.new = freq_Hz / 1000;
+   freqs.flags = 0;
+
+   if (freqs.old == freqs.new)
+   return 0;
+
+   for_each_possible_cpu(cpu) {
+   freqs.cpu = cpu;
+   cpufreq_notify_transition(freqs, CPUFREQ_PRECHANGE

[PATCH V3 6/7] arm/imx6q: register arm_clk as cpu to clkdev

2011-12-18 Thread Richard Zhao
cpufreq needs cpu clock to change frequency.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/clock-imx6q.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
index 039a7ab..72acbc2 100644
--- a/arch/arm/mach-imx/clock-imx6q.c
+++ b/arch/arm/mach-imx/clock-imx6q.c
@@ -1911,6 +1911,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, gpmi_io_clk, gpmi_io_clk),
_REGISTER_CLOCK(NULL, usboh3_clk, usboh3_clk),
_REGISTER_CLOCK(NULL, sata_clk, sata_clk),
+   _REGISTER_CLOCK(NULL, cpu, arm_clk),
 };
 
 int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-17 Thread Richard Zhao
On Fri, Dec 16, 2011 at 12:26:03PM +0100, Heiko Stübner wrote:
 Am Freitag, 16. Dezember 2011, 11:30:59 schrieb Richard Zhao:
  It support single core and multi-core ARM SoCs. But it assume
  all cores share the same frequency and voltage.
  
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  ---
   drivers/cpufreq/Kconfig.arm   |8 ++
   drivers/cpufreq/Makefile  |1 +
   drivers/cpufreq/arm-cpufreq.c |  269
  + 3 files changed, 278
  insertions(+), 0 deletions(-)
   create mode 100644 drivers/cpufreq/arm-cpufreq.c
 
 looks quite cool, but should also provide a description of the devicetree 
 bindings (i.e. like the rest in Documentation/devicetree/bindings/...) for 
 future reference.
Yes, Thanks for your remind.
 
 Heiko
 

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-17 Thread Richard Zhao
On Fri, Dec 16, 2011 at 08:32:35AM -0600, Rob Herring wrote:
 On 12/16/2011 04:30 AM, Richard Zhao wrote:
  It support single core and multi-core ARM SoCs. But it assume
  all cores share the same frequency and voltage.
  
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  ---
   drivers/cpufreq/Kconfig.arm   |8 ++
   drivers/cpufreq/Makefile  |1 +
   drivers/cpufreq/arm-cpufreq.c |  269 
  +
   3 files changed, 278 insertions(+), 0 deletions(-)
   create mode 100644 drivers/cpufreq/arm-cpufreq.c
  
 
 What makes this specific to ARM and not a generic DT + clk api +
 regulator api driver?
smp loops_per_jiffy update needs arm header asm/cpu.h.
 
 Also, you need documentation of the DT bindings.
Yes, Thanks.

Richard
 
 Rob
 
  diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
  index 72a0044..a0f7d35 100644
  --- a/drivers/cpufreq/Kconfig.arm
  +++ b/drivers/cpufreq/Kconfig.arm
  @@ -2,6 +2,14 @@
   # ARM CPU Frequency scaling drivers
   #
   
  +config ARM_GENERIC_CPUFREQ
  +   bool ARM generic
  +   help
  + This adds ARM generic CPUFreq driver. It assumes all
  + cores of the SoC share the same clock and voltage.
  +
  + If in doubt, say N.
  +
   config ARM_S3C64XX_CPUFREQ
  bool Samsung S3C64XX
  depends on CPU_S3C6410
  diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
  index ce75fcb..6ccf02d 100644
  --- a/drivers/cpufreq/Makefile
  +++ b/drivers/cpufreq/Makefile
  @@ -39,6 +39,7 @@ obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
   
   
  ##
   # ARM SoC drivers
  +obj-$(CONFIG_ARM_GENERIC_CPUFREQ)  += arm-cpufreq.o
   obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
   obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)  += s3c64xx-cpufreq.o
   obj-$(CONFIG_ARM_S5PV210_CPUFREQ)  += s5pv210-cpufreq.o
  diff --git a/drivers/cpufreq/arm-cpufreq.c b/drivers/cpufreq/arm-cpufreq.c
  new file mode 100644
  index 000..e4d20da
  --- /dev/null
  +++ b/drivers/cpufreq/arm-cpufreq.c
  @@ -0,0 +1,269 @@
  +/*
  + * Copyright (C) 2011 Freescale Semiconductor, Inc.
  + */
  +
  +/*
  + * The code contained herein is licensed under the GNU General Public
  + * License. You may obtain a copy of the GNU General Public License
  + * Version 2 or later at the following locations:
  + *
  + * http://www.opensource.org/licenses/gpl-license.html
  + * http://www.gnu.org/copyleft/gpl.html
  + */
  +
  +#include linux/module.h
  +#include linux/cpufreq.h
  +#include linux/clk.h
  +#include linux/regulator/consumer.h
  +#include linux/err.h
  +#include linux/slab.h
  +#include linux/of.h
  +#include asm/cpu.h
  +
  +static u32 *cpu_freqs; /* HZ */
  +static u32 *cpu_volts; /* uV */
  +static u32 trans_latency; /* ns */
  +static int cpu_op_nr;
  +
  +static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
  +static unsigned long l_p_j_ref_freq;
  +
  +static struct clk *cpu_clk;
  +static struct regulator *cpu_reg;
  +static struct cpufreq_frequency_table *arm_freq_table;
  +
  +static int set_cpu_freq(unsigned long freq, int index, int higher)
  +{
  +   int ret = 0;
  +
  +   if (higher  cpu_reg)
  +   regulator_set_voltage(cpu_reg,
  +   cpu_volts[index], cpu_volts[index]);
  +
  +   ret = clk_set_rate(cpu_clk, freq);
  +   if (ret != 0) {
  +   printk(KERN_DEBUG cannot set CPU clock rate\n);
  +   return ret;
  +   }
  +
  +   if (!higher  cpu_reg)
  +   regulator_set_voltage(cpu_reg,
  +   cpu_volts[index], cpu_volts[index]);
  +
  +   return ret;
  +}
  +
  +static int arm_verify_speed(struct cpufreq_policy *policy)
  +{
  +   return cpufreq_frequency_table_verify(policy, arm_freq_table);
  +}
  +
  +static unsigned int arm_get_speed(unsigned int cpu)
  +{
  +   return clk_get_rate(cpu_clk) / 1000;
  +}
  +
  +static int arm_set_target(struct cpufreq_policy *policy,
  + unsigned int target_freq, unsigned int relation)
  +{
  +   struct cpufreq_freqs freqs;
  +   unsigned long freq_Hz;
  +   int cpu;
  +   int ret = 0;
  +   unsigned int index;
  +
  +   cpufreq_frequency_table_target(policy, arm_freq_table,
  +   target_freq, relation, index);
  +   freq_Hz = clk_round_rate(cpu_clk, cpu_freqs[index]);
  +   freq_Hz = freq_Hz ? freq_Hz : cpu_freqs[index];
  +   freqs.old = clk_get_rate(cpu_clk) / 1000;
  +   freqs.new = clk_round_rate(cpu_clk, cpu_freqs[index]);
  +   freqs.new = freq_Hz / 1000;
  +   freqs.flags = 0;
  +
  +   if (freqs.old == freqs.new)
  +   return 0;
  +
  +   for_each_possible_cpu(cpu) {
  +   freqs.cpu = cpu;
  +   cpufreq_notify_transition(freqs, CPUFREQ_PRECHANGE);
  +   }
  +
  +   ret = set_cpu_freq(freq_Hz, index, (freqs.new  freqs.old));
  +
  +#ifdef CONFIG_SMP
  +   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
  +* So update

Re: [PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-17 Thread Richard Zhao
On Fri, Dec 16, 2011 at 10:52:29AM +, Jamie Iles wrote:
 Hi Richard,
 
 A couple of questions inline, but otherwise looks nice!
Thanks for your review.
 
 Jamie
 
 On Fri, Dec 16, 2011 at 06:30:59PM +0800, Richard Zhao wrote:
  It support single core and multi-core ARM SoCs. But it assume
  all cores share the same frequency and voltage.
  
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  ---
 [...]
  diff --git a/drivers/cpufreq/arm-cpufreq.c b/drivers/cpufreq/arm-cpufreq.c
  new file mode 100644
  index 000..e4d20da
  --- /dev/null
  +++ b/drivers/cpufreq/arm-cpufreq.c
  @@ -0,0 +1,269 @@
  +/*
  + * Copyright (C) 2011 Freescale Semiconductor, Inc.
  + */
  +
  +/*
  + * The code contained herein is licensed under the GNU General Public
  + * License. You may obtain a copy of the GNU General Public License
  + * Version 2 or later at the following locations:
  + *
  + * http://www.opensource.org/licenses/gpl-license.html
  + * http://www.gnu.org/copyleft/gpl.html
  + */
  +
  +#include linux/module.h
  +#include linux/cpufreq.h
  +#include linux/clk.h
  +#include linux/regulator/consumer.h
  +#include linux/err.h
  +#include linux/slab.h
  +#include linux/of.h
  +#include asm/cpu.h
  +
  +static u32 *cpu_freqs; /* HZ */
  +static u32 *cpu_volts; /* uV */
  +static u32 trans_latency; /* ns */
  +static int cpu_op_nr;
  +
  +static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
  +static unsigned long l_p_j_ref_freq;
  +
  +static struct clk *cpu_clk;
 
 This assumes that all CPU's share the same clk and run at the same rate.  
 Is that a fair/safe assumption?  I honestly don't know the answer to 
 this so it's just a question!!!
As I know, most share the same clk/volt. From the code:
IMX6: yes
Tegra: Yes, but strange it sets CPUFREQ_SHARED_TYPE_ALL.

MSM is an exception. I can support the case, but I have to make sure it's
handy to use.
 
  +static struct regulator *cpu_reg;
  +static struct cpufreq_frequency_table *arm_freq_table;
  +
  +static int set_cpu_freq(unsigned long freq, int index, int higher)
  +{
  +   int ret = 0;
  +
  +   if (higher  cpu_reg)
  +   regulator_set_voltage(cpu_reg,
  +   cpu_volts[index], cpu_volts[index]);
  +
  +   ret = clk_set_rate(cpu_clk, freq);
  +   if (ret != 0) {
  +   printk(KERN_DEBUG cannot set CPU clock rate\n);
 
 Perhaps use pr_debug() and friends throughout this driver?
ok. Thanks.
 
  +   return ret;
  +   }
  +
  +   if (!higher  cpu_reg)
  +   regulator_set_voltage(cpu_reg,
  +   cpu_volts[index], cpu_volts[index]);
  +
  +   return ret;
  +}
  +
  +static int arm_verify_speed(struct cpufreq_policy *policy)
  +{
  +   return cpufreq_frequency_table_verify(policy, arm_freq_table);
  +}
  +
  +static unsigned int arm_get_speed(unsigned int cpu)
  +{
  +   return clk_get_rate(cpu_clk) / 1000;
  +}
  +
  +static int arm_set_target(struct cpufreq_policy *policy,
  + unsigned int target_freq, unsigned int relation)
  +{
  +   struct cpufreq_freqs freqs;
  +   unsigned long freq_Hz;
  +   int cpu;
  +   int ret = 0;
  +   unsigned int index;
  +
  +   cpufreq_frequency_table_target(policy, arm_freq_table,
  +   target_freq, relation, index);
  +   freq_Hz = clk_round_rate(cpu_clk, cpu_freqs[index]);
  +   freq_Hz = freq_Hz ? freq_Hz : cpu_freqs[index];
  +   freqs.old = clk_get_rate(cpu_clk) / 1000;
  +   freqs.new = clk_round_rate(cpu_clk, cpu_freqs[index]);
I forgot to delete this line.
  +   freqs.new = freq_Hz / 1000;
 
 Why round the rate then overwrite it?  Should this be freqs.new /= 1000?
 
  +   freqs.flags = 0;
  +
  +   if (freqs.old == freqs.new)
  +   return 0;
  +
  +   for_each_possible_cpu(cpu) {
  +   freqs.cpu = cpu;
  +   cpufreq_notify_transition(freqs, CPUFREQ_PRECHANGE);
  +   }
  +
  +   ret = set_cpu_freq(freq_Hz, index, (freqs.new  freqs.old));
  +
  +#ifdef CONFIG_SMP
  +   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
  +* So update it for all CPUs.
  +*/
  +   for_each_possible_cpu(cpu)
  +   per_cpu(cpu_data, cpu).loops_per_jiffy =
  +   cpufreq_scale(per_cpu(l_p_j_ref, cpu), l_p_j_ref_freq,
  +   freqs.new);
  +#endif
  +
  +   for_each_possible_cpu(cpu) {
  +   freqs.cpu = cpu;
  +   cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE);
  +   }
  +
  +   return ret;
  +}
  +
  +static int arm_cpufreq_init(struct cpufreq_policy *policy)
  +{
  +   int ret;
  +
  +   if (policy-cpu = num_possible_cpus())
  +   return -EINVAL;
  +
  +   policy-cur = clk_get_rate(cpu_clk) / 1000;
  +   policy-shared_type = CPUFREQ_SHARED_TYPE_ANY;
  +   cpumask_setall(policy-cpus);
  +   /* Manual states, that PLL stabilizes in two CLK32 periods */
  +   policy-cpuinfo.transition_latency = trans_latency;
  +
  +   ret = cpufreq_frequency_table_cpuinfo(policy, arm_freq_table

Re: [PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-17 Thread Richard Zhao
On Fri, Dec 16, 2011 at 11:59:02AM -0800, Bryan Huntsman wrote:
 On 12/16/2011 02:52 AM, Jamie Iles wrote:
 
  +static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
  +static unsigned long l_p_j_ref_freq;
  +
  +static struct clk *cpu_clk;
  
  This assumes that all CPU's share the same clk and run at the same rate.  
  Is that a fair/safe assumption?  I honestly don't know the answer to 
  this so it's just a question!!!
 
 On MSM, cpus independently scale both frequency and voltage.  Our clock
 driver isn't upstream yet.  David Brown has a preliminary version here:
If
 - cpu_clk are per_cpu, and get from cpu0 clk, cpu1 clk, etc.
   The same to regulators.
 - set CPUFREQ_SHARED_TYPE_NONE
 - don't set affect cpus.

Does that help you?

Thanks
Richard
 
 https://www.codeaurora.org/gitweb/quic/kernel/?p=davidb/linux-msm.git;a=shortlog;h=refs/heads/msm-clock-rfc
 
 Once we get our driver upstream, MSM will be an exception and not select
 ARM_GENERIC_CPUFREQ.  We'll probably have a separate msm-cpufreq.c
 driver under drivers/cpufreq/.
 
 - Bryan
 
 -- 
 Sent by an employee of the Qualcomm Innovation Center, Inc.
 The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [RFC V1 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-16 Thread Richard Zhao
On Fri, Dec 16, 2011 at 08:24:23AM +, Russell King - ARM Linux wrote:
 On Thu, Dec 15, 2011 at 12:50:07PM -0600, Mark Langsdorf wrote:
  I'd prefer to see clk_get90 replaced with of_clk_get() and
  get_this_cpu_node() from the clk-cpufreq driver by Jamie Iles that
  I resubmitted yesterday.
 
 Why isn't of_clk_get() hidden inside clk_get() ?
Good point.
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V2 0/4] add arm soc generic cpufreq driver

2011-12-16 Thread Richard Zhao
The driver support single core and multi core ARM SoCs. For multi core,
it assume all cores share the same clock and voltage.

Changes in v2:
 - add volatage change support
 - change '_' in property name to '-'
 - use initial value to calculate loops_per_jiffy
 - fix reading cpu_volts property bug 
 - let cpufreq_frequency_table_cpuinfo routines handle cpu_freq_khz_max/min
 - don't change freq in arm_cpufreq_exit, because every core share the same 
freq.
 - use unsigned long describe frequency as much as possible. Because clk use
   unsigned long, but cpufreq use unsigned int.

[PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver
[PATCH V2 2/4] dts/imx6q: add cpufreq property
[PATCH V2 3/4] arm/imx6q: register arm_clk as cpu to clkdev
[PATCH V2 4/4] arm/imx6q: select ARCH_HAS_CPUFREQ

Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V2 4/4] arm/imx6q: select ARCH_HAS_CPUFREQ

2011-12-16 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c44aa97..39cf00a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -595,6 +595,7 @@ comment i.MX6 family:
 
 config SOC_IMX6Q
bool i.MX6 Quad support
+   select ARCH_HAS_CPUFREQ
select ARM_GIC
select CACHE_L2X0
select CPU_V7
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V2 3/4] arm/imx6q: register arm_clk as cpu to clkdev

2011-12-16 Thread Richard Zhao
cpufreq needs cpu clock to change frequency.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/clock-imx6q.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
index 039a7ab..72acbc2 100644
--- a/arch/arm/mach-imx/clock-imx6q.c
+++ b/arch/arm/mach-imx/clock-imx6q.c
@@ -1911,6 +1911,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, gpmi_io_clk, gpmi_io_clk),
_REGISTER_CLOCK(NULL, usboh3_clk, usboh3_clk),
_REGISTER_CLOCK(NULL, sata_clk, sata_clk),
+   _REGISTER_CLOCK(NULL, cpu, arm_clk),
 };
 
 int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[PATCH V2 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-16 Thread Richard Zhao
It support single core and multi-core ARM SoCs. But it assume
all cores share the same frequency and voltage.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/Kconfig.arm   |8 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/arm-cpufreq.c |  269 +
 3 files changed, 278 insertions(+), 0 deletions(-)
 create mode 100644 drivers/cpufreq/arm-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 72a0044..a0f7d35 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -2,6 +2,14 @@
 # ARM CPU Frequency scaling drivers
 #
 
+config ARM_GENERIC_CPUFREQ
+   bool ARM generic
+   help
+ This adds ARM generic CPUFreq driver. It assumes all
+ cores of the SoC share the same clock and voltage.
+
+ If in doubt, say N.
+
 config ARM_S3C64XX_CPUFREQ
bool Samsung S3C64XX
depends on CPU_S3C6410
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ce75fcb..6ccf02d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
 
 
##
 # ARM SoC drivers
+obj-$(CONFIG_ARM_GENERIC_CPUFREQ)  += arm-cpufreq.o
 obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
 obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)  += s3c64xx-cpufreq.o
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)  += s5pv210-cpufreq.o
diff --git a/drivers/cpufreq/arm-cpufreq.c b/drivers/cpufreq/arm-cpufreq.c
new file mode 100644
index 000..e4d20da
--- /dev/null
+++ b/drivers/cpufreq/arm-cpufreq.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include linux/module.h
+#include linux/cpufreq.h
+#include linux/clk.h
+#include linux/regulator/consumer.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/of.h
+#include asm/cpu.h
+
+static u32 *cpu_freqs; /* HZ */
+static u32 *cpu_volts; /* uV */
+static u32 trans_latency; /* ns */
+static int cpu_op_nr;
+
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
+static unsigned long l_p_j_ref_freq;
+
+static struct clk *cpu_clk;
+static struct regulator *cpu_reg;
+static struct cpufreq_frequency_table *arm_freq_table;
+
+static int set_cpu_freq(unsigned long freq, int index, int higher)
+{
+   int ret = 0;
+
+   if (higher  cpu_reg)
+   regulator_set_voltage(cpu_reg,
+   cpu_volts[index], cpu_volts[index]);
+
+   ret = clk_set_rate(cpu_clk, freq);
+   if (ret != 0) {
+   printk(KERN_DEBUG cannot set CPU clock rate\n);
+   return ret;
+   }
+
+   if (!higher  cpu_reg)
+   regulator_set_voltage(cpu_reg,
+   cpu_volts[index], cpu_volts[index]);
+
+   return ret;
+}
+
+static int arm_verify_speed(struct cpufreq_policy *policy)
+{
+   return cpufreq_frequency_table_verify(policy, arm_freq_table);
+}
+
+static unsigned int arm_get_speed(unsigned int cpu)
+{
+   return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int arm_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+   struct cpufreq_freqs freqs;
+   unsigned long freq_Hz;
+   int cpu;
+   int ret = 0;
+   unsigned int index;
+
+   cpufreq_frequency_table_target(policy, arm_freq_table,
+   target_freq, relation, index);
+   freq_Hz = clk_round_rate(cpu_clk, cpu_freqs[index]);
+   freq_Hz = freq_Hz ? freq_Hz : cpu_freqs[index];
+   freqs.old = clk_get_rate(cpu_clk) / 1000;
+   freqs.new = clk_round_rate(cpu_clk, cpu_freqs[index]);
+   freqs.new = freq_Hz / 1000;
+   freqs.flags = 0;
+
+   if (freqs.old == freqs.new)
+   return 0;
+
+   for_each_possible_cpu(cpu) {
+   freqs.cpu = cpu;
+   cpufreq_notify_transition(freqs, CPUFREQ_PRECHANGE);
+   }
+
+   ret = set_cpu_freq(freq_Hz, index, (freqs.new  freqs.old));
+
+#ifdef CONFIG_SMP
+   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
+* So update it for all CPUs.
+*/
+   for_each_possible_cpu(cpu)
+   per_cpu(cpu_data, cpu).loops_per_jiffy =
+   cpufreq_scale(per_cpu(l_p_j_ref, cpu), l_p_j_ref_freq,
+   freqs.new);
+#endif
+
+   for_each_possible_cpu(cpu) {
+   freqs.cpu = cpu;
+   cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE);
+   }
+
+   return ret

[PATCH V2 2/4] dts/imx6q: add cpufreq property

2011-12-16 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/boot/dts/imx6q.dtsi |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 263e8f3..f2e3eaf 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -29,6 +29,9 @@
compatible = arm,cortex-a9;
reg = 0;
next-level-cache = L2;
+   cpu-freqs = 99600 79200 39600 19800;
+   cpu-volts = 1225000 110 95 85;
+   trans-latency = 61036; /* two CLK32 periods */
};
 
cpu@1 {
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH V2 3/4] arm/imx6q: register arm_clk as cpu to clkdev

2011-12-16 Thread Richard Zhao
On Fri, Dec 16, 2011 at 11:35:39AM -0500, Mark Langsdorf wrote:
 Is there a portable/generic approach for other drivers that may
 want to use arm-cpufreq.c? arm_clk is not normally defined for
 my SoC and I don't see an easy way to pull it in.
Could you tell me the details? Is your board arch/arm/mach-highbank/ Rob
maintained?
clk API is the most generic way for arm as far as I find out.

Thanks
Richard
 
 --Mark Langsdorf
 Calxeda, Inc.
 
 
 From: Richard Zhao [richard.z...@linaro.org]
 Sent: Friday, December 16, 2011 4:31 AM
 To: linux-arm-ker...@lists.infradead.org; cpuf...@vger.kernel.org; 
 devicetree-disc...@lists.ozlabs.org
 Cc: li...@arm.linux.org.uk; da...@redhat.com; ker...@pengutronix.de; 
 shawn@linaro.org; eric.m...@linaro.org; Mark Langsdorf; 
 linaro-dev@lists.linaro.org; patc...@linaro.org; Richard Zhao
 Subject: [PATCH V2 3/4] arm/imx6q: register arm_clk as cpu to clkdev
 
 cpufreq needs cpu clock to change frequency.
 
 Signed-off-by: Richard Zhao richard.z...@linaro.org
 ---
  arch/arm/mach-imx/clock-imx6q.c |1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
 
 diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
 index 039a7ab..72acbc2 100644
 --- a/arch/arm/mach-imx/clock-imx6q.c
 +++ b/arch/arm/mach-imx/clock-imx6q.c
 @@ -1911,6 +1911,7 @@ static struct clk_lookup lookups[] = {
 _REGISTER_CLOCK(NULL, gpmi_io_clk, gpmi_io_clk),
 _REGISTER_CLOCK(NULL, usboh3_clk, usboh3_clk),
 _REGISTER_CLOCK(NULL, sata_clk, sata_clk),
 +   _REGISTER_CLOCK(NULL, cpu, arm_clk),
  };
 
  int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
 --
 1.7.5.4

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[RFC V1 4/4] arm/imx6q: select ARCH_HAS_CPUFREQ

2011-12-15 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c44aa97..39cf00a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -595,6 +595,7 @@ comment i.MX6 family:
 
 config SOC_IMX6Q
bool i.MX6 Quad support
+   select ARCH_HAS_CPUFREQ
select ARM_GIC
select CACHE_L2X0
select CPU_V7
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[RFC V1 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-15 Thread Richard Zhao
It support single core and multi-core ARM SoCs. But it assume
all cores share the same frequency and voltage.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 drivers/cpufreq/Kconfig.arm   |8 ++
 drivers/cpufreq/Makefile  |1 +
 drivers/cpufreq/arm-cpufreq.c |  260 +
 3 files changed, 269 insertions(+), 0 deletions(-)
 create mode 100644 drivers/cpufreq/arm-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 72a0044..a0f7d35 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -2,6 +2,14 @@
 # ARM CPU Frequency scaling drivers
 #
 
+config ARM_GENERIC_CPUFREQ
+   bool ARM generic
+   help
+ This adds ARM generic CPUFreq driver. It assumes all
+ cores of the SoC share the same clock and voltage.
+
+ If in doubt, say N.
+
 config ARM_S3C64XX_CPUFREQ
bool Samsung S3C64XX
depends on CPU_S3C6410
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index ce75fcb..6ccf02d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
 
 
##
 # ARM SoC drivers
+obj-$(CONFIG_ARM_GENERIC_CPUFREQ)  += arm-cpufreq.o
 obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
 obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)  += s3c64xx-cpufreq.o
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)  += s5pv210-cpufreq.o
diff --git a/drivers/cpufreq/arm-cpufreq.c b/drivers/cpufreq/arm-cpufreq.c
new file mode 100644
index 000..fd9759f
--- /dev/null
+++ b/drivers/cpufreq/arm-cpufreq.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include linux/module.h
+#include linux/cpufreq.h
+#include linux/clk.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/of.h
+#include asm/cpu.h
+#include mach/hardware.h
+#include mach/clock.h
+
+static u32 *cpu_freqs;
+static u32 *cpu_volts;
+static u32 trans_latency;
+static int cpu_op_nr;
+
+static int cpu_freq_khz_min;
+static int cpu_freq_khz_max;
+
+static struct clk *cpu_clk;
+static struct cpufreq_frequency_table *arm_freq_table;
+
+static int set_cpu_freq(int freq)
+{
+   int ret = 0;
+   int org_cpu_rate;
+
+   org_cpu_rate = clk_get_rate(cpu_clk);
+   if (org_cpu_rate == freq)
+   return ret;
+
+   ret = clk_set_rate(cpu_clk, freq);
+   if (ret != 0) {
+   printk(KERN_DEBUG cannot set CPU clock rate\n);
+   return ret;
+   }
+
+   return ret;
+}
+
+static int arm_verify_speed(struct cpufreq_policy *policy)
+{
+   return cpufreq_frequency_table_verify(policy, arm_freq_table);
+}
+
+static unsigned int arm_get_speed(unsigned int cpu)
+{
+   return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int arm_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+   struct cpufreq_freqs freqs;
+   int freq_Hz, cpu;
+   int ret = 0;
+   unsigned int index;
+
+   cpufreq_frequency_table_target(policy, arm_freq_table,
+   target_freq, relation, index);
+   freq_Hz = arm_freq_table[index].frequency * 1000;
+
+   freqs.old = clk_get_rate(cpu_clk) / 1000;
+   freqs.new = clk_round_rate(cpu_clk, freq_Hz);
+   freqs.new = (freqs.new ? freqs.new : freq_Hz) / 1000;
+   freqs.flags = 0;
+
+   if (freqs.old == freqs.new)
+   return 0;
+
+   for_each_possible_cpu(cpu) {
+   freqs.cpu = cpu;
+   cpufreq_notify_transition(freqs, CPUFREQ_PRECHANGE);
+   }
+
+   ret = set_cpu_freq(freq_Hz);
+
+#ifdef CONFIG_SMP
+   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
+* So update it for all CPUs.
+*/
+   for_each_possible_cpu(cpu)
+   per_cpu(cpu_data, cpu).loops_per_jiffy =
+   cpufreq_scale(per_cpu(cpu_data, cpu).loops_per_jiffy,
+   freqs.old, freqs.new);
+#endif
+
+   for_each_possible_cpu(cpu) {
+   freqs.cpu = cpu;
+   cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE);
+   }
+
+   return ret;
+}
+
+static int arm_cpufreq_init(struct cpufreq_policy *policy)
+{
+   int ret;
+
+   printk(KERN_INFO ARM CPU frequency driver\n);
+
+   if (policy-cpu = num_possible_cpus())
+   return -EINVAL;
+
+   policy-cur = clk_get_rate(cpu_clk) / 1000;
+   policy-min = policy-cpuinfo.min_freq = cpu_freq_khz_min

[RFC V1 3/4] arm/imx6q: register arm_clk as cpu to clkdev

2011-12-15 Thread Richard Zhao
cpufreq needs cpu clock to change frequency.

Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/mach-imx/clock-imx6q.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
index 039a7ab..72acbc2 100644
--- a/arch/arm/mach-imx/clock-imx6q.c
+++ b/arch/arm/mach-imx/clock-imx6q.c
@@ -1911,6 +1911,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, gpmi_io_clk, gpmi_io_clk),
_REGISTER_CLOCK(NULL, usboh3_clk, usboh3_clk),
_REGISTER_CLOCK(NULL, sata_clk, sata_clk),
+   _REGISTER_CLOCK(NULL, cpu, arm_clk),
 };
 
 int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


[RFC V1 2/4] dts/imx6q: add cpufreq property

2011-12-15 Thread Richard Zhao
Signed-off-by: Richard Zhao richard.z...@linaro.org
---
 arch/arm/boot/dts/imx6q.dtsi |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 263e8f3..9e9943b 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -29,6 +29,8 @@
compatible = arm,cortex-a9;
reg = 0;
next-level-cache = L2;
+   cpu_freqs = 99600 79200 39600 19800;
+   cpu_volts = 1225000 110 95 85;
};
 
cpu@1 {
-- 
1.7.5.4



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [RFC V1 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-15 Thread Richard Zhao
TODO:
 - add voltage change.

Thanks
Richard 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [RFC V1 2/4] dts/imx6q: add cpufreq property

2011-12-15 Thread Richard Zhao
On Thu, Dec 15, 2011 at 07:58:54PM +0800, Shawn Guo wrote:
 Hi Richard,
 
 Whenever we invent some new device tree binding support, we need to
 Cc devicetree-disc...@lists.ozlabs.org (Cc-ed).
Thanks for your reminder.
 
 On Thu, Dec 15, 2011 at 07:16:36PM +0800, Richard Zhao wrote:
  Signed-off-by: Richard Zhao richard.z...@linaro.org
  ---
   arch/arm/boot/dts/imx6q.dtsi |2 ++
   1 files changed, 2 insertions(+), 0 deletions(-)
  
  diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
  index 263e8f3..9e9943b 100644
  --- a/arch/arm/boot/dts/imx6q.dtsi
  +++ b/arch/arm/boot/dts/imx6q.dtsi
  @@ -29,6 +29,8 @@
  compatible = arm,cortex-a9;
  reg = 0;
  next-level-cache = L2;
  +   cpu_freqs = 99600 79200 39600 19800;
  +   cpu_volts = 1225000 110 95 85;
 
 For dt property name, we use '-' rather than '_'.
ok.
 
 And I'm not sure this is correct, since these data obviously does not
 belong to arm,cortex-a9.
That's why RFC.

Thanks
Richard
 
 Regards,
 Shawn
 
  };
   
  cpu@1 {
  -- 
  1.7.5.4
 
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [RFC V1 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-15 Thread Richard Zhao
On Thu, Dec 15, 2011 at 12:50:07PM -0600, Mark Langsdorf wrote:
 Comments below. I tested this on the Calxeda Highbank SoC using
 QEMU. I found one definite error and a few things I would change.
Thanks for your test.
 
 On 12/15/2011 05:16 AM, Richard Zhao wrote:
 It support single core and multi-core ARM SoCs. But it assume
 all cores share the same frequency and voltage.
 
 Signed-off-by: Richard Zhaorichard.z...@linaro.org
 ---
 
 diff --git a/drivers/cpufreq/arm-cpufreq.c b/drivers/cpufreq/arm-cpufreq.c
 new file mode 100644
 index 000..fd9759f
 --- /dev/null
 +++ b/drivers/cpufreq/arm-cpufreq.c
 @@ -0,0 +1,260 @@
 +/*
 + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
 + */
 +
 +/*
 + * The code contained herein is licensed under the GNU General Public
 + * License. You may obtain a copy of the GNU General Public License
 + * Version 2 or later at the following locations:
 + *
 + * http://www.opensource.org/licenses/gpl-license.html
 + * http://www.gnu.org/copyleft/gpl.html
 + */
 +
 +#includelinux/module.h
 +#includelinux/cpufreq.h
 +#includelinux/clk.h
 +#includelinux/err.h
 +#includelinux/slab.h
 +#includelinux/of.h
 +#includeasm/cpu.h
 +#includemach/hardware.h
 +#includemach/clock.h
 
 These should probably be replaced by linux/of_clk.h. See
 below for details.
I'll remove mach/*.
But are you sure clk DT binding has went to -next or -rc? If yes,
I'm glad to use it. If no, I don't want to pend on it.
 
 +
 +static u32 *cpu_freqs;
 +static u32 *cpu_volts;
 +static u32 trans_latency;
 +static int cpu_op_nr;
 +
 +static int cpu_freq_khz_min;
 +static int cpu_freq_khz_max;
 +
 +static struct clk *cpu_clk;
 +static struct cpufreq_frequency_table *arm_freq_table;
 +
 +static int set_cpu_freq(int freq)
 +{
 +int ret = 0;
 +int org_cpu_rate;
 +
 +org_cpu_rate = clk_get_rate(cpu_clk);
 +if (org_cpu_rate == freq)
 +return ret;
 +
 +ret = clk_set_rate(cpu_clk, freq);
 +if (ret != 0) {
 +printk(KERN_DEBUG cannot set CPU clock rate\n);
 +return ret;
 +}
 +
 +return ret;
 +}
 +
 +static int arm_verify_speed(struct cpufreq_policy *policy)
 +{
 +return cpufreq_frequency_table_verify(policy, arm_freq_table);
 +}
 +
 +static unsigned int arm_get_speed(unsigned int cpu)
 +{
 +return clk_get_rate(cpu_clk) / 1000;
 +}
 +
 +static int arm_set_target(struct cpufreq_policy *policy,
 +  unsigned int target_freq, unsigned int relation)
 +{
 +struct cpufreq_freqs freqs;
 +int freq_Hz, cpu;
 +int ret = 0;
 +unsigned int index;
 +
 +cpufreq_frequency_table_target(policy, arm_freq_table,
 +target_freq, relation,index);
 +freq_Hz = arm_freq_table[index].frequency * 1000;
 +
 +freqs.old = clk_get_rate(cpu_clk) / 1000;
 +freqs.new = clk_round_rate(cpu_clk, freq_Hz);
 +freqs.new = (freqs.new ? freqs.new : freq_Hz) / 1000;
 +freqs.flags = 0;
 +
 +if (freqs.old == freqs.new)
 +return 0;
 +
 +for_each_possible_cpu(cpu) {
 +freqs.cpu = cpu;
 +cpufreq_notify_transition(freqs, CPUFREQ_PRECHANGE);
 +}
 +
 +ret = set_cpu_freq(freq_Hz);
 +
 +#ifdef CONFIG_SMP
 +/* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
 + * So update it for all CPUs.
 + */
 +for_each_possible_cpu(cpu)
 +per_cpu(cpu_data, cpu).loops_per_jiffy =
 +cpufreq_scale(per_cpu(cpu_data, cpu).loops_per_jiffy,
 +freqs.old, freqs.new);
 +#endif
 +
 +for_each_possible_cpu(cpu) {
 +freqs.cpu = cpu;
 +cpufreq_notify_transition(freqs, CPUFREQ_POSTCHANGE);
 +}
 +
 +return ret;
 +}
 +
 +static int arm_cpufreq_init(struct cpufreq_policy *policy)
 +{
 +int ret;
 +
 +printk(KERN_INFO ARM CPU frequency driver\n);
 +
 +if (policy-cpu= num_possible_cpus())
 +return -EINVAL;
 +
 +policy-cur = clk_get_rate(cpu_clk) / 1000;
 +policy-min = policy-cpuinfo.min_freq = cpu_freq_khz_min;
 +policy-max = policy-cpuinfo.max_freq = cpu_freq_khz_max;
 +policy-shared_type = CPUFREQ_SHARED_TYPE_ANY;
 +cpumask_setall(policy-cpus);
 +/* Manual states, that PLL stabilizes in two CLK32 periods */
 +policy-cpuinfo.transition_latency = trans_latency;
 +
 +ret = cpufreq_frequency_table_cpuinfo(policy, arm_freq_table);
 +
 +if (ret  0) {
 +printk(KERN_ERR %s: failed to register i.MXC CPUfreq with 
 error code %d\n,
 +   __func__, ret);
 +return ret;
 +}
 +
 +cpufreq_frequency_table_get_attr(arm_freq_table, policy-cpu);
 +return 0;
 +}
 +
 +static int arm_cpufreq_exit(struct cpufreq_policy *policy)
 +{
 +cpufreq_frequency_table_put_attr(policy-cpu);
 +
 +set_cpu_freq(cpu_freq_khz_max * 1000);
 +return 0;
 +}
 +
 +static struct cpufreq_driver arm_cpufreq_driver = {
 +.flags = CPUFREQ_STICKY,
 +.verify = arm_verify_speed

Re: [RFC V1 1/4] cpufreq: add arm soc generic cpufreq driver

2011-12-15 Thread Richard Zhao
On Thu, Dec 15, 2011 at 08:29:11PM +, Russell King - ARM Linux wrote:
 On Thu, Dec 15, 2011 at 07:16:35PM +0800, Richard Zhao wrote:
  +#ifdef CONFIG_SMP
  +   /* loops_per_jiffy is not updated by the cpufreq core for SMP systems.
  +* So update it for all CPUs.
  +*/
  +   for_each_possible_cpu(cpu)
  +   per_cpu(cpu_data, cpu).loops_per_jiffy =
  +   cpufreq_scale(per_cpu(cpu_data, cpu).loops_per_jiffy,
  +   freqs.old, freqs.new);
 
 NAK.  If you think this is a good solution, you're very wrong.  If this
 is what's in the core cpufreq code, then it too is very broken.
 
 I've seen this exact method result in the loops_per_jiffy being totally
 buggered over time by the constant scaling up and down.  The only way
 to do this _sensibly_ is to record the _initial_ loops_per_jiffy and
 _inital_ frequency, and scale from that.
 
 That way you get consistent results irrespective of the scalings you
 do over time, rather than something which continually deteriorates with
 every frequency change.
Thanks for your comments. I'll recalculate loops_per_jiffy always based on boot
up values.

Thanks
Richard
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [Activity] Power Management WG Weekly Status report for week ending 2011-12-09

2011-12-13 Thread Richard Zhao
Hi Amit,

On 12 December 2011 15:21, Amit Kucheria amit.kuche...@linaro.org wrote:
 On Sat, Dec 10, 2011 at 6:59 AM, Richard Zhao richard.z...@linaro.org wrote:
 I saw a topic 'Multi-core decision co-ordination' at 
 https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/CPUFreq .
 Is it still going on?

 Richard,

 This was related to teaching cpufreq to synchronise the scaling of
 frequency on both cores in case of a hardware constraint. But that is
 already taken care of by the cpufreq core (affected_cpus,
 related_cpus)
policy-shared_type = CPUFREQ_SHARED_TYPE_ANY;
cpumask_setall(policy-cpus);
Do you mean add above to cpufreq_driver.init ?
When suspend/resume, cpufreq_driver.init/exit also be called multi
times, though finally only cpu0 inited.

Thanks
Richard

 Regards,
 Amit

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v4 3/6] clk: introduce the common clock framework

2011-12-13 Thread Richard Zhao
Hi Mike,
 + *
 + * @recalc_rate  Recalculate the rate of this clock, by quering hardware
 + *   and/or the clock's parent. It is up to the caller to insure
 + *   that the prepare_mutex is held across this call.  Returns the
 + *   calculated rate.  Optional, but recommended - if this op is not
 + *   set then clock rate will be initialized to 0.
I'm still concerned, if it's NULL, why don't just retrun parent's rate if it 
has? 
 
Thanks
Richard


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [Activity] Power Management WG Weekly Status report for week ending 2011-12-09

2011-12-09 Thread Richard Zhao
I saw a topic 'Multi-core decision co-ordination' at 
https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/CPUFreq .
Is it still going on?

Thanks
Richard

___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: Bus framework

2011-10-26 Thread Richard Zhao
On 26 October 2011 14:39, Amit Kucheria amit.kuche...@linaro.org wrote:
 On 11 Oct 26, Richard Zhao wrote:
 Hi Amit,

 Is there anyone working on a SoC bus framework?
 The bus framework can manage the bus fabric, ddr, OCRAM clocks. When a
 device driver become working, it tells bus framework, cpu may access
 me (ip bus and related bus fabric on), I'm also a bus master, may
 access ddr (ddr dma access +1 ). For bus framework, if ddr dma access
 request is zero, ddr clk can be disabled in WFI/wait mode. The bus
 framework manage the SoC bus topology.  If a bus switch use count is
 zero, it can be disabled. It may even adjust the bus freq dynamically
 according to bus request.

 Why can't this be handled in the PM runtime framework? Bus runtime drivers
 retain the logic for enabling/disabling the clocks and regulators required
 for the bus.
Yes, I think it could be part of PM runtime framework. I just need the
function described above. Can we do that now?

Regards
Richard

 /Amit



___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-21 Thread Richard Zhao
On Thu, Sep 22, 2011 at 03:26:56PM -0700, Mike Turquette wrote:
 +/* For USE_COMMON_STRUCT_CLK, these are provided in clk.c, but not exported
 + * through other headers; we don't want them used anywhere but here. */
 +#ifdef CONFIG_USE_COMMON_STRUCT_CLK
change to CONFIG_GENERIC_CLK?
 +extern int __clk_get(struct clk *clk);
 +extern void __clk_put(struct clk *clk);
clk.c does not define it.
 +#endif

Thanks
Richard 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v2 4/7] clk: Add simple gated clock

2011-10-17 Thread Richard Zhao
On Sun, Oct 16, 2011 at 08:26:49PM +0200, Sascha Hauer wrote:
 On Wed, Oct 12, 2011 at 07:59:19AM -0700, Turquette, Mike wrote:
  On Tue, Oct 11, 2011 at 11:46 PM, Richard Zhao
  richard.z...@freescale.com wrote:
   On Thu, Sep 22, 2011 at 03:26:59PM -0700, Mike Turquette wrote:
   From: Jeremy Kerr jeremy.k...@canonical.com
  
   Signed-off-by: Jeremy Kerr jeremy.k...@canonical.com
   Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
   Signed-off-by: Jamie Iles ja...@jamieiles.com
   Signed-off-by: Mike Turquette mturque...@ti.com
   ---
   Changes since v1:
   Add copyright header
   Fold in Jamie's patch for set-to-disable clks
   Use BIT macro instead of shift
  
    drivers/clk/Kconfig    |    4 ++
    drivers/clk/Makefile   |    1 +
    drivers/clk/clk-gate.c |   78 
   
    include/linux/clk.h    |   13 
    4 files changed, 96 insertions(+), 0 deletions(-)
    create mode 100644 drivers/clk/clk-gate.c
  
   I feel hard to tell the tree the clk parent, at register/init time. For 
   the
   simple gate clk, the only way is to set .get_parent. But normally, for clk
   without any divider we set .get_parent to NULL. Maybe we can put .parent 
   to
   struct clk_hw?
  
  For non-mux clocks, whose parent is *always* going to be the same, you
  should create a duplicate .parent in the clk_hw_* structure and then
  have .get_parent return clk_hw_*-parent.
 
 Maybe I do not understand what you mean here, but I think there is
 something missing in the gate.
yes, clk_gate can not set fixed parent in v2 patch. Mike means add .parent int 
clk_gate
and set .get_parent in the ops.
 
  
  This is analogous to the way clk_hw_fixed returns clk_hw_fixed-rate
  when .recalc is called on it.
  
   +
   +static unsigned long clk_gate_get_rate(struct clk_hw *clk)
   +{
   +     return clk_get_rate(clk_get_parent(clk-clk));
   +}
 
 clk_get_parent goes down to clk_gate_set_enable_ops.get_parent below...
 
   +
   +
   +struct clk_hw_ops clk_gate_set_enable_ops = {
   +     .recalc_rate = clk_gate_get_rate,
   +     .enable = clk_gate_enable_set,
   +     .disable = clk_gate_disable_clear,
   +};
 
 ...but this does not have a get_parent pointer, so clk_get_parent()
 for a gate always returns NULL which means that a gate never has
 a valid rate.
 
 Sascha
 
 -- 
 Pengutronix e.K.   | |
 Industrial Linux Solutions | http://www.pengutronix.de/  |
 Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
 Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-17 Thread Richard Zhao
On Sun, Oct 16, 2011 at 07:55:21PM +0200, Sascha Hauer wrote:
 On Fri, Oct 14, 2011 at 06:32:33PM +0800, Richard Zhao wrote:
  On Fri, Oct 14, 2011 at 11:05:04AM +0100, Mark Brown wrote:
   On Fri, Oct 14, 2011 at 04:10:26PM +0800, Richard Zhao wrote:
On Thu, Sep 22, 2011 at 03:26:56PM -0700, Mike Turquette wrote:
   
   snip essentially Mike's entire mail - *please* delete irrelevant quotes
   from your replies, it makes it very much easier to find the new text in
   your mail and is much more friendly to people reading mail on mobile
   devices.
  I snip not enough? sorry for that. I'll be carefull.
   
 +static int __clk_enable(struct clk *clk)
 +{
   
Could you expose __clk_enable/__clk_disable? I find it hard to implement
clk group. clk group means, when a major clk enable/disable, it want a 
set
of other clks enable/disable accordingly.
   
   Shouldn't this be something the core is implementing?  I'd strongly
   expect that the clock drivers are relatively dumb and delegate all the
   decision making to the core API.  Otherwise it's going to be hard for
   the core to implement any logic that involves working with more than one
   clock like rate change notification, or guarantee that driver requests
   made through the API are satisfied, as the state of the clocks will be
   changing underneath it.
  From my point of view, the first step of generic clk can be, easy to adopt
  features of clocks in current mainline git.
  Back to the clk group, I have a patch based on Sascha's work. 
  http://git.linaro.org/gitweb?p=people/riczhao/linux-2.6.git;a=shortlog;h=refs/heads/imx-clk
 
 I thought further about this and a clock group is not something we want
 to have at all. Clocks are supposed to be arranged in a tree and
 grouping clocks together violates this which leads to problems.
 This grouping should be done at driver level, so when a driver needs
 more than one clock it should request them all, maybe with a clk_get_all
 helper function.
clock group is not limited to help driver get clock. It refects clock 
dependency.
For example, devices that possible access to on-chip RAM, depend on OCRAM 
clock. 
On imx53, VPU depends on OCRAM clock, even when VPU does not use OCRAM.

Thanks
Richard
 
 Sascha
 
 -- 
 Pengutronix e.K.   | |
 Industrial Linux Solutions | http://www.pengutronix.de/  |
 Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
 Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-17 Thread Richard Zhao
On Mon, Oct 17, 2011 at 10:20:28AM +0100, Mark Brown wrote:
 On Mon, Oct 17, 2011 at 04:48:52PM +0800, Richard Zhao wrote:
 
  For example, devices that possible access to on-chip RAM, depend on OCRAM 
  clock. 
  On imx53, VPU depends on OCRAM clock, even when VPU does not use OCRAM.
 
 So if the VPU depends on OCRAM the VPU should be enabling the OCRAM
 clock.  The function of a given clock isn't terribly relevant, and
 certainly grouping clocks together doesn't seem to be the obvious
 solution from what you've said
VPU don't know OCRAM clk, it's SoC specific. I know it's clock function
replationship. But it's the only better place to refect the dependency 
in clock tree. Another dependency example, from SoC bus topology, some bus
clk always depends on bus switch/hub.
 - if the driver doesn't know about the
 clock it seems like the core ought to be enabling it transparently
 rather than gluing it together with some other random clock.
If you mean clk core here, then we need things like below:
struct clk_hw {
struct clk *clk;
struct dependency {
struct clk_hw *clks;
int count;
};
};
Though Mike does not like to add things in clk_hw, but it's the only place
to put common things of clk drivers.

Thanks
Richard
 
 Either way the point here is that individual drivers shouldn't be hand
 coding this stuff, it should be being handled by core code.
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-17 Thread Richard Zhao
On Sun, Oct 16, 2011 at 02:17:29PM -0700, Turquette, Mike wrote:
 On Fri, Oct 14, 2011 at 7:24 PM, Richard Zhao richard.z...@linaro.org wrote:
  On Fri, Oct 14, 2011 at 11:14:19AM -0700, Turquette, Mike wrote:
  On Thu, Sep 22, 2011 at 3:26 PM, Mike Turquette mturque...@ti.com wrote:
  unsigned long omap_recalc_rate(struct clk_hw *hw)
  {
          struct clk *parent;
          struct clk_hw_omap *oclk;
 
          parent = hw-clk-parent;
  clk drivers can not see struct clk details. I use clk_get_parent.
 
 clk_get_parent should query the hardware to see what the parent is.
 This can have undesireable overhead.  It is quite acceptable to
 reference a clock's parent through clk-parent, just as it is
 acceptable to get a clock rate through clk-rate.
IMHO, we only need to get parent from hw at register/init time.
clk_get_parent can get it from cache, like current code.
 
 An analogous situation is a clk_get_rate call which uses a clk's
 .recalc.  There is undesirable overhead involved in .recalc for clocks
 whose rates won't change behind our backs, so best to just treat the
 data in struct clk as cache and reference it directly.
 
          oclk = to_clk_omap(hw);
          ...
  }
 
 ...
 
  unsigned long omap_recalc_rate(struct clk *clk)
  {
          struct clk *parent;
          struct clk_hw_omap *oclk;
 
          parent = clk-parent;
          oclk = to_clk_omap(clk-hw);
          ...
  }
  In my understanding, struct clk stores things specific to clk core,
  struct clk_hw stores common things needed by clk drivers. For static clk 
  driver
  there' some problems:
   - For clocks without mux, I need duplicate a  .parent and set .get_parent.
    Even when we adopt DT and dynamicly create clk, it's still a problem.
    Moving .parent to clk_hw can fix it.
 
 For clocks with a fixed parent we should just pass it in at
 register-time.  We should definitely not move .parent out of struct
 clk, since struct clk should be the platform agnostic bit that lets us
 do tree walks, build topology, etc etc.
 
 If you really want a .parent outside of struct clk then duplicate it
 in your struct clk_hw_imx
I don't have clk_hw_imx. I just use generic clks like clk_hw_gate, 
clk_hw_divider,
clk_hw_mux, and some specific clks.
  and teach your .ops about it (analogous to
 struct clk_hw_fixed-rate).
I have to define things like below:
stuct pair {
struct clk_hw *clk = clk_hw_gate.hw;
struct clk_hw_ops *ops;
};
and use for (.. ) to register the clk array.
 
   - When I define a clk array, I don't need to find another place to store 
  .ops.
    It's not problem for dynamic creating clock.
 
 Something like the following?
 
 static struct clk aess_fclk;
 
 static const clk_hw_ops aess_fclk_ops = {
 .recalc = omap2_clksel_recalc,
 .round_rate = omap2_clksel_round_rate,
 .set_rate = omap2_clksel_set_rate,
 };
 
 static struct clk_hw_omap aess_fclk_hw = {
 .hw = {
 .clk = aess_fclk,
 },
 .clksel = aess_fclk_div,
 .clksel_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL,
 .clksel_mask = OMAP4430_CLKSEL_AESS_FCLK_MASK,
 };
 
 static struct clk aess_fclk = {
 .name = aess_fclk,
 .ops = aess_fclk_ops,
 .hw = aess_fclk_hw.hw,
 .parent = abe_clk,
 };
If we don't protect struct clk members, how about the below:
struct clk_hw_omap aess_fclk = {
.clk = {
.name = aess_fclk,
.ops = aess_fclk_ops,
.parent = abe_clk,
};
 .clksel = aess_fclk_div,
 .clksel_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL,
 .clksel_mask = OMAP4430_CLKSEL_AESS_FCLK_MASK,
};

 
   - As I mentioned in another mail, clk group need no lock version 
  prepare/unprepare
    and enable/disable functions
 
 Clock groups are out of scope for this first series.  We should
 discuss more what the needs are for your clock groups.  If it boils
 down to just enabling all of the clocks for a given device then you
 might want to abstract that away with pm_runtime_* calls, and maybe a
 supplementary layer like OMAP's hwmod.  But I might be way off base, I
 really don't understand your use case for clock groups.
clk group is clk function dependency. I talked about it in another email in 
this thread.
That's ok to leave it to other framework.
 
    Another way is, add a {struct clk_hw *clks; int count} in clk_hw, let 
  clk
    core handle it.
    I prefer the second way, but I'm not sure whether it's common enough. It's
    still a problem for dynamic creating clock.
 
 struct clk_hw is just a pointer for navigating from struct clk -
 struct your_custom_clk and vice versa.  Again can you elaborate on
 your needs for managing multiple clocks with a single struct clk_hw?

 
 Thanks,
 Mike
 
 
  Thanks
  Richard
 
  It is a small nitpick, but it affects the API for everybody so best to
  get it right now before folks start migrating over to it.
 
  Thanks,
  Mike
 
          int

Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-14 Thread Richard Zhao
Hi Mike,

On Thu, Sep 22, 2011 at 03:26:56PM -0700, Mike Turquette wrote:
 From: Jeremy Kerr jeremy.k...@canonical.com
 
 We currently have ~21 definitions of struct clk in the ARM architecture,
 each defined on a per-platform basis. This makes it difficult to define
 platform- (or architecture-) independent clock sources without making
 assumptions about struct clk, and impossible to compile two
 platforms with different struct clks into a single image.
 
 This change is an effort to unify struct clk where possible, by defining
 a common struct clk, and a set of clock operations. Different clock
 implementations can set their own operations, and have a standard
 interface for generic code. The callback interface is exposed to the
 kernel proper, while the clock implementations only need to be seen by
 the platform internals.
 
 The interface is split into two halves:
 
  * struct clk, which is the generic-device-driver interface. This
provides a set of functions which drivers may use to request
enable/disable, query or manipulate in a hardware-independent manner.
 
  * struct clk_hw and struct clk_hw_ops, which is the hardware-specific
interface. Clock drivers implement the ops, which allow the core
clock code to implement the generic 'struct clk' API.
 
 This allows us to share clock code among platforms, and makes it
 possible to dynamically create clock devices in platform-independent
 code.
 
 Platforms can enable the generic struct clock through
 CONFIG_GENERIC_CLK. In this case, the clock infrastructure consists of a
 common, opaque struct clk, and a set of clock operations (defined per
 type of clock):
 
   struct clk_hw_ops {
   int (*prepare)(struct clk_hw *);
   void(*unprepare)(struct clk_hw *);
   int (*enable)(struct clk_hw *);
   void(*disable)(struct clk_hw *);
   unsigned long   (*recalc_rate)(struct clk_hw *);
   int (*set_rate)(struct clk_hw *,
   unsigned long, unsigned long *);
   long(*round_rate)(struct clk_hw *, unsigned long);
   int (*set_parent)(struct clk_hw *, struct clk *);
   struct clk *(*get_parent)(struct clk_hw *);
   };
 
 Platform clock code can register a clock through clk_register, passing a
 set of operations, and a pointer to hardware-specific data:
 
   struct clk_hw_foo {
   struct clk_hw clk;
   void __iomem *enable_reg;
   };
 
   #define to_clk_foo(c) offsetof(c, clk_hw_foo, clk)
 
   static int clk_foo_enable(struct clk_hw *clk)
   {
   struct clk_foo *foo = to_clk_foo(clk);
   raw_writeb(foo-enable_reg, 1);
   return 0;
   }
 
   struct clk_hw_ops clk_foo_ops = {
   .enable = clk_foo_enable,
   };
 
 And in the platform initialisation code:
 
   struct clk_foo my_clk_foo;
 
   void init_clocks(void)
   {
   my_clk_foo.enable_reg = ioremap(...);
 
   clk_register(clk_foo_ops, my_clk_foo, NULL);
   }
 
 Changes from Thomas Gleixner t...@linutronix.de.
 
 The common clock definitions are based on a development patch from Ben
 Herrenschmidt b...@kernel.crashing.org.
 
 TODO:
 
  * We don't keep any internal reference to the clock topology at present.
 
 Signed-off-by: Jeremy Kerr jeremy.k...@canonical.com
 Signed-off-by: Thomas Gleixner t...@linutronix.de
 Signed-off-by: Mark Brown broo...@opensource.wolfsonmicro.com
 Signed-off-by: Mike Turquette mturque...@ti.com
 ---
 Changes since v1:
 Create a dummy clk_unregister and prototype/document it and clk_register
 Constify struct clk_hw_ops
 Remove spinlock.h header, include kernel.h
 Use EOPNOTSUPP instead of ENOTSUPP
 Add might_sleep to clk_prepare/clk_unprepare stubs
 Properly init children hlist and child_node
 Whitespace and typo fixes
 
  drivers/clk/Kconfig  |3 +
  drivers/clk/Makefile |1 +
  drivers/clk/clk.c|  232 
 ++
  drivers/clk/clkdev.c |7 ++
  include/linux/clk.h  |  140 +++---
  5 files changed, 371 insertions(+), 12 deletions(-)
  create mode 100644 drivers/clk/clk.c
 
[...]
 +static void __clk_disable(struct clk *clk)
 +{
 + if (!clk)
 + return;
 +
 + if (WARN_ON(clk-enable_count == 0))
 + return;
 +
 + if (--clk-enable_count  0)
 + return;
 +
 + if (clk-ops-disable)
 + clk-ops-disable(clk-hw);
 + __clk_disable(clk-parent);
 +}
 +
 +void clk_disable(struct clk *clk)
 +{
 + unsigned long flags;
 +
 + spin_lock_irqsave(enable_lock, flags);
 + __clk_disable(clk);
 + spin_unlock_irqrestore(enable_lock, flags);
 +}
 +EXPORT_SYMBOL_GPL(clk_disable);
 +
 +static int __clk_enable(struct clk *clk)
 +{
 + int ret;
 +
 + if (!clk)
 + return 0;
 +
 + if (WARN_ON(clk-prepare_count == 0))
 + return -ESHUTDOWN;
 +
 +
 + if (clk-enable_count == 0) {
 + ret = __clk_enable(clk-parent);
 +   

Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-14 Thread Richard Zhao
On Fri, Oct 14, 2011 at 11:05:04AM +0100, Mark Brown wrote:
 On Fri, Oct 14, 2011 at 04:10:26PM +0800, Richard Zhao wrote:
  On Thu, Sep 22, 2011 at 03:26:56PM -0700, Mike Turquette wrote:
 
 snip essentially Mike's entire mail - *please* delete irrelevant quotes
 from your replies, it makes it very much easier to find the new text in
 your mail and is much more friendly to people reading mail on mobile
 devices.
I snip not enough? sorry for that. I'll be carefull.
 
   +static int __clk_enable(struct clk *clk)
   +{
 
  Could you expose __clk_enable/__clk_disable? I find it hard to implement
  clk group. clk group means, when a major clk enable/disable, it want a set
  of other clks enable/disable accordingly.
 
 Shouldn't this be something the core is implementing?  I'd strongly
 expect that the clock drivers are relatively dumb and delegate all the
 decision making to the core API.  Otherwise it's going to be hard for
 the core to implement any logic that involves working with more than one
 clock like rate change notification, or guarantee that driver requests
 made through the API are satisfied, as the state of the clocks will be
 changing underneath it.
From my point of view, the first step of generic clk can be, easy to adopt
features of clocks in current mainline git.
Back to the clk group, I have a patch based on Sascha's work. 
http://git.linaro.org/gitweb?p=people/riczhao/linux-2.6.git;a=shortlog;h=refs/heads/imx-clk

Thanks
Richard
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-14 Thread Richard Zhao
On Fri, Oct 14, 2011 at 11:14:19AM -0700, Turquette, Mike wrote:
 On Thu, Sep 22, 2011 at 3:26 PM, Mike Turquette mturque...@ti.com wrote:
  From: Jeremy Kerr jeremy.k...@canonical.com
   struct clk_hw_ops {
         int             (*prepare)(struct clk_hw *);
         void            (*unprepare)(struct clk_hw *);
         int             (*enable)(struct clk_hw *);
         void            (*disable)(struct clk_hw *);
         unsigned long   (*recalc_rate)(struct clk_hw *);
 
 In implementing recalc for divider clocks, I started to wonder, why
 not just pass struct clk *clk into the clk_hw_ops func ptrs?.
 
 recalc is an obvious example whereby we need access to parent-rate.
 The code usually ends up looking something like:
 
 unsigned long omap_recalc_rate(struct clk_hw *hw)
 {
 struct clk *parent;
 struct clk_hw_omap *oclk;
 
 parent = hw-clk-parent;
clk drivers can not see struct clk details. I use clk_get_parent.
 oclk = to_clk_omap(hw);
 ...
 }
 
 That's a bit of a song and dance to have to do in almost every op, and
 often these ops will need access to stuff like clk-rate also.   Is
 there any opposition to just passing in struct clk?  e.g:
 
 unsigned long omap_recalc_rate(struct clk *clk)
 {
 struct clk *parent;
 struct clk_hw_omap *oclk;
 
 parent = clk-parent;
 oclk = to_clk_omap(clk-hw);
 ...
 }
In my understanding, struct clk stores things specific to clk core,
struct clk_hw stores common things needed by clk drivers. For static clk driver
there' some problems:
 - For clocks without mux, I need duplicate a  .parent and set .get_parent.
   Even when we adopt DT and dynamicly create clk, it's still a problem.
   Moving .parent to clk_hw can fix it.
 - When I define a clk array, I don't need to find another place to store .ops.
   It's not problem for dynamic creating clock.
 - As I mentioned in another mail, clk group need no lock version 
prepare/unprepare
   and enable/disable functions
   Another way is, add a {struct clk_hw *clks; int count} in clk_hw, let clk
   core handle it.
   I prefer the second way, but I'm not sure whether it's common enough. It's
   still a problem for dynamic creating clock.

Thanks
Richard
 
 It is a small nitpick, but it affects the API for everybody so best to
 get it right now before folks start migrating over to it.
 
 Thanks,
 Mike
 
         int             (*set_rate)(struct clk_hw *,
                                         unsigned long, unsigned long *);
         long            (*round_rate)(struct clk_hw *, unsigned long);
         int             (*set_parent)(struct clk_hw *, struct clk *);
         struct clk *    (*get_parent)(struct clk_hw *);
   };
 
 ___
 linux-arm-kernel mailing list
 linux-arm-ker...@lists.infradead.org
 http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure

2011-10-14 Thread Richard Zhao
  - When I define a clk array, I don't need to find another place to store 
 .ops.
  ^
remove don't. sorry for that.
 


___
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev


  1   2   >