Skip to content

Instantly share code, notes, and snippets.

@snq-
Created October 27, 2010 21:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save snq-/650010 to your computer and use it in GitHub Desktop.
Save snq-/650010 to your computer and use it in GitHub Desktop.
bravo-2.6.32: CPU Vdd levels sysfs interface
diff -urN bravo-2.6.32-gd96f2c0.orightc/arch/arm/mach-msm/acpuclock-scorpion.c bravo-2.6.32-gd96f2c0.snq/arch/arm/mach-msm/acpuclock-scorpion.c
--- bravo-2.6.32-gd96f2c0.orightc/arch/arm/mach-msm/acpuclock-scorpion.c 2010-09-28 14:03:54.000000000 +0200
+++ bravo-2.6.32-gd96f2c0.snq/arch/arm/mach-msm/acpuclock-scorpion.c 2010-10-27 22:27:08.000000000 +0200
@@ -29,6 +29,9 @@
#include "acpuclock.h"
#include "proc_comm.h"
#include "clock.h"
+#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
+#include "board-bravo.h"
+#endif
#if 0
#define DEBUG(x...) pr_info(x)
@@ -568,3 +571,41 @@
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), BRAVO_TPS65023_MIN_UV_MV), BRAVO_TPS65023_MAX_UV_MV);
+ else if (acpu_freq_tbl[i].acpu_khz == acpu_khz)
+ acpu_freq_tbl[i].vdd = min(max(vdd, BRAVO_TPS65023_MIN_UV_MV), BRAVO_TPS65023_MAX_UV_MV);
+ }
+ }
+ mutex_unlock(&drv_state.lock);
+}
+
+#endif
diff -urN bravo-2.6.32-gd96f2c0.orightc/arch/arm/mach-msm/board-bravo.c bravo-2.6.32-gd96f2c0.snq/arch/arm/mach-msm/board-bravo.c
--- bravo-2.6.32-gd96f2c0.orightc/arch/arm/mach-msm/board-bravo.c 2010-09-28 14:03:53.000000000 +0200
+++ bravo-2.6.32-gd96f2c0.snq/arch/arm/mach-msm/board-bravo.c 2010-10-27 22:23:56.000000000 +0200
@@ -660,8 +660,8 @@
{
.constraints = {
.name = "dcdc1", /* VREG_MSMC2_1V29 */
- .min_uV = 1000000,
- .max_uV = 1300000,
+ .min_uV = BRAVO_TPS65023_MIN_UV_MV * 1000,
+ .max_uV = BRAVO_TPS65023_MAX_UV_MV * 1000,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
},
.consumer_supplies = tps65023_dcdc1_supplies,
diff -urN bravo-2.6.32-gd96f2c0.orightc/arch/arm/mach-msm/board-bravo.h bravo-2.6.32-gd96f2c0.snq/arch/arm/mach-msm/board-bravo.h
--- bravo-2.6.32-gd96f2c0.orightc/arch/arm/mach-msm/board-bravo.h 2010-09-28 14:03:53.000000000 +0200
+++ bravo-2.6.32-gd96f2c0.snq/arch/arm/mach-msm/board-bravo.h 2010-10-27 22:23:56.000000000 +0200
@@ -163,4 +163,7 @@
#define BRAVO_LCD_DE (138)
#define BRAVO_LCD_ID0 (147)
+#define BRAVO_TPS65023_MIN_UV_MV (1000)
+#define BRAVO_TPS65023_MAX_UV_MV (1300)
+
#endif /* __ARCH_ARM_MACH_MSM_BOARD_BRAVO_H */
diff -urN bravo-2.6.32-gd96f2c0.orightc/drivers/cpufreq/cpufreq.c bravo-2.6.32-gd96f2c0.snq/drivers/cpufreq/cpufreq.c
--- bravo-2.6.32-gd96f2c0.orightc/drivers/cpufreq/cpufreq.c 2010-09-28 14:03:32.000000000 +0200
+++ bravo-2.6.32-gd96f2c0.snq/drivers/cpufreq/cpufreq.c 2010-10-27 22:23:56.000000000 +0200
@@ -647,6 +647,74 @@
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_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 @@
&scaling_driver.attr,
&scaling_available_governors.attr,
&scaling_setspeed.attr,
+#ifdef CONFIG_CPU_FREQ_VDD_LEVELS
+ &vdd_levels.attr,
+#endif
NULL
};
diff -urN bravo-2.6.32-gd96f2c0.orightc/drivers/cpufreq/Kconfig bravo-2.6.32-gd96f2c0.snq/drivers/cpufreq/Kconfig
--- bravo-2.6.32-gd96f2c0.orightc/drivers/cpufreq/Kconfig 2010-09-28 14:03:57.000000000 +0200
+++ bravo-2.6.32-gd96f2c0.snq/drivers/cpufreq/Kconfig 2010-10-27 22:23:56.000000000 +0200
@@ -190,4 +190,12 @@
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment