rk30:sdk add interface of avs function and interface to see dvfs tree(/sys/dvfs/dvfs_...
authorchenxing <chenxing@rock-chips.com>
Thu, 5 Jul 2012 10:28:18 +0000 (18:28 +0800)
committerchenxing <chenxing@rock-chips.com>
Thu, 5 Jul 2012 10:28:18 +0000 (18:28 +0800)
arch/arm/mach-rk30/dvfs.c
arch/arm/mach-rk30/include/mach/dvfs.h [changed mode: 0755->0644]

index df821d75c246e1d3f145bfc98861a67245c61bbe..1a8ca97323a18bea9a12c1eb85a80f01a5f761b9 100644 (file)
 #include <mach/clock.h>\r
 #include <linux/regulator/consumer.h>\r
 #include <linux/delay.h>\r
+#include <linux/io.h>\r
+#include <linux/hrtimer.h>\r
 \r
 #define DVFS_DBG(fmt, args...) {while(0);}\r
-#define DVFS_ERR(fmt, args...) pr_err("DVFS ERR:\t"fmt, ##args)\r
-#define DVFS_LOG(fmt, args...) pr_debug(fmt, ##args)\r
-//#define DVFS_LOG(fmt, args...) pr_err(fmt, ##args)\r
+#define DVFS_ERR(fmt, args...) printk("DVFS ERR:\t"fmt, ##args)\r
+#define DVFS_LOG(fmt, args...) printk("DVFS LOG:\t"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,10 +57,7 @@ static DEFINE_MUTEX(rk_dvfs_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
+static int dump_dbg_map(char* buf);\r
 \r
 #define PD_ON  1\r
 #define PD_OFF 0\r
@@ -294,6 +292,7 @@ int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequen
        struct vd_node          *vd;\r
        struct depend_list      *depend;\r
        struct clk_node         *info;\r
+\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
@@ -302,7 +301,7 @@ int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequen
 \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
+                       DVFS_DBG("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
@@ -311,9 +310,6 @@ int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequen
                                }\r
                        }\r
                        mutex_unlock(&mutex);\r
-#ifdef DVFS_DUMP_TREE\r
-                       dump_dbg_map();\r
-#endif\r
                        return 0;\r
                }\r
        }\r
@@ -615,7 +611,7 @@ static int dvfs_set_depend_pre(struct clk_node *dvfs_clk, unsigned long rate_old
                }\r
 \r
                if (!depend->dep_vd->regulator) {\r
-                       DVFS_LOG("%s regulator empty\n", __func__);\r
+                       DVFS_DBG("%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
@@ -631,20 +627,20 @@ static int dvfs_set_depend_pre(struct clk_node *dvfs_clk, unsigned long rate_old
 \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
+                       DVFS_DBG("%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
+               DVFS_DBG("%s setting voltage = %d\n", __func__, volt);\r
                ret = dvfs_regulator_set_voltage_readback(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
+               DVFS_DBG("%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
@@ -672,7 +668,7 @@ static int dvfs_set_depend_post(struct clk_node *dvfs_clk, unsigned long rate_ol
                }\r
 \r
                if (!depend->dep_vd->regulator) {\r
-                       DVFS_LOG("%s regulator empty\n", __func__);\r
+                       DVFS_DBG("%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
@@ -688,20 +684,20 @@ static int dvfs_set_depend_post(struct clk_node *dvfs_clk, unsigned long rate_ol
 \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
+                       DVFS_DBG("%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
+               DVFS_DBG("%s setting voltage = %d\n", __func__, volt);\r
                ret = dvfs_regulator_set_voltage_readback(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
+               DVFS_DBG("%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
@@ -1207,17 +1203,448 @@ int rk30_dvfs_init(void)
        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
+       return 0;\r
+}\r
+\r
+/*******************************AVS AREA****************************************/\r
+/*\r
+ * To use AVS function, you must call avs_init in machine_rk30_board_init(void)(board-rk30-sdk.c)\r
+ * And then call(vdd_log):\r
+ *     regulator_set_voltage(dcdc, 1100000, 1100000);\r
+ *     avs_init_val_get(1,1100000,"wm8326 init");\r
+ *     udelay(600);\r
+ *     avs_set_scal_val(AVS_BASE);\r
+ * in wm831x_post_init(board-rk30-sdk-wm8326.c)\r
+ * AVS_BASE can use 172\r
+ */\r
+\r
+int avs_scale_volt = 0;\r
+int avs_get_scal_val(int vol);\r
+\r
+int dvfs_avs_scale_table(struct clk *clk, char *depend_vd_name)\r
+{\r
+       /* if depend_vd_name == NULL scale clk table\r
+        * else scale clk's depend table, named depend_vd_name\r
+        * */\r
+       struct vd_node          *vd;\r
+       struct depend_list      *depend;\r
+       struct clk_node *info = clk_get_dvfs_info(clk);\r
+       struct cpufreq_frequency_table  *table = NULL;\r
+       int i;\r
+\r
+       if (NULL == depend_vd_name) {\r
+               table = info->dvfs_table;\r
+       } else {\r
+               list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
+                       if (0 == strcmp(vd->name, depend_vd_name)) {\r
+                               DVFS_DBG("%S FOUND A MATCH vd\n", __func__);\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
+                                               DVFS_DBG("%S FOUND A MATCH table\n", __func__);\r
+                                               table = depend->dep_table;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               mutex_unlock(&mutex);\r
+                       }\r
+               }\r
+       }\r
+\r
+       if (table == NULL) {\r
+               DVFS_ERR("%s can not find match table\n", __func__);\r
+               return -1;\r
+       }\r
+       if (avs_scale_volt != 0) {\r
+               DVFS_LOG("AVS scale %s, depend name = %s, voltage = %d\n",\r
+                               info->name, depend_vd_name, avs_scale_volt);\r
+               for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {\r
+                       table[i].index = avs_get_scal_val(table[i].index);\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+void __iomem *rk30_nandc_base;\r
+\r
+#define nandc_readl(offset)    readl_relaxed(rk30_nandc_base + offset)\r
+#define nandc_writel(v, offset) do { writel_relaxed(v, rk30_nandc_base + offset); dsb(); } while (0)\r
+u8 rk30_get_avs_val(void)\r
+{\r
+       u32 nanc_save_reg[4];\r
+       unsigned long flags;\r
+       u32 paramet = 0;\r
+       u32 count = 100;\r
+       preempt_disable();\r
+       local_irq_save(flags);\r
+\r
+       nanc_save_reg[0] = nandc_readl(0);\r
+       nanc_save_reg[1] = nandc_readl(0x130);\r
+       nanc_save_reg[2] = nandc_readl(0x134);\r
+       nanc_save_reg[3] = nandc_readl(0x158);\r
+\r
+       nandc_writel(nanc_save_reg[0] | 0x1 << 14, 0);\r
+       nandc_writel(0x5, 0x130);\r
+\r
+       nandc_writel(7, 0x158);\r
+       nandc_writel(1, 0x134);\r
+\r
+       while(count--) {\r
+               paramet = nandc_readl(0x138);\r
+               if((paramet & 0x1))\r
+                       break;\r
+               udelay(1);\r
+       };\r
+       paramet = (paramet >> 1) & 0xff;\r
+       nandc_writel(nanc_save_reg[0], 0);\r
+       nandc_writel(nanc_save_reg[1], 0x130);\r
+       nandc_writel(nanc_save_reg[2], 0x134);\r
+       nandc_writel(nanc_save_reg[3], 0x158);\r
+\r
+       local_irq_restore(flags);\r
+       preempt_enable();\r
+       return (u8)paramet;\r
+\r
+}\r
+#define init_avs_times 10\r
+#define init_avs_st_num 5\r
+\r
+struct init_avs_st {\r
+       int is_set;\r
+       u8 paramet[init_avs_times];\r
+       int vol;\r
+       char *s;\r
+};\r
+\r
+struct init_avs_st init_avs_paramet[init_avs_st_num];\r
+\r
+void avs_init_val_get(int index, int vol, char *s)\r
+{\r
+       int i;\r
+       if(index >= init_avs_times)\r
+               return;\r
+       init_avs_paramet[index].vol = vol;\r
+       init_avs_paramet[index].s = s;\r
+       init_avs_paramet[index].is_set++;\r
+       for(i = 0; i < init_avs_times; i++) {\r
+               init_avs_paramet[index].paramet[i] = rk30_get_avs_val();\r
+               mdelay(1);\r
+       }\r
+}\r
+\r
+void avs_init(void)\r
+{\r
+       memset(&init_avs_paramet[0].is_set, 0, sizeof(init_avs_paramet));\r
+       rk30_nandc_base = ioremap(RK30_NANDC_PHYS, RK30_NANDC_SIZE);\r
+       //avs_init_val_get(0,1150000,"board_init");\r
+}\r
+\r
+#define VOL_DYN_STEP (12500)  //mv\r
+#define AVS_VAL_PER_STEP (4)  //mv\r
+\r
+u8 avs_init_get_min_val(void)\r
+{\r
+       int i, j;\r
+       u8 min_avs = 0xff;\r
+       for(i = 0; i < init_avs_st_num; i++) {\r
+               if(init_avs_paramet[i].is_set && init_avs_paramet[i].vol == (1100 * 1000)) {\r
+                       for(j = 0; j < init_avs_times; j++)\r
+                               min_avs = (u8)min(min_avs, init_avs_paramet[i].paramet[j]);\r
+               }\r
+\r
+       }\r
+       return min_avs;\r
+}\r
+\r
+int avs_get_scal_val(int vol)\r
+{\r
+       vol += avs_scale_volt;\r
+       if(vol < 1000 * 1000)\r
+               vol = 1000 * 1000;\r
+       if(vol > 1400 * 1000)\r
+               vol = 1400 * 1000;\r
+       return vol;\r
+}\r
+#if 0\r
+u8 avs_test_date[] = {172, 175, 176, 179, 171, 168, 165, 162, 199, 0};\r
+u8 avs_test_date_cunt = 0;\r
 #endif\r
+int avs_set_scal_val(u8 avs_base)\r
+{\r
+       u8 avs_test = avs_init_get_min_val();\r
+       s8 step = 0;\r
+\r
+       if (avs_base < avs_test) {\r
+               DVFS_LOG("AVS down voltage, ignore\n");\r
+               return 0;\r
+       }\r
+       step = (avs_base - avs_test) / AVS_VAL_PER_STEP;\r
+       step = (avs_base > avs_test) ? (step + 1) : step;\r
+       if (step > 2)\r
+               step += 1;\r
+       avs_scale_volt = (step) * (VOL_DYN_STEP);\r
+\r
+       DVFS_LOG("avs_set_scal_val test=%d,base=%d,step=%d,scale_vol=%d\n",\r
+                       avs_test, avs_base, step, avs_scale_volt);\r
        return 0;\r
 }\r
 \r
-#ifdef DVFS_DUMP_TREE\r
+u32 print_avs_init(char *buf)\r
+{\r
+       char *s = buf;\r
+       int i, j;\r
+\r
+       for(j = 0; j < init_avs_st_num; j++) {\r
+               if(init_avs_paramet[j].vol <= 0)\r
+                       continue;\r
+               s += sprintf(s, "%s ,vol=%d,paramet following\n", \r
+                               init_avs_paramet[j].s, init_avs_paramet[j].vol);\r
+               for(i = 0; i < init_avs_times; i++) {\r
+                       s += sprintf(s, "%d ", init_avs_paramet[j].paramet[i]);\r
+               }\r
+\r
+               s += sprintf(s, "\n");\r
+       }\r
+       return (s - buf);\r
+}\r
+\r
+static ssize_t avs_init_show(struct kobject *kobj, struct kobj_attribute *attr,\r
+               char *buf)\r
+{\r
+       return print_avs_init(buf);\r
+}\r
+\r
+static ssize_t avs_init_store(struct kobject *kobj, struct kobj_attribute *attr,\r
+               const char *buf, size_t n)\r
+{\r
+\r
+       return n;\r
+}\r
+static ssize_t avs_now_show(struct kobject *kobj, struct kobj_attribute *attr,\r
+               char *buf)\r
+{\r
+       return sprintf(buf, "%d\n", rk30_get_avs_val());\r
+}\r
+\r
+static ssize_t avs_now_store(struct kobject *kobj, struct kobj_attribute *attr,\r
+               const char *buf, size_t n)\r
+{\r
+       return n;\r
+}\r
+extern struct timer_list avs_timer;\r
+u32 avs_dyn_start = 0;\r
+extern u32 avs_dyn_data_cnt;\r
+u8 *avs_dyn_data = NULL;\r
+u32 show_line_cnt = 0;\r
+#define val_per_line (30)\r
+#define line_pre_show (30)\r
+u8 dly_min;\r
+u8 dly_max;\r
+#define USE_NORMAL_TIME\r
+static ssize_t avs_dyn_show(struct kobject *kobj, struct kobj_attribute *attr,\r
+               char *buf)\r
+{\r
+       char *s = buf;\r
+       u32 i;\r
+\r
+       if(avs_dyn_start) {\r
+               int start_cnt;\r
+               int end_cnt;\r
+               end_cnt = (avs_dyn_data_cnt ? (avs_dyn_data_cnt - 1) : 0);\r
+               if(end_cnt > (line_pre_show * val_per_line))\r
+                       start_cnt = end_cnt - (line_pre_show * val_per_line);\r
+               else\r
+                       start_cnt = 0;\r
+\r
+               dly_min = avs_dyn_data[start_cnt];\r
+               dly_max = avs_dyn_data[start_cnt];\r
+\r
+               //s += sprintf(s,"data start=%d\n",i);\r
+               for(i = start_cnt; i <= end_cnt;) {\r
+                       s += sprintf(s, "%d", avs_dyn_data[i]);\r
+                       dly_min = min(dly_min, avs_dyn_data[i]);\r
+                       dly_max = max(dly_max, avs_dyn_data[i]);\r
+                       i++;\r
+                       if(!(i % val_per_line)) {\r
+                               s += sprintf(s, "\n");\r
+                       } else\r
+                               s += sprintf(s, " ");\r
+               }\r
+\r
+               s += sprintf(s, "\n");\r
+\r
+               s += sprintf(s, "new data is from=%d to %d\n", start_cnt, end_cnt);\r
+               //s += sprintf(s,"\n max=%d,min=%d,totolcnt=%d,line=%d\n",dly_max,dly_min,avs_dyn_data_cnt,show_line_cnt);\r
+\r
+\r
+       } else {\r
+               if(show_line_cnt == 0) {\r
+                       dly_min = avs_dyn_data[0];\r
+                       dly_max = avs_dyn_data[0];\r
+               }\r
+\r
+\r
+               for(i = show_line_cnt * (line_pre_show * val_per_line); i < avs_dyn_data_cnt;) {\r
+                       s += sprintf(s, "%d", avs_dyn_data[i]);\r
+                       dly_min = min(dly_min, avs_dyn_data[i]);\r
+                       dly_max = max(dly_max, avs_dyn_data[i]);\r
+                       i++;\r
+                       if(!(i % val_per_line)) {\r
+                               s += sprintf(s, "\n");\r
+                       } else\r
+                               s += sprintf(s, " ");\r
+                       if(i >= ((show_line_cnt + 1)*line_pre_show * val_per_line))\r
+                               break;\r
+               }\r
+\r
+               s += sprintf(s, "\n");\r
+\r
+               s += sprintf(s, "max=%d,min=%d,totolcnt=%d,line=%d\n", \r
+                               dly_max, dly_min, avs_dyn_data_cnt, show_line_cnt);\r
+               show_line_cnt++;\r
+               if(((show_line_cnt * line_pre_show)*val_per_line) >= avs_dyn_data_cnt) {\r
+\r
+                       show_line_cnt = 0;\r
+\r
+                       s += sprintf(s, "data is over\n");\r
+               }\r
+       }\r
+       return (s - buf);\r
+}\r
+extern struct hrtimer dvfs_hrtimer;\r
+\r
+static ssize_t avs_dyn_store(struct kobject *kobj, struct kobj_attribute *attr,\r
+               const char *buf, size_t n)\r
+{\r
+       const char *pbuf;\r
+\r
+       if((strncmp(buf, "start", strlen("start")) == 0)) {\r
+               pbuf = &buf[strlen("start")];\r
+               avs_dyn_data_cnt = 0;\r
+               show_line_cnt = 0;\r
+               if(avs_dyn_data) {\r
+#ifdef USE_NORMAL_TIME\r
+                       mod_timer(&avs_timer, jiffies + msecs_to_jiffies(5));\r
+#else\r
+                       hrtimer_start(&dvfs_hrtimer, ktime_set(0, 5 * 1000 * 1000), HRTIMER_MODE_REL);\r
+#endif\r
+                       avs_dyn_start = 1;\r
+               }\r
+               //sscanf(pbuf, "%d %d", &number, &voltage);\r
+               //DVFS_LOG("---------ldo %d %d\n", number, voltage);\r
+\r
+       } else if((strncmp(buf, "stop", strlen("stop")) == 0)) {\r
+               pbuf = &buf[strlen("stop")];\r
+               avs_dyn_start = 0;\r
+               show_line_cnt = 0;\r
+               //sscanf(pbuf, "%d %d", &number, &voltage);\r
+               //DVFS_LOG("---------dcdc %d %d\n", number, voltage);\r
+       }\r
+\r
+\r
+\r
+       return n;\r
+}\r
+\r
+static ssize_t dvfs_tree_store(struct kobject *kobj, struct kobj_attribute *attr,\r
+               const char *buf, size_t n)\r
+{\r
+       return n;\r
+}\r
+static ssize_t dvfs_tree_show(struct kobject *kobj, struct kobj_attribute *attr,\r
+               char *buf)\r
+{\r
+       return dump_dbg_map(buf);\r
+\r
+}\r
+\r
+struct timer_list avs_timer;\r
+\r
+#define avs_dyn_data_num (3*1000*1000)\r
+//char *avs_dyn_data;\r
+u32 avs_dyn_data_cnt = 0;\r
+\r
+\r
+static void avs_timer_fn(unsigned long data)\r
+{\r
+       int i;\r
+       for(i = 0; i < 1; i++) {\r
+               if(avs_dyn_data_cnt >= avs_dyn_data_num)\r
+                       return;\r
+               avs_dyn_data[avs_dyn_data_cnt] = rk30_get_avs_val();\r
+               avs_dyn_data_cnt++;\r
+       }\r
+       if(avs_dyn_start)\r
+               mod_timer(&avs_timer, jiffies + msecs_to_jiffies(10));\r
+}\r
+#if 0\r
+struct hrtimer dvfs_hrtimer;\r
+static enum hrtimer_restart dvfs_hrtimer_timer_func(struct hrtimer *timer)\r
+{\r
+       int i;\r
+       for(i = 0; i < 1; i++) {\r
+               if(avs_dyn_data_cnt >= avs_dyn_data_num)\r
+                       return HRTIMER_NORESTART;\r
+               avs_dyn_data[avs_dyn_data_cnt] = rk30_get_avs_val();\r
+               avs_dyn_data_cnt++;\r
+       }\r
+       if(avs_dyn_start)\r
+               hrtimer_start(timer, ktime_set(0, 1 * 1000 * 1000), HRTIMER_MODE_REL);\r
+\r
+}\r
+#endif\r
+/*********************************************************************************/\r
+struct kobject *dvfs_kobj;\r
+struct dvfs_attribute {\r
+       struct attribute        attr;\r
+       ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,\r
+                       char *buf);\r
+       ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,\r
+                       const char *buf, size_t n);\r
+};\r
+\r
+static struct dvfs_attribute dvfs_attrs[] = {\r
+       /*     node_name        permision               show_func       store_func */\r
+       __ATTR(dvfs_tree,       S_IRUGO | S_IWUSR,      dvfs_tree_show, dvfs_tree_store),\r
+       __ATTR(avs_init,        S_IRUGO | S_IWUSR,      avs_init_show,  avs_init_store),\r
+       //__ATTR(avs_dyn,               S_IRUGO | S_IWUSR,      avs_dyn_show,   avs_dyn_store),\r
+       __ATTR(avs_now,         S_IRUGO | S_IWUSR,      avs_now_show,   avs_now_store),\r
+};\r
+\r
+static int __init dvfs_init(void)\r
+{\r
+       int i, ret = 0;\r
+#ifdef USE_NORMAL_TIME\r
+       init_timer(&avs_timer);\r
+       //avs_timer.expires = jiffies+msecs_to_jiffies(1);\r
+       avs_timer.function = avs_timer_fn;\r
+       //mod_timer(&avs_timer,jiffies+msecs_to_jiffies(1));\r
+#else\r
+       hrtimer_init(&dvfs_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);\r
+       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
+       dvfs_kobj = kobject_create_and_add("dvfs", NULL);\r
+       if (!dvfs_kobj)\r
+               return -ENOMEM;\r
+       for (i = 0; i < ARRAY_SIZE(dvfs_attrs); i++) {\r
+               ret = sysfs_create_file(dvfs_kobj, &dvfs_attrs[i].attr);\r
+               if (ret != 0) {\r
+                       DVFS_ERR("create index %d error\n", i);\r
+                       return ret;\r
+               }\r
+       }\r
+\r
+       return ret;\r
+}\r
+subsys_initcall(dvfs_init);\r
+\r
 /**\r
  * dump_dbg_map() : Draw all informations of dvfs while debug\r
  */\r
-static void dump_dbg_map(void)\r
+static int dump_dbg_map(char *buf)\r
 {\r
        int i;\r
        struct vd_node  *vd;\r
@@ -1225,42 +1652,43 @@ static void dump_dbg_map(void)
        struct clk_list *child;\r
        struct clk_node *dvfs_clk;\r
        struct depend_list *depend;\r
-\r
-       DVFS_LOG("-------------DVFS DEBUG-----------\n\n\n");\r
-       DVFS_LOG("RK30 DVFS TREE:\n");\r
+       char* s = buf;\r
+       \r
+       s += sprintf(s, "-------------DVFS TREE-----------\n\n\n");\r
+       s += sprintf(s, "RK30 DVFS TREE:\n");\r
        list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
-               DVFS_LOG("|\n|- voltage domain:%s\n", vd->name);\r
-               DVFS_LOG("|- current voltage:%d\n", vd->cur_volt);\r
+               s += sprintf(s, "|\n|- voltage domain:%s\n", vd->name);\r
+               s += sprintf(s, "|- 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
+                       s += sprintf(s, "|- 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_LOG("|  |\n|  |- power domain:%s, status = %s, current volt = %d\n",\r
+                       s += sprintf(s, "|  |\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_LOG("|  |  |\n|  |  |- clock: %s current: rate %d, volt = %d, enable_dvfs = %s\n",\r
+                               s += sprintf(s, "|  |  |\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_LOG("|  |  |  |- clock parents: %s, vd_parent = %s\n", \r
+                                       s += sprintf(s, "|  |  |  |- 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_LOG("|  |  |  |- freq = %d, volt = %d\n", \r
+                                       s += sprintf(s, "|  |  |  |- 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
+                                       s += sprintf(s, "|  |  |  |  |- 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
+                                               s += sprintf(s, "|  |  |  |  |- freq = %d, req_volt = %d\n", \r
                                                                depend->dep_table[i].frequency, \r
                                                                depend->dep_table[i].index);\r
 \r
@@ -1269,9 +1697,8 @@ static void dump_dbg_map(void)
                        }\r
                }\r
        }\r
-       DVFS_LOG("-------------DVFS DEBUG END------------\n");\r
+       s += sprintf(s, "-------------DVFS TREE END------------\n");\r
+       return s - buf;\r
 }\r
-#endif\r
-\r
 \r
 \r
old mode 100755 (executable)
new mode 100644 (file)
index 3097c6a..d20eb99
@@ -154,6 +154,10 @@ struct regulator* dvfs_get_regulator(char *regulator_name);
 int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate);\r
 int dvfs_clk_disable_limit(struct clk *clk);\r
 \r
+void avs_init(void);\r
+void avs_init_val_get(int index,int vol,char *s);\r
+int avs_set_scal_val(u8 avs_base);\r
+int dvfs_avs_scale_table(struct clk* clk, char* depend_vd_name);\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
@@ -168,6 +172,11 @@ static inline int dvfs_set_arm_logic_volt(struct dvfs_arm_table *dvfs_cpu_logic_
 static inline struct regulator* dvfs_get_regulator(char *regulator_name){ return NULL; }\r
 static inline int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate){ return 0; }\r
 static inline int dvfs_clk_disable_limit(struct clk *clk){ return 0; };\r
+\r
+static inline void avs_init(void){};\r
+static inline void avs_init_val_get(int index, int vol, char *s){};\r
+static inline int avs_set_scal_val(u8 avs_base){ return 0; };\r
+static inline int dvfs_avs_scale_table(struct clk* clk, char* depend_vd_name){ return 0; };\r
 #endif\r
 \r
 #endif\r