Skip to content

Commit

Permalink
cpufreq: Make voltage control compatible with ASV
Browse files Browse the repository at this point in the history
The old approach used a fixed voltage table not compatible with ASV.

New approach uses ASV values by default.  This approach is based
on gokhanmoral's SiyahKernel UV implementation for I9100 ICS.

Also add min/max voltage enforcement.
Signed-off-by: Andrew Dodd <atd7@cornell.edu>
  • Loading branch information
Entropy512 committed Jun 29, 2012
1 parent b46292a commit fa22f81
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 32 deletions.
39 changes: 32 additions & 7 deletions arch/arm/mach-s5pv210/cpu-freq_c110b.c
Expand Up @@ -50,8 +50,8 @@ static unsigned int mpll_freq; /* in MHz */
static unsigned int apll_freq_max; /* in MHz */
static DEFINE_MUTEX(set_freq_lock);

/* UV */
extern int exp_UV_mV[5];
#define CPU_UV_MV_MAX 1350000
#define CPU_UV_MV_MIN 800000

/* frequency */
static struct cpufreq_frequency_table freq_table[] = {
Expand Down Expand Up @@ -509,7 +509,7 @@ static int s5pv210_cpufreq_target(struct cpufreq_policy *policy,
if (s3c_freqs.freqs.new == s3c_freqs.freqs.old && !first_run)
goto out;

arm_volt = exp_UV_mV[index]; //dvs_conf[index].arm_volt;
arm_volt = dvs_conf[index].arm_volt;
int_volt = dvs_conf[index].int_volt;

/* New clock information update */
Expand Down Expand Up @@ -692,8 +692,7 @@ static int s5pv210_cpufreq_target(struct cpufreq_policy *policy,
memcpy(&s3c_freqs.old, &s3c_freqs.new, sizeof(struct s3c_freq));
cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, KERN_INFO,
"cpufreq: Performance changed[L%d]\n", index);
// previous_arm_volt = dvs_conf[index].arm_volt;
previous_arm_volt = exp_UV_mV[index];
previous_arm_volt = dvs_conf[index].arm_volt;

if (first_run)
first_run = false;
Expand Down Expand Up @@ -736,7 +735,7 @@ static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)

memcpy(&s3c_freqs.old, &clk_info[level],
sizeof(struct s3c_freq));
previous_arm_volt = exp_UV_mV[level]; //dvs_conf[level].arm_volt;
previous_arm_volt = dvs_conf[level].arm_volt;

return ret;
}
Expand Down Expand Up @@ -804,7 +803,7 @@ static int __init s5pv210_cpufreq_driver_init(struct cpufreq_policy *policy)

memcpy(&s3c_freqs.old, &clk_info[level],
sizeof(struct s3c_freq));
previous_arm_volt = exp_UV_mV[level]; //dvs_conf[level].arm_volt;
previous_arm_volt = dvs_conf[level].arm_volt;

#ifdef CONFIG_DVFS_LIMIT
for(i = 0; i < DVFS_LOCK_TOKEN_NUM; i++)
Expand Down Expand Up @@ -914,3 +913,29 @@ static int __init s5pv210_cpufreq_init(void)
}

late_initcall(s5pv210_cpufreq_init);

/* sysfs interface for UV control */
ssize_t show_UV_mV_table(struct cpufreq_policy *policy, char *buf) {
return sprintf(buf, "1200mhz: %lu mV\n800mhz: %lu mV\n400mhz: %lu mV\n200mhz: %lu mV\n100mhz: %lu mV\n", dvs_conf[0].arm_volt/1000, dvs_conf[1].arm_volt/1000, dvs_conf[2].arm_volt/1000, dvs_conf[3].arm_volt/1000, dvs_conf[4].arm_volt/1000);
}

ssize_t store_UV_mV_table(struct cpufreq_policy *policy,
const char *buf, size_t count) {
unsigned int ret = -EINVAL;
int u[5];
int i = 0;
ret = sscanf(buf, "%d %d %d %d %d", &u[0], &u[1], &u[2], &u[3], &u[4]);
if(ret != 5) {
return -EINVAL;
}
else {
for( i = 0; i < 5; i++ ) {
if (u[i] > CPU_UV_MV_MAX / 1000) u[i] = CPU_UV_MV_MAX / 1000;
else if (u[i] < CPU_UV_MV_MIN / 1000) u[i] = CPU_UV_MV_MIN / 1000;
}
for( i = 0; i < 5; i++ ) {
dvs_conf[i].arm_volt = u[i] * 1000;
}
return count;
}
}
28 changes: 3 additions & 25 deletions drivers/cpufreq/cpufreq.c
Expand Up @@ -32,9 +32,6 @@
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
"cpufreq-core", msg)

/* UV */
int exp_UV_mV[5] = { 1300000, 1200000, 1050000, 950000, 950000 };

/**
* The "cpufreq driver" - the arch- or hardware-dependent low
* level driver of CPUFreq support, and its spinlock. This lock
Expand Down Expand Up @@ -651,28 +648,9 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
}

/* sysfs interface for UV control */
static ssize_t show_UV_mV_table(struct cpufreq_policy *policy, char *buf) {

return sprintf(buf, "1200mhz: %d mV\n800mhz: %d mV\n400mhz: %d mV\n200mhz: %d mV\n100mhz: %d mV\n", exp_UV_mV[0]/1000, exp_UV_mV[1]/1000, exp_UV_mV[2]/1000, exp_UV_mV[3]/1000, exp_UV_mV[4]/1000);

}

static ssize_t store_UV_mV_table(struct cpufreq_policy *policy,
const char *buf, size_t count) {

unsigned int ret = -EINVAL;
int i = 0;
ret = sscanf(buf, "%d %d %d %d %d", &exp_UV_mV[0], &exp_UV_mV[1], &exp_UV_mV[2], &exp_UV_mV[3], &exp_UV_mV[4]);
if(ret != 5) {
return -EINVAL;
}
else
for( i = 0; i < 5; i++ )
{
exp_UV_mV[i] *= 1000;
}
return count;
}
extern ssize_t show_UV_mV_table(struct cpufreq_policy *policy, char *buf);
extern ssize_t store_UV_mV_table(struct cpufreq_policy *policy,
const char *buf, size_t count);

/**
* show_scaling_driver - show the current cpufreq HW/BIOS limitation
Expand Down

0 comments on commit fa22f81

Please sign in to comment.