aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/s5pv210-cpufreq.c
diff options
context:
space:
mode:
authorJonghwan Choi <jhbird.choi@samsung.com>2011-06-24 03:04:14 -0400
committerDave Jones <davej@redhat.com>2011-07-13 18:29:56 -0400
commite8b4c1986efbb5b1e1bab9f359c340816e4d9869 (patch)
treec785578962af93033cc0136ae2dcf66ff72cc4de /drivers/cpufreq/s5pv210-cpufreq.c
parent90d5d0a119bcf189e8b33f776b4f8371b789b311 (diff)
[CPUFREQ] S5PV210: Add arm/int voltage control support
Signed-off-by: Jonghwan Choi <jhbird.choi@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/cpufreq/s5pv210-cpufreq.c')
-rw-r--r--drivers/cpufreq/s5pv210-cpufreq.c71
1 files changed, 68 insertions, 3 deletions
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c
index 48a4a9058864..9a5b28474342 100644
--- a/drivers/cpufreq/s5pv210-cpufreq.c
+++ b/drivers/cpufreq/s5pv210-cpufreq.c
@@ -16,6 +16,7 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/cpufreq.h> 18#include <linux/cpufreq.h>
19#include <linux/regulator/consumer.h>
19 20
20#include <mach/map.h> 21#include <mach/map.h>
21#include <mach/regs-clock.h> 22#include <mach/regs-clock.h>
@@ -77,6 +78,40 @@ static struct cpufreq_frequency_table s5pv210_freq_table[] = {
77 {0, CPUFREQ_TABLE_END}, 78 {0, CPUFREQ_TABLE_END},
78}; 79};
79 80
81static struct regulator *arm_regulator;
82static struct regulator *int_regulator;
83
84struct s5pv210_dvs_conf {
85 int arm_volt; /* uV */
86 int int_volt; /* uV */
87};
88
89static const int arm_volt_max = 1350000;
90static const int int_volt_max = 1250000;
91
92static struct s5pv210_dvs_conf dvs_conf[] = {
93 [L0] = {
94 .arm_volt = 1250000,
95 .int_volt = 1100000,
96 },
97 [L1] = {
98 .arm_volt = 1200000,
99 .int_volt = 1100000,
100 },
101 [L2] = {
102 .arm_volt = 1050000,
103 .int_volt = 1100000,
104 },
105 [L3] = {
106 .arm_volt = 950000,
107 .int_volt = 1100000,
108 },
109 [L4] = {
110 .arm_volt = 950000,
111 .int_volt = 1000000,
112 },
113};
114
80static u32 clkdiv_val[5][11] = { 115static u32 clkdiv_val[5][11] = {
81 /* 116 /*
82 * Clock divider value for following 117 * Clock divider value for following
@@ -157,6 +192,8 @@ static int s5pv210_target(struct cpufreq_policy *policy,
157 unsigned int index, priv_index; 192 unsigned int index, priv_index;
158 unsigned int pll_changing = 0; 193 unsigned int pll_changing = 0;
159 unsigned int bus_speed_changing = 0; 194 unsigned int bus_speed_changing = 0;
195 int arm_volt, int_volt;
196 int ret = 0;
160 197
161 if (relation & ENABLE_FURTHER_CPUFREQ) 198 if (relation & ENABLE_FURTHER_CPUFREQ)
162 no_cpufreq_access = false; 199 no_cpufreq_access = false;
@@ -191,12 +228,23 @@ static int s5pv210_target(struct cpufreq_policy *policy,
191 freqs.old, relation, &priv_index)) 228 freqs.old, relation, &priv_index))
192 return -EINVAL; 229 return -EINVAL;
193 230
194 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 231 arm_volt = dvs_conf[index].arm_volt;
232 int_volt = dvs_conf[index].int_volt;
195 233
196 if (freqs.new > freqs.old) { 234 if (freqs.new > freqs.old) {
197 /* Voltage up: will be implemented */ 235 ret = regulator_set_voltage(arm_regulator,
236 arm_volt, arm_volt_max);
237 if (ret)
238 return ret;
239
240 ret = regulator_set_voltage(int_regulator,
241 int_volt, int_volt_max);
242 if (ret)
243 return ret;
198 } 244 }
199 245
246 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
247
200 /* Check if there need to change PLL */ 248 /* Check if there need to change PLL */
201 if ((index == L0) || (priv_index == L0)) 249 if ((index == L0) || (priv_index == L0))
202 pll_changing = 1; 250 pll_changing = 1;
@@ -408,7 +456,11 @@ static int s5pv210_target(struct cpufreq_policy *policy,
408 } 456 }
409 457
410 if (freqs.new < freqs.old) { 458 if (freqs.new < freqs.old) {
411 /* Voltage down: will be implemented */ 459 regulator_set_voltage(int_regulator,
460 int_volt, int_volt_max);
461
462 regulator_set_voltage(arm_regulator,
463 arm_volt, arm_volt_max);
412 } 464 }
413 465
414 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 466 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
@@ -515,6 +567,19 @@ static struct cpufreq_driver s5pv210_driver = {
515 567
516static int __init s5pv210_cpufreq_init(void) 568static int __init s5pv210_cpufreq_init(void)
517{ 569{
570 arm_regulator = regulator_get(NULL, "vddarm");
571 if (IS_ERR(arm_regulator)) {
572 pr_err("failed to get regulator vddarm");
573 return PTR_ERR(arm_regulator);
574 }
575
576 int_regulator = regulator_get(NULL, "vddint");
577 if (IS_ERR(int_regulator)) {
578 pr_err("failed to get regulator vddint");
579 regulator_put(arm_regulator);
580 return PTR_ERR(int_regulator);
581 }
582
518 return cpufreq_register_driver(&s5pv210_driver); 583 return cpufreq_register_driver(&s5pv210_driver);
519} 584}
520 585