From e8b4c1986efbb5b1e1bab9f359c340816e4d9869 Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Fri, 24 Jun 2011 16:04:14 +0900 Subject: [CPUFREQ] S5PV210: Add arm/int voltage control support Signed-off-by: Jonghwan Choi Signed-off-by: Kukjin Kim Signed-off-by: Dave Jones --- drivers/cpufreq/s5pv210-cpufreq.c | 71 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) (limited to 'drivers/cpufreq') diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 48a4a90..9a5b284 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,40 @@ static struct cpufreq_frequency_table s5pv210_freq_table[] = { {0, CPUFREQ_TABLE_END}, }; +static struct regulator *arm_regulator; +static struct regulator *int_regulator; + +struct s5pv210_dvs_conf { + int arm_volt; /* uV */ + int int_volt; /* uV */ +}; + +static const int arm_volt_max = 1350000; +static const int int_volt_max = 1250000; + +static struct s5pv210_dvs_conf dvs_conf[] = { + [L0] = { + .arm_volt = 1250000, + .int_volt = 1100000, + }, + [L1] = { + .arm_volt = 1200000, + .int_volt = 1100000, + }, + [L2] = { + .arm_volt = 1050000, + .int_volt = 1100000, + }, + [L3] = { + .arm_volt = 950000, + .int_volt = 1100000, + }, + [L4] = { + .arm_volt = 950000, + .int_volt = 1000000, + }, +}; + static u32 clkdiv_val[5][11] = { /* * Clock divider value for following @@ -157,6 +192,8 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index, priv_index; unsigned int pll_changing = 0; unsigned int bus_speed_changing = 0; + int arm_volt, int_volt; + int ret = 0; if (relation & ENABLE_FURTHER_CPUFREQ) no_cpufreq_access = false; @@ -191,12 +228,23 @@ static int s5pv210_target(struct cpufreq_policy *policy, freqs.old, relation, &priv_index)) return -EINVAL; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + arm_volt = dvs_conf[index].arm_volt; + int_volt = dvs_conf[index].int_volt; if (freqs.new > freqs.old) { - /* Voltage up: will be implemented */ + ret = regulator_set_voltage(arm_regulator, + arm_volt, arm_volt_max); + if (ret) + return ret; + + ret = regulator_set_voltage(int_regulator, + int_volt, int_volt_max); + if (ret) + return ret; } + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + /* Check if there need to change PLL */ if ((index == L0) || (priv_index == L0)) pll_changing = 1; @@ -408,7 +456,11 @@ static int s5pv210_target(struct cpufreq_policy *policy, } if (freqs.new < freqs.old) { - /* Voltage down: will be implemented */ + regulator_set_voltage(int_regulator, + int_volt, int_volt_max); + + regulator_set_voltage(arm_regulator, + arm_volt, arm_volt_max); } cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); @@ -515,6 +567,19 @@ static struct cpufreq_driver s5pv210_driver = { static int __init s5pv210_cpufreq_init(void) { + arm_regulator = regulator_get(NULL, "vddarm"); + if (IS_ERR(arm_regulator)) { + pr_err("failed to get regulator vddarm"); + return PTR_ERR(arm_regulator); + } + + int_regulator = regulator_get(NULL, "vddint"); + if (IS_ERR(int_regulator)) { + pr_err("failed to get regulator vddint"); + regulator_put(arm_regulator); + return PTR_ERR(int_regulator); + } + return cpufreq_register_driver(&s5pv210_driver); } -- cgit v1.1