#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
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
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
}\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
\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
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
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
}\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
.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
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
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
#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
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
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
\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
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
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
\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
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
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
}\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
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
}\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
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
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
\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
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
}\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
* 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
{.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
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
.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
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
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
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