rk30:sdk: add logic dynamic voltage scale
authorchenxing <chenxing@rock-chips.com>
Wed, 25 Apr 2012 07:17:08 +0000 (15:17 +0800)
committerchenxing <chenxing@rock-chips.com>
Wed, 25 Apr 2012 07:17:08 +0000 (15:17 +0800)
arch/arm/mach-rk30/dvfs.c
arch/arm/mach-rk30/include/mach/dvfs.h

index a15998c9bd125d359c5043a875866dee5d189699..95a84a8097aa1294e185c49f0f14d078adc1b58d 100755 (executable)
 #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_DBG(fmt, args...) {while(0);}\r
 #define DVFS_ERR(fmt, args...) pr_err(fmt, ##args)\r
-#define DVFS_LOG(fmt, args...) pr_debug(fmt, ##args)//while(0)\r
+#define DVFS_LOG(fmt, args...) pr_debug(fmt, ##args)\r
+//#define DVFS_LOG(fmt, args...) pr_err(fmt, ##args)\r
 \r
 #define dvfs_regulator_get(dev,id) regulator_get((dev),(id))\r
 #define dvfs_regulator_put(regu) regulator_put((regu))\r
@@ -56,6 +55,11 @@ static DEFINE_MUTEX(mutex);
 extern int rk30_clk_notifier_register(struct clk *clk, struct notifier_block *nb);\r
 extern int rk30_clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);\r
 \r
+// #define DVFS_DUMP_TREE\r
+#ifdef DVFS_DUMP_TREE\r
+static void dump_dbg_map(void);\r
+#endif\r
+\r
 #define PD_ON  1\r
 #define PD_OFF 0\r
 \r
@@ -82,12 +86,33 @@ int dvfs_set_rate(struct clk *clk, unsigned long rate)
        return ret;\r
 }\r
 \r
+static int dvfs_clk_get_ref_volt_depend(struct depend_list *depend, int rate_khz,\r
+               struct cpufreq_frequency_table *clk_fv)\r
+{\r
+       int i = 0;\r
+       if (rate_khz == 0 || !depend || !depend->dep_table) {\r
+               return -1;\r
+       }\r
+       clk_fv->frequency = rate_khz;\r
+       clk_fv->index = 0;\r
+\r
+       for (i = 0; (depend->dep_table[i].frequency != CPUFREQ_TABLE_END); i++) {\r
+               if (depend->dep_table[i].frequency >= rate_khz) {\r
+                       clk_fv->frequency = depend->dep_table[i].frequency;\r
+                       clk_fv->index = depend->dep_table[i].index;\r
+                       return 0;\r
+               }\r
+       }\r
+       clk_fv->frequency = 0;\r
+       clk_fv->index = 0;\r
+       return -1;\r
+}\r
 static int dvfs_clk_get_ref_volt(struct clk_node *dvfs_clk, int rate_khz,\r
                struct cpufreq_frequency_table *clk_fv)\r
 {\r
        int i = 0;\r
        if (rate_khz == 0 || !dvfs_clk || !dvfs_clk->dvfs_table) {\r
-               /* since no need*/\r
+               /* since no need */\r
                return -1;\r
        }\r
        clk_fv->frequency = rate_khz;\r
@@ -121,8 +146,8 @@ static int dvfs_pd_get_newvolt_byclk(struct pd_node *pd, struct clk_node *dvfs_c
        }\r
 \r
        list_for_each_entry(child, &pd->clk_list, node) {\r
-               //DVFS_DBG("%s ,pd(%s),dvfs(%s),volt(%u)\n",__func__,pd->name,\r
-               //dvfs_clk->name,dvfs_clk->set_volt);\r
+               // DVFS_DBG("%s ,pd(%s),dvfs(%s),volt(%u)\n",__func__,pd->name,\r
+               // dvfs_clk->name,dvfs_clk->set_volt);\r
                volt_max = max(volt_max, child->dvfs_clk->set_volt);\r
        }\r
        return volt_max;\r
@@ -143,12 +168,20 @@ void dvfs_update_clk_pds_volt(struct clk_node *dvfs_clk)
 \r
 static int dvfs_vd_get_newvolt_bypd(struct vd_node *vd)\r
 {\r
-       struct pd_node *pd;\r
+       struct pd_node          *pd;\r
+       struct depend_list      *depend;\r
        int     volt_max_vd = 0;\r
        list_for_each_entry(pd, &vd->pd_list, node) {\r
-               //DVFS_DBG("%s pd(%s,%u)\n",__func__,pd->name,pd->cur_volt);\r
+               // DVFS_DBG("%s pd(%s,%u)\n",__func__,pd->name,pd->cur_volt);\r
                volt_max_vd = max(volt_max_vd, pd->cur_volt);\r
        }\r
+\r
+       /* some clks depend on this voltage domain */\r
+       if (!list_empty(&vd->req_volt_list)) {\r
+               list_for_each_entry(depend, &vd->req_volt_list, node2vd) {\r
+                       volt_max_vd = max(volt_max_vd, depend->req_volt);\r
+               }\r
+       }\r
        return volt_max_vd;\r
 }\r
 \r
@@ -191,6 +224,39 @@ int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *ta
        return 0;\r
 }\r
 \r
+int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequency_table *table)\r
+{\r
+       struct vd_node          *vd;\r
+       struct depend_list      *depend;\r
+       struct clk_node         *info;\r
+       info = clk_get_dvfs_info(clk);\r
+       if (!table || !info || !vd_name) {\r
+               DVFS_ERR("%s :DVFS SET DEPEND TABLE ERROR! table or info or name empty\n", __func__);\r
+               return -1;\r
+       }\r
+\r
+       list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
+               if (0 == strcmp(vd->name, vd_name)) {\r
+                       DVFS_LOG("FOUND A MATCH\n");\r
+                       mutex_lock(&mutex);\r
+                       list_for_each_entry(depend, &info->depend_list, node2clk) {\r
+                               if (vd == depend->dep_vd && info == depend->dvfs_clk) {\r
+                                       depend->dep_table = table;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       mutex_unlock(&mutex);\r
+#ifdef DVFS_DUMP_TREE\r
+                       dump_dbg_map();\r
+#endif\r
+                       return 0;\r
+               }\r
+       }\r
+       DVFS_ERR("%s :DVFS SET DEPEND TABLE ERROR! can not find vd:%s\n", __func__, vd_name);\r
+\r
+       return 0;\r
+}\r
+\r
 int clk_enable_dvfs(struct clk *clk)\r
 {\r
        struct regulator *regulator;\r
@@ -212,7 +278,7 @@ int clk_enable_dvfs(struct clk *clk)
                        if (dvfs_clk->vd->regulator_name)\r
                                regulator = dvfs_regulator_get(NULL, dvfs_clk->vd->regulator_name);\r
                        if (regulator) {\r
-                               //DVFS_DBG("dvfs_regulator_get(%s)\n",dvfs_clk->vd->regulator_name);\r
+                               // DVFS_DBG("dvfs_regulator_get(%s)\n",dvfs_clk->vd->regulator_name);\r
                                dvfs_clk->vd->regulator = regulator;\r
                        } else {\r
                                dvfs_clk->vd->regulator = NULL;\r
@@ -222,18 +288,18 @@ int clk_enable_dvfs(struct clk *clk)
                        }\r
                } else {\r
                        dvfs_clk->vd->cur_volt = dvfs_regulator_get_voltage(dvfs_clk->vd->regulator);\r
-                       //DVFS_DBG("%s(%s) vd volt=%u\n",__func__,dvfs_clk->name,dvfs_clk->vd->cur_volt);\r
+                       // DVFS_DBG("%s(%s) vd volt=%u\n",__func__,dvfs_clk->name,dvfs_clk->vd->cur_volt);\r
                }\r
 \r
                dvfs_clk->set_freq = dvfs_clk_get_rate_kz(clk);\r
-               //DVFS_DBG("%s ,%s get freq%u!\n",__func__,dvfs_clk->name,dvfs_clk->set_freq);\r
+               // DVFS_DBG("%s ,%s get freq%u!\n",__func__,dvfs_clk->name,dvfs_clk->set_freq);\r
 \r
                if (dvfs_clk_get_ref_volt(dvfs_clk, dvfs_clk->set_freq, &clk_fv)) {\r
                        dvfs_clk->enable_dvfs = 0;\r
                        return -1;\r
                }\r
                dvfs_clk->set_volt = clk_fv.index;\r
-               //DVFS_DBG("%s,%s,freq%u(ref vol %u)\n",__func__,dvfs_clk->name,\r
+               // DVFS_DBG("%s,%s,freq%u(ref vol %u)\n",__func__,dvfs_clk->name,\r
                //       dvfs_clk->set_freq,dvfs_clk->set_volt);\r
 #if 0\r
                if (dvfs_clk->dvfs_nb) {\r
@@ -318,6 +384,22 @@ static struct notifier_block rk_dvfs_clk_notifier = {
        .notifier_call = rk_dvfs_clk_notifier_event,\r
 };\r
 \r
+static struct clk_node *dvfs_get_dvfs_clk_byname(char *name)\r
+{\r
+       struct vd_node *vd;\r
+       struct pd_node *pd;\r
+       struct clk_list *child;\r
+       list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
+               list_for_each_entry(pd, &vd->pd_list, node) {\r
+                       list_for_each_entry(child, &pd->clk_list, node) {\r
+                               if (0 == strcmp(child->dvfs_clk->name, name)) {\r
+                                       return child->dvfs_clk;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       return NULL;\r
+}\r
 static int rk_regist_vd(struct vd_node *vd)\r
 {\r
        if (!vd)\r
@@ -326,6 +408,7 @@ static int rk_regist_vd(struct vd_node *vd)
        mutex_init(&vd->dvfs_mutex);\r
        list_add(&vd->node, &rk_dvfs_tree);\r
        INIT_LIST_HEAD(&vd->pd_list);\r
+       INIT_LIST_HEAD(&vd->req_volt_list);\r
 \r
        mutex_unlock(&mutex);\r
        return 0;\r
@@ -372,8 +455,40 @@ static int rk_regist_clk(struct clk_node *dvfs_clk)
                list_add(&child->node, &pd->clk_list);\r
        }\r
        clk = dvfs_clk_get(NULL, dvfs_clk->name);\r
-       dvfs_clk->ck = clk;\r
+       dvfs_clk->clk = clk;\r
        clk_register_dvfs(dvfs_clk, clk);\r
+       INIT_LIST_HEAD(&dvfs_clk->depend_list);\r
+       mutex_unlock(&mutex);\r
+       return 0;\r
+}\r
+\r
+static int rk_regist_depends(struct depend_lookup *dep_node)\r
+{\r
+       struct depend_list      *depend_list;\r
+       struct clk_node         *dvfs_clk;\r
+\r
+       if (!dep_node) {\r
+               DVFS_ERR("%s : DVFS BAD depend node!\n", __func__);\r
+               return -1;\r
+       }\r
+\r
+       if (!dep_node->clk_name || !dep_node->dep_vd) {\r
+               DVFS_ERR("%s : DVFS BAD depend members!\n", __func__);\r
+               return -1;\r
+       }\r
+\r
+       depend_list = &dep_node->dep_list;\r
+       dvfs_clk = dvfs_get_dvfs_clk_byname(dep_node->clk_name);\r
+\r
+       mutex_lock(&mutex);\r
+\r
+       depend_list->dvfs_clk = dvfs_clk;\r
+       depend_list->dep_vd = dep_node->dep_vd;\r
+       depend_list->dep_table = dep_node->dep_table;\r
+\r
+       list_add(&depend_list->node2clk, &dvfs_clk->depend_list);\r
+       list_add(&depend_list->node2vd, &depend_list->dep_vd->req_volt_list);\r
+\r
        mutex_unlock(&mutex);\r
        return 0;\r
 }\r
@@ -381,43 +496,121 @@ 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
+static int dvfs_set_depend_pre(struct clk_node *dvfs_clk, unsigned long rate_old, unsigned long rate_new)\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
+       struct depend_list      *depend;\r
+       struct cpufreq_frequency_table  clk_fv;\r
+       int ret = -1;\r
+       int volt = 0;\r
+       struct regulator *regulator;\r
+\r
+       if (rate_old >= rate_new) {\r
+               return 0;\r
        }\r
-       dvfs_regulator_put(vdd_core);\r
-       return ret;\r
+       list_for_each_entry(depend, &dvfs_clk->depend_list, node2clk) {\r
+               ret = dvfs_clk_get_ref_volt_depend(depend, rate_new / 1000, &clk_fv);\r
+               if (ret != 0) {\r
+                       DVFS_ERR("%s LOGIC DVFS CAN NOT GET REF VOLT!, frequency too large!\n", __func__);\r
+                       return -1;\r
+               }\r
+\r
+               if (!depend->dep_vd->regulator) {\r
+                       DVFS_LOG("%s regulator empty\n", __func__);\r
+                       regulator = dvfs_regulator_get(NULL, depend->dep_vd->regulator_name);\r
+                       if (!regulator) {\r
+                               DVFS_ERR("%s get regulator err\n", __func__);\r
+                               return -1;\r
+                       }\r
+\r
+                       depend->dep_vd->regulator = regulator;\r
+               }\r
+               if (!depend->dep_vd->regulator) {\r
+                       DVFS_ERR("%s vd's(%s) regulator empty\n", __func__, depend->dep_vd->name);\r
+                       return -1;\r
+               }\r
+\r
+               if (clk_fv.index == dvfs_regulator_get_voltage(depend->dep_vd->regulator)) {\r
+                       depend->req_volt = clk_fv.index;\r
+                       DVFS_LOG("%s same voltage\n", __func__);\r
+                       return 0;\r
+               }\r
+\r
+               depend->req_volt = clk_fv.index;\r
+               volt = dvfs_vd_get_newvolt_bypd(depend->dep_vd);\r
+               DVFS_LOG("%s setting voltage = %d\n", __func__, volt);\r
+               ret = dvfs_regulator_set_voltage(depend->dep_vd->regulator, volt, volt);\r
+               if (0 != ret) {\r
+                       DVFS_ERR("%s set voltage = %d ERROR, ret = %d\n", __func__, volt, ret);\r
+                       return -1;\r
+               }\r
+               udelay(200);\r
+               DVFS_LOG("%s set voltage = %d OK, ret = %d\n", __func__, volt, ret);\r
+               if (ret != 0) {\r
+                       DVFS_ERR("%s err, ret = %d\n", __func__, ret);\r
+                       return -1;\r
+               }\r
+       }\r
+\r
+       return 0;\r
 }\r
 \r
-static int dvfs_down_volt_logic(void)\r
+static int dvfs_set_depend_post(struct clk_node *dvfs_clk, unsigned long rate_old, unsigned long rate_new)\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
+       struct depend_list      *depend;\r
+       struct cpufreq_frequency_table  clk_fv;\r
+       int ret = -1;\r
+       int volt = 0;\r
+       struct regulator *regulator;\r
+\r
+       if (rate_old <= rate_new) \r
+               return 0;\r
+       list_for_each_entry(depend, &dvfs_clk->depend_list, node2clk) {\r
+               ret = dvfs_clk_get_ref_volt_depend(depend, rate_new / 1000, &clk_fv);\r
+               if (ret != 0) {\r
+                       DVFS_ERR("%s LOGIC DVFS CAN NOT GET REF VOLT!, frequency too large!\n", __func__);\r
+                       return -1;\r
+               }\r
+\r
+               if (!depend->dep_vd->regulator) {\r
+                       DVFS_LOG("%s regulator empty\n", __func__);\r
+                       regulator = dvfs_regulator_get(NULL, depend->dep_vd->regulator_name);\r
+                       if (!regulator) {\r
+                               DVFS_ERR("%s get regulator err\n", __func__);\r
+                               return -1;\r
+                       }\r
+\r
+                       depend->dep_vd->regulator = regulator;\r
+               }\r
+               if (!depend->dep_vd->regulator) {\r
+                       DVFS_ERR("%s vd's(%s) regulator empty\n", __func__, depend->dep_vd->name);\r
+                       return -1;\r
+               }\r
+\r
+               if (clk_fv.index == dvfs_regulator_get_voltage(depend->dep_vd->regulator)) {\r
+                       depend->req_volt = clk_fv.index;\r
+                       DVFS_LOG("%s same voltage\n", __func__);\r
+                       return 0;\r
+               }\r
+\r
+               depend->req_volt = clk_fv.index;\r
+               volt = dvfs_vd_get_newvolt_bypd(depend->dep_vd);\r
+               DVFS_LOG("%s setting voltage = %d\n", __func__, volt);\r
+               ret = dvfs_regulator_set_voltage(depend->dep_vd->regulator, volt, volt);\r
+               if (0 != ret) {\r
+                       DVFS_ERR("%s set voltage = %d ERROR, ret = %d\n", __func__, volt, ret);\r
+                       return -1;\r
+               }\r
+               udelay(200);\r
+               DVFS_LOG("%s set voltage = %d OK, ret = %d\n", __func__, volt, ret);\r
+               if (ret != 0) {\r
+                       DVFS_ERR("%s err, ret = %d\n", __func__, ret);\r
+                       return -1;\r
+               }\r
        }\r
-       dvfs_regulator_put(vdd_core);\r
-       return ret;\r
+\r
+       return 0;\r
 }\r
-#endif\r
+\r
 static int flag_core_set_volt_err = 0;\r
 int dvfs_target_core(struct clk *clk, unsigned long rate_hz)\r
 {\r
@@ -426,7 +619,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
        struct cpufreq_frequency_table clk_fv = {0, 0};\r
        int ret = 0;\r
        int flag_set_volt_correct = 0;\r
-       unsigned long temp_hz;\r
+       unsigned long rate_new, rate_old;\r
 \r
        if (!clk) {\r
                DVFS_ERR("%s is not clk\n", __func__);\r
@@ -439,14 +632,16 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
                return -1;\r
        }\r
 \r
-       temp_hz = rate_hz;//clk_round_rate_nolock(clk, rate_hz);\r
+       // clk_round_rate_nolock(clk, rate_hz);\r
+       rate_new = rate_hz;\r
+       rate_old = clk_get_rate(clk);\r
 \r
-       //DVFS_DBG("dvfs(%s) round rate(%lu)(rount %lu)\n",dvfs_clk->name,rate_hz,temp_hz);\r
+       // DVFS_DBG("dvfs(%s) round rate(%lu)(rount %lu)\n",dvfs_clk->name,rate_hz,rate_new);\r
 \r
        /* find the clk corresponding voltage */\r
-       if (dvfs_clk_get_ref_volt(dvfs_clk, temp_hz / 1000, &clk_fv)) {\r
+       if (dvfs_clk_get_ref_volt(dvfs_clk, rate_new / 1000, &clk_fv)) {\r
                DVFS_ERR("%s--%s:rate%lu,Get corresponding voltage error!\n", \r
-                               __func__, dvfs_clk->name, temp_hz);\r
+                               __func__, dvfs_clk->name, rate_new);\r
                return -1;\r
        }\r
        volt_old = dvfs_clk->vd->cur_volt;\r
@@ -457,8 +652,8 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
 \r
        volt_new = dvfs_vd_get_newvolt_byclk(dvfs_clk);\r
 \r
-       DVFS_LOG("dvfs--(%s),volt=%d(was %dmV),rate=%lu(was %lu),vd%u=(was%u)\n",\r
-                       dvfs_clk->name, clk_fv.index, dvfs_clk->set_volt, temp_hz, clk_get_rate(clk)\r
+       DVFS_DBG("dvfs--(%s),volt=%d(was %dmV),rate=%lu(was %lu),vd%u=(was%u)\n",\r
+                       dvfs_clk->name, clk_fv.index, dvfs_clk->set_volt, rate_new, rate_old\r
                        , volt_new, volt_old);\r
 \r
        if (flag_core_set_volt_err) {\r
@@ -467,14 +662,14 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
                if (flag_set_volt_correct <= 0) {\r
                        DVFS_ERR("%s (clk:%s),volt=%d(was %dmV),rate=%lu(was %lu), try to reload core_volt error %d!!! stop scaling\n", \r
                                        __func__, dvfs_clk->name, volt_new, volt_old, \r
-                                       temp_hz, clk_get_rate(clk), flag_set_volt_correct);\r
+                                       rate_new, rate_old, flag_set_volt_correct);\r
                        return -1;\r
                }\r
 \r
                flag_core_set_volt_err = 0;\r
                DVFS_ERR("%s (clk:%s),volt=%d(was %dmV),rate=%lu(was %lu), try to reload core_volt! core_volt_correct = %d\n", \r
                                __func__, dvfs_clk->name, volt_new, volt_old, \r
-                               temp_hz, clk_get_rate(clk), flag_set_volt_correct);\r
+                               rate_new, rate_old, flag_set_volt_correct);\r
 \r
                /* Reset vd's voltage */\r
                dvfs_clk->vd->cur_volt = flag_set_volt_correct;\r
@@ -489,7 +684,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
                                flag_core_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage up err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r
                                                __func__, dvfs_clk->name, ret, \r
-                                               temp_hz, clk_get_rate(clk), volt_new, volt_old);\r
+                                               rate_new, rate_old, volt_new, volt_old);\r
                                return -1;\r
                        }\r
 \r
@@ -500,14 +695,14 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
 \r
                dvfs_clk->vd->cur_volt = volt_new;\r
                udelay(get_volt_up_delay(volt_new, volt_old));\r
-               DVFS_LOG("%s %s set voltage OK up ret = %d, Vnew = %d(was %d), Rnew = %lu(was %lu)\n", \r
-                               __func__, dvfs_clk->name, ret, volt_new, volt_old, temp_hz, clk_get_rate(clk));\r
+               DVFS_DBG("%s %s set voltage OK up ret = %d, Vnew = %d(was %d), Rnew = %lu(was %lu)\n", \r
+                               __func__, dvfs_clk->name, ret, volt_new, volt_old, rate_new, rate_old);\r
        }\r
 \r
        if (dvfs_clk->clk_dvfs_target) {\r
-               ret = dvfs_clk->clk_dvfs_target(clk, temp_hz, clk_set_rate_locked);\r
+               ret = dvfs_clk->clk_dvfs_target(clk, rate_new, clk_set_rate_locked);\r
        } else {\r
-               ret = clk_set_rate_locked(clk, temp_hz);\r
+               ret = clk_set_rate_locked(clk, rate_new);\r
        }\r
 \r
        if (ret < 0) {\r
@@ -517,7 +712,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
                DVFS_ERR("set rate err\n");\r
                return -1;\r
        }\r
-       dvfs_clk->set_freq      = temp_hz / 1000;\r
+       dvfs_clk->set_freq      = rate_new / 1000;\r
 \r
        /* if down the voltage */\r
        if (volt_old > volt_new) {\r
@@ -526,7 +721,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
                        if (ret < 0) {\r
                                flag_core_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage down err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r
-                                               __func__, dvfs_clk->name, ret, temp_hz, clk_get_rate(clk)\r
+                                               __func__, dvfs_clk->name, ret, rate_new, rate_old\r
                                                volt_new, volt_old);\r
                                return -1;\r
                        }\r
@@ -537,7 +732,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz)
                }\r
 \r
                dvfs_clk->vd->cur_volt = volt_new;\r
-               DVFS_LOG("dvfs %s set volt ok dn\n", dvfs_clk->name);\r
+               DVFS_DBG("dvfs %s set volt ok dn\n", dvfs_clk->name);\r
 \r
        }\r
 \r
@@ -552,7 +747,7 @@ 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, pre_rate_hz;\r
+       unsigned long rate_new, rate_old;\r
 \r
 \r
        if (!clk) {\r
@@ -567,12 +762,12 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
        }\r
 \r
        /* need round rate */\r
-       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
+       rate_new = clk_round_rate_nolock(clk, rate_hz);\r
+       DVFS_DBG("dvfs(%s) round rate (%lu)(rount %lu)\n", dvfs_clk->name, rate_hz, rate_new);\r
 \r
-       pre_rate_hz = clk_get_rate(clk);\r
+       rate_old = 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
+       if (0 != dvfs_clk_get_ref_volt(dvfs_clk, rate_new / 1000, &clk_fv)) {\r
                DVFS_ERR("dvfs(%s) rate %luhz is larger,not support\n", dvfs_clk->name, rate_hz);\r
                return -1;\r
        }\r
@@ -585,28 +780,20 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
                if (flag_set_volt_correct <= 0) {\r
                        DVFS_ERR("%s (clk:%s),volt=%d(was %dmV),rate=%lu(was %lu), try to reload arm_volt error %d!!! stop scaling\n", \r
                                        __func__, dvfs_clk->name, volt_new, volt_old, \r
-                                       temp_hz, clk_get_rate(clk), flag_set_volt_correct);\r
+                                       rate_new, rate_old, flag_set_volt_correct);\r
                        return -1;\r
                }\r
 \r
                flag_arm_set_volt_err = 0;\r
                DVFS_ERR("%s (clk:%s),volt=%d(was %dmV),rate=%lu(was %lu), try to reload arm_volt! arm_volt_correct = %d\n", \r
                                __func__, dvfs_clk->name, volt_new, volt_old, \r
-                               temp_hz, clk_get_rate(clk), flag_set_volt_correct);\r
+                               rate_new, rate_old, flag_set_volt_correct);\r
 \r
                /* Reset vd's voltage */\r
                dvfs_clk->vd->cur_volt = flag_set_volt_correct;\r
                volt_old = dvfs_clk->vd->cur_volt;\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
+\r
        /* if up the voltage */\r
        if (volt_old < volt_new) {\r
                if (dvfs_clk->vd->regulator) {\r
@@ -614,7 +801,7 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
                        if (ret < 0) {\r
                                flag_arm_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage up err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r
-                                               __func__, dvfs_clk->name, ret, temp_hz, clk_get_rate(clk)\r
+                                               __func__, dvfs_clk->name, ret, rate_new, rate_old\r
                                                volt_new, volt_old);\r
                                return -1;\r
                        }\r
@@ -626,23 +813,39 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
 \r
                dvfs_clk->vd->cur_volt = volt_new;\r
                udelay(get_volt_up_delay(volt_new, volt_old));\r
-               DVFS_LOG("%s %s set voltage OK up ret = %d, Vnew = %d(was %d), Rnew = %lu(was %lu)\n", \r
-                               __func__, dvfs_clk->name, ret, volt_new, volt_old, temp_hz, clk_get_rate(clk));\r
+               DVFS_DBG("%s %s set voltage OK up ret = %d, Vnew = %d(was %d), Rnew = %lu(was %lu)\n", \r
+                               __func__, dvfs_clk->name, ret, volt_new, volt_old, rate_new, rate_old);\r
+       }\r
+       \r
+       /* depend voltage domain set up*/\r
+       if (0 != dvfs_set_depend_pre(dvfs_clk, rate_old, rate_new)) {\r
+               DVFS_ERR("%s (clk:%s),volt=%d(was %dmV),rate=%lu(was %lu), set depend pre voltage err, stop scaling\n", \r
+                               __func__, dvfs_clk->name, volt_new, volt_old, \r
+                               rate_new, rate_old);\r
+               return -1;\r
        }\r
 \r
        if (dvfs_clk->clk_dvfs_target) {\r
-               ret = dvfs_clk->clk_dvfs_target(clk, temp_hz, clk_set_rate_locked);\r
+               ret = dvfs_clk->clk_dvfs_target(clk, rate_new, clk_set_rate_locked);\r
        } else {\r
-               ret = clk_set_rate_locked(clk, temp_hz);\r
+               ret = clk_set_rate_locked(clk, rate_new);\r
        }\r
 \r
        if (ret < 0) {\r
                DVFS_ERR("set rate err\n");\r
                return -1;\r
        }\r
-       dvfs_clk->set_freq      = temp_hz / 1000;\r
+       dvfs_clk->set_freq      = rate_new / 1000;\r
 \r
-       DVFS_LOG("dvfs %s set rate%lu ok\n", dvfs_clk->name, clk_get_rate(clk));\r
+       DVFS_DBG("dvfs %s set rate %lu ok\n", dvfs_clk->name, clk_get_rate(clk));\r
+\r
+       /* depend voltage domain set down*/\r
+       if (0 != dvfs_set_depend_post(dvfs_clk, rate_old, rate_new)) {\r
+               DVFS_ERR("%s (clk:%s),volt=%d(was %dmV),rate=%lu(was %lu), set depend post voltage  err, stop scaling\n", \r
+                               __func__, dvfs_clk->name, volt_new, volt_old, \r
+                               rate_new, rate_old);\r
+               return -1;\r
+       }\r
 \r
        /* if down the voltage */\r
        if (volt_old > volt_new) {\r
@@ -651,7 +854,7 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
                        if (ret < 0) {\r
                                flag_arm_set_volt_err = 1;\r
                                DVFS_ERR("%s %s set voltage down err ret = %d, Rnew = %lu(was %lu)Hz, Vnew = %d(was %d)mV\n", \r
-                                               __func__, dvfs_clk->name, ret, temp_hz, clk_get_rate(clk)\r
+                                               __func__, dvfs_clk->name, ret, rate_new, rate_old\r
                                                volt_new, volt_old);\r
                                return -1;\r
                        }\r
@@ -662,18 +865,10 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
                }\r
 \r
                dvfs_clk->vd->cur_volt = volt_new;\r
-               DVFS_LOG("dvfs %s set volt ok dn\n", dvfs_clk->name);\r
+               DVFS_DBG("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
+\r
        return ret;\r
 }\r
 \r
@@ -684,17 +879,17 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)
  * rate must be raising sequence\r
  */\r
 static struct cpufreq_frequency_table cpu_dvfs_table[] = {\r
-       //{.frequency   = 48 * DVFS_KHZ, .index = 920*DVFS_MV},\r
-       //{.frequency   = 126 * DVFS_KHZ, .index        = 970 * DVFS_MV},\r
+       // {.frequency  = 48 * DVFS_KHZ, .index = 920*DVFS_MV},\r
+       // {.frequency  = 126 * DVFS_KHZ, .index        = 970 * DVFS_MV},\r
        // {.frequency  = 252 * DVFS_KHZ, .index        = 1040 * DVFS_MV},\r
-       // {.frequency  = 504 * DVFS_KHZ, .index        = 1060 * DVFS_MV},\r
-       {.frequency     = 816 * DVFS_KHZ, .index        = 1080 * DVFS_MV},\r
-       //  {.frequency = 1008 * DVFS_KHZ, .index       = 1100 * DVFS_MV},\r
+       // {.frequency  = 504 * DVFS_KHZ, .index        = 1050 * DVFS_MV},\r
+       {.frequency     = 816 * DVFS_KHZ, .index        = 1050 * DVFS_MV},\r
+       // {.frequency  = 1008 * DVFS_KHZ, .index       = 1100 * DVFS_MV},\r
        {.frequency     = CPUFREQ_TABLE_END},\r
 };\r
 \r
 static struct cpufreq_frequency_table ddr_dvfs_table[] = {\r
-       //{.frequency = 100 * DVFS_KHZ, .index = 1100 * DVFS_MV},\r
+       // {.frequency = 100 * DVFS_KHZ, .index = 1100 * DVFS_MV},\r
        {.frequency = 200 * DVFS_KHZ, .index = 1000 * DVFS_MV},\r
        {.frequency = 300 * DVFS_KHZ, .index = 1050 * DVFS_MV},\r
        {.frequency = 400 * DVFS_KHZ, .index = 1100 * DVFS_MV},\r
@@ -720,6 +915,19 @@ static struct cpufreq_frequency_table peri_aclk_dvfs_table[] = {
        {.frequency = CPUFREQ_TABLE_END},\r
 };\r
 \r
+static struct cpufreq_frequency_table dep_cpu2core_table[] = {\r
+       // {.frequency = 252 * DVFS_KHZ, .index    = 1025 * DVFS_MV},\r
+       // {.frequency = 504 * DVFS_KHZ, .index    = 1025 * DVFS_MV},\r
+       {.frequency = 816 * DVFS_KHZ, .index    = 1050 * DVFS_MV},//logic 1.050V\r
+       // {.frequency = 1008 * DVFS_KHZ,.index    = 1050 * DVFS_MV},\r
+       // {.frequency = 1200 * DVFS_KHZ,.index    = 1050 * DVFS_MV},\r
+       // {.frequency = 1272 * DVFS_KHZ,.index    = 1050 * DVFS_MV},//logic 1.050V\r
+       // {.frequency = 1416 * DVFS_KHZ,.index    = 1100 * DVFS_MV},//logic 1.100V\r
+       // {.frequency = 1512 * DVFS_KHZ,.index    = 1125 * DVFS_MV},//logic 1.125V\r
+       // {.frequency = 1608 * DVFS_KHZ,.index    = 1175 * DVFS_MV},//logic 1.175V\r
+       {.frequency     = CPUFREQ_TABLE_END},\r
+};\r
+\r
 static struct vd_node vd_cpu = {\r
        .name           = "vd_cpu",\r
        .regulator_name = "vdd_cpu",\r
@@ -823,6 +1031,11 @@ static struct pds_list gpu_pds[] = {
        CLK_PDS(NULL),\r
 };\r
 \r
+static struct pds_list aclk_periph_pds[] = {\r
+       CLK_PDS(&pd_peri),\r
+       CLK_PDS(NULL),\r
+};\r
+\r
 #define RK_CLKS(_clk_name, _ppds, _dvfs_table, _dvfs_nb) \\r
 { \\r
        .name   = _clk_name, \\r
@@ -831,12 +1044,6 @@ static struct pds_list gpu_pds[] = {
        .dvfs_nb        = _dvfs_nb,     \\r
 }\r
 \r
-static struct pds_list aclk_periph_pds[] = {\r
-       CLK_PDS(&pd_peri),\r
-       CLK_PDS(NULL),\r
-};\r
-\r
-\r
 static struct clk_node rk30_clks[] = {\r
        RK_CLKS("cpu", cpu_pds, cpu_dvfs_table, &rk_dvfs_clk_notifier),\r
        RK_CLKS("ddr", ddr_pds, ddr_dvfs_table, &rk_dvfs_clk_notifier),\r
@@ -844,6 +1051,17 @@ static struct clk_node rk30_clks[] = {
        RK_CLKS("aclk_periph", aclk_periph_pds, peri_aclk_dvfs_table, &rk_dvfs_clk_notifier),\r
 };\r
 \r
+#define RK_DEPPENDS(_clk_name, _pvd, _dep_table) \\r
+{ \\r
+       .clk_name       = _clk_name, \\r
+       .dep_vd         = _pvd,\\r
+       .dep_table      = _dep_table,   \\r
+}\r
+\r
+static struct depend_lookup rk30_depends[] = {\r
+       RK_DEPPENDS("cpu", &vd_core, dep_cpu2core_table),\r
+};\r
+\r
 int rk30_dvfs_init(void)\r
 {\r
        int i = 0;\r
@@ -856,12 +1074,16 @@ int rk30_dvfs_init(void)
        for (i = 0; i < ARRAY_SIZE(rk30_clks); i++) {\r
                rk_regist_clk(&rk30_clks[i]);\r
        }\r
-\r
+       for (i = 0; i < ARRAY_SIZE(rk30_depends); i++) {\r
+               rk_regist_depends(&rk30_depends[i]);\r
+       }\r
+#ifdef DVFS_DUMP_TREE\r
+       dump_dbg_map();\r
+#endif\r
        return 0;\r
 }\r
 \r
-//#define DVFS_DUMP_DBG\r
-#ifdef DVFS_DUMP_DBG\r
+#ifdef DVFS_DUMP_TREE\r
 /**\r
  * dump_dbg_map() : Draw all informations of dvfs while debug\r
  */\r
@@ -872,38 +1094,52 @@ static void dump_dbg_map(void)
        struct pd_node  *pd, *clkparent;\r
        struct clk_list *child;\r
        struct clk_node *dvfs_clk;\r
+       struct depend_list *depend;\r
 \r
-       DVFS_DBG("-------------DVFS DEBUG-----------\n\n\n");\r
-       DVFS_DBG("RK30 DVFS TREE:\n");\r
+       DVFS_LOG("-------------DVFS DEBUG-----------\n\n\n");\r
+       DVFS_LOG("RK30 DVFS TREE:\n");\r
        list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
-               DVFS_DBG("|\n|- voltage domain:%s\n", vd->name);\r
-               DVFS_DBG("|- current voltage:%d\n", vd->cur_volt);\r
+               DVFS_LOG("|\n|- voltage domain:%s\n", vd->name);\r
+               DVFS_LOG("|- current voltage:%d\n", vd->cur_volt);\r
+               list_for_each_entry(depend, &vd->req_volt_list, node2vd) {\r
+                       DVFS_LOG("|- request voltage:%d, clk:%s\n", depend->req_volt, depend->dvfs_clk->name);\r
+               }\r
 \r
                list_for_each_entry(pd, &vd->pd_list, node) {\r
-                       DVFS_DBG("|  |\n|  |- power domain:%s, status = %s, current volt = %d\n",\r
+                       DVFS_LOG("|  |\n|  |- power domain:%s, status = %s, current volt = %d\n",\r
                                        pd->name, (pd->pd_status == PD_ON) ? "ON" : "OFF", pd->cur_volt);\r
 \r
                        list_for_each_entry(child, &pd->clk_list, node) {\r
                                dvfs_clk = child->dvfs_clk;\r
-                               DVFS_DBG("|  |  |\n|  |  |- clock: %s current: rate %d, volt = %d, enable_dvfs = %s\n",\r
+                               DVFS_LOG("|  |  |\n|  |  |- clock: %s current: rate %d, volt = %d, enable_dvfs = %s\n",\r
                                                dvfs_clk->name, dvfs_clk->set_freq, dvfs_clk->set_volt, \r
                                                dvfs_clk->enable_dvfs == 0 ? "DISABLE" : "ENABLE");\r
                                for (i = 0; dvfs_clk->pds[i].pd != NULL; i++) {\r
                                        clkparent = dvfs_clk->pds[i].pd;\r
-                                       DVFS_DBG("|  |  |  |- clock parents: %s, vd_parent = %s\n", \r
+                                       DVFS_LOG("|  |  |  |- clock parents: %s, vd_parent = %s\n", \r
                                                        clkparent->name, clkparent->vd->name);\r
                                }\r
 \r
                                for (i = 0; (dvfs_clk->dvfs_table[i].frequency != CPUFREQ_TABLE_END); i++) {\r
-                                       DVFS_DBG("|  |  |  |- freq = %d, volt = %d\n", \r
+                                       DVFS_LOG("|  |  |  |- freq = %d, volt = %d\n", \r
                                                        dvfs_clk->dvfs_table[i].frequency, \r
                                                        dvfs_clk->dvfs_table[i].index);\r
 \r
                                }\r
+\r
+                               list_for_each_entry(depend, &dvfs_clk->depend_list, node2clk) {\r
+                                       DVFS_LOG("|  |  |  |  |- DEPEND VD: %s\n", depend->dep_vd->name); \r
+                                       for (i = 0; (depend->dep_table[i].frequency != CPUFREQ_TABLE_END); i++) {\r
+                                               DVFS_LOG("|  |  |  |  |- freq = %d, req_volt = %d\n", \r
+                                                               depend->dep_table[i].frequency, \r
+                                                               depend->dep_table[i].index);\r
+\r
+                                       }\r
+                               }\r
                        }\r
                }\r
        }\r
-       DVFS_DBG("-------------DVFS DEBUG END------------\n");\r
+       DVFS_LOG("-------------DVFS DEBUG END------------\n");\r
 }\r
 #endif\r
 \r
index 18e9ef36e3228347785fe1b0ae110111718dfcc3..8f4ce715ede494d91510a19f45fa6cad4e19fd70 100755 (executable)
@@ -24,94 +24,134 @@ typedef int (*clk_dvfs_target_callback)(struct clk *clk, unsigned long rate,
 \r
 /**\r
  * struct vd_node:     To Store All Voltage Domains' info\r
- * @vd_name:   Voltage Domain's Name\r
- * @cur_volt:  Voltage Domain's Current Voltage\r
- * @vd_list:   Point of he Voltage Domain List Node\r
- * @pd_list:   Head of Power Domain List Belongs to This Voltage Domain\r
- * @vd_voltreq_list:   Head of Voltage Request List for Voltage Domain\r
+ * @name:              Voltage Domain's Name\r
+ * @regulator_name:    Voltage domain's regulator name\r
+ * @cur_volt:          Voltage Domain's Current Voltage\r
+ * @regulator:         Voltage Domain's regulator point\r
+ * @node:              Point of he Voltage Domain List Node\r
+ * @pd_list:           Head of Power Domain List Belongs to This Voltage Domain\r
+ * @req_volt_list:     The list of clocks requests\r
+ * @dvfs_mutex:                Lock\r
+ * @vd_dvfs_target:    Callback function       \r
  */\r
 \r
 struct vd_node {\r
-       char    *name;\r
-       char    *regulator_name;\r
-       int             cur_volt;\r
+       char                    *name;\r
+       char                    *regulator_name;\r
+       int                     cur_volt;\r
        struct regulator        *regulator;\r
-       struct mutex            dvfs_mutex;\r
        struct list_head        node;\r
        struct list_head        pd_list;\r
+       struct list_head        req_volt_list;\r
+       struct mutex            dvfs_mutex;\r
        vd_dvfs_target_callback vd_dvfs_target;\r
 };\r
-struct vd_node_lookup {\r
-       struct vd_node  *vd;\r
-       char                    *regulator_name;\r
-};\r
+\r
 /**\r
- * struct pd_node:     To Store All Power Domains' info per Voltage Domain\r
- * @pd_name:   Power Domain's Name\r
- * @cur_volt:  Power Domain's Current Voltage\r
- * @pd_list:   Point of the Power Domain List Node\r
- * @clk_list:  Head of Power Domain's Clocks List\r
- * @pd_status:         If The Power Domain On: 1 means on, 0 means off\r
+ * struct pd_node:     To Store All Power Domains' info\r
+ * @name:              Power Domain's Name\r
+ * @cur_volt:          Power Domain's Current Voltage\r
+ * @pd_status:         Power Domain's status\r
+ * @vd:                        Voltage Domain the power domain belongs to\r
+ * @pd_clk:            Look power domain as a clock\r
+ * @node:              List node to Voltage Domain\r
+ * @clk_list:          Head of Power Domain's Clocks List\r
  */\r
 struct pd_node {\r
-       char    *name;\r
-       int             cur_volt;\r
-       unsigned char   pd_status;\r
-       struct vd_node  *vd;\r
-       struct  clk             *pd_clk;\r
+       char                    *name;\r
+       int                     cur_volt;\r
+       unsigned char           pd_status;\r
+       struct vd_node          *vd;\r
+       //struct clk            *pd_clk;\r
        struct list_head        node;\r
        struct list_head        clk_list;\r
 };\r
 \r
 struct pd_node_lookup {\r
-       struct pd_nodepd;\r
+       struct pd_node          *pd;\r
 };\r
 \r
 struct clk_list{\r
-       struct clk_node *dvfs_clk;\r
-       struct list_head node;\r
+       struct clk_node         *dvfs_clk;\r
+       struct list_head        node;\r
 };\r
 \r
 struct pds_list {\r
-       struct clk_list clk_list;\r
-       struct pd_node *pd;\r
+       struct clk_list         clk_list;\r
+       struct pd_node          *pd;\r
 };\r
 \r
+struct depend_list {\r
+       int                     req_volt;\r
+       struct clk_node         *dvfs_clk;\r
+       struct vd_node          *dep_vd;\r
+       struct list_head        node2clk;\r
+       struct list_head        node2vd;\r
+       struct cpufreq_frequency_table  *dep_table;\r
+};\r
+\r
+struct depend_lookup {\r
+       char                    *clk_name;\r
+       struct clk_node         *dvfs_clk;\r
+       struct vd_node          *dep_vd;\r
+       struct depend_list      dep_list;\r
+       struct cpufreq_frequency_table  *dep_table;\r
+};\r
+\r
+/**\r
+ * struct clk_node:    To Store All dvfs clocks' info\r
+ * @name:              Dvfs clock's Name\r
+ * @set_freq:          Dvfs clock's Current Frequency\r
+ * @set_volt:          Dvfs clock's Current Voltage\r
+ * @enable_dvfs:       Sign if DVFS clock enable\r
+ * @clk:               System clk's point\r
+ * @pds:               Power Domains dvfs clock belongs to\r
+ * @vd:                        Voltage Domains dvfs clock belongs to\r
+ * @depend_list:       Dvfs Clock depend list\r
+ * @dvfs_nb:           Notify list\r
+ * @dvfs_table:                Frequency and voltage table for dvfs\r
+ * @clk_dvfs_target:   Callback function\r
+ */\r
 struct clk_node {\r
-       char    *name;\r
-       int             set_freq;//khz\r
-       int             set_volt;\r
-       int             enable_dvfs;\r
-       struct clk *ck;\r
+       char                    *name;\r
+       int                     set_freq;       //KHZ\r
+       int                     set_volt;       //MV\r
+       int                     enable_dvfs;\r
+       struct clk              *clk;\r
        struct pds_list         *pds;\r
        struct vd_node          *vd;\r
+       struct list_head        depend_list;\r
+       struct notifier_block   *dvfs_nb;\r
        struct cpufreq_frequency_table  *dvfs_table;\r
-       struct notifier_block *dvfs_nb;\r
-       struct list_head        node;\r
-       clk_dvfs_target_callback clk_dvfs_target;\r
+       clk_dvfs_target_callback        clk_dvfs_target;\r
 };\r
+struct dvfs_arm_table {\r
+       unsigned int    frequency; /* kHz - doesn't need to be in ascending\r
+                                   * order */\r
+       unsigned int    cpu_volt;     /* any */\r
 \r
+       unsigned int    logic_volt;\r
+};\r
 #ifdef CONFIG_DVFS\r
 int rk30_dvfs_init(void);\r
 int is_support_dvfs(struct clk_node *dvfs_info);\r
 int dvfs_set_rate(struct clk *clk, unsigned long rate);\r
 int clk_enable_dvfs(struct clk *clk);\r
 int clk_disable_dvfs(struct clk *clk);\r
-int cpufreq_dvfs_init(struct clk *ck, struct cpufreq_frequency_table **table, clk_dvfs_target_callback clk_dvfs_target);\r
 void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target);\r
 struct cpufreq_frequency_table *dvfs_get_freq_volt_table(struct clk *clk);\r
 int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *table);\r
-int rk30_dvfs_init(void);\r
+int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequency_table *table);\r
 #else\r
 static inline int rk30_dvfs_init(void) { return 0; }\r
 static inline int is_support_dvfs(struct clk_node *dvfs_info) { return 0; }\r
 static inline int dvfs_set_rate(struct clk *clk, unsigned long rate) { return 0; }\r
 static inline int clk_enable_dvfs(struct clk *clk) { return 0; }\r
 static inline int clk_disable_dvfs(struct clk *clk) { return 0; }\r
-static inline int cpufreq_dvfs_init(struct clk *ck, struct cpufreq_frequency_table **table, clk_dvfs_target_callback clk_dvfs_target) { return 0; }\r
 static inline void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target) {}\r
 static inline struct cpufreq_frequency_table *dvfs_get_freq_volt_table(struct clk *clk) { return NULL; }\r
 static inline int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *table) { return 0; }\r
+static inline int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequency_table *table) {return 0;}\r
 #endif\r
 \r
 #endif\r