RE: [PATCH 4/5] [CPUFREQ] EXYNOS4210: Add DVS lock feature for other driver

2011-11-04 Thread Kukjin Kim
MyungJoo Ham wrote:
 
 On Wed, Nov 2, 2011 at 9:43 PM, Kukjin Kim kgene@samsung.com wrote:
  From: Jongpill Lee boyko@samsung.com
 
  This patch adds DVS lock feature for other driver and pm/
  reboot notifier to enhance stability.
 
(snip)
 
Same, following is from Jaecheol Lee.

 Except for the case of PM (suspend/reset), it appears that this
 feature is something that is meant to be supported by qos
 (linux/pm_qos.h).
 Couldn't we simply use the QoS feature to support locking frequency
 above some specific levels? With QoS, I guess the implementation
 becomes more general and straightforward.
 Although we will probably need to use CPU_DMA_LATENCY for this case,
 I think it isn't awefully difficult to use DMA-Latency as the metric.
 
Our goal is removal of using this cpufreq lock, but now some device driver
which is not fully optimized need to use this lock temporary. If there is no
request of this API from device driver, we will remove this feature or
support this feature with different manner as you mentioned.

 One concern about this is that we are hereby enforcing all the related
 device drivers stuck with Exynos4210 only unless others also use
 cpufreq_lock_ID and its friends.

We recommend this feature in only rare instances (performance issue). After
resolving that problem, the device driver which is using lock should be
modified with removing lock. Actually, there is no device driver that using
lock now.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim kgene@samsung.com, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/5] [CPUFREQ] EXYNOS4210: Add DVS lock feature for other driver

2011-11-02 Thread MyungJoo Ham
On Wed, Nov 2, 2011 at 9:43 PM, Kukjin Kim kgene@samsung.com wrote:
 From: Jongpill Lee boyko@samsung.com

 This patch adds DVS lock feature for other driver and pm/
 reboot notifier to enhance stability.

 Signed-off-by: Jongpill Lee boyko@samsung.com
 Signed-off-by: SangWook Ju sw...@samsung.com
 Signed-off-by: Jonghwan Choi jhbird.c...@samsung.com
 Signed-off-by: Jaecheol Lee jc@samsung.com
 ---
  arch/arm/mach-exynos4/include/mach/cpufreq.h |   39 ++
  drivers/cpufreq/exynos4210-cpufreq.c         |  174
 +-
  2 files changed, 207 insertions(+), 6 deletions(-)
  create mode 100644 arch/arm/mach-exynos4/include/mach/cpufreq.h

 diff --git a/arch/arm/mach-exynos4/include/mach/cpufreq.h
 b/arch/arm/mach-exynos4/include/mach/cpufreq.h
 new file mode 100644
 index 000..7e00931
 --- /dev/null
 +++ b/arch/arm/mach-exynos4/include/mach/cpufreq.h
 @@ -0,0 +1,39 @@
 +/* linux/arch/arm/mach-exynos4/include/mach/cpufreq.h
 + *
 + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
 + *             http://www.samsung.com
 + *
 + * EXYNOS4 - CPUFreq support
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +
 +/*
 + * CPU frequency level index for using cpufreq lock API
 + * This should be same with cpufreq_frequency_table
 + */
 +enum cpufreq_level_request {
 +       CPU_L0,         /* 1200MHz */
 +       CPU_L1,         /* 1000MHz */
 +       CPU_L2,         /* 800MHz */
 +       CPU_L3,         /* 500MHz */
 +       CPU_L4,         /* 200MHz */
 +       CPU_LEVEL_END,
 +};
 +
 +enum cpufreq_lock_ID {
 +       DVFS_LOCK_ID_G2D,       /* G2D */
 +       DVFS_LOCK_ID_TV,        /* TV */
 +       DVFS_LOCK_ID_MFC,       /* MFC */
 +       DVFS_LOCK_ID_USB,       /* USB */
 +       DVFS_LOCK_ID_CAM,       /* CAM */
 +       DVFS_LOCK_ID_PM,        /* PM */
 +       DVFS_LOCK_ID_USER,      /* USER */
 +       DVFS_LOCK_ID_END,
 +};
 +
 +int exynos4_cpufreq_lock(unsigned int nId,
 +                       enum cpufreq_level_request cpufreq_level);
 +void exynos4_cpufreq_lock_free(unsigned int nId);
 diff --git a/drivers/cpufreq/exynos4210-cpufreq.c
 b/drivers/cpufreq/exynos4210-cpufreq.c
 index 246f9e2..30e1949 100644
 --- a/drivers/cpufreq/exynos4210-cpufreq.c
 +++ b/drivers/cpufreq/exynos4210-cpufreq.c
 @@ -17,14 +17,21 @@
  #include linux/slab.h
  #include linux/regulator/consumer.h
  #include linux/cpufreq.h
 +#include linux/suspend.h
 +#include linux/reboot.h

  #include mach/map.h
  #include mach/regs-clock.h
  #include mach/regs-mem.h
 +#include mach/cpufreq.h

  #include plat/clock.h
  #include plat/pm.h

 +static bool exynos4_cpufreq_init_done;
 +static DEFINE_MUTEX(set_freq_lock);
 +static DEFINE_MUTEX(set_cpu_freq_lock);
 +
  static struct clk *cpu_clk;
  static struct clk *moutcore;
  static struct clk *mout_mpll;
 @@ -53,6 +60,12 @@ static struct cpufreq_frequency_table
 exynos4_freq_table[] = {
        {0, CPUFREQ_TABLE_END},
  };

 +/* This defines are for cpufreq lock */
 +#define CPUFREQ_MIN_LEVEL      (CPUFREQ_LEVEL_END - 1)
 +unsigned int cpufreq_lock_id;
 +unsigned int cpufreq_lock_val[DVFS_LOCK_ID_END];
 +unsigned int cpufreq_lock_level = CPUFREQ_MIN_LEVEL;
 +
  static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
        /*
         * Clock divider value for following
 @@ -272,22 +285,31 @@ static int exynos4_target(struct cpufreq_policy
 *policy,
  {
        unsigned int index, old_index;
        unsigned int arm_volt;
 +       int ret = 0;
 +
 +       mutex_lock(set_freq_lock);

        freqs.old = exynos4_getspeed(policy-cpu);

        if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
 -                                          freqs.old, relation, old_index))
 -               return -EINVAL;
 +                                          freqs.old, relation, old_index))
 {
 +               ret = -EINVAL;
 +               goto out;
 +       }

        if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
 -                                          target_freq, relation, index))
 -               return -EINVAL;
 +                                          target_freq, relation, index)) {
 +               ret = -EINVAL;
 +               goto out;
 +       }

        freqs.new = exynos4_freq_table[index].frequency;
        freqs.cpu = policy-cpu;

 -       if (freqs.new == freqs.old)
 -               return 0;
 +       if (freqs.new == freqs.old) {
 +               ret = -EINVAL;
 +               goto out;
 +       }

        /* get the voltage value */
        arm_volt = exynos4_volt_table[index].arm_volt;
 @@ -311,8 +333,98 @@ static int exynos4_target(struct cpufreq_policy
 *policy,
                regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
        }

 +out:
 +       mutex_unlock(set_freq_lock);
 +
 +       return ret;
 +}
 +
 +atomic_t