#define get_volt_up_delay(new_volt, old_volt) \\r
((new_volt) > (old_volt) ? (((new_volt) - (old_volt)) >> 9) : 0)\r
\r
+\r
+\r
+/**************************************vd regulator functions***************************************/\r
int dvfs_regulator_set_voltage_readback(struct regulator *regulator, int min_uV, int max_uV)\r
{\r
int ret = 0, read_back = 0;\r
vd->volt_set_flag = DVFS_SET_VOLT_SUCCESS;\r
}\r
\r
+static void dvfs_get_vd_regulator_volt_list(struct vd_node *vd)\r
+{\r
+ unsigned i,selector=dvfs_regulator_count_voltages(vd->regulator);\r
+ int sel_volt=0;\r
+ \r
+ if(selector>VD_VOL_LIST_CNT)\r
+ selector=VD_VOL_LIST_CNT;\r
+ \r
+ mutex_unlock(&mutex);\r
+ for (i = 0; i<selector; i++) {\r
+ sel_volt=dvfs_regulator_list_voltage(vd->regulator,i);\r
+ if(sel_volt<=0)\r
+ { \r
+ DVFS_WARNING("%s : selector=%u,but volt <=0\n",vd->name,i);\r
+ break;\r
+ }\r
+ vd->volt_list[i]=sel_volt; \r
+ printk("%s:selector=%u,volt %d\n",vd->name,i,sel_volt);\r
+ }\r
+ vd->n_voltages=selector;\r
+ mutex_unlock(&mutex);\r
+}\r
+\r
+// >= volt\r
+static int vd_regulator_round_volt_max(struct vd_node *vd, int volt)\r
+{\r
+ int sel_volt;\r
+ unsigned i;\r
+ \r
+ for (i = 0; i<vd->n_voltages; i++) {\r
+ sel_volt=vd->volt_list[i];\r
+ if(sel_volt<=0)\r
+ { \r
+ DVFS_WARNING("%s:list_volt : selector=%u,but volt <=0\n",__FUNCTION__,i);\r
+ return -1;\r
+ }\r
+ if(sel_volt>=volt)\r
+ return sel_volt; \r
+ }\r
+ return -1;\r
+}\r
+// >=volt\r
+static int vd_regulator_round_volt_min(struct vd_node *vd, int volt)\r
+{\r
+ int sel_volt;\r
+ unsigned i;\r
+ \r
+ for (i = 0; i<vd->n_voltages; i++) {\r
+ sel_volt=vd->volt_list[i];\r
+ if(sel_volt<=0)\r
+ { \r
+ DVFS_WARNING("%s:list_volt : selector=%u,but volt <=0\n",__FUNCTION__,i);\r
+ return -1;\r
+ }\r
+ if(sel_volt>volt)\r
+ {\r
+ if(i>0)\r
+ return vd->volt_list[i-1];\r
+ else\r
+ return -1;\r
+ } \r
+ }\r
+ return -1;\r
+}\r
+\r
+// >=volt\r
+int vd_regulator_round_volt(struct vd_node *vd, int volt,int flags)\r
+{\r
+ if(!vd->n_voltages)\r
+ return -1;\r
+ if(flags==VD_LIST_RELATION_L)\r
+ return vd_regulator_round_volt_min(vd,volt);\r
+ else\r
+ return vd_regulator_round_volt_max(vd,volt); \r
+}\r
+EXPORT_SYMBOL(vd_regulator_round_volt);\r
+\r
+\r
+static void dvfs_table_round_volt(struct clk_node *dvfs_clk)\r
+{\r
+ int i,test_volt;\r
+\r
+ if(!dvfs_clk->dvfs_table||!dvfs_clk->vd||IS_ERR_OR_NULL(dvfs_clk->vd->regulator))\r
+ return;\r
+ mutex_lock(&mutex);\r
+ for (i = 0; (dvfs_clk->dvfs_table[i].frequency != CPUFREQ_TABLE_END); i++) {\r
+\r
+ test_volt=vd_regulator_round_volt(dvfs_clk->vd,dvfs_clk->dvfs_table[i].index,VD_LIST_RELATION_H);\r
+ if(test_volt<=0)\r
+ { \r
+ DVFS_WARNING("clk %s:round_volt : is %d,but list <=0\n",dvfs_clk->name,dvfs_clk->dvfs_table[i].index);\r
+ break;\r
+ }\r
+ printk("clk %s:round_volt %d to %d\n",dvfs_clk->name,dvfs_clk->dvfs_table[i].index,test_volt);\r
+ dvfs_clk->dvfs_table[i].index=test_volt; \r
+ }\r
+ mutex_unlock(&mutex);\r
+}\r
struct regulator *dvfs_get_regulator(char *regulator_name) \r
{\r
struct vd_node *vd;\r
return NULL;\r
}\r
\r
+/**************************************dvfs clocks functions***************************************/\r
int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate)\r
{\r
struct clk_node *dvfs_clk;\r
return ret;\r
}\r
\r
+static void dvfs_table_round_clk_rate(struct clk_node *dvfs_clk)\r
+{\r
+ int i;\r
+ long temp_rate;\r
+ int rate;\r
+ int flags;\r
+ \r
+ if(!dvfs_clk->dvfs_table||dvfs_clk->clk==NULL||is_suport_round_rate(dvfs_clk->clk)<0)\r
+ return;\r
+ \r
+ mutex_lock(&mutex);\r
+ for (i = 0; (dvfs_clk->dvfs_table[i].frequency != CPUFREQ_TABLE_END); i++) {\r
+ //ddr rate = real rate+flags\r
+ flags=dvfs_clk->dvfs_table[i].frequency%1000;\r
+ rate=(dvfs_clk->dvfs_table[i].frequency/1000)*1000;\r
+ temp_rate=clk_round_rate(dvfs_clk->clk,rate*1000);\r
+ if(temp_rate<=0)\r
+ { \r
+ DVFS_WARNING("clk %s:round_clk_rate : is %d,but round <=0",dvfs_clk->name,dvfs_clk->dvfs_table[i].frequency);\r
+ break;\r
+ }\r
+ temp_rate=(temp_rate/1000)+flags;\r
+ \r
+ printk("clk %s round_clk_rate %d to %d\n",\r
+ dvfs_clk->name,dvfs_clk->dvfs_table[i].frequency,(int)(temp_rate));\r
+ \r
+ dvfs_clk->dvfs_table[i].frequency=temp_rate; \r
+ }\r
+ mutex_unlock(&mutex);\r
+}\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
dvfs_clk->clk_dvfs_target = clk_dvfs_target;\r
}\r
\r
+/************************************************ freq volt table************************************/\r
struct cpufreq_frequency_table *dvfs_get_freq_volt_table(struct clk *clk) \r
{\r
struct clk_node *info = clk_get_dvfs_info(clk);\r
DVFS_DBG("%s,clk %s,limit max=%lu,min=%lu\n",__FUNCTION__,info->name,info->max_rate,info->min_rate);\r
\r
mutex_unlock(&mutex);\r
+ dvfs_table_round_clk_rate(info);\r
+ dvfs_table_round_volt(info);\r
return 0;\r
}\r
EXPORT_SYMBOL(dvfs_set_freq_volt_table);\r
}\r
\r
\r
-\r
-\r
int clk_enable_dvfs(struct clk *clk)\r
{\r
struct clk_node *dvfs_clk;\r
if (!IS_ERR_OR_NULL(dvfs_clk->vd->regulator)) {\r
// DVFS_DBG("dvfs_regulator_get(%s)\n",dvfs_clk->vd->regulator_name);\r
clk_enable_dvfs_regulator_check(dvfs_clk->vd);\r
+ dvfs_get_vd_regulator_volt_list(dvfs_clk->vd);\r
} else {\r
//dvfs_clk->vd->regulator = NULL;\r
dvfs_clk->enable_dvfs = 0;\r
// DVFS_DBG("%s(%s) vd volt=%u\n",__func__,dvfs_clk->name,dvfs_clk->vd->cur_volt);\r
}\r
\r
+ dvfs_table_round_clk_rate(dvfs_clk);\r
+ dvfs_table_round_volt(dvfs_clk);\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
\r
* @dvfs_mutex: Lock\r
* @vd_dvfs_target: Callback function \r
*/\r
+ #define VD_VOL_LIST_CNT (200)\r
+ #define VD_LIST_RELATION_L 0\r
+ #define VD_LIST_RELATION_H 1\r
\r
struct vd_node {\r
char *name;\r
struct list_head req_volt_list;\r
//struct mutex dvfs_mutex;\r
vd_dvfs_target_callback vd_dvfs_target;\r
+ unsigned n_voltages;\r
+ int volt_list[VD_VOL_LIST_CNT];\r
};\r
\r
/**\r
#define dvfs_regulator_put(regu) regulator_put((regu))\r
#define dvfs_regulator_set_voltage(regu,min_uV,max_uV) regulator_set_voltage((regu),(min_uV),(max_uV))\r
#define dvfs_regulator_get_voltage(regu) regulator_get_voltage((regu))\r
+#define dvfs_regulator_list_voltage(regu,selector) regulator_list_voltage((regu),(selector))\r
+#define dvfs_regulator_count_voltages(regu) regulator_count_voltages((regu))\r
\r
#define dvfs_clk_get(a,b) clk_get((a),(b))\r
#define dvfs_clk_get_rate_kz(a) (clk_get_rate((a))/1000)\r
int rk_regist_pd(struct pd_node_lookup *pd_lookup);\r
int rk_regist_clk(struct clk_node *dvfs_clk);\r
int rk_regist_depends(struct depend_lookup *dep_node);\r
-struct clk_node *dvfs_get_dvfs_clk_byname(char *name) ;\r
-\r
+struct clk_node *dvfs_get_dvfs_clk_byname(char *name);\r
+int vd_regulator_round_volt(struct vd_node *vd, int volt,int flags);\r
\r
/******************************************************************************/\r
\r