rk2928: update dvfs.c
authorchenxing <chenxing@rock-chips.com>
Wed, 12 Sep 2012 12:39:20 +0000 (20:39 +0800)
committerchenxing <chenxing@rock-chips.com>
Wed, 12 Sep 2012 12:39:20 +0000 (20:39 +0800)
arch/arm/mach-rk2928/dvfs.c

index b58b9d7545bbff843fa52a5e9095e604eed6f4fd..ede6bb7241d615c95184a2181897a64de5792d9f 100644 (file)
 #else\r
 #define DVFS_DBG(fmt, args...) printk(KERN_DEBUG "DVFS DBG:\t"fmt, ##args)\r
 #endif\r
+\r
+#define DVFS_SET_VOLT_FAILURE  1\r
+#define DVFS_SET_VOLT_SUCCESS  0\r
+\r
 #define DVFS_ERR(fmt, args...) printk(KERN_ERR "DVFS ERR:\t"fmt, ##args)\r
 #define DVFS_LOG(fmt, args...) printk(KERN_DEBUG "DVFS LOG:\t"fmt, ##args)\r
 \r
@@ -101,12 +105,18 @@ struct regulator* dvfs_get_regulator(char *regulator_name)
 int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate)\r
 {\r
        struct clk_node* dvfs_clk;\r
+       u32 rate = 0;\r
        dvfs_clk = clk->dvfs_info;\r
 \r
        dvfs_clk->freq_limit_en = 1;\r
        dvfs_clk->min_rate = min_rate;\r
        dvfs_clk->max_rate = max_rate;\r
        \r
+       rate = clk_get_rate(clk);\r
+       if (rate < min_rate) \r
+               dvfs_clk_set_rate(clk, min_rate);\r
+       else if (rate > max_rate)\r
+               dvfs_clk_set_rate(clk, max_rate);\r
        return 0;\r
 }\r
 \r
@@ -255,6 +265,10 @@ static int dvfs_vd_get_newvolt_byclk(struct clk_node *dvfs_clk)
 void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target)\r
 {\r
        struct clk_node *dvfs_clk = clk_get_dvfs_info(clk);\r
+       if (IS_ERR_OR_NULL(dvfs_clk)){\r
+               DVFS_ERR("%s %s get dvfs_clk err\n", __func__, clk->name);\r
+               return ;\r
+       }\r
        dvfs_clk->clk_dvfs_target = clk_dvfs_target;\r
 }\r
 \r
@@ -393,6 +407,21 @@ int clk_enable_dvfs(struct clk *clk)
                }\r
 #endif\r
                dvfs_vd_get_newvolt_byclk(dvfs_clk);\r
+               if(dvfs_clk->vd->cur_volt<dvfs_clk->set_volt) {\r
+                       int ret;\r
+                       mutex_lock(&rk_dvfs_mutex);\r
+                       ret = dvfs_regulator_set_voltage_readback(dvfs_clk->vd->regulator, \r
+                                       dvfs_clk->set_volt, dvfs_clk->set_volt);\r
+                       if (ret < 0) {\r
+                               dvfs_clk->vd->volt_set_flag = DVFS_SET_VOLT_FAILURE;\r
+                               dvfs_clk->enable_dvfs = 0;\r
+                               DVFS_ERR("dvfs enable clk %s,set volt error \n", dvfs_clk->name);\r
+                               mutex_unlock(&rk_dvfs_mutex);\r
+                               return -1;\r
+                       }\r
+                       dvfs_clk->vd->volt_set_flag = DVFS_SET_VOLT_SUCCESS;\r
+                       mutex_unlock(&rk_dvfs_mutex);\r
+               }\r
                dvfs_clk->enable_dvfs++;\r
        } else {\r
                DVFS_ERR("dvfs already enable clk enable = %d!\n", dvfs_clk->enable_dvfs);\r
@@ -693,8 +722,7 @@ static int dvfs_set_depend_post(struct clk_node *dvfs_clk, unsigned long rate_ol
        return 0;\r
 }\r
 #endif\r
-#define DVFS_SET_VOLT_FAILURE  1\r
-#define DVFS_SET_VOLT_SUCCESS  0\r
+\r
 #define ARM_HIGHER_LOGIC       (150 * 1000)\r
 #define LOGIC_HIGHER_ARM       (100 * 1000)\r
 \r
@@ -1018,6 +1046,8 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
        /* need round rate */\r
        rate_old = clk_get_rate(clk);\r
        rate_new = clk_round_rate_nolock(clk, rate_hz);\r
+       if(rate_new == rate_old)\r
+               return 0;\r
        DVFS_DBG("dvfs(%s) round rate (%lu)(rount %lu) old (%lu)\n", \r
                        dvfs_clk->name, rate_hz, rate_new, rate_old);\r
 \r
@@ -1146,6 +1176,8 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
        /* need round rate */\r
        rate_old = clk_get_rate(clk);\r
        rate_new = clk_round_rate_nolock(clk, rate_hz);\r
+       if(rate_new == rate_old)\r
+               return 0;\r
        DVFS_DBG("dvfs(%s) round rate (%lu)(rount %lu) old (%lu)\n", \r
                        dvfs_clk->name, rate_hz, rate_new, rate_old);\r
 \r
@@ -1273,18 +1305,21 @@ static struct cpufreq_frequency_table dep_cpu2core_table[] = {
 static struct vd_node vd_cpu = {\r
        .name           = "vd_cpu",\r
        .regulator_name = "vdd_cpu",\r
+       .volt_set_flag  = DVFS_SET_VOLT_FAILURE,\r
        .vd_dvfs_target = dvfs_target_cpu,\r
 };\r
 \r
 static struct vd_node vd_core = {\r
        .name           = "vd_core",\r
        .regulator_name = "vdd_core",\r
+       .volt_set_flag  = DVFS_SET_VOLT_FAILURE,\r
        .vd_dvfs_target = dvfs_target_core,\r
 };\r
 \r
 static struct vd_node vd_rtc = {\r
        .name           = "vd_rtc",\r
        .regulator_name = "vdd_rtc",\r
+       .volt_set_flag  = DVFS_SET_VOLT_FAILURE,\r
        .vd_dvfs_target = NULL,\r
 };\r
 \r
@@ -1675,6 +1710,9 @@ static ssize_t avs_dyn_show(struct kobject *kobj, struct kobj_attribute *attr,
        char *s = buf;\r
        u32 i;\r
 \r
+       if(avs_dyn_data==NULL)\r
+               return (s - buf);\r
+               \r
        if(avs_dyn_start) {\r
                int start_cnt;\r
                int end_cnt;\r
@@ -1746,6 +1784,11 @@ static ssize_t avs_dyn_store(struct kobject *kobj, struct kobj_attribute *attr,
        const char *pbuf;\r
 \r
        if((strncmp(buf, "start", strlen("start")) == 0)) {\r
+               if(avs_dyn_data==NULL)  \r
+                       avs_dyn_data = kmalloc(avs_dyn_data_num, GFP_KERNEL);\r
+               if(avs_dyn_data==NULL)\r
+                       return n;\r
+               \r
                pbuf = &buf[strlen("start")];\r
                avs_dyn_data_cnt = 0;\r
                show_line_cnt = 0;\r
@@ -1844,7 +1887,7 @@ static int __init dvfs_init(void)
        dvfs_hrtimer.function = dvfs_hrtimer_timer_func;\r
        //hrtimer_start(&dvfs_hrtimer,ktime_set(0, 5*1000*1000),HRTIMER_MODE_REL);\r
 #endif\r
-       avs_dyn_data = kmalloc(avs_dyn_data_num, GFP_KERNEL);\r
+\r
 \r
        dvfs_kobj = kobject_create_and_add("dvfs", NULL);\r
        if (!dvfs_kobj)\r