forget adding dvfs.c,so submit again
authorxxx <xxx@rock-chips.com>
Tue, 22 Jan 2013 10:05:40 +0000 (18:05 +0800)
committerxxx <xxx@rock-chips.com>
Tue, 22 Jan 2013 10:06:06 +0000 (18:06 +0800)
arch/arm/mach-rk3188/dvfs.c [new file with mode: 0755]

diff --git a/arch/arm/mach-rk3188/dvfs.c b/arch/arm/mach-rk3188/dvfs.c
new file mode 100755 (executable)
index 0000000..5ed1809
--- /dev/null
@@ -0,0 +1,678 @@
+/* arch/arm/mach-rk30/rk30_dvfs.c\r
+ *\r
+ * Copyright (C) 2012 ROCKCHIP, Inc.\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ */\r
+\r
+#include <linux/kernel.h>\r
+#include <linux/err.h>\r
+#include <linux/spinlock.h>\r
+#include <linux/list.h>\r
+#include <linux/slab.h>\r
+#include <linux/clk.h>\r
+#include <linux/cpufreq.h>\r
+#include <mach/dvfs.h>\r
+#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
+static int rk_dvfs_clk_notifier_event(struct notifier_block *this,\r
+               unsigned long event, void *ptr)\r
+{\r
+       struct clk_notifier_data *noti_info;\r
+       struct clk *clk;\r
+       struct clk_node *dvfs_clk;\r
+       noti_info = (struct clk_notifier_data *)ptr;\r
+       clk = noti_info->clk;\r
+       dvfs_clk = clk->dvfs_info;\r
+\r
+       switch (event) {\r
+               case CLK_PRE_RATE_CHANGE:\r
+                       DVFS_DBG("%s CLK_PRE_RATE_CHANGE\n", __func__);\r
+                       break;\r
+               case CLK_POST_RATE_CHANGE:\r
+                       DVFS_DBG("%s CLK_POST_RATE_CHANGE\n", __func__);\r
+                       break;\r
+               case CLK_ABORT_RATE_CHANGE:\r
+                       DVFS_DBG("%s CLK_ABORT_RATE_CHANGE\n", __func__);\r
+                       break;\r
+               case CLK_PRE_ENABLE:\r
+                       DVFS_DBG("%s CLK_PRE_ENABLE\n", __func__);\r
+                       break;\r
+               case CLK_POST_ENABLE:\r
+                       DVFS_DBG("%s CLK_POST_ENABLE\n", __func__);\r
+                       break;\r
+               case CLK_ABORT_ENABLE:\r
+                       DVFS_DBG("%s CLK_ABORT_ENABLE\n", __func__);\r
+                       break;\r
+               case CLK_PRE_DISABLE:\r
+                       DVFS_DBG("%s CLK_PRE_DISABLE\n", __func__);\r
+                       break;\r
+               case CLK_POST_DISABLE:\r
+                       DVFS_DBG("%s CLK_POST_DISABLE\n", __func__);\r
+                       dvfs_clk->set_freq = 0;\r
+                       break;\r
+               case CLK_ABORT_DISABLE:\r
+                       DVFS_DBG("%s CLK_ABORT_DISABLE\n", __func__);\r
+\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static struct notifier_block rk_dvfs_clk_notifier = {\r
+       .notifier_call = rk_dvfs_clk_notifier_event,\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
+#else\r
+static int g_arm_high_logic = 150 * 1000;\r
+static int g_logic_high_arm = 100 * 1000;\r
+#endif\r
+\r
+\r
+#ifdef CONFIG_ARCH_RK3188\r
+static struct cpufreq_frequency_table arm_high_logic_table[] = {\r
+        {.frequency = 1416 * DVFS_KHZ, .index = 25 * DVFS_MV},\r
+        {.frequency = 1608 * DVFS_KHZ, .index = 25 * DVFS_MV},\r
+        {.frequency = CPUFREQ_TABLE_END},\r
+};\r
+\r
+static struct cpufreq_frequency_table logic_high_arm_table[] = {\r
+        {.frequency = 1008 * DVFS_KHZ, .index = 150 * DVFS_MV},\r
+        {.frequency = 1608 * DVFS_KHZ, .index = 75 * DVFS_MV},\r
+        {.frequency = CPUFREQ_TABLE_END},\r
+};\r
+#else\r
+static struct cpufreq_frequency_table arm_high_logic_table[] = {\r
+        {.frequency = 1416 * DVFS_KHZ, .index = 50 * DVFS_MV},\r
+        {.frequency = 1608 * DVFS_KHZ, .index = 100 * DVFS_MV},\r
+        {.frequency = CPUFREQ_TABLE_END},\r
+};\r
+static struct cpufreq_frequency_table logic_high_arm_table[] = {\r
+        {.frequency = 816 * DVFS_KHZ,  .index = 200 * DVFS_MV},\r
+        {.frequency = 1416 * DVFS_KHZ, .index = 150 * DVFS_MV},\r
+        {.frequency = 1608 * DVFS_KHZ, .index = 100 * DVFS_MV},\r
+};\r
+#endif\r
+\r
+\r
+int get_arm_logic_limit(unsigned long arm_rate, int *arm_high_logic, int *logic_high_arm)\r
+{\r
+       int i;\r
+\r
+       for (i = 0; arm_high_logic_table[i].frequency != CPUFREQ_TABLE_END; i++) {\r
+               if (arm_rate <= arm_high_logic_table[i].frequency) {\r
+                       *arm_high_logic = arm_high_logic_table[i].index;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       if (arm_high_logic_table[i].frequency == CPUFREQ_TABLE_END) {\r
+               *arm_high_logic = arm_high_logic_table[i-1].index;\r
+       }\r
+\r
+       for (i = 0; logic_high_arm_table[i].frequency != CPUFREQ_TABLE_END; i++) {\r
+               if (arm_rate <= logic_high_arm_table[i].frequency) {\r
+                       *logic_high_arm = logic_high_arm_table[i].index;\r
+                       break;\r
+               }\r
+       }\r
+       if (logic_high_arm_table[i].frequency == CPUFREQ_TABLE_END)\r
+               *logic_high_arm = logic_high_arm_table[i-1].index;\r
+\r
+       return 0;\r
+}\r
+\r
+static struct clk_node *dvfs_clk_cpu;\r
+static struct vd_node vd_core;\r
+int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)\r
+{\r
+       struct clk_node *dvfs_clk;\r
+       int volt_new = 0, volt_dep_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
+       int cur_arm_high_logic, cur_logic_high_arm;\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
+\r
+       /* if up the rate */\r
+       if (rate_new > rate_old) {\r
+               if (!list_empty(&dvfs_clk->depend_list)) {\r
+                       // update depend's req_volt\r
+                       ret = dvfs_get_depend_volt(dvfs_clk, &vd_core, rate_new);\r
+                       if (ret <= 0)\r
+                               goto fail_roll_back;\r
+               }\r
+               volt_dep_new = dvfs_vd_get_newvolt_bypd(&vd_core);\r
+               if (volt_dep_new <= 0)\r
+                       goto fail_roll_back;\r
+\r
+               cur_arm_high_logic = g_arm_high_logic;\r
+               cur_logic_high_arm = g_logic_high_arm;\r
+\r
+#ifdef CONFIG_ARCH_RK3188\r
+               get_arm_logic_limit(rate_new / 1000, &g_arm_high_logic, &g_logic_high_arm);\r
+#endif\r
+\r
+               ret = dvfs_scale_volt_bystep(dvfs_clk->vd, &vd_core, volt_new, volt_dep_new,\r
+                               cur_arm_high_logic, cur_logic_high_arm, g_arm_high_logic, g_logic_high_arm);\r
+               if (ret < 0)\r
+                       goto fail_roll_back;\r
+\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
+               if (!list_empty(&dvfs_clk->depend_list)) {\r
+                       // update depend's req_volt\r
+                       ret = dvfs_get_depend_volt(dvfs_clk, &vd_core, rate_new);\r
+                       if (ret <= 0)\r
+                               goto out;\r
+               }\r
+\r
+               volt_dep_new = dvfs_vd_get_newvolt_bypd(&vd_core);\r
+               if (volt_dep_new <= 0)\r
+                       goto out;\r
+\r
+#ifdef CONFIG_ARCH_RK3188\r
+               get_arm_logic_limit(rate_new / 1000, &g_arm_high_logic, &g_logic_high_arm);\r
+#endif\r
+               cur_arm_high_logic = g_arm_high_logic;\r
+               cur_logic_high_arm = g_logic_high_arm;\r
+\r
+               ret = dvfs_scale_volt_bystep(dvfs_clk->vd, &vd_core, volt_new, volt_dep_new,\r
+                               cur_arm_high_logic, cur_logic_high_arm, g_arm_high_logic, g_logic_high_arm);\r
+               if (ret < 0)\r
+                       goto out;\r
+\r
+       }\r
+\r
+       return ret;\r
+fail_roll_back:\r
+       dvfs_clk->set_volt = clk_volt_store;\r
+       ret = dvfs_get_depend_volt(dvfs_clk, &vd_core, rate_old);\r
+       if (ret <= 0) {\r
+               DVFS_ERR("%s dvfs_get_depend_volt error when roll back!\n", __func__);\r
+       }\r
+out:\r
+       return -1;\r
+}\r
+\r
+int dvfs_target_core(struct clk *clk, unsigned long rate_hz)\r
+{\r
+       struct clk_node *dvfs_clk;\r
+       int volt_new = 0, volt_dep_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
+       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
+\r
+       /* if up the rate */\r
+       if (rate_new > rate_old) {\r
+               DVFS_DBG("-----------------------------rate_new > rate_old\n");\r
+               volt_dep_new = dvfs_vd_get_newvolt_byclk(dvfs_clk_cpu);\r
+\r
+               if (volt_dep_new < 0)\r
+                       goto fail_roll_back;\r
+               ret = dvfs_scale_volt_bystep(dvfs_clk->vd, dvfs_clk_cpu->vd, volt_new, volt_dep_new,\r
+                               g_logic_high_arm, g_arm_high_logic, g_logic_high_arm, g_arm_high_logic);\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
+               DVFS_DBG("-----------------------------rate_new < rate_old\n");\r
+               volt_dep_new = dvfs_vd_get_newvolt_byclk(dvfs_clk_cpu);\r
+\r
+               if (volt_dep_new < 0)\r
+                       goto out;\r
+               ret = dvfs_scale_volt_bystep(dvfs_clk->vd, dvfs_clk_cpu->vd, volt_new, volt_dep_new,\r
+                               g_logic_high_arm, g_arm_high_logic, g_logic_high_arm, g_arm_high_logic);\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
+       ret = dvfs_get_depend_volt(dvfs_clk, &vd_core, rate_old);\r
+       if (ret <= 0) {\r
+               DVFS_ERR("%s dvfs_get_depend_volt error when roll back!\n", __func__);\r
+       }\r
+\r
+out:\r
+       return -1;\r
+}\r
+\r
+/*****************************init**************************/\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  = 252 * DVFS_KHZ, .index        = 1040 * 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 = 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 = 500 * DVFS_KHZ, .index = 1150 * DVFS_MV},\r
+       {.frequency = 600 * DVFS_KHZ, .index = 1200 * DVFS_MV},\r
+       {.frequency = CPUFREQ_TABLE_END},\r
+};\r
+\r
+static struct cpufreq_frequency_table gpu_dvfs_table[] = {\r
+       {.frequency = 90 * DVFS_KHZ, .index = 1100 * DVFS_MV},\r
+       {.frequency = 180 * DVFS_KHZ, .index = 1150 * DVFS_MV},\r
+       {.frequency = 300 * DVFS_KHZ, .index = 1100 * DVFS_MV},\r
+       {.frequency = 400 * DVFS_KHZ, .index = 1150 * DVFS_MV},\r
+       {.frequency = 500 * DVFS_KHZ, .index = 1200 * DVFS_MV},\r
+       {.frequency = CPUFREQ_TABLE_END},\r
+};\r
+\r
+static struct cpufreq_frequency_table peri_aclk_dvfs_table[] = {\r
+       {.frequency = 100 * DVFS_KHZ, .index = 1000 * DVFS_MV},\r
+       {.frequency = 200 * DVFS_KHZ, .index = 1050 * DVFS_MV},\r
+       {.frequency = 300 * DVFS_KHZ, .index = 1070 * DVFS_MV},\r
+       {.frequency = 500 * 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
+       .volt_set_flag          = DVFS_SET_VOLT_FAILURE,\r
+       .vd_dvfs_target = dvfs_target_cpu,\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
+       .vd_dvfs_target = dvfs_target_core,\r
+};\r
+\r
+static struct vd_node vd_rtc = {\r
+       .name           = "vd_rtc",\r
+       .regulator_name = "vdd_rtc",\r
+       .volt_set_flag          = DVFS_SET_VOLT_FAILURE,\r
+       .vd_dvfs_target = NULL,\r
+};\r
+\r
+static struct vd_node *rk30_vds[] = {&vd_cpu, &vd_core, &vd_rtc};\r
+\r
+static struct pd_node pd_a9_0 = {\r
+       .name                   = "pd_a9_0",\r
+       .vd                     = &vd_cpu,\r
+};\r
+static struct pd_node pd_a9_1 = {\r
+       .name                   = "pd_a9_1",\r
+       .vd                     = &vd_cpu,\r
+};\r
+static struct pd_node pd_a9_2 = {\r
+       .name                   = "pd_a9_2",\r
+       .vd                     = &vd_cpu,\r
+};\r
+static struct pd_node pd_a9_3 = {\r
+       .name                   = "pd_a9_3",\r
+       .vd                     = &vd_cpu,\r
+};\r
+\r
+static struct pd_node pd_debug = {\r
+       .name                   = "pd_debug",\r
+       .vd                     = &vd_cpu,\r
+};\r
+static struct pd_node pd_scu = {\r
+       .name                   = "pd_scu",\r
+       .vd                     = &vd_cpu,\r
+};\r
+static struct pd_node pd_video = {\r
+       .name                   = "pd_video",\r
+       .vd                     = &vd_core,\r
+};\r
+static struct pd_node pd_vio = {\r
+       .name                   = "pd_vio",\r
+       .vd                     = &vd_core,\r
+};\r
+static struct pd_node pd_gpu = {\r
+       .name                   = "pd_gpu",\r
+       .vd                     = &vd_core,\r
+};\r
+static struct pd_node pd_peri = {\r
+       .name                   = "pd_peri",\r
+       .vd                     = &vd_core,\r
+};\r
+static struct pd_node pd_cpu = {\r
+       .name                   = "pd_cpu",\r
+       .vd                     = &vd_core,\r
+};\r
+static struct pd_node pd_alive = {\r
+       .name                   = "pd_alive",\r
+       .vd                     = &vd_core,\r
+};\r
+static struct pd_node pd_rtc = {\r
+       .name                   = "pd_rtc",\r
+       .vd                     = &vd_rtc,\r
+};\r
+#define LOOKUP_PD(_ppd)        \\r
+{      \\r
+       .pd     = _ppd, \\r
+}\r
+static struct pd_node_lookup rk30_pds[] = {\r
+       LOOKUP_PD(&pd_a9_0),\r
+       LOOKUP_PD(&pd_a9_1),\r
+       LOOKUP_PD(&pd_a9_2),\r
+       LOOKUP_PD(&pd_a9_3),\r
+       LOOKUP_PD(&pd_debug),\r
+       LOOKUP_PD(&pd_scu),\r
+       LOOKUP_PD(&pd_video),\r
+       LOOKUP_PD(&pd_vio),\r
+       LOOKUP_PD(&pd_gpu),\r
+       LOOKUP_PD(&pd_peri),\r
+       LOOKUP_PD(&pd_cpu),\r
+       LOOKUP_PD(&pd_alive),\r
+       LOOKUP_PD(&pd_rtc),\r
+};\r
+\r
+#define CLK_PDS(_ppd) \\r
+{      \\r
+       .pd     = _ppd, \\r
+}\r
+\r
+static struct pds_list cpu_pds[] = {\r
+       CLK_PDS(&pd_a9_0),\r
+       CLK_PDS(&pd_a9_1),\r
+       CLK_PDS(&pd_a9_2),\r
+       CLK_PDS(&pd_a9_3),\r
+       CLK_PDS(NULL),\r
+};\r
+\r
+static struct pds_list ddr_pds[] = {\r
+       CLK_PDS(&pd_cpu),\r
+       CLK_PDS(NULL),\r
+};\r
+\r
+static struct pds_list gpu_pds[] = {\r
+       CLK_PDS(&pd_gpu),\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
+       .pds = _ppds,\\r
+       .dvfs_table = _dvfs_table,      \\r
+       .dvfs_nb        = _dvfs_nb,     \\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("gpu", gpu_pds, gpu_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
+#if 0\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
+#ifndef CONFIG_ARCH_RK3188\r
+       RK_DEPPENDS("cpu", &vd_core, dep_cpu2core_table),\r
+#endif\r
+       //RK_DEPPENDS("gpu", &vd_cpu, NULL),\r
+       //RK_DEPPENDS("gpu", &vd_cpu, NULL),\r
+};\r
+#endif\r
+//static struct avs_ctr_st rk30_avs_ctr;\r
+\r
+int rk3188_dvfs_init(void)\r
+{\r
+       int i = 0;\r
+       for (i = 0; i < ARRAY_SIZE(rk30_vds); i++) {\r
+               rk_regist_vd(rk30_vds[i]);\r
+       }\r
+       for (i = 0; i < ARRAY_SIZE(rk30_pds); i++) {\r
+               rk_regist_pd(&rk30_pds[i]);\r
+       }\r
+       for (i = 0; i < ARRAY_SIZE(rk30_clks); i++) {\r
+               rk_regist_clk(&rk30_clks[i]);\r
+       }\r
+       #if 0\r
+       for (i = 0; i < ARRAY_SIZE(rk30_depends); i++) {\r
+               rk_regist_depends(&rk30_depends[i]);\r
+       }\r
+       #endif\r
+       dvfs_clk_cpu = dvfs_get_dvfs_clk_byname("cpu");\r
+       //avs_board_init(&rk30_avs_ctr);\r
+       return 0;\r
+}\r
+\r
+\r
+\r
+/******************************rk30 avs**************************************************/\r
+\r
+#if 0\r
+\r
+static void __iomem *rk30_nandc_base=NULL;\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
+static 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
+       if(rk30_nandc_base==NULL)       \r
+               return 0;\r
+               \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(3, 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
+\r
+void rk30_avs_init(void)\r
+{\r
+       rk30_nandc_base = ioremap(RK30_NANDC_PHYS, RK30_NANDC_SIZE);\r
+}\r
+static struct avs_ctr_st rk30_avs_ctr= {\r
+       .avs_init               =rk30_avs_init,\r
+       .avs_get_val    = rk30_get_avs_val,\r
+};\r
+#endif\r
+\r
+\r