rk30: add logic voltage scale
authorchenxing <chenxing@rock-chips.com>
Sat, 21 Apr 2012 09:36:05 +0000 (17:36 +0800)
committerchenxing <chenxing@rock-chips.com>
Sat, 21 Apr 2012 09:36:05 +0000 (17:36 +0800)
arch/arm/mach-rk30/dvfs.c

index 26a50fc1d4932dd2035459247d513bb42b810da3..f2365da416f04a108476d1ca17f2826fe507d6a5 100755 (executable)
@@ -26,6 +26,8 @@
 #include <linux/regulator/consumer.h>\r
 #include <linux/delay.h>\r
 \r
+#define JUMP_RATE 816000000\r
+#define LOGIC_VOLT_SCALING\r
 #define DVFS_DBG(fmt, args...) {while(0);}     //pr_debug(fmt, ##args)\r
 #define DVFS_ERR(fmt, args...) pr_err(fmt, ##args)\r
 #define DVFS_LOG(fmt, args...) pr_debug(fmt, ##args)//while(0)\r
@@ -378,7 +380,43 @@ static int rk_regist_clk(struct clk_node *dvfs_clk)
 #define get_volt_up_delay(new_volt, old_volt)  \\r
        ((new_volt) > (old_volt) ? (((new_volt) - (old_volt)) >> 10) : 0)\r
 \r
+#ifdef LOGIC_VOLT_SCALING\r
+#define DVFS_LOGIC_VOLT_H      1175000\r
+#define DVFS_LOGIC_VOLT_L      1025000\r
+static int dvfs_up_volt_logic(void)\r
+{\r
+       struct regulator *vdd_core;\r
+       int ret = 0;\r
+       DVFS_DBG("second jump > 816M\n");\r
+       vdd_core = dvfs_regulator_get(NULL, "vdd_core");\r
+       ret = dvfs_regulator_set_voltage(vdd_core, DVFS_LOGIC_VOLT_H, DVFS_LOGIC_VOLT_H);\r
+       udelay(200);\r
+       DVFS_DBG("DVFS > 816M\n");\r
+       if (ret != 0) {\r
+               DVFS_ERR("%s err, ret = %d\n", __func__, ret);\r
+               return -1;\r
+       }\r
+       dvfs_regulator_put(vdd_core);\r
+       return ret;\r
+}\r
 \r
+static int dvfs_down_volt_logic(void)\r
+{\r
+       struct regulator *vdd_core;\r
+       int ret = 0;\r
+       DVFS_DBG("first jump %d\n", JUMP_RATE);\r
+       vdd_core = dvfs_regulator_get(NULL, "vdd_core");\r
+       ret = dvfs_regulator_set_voltage(vdd_core, DVFS_LOGIC_VOLT_L, DVFS_LOGIC_VOLT_L);\r
+       //udelay(200);\r
+       DVFS_DBG("DVFS <= 816M\n");\r
+       if (ret != 0) {\r
+               DVFS_ERR("%s err, ret = %d\n", __func__, ret);\r
+               return -1;\r
+       }\r
+       dvfs_regulator_put(vdd_core);\r
+       return ret;\r
+}\r
+#endif\r
 static int flag_core_set_volt_err = 0;\r
 int dvfs_target_core(struct clk *clk, unsigned long rate_hz)\r
 {\r
@@ -513,7 +551,8 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
        struct cpufreq_frequency_table clk_fv;\r
        int ret = 0;\r
        int flag_set_volt_correct = 0;\r
-       unsigned long temp_hz;\r
+       unsigned long temp_hz, pre_rate_hz;\r
+\r
 \r
        if (!clk) {\r
                DVFS_ERR("%s is not clk\n", __func__);\r
@@ -530,6 +569,7 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
        temp_hz = clk_round_rate_nolock(clk, rate_hz);\r
        DVFS_DBG("dvfs(%s) round rate (%lu)(rount %lu)\n", dvfs_clk->name, rate_hz, temp_hz);\r
 \r
+       pre_rate_hz = clk_get_rate(clk);\r
        /* find the clk corresponding voltage */\r
        if (0 != dvfs_clk_get_ref_volt(dvfs_clk, temp_hz / 1000, &clk_fv)) {\r
                DVFS_ERR("dvfs(%s) rate %luhz is larger,not support\n", dvfs_clk->name, rate_hz);\r
@@ -557,7 +597,15 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
                dvfs_clk->vd->cur_volt = flag_set_volt_correct;\r
                volt_old = dvfs_clk->vd->cur_volt;\r
        }\r
-\r
+#ifdef LOGIC_VOLT_SCALING\r
+       if (temp_hz > JUMP_RATE && pre_rate_hz <= JUMP_RATE) {\r
+               ret = dvfs_up_volt_logic();\r
+               if (ret != 0) {\r
+                       DVFS_ERR("%s up logic volt error %d", __func__, ret);\r
+                       return -1;\r
+               }\r
+       }\r
+#endif\r
        /* if up the voltage */\r
        if (volt_old < volt_new) {\r
                if (dvfs_clk->vd->regulator) {\r
@@ -616,6 +664,15 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
                DVFS_LOG("dvfs %s set volt ok dn\n", dvfs_clk->name);\r
 \r
        }\r
+#ifdef LOGIC_VOLT_SCALING\r
+       if (temp_hz <= JUMP_RATE && pre_rate_hz > JUMP_RATE) {\r
+               ret = dvfs_down_volt_logic();\r
+               if (ret != 0) {\r
+                       DVFS_ERR("%s down logic volt error %d", __func__, ret);\r
+                       return -1;\r
+               }\r
+       }\r
+#endif\r
        return ret;\r
 }\r
 \r