[PATCH V2 2/6] [CPUFREQ] S5PV210: Add arm/int voltage control support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Jonghwan Choi <jhbird.choi@xxxxxxxxxxx>

Signed-off-by: Jonghwan Choi <jhbird.choi@xxxxxxxxxxx>
Signed-off-by: Kukjin Kim <kgene.kim@xxxxxxxxxxx>
---
 drivers/cpufreq/s5pv210-cpufreq.c |   71 +++++++++++++++++++++++++++++++++++--
 1 files changed, 68 insertions(+), 3 deletions(-)

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 <linux/clk.h>
 #include <linux/io.h>
 #include <linux/cpufreq.h>
+#include <linux/regulator/consumer.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
@@ -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);
 }
 
-- 
1.7.1

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


[Index of Archives]     [Linux Kernel Devel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Forum]     [Linux SCSI]

  Powered by Linux