rk30: add cpufreq support
authorxxx <xxx@rock-chips.com>
Mon, 2 Apr 2012 10:13:18 +0000 (03:13 -0700)
committerxxx <xxx@rock-chips.com>
Mon, 2 Apr 2012 10:13:18 +0000 (03:13 -0700)
arch/arm/mach-rk30/Makefile
arch/arm/mach-rk30/clock.c
arch/arm/mach-rk30/clock.h [changed mode: 0644->0755]
arch/arm/mach-rk30/clock_data.c
arch/arm/mach-rk30/dvfs.c [changed mode: 0644->0755]
arch/arm/mach-rk30/include/mach/dvfs.h [changed mode: 0644->0755]
arch/arm/plat-rk/Kconfig

index 1f2133674bd22f82b20d26409939dda3f01e1da9..21cc5ec149865703389a2361fcc1ea4aa4970e9a 100755 (executable)
@@ -3,7 +3,6 @@ obj-y += clock_data.o
 obj-y += common.o
 obj-y += ddr.o
 obj-y += devices.o
-obj-y += dvfs.o
 obj-y += io.o
 obj-y += iomux.o
 obj-y += pmu.o
@@ -16,6 +15,8 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
 obj-$(CONFIG_PM) += pm.o
 obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_DVFS) += dvfs.o
 
 obj-$(CONFIG_MACH_RK30_SDK) += board-rk30-sdk.o board-rk30-sdk-key.o board-rk30-sdk-rfkill.o
 obj-$(CONFIG_MACH_RK30_PHONE) += board-rk30-phone.o board-rk30-phone-key.o board-rk30-phone-rfkill.o
index 78b3fa8230bf2c233557844ed11406e4dd2b80ec..bf68a8bbcde6b8ac72c977beb4a7b8ee5d609ab4 100755 (executable)
@@ -162,7 +162,7 @@ static void __clk_reparent(struct clk *child, struct clk *parent)
 {
        if (child->parent == parent)
                return;
-       CLOCK_PRINTK_DBG("%s reparent to %s (was %s)\n", child->name, parent->name, ((child->parent) ? child->parent->name : "NULL"));
+       //CLOCK_PRINTK_DBG("%s reparent to %s (was %s)\n", child->name, parent->name, ((child->parent) ? child->parent->name : "NULL"));
 
        list_del_init(&child->sibling);
        if (parent)
@@ -267,7 +267,7 @@ int clk_set_rate_nolock(struct clk *clk, unsigned long rate)
 
        if (ret == 0) {
                __clk_recalc(clk);
-               //CLOCK_PRINTK_LOG("**set %s rate recalc=%lu\n",clk->name,clk->rate);
+               CLOCK_PRINTK_LOG("**set %s rate recalc=%lu\n",clk->name,clk->rate);
                __propagate_rate(clk);
        }
 
old mode 100644 (file)
new mode 100755 (executable)
index 254963453765c67d7ee98c227f76b7c871ea1e57..b127b02d48473bc4d1711c1c41bc56c517238da7 100755 (executable)
@@ -165,7 +165,7 @@ void rk30_clkdev_add(struct clk_lookup *cl);
 #endif
 
 
-#define CRU_PRINTK_DBG(fmt, args...) pr_debug(fmt, ## args);
+#define CRU_PRINTK_DBG(fmt, args...) {while(0);}//pr_debug(fmt, ## args);
 #define CRU_PRINTK_ERR(fmt, args...) pr_err(fmt, ## args);
 #define CRU_PRINTK_LOG(fmt, args...) pr_debug(fmt, ## args);
 
@@ -491,7 +491,7 @@ static void pll_wait_lock(int pll_idx)
 {
        u32 pll_state[4]={1,0,2,3};
        u32 bit = 0x10u << pll_state[pll_idx];
-       int delay = 2400000;
+       int delay = 24000000;
        while (delay > 0) {
                if (regfile_readl(GRF_SOC_STATUS0) & bit)
                        break;
@@ -499,6 +499,7 @@ static void pll_wait_lock(int pll_idx)
        }
        if (delay == 0) {
                CRU_PRINTK_ERR("wait pll bit 0x%x time out!\n", bit);
+               while(1);
        }
 }
 
@@ -773,6 +774,43 @@ static long arm_pll_clk_round_rate(struct clk *clk, unsigned long rate)
 {
        return arm_pll_clk_get_best_pll_set(rate,clk->pll->table)->rate;
 }
+#if 1
+struct arm_clks_div_set {
+       u32 rate;
+       u32     clksel0;
+       u32     clksel1;
+};
+
+#define _arm_clks_div_set(_mhz,_periph_div,_axi_div,_ahb_div, _apb_div,_ahb2apb) \
+       { \
+       .rate    =_mhz,\
+       .clksel0 = CORE_PERIPH_W_MSK|CORE_PERIPH_##_periph_div,\
+       .clksel1 = CORE_ACLK_W_MSK|CORE_ACLK_##_axi_div\
+       |ACLK_HCLK_W_MSK|ACLK_HCLK_##_ahb_div\
+       |ACLK_PCLK_W_MSK|ACLK_PCLK_##_apb_div\
+       |AHB2APB_W_MSK  |AHB2APB_##_ahb2apb,\
+}
+struct arm_clks_div_set arm_clk_div_tlb[]={
+       _arm_clks_div_set(50 ,  2, 11, 11, 11, 11),//25,50,50,50,50
+       _arm_clks_div_set(100 , 4, 11, 21, 21, 11),//25,100,50,50,50
+       _arm_clks_div_set(150 , 4, 11, 21, 21, 11),//37,150,75,75,75
+       _arm_clks_div_set(200 , 8, 21, 21, 21, 11),//25,100,50,50,50
+       _arm_clks_div_set(300 , 8, 21, 21, 11, 11),//37,150,75,75,75
+       _arm_clks_div_set(400 , 8, 21, 21, 41, 21),//50,200,100,50,50
+       _arm_clks_div_set(0 ,   2, 11, 11, 11, 11),//25,50,50,50,50
+};
+struct arm_clks_div_set * arm_clks_get_div(u32 rate)
+{
+       int i=0;
+       for(i=0;arm_clk_div_tlb[i].rate!=0;i++)
+       {
+               if(arm_clk_div_tlb[i].rate>=rate)
+                       return &arm_clk_div_tlb[i];             
+       }
+       return NULL;
+}
+
+#endif
 
 static int arm_pll_clk_set_rate(struct clk *clk, unsigned long rate)
 {
@@ -780,7 +818,9 @@ static int arm_pll_clk_set_rate(struct clk *clk, unsigned long rate)
        const struct apll_clk_set *ps;
        u32 pll_id=clk->pll->id;
        u32 temp_div;
-       u32 old_aclk_div=0,new_aclk_div;
+       u32 old_aclk_div=0,new_aclk_div,gpll_arm_aclk_div;
+       struct arm_clks_div_set *temp_clk_div;
+       unsigned long arm_gpll_rate;
 
        ps = arm_pll_clk_get_best_pll_set(rate,(struct apll_clk_set *)clk->pll->table);
 
@@ -790,21 +830,54 @@ static int arm_pll_clk_set_rate(struct clk *clk, unsigned long rate)
        CRU_PRINTK_LOG("apll will set rate(%lu) tlb con(%x,%x,%x),sel(%x,%x)\n",
                ps->rate,ps->pllcon0,ps->pllcon1,ps->pllcon2,ps->clksel0,ps->clksel1);  
 
+       //rk30_l2_cache_latency(ps->rate/MHZ);
+
        if(general_pll_clk.rate>clk->rate)
        {
                temp_div=clk_get_freediv(clk->rate,general_pll_clk.rate,10);
-               cru_writel(CORE_CLK_DIV(temp_div)|CORE_CLK_DIV_W_MSK, CRU_CLKSELS_CON(0));
        }
-
+       else
+       {
+               temp_div=1;
+       }       
+       //sel gpll
+       //cru_writel(CORE_CLK_DIV(temp_div)|CORE_CLK_DIV_W_MSK, CRU_CLKSELS_CON(0));
+       
+       arm_gpll_rate=general_pll_clk.rate/temp_div;
+       temp_clk_div=arm_clks_get_div(arm_gpll_rate/MHZ);
+       if(!temp_clk_div)
+               temp_clk_div=&arm_clk_div_tlb[4];
+       
+       gpll_arm_aclk_div=GET_CORE_ACLK_VAL(temp_clk_div->clksel1&CORE_ACLK_MSK);
+       
+       CRU_PRINTK_LOG("gpll_arm_rate=%lu,sel rate%u,sel0%x,sel1%x\n",arm_gpll_rate,temp_clk_div->rate,
+                                       temp_clk_div->clksel0,temp_clk_div->clksel1);
+       
+       local_irq_save(flags);
 
        // open gpu gpll path
-       cru_writel(CLK_GATE_W_MSK(CLK_GATE_CPU_GPLL_PATH)|CLK_UN_GATE(CLK_GATE_CPU_GPLL_PATH)
-               , CLK_GATE_CLKID_CONS(CLK_GATE_CPU_GPLL_PATH));
-       local_irq_save(flags);
+       cru_writel(CLK_GATE_W_MSK(CLK_GATE_CPU_GPLL_PATH)|CLK_UN_GATE(CLK_GATE_CPU_GPLL_PATH),CLK_GATE_CLKID_CONS(CLK_GATE_CPU_GPLL_PATH));
+       
        cru_writel(CORE_SEL_GPLL|CORE_SEL_PLL_W_MSK, CRU_CLKSELS_CON(0));
-       loops_per_jiffy = lpj_gpll;
+       
+       loops_per_jiffy = lpj_gpll/temp_div;
 
        
+       if((old_aclk_div==3||gpll_arm_aclk_div==3)&&(gpll_arm_aclk_div!=old_aclk_div))
+       {       
+               cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON);
+               cru_writel((temp_clk_div->clksel1), CRU_CLKSELS_CON(1));
+               cru_writel((temp_clk_div->clksel0|CORE_CLK_DIV(temp_div)|CORE_CLK_DIV_W_MSK), 
+                                                                                       CRU_CLKSELS_CON(0));
+               cru_writel(PLL_MODE_NORM(APLL_ID), CRU_MODE_CON);
+       }
+       else 
+       {
+               cru_writel((temp_clk_div->clksel1), CRU_CLKSELS_CON(1));
+               cru_writel((temp_clk_div->clksel0)|CORE_CLK_DIV(temp_div)|CORE_CLK_DIV_W_MSK, 
+                                                                       CRU_CLKSELS_CON(0));
+       }
+
        /*if core src don't select gpll ,apll neet to enter slow mode */
        //cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON);
 
@@ -814,30 +887,27 @@ static int arm_pll_clk_set_rate(struct clk *clk, unsigned long rate)
        cru_writel(ps->pllcon1, PLL_CONS(pll_id,1));
        cru_writel(ps->pllcon2, PLL_CONS(pll_id,2));
 
-       local_irq_restore(flags);
        rk30_clock_udelay(5);
 
        //return form rest
        cru_writel(PLL_REST_W_MSK|PLL_REST_RESM, PLL_CONS(pll_id,3));
 
        //wating lock state
-       rk30_clock_udelay(ps->rst_dly);
+       ///rk30_clock_udelay(ps->rst_dly);//lcdc flash
+       
        pll_wait_lock(pll_id);
 
-       local_irq_save(flags);
-       
        //return form slow
        //cru_writel(PLL_MODE_NORM(APLL_ID), CRU_MODE_CON);
-
        //a/h/p clk sel
-       if((old_aclk_div==3||new_aclk_div==3)&&(new_aclk_div!=old_aclk_div))
+       if((gpll_arm_aclk_div==3||new_aclk_div==3)&&(new_aclk_div!=gpll_arm_aclk_div))
        {       
                cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON);
                cru_writel((ps->clksel1), CRU_CLKSELS_CON(1));
                cru_writel((ps->clksel0)|CORE_CLK_DIV(1)|CORE_CLK_DIV_W_MSK, CRU_CLKSELS_CON(0));
                cru_writel(PLL_MODE_NORM(APLL_ID), CRU_MODE_CON);
        }
-       else
+       else 
        {
                cru_writel((ps->clksel1), CRU_CLKSELS_CON(1));
                cru_writel((ps->clksel0)|CORE_CLK_DIV(1)|CORE_CLK_DIV_W_MSK, CRU_CLKSELS_CON(0));
@@ -866,16 +936,34 @@ static int arm_pll_clk_set_rate(struct clk *clk, unsigned long rate)
 
 static const struct apll_clk_set apll_clks[] = {
        //rate, nr ,nf ,no,core_div,peri,axi,hclk,pclk,_ahb2apb
-       _APLL_SET_CLKS(1416, 1, 59, 1, 8, 31, 21, 81, 41),
-       _APLL_SET_CLKS(1200, 1, 50, 1, 8, 31, 21, 81, 41),
-       _APLL_SET_CLKS(1008, 1, 42, 1, 8, 31, 21, 81, 41),
-       _APLL_SET_CLKS(816 , 1, 34, 1, 8, 21, 21, 81, 41),
-       _APLL_SET_CLKS(504 , 1, 21, 1, 4, 21, 21, 81, 41),
-       _APLL_SET_CLKS(252 , 1, 21, 2, 2, 21, 21, 41, 21),
+       //_APLL_SET_CLKS(1800, 1, 75, 1, 8, 31, 41, 81),
+       //_APLL_SET_CLKS(1752, 1, 73, 1, 8, 31, 41, 81),
+       //_APLL_SET_CLKS(1704, 1, 71, 1, 8, 31, 41, 81),
+       //_APLL_SET_CLKS(1656, 1, 69, 1, 8, 31, 41, 81),
+       _APLL_SET_CLKS(1608, 1, 67, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1560, 1, 65, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1512, 1, 63, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1464, 1, 61, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1416, 1, 59, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1368, 1, 57, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1272, 1, 53, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1200, 1, 50, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1176, 1, 49, 1, 8, 41, 21, 41, 21),
+       _APLL_SET_CLKS(1008, 1, 42, 1, 8, 31, 21, 41, 21),
+       _APLL_SET_CLKS(888,  1, 37, 1, 8, 31, 21, 41, 21),
+       _APLL_SET_CLKS(816 , 1, 34, 1, 8, 31, 21, 41, 21),
+       _APLL_SET_CLKS(792 , 1, 33, 1, 8, 31, 21, 41, 21),
+       _APLL_SET_CLKS(696 , 1, 29, 1, 8, 31, 21, 41, 21),
+       _APLL_SET_CLKS(600 , 1, 25, 1, 4, 31, 21, 41, 21),
+       _APLL_SET_CLKS(504 , 1, 21, 1, 4, 21, 21, 41, 21),
+       _APLL_SET_CLKS(408 , 1, 17, 1, 4, 21, 21, 41, 21),
+       _APLL_SET_CLKS(312 , 1, 13, 1, 2, 21, 21, 21, 21),
+       _APLL_SET_CLKS(252 , 1, 21, 2, 2, 21, 21, 21, 21),
+       _APLL_SET_CLKS(216 , 1, 18, 2, 2, 21, 21, 21, 21),
        _APLL_SET_CLKS(126 , 1, 21, 4, 2, 21, 11, 11, 11),
-       //_APLL_SET_CLKS(63  , 1, 21, 8, 2, 11, 11, 11, 11),
-       //_APLL_SET_CLKS(48  , 1, 16, 8, 2, 11, 11, 11, 11),
-       _APLL_SET_CLKS(0   , 1, 21, 4, 2, 21, 21, 41, 11),
+       _APLL_SET_CLKS(48  , 1, 16, 8, 2, 11, 11, 11, 11),
+       _APLL_SET_CLKS(0   , 1, 21, 4, 2, 21, 21, 41, 21),
+
 };
 static struct _pll_data apll_data=SET_PLL_DATA(APLL_ID,(void *)apll_clks);
 static struct clk arm_pll_clk ={
@@ -1789,9 +1877,10 @@ static int clksel_set_rate_hdmi(struct clk *clk, unsigned long rate)
        u32 div;
        div=clk_get_freediv(rate,clk->parent->rate,clk->div_max);
        if(rate==(clk->parent->rate/div)&&!(clk->parent->rate%div))
-               return 0;
-       set_cru_bits_w_msk(div-1,clk->div_mask,clk->div_shift,clk->clksel_con);
-       return -ENOENT;
+               set_cru_bits_w_msk(div-1,clk->div_mask,clk->div_shift,clk->clksel_con);
+       else
+               return -ENOENT;
+       return 0;
 }
 //hdmi
 static struct clk dclk_lcdc1_div = {
@@ -1857,7 +1946,6 @@ static struct clk dclk_lcdc1 = {
        CRU_PARENTS_SET(dclk_lcdc1_parents),
 };
 
-
 static struct clk *cifout_sel_pll_parents[2]={&codec_pll_clk,&general_pll_clk};
 static struct clk cif_out_pll = {
        .name           = "cif_out_pll",
@@ -2819,7 +2907,7 @@ struct clk_dump_ops dump_ops;
 
 static void clk_dump_regs(void);
 
-void __init rk30_clock_data_init(unsigned long gpll,unsigned long cpll,unsigned long max_i2s_rate)
+void __init _rk30_clock_data_init(unsigned long gpll,unsigned long cpll,unsigned long max_i2s_rate)
 {
        struct clk_lookup *lk;
        
@@ -2856,7 +2944,12 @@ void __init rk30_clock_data_init(unsigned long gpll,unsigned long cpll,unsigned
        //cru_writel(0x07000000,CRU_MISC_CON);
        
 }
-extern int rk30_dvfs_init(void);
+
+void __init rk30_clock_data_init(unsigned long gpll,unsigned long cpll,unsigned long max_i2s_rate)
+{
+       _rk30_clock_data_init(gpll,cpll,max_i2s_rate);
+       rk30_dvfs_init();
+}
 
 /*
  * You can override arm_clk rate with armclk= cmdline option.
old mode 100644 (file)
new mode 100755 (executable)
index 6283fda..f2a2492
 #include <linux/slab.h>\r
 #include <linux/clk.h>\r
 #include <linux/cpufreq.h>\r
-\r
 #include "clock.h"\r
 #include <mach/dvfs.h>\r
 #include <mach/clock.h>\r
+#include <linux/regulator/consumer.h>\r
+#include <linux/delay.h>\r
 \r
-#if 0\r
-#define DVFS_DBG(fmt, args...) pr_debug(fmt, ##args)\r
+#define DVFS_DBG(fmt, args...) {while(0);}//pr_debug(fmt, ##args)\r
 #define DVFS_ERR(fmt, args...) pr_err(fmt, ##args)\r
-#else\r
-#define DEBUG_RK30_DVFS\r
-#define DVFS_DBG(fmt, args...) printk(fmt, ##args)\r
-#define DVFS_ERR(fmt, args...) printk(fmt, ##args)\r
-#endif\r
-\r
-#ifndef CONFIG_ARCH_RK30\r
-#define DVFS_TEST_OFF_BOARD\r
-#endif\r
-\r
-\r
-\r
-#ifdef DVFS_TEST_OFF_BOARD\r
-/* Just for simulation */\r
-\r
-struct regulator {\r
-    int min_uV;\r
-};\r
-#if 0\r
-static void test_regulator_put(struct regulator *regulator)\r
-{\r
-    kfree(regulator);\r
-}\r
-#endif\r
-struct regulator regulators[100];\r
-static struct regulator *test_regulator_get(struct device *dev, const char *id) {\r
-    static int ret_cnt = 0;\r
-    return &regulators[ret_cnt++];\r
-}\r
-\r
-static int test_regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)\r
-{\r
-    regulator->min_uV = min_uV;\r
-    return 0;\r
-}\r
-\r
-static int test_regulator_get_voltage(struct regulator *regulator)\r
-{\r
-    return regulator->min_uV;\r
-}\r
-\r
-int rk30_clk_set_rate(struct clk *clk, unsigned long rate);\r
-static void dump_dbg_map(void);\r
-int rk30_dvfs_init_test(void);\r
-int rk30_clk_enable(struct clk *clk);\r
-int rk30_clk_disable(struct clk *clk);\r
-\r
-#define dvfs_regulator_get(dev,id) test_regulator_get((dev),(id))\r
-#define dvfs_regulator_put(regu) test_regulator_get((regu))\r
-#define dvfs_regulator_set_voltage(regu,min_uV,max_uV) test_regulator_set_voltage((regu),(min_uV),(max_uV))\r
-#define dvfs_regulator_get_voltage(regu) test_regulator_get_voltage((regu))\r
-\r
-/* clock */\r
-#define dvfs_clk_get(a,b) rk30_clk_get((a),(b))\r
-#define dvfs_clk_set_rate(a,b) rk30_clk_set_rate((a),(b))\r
-#define dvfs_clk_enable(a) rk30_clk_enable((a))\r
-#define dvfs_clk_disable(a) rk30_clk_disable((a))\r
-\r
-#else\r
-/* board runing */\r
-#include <linux/regulator/consumer.h>\r
+#define DVFS_LOG(fmt, args...) pr_debug(fmt, ##args)//while(0)\r
 \r
 #define dvfs_regulator_get(dev,id) regulator_get((dev),(id))\r
 #define dvfs_regulator_put(regu) regulator_get((regu))\r
@@ -96,81 +36,234 @@ int rk30_clk_disable(struct clk *clk);
 #define dvfs_regulator_get_voltage(regu) regulator_get_voltage((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
 #define dvfs_clk_set_rate(a,b) clk_set_rate((a),(b))\r
 #define dvfs_clk_enable(a) clk_enable((a))\r
 #define dvfs_clk_disable(a) clk_disable((a))\r
-#endif\r
+\r
+#define DVFS_MHZ (1000*1000)\r
+#define DVFS_KHZ (1000)\r
+\r
+#define DVFS_V (1000*1000)\r
+#define DVFS_MV (1000)\r
 \r
 \r
 static LIST_HEAD(rk_dvfs_tree);\r
 static DEFINE_MUTEX(mutex);\r
-/*\r
-int dvfs_target_core(struct clk *clk, unsigned int rate);\r
-int dvfs_target(struct clk *clk, unsigned int rate);\r
-int dvfs_clk_set_rate(struct clk *clk, unsigned long rate);\r
-*/\r
+\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 FV_TABLE_END 0\r
 #define PD_ON  1\r
 #define PD_OFF 0\r
 \r
-\r
-static void dvfs_clk_scale_volt(struct clk_node *dvfs_clk, unsigned int volt);\r
-static int dvfs_clk_get_volt(struct clk_node *dvfs_clk, unsigned long rate,\r
-                             struct cpufreq_frequency_table *clk_fv);\r
-\r
-/**\r
- * **************************FUNCTIONS***********************************\r
- */\r
-\r
-#ifdef DEBUG_RK30_DVFS\r
-/**\r
- * dump_dbg_map() : Draw all informations of dvfs while debug\r
- */\r
-static void dump_dbg_map(void)\r
+int is_support_dvfs(struct clk_node *dvfs_info)\r
 {\r
-    int i;\r
-    struct vd_node     *vd;\r
-    struct pd_node     *pd, *clkparent;\r
-    struct clk_list    *child;\r
-    struct clk_node    *dvfs_clk;\r
-\r
-    DVFS_DBG("-------------DVFS DEBUG-----------\n\n\n");\r
-    DVFS_DBG("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
+    return (dvfs_info->vd && dvfs_info->vd->vd_dvfs_target && dvfs_info->enable_dvfs);\r
+}\r
+int dvfs_set_rate(struct clk *clk, unsigned long rate)\r
+{\r
+    int ret = 0;\r
+    struct vd_node *vd;\r
+       DVFS_DBG("%s(%s(%lu))\n",__func__,clk->name,rate);\r
+    if(!clk->dvfs_info) {\r
+        DVFS_ERR("%s :This clk do not support dvfs!\n", __func__);\r
+        ret = -1;\r
+    } else {\r
+        vd = clk->dvfs_info->vd;\r
+        mutex_lock(&vd->dvfs_mutex);\r
+        ret = vd->vd_dvfs_target(clk, rate);\r
+        mutex_unlock(&vd->dvfs_mutex);\r
+    }\r
+    DVFS_DBG("%s(%s(%lu)),is end\n",__func__,clk->name,rate);\r
+    return ret;\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
-                     pd->name, (pd->pd_status == PD_ON) ? "ON" : "OFF", pd->cur_volt);\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
+        return -1;\r
+    }\r
+    clk_fv->frequency = rate_khz;\r
+    clk_fv->index = 0;\r
+       \r
+    for(i = 0; (dvfs_clk->dvfs_table[i].frequency != CPUFREQ_TABLE_END); i++) {\r
+        if(dvfs_clk->dvfs_table[i].frequency >= rate_khz) {\r
+            clk_fv->frequency = dvfs_clk->dvfs_table[i].frequency;\r
+            clk_fv->index = dvfs_clk->dvfs_table[i].index;\r
+           // DVFS_DBG("%s,%s rate=%ukhz(vol=%d)\n",__func__,dvfs_clk->name, clk_fv->frequency, clk_fv->index);\r
+            return 0;\r
+        }\r
+    }\r
+    clk_fv->frequency = 0;\r
+    clk_fv->index = 0;\r
+   // DVFS_DBG("%s get corresponding voltage error! out of bound\n", dvfs_clk->name);\r
+    return -1;\r
+}\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_clk->name, dvfs_clk->cur_freq, dvfs_clk->cur_volt, 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", clkparent->name, clkparent->vd->name);\r
-                }\r
+static int dvfs_pd_get_newvolt_for_clk(struct pd_node *pd,struct clk_node *dvfs_clk)\r
+{\r
+       struct clk_list *child;\r
+       int volt_max = 0;\r
+       \r
+       if(!pd||!dvfs_clk)\r
+               return 0;\r
+\r
+       if(dvfs_clk->set_volt>=pd->cur_volt)\r
+       {\r
+               return dvfs_clk->set_volt;\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,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
 \r
-                for (i = 0; (dvfs_clk->dvfs_table[i].frequency != FV_TABLE_END); i++) {\r
-                    DVFS_DBG("|  |  |  |- freq = %d, volt = %d\n", dvfs_clk->dvfs_table[i].frequency, dvfs_clk->dvfs_table[i].index);\r
+void dvfs_update_clk_pds_volt(struct clk_node *dvfs_clk)\r
+{\r
+       struct pd_node   *pd;\r
+       int i;\r
+       if(!dvfs_clk)\r
+        return;\r
+       for(i = 0; (dvfs_clk->pds[i].pd != NULL); i++) {\r
+                pd = dvfs_clk->pds[i].pd;\r
+               // DVFS_DBG("%s dvfs(%s),pd(%s)\n",__func__,dvfs_clk->name,pd->name);\r
+                pd->cur_volt=dvfs_pd_get_newvolt_for_clk(pd,dvfs_clk);\r
+       }\r
+}\r
 \r
-                }\r
-            }\r
+static int dvfs_get_vd_volt_bypd(struct vd_node *vd)\r
+{\r
+       struct pd_node *pd;\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
+         volt_max_vd = max(volt_max_vd, pd->cur_volt);\r
+       }\r
+       return volt_max_vd;\r
+}\r
+static int dvfs_vd_get_newvolt_for_clk(struct clk_node *dvfs_clk)\r
+{\r
+       if(!dvfs_clk)\r
+               return -1;\r
+       dvfs_update_clk_pds_volt(dvfs_clk);\r
+       return  dvfs_get_vd_volt_bypd(dvfs_clk->vd);\r
+}\r
+void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target)\r
+{\r
+    struct clk_node *dvfs_clk = clk_get_dvfs_info(clk);\r
+    dvfs_clk->clk_dvfs_target = clk_dvfs_target;\r
+}\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
+\r
+       if(!info||!info->dvfs_table) {\r
+          return NULL;\r
+       }\r
+       mutex_lock(&mutex);\r
+       return info->dvfs_table;\r
+       mutex_unlock(&mutex);\r
+}\r
+int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *table)\r
+{\r
+       struct clk_node *info = clk_get_dvfs_info(clk);\r
+       if(!table || !info)\r
+           return -1;\r
+\r
+       mutex_lock(&mutex);\r
+       info->dvfs_table = table;\r
+       mutex_unlock(&mutex);\r
+       return 0;\r
+}\r
+int clk_enable_dvfs(struct clk *clk)\r
+{\r
+    struct regulator *regulator;\r
+    struct clk_node *dvfs_clk;\r
+       struct cpufreq_frequency_table clk_fv;\r
+       if(!clk){\r
+        DVFS_ERR("clk enable dvfs error\n");\r
+        return -1;\r
+    }  \r
+       dvfs_clk=clk_get_dvfs_info(clk);\r
+    if(!dvfs_clk||!dvfs_clk->vd) {\r
+        DVFS_ERR("%s clk(%s) not support dvfs!\n",__func__,clk->name);\r
+        return -1;\r
+    }\r
+    if(dvfs_clk->enable_dvfs==0){\r
+      \r
+               if(!dvfs_clk->vd->regulator) {\r
+                       regulator=NULL;\r
+                       if(dvfs_clk->vd->regulator_name)\r
+                               regulator = dvfs_regulator_get(NULL,dvfs_clk->vd->regulator_name);\r
+                       if(regulator)\r
+                       {               \r
+                               //DVFS_DBG("dvfs_regulator_get(%s)\n",dvfs_clk->vd->regulator_name);\r
+                               dvfs_clk->vd->regulator = regulator;\r
+                       }\r
+                       else\r
+                       {\r
+                               dvfs_clk->vd->regulator = NULL;\r
+                               dvfs_clk->enable_dvfs=0;\r
+                               DVFS_ERR("%s can't get regulator in %s\n",dvfs_clk->name,__func__);\r
+                               return -1;\r
+                       }       \r
+               }\r
+               else\r
+               {\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
+               }\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
+\r
+               if(dvfs_clk_get_ref_volt(dvfs_clk,dvfs_clk->set_freq,&clk_fv))\r
+               {\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_clk->set_freq,dvfs_clk->set_volt);\r
+#if 0\r
+        if(dvfs_clk->dvfs_nb) {\r
+            // must unregister when clk disable\r
+            rk30_clk_notifier_register(clk, dvfs_clk->dvfs_nb);\r
         }\r
+#endif\r
+               dvfs_vd_get_newvolt_for_clk(dvfs_clk);\r
+        dvfs_clk->enable_dvfs++;       \r
+    } else {\r
+        DVFS_ERR("dvfs already enable clk enable = %d!\n", dvfs_clk->enable_dvfs);\r
+        dvfs_clk->enable_dvfs++;\r
     }\r
-    DVFS_DBG("-------------DVFS DEBUG END------------\n");\r
+    return 0;\r
 }\r
-#endif\r
 \r
-int is_support_dvfs(struct clk_node *dvfs_info)\r
+int clk_disable_dvfs(struct clk *clk)\r
 {\r
-    return (dvfs_info->vd && dvfs_info->vd->vd_dvfs_target && dvfs_info->enable_dvfs);\r
+    struct clk_node *dvfs_clk;\r
+    dvfs_clk = clk->dvfs_info;\r
+    if(!dvfs_clk->enable_dvfs) {\r
+        DVFS_DBG("clk is already closed!\n");\r
+        return -1;\r
+    } else {\r
+        dvfs_clk->enable_dvfs--;\r
+        if(0 == dvfs_clk->enable_dvfs) {\r
+            DVFS_ERR("clk closed!\n");\r
+            rk30_clk_notifier_unregister(clk, dvfs_clk->dvfs_nb);\r
+            DVFS_DBG("clk unregister nb!\n");\r
+        }\r
+    }\r
+    return 0;\r
 }\r
+\r
 static int rk_dvfs_clk_notifier_event(struct notifier_block *this,\r
                                       unsigned long event, void *ptr)\r
 {\r
@@ -205,8 +298,7 @@ static int rk_dvfs_clk_notifier_event(struct notifier_block *this,
         break;\r
     case CLK_POST_DISABLE:\r
         DVFS_DBG("%s CLK_POST_DISABLE\n", __func__);\r
-        dvfs_clk->cur_freq = 0;\r
-        dvfs_clk_scale_volt(dvfs_clk, 0);\r
+        dvfs_clk->set_freq = 0;\r
         break;\r
     case CLK_ABORT_DISABLE:\r
         DVFS_DBG("%s CLK_ABORT_DISABLE\n", __func__);\r
@@ -220,385 +312,276 @@ static int rk_dvfs_clk_notifier_event(struct notifier_block *this,
 static struct notifier_block rk_dvfs_clk_notifier = {\r
     .notifier_call = rk_dvfs_clk_notifier_event,\r
 };\r
-int clk_disable_dvfs(struct clk *clk)\r
+\r
+static int rk_regist_vd(struct vd_node *vd)\r
 {\r
-    struct clk_node *dvfs_clk;\r
-    dvfs_clk = clk->dvfs_info;\r
-    if(dvfs_clk->enable_dvfs - 1 < 0) {\r
-        DVFS_ERR("clk is already closed!\n");\r
+    if(!vd)\r
         return -1;\r
-    } else {\r
-        DVFS_ERR("clk is disable now!\n");\r
-        dvfs_clk->enable_dvfs--;\r
-        if(0 == dvfs_clk->enable_dvfs) {\r
-            DVFS_ERR("clk closed!\n");\r
-            rk30_clk_notifier_unregister(clk, dvfs_clk->dvfs_nb);\r
-            DVFS_ERR("clk unregister nb!\n");\r
-            dvfs_clk_scale_volt(dvfs_clk, 0);\r
-        }\r
-    }\r
-    dump_dbg_map();\r
+    mutex_lock(&mutex);\r
+    mutex_init(&vd->dvfs_mutex);\r
+    list_add(&vd->node, &rk_dvfs_tree);\r
+    INIT_LIST_HEAD(&vd->pd_list);\r
+       \r
+    mutex_unlock(&mutex);\r
     return 0;\r
 }\r
-\r
-int clk_enable_dvfs(struct clk *clk)\r
+static int rk_regist_pd(struct pd_node_lookup *pd_lookup)\r
 {\r
-    struct regulator *regulator;\r
-    struct clk_node *dvfs_clk;\r
-    struct cpufreq_frequency_table clk_fv;\r
-\r
-    if(!clk->dvfs_info) {\r
-        DVFS_ERR("This clk(%s) not support dvfs!\n", clk->name);\r
-        return -1;\r
-    }\r
+    struct vd_node     *vd;\r
+    struct pd_node     *pd;\r
 \r
-    dvfs_clk = clk->dvfs_info;\r
-    DVFS_ERR("dvfs clk enable dvfs %s\n", dvfs_clk->name);\r
-    if(0 == dvfs_clk->enable_dvfs) {\r
-        dvfs_clk->enable_dvfs++;\r
-        if(!dvfs_clk->vd->regulator) {\r
-            regulator = dvfs_regulator_get(NULL, dvfs_clk->vd->regulator_name);\r
-            if(regulator)\r
-                dvfs_clk->vd->regulator = regulator;\r
-            else\r
-                dvfs_clk->vd->regulator = NULL;\r
-        }\r
-        if(dvfs_clk->dvfs_nb) {\r
-            // must unregister when clk disable\r
-            rk30_clk_notifier_register(clk, dvfs_clk->dvfs_nb);\r
-        }\r
+    mutex_lock(&mutex);\r
+    pd = pd_lookup->pd;\r
 \r
-        if(!clk || IS_ERR(clk)) {\r
-            DVFS_ERR("%s get clk %s error\n", __func__, dvfs_clk->name);\r
-            return -1;\r
+    list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
+        if (vd == pd->vd) {\r
+            list_add(&pd->node, &vd->pd_list);\r
+            INIT_LIST_HEAD(&pd->clk_list);\r
+            break;\r
         }\r
-        //DVFS_DBG("%s get clk %s rate = %lu\n", __func__, clk->name, clk->rate);\r
-               if(dvfs_clk->cur_freq == 0)\r
-               dvfs_clk_get_volt(dvfs_clk, clk->rate, &clk_fv);\r
-               else\r
-                       dvfs_clk_get_volt(dvfs_clk, dvfs_clk->cur_freq, &clk_fv);\r
-        dvfs_clk->cur_volt = clk_fv.index;\r
-        dvfs_clk->cur_freq = clk_fv.frequency;\r
-        dvfs_clk_scale_volt(dvfs_clk, dvfs_clk->cur_volt);\r
-               dump_dbg_map();\r
-\r
-    } else {\r
-        DVFS_ERR("dvfs already enable clk enable = %d!\n", dvfs_clk->enable_dvfs);\r
-        dvfs_clk->enable_dvfs++;\r
     }\r
+    mutex_unlock(&mutex);\r
     return 0;\r
 }\r
 \r
-int dvfs_set_rate(struct clk *clk, unsigned long rate)\r
-{\r
-    int ret = 0;\r
-    struct vd_node *vd;\r
-    DVFS_DBG("%s dvfs start\n", clk->name);\r
-    if(!clk->dvfs_info) {\r
-        DVFS_ERR("%s :This clk do not support dvfs!\n", __func__);\r
-        ret = -1;\r
-    } else {\r
-        vd = clk->dvfs_info->vd;\r
-        mutex_lock(&vd->dvfs_mutex);\r
-        ret = vd->vd_dvfs_target(clk, rate);\r
-        mutex_unlock(&vd->dvfs_mutex);\r
-    }\r
-    return ret;\r
-}\r
-\r
-/**\r
- * get correspond voltage khz\r
- */\r
-static int dvfs_clk_get_volt(struct clk_node *dvfs_clk, unsigned long rate,\r
-                             struct cpufreq_frequency_table *clk_fv)\r
-{\r
-    int i = 0;\r
-    if (rate == 0) {\r
-        /* since no need*/\r
-        return -1;\r
-    }\r
-    clk_fv->frequency = rate;\r
-    clk_fv->index = 0;\r
-    for(i = 0; (dvfs_clk->dvfs_table[i].frequency != FV_TABLE_END); i++) {\r
-        if(dvfs_clk->dvfs_table[i].frequency >= rate) {\r
-            clk_fv->frequency = dvfs_clk->dvfs_table[i].frequency;\r
-            clk_fv->index = dvfs_clk->dvfs_table[i].index;\r
-            DVFS_DBG("%s dvfs_clk_get_volt rate=%u hz ref vol=%d uV\n", dvfs_clk->name, clk_fv->frequency, clk_fv->index);\r
-            return 0;\r
-        }\r
-    }\r
-    clk_fv->frequency = 0;\r
-    clk_fv->index = 0;\r
-    DVFS_ERR("%s get corresponding voltage error! out of bound\n", dvfs_clk->name);\r
-    return -1;\r
-}\r
-\r
-static int dvfs_clk_round_volt(struct clk_node *dvfs_clk, int volt)\r
+static int rk_regist_clk(struct clk_node *dvfs_clk)\r
 {\r
     struct pd_node     *pd;\r
-    struct clk_node    *dvfs_clk_tmp;\r
-    int volt_max = 0;\r
-    int i;\r
-\r
-    for(i = 0; (dvfs_clk->pds[i].pd != NULL); i++) {\r
-        pd = dvfs_clk->pds[i].pd;\r
-        if(volt > pd->cur_volt) {\r
-            /**\r
-             * if dvfs_clk parent power domain's voltage is smaller then\r
-             * this dvfs_clk's voltage ignore this power domain\r
-             */\r
-            volt_max = max(volt_max, volt);\r
-            continue;\r
-        }\r
-        list_for_each_entry(dvfs_clk_tmp, &pd->clk_list, node) {\r
-            /**\r
-             * found the max voltage uninclude dvfs_clk\r
-             */\r
-            if(dvfs_clk_tmp != dvfs_clk) {\r
-                volt_max = max(volt_max, dvfs_clk_tmp->cur_volt);\r
-            }\r
-        }\r
-    }\r
-\r
-    volt_max = max(volt_max, volt);\r
-    return volt_max;\r
-}\r
-\r
-static void dvfs_clk_scale_volt(struct clk_node *dvfs_clk, unsigned int volt)\r
-{\r
-    struct vd_node *vd;\r
-    struct pd_node *pd;\r
     struct clk_list    *child;\r
-    struct clk_node    *dvfs_clk_tmp;\r
-    int volt_max_vd = 0, volt_max_pd = 0, i;\r
-\r
-    dvfs_clk->cur_volt = volt;//set  clk node volt\r
-    vd = dvfs_clk->vd;// vd\r
-    for(i = 0; (dvfs_clk->pds[i].pd != NULL); i++) {\r
-        pd = dvfs_clk->pds[i].pd;\r
-        volt_max_pd = 0;\r
-        /**\r
-         * set corresponding voltage, clk do not need to set voltage,just for\r
-         * powerdomain\r
-         */\r
-\r
-        if(volt > pd->cur_volt) {\r
-            pd->cur_volt = volt;\r
-            pd->pd_status = (pd->cur_volt == 0) ? PD_OFF : PD_ON;\r
-            continue;\r
-        }\r
-\r
-        /* set power domain voltage */\r
-        list_for_each_entry(child, &pd->clk_list, node) {\r
-            dvfs_clk_tmp = child->dvfs_clk;\r
-                       if(dvfs_clk_tmp->enable_dvfs){\r
-               volt_max_pd = max(volt_max_pd, dvfs_clk_tmp->cur_volt);\r
-                       }\r
-        }\r
-        pd->cur_volt = volt_max_pd;\r
+    struct clk *clk;\r
+    int i = 0;\r
 \r
-        pd->pd_status = (volt_max_pd == 0) ? PD_OFF : PD_ON;\r
-    }\r
+    if(!dvfs_clk)\r
+        return -1;\r
 \r
-    /* set voltage domain voltage */\r
-    volt_max_vd = 0;\r
-    list_for_each_entry(pd, &vd->pd_list, node) {\r
-        volt_max_vd = max(volt_max_vd, pd->cur_volt);\r
+    if(!dvfs_clk->pds)\r
+        return -1;\r
+    mutex_lock(&mutex);\r
+    dvfs_clk->enable_dvfs = 0;\r
+    dvfs_clk->vd = dvfs_clk->pds[0].pd->vd;\r
+    for (i = 0; dvfs_clk->pds[i].pd != NULL; i++) {\r
+        child = &(dvfs_clk->pds[i].clk_list);\r
+        child->dvfs_clk = dvfs_clk;\r
+        pd = dvfs_clk->pds[i].pd;\r
+        list_add(&child->node, &pd->clk_list);\r
     }\r
-    vd->cur_volt = volt_max_vd;\r
+    clk = dvfs_clk_get(NULL, dvfs_clk->name);\r
+       dvfs_clk->ck=clk;\r
+    clk_register_dvfs(dvfs_clk, clk);\r
+    mutex_unlock(&mutex);\r
+    return 0;\r
 }\r
 \r
-int dvfs_target_set_rate_core(struct clk *clk, unsigned long rate)\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_old = 0;\r
-    struct cpufreq_frequency_table clk_fv;\r
+    unsigned int volt_vd_new = 0,volt_vd_old = 0,volt_clk_old=0;\r
+    struct cpufreq_frequency_table clk_fv = {0, 0};\r
     int ret = 0;\r
-    dvfs_clk = clk_get_dvfs_info(clk);\r
+       unsigned long temp_hz;\r
+\r
+       if(!clk)\r
+       {\r
+               DVFS_ERR("%s is not clk\n",__func__);\r
+               return -1;\r
+       }\r
+       dvfs_clk = clk_get_dvfs_info(clk);\r
 \r
-    DVFS_ERR("%s get clk %s\n", __func__, clk->name);\r
-    if(dvfs_clk->vd->regulator == NULL) {\r
+    if(!dvfs_clk||dvfs_clk->vd->regulator == NULL) {\r
         DVFS_ERR("%s can't get dvfs regulater\n", clk->name);\r
         return -1;\r
     }\r
+       \r
+    temp_hz = rate_hz;//clk_round_rate_nolock(clk, rate_hz);\r
+       \r
+       //DVFS_DBG("dvfs(%s) round rate(%lu)(rount %lu)\n",dvfs_clk->name,rate_hz,temp_hz);\r
 \r
-    /* If power domain off do scale in the notify function */\r
-    /*\r
-       if (rate == 0) {\r
-       dvfs_clk->cur_freq = 0;\r
-       dvfs_clk_scale_volt(dvfs_clk, 0);\r
-       return 0;\r
-       }\r
-       */\r
-    /* need round rate */\r
-    DVFS_ERR("%s going to round rate = %lu\n", clk->name, rate);\r
-    rate = clk_round_rate_nolock(clk, rate);\r
-    DVFS_ERR("%s round get rate = %lu\n", clk->name, rate);\r
     /* find the clk corresponding voltage */\r
-    if (0 != dvfs_clk_get_volt(dvfs_clk, rate, &clk_fv)) {\r
-        DVFS_ERR("%s rate %lukhz is larger,not support\n", clk->name, rate);\r
+    if (dvfs_clk_get_ref_volt(dvfs_clk, temp_hz/1000, &clk_fv)) {\r
+        DVFS_ERR("%s--%s:rate%lu,Get corresponding voltage error!\n",__func__,dvfs_clk->name,temp_hz);\r
         return -1;\r
     }\r
-    volt_old = dvfs_clk->vd->cur_volt;\r
-    volt_new = clk_fv.index;\r
+    volt_vd_old = dvfs_clk->vd->cur_volt;\r
 \r
-    DVFS_DBG("vol_new = %d mV(was %d mV)\n", volt_new, volt_old);\r\r
+       volt_clk_old=dvfs_clk->set_volt;\r
 \r
-    /* if up the voltage*/\r
-    if (volt_old < volt_new) {\r
-        if(dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new) < 0) {\r
-            DVFS_ERR("set voltage err\n");\r
+       dvfs_clk->set_volt=clk_fv.index;\r
 \r
+    volt_vd_new = dvfs_vd_get_newvolt_for_clk(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
+                                       ,volt_vd_new,volt_vd_old);\r
+    // if up the voltage\r
+    #if 1\r
+    if (volt_vd_old < volt_vd_new) {\r
+        if(dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_vd_new, volt_vd_new) < 0) {\r
+            DVFS_ERR("set voltage err\n");\r
             return -1;\r
         }\r
-        dvfs_clk->vd->cur_volt = volt_new;\r
-        /* CPU do not use power domain, so save scale times */\r
-        //dvfs_clk_scale_volt(dvfs_clk, clk_fv.index);\r
+               dvfs_clk->vd->cur_volt=volt_vd_new;\r
     }\r
-\r
+       #endif\r
     if(dvfs_clk->clk_dvfs_target) {\r
-        ret = dvfs_clk->clk_dvfs_target(clk, rate, clk_set_rate_locked);\r
+        ret = dvfs_clk->clk_dvfs_target(clk, temp_hz, clk_set_rate_locked);\r
     } else {\r
-        ret = clk_set_rate_locked(clk, rate);\r
+        ret = clk_set_rate_locked(clk, temp_hz);\r
     }\r
     if (ret < 0) {\r
+               \r
+               dvfs_clk->set_volt=volt_vd_old;\r
+               dvfs_vd_get_newvolt_for_clk(dvfs_clk);  \r
         DVFS_ERR("set rate err\n");\r
         return -1;\r
     }\r
-    dvfs_clk->cur_freq = rate;\r
-    dvfs_clk->cur_volt = volt_new;\r
-\r
-    /* if down the voltage */\r
-    if (volt_old > volt_new) {\r
-        if(dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new) < 0) {\r
+    dvfs_clk->set_freq = temp_hz/1000;\r
+       #if 1\r
+    if (volt_vd_old > volt_vd_new){\r
+        if(dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_vd_new, volt_vd_new) < 0) {\r
             DVFS_ERR("set voltage err\n");\r
-\r
-            return -1;\r
+                       return -1;\r
         }\r
-        dvfs_clk->vd->cur_volt = volt_new;\r
-        /* CPU do not use power domain, so save scale times */\r
-        //dvfs_clk_scale_volt(dvfs_clk, clk_fv.index);\r
+               dvfs_clk->vd->cur_volt=volt_vd_new;\r
     }\r
-\r
-    return ret;\r
+       #endif\r
+    return 0;\r
 }\r
+#define get_volt_up_delay(new_volt,old_volt) ((new_volt)>(old_volt)?\\r
+       (((new_volt)-(old_volt))>>10):0)\r
 \r
-int dvfs_target_set_rate_normal(struct clk *clk, unsigned long rate)\r
+int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz)\r
 {\r
     struct clk_node *dvfs_clk;\r
-    unsigned int volt_new = 0, volt_old = 0;\r
-    struct cpufreq_frequency_table clk_fv = {0, 0};\r
+    int volt_new = 0, volt_old = 0;\r
+    struct cpufreq_frequency_table clk_fv;\r
     int ret = 0;\r
-\r
-    dvfs_clk = clk_get_dvfs_info(clk);\r
-    DVFS_ERR("%s get clk %s\n", __func__, clk->name);\r
-    if(dvfs_clk->vd->regulator == NULL) {\r
-        DVFS_DBG("%s can't get dvfs regulater\n", clk->name);\r
+       unsigned long temp_hz;\r
+\r
+       if(!clk)\r
+       {\r
+               DVFS_ERR("%s is not clk\n",__func__);\r
+               return -1;\r
+       }\r
+       dvfs_clk = clk_get_dvfs_info(clk);\r
+       \r
+    if(!dvfs_clk||dvfs_clk->vd->regulator == NULL) {\r
+        DVFS_ERR("dvfs(%s) is not register regulator\n", dvfs_clk->name);\r
         return -1;\r
     }\r
-\r
     /* need round rate */\r
-    DVFS_ERR("%s going to round rate = %lu\n", clk->name, rate);\r
-    rate = clk_round_rate_nolock(clk, rate);\r
-    DVFS_ERR("%s round get rate = %lu\n", clk->name, rate);\r
+    temp_hz = clk_round_rate_nolock(clk, rate_hz);\r
+       \r
+       DVFS_DBG("dvfs(%s) round rate (%lu)(rount %lu)\n",dvfs_clk->name,rate_hz,temp_hz);\r
+\r
     /* find the clk corresponding voltage */\r
-    if (dvfs_clk_get_volt(dvfs_clk, rate, &clk_fv)) {\r
-        DVFS_DBG("dvfs_clk_get_volt:rate = Get corresponding voltage error!\n");\r
+    if (0 != dvfs_clk_get_ref_volt(dvfs_clk, temp_hz/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
-\r
     volt_old = dvfs_clk->vd->cur_volt;\r
-    volt_new = dvfs_clk_round_volt(dvfs_clk, clk_fv.index);\r
+    volt_new = clk_fv.index;\r
 \r
-    // if up the voltage\r
+    DVFS_LOG("%s--(%s),volt=%d(was %dmV),rate=%lu(was %lu),vd=%u(was %u)\n",__func__,\r
+                                               dvfs_clk->name,volt_new,volt_old,temp_hz,clk_get_rate(clk)\r
+                                               ,volt_new,volt_old);\r
+    /* if up the voltage*/\r
     if (volt_old < volt_new) {\r
-        if(dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new) < 0) {\r
-            DVFS_DBG("set voltage err\n");\r\r
+        if(dvfs_clk->vd->regulator&&dvfs_regulator_set_voltage(dvfs_clk->vd->regulator,volt_new, volt_new) < 0) {\r
+            DVFS_ERR("set voltage err\n");\r
             return -1;\r
         }\r
-        dvfs_clk_scale_volt(dvfs_clk, clk_fv.index);\r
+        dvfs_clk->vd->cur_volt = volt_new;\r
+               DVFS_LOG("%s set volt ok up\n",dvfs_clk->name); \r
+               udelay(get_volt_up_delay(volt_new,volt_old));\r
+               //DVFS_DBG("get_volt_up_delay%u",get_volt_up_delay(volt_new,volt_old));\r
     }\r
-\r
+       \r
     if(dvfs_clk->clk_dvfs_target) {\r
-        ret = dvfs_clk->clk_dvfs_target(clk, rate, clk_set_rate_locked);\r
+        ret = dvfs_clk->clk_dvfs_target(clk, temp_hz, clk_set_rate_locked);\r
     } else {\r
-        ret = clk_set_rate_locked(clk, rate);\r\r
+        ret = clk_set_rate_locked(clk, temp_hz);\r
     }\r
     if (ret < 0) {\r
         DVFS_ERR("set rate err\n");\r
         return -1;\r
-    }\r
-    dvfs_clk->cur_freq = rate;\r
-    dvfs_clk->cur_volt = volt_new;\r
-\r
-    // if down the voltage\r
+    }  \r
+    dvfs_clk->set_freq = temp_hz/1000;\r
+       \r
+       DVFS_LOG("dvfs %s set rate%lu ok\n",dvfs_clk->name,clk_get_rate(clk));\r
+       \r
+    /* if down the voltage */\r
     if (volt_old > volt_new) {\r
-        if(dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new) < 0) {\r
-            DVFS_DBG("set voltage err\n");\r
-                       return -1;\r
-\r
+        if(dvfs_clk->vd->regulator&&dvfs_regulator_set_voltage(dvfs_clk->vd->regulator, volt_new, volt_new) < 0) {\r
+            DVFS_ERR("set voltage err\n");\r
+            return -1;\r
         }\r
-        dvfs_clk_scale_volt(dvfs_clk, clk_fv.index);\r
+        dvfs_clk->vd->cur_volt = volt_new;\r
+               DVFS_LOG("dvfs %s set volt ok dn\n",dvfs_clk->name);\r
+      \r
     }\r
-\r
-    return 0;\r
+    return ret;\r
 }\r
 \r
 \r
+\r
 /*****************************init**************************/\r
 /**\r
- * rate must be raising sequence\r
- */\r
-\r
-struct cpufreq_frequency_table cpu_dvfs_table[] = {\r
-    {.frequency        = 126000000, .index     = 800000},\r
-    {.frequency        = 252000000, .index     = 850000},\r
-    {.frequency        = 504000000, .index     = 900000},\r
-    {.frequency        = 816000000, .index     = 1050000},\r
-    {.frequency        = 1008000000, .index    = 1100000},\r
-    {.frequency        = 1200000000, .index    = 1200000},\r
-    {.frequency        = FV_TABLE_END},\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  = 1060*DVFS_MV},\r
+       {.frequency     = 816*DVFS_KHZ, .index  = 1080*DVFS_MV},\r
+       //  {.frequency = 1008*DVFS_KHZ, .index = 1100*DVFS_MV},\r
+       {.frequency     = CPUFREQ_TABLE_END},\r
 };\r
-struct cpufreq_frequency_table ddr_dvfs_table[] = {\r
-    {.frequency        = 24000000, .index              = 600000},\r
-    {.frequency        = 64000000, .index              = 700000},\r
-    {.frequency        = 126000000, .index     = 800000},\r
-    {.frequency        = 252000000, .index     = 850000},\r
-    {.frequency        = 504000000, .index     = 900000},\r
-    {.frequency        = FV_TABLE_END},\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
-struct cpufreq_frequency_table gpu_dvfs_table[] = {\r
-    {.frequency        = 64000000, .index              = 700000},\r
-    {.frequency        = 126000000, .index     = 800000},\r
-    {.frequency        = 360000000, .index     = 850000},\r
-    {.frequency        = FV_TABLE_END},\r
+static struct cpufreq_frequency_table gpu_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 = 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 vd_node vd_cpu = {\r
     .name                      = "vd_cpu",\r
-    .vd_dvfs_target    = dvfs_target_set_rate_core,\r
+       .regulator_name = "vdd_cpu",\r
+    .vd_dvfs_target    = dvfs_target_cpu,\r
 };\r
 \r
 static struct vd_node vd_core = {\r
     .name                      = "vd_core",\r
-    .vd_dvfs_target    = dvfs_target_set_rate_normal,\r
+       .regulator_name = "vdd_core",\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
     .vd_dvfs_target    = NULL,\r
 };\r
 \r
-#define LOOKUP_VD(_pvd, _regulator_name)       \\r
-{      \\r
-       .vd                             = _pvd, \\r
-       .regulator_name = _regulator_name,      \\r
-}\r
-static struct vd_node_lookup rk30_vds[] = {\r
-    LOOKUP_VD(&vd_cpu, "cpu"),\r
-    LOOKUP_VD(&vd_core, "core"),\r
-    LOOKUP_VD(&vd_rtc, "rtc"),\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
@@ -681,134 +664,32 @@ static struct pds_list gpu_pds[] = {
     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
+#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
+\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("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
- * first scale regulator volt\r
- */\r
-static int rk_dvfs_check_regulator_volt(void)\r
-{\r
-    struct vd_node     *vd;\r
-    struct pd_node     *pd;\r
-    struct clk_list    *child;\r
-    struct clk_node    *dvfs_clk;\r
-    struct clk                 *clk;\r
-    struct cpufreq_frequency_table clk_fv;\r
-    unsigned int vmax_pd = 0, vmax_vd = 0;\r
 \r
-    list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
-        vmax_vd = 0;\r
-        list_for_each_entry(pd, &vd->pd_list, node) {\r
-            vmax_pd = 0;\r
-            list_for_each_entry(child, &pd->clk_list, node) {\r
-\r
-                dvfs_clk = child->dvfs_clk;\r
-                clk = dvfs_clk_get(NULL, dvfs_clk->name);\r
-                if(!clk || IS_ERR(clk)) {\r
-                    DVFS_ERR("%s get clk %s error\n", __func__, dvfs_clk->name);\r
-                    continue;\r
-                }\r
-                //DVFS_DBG("%s get clk %s rate = %lu\n", __func__, clk->name, clk->rate);\r
-                dvfs_clk_get_volt(dvfs_clk, clk->rate, &clk_fv);\r
-                dvfs_clk->cur_volt = clk_fv.index;\r
-                dvfs_clk->cur_freq = clk_fv.frequency;\r
-                vmax_pd = max(vmax_pd, clk_fv.index);\r
-                pd->pd_status = (vmax_pd == 0) ? PD_OFF : PD_ON;\r
-            }\r
-            pd->cur_volt = vmax_pd;\r
-            vmax_vd = max(vmax_vd, vmax_pd);\r
-        }\r
-\r
-        vd->cur_volt = vmax_vd;\r
-        //DVFS_DBG("%s check error: %d, %d\n", vd->name, vd->cur_volt, dvfs_regulator_get_voltage(vd->regulator));\r
-        //if (vd->cur_volt != dvfs_regulator_get_voltage(vd->regulator)) {\r
-        //     DVFS_ERR("%s default voltage domain value error!\n", vd->name);\r
-        //}\r
-    }\r
-    return 0;\r
-}\r
-\r
-static int rk_regist_vd(struct vd_node_lookup *vd_lookup)\r
-{\r
-    struct vd_node *vd;\r
-    if(!vd_lookup)\r
-        return -1;\r
-    vd = vd_lookup->vd;\r
-    vd->regulator_name = vd_lookup->regulator_name;\r
-\r
-    mutex_lock(&mutex);\r
-\r
-    mutex_init(&vd->dvfs_mutex);\r
-    list_add(&vd->node, &rk_dvfs_tree);\r
-    INIT_LIST_HEAD(&vd->pd_list);\r
-\r
-    mutex_unlock(&mutex);\r
-\r
-    return 0;\r
-}\r
-static int rk_regist_pd(struct pd_node_lookup *pd_lookup)\r
-{\r
-    struct vd_node     *vd;\r
-    struct pd_node     *pd;\r
-\r
-    mutex_lock(&mutex);\r
-    pd = pd_lookup->pd;\r
-\r
-    list_for_each_entry(vd, &rk_dvfs_tree, node) {\r
-        if (vd == pd->vd) {\r
-            list_add(&pd->node, &vd->pd_list);\r
-            INIT_LIST_HEAD(&pd->clk_list);\r
-            break;\r
-        }\r
-    }\r
-    mutex_unlock(&mutex);\r
-    return 0;\r
-}\r
-//extern int rk30_clk_notifier_register(struct clk *clk, struct notifier_block *nb);\r
-\r
-static int rk_regist_clk(struct clk_node *dvfs_clk)\r
-{\r
-    struct pd_node     *pd;\r
-    struct clk_list    *child;\r
-    struct clk *clk;\r
-    int i = 0;\r
-\r
-    if(!dvfs_clk)\r
-        return -1;\r
-\r
-    if(!dvfs_clk->pds)\r
-        return -1;\r
-\r
-    mutex_lock(&mutex);\r
-    // set clk unsupport dvfs\r
-    dvfs_clk->enable_dvfs = 0;\r
-    dvfs_clk->vd = dvfs_clk->pds[0].pd->vd;\r
-    for (i = 0; dvfs_clk->pds[i].pd != NULL; i++) {\r
-        child = &(dvfs_clk->pds[i].clk_list);\r
-        child->dvfs_clk = dvfs_clk;\r
-        pd = dvfs_clk->pds[i].pd;\r
-        list_add(&child->node, &pd->clk_list);\r
-    }\r
-    clk = dvfs_clk_get(NULL, dvfs_clk->name);\r
-    clk_register_dvfs(dvfs_clk, clk);\r
-    mutex_unlock(&mutex);\r
-    return 0;\r
-}\r
 int rk30_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
+        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
@@ -816,127 +697,51 @@ int rk30_dvfs_init(void)
     for (i = 0; i < ARRAY_SIZE(rk30_clks); i++) {\r
         rk_regist_clk(&rk30_clks[i]);\r
     }\r
-    dump_dbg_map();\r
-    //DVFS_DBG("%s dvfs tree create finish!\n", __func__);\r
-    //rk_dvfs_check_regulator_volt();\r
+       \r
     return 0;\r
 }\r
 \r
-void dvfs_clk_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target)\r
-{\r
-    struct clk_node *dvfs_clk = clk_get_dvfs_info(clk);\r
-    dvfs_clk->clk_dvfs_target = clk_dvfs_target;\r
-}\r
-//\r
-\r
-/*\r
- *cpufreq_frequency_table->index for cpufreq is index\r
- *cpufreq_frequency_table->index for dvfstable is volt\r
+#if 1\r
+/**\r
+ * dump_dbg_map() : Draw all informations of dvfs while debug\r
  */\r
-int cpufreq_dvfs_init(struct clk *clk, struct cpufreq_frequency_table **table, clk_dvfs_target_callback clk_dvfs_target)\r
+static void dump_dbg_map(void)\r
 {\r
+    int i;\r
+    struct vd_node     *vd;\r
+    struct pd_node     *pd, *clkparent;\r
+    struct clk_list    *child;\r
+    struct clk_node    *dvfs_clk;\r
 \r
-    struct cpufreq_frequency_table *freq_table;\r
-    struct clk_node *info = clk_get_dvfs_info(clk);\r
-    struct cpufreq_frequency_table *dvfs_table;//dvfs volt freq table\r
-    int i = 0;\r
-    DVFS_DBG("%s clk name %s\n", __func__, clk->name);\r
-    if(!info) {\r
-        return -1;\r
-    }\r
-    dvfs_table = info->dvfs_table;\r
+    DVFS_DBG("-------------DVFS DEBUG-----------\n\n\n");\r
+    DVFS_DBG("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
 \r
-    if(!dvfs_table) {\r
-        return -1;\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
+                     pd->name, (pd->pd_status == PD_ON) ? "ON" : "OFF", pd->cur_volt);\r
 \r
-    /********************************count table num****************************/\r
-    i = 0;\r
-    while(dvfs_table[i].frequency != FV_TABLE_END) {\r
-        //DVFS_DBG("dvfs_table1 %lu\n",dvfs_table[i].frequency);\r
-        i++;\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_clk->name, dvfs_clk->set_freq, dvfs_clk->set_volt, 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", clkparent->name, clkparent->vd->name);\r
+                }\r
 \r
-    freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * (i + 1), GFP_KERNEL);\r
-    //last freq is end tab\r
-    freq_table[i].index = i;\r
-    freq_table[i].frequency = CPUFREQ_TABLE_END;\r
-\r
-    //set freq table\r
-    i = 0;\r
-    while(dvfs_table[i].frequency != FV_TABLE_END) {\r
-        freq_table[i].index = i;\r
-        freq_table[i].frequency = dvfs_table[i].frequency;\r
-        //DVFS_DBG("dvfs_table %d %lu\n",i,dvfs_table[i].frequency);\r
-        i++;\r
-    }\r
-    *table = &freq_table[0];\r
-    dvfs_clk_set_rate_callback(clk, clk_dvfs_target);\r
-    return 0;\r
-}\r
+                for (i = 0; (dvfs_clk->dvfs_table[i].frequency != CPUFREQ_TABLE_END); i++) {\r
+                    DVFS_DBG("|  |  |  |- freq = %d, volt = %d\n", dvfs_clk->dvfs_table[i].frequency, dvfs_clk->dvfs_table[i].index);\r
 \r
-int clk_dvfs_set_dvfs_table(struct clk *clk, struct cpufreq_frequency_table *table)\r
-{\r
-    struct clk_node *info = clk_get_dvfs_info(clk);\r
-    if(!table || !info)\r
-        return -1;\r
-    info->dvfs_table = table;\r
-    return 0;\r
+                }\r
+            }\r
+        }\r
+    }\r
+    DVFS_DBG("-------------DVFS DEBUG END------------\n");\r
 }\r
-/********************************simulation cases****************************/\r
-\r
-#ifdef DVFS_TEST_OFF_BOARD\r
-int rk30_dvfs_init_test(void)\r
-{\r
-    struct clk *clk1;\r
-    DVFS_DBG("********************************simulation cases****************************\n");\r
-#ifdef DEBUG_RK30_DVFS\r
-    DVFS_DBG("\n\n");\r
-    dump_dbg_map();\r
 #endif\r
-    clk1 = dvfs_clk_get(NULL, "cpu");\r
-    if (clk1) {\r
-        dvfs_clk_set_rate(clk1, 1008000000);\r
-        dump_dbg_map();\r
-        dvfs_clk_set_rate(clk1, 816000000);\r
-        dump_dbg_map();\r
-        dvfs_clk_set_rate(clk1, 0);\r
-        dump_dbg_map();\r
-        dvfs_clk_set_rate(clk1, 1200000000);\r
-        dump_dbg_map();\r
-        dvfs_clk_set_rate(clk1, 1009000000);\r
-        dump_dbg_map();\r
-        dvfs_clk_set_rate(clk1, 1416000000);\r
-        dump_dbg_map();\r
-\r
-    } else {\r
-        DVFS_DBG("\t\t%s:\t can not find clk cpu\n", __func__);\r
-    }\r
-\r
-    clk1 = dvfs_clk_get(NULL, "gpu");\r
-    if (clk1) {\r
-        dvfs_clk_set_rate(clk1, 120000000);\r
-        dump_dbg_map();\r
-        dvfs_clk_enable(clk1);\r
-        dvfs_clk_disable(clk1);\r
-        dump_dbg_map();\r
-    } else {\r
-        DVFS_DBG("\t\t%s:\t can not find clk gpu\n", __func__);\r
-        dump_dbg_map();\r
-    }\r
 \r
-    clk1 = dvfs_clk_get(NULL, "arm_pll");\r
-    if (clk1) {\r
-        dvfs_clk_set_rate(clk1, 24000000);\r
-        dump_dbg_map();\r
-    } else {\r
-        DVFS_DBG("\t\t%s:\t can not find clk arm_pll\n", __func__);\r
-    }\r
 \r
-    DVFS_DBG("********************************simulation cases end***************************\n");\r
-\r
-    return 0;\r
-\r
-}\r
-#endif\r
 \r
old mode 100644 (file)
new mode 100755 (executable)
index 92cef0e..67d79d8
@@ -79,9 +79,10 @@ struct pds_list {
 \r
 struct clk_node {\r
        char    *name;\r
-       int             cur_freq;\r
-       int             cur_volt;\r
+       int             set_freq;//khz\r
+       int             set_volt;\r
        int             enable_dvfs;\r
+       struct clk *ck;\r
        struct pds_list         *pds;\r
        struct vd_node          *vd;\r
        struct cpufreq_frequency_table  *dvfs_table;\r
@@ -90,13 +91,33 @@ struct clk_node {
        clk_dvfs_target_callback clk_dvfs_target;\r
 };\r
 \r
+#ifdef CONFIG_DVFS\r
 int rk30_dvfs_init(void);\r
 int is_support_dvfs(struct clk_node *dvfs_info);\r
 int dvfs_set_rate(struct clk *clk, unsigned long rate);\r
-void clk_set_dvfs_target_rate_callback(struct clk *ck, clk_dvfs_target_callback clk_dvfs_target);\r
 int clk_enable_dvfs(struct clk *clk);\r
 int clk_disable_dvfs(struct clk *clk);\r
 int cpufreq_dvfs_init(struct clk *ck, struct cpufreq_frequency_table **table, clk_dvfs_target_callback clk_dvfs_target);\r
-int clk_dvfs_set_dvfs_table(struct clk *clk,struct cpufreq_frequency_table *table);\r
+void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target);\r
+struct cpufreq_frequency_table *dvfs_get_freq_volt_table(struct clk *clk);\r
+int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *table);\r
+int rk30_dvfs_init(void);\r
+#else\r
+int rk30_dvfs_init(void){};\r
+int is_support_dvfs(struct clk_node *dvfs_info){};\r
+int dvfs_set_rate(struct clk *clk, unsigned long rate){};\r
+int clk_enable_dvfs(struct clk *clk){};\r
+int clk_disable_dvfs(struct clk *clk){};\r
+int cpufreq_dvfs_init(struct clk *ck, struct cpufreq_frequency_table **table, clk_dvfs_target_callback clk_dvfs_target){};\r
+void dvfs_clk_register_set_rate_callback(struct clk *clk, clk_dvfs_target_callback clk_dvfs_target){};\r
+struct cpufreq_frequency_table *dvfs_get_freq_volt_table(struct clk *clk){};\r
+int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *table);\r
+int rk30_dvfs_init(void){};\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
 \r
 #endif\r
index 9ba0b4d7c71a45427c81564967b3fffef4bb38d5..caa635d836fa80ac10c5475689b278b2e1d034a7 100644 (file)
@@ -95,6 +95,11 @@ config DDR_TEST
        select CRC32
        default y
 
+config DVFS
+       bool "Enable dvfs"
+       depends on REGULATOR&&CPU_FREQ
+       default y
+
 config WIFI_CONTROL_FUNC
         bool "Enable WiFi control function abstraction"
         help