static struct notifier_block rk_dvfs_clk_notifier = {\r
.notifier_call = rk_dvfs_clk_notifier_event,\r
};\r
+\r
+#define NO_VOLT_DIFF\r
+#ifdef NO_VOLT_DIFF\r
+\r
+int dvfs_target(struct clk *clk, unsigned long rate_hz)\r
+{\r
+ struct clk_node *dvfs_clk;\r
+ int volt_new = 0, clk_volt_store = 0;\r
+ struct cpufreq_frequency_table clk_fv;\r
+ int ret = 0;\r
+ unsigned long rate_new, rate_old;\r
+\r
+ if (!clk) {\r
+ DVFS_ERR("%s is not a clk\n", __func__);\r
+ return -1;\r
+ }\r
+ dvfs_clk = clk_get_dvfs_info(clk);\r
+ DVFS_DBG("enter %s: clk(%s) rate = %lu Hz\n", __func__, dvfs_clk->name, rate_hz);\r
+\r
+ if (!dvfs_clk || dvfs_clk->vd == NULL || IS_ERR_OR_NULL(dvfs_clk->vd->regulator)) {\r
+ DVFS_ERR("dvfs(%s) is not register regulator\n", dvfs_clk->name);\r
+ return -1;\r
+ }\r
+\r
+ if (dvfs_clk->vd->volt_set_flag == DVFS_SET_VOLT_FAILURE) {\r
+ /* It means the last time set voltage error */\r
+ ret = dvfs_reset_volt(dvfs_clk->vd);\r
+ if (ret < 0) {\r
+ return -1;\r
+ }\r
+ }\r
+\r
+ /* Check limit rate */\r
+ //if (dvfs_clk->freq_limit_en) {\r
+ if (rate_hz < dvfs_clk->min_rate) {\r
+ rate_hz = dvfs_clk->min_rate;\r
+ } else if (rate_hz > dvfs_clk->max_rate) {\r
+ rate_hz = dvfs_clk->max_rate;\r
+ }\r
+ //}\r
+\r
+ /* 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
+\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
+ /* find the clk corresponding voltage */\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
+ clk_volt_store = dvfs_clk->set_volt;\r
+ dvfs_clk->set_volt = clk_fv.index;\r
+ volt_new = dvfs_vd_get_newvolt_byclk(dvfs_clk);\r
+ DVFS_DBG("%s,%s,new rate=%lu(was=%lu),new volt=%lu,(was=%d)\n",__FUNCTION__,dvfs_clk->name,rate_new,\r
+ rate_old,volt_new,dvfs_clk->vd->cur_volt);\r
+\r
+ /* if up the rate */\r
+ if (rate_new > rate_old) {\r
+ ret = dvfs_scale_volt_direct(dvfs_clk->vd, volt_new);\r
+ if (ret < 0)\r
+ goto fail_roll_back;\r
+ }\r
+\r
+ /* scale rate */\r
+ if (dvfs_clk->clk_dvfs_target) {\r
+ ret = dvfs_clk->clk_dvfs_target(clk, rate_new, clk_set_rate_locked);\r
+ } else {\r
+ ret = clk_set_rate_locked(clk, rate_new);\r
+ }\r
+\r
+ if (ret < 0) {\r
+ DVFS_ERR("%s set rate err\n", __func__);\r
+ goto fail_roll_back;\r
+ }\r
+ dvfs_clk->set_freq = rate_new / 1000;\r
+\r
+ DVFS_DBG("dvfs %s set rate %lu ok\n", dvfs_clk->name, clk_get_rate(clk));\r
+\r
+ /* if down the rate */\r
+ if (rate_new < rate_old) {\r
+ ret = ret = dvfs_scale_volt_direct(dvfs_clk->vd, volt_new);\r
+ if (ret < 0)\r
+ goto out;\r
+ }\r
+\r
+ return ret;\r
+fail_roll_back:\r
+ dvfs_clk->set_volt = clk_volt_store;\r
+out:\r
+ return -1;\r
+}\r
+\r
+\r
+#else\r
+\r
#ifdef CONFIG_ARCH_RK3188\r
static int g_arm_high_logic = 50 * 1000;\r
static int g_logic_high_arm = 100 * 1000;\r
return -1;\r
}\r
\r
+\r
+#endif\r
/*****************************init**************************/\r
/**\r
* rate must be raising sequence\r
.name = "vd_cpu",\r
.regulator_name = "vdd_cpu",\r
.volt_set_flag = DVFS_SET_VOLT_FAILURE,\r
+#ifdef NO_VOLT_DIFF\r
+ .vd_dvfs_target = dvfs_target,\r
+#else\r
.vd_dvfs_target = dvfs_target_cpu,\r
+#endif\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
+#ifdef NO_VOLT_DIFF\r
+ .vd_dvfs_target = dvfs_target,\r
+#else\r
.vd_dvfs_target = dvfs_target_core,\r
+#endif\r
+\r
};\r
\r
static struct vd_node vd_rtc = {\r
rk_regist_depends(&rk30_depends[i]);\r
}\r
#endif\r
+#ifndef NO_VOLT_DIFF\r
dvfs_clk_cpu = dvfs_get_dvfs_clk_byname("cpu");\r
+#endif\r
//avs_board_init(&rk30_avs_ctr);\r
return 0;\r
}\r