+#define S950M 950000000
+#define S900M 900000000
+#define S850M 850000000
-+#define S810M 810000000
++#define S805M 805000000
+#define S750M 750000000
+#define S700M 700000000
#define S600M 600000000
+#define S125M 124999000
/* DSP speeds */
-+#define S520M 500000000
++#define S520M 520000000
#define S430M 430000000
#define S400M 400000000
#define S360M 360000000
--- kernel-maemo-2.6.28.orig/arch/arm/mach-omap2/smartreflex.c
+++ kernel-maemo-2.6.28/arch/arm/mach-omap2/smartreflex.c
-@@ -37,6 +37,62 @@
- #include "prm.h"
- #include "smartreflex.h"
+@@ -513,7 +513,7 @@
+ sr->req_opp_no = target_opp_no;
+
+ if (sr->srid == SR1) {
+- switch (target_opp_no) {
++ switch (min(target_opp_no-1,5)) {
+ case 5:
+ nvalue_reciprocal = sr->opp5_nvalue;
+ break;
+@@ -527,6 +527,7 @@
+ nvalue_reciprocal = sr->opp2_nvalue;
+ break;
+ case 1:
++ case 0:
+ nvalue_reciprocal = sr->opp1_nvalue;
+ break;
+ default:
+@@ -564,6 +565,8 @@
+ (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
+
+ if (sr->srid == SR1) {
++ /*printk(KERN_NOTICE "OPP%d setting voltage %d\n",
++ target_opp_no,mpu_opps[target_opp_no].vsel);*/
+ errminlimit = (target_opp_no > SR_MAX_LOW_OPP) ?
+ SR1_ERRMINLIMIT_HIGHOPP : SR1_ERRMINLIMIT_LOWOPP;
+
+@@ -866,6 +869,8 @@
+ current_opp_no = get_opp_no(current_opp);
+
+ if (vdd == PRCM_VDD1) {
++ /*printk(KERN_DEBUG "OPP%d bypass setting voltage %d\n",
++ target_opp_no,target_vsel);*/
+ t2_smps_steps = abs(target_vsel - current_vsel);
+ errorgain = (target_opp_no > SR_MAX_LOW_OPP) ?
+ PRM_VP1_CONFIG_ERRORGAIN_HIGHOPP :
+--- kernel-maemo-2.6.28.orig/arch/arm/plat-omap/cpu-omap.c
++++ kernel-maemo-2.6.28/arch/arm/plat-omap/cpu-omap.c
+@@ -148,10 +148,13 @@
+ VERY_HI_RATE) / 1000;
+ }
+
+- clk_set_rate(mpu_clk, policy->cpuinfo.max_freq * 1000);
++ /*clk_set_rate(mpu_clk, policy->cpuinfo.max_freq * 1000);*/
++ clk_set_rate(mpu_clk, 600000 * 1000); /*N900 hack: set default max to 600MHz */
+
+- policy->min = policy->cpuinfo.min_freq;
+- policy->max = policy->cpuinfo.max_freq;
++ /*policy->min = policy->cpuinfo.min_freq;*/
++ /*policy->max = policy->cpuinfo.max_freq;*/
++ policy->min = 250000;
++ policy->max = 600000; /*N900 hack: set default to 250-600MHz */
+ policy->cur = omap_getspeed(0);
+
+ policy->cpuinfo.transition_latency = 300 * 1000;
+--- kernel-maemo-2.6.28.orig/arch/arm/mach-omap2/smartreflex.h
++++ kernel-maemo-2.6.28/arch/arm/mach-omap2/smartreflex.h
+@@ -254,7 +254,7 @@
+ /* XXX: end remove/move */
+
+ /* SR_MAX_LOW_OPP: the highest of the "low OPPs", 1 and 2. */
+-#define SR_MAX_LOW_OPP 2
++#define SR_MAX_LOW_OPP 3
+
+ /* XXX: find more appropriate place for these once DVFS is in place */
+ extern u32 current_vdd1_opp;
+--- kernel-maemo-2.6.28.orig/drivers/cpufreq/cpufreq.c
++++ kernel-maemo-2.6.28/drivers/cpufreq/cpufreq.c
+@@ -465,7 +465,7 @@
+ /**
+ * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
+ */
+-#define store_one(file_name, object) \
++#define store_one(file_name, object,ignore) \
+ static ssize_t store_##file_name \
+ (struct cpufreq_policy *policy, const char *buf, size_t count) \
+ { \
+@@ -479,15 +479,16 @@
+ ret = sscanf (buf, "%u", &new_policy.object); \
+ if (ret != 1) \
+ return -EINVAL; \
+- \
+- ret = __cpufreq_set_policy(policy, &new_policy); \
++ printk(KERN_DEBUG "cpufreq: request %u -> %u\n",policy->object,new_policy.object); \
++ if (new_policy.object != ignore && new_policy.object >= 100000) \
++ ret = __cpufreq_set_policy(policy, &new_policy); \
+ policy->user_policy.object = policy->object; \
+ \
+ return ret ? ret : count; \
+ }
+
+-store_one(scaling_min_freq,min);
+-store_one(scaling_max_freq,max);
++store_one(scaling_min_freq,min,0);
++store_one(scaling_max_freq,max,600000);
+
+ /**
+ * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
+--- kernel-maemo-2.6.28.orig/arch/arm/mach-omap2/pm.c
++++ kernel-maemo-2.6.28/arch/arm/mach-omap2/pm.c
+@@ -39,6 +39,62 @@
#include "prm-regbits-34xx.h"
+ #include "pm.h"
+ #include "smartreflex.h"
++#include "resource34xx_mutex.h"
+#include "omap3-opp.h"
+
+struct omap_opp omap3_mpu_rate_table[] = {
+ /*overclocking*/
+ {S700M, 7, 0x3C},
+ {S750M, 8, 0x3C},
-+ {S810M, 9, 0x3C},
++ {S805M, 9, 0x3C},
+ {S850M, 10, 0x3C},
+ {S900M, 11, 0x3C},
+ {S950M, 12, 0x3C},
+ {S1000M, 13, 0x3C},
-+ {S1100M, 14, 0x43},
++ {S1100M, 14, 0x48},
+ {S1150M, 15, 0x48},
+};
+
+ {S430M, 7, 0x3C},
+ {S430M, 8, 0x3C},
+ {S430M, 9, 0x3C},/*800MHz*/
-+ {S520M, 10, 0x3C},
-+ {S520M, 11, 0x3C},
-+ {S520M, 12, 0x3C},
-+ {S520M, 13, 0x3C},
-+ {S520M, 14, 0x3C},
-+ {S520M, 15, 0x3C},
++ {S500M, 10, 0x3C},
++ {S500M, 11, 0x3C},
++ {S500M, 12, 0x3C},
++ {S500M, 13, 0x3C},
++ {S520M, 14, 0x48},
++ {S520M, 15, 0x48},
+};
-+
-
- /*
- * VP_TRANXDONE_TIMEOUT: maximum microseconds to wait for the VP to
-@@ -513,7 +569,7 @@
- sr->req_opp_no = target_opp_no;
-
- if (sr->srid == SR1) {
-- switch (target_opp_no) {
-+ switch (min(target_opp_no-1,5)) {
- case 5:
- nvalue_reciprocal = sr->opp5_nvalue;
- break;
-@@ -527,6 +583,7 @@
- nvalue_reciprocal = sr->opp2_nvalue;
- break;
- case 1:
-+ case 0:
- nvalue_reciprocal = sr->opp1_nvalue;
- break;
- default:
-@@ -564,6 +621,8 @@
- (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
-
- if (sr->srid == SR1) {
-+ /*printk(KERN_NOTICE "OPP%d setting voltage %d\n",
-+ target_opp_no,mpu_opps[target_opp_no].vsel);*/
- errminlimit = (target_opp_no > SR_MAX_LOW_OPP) ?
- SR1_ERRMINLIMIT_HIGHOPP : SR1_ERRMINLIMIT_LOWOPP;
-@@ -866,6 +925,8 @@
- current_opp_no = get_opp_no(current_opp);
+ unsigned short enable_dyn_sleep;
+ unsigned short clocks_off_while_idle;
+@@ -81,6 +137,108 @@
- if (vdd == PRCM_VDD1) {
-+ /*printk(KERN_DEBUG "OPP%d bypass setting voltage %d\n",
-+ target_opp_no,target_vsel);*/
- t2_smps_steps = abs(target_vsel - current_vsel);
- errorgain = (target_opp_no > SR_MAX_LOW_OPP) ?
- PRM_VP1_CONFIG_ERRORGAIN_HIGHOPP :
-@@ -940,6 +1001,57 @@
- return SR_PASS;
- }
+ #endif
-+static ssize_t omap_sr_vdd1_opps_vsel_show(struct kobject *kobj,
++static ssize_t omap_vdd1_opps_vsel_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ int i;
+ char *b=buf;
+ for(i=1;i<=MAX_VDD1_OPP;i++)
-+ b+=sprintf(b, "%d ", mpu_opps[i].vsel);
++ b+=sprintf(b, "%hu ", mpu_opps[i].vsel);
+ b+=sprintf(b, "\n");
+ return b-buf;
+}
+
-+static ssize_t omap_sr_vdd1_opps_vsel_store(struct kobject *kobj,
++static ssize_t omap_vdd1_opps_vsel_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
-+ unsigned short value[16];
++ u16 value[16];
+ int i;
+
+ if (sscanf(buf, "%hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu %hu",
+ &value[8], &value[9], &value[10], &value[11],
+ &value[12], &value[13], &value[14], &value[15]
+ ) != MAX_VDD1_OPP) {
-+ printk(KERN_ERR "sr_vdd1_opps_vsel: Invalid value\n");
++ printk(KERN_ERR "vdd1_opps_vsel: Invalid value\n");
+ return -EINVAL;
+ }
+
+ return n;
+}
+
-+static struct kobj_attribute sr_vdd1_opps_vsel = {
++static struct kobj_attribute vdd1_opps_vsel = {
+ .attr = {
-+ .name = __stringify(sr_vdd1_opps_vsel),
++ .name = __stringify(vdd1_opps_vsel),
+ .mode = 0644,
+ },
-+ .show = omap_sr_vdd1_opps_vsel_show,
-+ .store = omap_sr_vdd1_opps_vsel_store,
++ .show = omap_vdd1_opps_vsel_show,
++ .store = omap_vdd1_opps_vsel_store,
+};
+
++static ssize_t omap_dsp_opps_rate_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ int i;
++ char *b=buf;
++ for(i=1;i<=MAX_VDD1_OPP;i++)
++ b+=sprintf(b, "%lu ", dsp_opps[i].rate);
++ b+=sprintf(b, "\n");
++ return b-buf;
++}
+
- /* Sysfs interface to select SR VDD1 auto compensation */
- static ssize_t omap_sr_vdd1_autocomp_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-@@ -1075,6 +1187,10 @@
-
- printk(KERN_INFO "SmartReflex driver initialized\n");
-
-+ ret = sysfs_create_file(power_kobj, &sr_vdd1_opps_vsel.attr);
-+ if (ret)
-+ printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
++static ssize_t omap_dsp_opps_rate_store(struct kobject *kobj,
++ struct kobj_attribute *attr,
++ const char *buf, size_t n)
++{
++ unsigned long value[16];
++ int i;
+
- ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
- if (ret)
- printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
---- kernel-maemo-2.6.28.orig/arch/arm/plat-omap/cpu-omap.c
-+++ kernel-maemo-2.6.28/arch/arm/plat-omap/cpu-omap.c
-@@ -148,10 +148,13 @@
- VERY_HI_RATE) / 1000;
++ if (sscanf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
++ &value[0], &value[1], &value[2], &value[3],
++ &value[4], &value[5], &value[6], &value[7],
++ &value[8], &value[9], &value[10], &value[11],
++ &value[12], &value[13], &value[14], &value[15]
++ ) != MAX_VDD1_OPP) {
++ printk(KERN_ERR "dsp_opps_rate: Invalid value\n");
++ return -EINVAL;
++ }
++
++ mutex_lock(&dvfs_mutex);
++
++ for(i=1;i<=MAX_VDD1_OPP;i++) {
++ if(value[i-1]<=600000) {
++ dsp_opps[i].rate = value[i-1];
++ }
++ }
++
++ mutex_unlock(&dvfs_mutex);
++
++ return n;
++}
++
++static struct kobj_attribute dsp_opps_rate = {
++ .attr = {
++ .name = __stringify(dsp_opps_rate),
++ .mode = 0644,
++ },
++ .show = omap_dsp_opps_rate_show,
++ .store = omap_dsp_opps_rate_store,
++};
++
++
++
+ static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+ {
+@@ -258,6 +416,17 @@
+ printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
+ return error;
}
-
-- clk_set_rate(mpu_clk, policy->cpuinfo.max_freq * 1000);
-+ /*clk_set_rate(mpu_clk, policy->cpuinfo.max_freq * 1000);*/
-+ clk_set_rate(mpu_clk, 600000 * 1000); /*N900 hack: set default max to 600MHz */
-
-- policy->min = policy->cpuinfo.min_freq;
-- policy->max = policy->cpuinfo.max_freq;
-+ /*policy->min = policy->cpuinfo.min_freq;*/
-+ /*policy->max = policy->cpuinfo.max_freq;*/
-+ policy->min = 250000;
-+ policy->max = 600000; /*N900 hack: set default to 250-600MHz */
- policy->cur = omap_getspeed(0);
-
- policy->cpuinfo.transition_latency = 300 * 1000;
---- kernel-maemo-2.6.28.orig/arch/arm/mach-omap2/smartreflex.h
-+++ kernel-maemo-2.6.28/arch/arm/mach-omap2/smartreflex.h
-@@ -254,7 +254,7 @@
- /* XXX: end remove/move */
-
- /* SR_MAX_LOW_OPP: the highest of the "low OPPs", 1 and 2. */
--#define SR_MAX_LOW_OPP 2
-+#define SR_MAX_LOW_OPP 3
-
- /* XXX: find more appropriate place for these once DVFS is in place */
- extern u32 current_vdd1_opp;
---- kernel-maemo-2.6.28.orig/drivers/cpufreq/cpufreq.c
-+++ kernel-maemo-2.6.28/drivers/cpufreq/cpufreq.c
-@@ -465,7 +465,7 @@
- /**
- * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
- */
--#define store_one(file_name, object) \
-+#define store_one(file_name, object,ignore) \
- static ssize_t store_##file_name \
- (struct cpufreq_policy *policy, const char *buf, size_t count) \
- { \
-@@ -479,15 +479,16 @@
- ret = sscanf (buf, "%u", &new_policy.object); \
- if (ret != 1) \
- return -EINVAL; \
-- \
-- ret = __cpufreq_set_policy(policy, &new_policy); \
-+ printk(KERN_DEBUG "cpufreq: request %u -> %u\n",policy->object,new_policy.object); \
-+ if (new_policy.object != ignore && new_policy.object >= 100000) \
-+ ret = __cpufreq_set_policy(policy, &new_policy); \
- policy->user_policy.object = policy->object; \
- \
- return ret ? ret : count; \
- }
-
--store_one(scaling_min_freq,min);
--store_one(scaling_max_freq,max);
-+store_one(scaling_min_freq,min,0);
-+store_one(scaling_max_freq,max,600000);
-
- /**
- * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
++ error = sysfs_create_file(power_kobj, &vdd1_opps_vsel.attr);
++ if (error) {
++ printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
++ return error;
++ }
++ error = sysfs_create_file(power_kobj, &dsp_opps_rate.attr);
++ if (error) {
++ printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
++ return error;
++ }
++
+ #ifdef CONFIG_OMAP_PM_SRF
+ error = sysfs_create_file(power_kobj,
+ &vdd1_opp_attr.attr);