Added sysfs interface for undervolting based on information from here:
http://forum.xda-developers.com/showthread.php?t=821372 See the thread for information on how to use it.
This commit is contained in:
parent
1d971023be
commit
19867bdf03
@ -29,6 +29,9 @@
|
||||
#include "acpuclock.h"
|
||||
#include "proc_comm.h"
|
||||
#include "clock.h"
|
||||
#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
|
||||
#include "board-htcleo.h"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define DEBUG(x...) pr_info(x)
|
||||
@ -693,3 +696,41 @@ void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata)
|
||||
clk_set_rate(drv_state.clk_ebi1, drv_state.current_speed->axiclk_khz * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
|
||||
|
||||
ssize_t acpuclk_get_vdd_levels_str(char *buf)
|
||||
{
|
||||
int i, len = 0;
|
||||
if (buf)
|
||||
{
|
||||
mutex_lock(&drv_state.lock);
|
||||
for (i = 0; acpu_freq_tbl[i].acpu_khz; i++)
|
||||
{
|
||||
if (freq_table[i].frequency != CPUFREQ_ENTRY_INVALID)
|
||||
len += sprintf(buf + len, "%8u: %4d\n", acpu_freq_tbl[i].acpu_khz, acpu_freq_tbl[i].vdd);
|
||||
}
|
||||
mutex_unlock(&drv_state.lock);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void acpuclk_set_vdd(unsigned acpu_khz, int vdd)
|
||||
{
|
||||
int i;
|
||||
vdd = vdd / 25 * 25; //! regulator only accepts multiples of 25 (mV)
|
||||
mutex_lock(&drv_state.lock);
|
||||
for (i = 0; acpu_freq_tbl[i].acpu_khz; i++)
|
||||
{
|
||||
if (freq_table[i].frequency != CPUFREQ_ENTRY_INVALID)
|
||||
{
|
||||
if (acpu_khz == 0)
|
||||
acpu_freq_tbl[i].vdd = min(max((acpu_freq_tbl[i].vdd + vdd), HTCLEO_TPS65023_MIN_UV_MV), HTCLEO_TPS65023_MAX_UV_MV);
|
||||
else if (acpu_freq_tbl[i].acpu_khz == acpu_khz)
|
||||
acpu_freq_tbl[i].vdd = min(max(vdd, HTCLEO_TPS65023_MIN_UV_MV), HTCLEO_TPS65023_MAX_UV_MV);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&drv_state.lock);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -110,8 +110,8 @@ static struct regulator_init_data tps65023_data[5] =
|
||||
.constraints =
|
||||
{
|
||||
.name = "dcdc1", /* VREG_MSMC2_1V29 */
|
||||
.min_uV = 800000,
|
||||
.max_uV = 1350000,
|
||||
.min_uV = HTCLEO_TPS65023_MIN_UV_MV * 1000,
|
||||
.max_uV = HTCLEO_TPS65023_MAX_UV_MV * 1000,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
|
||||
},
|
||||
.consumer_supplies = tps65023_dcdc1_supplies,
|
||||
|
@ -168,7 +168,9 @@
|
||||
#define HTCLEO_LCD_HSYNC (137)
|
||||
#define HTCLEO_LCD_DE (138)
|
||||
|
||||
|
||||
/* Voltage driver */
|
||||
#define HTCLEO_TPS65023_MIN_UV_MV (800)
|
||||
#define HTCLEO_TPS65023_MAX_UV_MV (1350)
|
||||
|
||||
int htcleo_pm_set_vreg(int enable, unsigned id);
|
||||
int __init htcleo_init_panel(void);
|
||||
|
@ -205,4 +205,12 @@ config CPU_FREQ_GOV_CONSERVATIVE
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config CPU_FREQ_VDD_LEVELS
|
||||
bool "CPU Vdd levels sysfs interface"
|
||||
depends on CPU_FREQ_STAT
|
||||
depends on ARCH_QSD8X50
|
||||
default n
|
||||
help
|
||||
CPU Vdd levels sysfs interface
|
||||
|
||||
endif # CPU_FREQ
|
||||
|
@ -647,6 +647,74 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
|
||||
return policy->governor->show_setspeed(policy, buf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
|
||||
|
||||
extern ssize_t acpuclk_get_vdd_levels_str(char *buf);
|
||||
static ssize_t show_vdd_levels(struct cpufreq_policy *policy, char *buf)
|
||||
{
|
||||
return acpuclk_get_vdd_levels_str(buf);
|
||||
}
|
||||
|
||||
extern void acpuclk_set_vdd(unsigned acpu_khz, int vdd);
|
||||
static ssize_t store_vdd_levels(struct cpufreq_policy *policy, const char *buf, size_t count)
|
||||
{
|
||||
int i = 0, j;
|
||||
int pair[2] = { 0, 0 };
|
||||
int sign = 0;
|
||||
|
||||
if (count < 1)
|
||||
return 0;
|
||||
|
||||
if (buf[0] == '-')
|
||||
{
|
||||
sign = -1;
|
||||
i++;
|
||||
}
|
||||
else if (buf[0] == '+')
|
||||
{
|
||||
sign = 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
for (j = 0; i < count; i++)
|
||||
{
|
||||
char c = buf[i];
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
{
|
||||
pair[j] *= 10;
|
||||
pair[j] += (c - '0');
|
||||
}
|
||||
else if ((c == ' ') || (c == '\t'))
|
||||
{
|
||||
if (pair[j] != 0)
|
||||
{
|
||||
j++;
|
||||
if ((sign != 0) || (j > 1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (sign != 0)
|
||||
{
|
||||
if (pair[0] > 0)
|
||||
acpuclk_set_vdd(0, sign * pair[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pair[0] > 0) && (pair[1] > 0))
|
||||
acpuclk_set_vdd((unsigned)pair[0], pair[1]);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define define_one_ro(_name) \
|
||||
static struct freq_attr _name = \
|
||||
__ATTR(_name, 0444, show_##_name, NULL)
|
||||
@ -672,6 +740,9 @@ define_one_rw(scaling_min_freq);
|
||||
define_one_rw(scaling_max_freq);
|
||||
define_one_rw(scaling_governor);
|
||||
define_one_rw(scaling_setspeed);
|
||||
#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
|
||||
define_one_rw(vdd_levels);
|
||||
#endif
|
||||
|
||||
static struct attribute *default_attrs[] = {
|
||||
&cpuinfo_min_freq.attr,
|
||||
@ -685,6 +756,9 @@ static struct attribute *default_attrs[] = {
|
||||
&scaling_driver.attr,
|
||||
&scaling_available_governors.attr,
|
||||
&scaling_setspeed.attr,
|
||||
#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
|
||||
&vdd_levels.attr,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user