rk: rename drivers/clk/rockchip to drivers/clk/rk
authorHuang, Tao <huangtao@rock-chips.com>
Wed, 11 Nov 2015 06:57:32 +0000 (14:57 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 11 Nov 2015 06:57:32 +0000 (14:57 +0800)
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
18 files changed:
drivers/clk/rk/Makefile [new file with mode: 0644]
drivers/clk/rk/clk-ops.c [new file with mode: 0644]
drivers/clk/rk/clk-ops.h [new file with mode: 0644]
drivers/clk/rk/clk-pd.c [new file with mode: 0644]
drivers/clk/rk/clk-pd.h [new file with mode: 0644]
drivers/clk/rk/clk-pll.c [new file with mode: 0644]
drivers/clk/rk/clk-pll.h [new file with mode: 0755]
drivers/clk/rk/clk.c [new file with mode: 0644]
drivers/clk/rk/pd-rk3368.c [new file with mode: 0644]
drivers/clk/rockchip/Makefile [deleted file]
drivers/clk/rockchip/clk-ops.c [deleted file]
drivers/clk/rockchip/clk-ops.h [deleted file]
drivers/clk/rockchip/clk-pd.c [deleted file]
drivers/clk/rockchip/clk-pd.h [deleted file]
drivers/clk/rockchip/clk-pll.c [deleted file]
drivers/clk/rockchip/clk-pll.h [deleted file]
drivers/clk/rockchip/clk.c [deleted file]
drivers/clk/rockchip/pd-rk3368.c [deleted file]

diff --git a/drivers/clk/rk/Makefile b/drivers/clk/rk/Makefile
new file mode 100644 (file)
index 0000000..9c9e0e0
--- /dev/null
@@ -0,0 +1,5 @@
+obj-y  += clk.o
+obj-y  += clk-ops.o
+obj-y  += clk-pll.o
+obj-y  += clk-pd.o
+obj-y  += pd-rk3368.o
diff --git a/drivers/clk/rk/clk-ops.c b/drivers/clk/rk/clk-ops.c
new file mode 100644 (file)
index 0000000..948ffec
--- /dev/null
@@ -0,0 +1,921 @@
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk-private.h>
+#include <linux/delay.h>
+#include <linux/rockchip/common.h>
+#include <linux/rockchip/cpu.h>
+
+#include "clk-ops.h"
+
+/* mux_ops */
+struct clk_ops_table rk_clk_mux_ops_table[] = {
+       {.index = CLKOPS_TABLE_END},
+};
+
+
+/* rate_ops */
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+#define div_mask(d)    ((1 << ((d)->width)) - 1)
+
+static u32 clk_gcd(u32 numerator, u32 denominator)
+{
+       u32 a, b;
+
+       if (!numerator || !denominator)
+               return 0;
+       if (numerator > denominator) {
+               a = numerator;
+               b = denominator;
+       } else {
+               a = denominator;
+               b = numerator;
+       }
+       while (b != 0) {
+               int r = b;
+               b = a % b;
+               a = r;
+       }
+
+       return a;
+}
+
+static int clk_fracdiv_get_config(unsigned long rate_out, unsigned long rate,
+               u32 *numerator, u32 *denominator)
+{
+       u32 gcd_val;
+       gcd_val = clk_gcd(rate, rate_out);
+       clk_debug("%s: frac_get_seting rate=%lu, parent=%lu, gcd=%d\n",
+                       __func__, rate_out, rate, gcd_val);
+
+       if (!gcd_val) {
+               clk_err("gcd=0, frac div is not be supported\n");
+               return -EINVAL;
+       }
+
+       *numerator = rate_out / gcd_val;
+       *denominator = rate / gcd_val;
+
+       clk_debug("%s: frac_get_seting numerator=%d, denominator=%d, times=%d\n",
+                       __func__, *numerator, *denominator,
+                       *denominator / *numerator);
+
+       if (*numerator > 0xffff || *denominator > 0xffff ||
+                       (*denominator / (*numerator)) < 20) {
+               clk_err("can't get a available nume and deno\n");
+               return -EINVAL;
+       }
+
+       return 0;
+
+}
+
+static int clk_fracdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       u32 numerator, denominator;
+       struct clk_divider *div = to_clk_divider(hw);
+
+
+       if(clk_fracdiv_get_config(rate, parent_rate,
+                               &numerator, &denominator) == 0) {
+               writel(numerator << 16 | denominator, div->reg);
+               clk_debug("%s set rate=%lu,is ok\n", hw->clk->name, rate);
+       } else {
+               clk_err("clk_frac_div name=%s can't get rate=%lu\n",
+                               hw->clk->name, rate);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static unsigned long clk_fracdiv_recalc(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       unsigned long rate;
+       u64 rate64;
+       struct clk_divider *div = to_clk_divider(hw);
+       u32 numerator, denominator, reg_val;
+
+       reg_val = readl(div->reg);
+       if (reg_val == 0)
+               return parent_rate;
+
+       numerator = reg_val >> 16;
+       denominator = reg_val & 0xFFFF;
+       rate64 = (u64)parent_rate * numerator;
+       do_div(rate64, denominator);
+       rate = rate64;
+       clk_debug("%s: %s new clock rate is %lu, prate %lu (frac %u/%u)\n",
+                       __func__, hw->clk->name, rate, parent_rate,
+                       numerator, denominator);
+       return rate;
+}
+
+static long clk_fracdiv_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct clk *clk = hw->clk;
+       struct clk *parent = clk->parent;
+       long rate_out;
+
+       //FIXME: now just simply return rate
+       /*
+        *frac_div request a big input rate, and its parent is always a div,
+        *so we set parent->parent->rate as best_parent_rate.
+        */
+       rate_out = rate;
+       *prate = parent->parent->rate;
+
+       return rate_out;
+}
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return clk_divider_ops.recalc_rate(hw, parent_rate);
+}
+
+static long clk_divider_round_rate(struct clk_hw *hw,
+               unsigned long rate, unsigned long *prate)
+{
+       return clk_divider_ops.round_rate(hw, rate, prate);
+}
+
+static int clk_divider_set_rate(struct clk_hw *hw,
+               unsigned long rate, unsigned long parent_rate)
+{
+       return clk_divider_ops.set_rate(hw, rate, parent_rate);
+}
+
+static long clk_mux_with_div_determine_rate(struct clk_hw *div_hw, unsigned long rate,
+               unsigned long *best_parent_rate,
+               struct clk **best_parent_p)
+{
+       struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
+       int i, num_parents;
+       unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
+
+
+       parent = __clk_get_parent(clk);
+       if(!parent){
+               best = __clk_get_rate(clk);
+               goto out;
+       }
+
+       /* if NO_REPARENT flag set, pass through to current parent */
+       if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
+               best_prate = __clk_get_rate(parent);
+               best = clk_divider_ops.round_rate(div_hw, rate, &best_prate);
+               goto out;
+       }
+
+       /* find the parent that can provide the fastest rate <= rate */
+       num_parents = clk->num_parents;
+       for (i = 0; i < num_parents; i++) {
+               parent = clk_get_parent_by_index(clk, i);
+               if (!parent)
+                       continue;
+
+               parent_rate = __clk_get_rate(parent);
+               now = clk_divider_ops.round_rate(div_hw, rate, &parent_rate);
+
+               if (now <= rate && now > best) {
+                       best_parent = parent;
+                       best_prate = parent_rate;
+                       best = now;
+               }
+       }
+
+out:
+       if(best_prate)
+               *best_parent_rate = best_prate;
+
+       if (best_parent)
+               *best_parent_p = best_parent;
+
+       clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
+                       "\tbest_parent name = %s, best_prate = %lu\n",
+                       clk->name, rate, best,
+                       __clk_get_name(*best_parent_p), *best_parent_rate);
+
+       return best;
+}
+
+const struct clk_ops clkops_rate_auto_parent = {
+       .recalc_rate    = clk_divider_recalc_rate,
+       .round_rate     = clk_divider_round_rate,
+       .set_rate       = clk_divider_set_rate,
+       .determine_rate = clk_mux_with_div_determine_rate,
+};
+
+static long clk_div_round_rate_even(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       int i = 0;
+       struct clk_divider *divider =to_clk_divider(hw);
+       int max_div = 1 << divider->width;
+
+       for (i = 1; i <= max_div; i++) {
+               if (i > 1 && (i % 2 != 0))
+                       continue;
+               if (rate >= (*prate / i))
+                       return *prate / i;
+       }
+
+       return (*prate / max_div);
+}
+
+const struct clk_ops clkops_rate_evendiv = {
+       .recalc_rate    = clk_divider_recalc_rate,
+       .round_rate     = clk_div_round_rate_even,
+       .set_rate       = clk_divider_set_rate,
+};
+
+static long clk_mux_with_evendiv_determine_rate(struct clk_hw *div_hw, unsigned long rate,
+               unsigned long *best_parent_rate,
+               struct clk **best_parent_p)
+{
+       struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
+       int i, num_parents;
+       unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
+
+
+       parent = __clk_get_parent(clk);
+       if(!parent){
+               best = __clk_get_rate(clk);
+               goto out;
+       }
+
+       /* if NO_REPARENT flag set, pass through to current parent */
+       if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
+               best_prate = __clk_get_rate(parent);
+               best = clk_div_round_rate_even(div_hw, rate, &best_prate);
+               goto out;
+       }
+
+       /* find the parent that can provide the fastest rate <= rate */
+       num_parents = clk->num_parents;
+       for (i = 0; i < num_parents; i++) {
+               parent = clk_get_parent_by_index(clk, i);
+               if (!parent)
+                       continue;
+
+               parent_rate = __clk_get_rate(parent);
+               now = clk_div_round_rate_even(div_hw, rate, &parent_rate);
+
+               if (now <= rate && now > best) {
+                       best_parent = parent;
+                       best_prate = parent_rate;
+                       best = now;
+               }
+       }
+
+out:
+       if(best_prate)
+               *best_parent_rate = best_prate;
+
+       if (best_parent)
+               *best_parent_p = best_parent;
+
+       clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
+                       "\tbest_parent name = %s, best_prate = %lu\n",
+                       clk->name, rate, best,
+                       __clk_get_name(*best_parent_p), *best_parent_rate);
+
+       return best;
+}
+
+static long clk_mux_with_evendiv_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       return clk_div_round_rate_even(hw, rate, prate);
+}
+
+const struct clk_ops clkops_rate_mux_with_evendiv = {
+       .recalc_rate    = clk_divider_recalc_rate,
+       .set_rate       = clk_divider_set_rate,
+       .round_rate     = clk_mux_with_evendiv_round_rate,
+       .determine_rate = clk_mux_with_evendiv_determine_rate,
+};
+
+static int clk_i2s_fracdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       u32 numerator, denominator;
+       struct clk_divider *div = to_clk_divider(hw);
+       int i = 10;
+
+
+       if(clk_fracdiv_get_config(rate, parent_rate,
+                               &numerator, &denominator) == 0) {
+               while (i--) {
+                       writel((numerator - 1) << 16 | denominator, div->reg);
+                       mdelay(1);
+                       writel(numerator << 16 | denominator, div->reg);
+                       mdelay(1);
+               }
+               clk_debug("%s set rate=%lu,is ok\n", hw->clk->name, rate);
+       } else {
+               clk_err("clk_frac_div name=%s can't get rate=%lu\n",
+                               hw->clk->name, rate);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+const struct clk_ops clkops_rate_frac = {
+       .recalc_rate    = clk_fracdiv_recalc,
+       .round_rate     = clk_fracdiv_round_rate,
+       .set_rate       = clk_fracdiv_set_rate,
+};
+
+const struct clk_ops clkops_rate_i2s_frac = {
+       .recalc_rate    = clk_fracdiv_recalc,
+       .round_rate     = clk_fracdiv_round_rate,
+       .set_rate       = clk_i2s_fracdiv_set_rate,
+};
+
+static unsigned long clk_core_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       /* As parent rate could be changed in clk_core.set_rate
+        * ops, the passing_in parent_rate may not be the newest
+        * and we should use the parent->rate instead. As a side
+        * effect, we should NOT directly set clk_core's parent
+        * (apll) rate, otherwise we will get a wrong recalc rate
+        * with clk_core_recalc_rate.
+        */
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       return clk_divider_recalc_rate(hw, __clk_get_rate(parent));
+}
+
+static long clk_core_determine_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *best_parent_rate,
+               struct clk **best_parent_p)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (IS_ERR_OR_NULL(parent)) {
+               clk_err("fail to get parent!\n");
+               return 0;
+       }
+
+       return clk_round_rate(parent, rate);
+}
+
+static long clk_core_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       return clk_core_determine_rate(hw, rate, prate, NULL);
+}
+
+static int clk_core_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+       struct clk *grand_p = __clk_get_parent(parent);
+       int ret;
+
+       if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
+               clk_err("fail to get parent or grand_parent!\n");
+               return -EINVAL;
+       }
+
+       ret = parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p));
+       parent->rate = parent->ops->recalc_rate(parent->hw,
+                       __clk_get_rate(grand_p));
+
+       return ret;
+}
+
+const struct clk_ops clkops_rate_core = {
+       .recalc_rate    = clk_core_recalc_rate,
+       .round_rate     = clk_core_round_rate,
+       .set_rate       = clk_core_set_rate,
+       .determine_rate = clk_core_determine_rate,
+};
+
+/* Clk_ops for the child clk of clk_core, for example core_periph in rk3188 */
+const struct clk_ops clkops_rate_core_peri = {
+       .recalc_rate    = clk_divider_recalc_rate,
+       .round_rate     = clk_divider_round_rate,
+       .set_rate       = NULL,
+};
+
+
+static unsigned long clk_ddr_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       /* Same as clk_core, we should NOT set clk_ddr's parent
+        * (dpll) rate directly as a side effect.
+        */
+       return clk_core_recalc_rate(hw, parent_rate);
+}
+
+static long clk_ddr_determine_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *best_parent_rate,
+               struct clk **best_parent_p)
+{
+       long best = 0;
+
+       if (!ddr_round_rate) {
+               /* Do nothing before ddr init */
+               best = rate;//__clk_get_rate(hw->clk);
+       } else {
+               /* Func provided by ddr driver */
+               best = ddr_round_rate(rate/MHZ) * MHZ;
+       }
+
+       clk_debug("%s: from %lu to %lu\n", __func__, rate, best);
+
+       return best;
+}
+
+static long clk_ddr_round_rate(struct clk_hw *hw, unsigned long rate,
+                unsigned long *prate)
+{
+       return clk_ddr_determine_rate(hw, rate, prate, NULL);
+}
+
+static int clk_ddr_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+       struct clk *grand_p = __clk_get_parent(parent);
+
+
+       /* Do nothing before ddr init */
+       if (!ddr_change_freq)
+               return 0;
+
+       if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
+               clk_err("fail to get parent or grand_parent!\n");
+               return -EINVAL;
+       }
+
+       clk_debug("%s: will set rate = %lu\n", __func__, rate);
+
+       /* Func provided by ddr driver */
+       ddr_change_freq(rate/MHZ);
+
+       parent->rate = parent->ops->recalc_rate(parent->hw,
+                       __clk_get_rate(grand_p));
+
+       return 0;
+}
+
+const struct clk_ops clkops_rate_ddr = {
+       .recalc_rate    = clk_ddr_recalc_rate,
+       .round_rate     = clk_ddr_round_rate,
+       .set_rate       = clk_ddr_set_rate,
+       .determine_rate = clk_ddr_determine_rate,
+};
+
+static unsigned long clk_ddr_div2_recalc_rate(struct clk_hw *hw,
+                                             unsigned long parent_rate)
+{
+       /* Same as clk_core, we should NOT set clk_ddr's parent
+        * (dpll) rate directly as a side effect.
+        */
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       return clk_divider_recalc_rate(hw, __clk_get_rate(parent))/2;
+}
+
+const struct clk_ops clkops_rate_ddr_div2 = {
+       .recalc_rate    = clk_ddr_div2_recalc_rate,
+       .round_rate     = clk_ddr_round_rate,
+       .set_rate       = clk_ddr_set_rate,
+       .determine_rate = clk_ddr_determine_rate,
+};
+
+static unsigned long clk_ddr_div4_recalc_rate(struct clk_hw *hw,
+                                             unsigned long parent_rate)
+{
+       /* Same as clk_core, we should NOT set clk_ddr's parent
+        * (dpll) rate directly as a side effect.
+        */
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       return clk_divider_recalc_rate(hw, __clk_get_rate(parent))/4;
+}
+
+const struct clk_ops clkops_rate_ddr_div4 = {
+       .recalc_rate    = clk_ddr_div4_recalc_rate,
+       .round_rate     = clk_ddr_round_rate,
+       .set_rate       = clk_ddr_set_rate,
+       .determine_rate = clk_ddr_determine_rate,
+};
+
+
+static unsigned long clk_3288_i2s_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return parent_rate;
+}
+
+static long clk_3288_i2s_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       return rate;
+}
+
+static int clk_3288_i2s_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+       struct clk *grand_p = __clk_get_parent(parent);
+
+
+       if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
+               return 0;
+       }
+
+       if (parent->ops->set_rate) {
+               parent->ops->set_rate(parent->hw, rate/2, __clk_get_rate(grand_p));
+               parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p));
+       }
+
+       return 0;
+}
+
+const struct clk_ops clkops_rate_3288_i2s = {
+       .recalc_rate    = clk_3288_i2s_recalc_rate,
+       .round_rate     = clk_3288_i2s_round_rate,
+       .set_rate       = clk_3288_i2s_set_rate,
+};
+
+static bool usb480m_state = false;
+
+static long clk_3288_usb480m_determine_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *best_parent_rate,
+               struct clk **best_parent_p)
+{
+       if(rate == 0)
+               return 0;
+       else
+               return 480*MHZ;
+}
+
+static long clk_3288_usb480m_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       return clk_3288_usb480m_determine_rate(hw, rate, prate, NULL);
+}
+
+static int clk_3288_usb480m_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       if(rate == 0)
+               usb480m_state = false;
+       else
+               usb480m_state = true;
+
+       return 0;
+}
+
+static unsigned long clk_3288_usb480m_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       if(usb480m_state)
+               return 480*MHZ;
+       else
+               return 0;
+}
+
+const struct clk_ops clkops_rate_3288_usb480m = {
+       .determine_rate = clk_3288_usb480m_determine_rate,
+       .set_rate       = clk_3288_usb480m_set_rate,
+       .round_rate     = clk_3288_usb480m_round_rate,
+       .recalc_rate    = clk_3288_usb480m_recalc_rate,
+};
+
+#define RK3288_LIMIT_PLL_VIO0 (600*MHZ)
+
+static long clk_3288_dclk_lcdc0_determine_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *best_parent_rate,
+               struct clk **best_parent_p)
+{
+       struct clk *gpll = clk_get(NULL, "clk_gpll");
+       struct clk *cpll = clk_get(NULL, "clk_cpll");
+       unsigned long best, div, prate, gpll_rate;
+
+       gpll_rate = __clk_get_rate(gpll);
+
+       if ((rate <= (297*MHZ)) && (gpll_rate%rate == 0)) {
+               *best_parent_p = gpll;
+               best = rate;
+               *best_parent_rate = gpll_rate;
+       } else {
+               *best_parent_p = cpll;
+               div = RK3288_LIMIT_PLL_VIO0/rate;
+               prate = div * rate;
+               *best_parent_rate = clk_round_rate(cpll, prate);
+               best = (*best_parent_rate)/div; 
+       }
+
+       return best;
+}
+
+static long clk_3288_dclk_lcdc0_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       return clk_3288_dclk_lcdc0_determine_rate(hw, rate, prate, NULL);
+}
+
+static int clk_3288_dclk_lcdc0_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk* aclk_vio0 = clk_get(NULL, "aclk_vio0");
+       struct clk* hclk_vio = clk_get(NULL, "hclk_vio");
+       struct clk *aclk_vio1;
+       struct clk* parent;
+       struct clk *gpll = clk_get(NULL, "clk_gpll");
+       struct clk *cpll = clk_get(NULL, "clk_cpll");
+
+       clk_divider_ops.set_rate(hw, rate, parent_rate);
+
+       /* set aclk_vio */
+       if (parent_rate == __clk_get_rate(gpll)) {
+               parent = clk_get(NULL, "clk_gpll");
+               clk_set_parent(aclk_vio0, gpll);
+               clk_set_rate(aclk_vio0, 300*MHZ);
+       } else {
+               parent = clk_get(NULL, "clk_cpll");
+               clk_set_parent(aclk_vio0, cpll);
+               clk_set_rate(aclk_vio0, __clk_get_rate(cpll));
+       }
+       clk_set_rate(hclk_vio, 100*MHZ);
+
+       /* make aclk_isp and hclk_isp share a same pll in rk3288_eco */
+       if (rockchip_get_cpu_version() > 0) {
+               aclk_vio1 = clk_get(NULL, "aclk_vio1");
+               clk_set_parent(aclk_vio1, parent);
+               clk_set_rate(aclk_vio1, __clk_get_rate(parent));
+       }
+
+       return 0;
+}
+
+const struct clk_ops clkops_rate_3288_dclk_lcdc0 = {
+       .determine_rate = clk_3288_dclk_lcdc0_determine_rate,
+       .set_rate       = clk_3288_dclk_lcdc0_set_rate,
+       .round_rate     = clk_3288_dclk_lcdc0_round_rate,
+       .recalc_rate    = clk_divider_recalc_rate,
+};
+
+#define RK3288_LIMIT_PLL_VIO1 (350*MHZ)
+
+static long clk_3288_dclk_lcdc1_determine_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *best_parent_rate,
+               struct clk **best_parent_p)
+{
+       struct clk *gpll = clk_get(NULL, "clk_gpll");
+       struct clk *cpll = clk_get(NULL, "clk_cpll");
+       unsigned long best, div, prate, gpll_rate;
+
+       gpll_rate = __clk_get_rate(gpll);
+
+       if ((rate <= (297*MHZ)) && ((gpll_rate)%rate == 0)) {
+               *best_parent_p = gpll;
+               best = rate;
+               *best_parent_rate = gpll_rate;
+       } else {
+               *best_parent_p = cpll;
+               div = RK3288_LIMIT_PLL_VIO1/rate;
+               prate = div * rate;
+               *best_parent_rate = clk_round_rate(cpll, prate);
+               best = (*best_parent_rate)/div; 
+       }
+
+       return best;
+}
+
+static long clk_3288_dclk_lcdc1_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       return clk_3288_dclk_lcdc1_determine_rate(hw, rate, prate, NULL);
+}
+
+static int clk_3288_dclk_lcdc1_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk* aclk_vio1 = clk_get(NULL, "aclk_vio1");
+       struct clk* parent;
+       struct clk *gpll = clk_get(NULL, "clk_gpll");
+       struct clk *cpll = clk_get(NULL, "clk_cpll");
+
+       clk_divider_ops.set_rate(hw, rate, parent_rate);
+
+       /* set aclk_vio */
+       if (parent_rate == __clk_get_rate(gpll)) {
+               parent = clk_get(NULL, "clk_gpll");
+               clk_set_parent(aclk_vio1, gpll);
+               clk_set_rate(aclk_vio1, 300*MHZ);
+       } else {
+               parent = clk_get(NULL, "clk_cpll");
+               clk_set_parent(aclk_vio1, cpll);
+               clk_set_rate(aclk_vio1, __clk_get_rate(cpll));
+       }
+
+       if (rockchip_get_cpu_version() == 0) {
+               clk_set_parent(aclk_vio1, parent);
+               clk_set_rate(aclk_vio1, __clk_get_rate(parent));
+       }
+
+       return 0;
+}
+
+const struct clk_ops clkops_rate_3288_dclk_lcdc1 = {
+       .determine_rate = clk_3288_dclk_lcdc1_determine_rate,
+       .set_rate       = clk_3288_dclk_lcdc1_set_rate,
+       .round_rate     = clk_3288_dclk_lcdc1_round_rate,
+       .recalc_rate    = clk_divider_recalc_rate,
+};
+
+#define CONFIG_RK3368_MUX_NO_USE_NPLL
+
+static long clk_3368_mux_div_determine_rate(struct clk_hw *div_hw,
+                                           unsigned long rate,
+                                           unsigned long *best_parent_rate,
+                                           struct clk **best_parent_p)
+{
+       struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
+       int i, num_parents;
+       unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
+
+       parent = __clk_get_parent(clk);
+       if (!parent) {
+               best = __clk_get_rate(clk);
+               goto out;
+       }
+
+       /* if NO_REPARENT flag set, pass through to current parent */
+       if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
+               best_prate = __clk_get_rate(parent);
+               best = clk_divider_ops.round_rate(div_hw, rate, &best_prate);
+               goto out;
+       }
+
+       /* find the parent that can provide the fastest rate <= rate */
+       num_parents = clk->num_parents;
+       for (i = 0; i < num_parents; i++) {
+               parent = clk_get_parent_by_index(clk, i);
+               if (!parent)
+                       continue;
+
+#ifdef CONFIG_RK3368_MUX_NO_USE_NPLL
+               if (!strcmp(__clk_get_name(parent), "clk_npll"))
+                       continue;
+#endif
+               parent_rate = __clk_get_rate(parent);
+               now = clk_divider_ops.round_rate(div_hw, rate, &parent_rate);
+
+               if (now <= rate && now > best) {
+                       best_parent = parent;
+                       best_prate = parent_rate;
+                       best = now;
+               }
+       }
+
+out:
+       if (best_prate)
+               *best_parent_rate = best_prate;
+
+       if (best_parent)
+               *best_parent_p = best_parent;
+
+       clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
+                 "\tbest_parent name = %s, best_prate = %lu\n",
+                 clk->name, rate, best,
+                 __clk_get_name(*best_parent_p), *best_parent_rate);
+
+       return best;
+}
+
+const struct clk_ops clkops_rate_3368_auto_parent = {
+       .recalc_rate    = clk_divider_recalc_rate,
+       .round_rate     = clk_divider_round_rate,
+       .set_rate       = clk_divider_set_rate,
+       .determine_rate = clk_3368_mux_div_determine_rate,
+};
+
+#define RK3368_LIMIT_NPLL (1250*MHZ)
+
+static long clk_3368_dclk_lcdc_determine_rate(struct clk_hw *hw,
+                                             unsigned long rate,
+                                             unsigned long *best_parent_rate,
+                                             struct clk **best_parent_p)
+{
+       struct clk *npll = clk_get(NULL, "clk_npll");
+       unsigned long div, prate, best, *p_prate;
+       static unsigned long rk3368_pll_rates[] = {1188*MHZ, 0};
+
+       if (best_parent_p)
+               *best_parent_p = npll;
+
+       /* first get parent_rate from table */
+       p_prate = rk3368_pll_rates;
+
+       while (*p_prate) {
+               if (!(*p_prate % (rate*2)) || (*p_prate == rate)) {
+                       clk_debug("%s: get rate from table\n", __func__);
+                       *best_parent_rate = *p_prate;
+                       best = rate;
+                       return best;
+               }
+               p_prate++;
+       }
+
+       /* if not suitable parent_rate found in table, then auto calc rate */
+       div = RK3368_LIMIT_NPLL/rate;
+       /* div should be even */
+       if (div % 2)
+               div = div - 1;
+
+       prate = div * rate;
+       *best_parent_rate = clk_round_rate(npll, prate);
+       best = (*best_parent_rate)/div;
+
+       return best;
+}
+
+static long clk_3368_dclk_lcdc_round_rate(struct clk_hw *hw, unsigned long rate,
+                                         unsigned long *prate)
+{
+       return clk_3368_dclk_lcdc_determine_rate(hw, rate, prate, NULL);
+}
+
+const struct clk_ops clkops_rate_3368_dclk_lcdc = {
+       .determine_rate = clk_3368_dclk_lcdc_determine_rate,
+       .set_rate       = clk_divider_set_rate,
+       .round_rate     = clk_3368_dclk_lcdc_round_rate,
+       .recalc_rate    = clk_divider_recalc_rate,
+};
+
+static unsigned long clk_rk3368_ddr_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       if (!ddr_recalc_rate)
+               return (clk_core_recalc_rate(hw, parent_rate)/2);
+       else
+               return ddr_recalc_rate();
+}
+
+const struct clk_ops clkops_rate_rk3368_ddr = {
+       .recalc_rate    = clk_rk3368_ddr_recalc_rate,
+       .round_rate     = clk_ddr_round_rate,
+       .set_rate       = clk_ddr_set_rate,
+       .determine_rate = clk_ddr_determine_rate,
+};
+
+
+
+struct clk_ops_table rk_clkops_rate_table[] = {
+       {.index = CLKOPS_RATE_MUX_DIV,          .clk_ops = &clkops_rate_auto_parent},
+       {.index = CLKOPS_RATE_EVENDIV,          .clk_ops = &clkops_rate_evendiv},
+       {.index = CLKOPS_RATE_MUX_EVENDIV,      .clk_ops = &clkops_rate_mux_with_evendiv},
+       {.index = CLKOPS_RATE_I2S_FRAC,         .clk_ops = &clkops_rate_i2s_frac},
+       {.index = CLKOPS_RATE_FRAC,             .clk_ops = &clkops_rate_frac},
+       {.index = CLKOPS_RATE_CORE,             .clk_ops = &clkops_rate_core},
+       {.index = CLKOPS_RATE_CORE_CHILD,       .clk_ops = &clkops_rate_core_peri},
+       {.index = CLKOPS_RATE_DDR,              .clk_ops = &clkops_rate_ddr},
+       {.index = CLKOPS_RATE_RK3288_I2S,       .clk_ops = &clkops_rate_3288_i2s},
+       {.index = CLKOPS_RATE_RK3288_USB480M,   .clk_ops = &clkops_rate_3288_usb480m},
+       {.index = CLKOPS_RATE_RK3288_DCLK_LCDC0,.clk_ops = &clkops_rate_3288_dclk_lcdc0},
+       {.index = CLKOPS_RATE_RK3288_DCLK_LCDC1,.clk_ops = &clkops_rate_3288_dclk_lcdc1},
+       {.index = CLKOPS_RATE_DDR_DIV2,         .clk_ops = &clkops_rate_ddr_div2},
+       {.index = CLKOPS_RATE_DDR_DIV4,         .clk_ops = &clkops_rate_ddr_div4},
+       {.index = CLKOPS_RATE_RK3368_MUX_DIV_NPLL,   .clk_ops = &clkops_rate_3368_auto_parent},
+       {.index = CLKOPS_RATE_RK3368_DCLK_LCDC, .clk_ops = &clkops_rate_3368_dclk_lcdc},
+       {.index = CLKOPS_RATE_RK3368_DDR,   .clk_ops = &clkops_rate_rk3368_ddr},
+       {.index = CLKOPS_RATE_I2S,              .clk_ops = NULL},
+       {.index = CLKOPS_RATE_CIFOUT,           .clk_ops = NULL},
+       {.index = CLKOPS_RATE_UART,             .clk_ops = NULL},
+       {.index = CLKOPS_RATE_HSADC,            .clk_ops = NULL},
+       {.index = CLKOPS_RATE_MAC_REF,          .clk_ops = NULL},
+       {.index = CLKOPS_TABLE_END,             .clk_ops = NULL},
+};
+
+const struct clk_ops *rk_get_clkops(unsigned int idx)
+{
+       int i = 0;
+       unsigned int now_idx;
+
+       while(1){
+               now_idx = rk_clkops_rate_table[i].index;
+
+               if ((now_idx == idx) || (now_idx == CLKOPS_TABLE_END))
+                       return rk_clkops_rate_table[i].clk_ops;
+
+               i++;
+       }
+}
+EXPORT_SYMBOL_GPL(rk_get_clkops);
diff --git a/drivers/clk/rk/clk-ops.h b/drivers/clk/rk/clk-ops.h
new file mode 100644 (file)
index 0000000..7d43745
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __RK_CLK_OPS_H
+#define __RK_CLK_OPS_H
+
+#include <dt-bindings/clock/rockchip,rk3188.h>
+#include <linux/rockchip/iomap.h>
+#include <linux/rockchip/grf.h>
+
+#define MHZ                    (1000UL * 1000UL)
+#define KHZ                    (1000UL)
+
+struct clk_ops_table {
+       unsigned int            index;
+       const struct clk_ops    *clk_ops;
+};
+const struct clk_ops *rk_get_clkops(unsigned int idx);
+
+//#define RKCLK_DEBUG
+//#define RKCLK_TEST
+
+#if defined(RKCLK_DEBUG)
+#define clk_debug(fmt, args...) printk(KERN_INFO "rkclk: "fmt, ##args)
+#else
+#define clk_debug(fmt, args...) do {} while(0)
+#endif
+
+#define clk_err(fmt, args...) printk(KERN_ERR "rkclk: "fmt, ##args)
+
+u32 cru_readl(u32 offset);
+void cru_writel(u32 val, u32 offset);
+
+u32 grf_readl(u32 offset);
+
+#endif /* __RK_CLKOPS_H */
diff --git a/drivers/clk/rk/clk-pd.c b/drivers/clk/rk/clk-pd.c
new file mode 100644 (file)
index 0000000..4748cb3
--- /dev/null
@@ -0,0 +1,228 @@
+#include <linux/slab.h>
+
+#include "clk-ops.h"
+#include "clk-pd.h"
+
+
+static LIST_HEAD(clk_pd_notifier_list);
+
+static int __clk_pd_notify(struct clk *clk, unsigned long msg)
+{
+       struct clk_pd_notifier *cn;
+       int ret = NOTIFY_DONE;
+
+       list_for_each_entry(cn, &clk_pd_notifier_list, node) {
+               if (cn->clk == clk) {
+                       ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
+                                       NULL);
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+int rk_clk_pd_notifier_register(struct clk *clk, struct notifier_block *nb)
+{
+       struct clk_pd_notifier *cn;
+       int ret = -ENOMEM;
+
+       if (!clk || !nb)
+               return -EINVAL;
+
+       //clk_prepare_lock();
+
+       /* search the list of notifiers for this clk */
+       list_for_each_entry(cn, &clk_pd_notifier_list, node)
+               if (cn->clk == clk)
+                       break;
+
+       /* if clk wasn't in the notifier list, allocate new clk_notifier */
+       if (cn->clk != clk) {
+               cn = kzalloc(sizeof(struct clk_pd_notifier), GFP_KERNEL);
+               if (!cn)
+                       goto out;
+
+               cn->clk = clk;
+               srcu_init_notifier_head(&cn->notifier_head);
+
+               list_add(&cn->node, &clk_pd_notifier_list);
+       }
+
+       ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
+
+       //clk->notifier_count++;
+
+out:
+       //clk_prepare_unlock();
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(rk_clk_pd_notifier_register);
+
+int rk_clk_pd_notifier_unregister(struct clk *clk, struct notifier_block *nb)
+{
+       struct clk_pd_notifier *cn = NULL;
+       int ret = -EINVAL;
+
+       if (!clk || !nb)
+               return -EINVAL;
+
+       //clk_prepare_lock();
+
+       list_for_each_entry(cn, &clk_pd_notifier_list, node)
+               if (cn->clk == clk)
+                       break;
+
+       if (cn->clk == clk) {
+               ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
+
+               //clk->notifier_count--;
+
+               /* XXX the notifier code should handle this better */
+               if (!cn->notifier_head.head) {
+                       srcu_cleanup_notifier_head(&cn->notifier_head);
+                       list_del(&cn->node);
+                       kfree(cn);
+               }
+
+       } else {
+               ret = -ENOENT;
+       }
+
+       //clk_prepare_unlock();
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(rk_clk_pd_notifier_unregister);
+
+static int clk_pd_endisable(struct clk_hw *hw, bool enable)
+{
+       struct clk_pd *pd = to_clk_pd(hw);
+       unsigned long flags = 0;
+       int ret = 0;
+
+       if (pd->lock)
+               spin_lock_irqsave(pd->lock, flags);
+
+       ret = rockchip_pmu_ops.set_power_domain(pd->id, enable);
+
+       if (pd->lock)
+               spin_unlock_irqrestore(pd->lock, flags);
+
+       return ret;     
+}
+
+static int clk_pd_enable(struct clk_hw *hw)
+{
+       int ret = 0;
+
+       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_ENABLE);
+
+       ret = clk_pd_endisable(hw, true);
+
+       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_ENABLE);
+
+       return ret;
+}
+
+static void clk_pd_disable(struct clk_hw *hw)
+{
+       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_DISABLE);
+
+       clk_pd_endisable(hw, false);
+
+       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_DISABLE);
+}
+
+static int clk_pd_is_enabled(struct clk_hw *hw)
+{
+       struct clk_pd *pd = to_clk_pd(hw);
+
+       return rockchip_pmu_ops.power_domain_is_on(pd->id);
+}
+
+static int clk_pd_prepare(struct clk_hw *hw)
+{
+       __clk_pd_notify(hw->clk, RK_CLK_PD_PREPARE);
+
+       return 0;
+}
+
+static void clk_pd_unprepare(struct clk_hw *hw)
+{
+       __clk_pd_notify(hw->clk, RK_CLK_PD_UNPREPARE);
+}
+
+const struct clk_ops clk_pd_ops = {
+       .prepare = clk_pd_prepare,
+       .unprepare = clk_pd_unprepare,
+       .enable = clk_pd_enable,
+       .disable = clk_pd_disable,
+       .is_enabled = clk_pd_is_enabled,
+};
+
+static int clk_pd_virt_enable(struct clk_hw *hw)
+{
+       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_ENABLE);
+
+       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_ENABLE);
+
+       return 0;
+}
+
+static void clk_pd_virt_disable(struct clk_hw *hw)
+{
+       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_DISABLE);
+
+       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_DISABLE);
+}
+
+const struct clk_ops clk_pd_virt_ops = {
+       .prepare = clk_pd_prepare,
+       .unprepare = clk_pd_unprepare,
+       .enable = clk_pd_virt_enable,
+       .disable = clk_pd_virt_disable,
+};
+
+
+struct clk *rk_clk_register_pd(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags, 
+               u32 pd_id, spinlock_t *lock)
+{
+       struct clk_pd *pd;
+       struct clk *clk;
+       struct clk_init_data init;
+
+
+       /* allocate the pd */
+       pd = kzalloc(sizeof(struct clk_pd), GFP_KERNEL);
+       if (!pd) {
+               clk_err("%s: could not allocate pd clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = name;
+       init.flags = flags | CLK_IS_BASIC;
+       init.parent_names = (parent_name ? &parent_name: NULL);
+       init.num_parents = (parent_name ? 1 : 0);
+
+       if(pd_id == CLK_PD_VIRT)
+               init.ops = &clk_pd_virt_ops;
+       else
+               init.ops = &clk_pd_ops;
+
+       /* struct clk_pd assignments */
+       pd->id= pd_id;
+       pd->lock = lock;
+       pd->hw.init = &init;
+
+       /* register the clock */
+       clk = clk_register(dev, &pd->hw);
+
+       if (IS_ERR(clk))
+               kfree(pd);
+
+       return clk;
+}
+
diff --git a/drivers/clk/rk/clk-pd.h b/drivers/clk/rk/clk-pd.h
new file mode 100644 (file)
index 0000000..9983bdd
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __RK_CLK_PD_H
+#define __RK_CLK_PD_H
+
+#include <linux/clk-provider.h>
+#include <linux/rockchip/pmu.h>
+
+
+
+#define to_clk_pd(_hw) container_of(_hw, struct clk_pd, hw)
+
+struct clk_pd {
+       struct clk_hw   hw;
+       u32             id;
+       spinlock_t      *lock;
+};
+
+struct clk *rk_clk_register_pd(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags, 
+               u32 pd_id, spinlock_t *lock);
+
+
+#define RK_CLK_PD_PRE_ENABLE                   BIT(0)
+#define RK_CLK_PD_POST_ENABLE                  BIT(1)
+#define RK_CLK_PD_PRE_DISABLE                  BIT(2)
+#define RK_CLK_PD_POST_DISABLE                 BIT(3)
+#define RK_CLK_PD_PREPARE                      BIT(4)
+#define RK_CLK_PD_UNPREPARE                    BIT(5)
+
+
+struct clk_pd_notifier {
+       struct clk                      *clk;
+       struct srcu_notifier_head       notifier_head;
+       struct list_head                node;
+};
+
+int rk_clk_pd_notifier_register(struct clk *clk, struct notifier_block *nb);
+
+int rk_clk_pd_notifier_unregister(struct clk *clk, struct notifier_block *nb);
+
+#endif /* __RK_CLK_PD_H */
diff --git a/drivers/clk/rk/clk-pll.c b/drivers/clk/rk/clk-pll.c
new file mode 100644 (file)
index 0000000..5943ca1
--- /dev/null
@@ -0,0 +1,2581 @@
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <linux/rockchip/cpu.h>
+
+#include "clk-ops.h"
+#include "clk-pll.h"
+
+
+static const struct pll_clk_set rk3188_pll_com_table[] = {
+       _RK3188_PLL_SET_CLKS(1250000,   12,     625,    1),
+       _RK3188_PLL_SET_CLKS(1200000,   1,      50,     1),
+       _RK3188_PLL_SET_CLKS(1188000,   2,      99,     1),
+       _RK3188_PLL_SET_CLKS(891000,    8,      594,    2),
+       _RK3188_PLL_SET_CLKS(768000,    1,      64,     2),
+       _RK3188_PLL_SET_CLKS(594000,    2,      198,    4),
+       _RK3188_PLL_SET_CLKS(500000,    3,      250,    4),
+       _RK3188_PLL_SET_CLKS(408000,    1,      68,     4),
+       _RK3188_PLL_SET_CLKS(396000,    1,      66,     4),
+       _RK3188_PLL_SET_CLKS(384000,    2,      128,    4),
+       _RK3188_PLL_SET_CLKS(360000,    1,      60,     4),
+       _RK3188_PLL_SET_CLKS(300000,    1,      50,     4),
+       _RK3188_PLL_SET_CLKS(297000,    2,      198,    8),
+       _RK3188_PLL_SET_CLKS(148500,    2,      99,     8),
+       _RK3188_PLL_SET_CLKS(0,         0,      0,      0),
+};
+
+static const struct pll_clk_set rk3188plus_pll_com_table[] = {
+       _RK3188PLUS_PLL_SET_CLKS(1250000,       12,     625,    1),
+       _RK3188PLUS_PLL_SET_CLKS(1200000,       1,      50,     1),
+       _RK3188PLUS_PLL_SET_CLKS(1188000,       2,      99,     1),
+       _RK3188PLUS_PLL_SET_CLKS(891000,        8,      594,    2),
+       _RK3188PLUS_PLL_SET_CLKS(768000,        1,      64,     2),
+       _RK3188PLUS_PLL_SET_CLKS(594000,        2,      198,    4),
+       _RK3188PLUS_PLL_SET_CLKS(576000,        1,      48,     2),
+       _RK3188PLUS_PLL_SET_CLKS(500000,        3,      250,    4),
+       _RK3188PLUS_PLL_SET_CLKS(408000,        1,      68,     4),
+       _RK3188PLUS_PLL_SET_CLKS(400000,        3,      200,    4),
+       _RK3188PLUS_PLL_SET_CLKS(396000,        1,      66,     4),
+       _RK3188PLUS_PLL_SET_CLKS(384000,        2,      128,    4),
+       _RK3188PLUS_PLL_SET_CLKS(360000,        1,      60,     4),
+       _RK3188PLUS_PLL_SET_CLKS(300000,        1,      50,     4),
+       _RK3188PLUS_PLL_SET_CLKS(297000,        2,      198,    8),
+       _RK3188PLUS_PLL_SET_CLKS(148500,        2,      99,     8),
+       _RK3188PLUS_PLL_SET_CLKS(0,             0,      0,      0),
+};
+
+static const struct apll_clk_set rk3188_apll_table[] = {
+       //            (_mhz,    nr,     nf,     no,     _periph_div,    _aclk_div)
+       _RK3188_APLL_SET_CLKS(2208,     1,      92,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2184,     1,      91,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2160,     1,      90,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2136,     1,      89,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2112,     1,      88,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2088,     1,      87,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2064,     1,      86,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2040,     1,      85,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(2016,     1,      84,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1992,     1,      83,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1968,     1,      82,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1944,     1,      81,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1920,     1,      80,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1896,     1,      79,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1872,     1,      78,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1848,     1,      77,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1824,     1,      76,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1800,     1,      75,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1776,     1,      74,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1752,     1,      73,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1728,     1,      72,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1704,     1,      71,     1,      8,      81),
+       _RK3188_APLL_SET_CLKS(1680,     1,      70,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1656,     1,      69,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1632,     1,      68,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1608,     1,      67,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1560,     1,      65,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1512,     1,      63,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1488,     1,      62,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1464,     1,      61,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1440,     1,      60,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1416,     1,      59,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1392,     1,      58,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1368,     1,      57,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1344,     1,      56,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1320,     1,      55,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1296,     1,      54,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1272,     1,      53,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1248,     1,      52,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1224,     1,      51,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1200,     1,      50,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1176,     1,      49,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1128,     1,      47,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1104,     1,      46,     1,      8,      41),
+       _RK3188_APLL_SET_CLKS(1008,     1,      84,     2,      8,      41),
+       _RK3188_APLL_SET_CLKS(912,      1,      76,     2,      8,      41),
+       _RK3188_APLL_SET_CLKS(888,      1,      74,     2,      8,      41),
+       _RK3188_APLL_SET_CLKS(816,      1,      68,     2,      8,      41),
+       _RK3188_APLL_SET_CLKS(792,      1,      66,     2,      8,      41),
+       _RK3188_APLL_SET_CLKS(696,      1,      58,     2,      8,      41),
+       _RK3188_APLL_SET_CLKS(600,      1,      50,     2,      4,      41),
+       _RK3188_APLL_SET_CLKS(552,      1,      92,     4,      4,      41),
+       _RK3188_APLL_SET_CLKS(504,      1,      84,     4,      4,      41),
+       _RK3188_APLL_SET_CLKS(408,      1,      68,     4,      4,      21),
+       _RK3188_APLL_SET_CLKS(312,      1,      52,     4,      2,      21),
+       _RK3188_APLL_SET_CLKS(252,      1,      84,     8,      2,      21),
+       _RK3188_APLL_SET_CLKS(216,      1,      72,     8,      2,      21),
+       _RK3188_APLL_SET_CLKS(126,      1,      84,     16,     2,      11),
+       _RK3188_APLL_SET_CLKS(48,       1,      32,     16,     2,      11),
+       _RK3188_APLL_SET_CLKS(0,        1,      32,     16,     2,      11),
+};
+
+static const struct apll_clk_set rk3288_apll_table[] = {
+       //                   (_mhz,     nr,     nf,     no,     l2ram,  m0,     mp,     atclk,  pclk_dbg)
+       _RK3288_APLL_SET_CLKS(2208,     1,      92,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2184,     1,      91,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2160,     1,      90,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2136,     1,      89,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2112,     1,      88,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2088,     1,      87,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2064,     1,      86,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2040,     1,      85,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(2016,     1,      84,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1992,     1,      83,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1968,     1,      82,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1944,     1,      81,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1920,     1,      80,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1896,     1,      79,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1872,     1,      78,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1848,     1,      77,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1824,     1,      76,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1800,     1,      75,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1776,     1,      74,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1752,     1,      73,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1728,     1,      72,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1704,     1,      71,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1680,     1,      70,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1656,     1,      69,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1632,     1,      68,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1608,     1,      67,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1560,     1,      65,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1512,     1,      63,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1488,     1,      62,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1464,     1,      61,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1440,     1,      60,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1416,     1,      59,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1392,     1,      58,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1368,     1,      57,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1344,     1,      56,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1320,     1,      55,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1296,     1,      54,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1272,     1,      53,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1248,     1,      52,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1224,     1,      51,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1200,     1,      50,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1176,     1,      49,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1128,     1,      47,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1104,     1,      46,     1,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(1008,     1,      84,     2,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(912,      1,      76,     2,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(888,      1,      74,     2,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(816,      1,      68,     2,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(792,      1,      66,     2,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(696,      1,      58,     2,      2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(672,  1,      56,   2,     2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(648,  1,      54,   2,     2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(624,  1,      52,   2,     2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(600,  1,      50,        2,      2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(576,  1,      48,   2,     2,      2,      4,      4,      4), 
+       _RK3288_APLL_SET_CLKS(552,      1,      92,     4,      2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(528,  1,      88,   4,     2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(504,      1,      84,     4,      2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(480,  1,      80,   4,     2,      2,      4,      4,      4),
+        _RK3288_APLL_SET_CLKS(456,  1,      76,   4,     2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(252,      1,      84,     8,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(216,      1,      72,     8,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(126,      2,      84,     8,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(48,       2,      32,     8,      2,      2,      4,      4,      4),
+       _RK3288_APLL_SET_CLKS(0,        1,      32,     16,     2,      2,      4,      4,      4),
+};
+
+static const struct apll_clk_set rk3036_apll_table[] = {
+       _RK3036_APLL_SET_CLKS(1608, 1, 67, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1584, 1, 66, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1560, 1, 65, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1536, 1, 64, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1512, 1, 63, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1488, 1, 62, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1464, 1, 61, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1440, 1, 60, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1416, 1, 59, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1392, 1, 58, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1368, 1, 57, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1344, 1, 56, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1320, 1, 55, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1296, 1, 54, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1272, 1, 53, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1248, 1, 52, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1200, 1, 50, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1104, 1, 46, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1100, 12, 550, 1, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1008, 1, 84, 2, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(1000, 6, 500, 2, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(984, 1, 82, 2, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(960, 1, 80, 2, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(936, 1, 78, 2, 1, 1, 0, 81),
+       _RK3036_APLL_SET_CLKS(912, 1, 76, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(900, 4, 300, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(888, 1, 74, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(864, 1, 72, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(840, 1, 70, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(816, 1, 68, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(800, 6, 400, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(700, 6, 350, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(696, 1, 58, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(600, 1, 75, 3, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(504, 1, 63, 3, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(500, 6, 250, 2, 1, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(408, 1, 68, 2, 2, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(312, 1, 52, 2, 2, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(216, 1, 72, 4, 2, 1, 0, 41),
+       _RK3036_APLL_SET_CLKS(96, 1, 64, 4, 4, 1, 0, 21),
+       _RK3036_APLL_SET_CLKS(0, 1, 0, 1, 1, 1, 0, 21),
+};
+
+static const struct pll_clk_set rk3036plus_pll_com_table[] = {
+       _RK3036_PLL_SET_CLKS(1188000, 2, 99, 1, 1, 1, 0),
+       _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
+       /*_RK3036_PLL_SET_CLKS(297000, 2, 99, 4, 1, 1, 0),*/
+};
+
+static const struct pll_clk_set rk312xplus_pll_com_table[] = {
+       /*_RK3036_PLL_SET_CLKS(1064000, 3, 133, 1, 1, 1, 0),*/
+       /*_RK3036_PLL_SET_CLKS(798000, 2, 133, 2, 1, 1, 0),*/
+       _RK3036_PLL_SET_CLKS(1000000, 3, 125, 1,  1, 1, 0),
+       _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
+       _RK3036_PLL_SET_CLKS(500000, 3, 125, 2, 1, 1, 0),
+       _RK3036_PLL_SET_CLKS(400000, 3, 200, 2, 2, 1, 0),
+};
+
+static const struct apll_clk_set rk3368_apllb_table[] = {
+                       /*(_mhz,        nr,     nf,     no,     aclkm,  atclk,  pclk_dbg)*/
+       _RK3368_APLL_SET_CLKS(1608,     1,      67,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1560,     1,      65,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1512,     1,      63,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1488,     1,      62,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1464,     1,      61,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1440,     1,      60,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1416,     1,      59,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1392,     1,      58,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1368,     1,      57,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1344,     1,      56,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1320,     1,      55,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1296,     1,      54,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1272,     1,      53,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1248,     1,      52,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1224,     1,      51,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1200,     1,      50,     1,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(1176,     1,      49,     1,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(1128,     1,      47,     1,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(1104,     1,      46,     1,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(1008,     1,      84,     2,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(912,      1,      76,     2,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(888,      1,      74,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(816,      1,      68,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(792,      1,      66,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(696,      1,      58,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(672,      1,      56,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(648,      1,      54,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(624,      1,      52,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(600,      1,      50,     2,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(576,      1,      48,     2,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(552,      1,      92,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(528,      1,      88,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(504,      1,      84,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(480,      1,      80,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(456,      1,      76,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(252,      1,      84,     8,      2,      1,      1),
+       _RK3368_APLL_SET_CLKS(216,      1,      72,     8,      2,      1,      1),
+       _RK3368_APLL_SET_CLKS(126,      2,      84,     8,      2,      1,      1),
+       _RK3368_APLL_SET_CLKS(48,       2,      32,     8,      2,      1,      1),
+       _RK3368_APLL_SET_CLKS(0,        1,      32,     16,     2,      1,      1),
+};
+
+static const struct apll_clk_set rk3368_aplll_table[] = {
+                       /*(_mhz,        nr,     nf,     no,     aclkm,  atclk,  pclk_dbg)*/
+       _RK3368_APLL_SET_CLKS(1608,     1,      67,     1,      2,      7,      7),
+       _RK3368_APLL_SET_CLKS(1560,     1,      65,     1,      2,      7,      7),
+       _RK3368_APLL_SET_CLKS(1512,     1,      63,     1,      2,      7,      7),
+       _RK3368_APLL_SET_CLKS(1488,     1,      62,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1464,     1,      61,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1440,     1,      60,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1416,     1,      59,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1392,     1,      58,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1368,     1,      57,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1344,     1,      56,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1320,     1,      55,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1296,     1,      54,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1272,     1,      53,     1,      2,      6,      6),
+       _RK3368_APLL_SET_CLKS(1248,     1,      52,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1224,     1,      51,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1200,     1,      50,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1176,     1,      49,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1128,     1,      47,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1104,     1,      46,     1,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(1008,     1,      84,     2,      2,      5,      5),
+       _RK3368_APLL_SET_CLKS(912,      1,      76,     2,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(888,      1,      74,     2,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(816,      1,      68,     2,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(792,      1,      66,     2,      2,      4,      4),
+       _RK3368_APLL_SET_CLKS(696,      1,      58,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(672,      1,      56,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(648,      1,      54,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(624,      1,      52,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(600,      1,      50,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(576,      1,      48,     2,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(552,      1,      92,     4,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(528,      1,      88,     4,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(504,      1,      84,     4,      2,      3,      3),
+       _RK3368_APLL_SET_CLKS(480,      1,      80,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(456,      1,      76,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(252,      1,      84,     8,      2,      2,      2),
+       _RK3368_APLL_SET_CLKS(216,      1,      72,     8,      2,      1,      1),
+       _RK3368_APLL_SET_CLKS(126,      2,      84,     8,      2,      1,      1),
+       _RK3368_APLL_SET_CLKS(48,       2,      32,     8,      2,      1,      1),
+       _RK3368_APLL_SET_CLKS(0,        1,      32,     16,     2,      1,      1),
+};
+
+static const struct pll_clk_set rk3368_pll_table_low_jitter[] = {
+       /*                             _khz, nr,  nf, no, nb */
+       _RK3188PLUS_PLL_SET_CLKS_NB(1188000,  1,  99,  2,  1),
+       _RK3188PLUS_PLL_SET_CLKS_NB(400000,  1,  100,  6,  1),
+       _RK3188PLUS_PLL_SET_CLKS(         0,  0,   0,  0),
+};
+
+static void pll_wait_lock(struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       int delay = 24000000;
+
+       while (delay > 0) {
+               if (grf_readl(pll->status_offset) & (1 << pll->status_shift))
+                       break;
+               delay--;
+       }
+
+       if (delay == 0) {
+               clk_err("pll %s: can't lock! status_shift=%u\n"
+                               "pll_con0=%08x\npll_con1=%08x\n"
+                               "pll_con2=%08x\npll_con3=%08x\n",
+                               __clk_get_name(hw->clk),
+                               pll->status_shift,
+                               cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                               cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                               cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                               cru_readl(pll->reg + RK3188_PLL_CON(3)));
+
+               while(1);
+       }
+}
+
+static void rk3036_pll_wait_lock(struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       int delay = 24000000;
+
+
+       while (delay > 0) {
+               if (cru_readl(pll->status_offset) & (1 << pll->status_shift))
+                       break;
+               delay--;
+       }
+
+       if (delay == 0) {
+               clk_err("pll %s: can't lock! status_shift=%u\n"
+                               "pll_con0=%08x\npll_con1=%08x\n"
+                               "pll_con2=%08x\n",
+                               __clk_get_name(hw->clk),
+                               pll->status_shift,
+                               cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                               cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                               cru_readl(pll->reg + RK3188_PLL_CON(2)));
+               while (1);
+
+       }
+}
+
+
+/* get rate that is most close to target */
+static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
+               const struct apll_clk_set *table)
+{
+       const struct apll_clk_set *ps, *pt;
+
+       ps = pt = table;
+       while (pt->rate) {
+               if (pt->rate == rate) {
+                       ps = pt;
+                       break;
+               }
+
+               if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
+                       ps = pt;
+               if (pt->rate < rate)
+                       break;
+               pt++;
+       }
+
+       return ps;
+}
+
+/* get rate that is most close to target */
+static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
+               const struct pll_clk_set *table)
+{
+       const struct pll_clk_set *ps, *pt;
+
+       ps = pt = table;
+       while (pt->rate) {
+               if (pt->rate == rate) {
+                       ps = pt;
+                       break;
+               }
+
+               if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
+                       ps = pt;
+               if (pt->rate < rate)
+                       break;
+               pt++;
+       }
+
+       return ps;
+}
+
+/* CLK_PLL_3188 type ops */
+static unsigned long clk_pll_recalc_rate_3188(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long rate;
+
+
+       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
+               u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
+               u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
+
+               u64 rate64 = (u64)parent_rate * RK3188_PLL_NF(pll_con1);
+
+               do_div(rate64, RK3188_PLL_NR(pll_con0));
+               do_div(rate64, RK3188_PLL_NO(pll_con0));
+
+               rate = rate64;
+       } else {
+               /*FIXME*/
+               rate = parent_rate;
+               clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
+       }
+
+       clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
+
+       return rate;
+}
+
+static long clk_pll_round_rate_3188(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate==__clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (pll_com_get_best_set(rate, rk3188_pll_com_table)->rate);
+}
+
+static int _pll_clk_set_rate_3188(struct pll_clk_set *clk_set,
+               struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+
+
+       clk_debug("%s start!\n", __func__);
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       //enter slowmode
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+       //pll power down
+       cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
+
+       udelay(1);
+
+       //pll no power down
+       cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
+
+       pll_wait_lock(hw);
+
+       //return from slow
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
+                       __clk_get_name(hw->clk),
+                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                       cru_readl(pll->mode_offset));
+
+       clk_debug("%s end!\n", __func__);
+
+       return 0;
+}
+
+static int clk_pll_set_rate_3188(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188_pll_com_table);
+       int ret = 0;
+
+
+       if (rate == parent_rate) {
+               clk_debug("pll %s set rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+                               pll->mode_offset);
+               /* pll power down */
+               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
+               clk_debug("pll %s enter slow mode, set rate OK!\n",
+                               __clk_get_name(hw->clk));
+               return 0;
+       }
+
+       while(clk_set->rate) {
+               if (clk_set->rate == rate) {
+                       break;
+               }
+               clk_set++;
+       }
+
+       if (clk_set->rate == rate) {
+               ret = _pll_clk_set_rate_3188(clk_set, hw);
+               clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
+                               rate);
+       } else {
+               clk_err("pll %s is no corresponding rate=%lu\n",
+                               __clk_get_name(hw->clk), rate);
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct clk_ops clk_pll_ops_3188 = {
+       .recalc_rate = clk_pll_recalc_rate_3188,
+       .round_rate = clk_pll_round_rate_3188,
+       .set_rate = clk_pll_set_rate_3188,
+};
+
+
+/* CLK_PLL_3188_APLL type ops */
+static unsigned long clk_pll_recalc_rate_3188_apll(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return clk_pll_recalc_rate_3188(hw, parent_rate);
+}
+
+static long clk_pll_round_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate==__clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (apll_get_best_set(rate, rk3188_apll_table)->rate);
+}
+
+/* 1: use, 0: no use */
+#define RK3188_USE_ARM_GPLL    1
+
+static int clk_pll_set_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       struct clk *clk = hw->clk;
+       struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
+       unsigned long arm_gpll_rate;
+       const struct apll_clk_set *ps;
+       u32 old_aclk_div = 0, new_aclk_div = 0;
+       u32 temp_div;
+       unsigned long flags;
+       int sel_gpll = 0;
+
+
+       if (rate == parent_rate) {
+               clk_debug("pll %s set rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+                               pll->mode_offset);
+               /* pll power down */
+               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
+               clk_debug("pll %s enter slow mode, set rate OK!\n",
+                               __clk_get_name(hw->clk));
+               return 0;
+       }
+
+
+#if !RK3188_USE_ARM_GPLL
+       goto CHANGE_APLL;
+#endif
+
+       /* prepare arm_gpll before reparent clk_core to it */
+       if (!arm_gpll) {
+               clk_err("clk arm_gpll is NULL!\n");
+               goto CHANGE_APLL;
+       }
+
+       /* In rk3188, arm_gpll and cpu_gpll share a same gate,
+        * and aclk_cpu selects cpu_gpll as parent, thus this
+        * gate must keep enabled.
+        */
+#if 0
+       if (clk_prepare(arm_gpll)) {
+               clk_err("fail to prepare arm_gpll path\n");
+               clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+
+       if (clk_enable(arm_gpll)) {
+               clk_err("fail to enable arm_gpll path\n");
+               clk_disable(arm_gpll);
+               clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+#endif
+
+       arm_gpll_rate = __clk_get_rate(arm_gpll);
+       temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
+       temp_div = (temp_div == 0) ? 1 : temp_div;
+       if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
+               clk_debug("temp_div %d > max_div %d\n", temp_div,
+                               RK3188_CORE_CLK_MAX_DIV);
+               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
+                               __clk_get_rate(clk), arm_gpll_rate);
+               //clk_disable(arm_gpll);
+               //clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+
+       local_irq_save(flags);
+
+       /* firstly set div, then select arm_gpll path */
+       cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
+                       RK3188_CRU_CLKSELS_CON(0));
+       cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
+                       RK3188_CRU_CLKSELS_CON(0));
+
+       sel_gpll = 1;
+       //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       clk_debug("temp select arm_gpll path, get rate %lu\n",
+                       arm_gpll_rate/temp_div);
+       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+                       temp_div);
+
+CHANGE_APLL:
+       ps = apll_get_best_set(rate, rk3188_apll_table);
+       clk_debug("apll will set rate %lu\n", ps->rate);
+       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
+                       ps->pllcon0, ps->pllcon1, ps->pllcon2,
+                       ps->clksel0, ps->clksel1);
+
+       local_irq_save(flags);
+
+       /* If core src don't select gpll, apll need to enter slow mode
+        * before power down
+        */
+       //FIXME
+       //if (!sel_gpll)
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       /* PLL power down */
+       cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       dsb(sy);
+       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+
+       udelay(1);
+
+       /* PLL power up and wait for locked */
+       cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
+       pll_wait_lock(hw);
+
+       old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
+                       RK3188_CORE_ACLK_MSK);
+       new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
+
+       if (new_aclk_div >= old_aclk_div) {
+               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
+       }
+
+       /* PLL return from slow mode */
+       //FIXME
+       //if (!sel_gpll)
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       /* reparent to apll, and set div to 1 */
+       if (sel_gpll) {
+               cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
+                               RK3188_CRU_CLKSELS_CON(0));
+               cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
+                               RK3188_CRU_CLKSELS_CON(0));
+       }
+
+       if (old_aclk_div > new_aclk_div) {
+               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
+       }
+
+       //loops_per_jiffy = ps->lpj;
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       if (sel_gpll) {
+               sel_gpll = 0;
+               //clk_disable(arm_gpll);
+               //clk_unprepare(arm_gpll);
+       }
+
+       //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
+
+       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
+                       ps->rate,
+                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
+                       cru_readl(RK3188_CRU_CLKSELS_CON(0)),
+                       cru_readl(RK3188_CRU_CLKSELS_CON(1)));
+
+       return 0;
+}
+
+static const struct clk_ops clk_pll_ops_3188_apll = {
+       .recalc_rate = clk_pll_recalc_rate_3188_apll,
+       .round_rate = clk_pll_round_rate_3188_apll,
+       .set_rate = clk_pll_set_rate_3188_apll,
+};
+
+
+/* CLK_PLL_3188PLUS type ops */
+static unsigned long clk_pll_recalc_rate_3188plus(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long rate;
+
+
+       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
+               u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
+               u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
+
+               u64 rate64 = (u64)parent_rate * RK3188PLUS_PLL_NF(pll_con1);
+
+               do_div(rate64, RK3188PLUS_PLL_NR(pll_con0));
+               do_div(rate64, RK3188PLUS_PLL_NO(pll_con0));
+
+               rate = rate64;
+       } else {
+               /*FIXME*/
+               rate = parent_rate;
+               clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
+       }
+
+       clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
+
+       return rate;
+}
+
+static long clk_pll_round_rate_3188plus(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate==__clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (pll_com_get_best_set(rate, rk3188plus_pll_com_table)->rate);
+}
+
+static int _pll_clk_set_rate_3188plus(struct pll_clk_set *clk_set,
+               struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+
+
+       clk_debug("%s start!\n", __func__);
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       //enter slowmode
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       //enter rest
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       udelay(5);
+
+       //return from rest
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       //wating lock state
+       udelay(clk_set->rst_dly);
+
+       pll_wait_lock(hw);
+
+       //return from slow
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
+                       __clk_get_name(hw->clk),
+                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                       cru_readl(pll->mode_offset));
+
+       clk_debug("%s end!\n", __func__);
+
+       return 0;
+}
+
+static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       //struct clk_pll *pll = to_clk_pll(hw);
+       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188plus_pll_com_table);
+       int ret = 0;
+
+#if 0
+       if (rate == parent_rate) {
+               clk_debug("pll %s set rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+                               pll->mode_offset);
+               /* pll power down */
+               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
+               clk_debug("pll %s enter slow mode, set rate OK!\n",
+                               __clk_get_name(hw->clk));
+               return 0;
+       }
+#endif
+
+       while(clk_set->rate) {
+               if (clk_set->rate == rate) {
+                       break;
+               }
+               clk_set++;
+       }
+
+       if (cpu_is_rk3288() && ((rate == 297*MHZ) || (rate == 594*MHZ))) {
+               if((strncmp(__clk_get_name(hw->clk), "clk_gpll",
+                       strlen("clk_gpll")) == 0)) {
+
+                       printk("rk3288 set GPLL BW 20 for HDMI!\n");
+                       clk_set->pllcon2 = RK3188_PLL_CLK_BWADJ_SET(20);
+               }
+       }
+
+       if (clk_set->rate == rate) {
+               ret = _pll_clk_set_rate_3188plus(clk_set, hw);
+               clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
+                               rate);
+       } else {
+               clk_err("pll %s is no corresponding rate=%lu\n",
+                               __clk_get_name(hw->clk), rate);
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int clk_pll_is_enabled_3188plus(struct clk_hw *hw)
+{
+       unsigned long flags;
+       struct clk_pll *pll = to_clk_pll(hw);
+       int ret;
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift))
+               ret = 1;
+       else
+               ret = 0;
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static int clk_pll_enable_3188plus(struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags;
+       unsigned long rst_dly;
+       u32 nr;
+
+       clk_debug("%s enter\n", __func__);
+
+       if (clk_pll_is_enabled_3188plus(hw)) {
+               clk_debug("pll has been enabled\n");
+               return 0;
+       }
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       //enter slowmode
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       //power up
+       cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       //enter reset
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       //cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       //cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       //cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       udelay(5);
+
+       //return from reset
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       //wating lock state
+       nr = RK3188PLUS_PLL_NR(cru_readl(pll->reg + RK3188_PLL_CON(0)));
+       rst_dly = ((nr*500)/24+1);
+       udelay(rst_dly);
+
+       pll_wait_lock(hw);
+
+       //return from slow
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       clk_debug("pll %s dump reg:\n con0=0x%08x,\n con1=0x%08x,\n con2=0x%08x,\n"
+                       "con3=0x%08x,\n mode=0x%08x\n",
+                       __clk_get_name(hw->clk),
+                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
+                       cru_readl(pll->mode_offset));
+
+       return 0;
+}
+
+static void clk_pll_disable_3188plus(struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags;
+
+       clk_debug("%s enter\n", __func__);
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       //enter slowmode
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       //power down
+       cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+}
+
+static const struct clk_ops clk_pll_ops_3188plus = {
+       .recalc_rate = clk_pll_recalc_rate_3188plus,
+       .round_rate = clk_pll_round_rate_3188plus,
+       .set_rate = clk_pll_set_rate_3188plus,
+       .enable = clk_pll_enable_3188plus,
+       .disable = clk_pll_disable_3188plus,
+       .is_enabled = clk_pll_is_enabled_3188plus,
+};
+
+/* CLK_PLL_3188PLUS_AUTO type ops */
+#define PLL_FREF_MIN (269*KHZ)
+#define PLL_FREF_MAX (2200*MHZ)
+
+#define PLL_FVCO_MIN (440*MHZ)
+#define PLL_FVCO_MAX (2200*MHZ)
+
+#define PLL_FOUT_MIN (27500*KHZ) 
+#define PLL_FOUT_MAX (2200*MHZ)
+
+#define PLL_NF_MAX (4096)
+#define PLL_NR_MAX (64)
+#define PLL_NO_MAX (16)
+
+static u32 clk_gcd(u32 numerator, u32 denominator)
+{
+       u32 a, b;
+
+       if (!numerator || !denominator)
+               return 0;
+       if (numerator > denominator) {
+               a = numerator;
+               b = denominator;
+       } else {
+               a = denominator;
+               b = numerator;
+       }
+       while (b != 0) {
+               int r = b;
+
+               b = a % b;
+               a = r;
+       }
+
+       return a;
+}
+
+static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
+                               u32 *best_nr, u32 *best_nf, u32 *best_no)
+{
+       u32 nr, nf, no, nonr;
+       u32 nr_out, nf_out, no_out;
+       u32 n;
+       u32 YFfenzi;
+       u32 YFfenmu;
+       u64 fref, fvco, fout;
+       u32 gcd_val = 0;
+
+       nr_out = PLL_NR_MAX + 1;
+       no_out = 0;
+
+       if (!fin_hz || !fout_hz || fout_hz == fin_hz)
+               return -EINVAL;
+       gcd_val = clk_gcd(fin_hz, fout_hz);
+
+       YFfenzi = fout_hz / gcd_val;
+       YFfenmu = fin_hz / gcd_val;
+
+       for (n = 1;; n++) {
+               nf = YFfenzi * n;
+               nonr = YFfenmu * n;
+               if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
+                       break;
+
+               for (no = 1; no <= PLL_NO_MAX; no++) {
+                       if (!(no == 1 || !(no % 2)))
+                               continue;
+
+                       if (nonr % no)
+                               continue;
+                       nr = nonr / no;
+
+                       if (nr > PLL_NR_MAX)
+                               continue;
+
+                       fref = fin_hz / nr;
+                       if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
+                               continue;
+
+                       fvco = fref * nf;
+                       if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
+                               continue;
+
+                       fout = fvco / no;
+                       if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
+                               continue;
+
+                       /* select the best from all available PLL settings */
+                       if ((no > no_out) || ((no == no_out) && (nr < nr_out))) {
+                               nr_out = nr;
+                               nf_out = nf;
+                               no_out = no;
+                       }
+               }
+       }
+
+       /* output the best PLL setting */
+       if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) {
+               if (best_nr && best_nf && best_no) {
+                       *best_nr = nr_out;
+                       *best_nf = nf_out;
+                       *best_no = no_out;
+               }
+               return 0;
+       } else {
+               return -EINVAL;
+       }
+}
+
+static unsigned long clk_pll_recalc_rate_3188plus_auto(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return clk_pll_recalc_rate_3188plus(hw, parent_rate);
+}
+
+static long clk_pll_round_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       unsigned long best;
+
+       for(best=rate; best>0; best--){
+               if(!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
+                       return best;
+       }
+
+       return 0;
+}
+
+static int clk_pll_set_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       unsigned long best;
+       u32 nr,nf,no;
+       struct pll_clk_set clk_set;
+       int ret;
+
+
+       best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
+
+       if(!best)
+               return -EINVAL;
+
+       pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
+
+       /* prepare clk_set */
+       clk_set.rate = best;
+       clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
+       clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
+       clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
+       clk_set.rst_dly = ((nr*500)/24+1);
+
+       ret = _pll_clk_set_rate_3188plus(&clk_set, hw);
+       clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk), best);
+
+       return ret;
+}
+
+
+static const struct clk_ops clk_pll_ops_3188plus_auto = {
+       .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
+       .round_rate = clk_pll_round_rate_3188plus_auto,
+       .set_rate = clk_pll_set_rate_3188plus_auto,
+       .enable = clk_pll_enable_3188plus,
+       .disable = clk_pll_disable_3188plus,
+       .is_enabled = clk_pll_is_enabled_3188plus,
+};
+
+static long clk_pll_round_rate_3368_low_jitter(struct clk_hw *hw,
+                                              unsigned long rate,
+                                              unsigned long *prate)
+{
+       unsigned long best;
+       struct pll_clk_set *p_clk_set;
+
+       p_clk_set = (struct pll_clk_set *)(rk3368_pll_table_low_jitter);
+
+       while (p_clk_set->rate) {
+               if (p_clk_set->rate == rate)
+                       break;
+               p_clk_set++;
+       }
+
+       if (p_clk_set->rate == rate) {
+               clk_debug("get rate from table\n");
+               return rate;
+       }
+
+       for (best = rate; best > 0; best--) {
+               if (!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
+                       return best;
+       }
+
+       clk_err("%s: can't round rate %lu\n", __func__, rate);
+       return 0;
+}
+
+
+static int clk_pll_set_rate_3368_low_jitter(struct clk_hw *hw,
+                                           unsigned long rate,
+                                           unsigned long parent_rate)
+{
+       unsigned long best;
+       u32 nr, nf, no;
+       struct pll_clk_set clk_set, *p_clk_set;
+       int ret;
+
+       p_clk_set = (struct pll_clk_set *)(rk3368_pll_table_low_jitter);
+
+       while (p_clk_set->rate) {
+               if (p_clk_set->rate == rate)
+                       break;
+               p_clk_set++;
+       }
+
+       if (p_clk_set->rate == rate) {
+               clk_debug("get rate from table\n");
+               goto set_rate;
+       }
+
+       best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
+
+       if (!best)
+               return -EINVAL;
+
+       pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
+
+       /* prepare clk_set */
+       clk_set.rate = best;
+       clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
+       clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
+       clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
+       clk_set.rst_dly = ((nr*500)/24+1);
+
+       p_clk_set = &clk_set;
+
+set_rate:
+       ret = _pll_clk_set_rate_3188plus(p_clk_set, hw);
+       clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
+                 p_clk_set->rate);
+
+       return ret;
+}
+
+static const struct clk_ops clk_pll_ops_3368_low_jitter = {
+       .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
+       .round_rate = clk_pll_round_rate_3368_low_jitter,
+       .set_rate = clk_pll_set_rate_3368_low_jitter,
+       .enable = clk_pll_enable_3188plus,
+       .disable = clk_pll_disable_3188plus,
+       .is_enabled = clk_pll_is_enabled_3188plus,
+};
+
+/* CLK_PLL_3188PLUS_APLL type ops */
+static unsigned long clk_pll_recalc_rate_3188plus_apll(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return clk_pll_recalc_rate_3188plus(hw, parent_rate);
+}
+
+static long clk_pll_round_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       return clk_pll_round_rate_3188_apll(hw, rate, prate);
+}
+
+/* 1: use, 0: no use */
+#define RK3188PLUS_USE_ARM_GPLL        1
+
+static int clk_pll_set_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       struct clk *clk = hw->clk;
+       struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
+       unsigned long arm_gpll_rate;
+       const struct apll_clk_set *ps;
+       u32 old_aclk_div = 0, new_aclk_div = 0;
+       u32 temp_div;
+       unsigned long flags;
+       int sel_gpll = 0;
+
+#if 0
+       if (rate == parent_rate) {
+               clk_debug("pll %s set rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+                               pll->mode_offset);
+               /* pll power down */
+               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
+               clk_debug("pll %s enter slow mode, set rate OK!\n",
+                               __clk_get_name(hw->clk));
+               return 0;
+       }
+#endif
+
+
+#if !RK3188PLUS_USE_ARM_GPLL
+       goto CHANGE_APLL;
+#endif
+
+       /* prepare arm_gpll before reparent clk_core to it */
+       if (!arm_gpll) {
+               clk_err("clk arm_gpll is NULL!\n");
+               goto CHANGE_APLL;
+       }
+
+       /* In rk3188plus, arm_gpll and cpu_gpll share a same gate,
+        * and aclk_cpu selects cpu_gpll as parent, thus this
+        * gate must keep enabled.
+        */
+#if 0
+       if (clk_prepare(arm_gpll)) {
+               clk_err("fail to prepare arm_gpll path\n");
+               clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+
+       if (clk_enable(arm_gpll)) {
+               clk_err("fail to enable arm_gpll path\n");
+               clk_disable(arm_gpll);
+               clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+#endif
+
+       arm_gpll_rate = __clk_get_rate(arm_gpll);
+       temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
+       temp_div = (temp_div == 0) ? 1 : temp_div;
+       if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
+               clk_debug("temp_div %d > max_div %d\n", temp_div,
+                               RK3188_CORE_CLK_MAX_DIV);
+               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
+                               __clk_get_rate(clk), arm_gpll_rate);
+               //clk_disable(arm_gpll);
+               //clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+
+       local_irq_save(flags);
+
+       /* firstly set div, then select arm_gpll path */
+       cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
+                       RK3188_CRU_CLKSELS_CON(0));
+       cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
+                       RK3188_CRU_CLKSELS_CON(0));
+
+       sel_gpll = 1;
+       //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       clk_debug("temp select arm_gpll path, get rate %lu\n",
+                       arm_gpll_rate/temp_div);
+       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+                       temp_div);
+
+CHANGE_APLL:
+       ps = apll_get_best_set(rate, rk3188_apll_table);
+       clk_debug("apll will set rate %lu\n", ps->rate);
+       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
+                       ps->pllcon0, ps->pllcon1, ps->pllcon2,
+                       ps->clksel0, ps->clksel1);
+
+       local_irq_save(flags);
+
+       /* If core src don't select gpll, apll need to enter slow mode
+        * before reset
+        */
+       //FIXME
+       //if (!sel_gpll)
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       /* PLL enter rest */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       udelay(5);
+
+       /* return from rest */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       //wating lock state
+       udelay(ps->rst_dly);
+       pll_wait_lock(hw);
+
+       old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
+                       RK3188_CORE_ACLK_MSK);
+       new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
+
+       if (new_aclk_div >= old_aclk_div) {
+               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
+       }
+
+       /* PLL return from slow mode */
+       //FIXME
+       //if (!sel_gpll)
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       /* reparent to apll, and set div to 1 */
+       if (sel_gpll) {
+               cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
+                               RK3188_CRU_CLKSELS_CON(0));
+               cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
+                               RK3188_CRU_CLKSELS_CON(0));
+       }
+
+       if (old_aclk_div > new_aclk_div) {
+               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
+       }
+
+       //loops_per_jiffy = ps->lpj;
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       if (sel_gpll) {
+               sel_gpll = 0;
+               //clk_disable(arm_gpll);
+               //clk_unprepare(arm_gpll);
+       }
+
+       //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
+
+       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
+                       ps->rate,
+                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
+                       cru_readl(RK3188_CRU_CLKSELS_CON(0)),
+                       cru_readl(RK3188_CRU_CLKSELS_CON(1)));
+
+       return 0;
+}
+
+static const struct clk_ops clk_pll_ops_3188plus_apll = {
+       .recalc_rate = clk_pll_recalc_rate_3188plus_apll,
+       .round_rate = clk_pll_round_rate_3188plus_apll,
+       .set_rate = clk_pll_set_rate_3188plus_apll,
+};
+
+/* CLK_PLL_3288_APLL type ops */
+static unsigned long clk_pll_recalc_rate_3288_apll(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return clk_pll_recalc_rate_3188plus(hw, parent_rate);
+}
+
+static long clk_pll_round_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate==__clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (apll_get_best_set(rate, rk3288_apll_table)->rate);
+}
+
+/* 1: use, 0: no use */
+#define RK3288_USE_ARM_GPLL    1
+
+static int clk_pll_set_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       struct clk *clk = hw->clk;
+       struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
+       unsigned long arm_gpll_rate, temp_rate, old_rate;
+       const struct apll_clk_set *ps;
+//     u32 old_aclk_div = 0, new_aclk_div = 0;
+       u32 temp_div;
+       unsigned long flags;
+       int sel_gpll = 0;
+
+
+#if 0
+       if (rate == parent_rate) {
+               clk_debug("pll %s set rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+                               pll->mode_offset);
+               /* pll power down */
+               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
+               clk_debug("pll %s enter slow mode, set rate OK!\n",
+                               __clk_get_name(hw->clk));
+               return 0;
+       }
+#endif
+
+#if !RK3288_USE_ARM_GPLL
+       goto CHANGE_APLL;
+#endif
+
+       /* prepare arm_gpll before reparent clk_core to it */
+       if (!arm_gpll) {
+               clk_err("clk arm_gpll is NULL!\n");
+               goto CHANGE_APLL;
+       }
+
+       arm_gpll_rate = __clk_get_rate(arm_gpll);
+       old_rate = __clk_get_rate(clk);
+
+       temp_rate = (old_rate > rate) ? old_rate : rate;
+       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
+
+       if (temp_div > RK3288_CORE_CLK_MAX_DIV) {
+               clk_debug("temp_div %d > max_div %d\n", temp_div,
+                               RK3288_CORE_CLK_MAX_DIV);
+               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
+                               __clk_get_rate(clk), arm_gpll_rate);
+               goto CHANGE_APLL;
+       }
+
+#if 0
+       if (clk_prepare(arm_gpll)) {
+               clk_err("fail to prepare arm_gpll path\n");
+               clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+
+       if (clk_enable(arm_gpll)) {
+               clk_err("fail to enable arm_gpll path\n");
+               clk_disable(arm_gpll);
+               clk_unprepare(arm_gpll);
+               goto CHANGE_APLL;
+       }
+#endif
+
+       local_irq_save(flags);
+
+       /* select gpll */
+       if (temp_div == 1) {
+               /* when old_rate/2 < (old_rate-arm_gpll_rate),
+                  we can set div to make rate change more gently */
+               if (old_rate > (2*arm_gpll_rate)) {
+                       cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
+                               RK3288_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
+               } else {
+                       cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
+                               RK3288_CRU_CLKSELS_CON(0));
+               }
+       } else {
+               cru_writel(RK3288_CORE_CLK_DIV(temp_div), RK3288_CRU_CLKSELS_CON(0));
+               cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
+                               RK3288_CRU_CLKSELS_CON(0));
+       }
+
+       sel_gpll = 1;
+       //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       clk_debug("temp select arm_gpll path, get rate %lu\n",
+                       arm_gpll_rate/temp_div);
+       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+                       temp_div);
+
+CHANGE_APLL:
+       ps = apll_get_best_set(rate, rk3288_apll_table);
+       clk_debug("apll will set rate %lu\n", ps->rate);
+       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
+                       ps->pllcon0, ps->pllcon1, ps->pllcon2,
+                       ps->clksel0, ps->clksel1);
+
+       local_irq_save(flags);
+
+       /* If core src don't select gpll, apll need to enter slow mode
+        * before reset
+        */
+       //FIXME
+       //if (!sel_gpll)
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       /* PLL enter rest */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       udelay(5);
+
+       /* return from rest */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       //wating lock state
+       udelay(ps->rst_dly);
+       pll_wait_lock(hw);
+
+       if (rate >= __clk_get_rate(hw->clk)) {
+               cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
+       }
+
+       /* PLL return from slow mode */
+       //FIXME
+       //if (!sel_gpll)
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       /* reparent to apll, and set div to 1 */
+       if (sel_gpll) {
+               if (temp_div == 1) {
+                       /* when rate/2 < (rate-arm_gpll_rate),
+                          we can set div to make rate change more gently */
+                       if (rate > (2*arm_gpll_rate)) {
+                               cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
+                               udelay(10);
+                               cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
+                               udelay(10);
+                               cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
+                                       RK3288_CRU_CLKSELS_CON(0));
+                               udelay(10);
+                               cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
+                               udelay(10);
+                               cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
+                       } else {
+                               cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
+                                               RK3288_CRU_CLKSELS_CON(0));
+                       }
+               } else {
+                       cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
+                               RK3288_CRU_CLKSELS_CON(0));
+                       cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
+               }
+       }
+
+       if (rate < __clk_get_rate(hw->clk)) {
+               cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
+       }
+
+       //loops_per_jiffy = ps->lpj;
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       if (sel_gpll) {
+               sel_gpll = 0;
+               //clk_disable(arm_gpll);
+               //clk_unprepare(arm_gpll);
+       }
+
+       //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
+
+       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
+                       ps->rate,
+                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
+                       cru_readl(RK3288_CRU_CLKSELS_CON(0)),
+                       cru_readl(RK3288_CRU_CLKSELS_CON(1)));
+
+       return 0;
+}
+
+
+static const struct clk_ops clk_pll_ops_3288_apll = {
+       .recalc_rate = clk_pll_recalc_rate_3288_apll,
+       .round_rate = clk_pll_round_rate_3288_apll,
+       .set_rate = clk_pll_set_rate_3288_apll,
+};
+
+/* CLK_PLL_3036_APLL type ops */
+#define FRAC_MODE      0
+static unsigned long rk3036_pll_clk_recalc(struct clk_hw *hw,
+unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long rate;
+       unsigned int dsmp = 0;
+       u64 rate64 = 0, frac_rate64 = 0;
+
+       dsmp = RK3036_PLL_GET_DSMPD(cru_readl(pll->reg + RK3188_PLL_CON(1)));
+
+       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
+               u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
+               u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
+               u32 pll_con2 = cru_readl(pll->reg + RK3188_PLL_CON(2));
+               /*integer mode*/
+               rate64 = (u64)parent_rate * RK3036_PLL_GET_FBDIV(pll_con0);
+               do_div(rate64, RK3036_PLL_GET_REFDIV(pll_con1));
+
+               if (FRAC_MODE == dsmp) {
+                       /*fractional mode*/
+                       frac_rate64 = (u64)parent_rate
+                       * RK3036_PLL_GET_FRAC(pll_con2);
+                       do_div(frac_rate64, RK3036_PLL_GET_REFDIV(pll_con1));
+                       rate64 += frac_rate64 >> 24;
+                       clk_debug("%s frac_rate=%llu(%08x/2^24) by pass mode\n",
+                                       __func__, frac_rate64 >> 24,
+                                       RK3036_PLL_GET_FRAC(pll_con2));
+               }
+               do_div(rate64, RK3036_PLL_GET_POSTDIV1(pll_con0));
+               do_div(rate64, RK3036_PLL_GET_POSTDIV2(pll_con1));
+
+               rate = rate64;
+               } else {
+               rate = parent_rate;
+               clk_debug("pll_clk_recalc rate=%lu by pass mode\n", rate);
+       }
+       return rate;
+}
+
+static unsigned long clk_pll_recalc_rate_3036_apll(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return rk3036_pll_clk_recalc(hw, parent_rate);
+}
+
+static long clk_pll_round_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate == __clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (apll_get_best_set(rate, rk3036_apll_table)->rate);
+}
+
+static  int rk3036_pll_clk_set_rate(struct pll_clk_set *clk_set,
+       struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+
+       /*enter slowmode*/
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+       pll->mode_offset);
+
+       cru_writel(clk_set->pllcon0,  pll->reg + RK3188_PLL_CON(0));
+       cru_writel(clk_set->pllcon1,  pll->reg + RK3188_PLL_CON(1));
+       cru_writel(clk_set->pllcon2,  pll->reg + RK3188_PLL_CON(2));
+
+       clk_debug("pllcon0%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
+       clk_debug("pllcon1%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
+       clk_debug("pllcon2%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
+       /*wating lock state*/
+       udelay(clk_set->rst_dly);
+       rk3036_pll_wait_lock(hw);
+
+       /*return form slow*/
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
+       pll->mode_offset);
+
+       return 0;
+}
+
+#define MIN_FOUTVCO_FREQ       (400 * 1000 * 1000)
+#define MAX_FOUTVCO_FREQ       (1600 * 1000 * 1000)
+static int rk3036_pll_clk_set_postdiv(unsigned long fout_hz,
+u32 *postdiv1, u32 *postdiv2, u32 *foutvco)
+{
+       if (fout_hz < MIN_FOUTVCO_FREQ) {
+               for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++)
+                       for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
+                               if (fout_hz * (*postdiv1) * (*postdiv2)
+                                       >= MIN_FOUTVCO_FREQ && fout_hz
+                                       * (*postdiv1) * (*postdiv2)
+                                       <= MAX_FOUTVCO_FREQ) {
+                                       *foutvco = fout_hz * (*postdiv1)
+                                               * (*postdiv2);
+                                       return 0;
+                               }
+                       }
+               clk_debug("CANNOT FINE postdiv1/2 to make fout in range from 400M to 1600M, fout = %lu\n",
+                               fout_hz);
+       } else {
+               *postdiv1 = 1;
+               *postdiv2 = 1;
+       }
+       return 0;
+}
+
+static int rk3036_pll_clk_get_set(unsigned long fin_hz, unsigned long fout_hz,
+               u32 *refdiv, u32 *fbdiv, u32 *postdiv1,
+               u32 *postdiv2, u32 *frac)
+{
+       /* FIXME set postdiv1/2 always 1*/
+       u32 gcd, foutvco = fout_hz;
+       u64 fin_64, frac_64;
+       u32 f_frac;
+
+       if (!fin_hz || !fout_hz || fout_hz == fin_hz)
+               return -1;
+
+       rk3036_pll_clk_set_postdiv(fout_hz, postdiv1, postdiv2, &foutvco);
+       if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
+               fin_hz /= MHZ;
+               foutvco /= MHZ;
+               gcd = clk_gcd(fin_hz, foutvco);
+               *refdiv = fin_hz / gcd;
+               *fbdiv = foutvco / gcd;
+
+               *frac = 0;
+
+               clk_debug("fin=%lu,fout=%lu,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
+                       fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
+       } else {
+               clk_debug("******frac div running, fin_hz=%lu, fout_hz=%lu,fin_INT_mhz=%lu, fout_INT_mhz=%lu\n",
+                       fin_hz, fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
+               clk_debug("******frac get postdiv1=%u, postdiv2=%u,foutvco=%u\n",
+                       *postdiv1, *postdiv2, foutvco);
+               gcd = clk_gcd(fin_hz / MHZ, foutvco / MHZ);
+               *refdiv = fin_hz / MHZ / gcd;
+               *fbdiv = foutvco / MHZ / gcd;
+               clk_debug("******frac get refdiv=%u, fbdiv=%u\n", *refdiv, *fbdiv);
+
+               *frac = 0;
+
+               f_frac = (foutvco % MHZ);
+               fin_64 = fin_hz;
+               do_div(fin_64, (u64)*refdiv);
+               frac_64 = (u64)f_frac << 24;
+               do_div(frac_64, fin_64);
+               *frac = (u32) frac_64;
+               clk_debug("frac=%x\n", *frac);
+       }
+       return 0;
+}
+static int rk3036_pll_set_con(struct clk_hw *hw, u32 refdiv, u32 fbdiv, u32 postdiv1, u32 postdiv2, u32 frac)
+{
+       struct pll_clk_set temp_clk_set;
+       temp_clk_set.pllcon0 = RK3036_PLL_SET_FBDIV(fbdiv) | RK3036_PLL_SET_POSTDIV1(postdiv1);
+       temp_clk_set.pllcon1 = RK3036_PLL_SET_REFDIV(refdiv) | RK3036_PLL_SET_POSTDIV2(postdiv2);
+       if (frac != 0)
+               temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(0);
+       else
+               temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(1);
+
+       temp_clk_set.pllcon2 = RK3036_PLL_SET_FRAC(frac);
+       temp_clk_set.rst_dly = 0;
+       clk_debug("setting....\n");
+       return rk3036_pll_clk_set_rate(&temp_clk_set, hw);
+}
+
+static int clk_pll_set_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       struct apll_clk_set *ps = (struct apll_clk_set *)(rk3036_apll_table);
+       struct clk *arm_gpll = __clk_lookup("clk_gpll");
+       struct clk *clk = hw->clk;
+       unsigned long flags, arm_gpll_rate, old_rate, temp_rate;
+       u32 temp_div;
+
+       while (ps->rate) {
+               if (ps->rate == rate) {
+                       break;
+               }
+               ps++;
+       }
+
+       if (ps->rate != rate) {
+               clk_err("%s: unsupport arm rate %lu\n", __func__, rate);
+               return 0;
+       }
+
+       if (!arm_gpll) {
+               clk_err("clk arm_gpll is NULL!\n");
+               return 0;
+       }
+
+       old_rate = __clk_get_rate(clk);
+       arm_gpll_rate = __clk_get_rate(arm_gpll);
+       if (soc_is_rk3128() || soc_is_rk3126())
+               arm_gpll_rate /= 2;
+
+       temp_rate = (old_rate > rate) ? old_rate : rate;
+       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
+
+       local_irq_save(flags);
+
+       if (rate >= old_rate) {
+               cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
+       }
+
+       /* set div first, then select gpll */
+       if (temp_div > 1)
+               cru_writel(RK3036_CLK_CORE_DIV(temp_div), RK3036_CRU_CLKSELS_CON(0));
+       cru_writel(RK3036_CORE_SEL_PLL(1), RK3036_CRU_CLKSELS_CON(0));
+
+       clk_debug("temp select arm_gpll path, get rate %lu\n",
+                 arm_gpll_rate/temp_div);
+       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+                 temp_div);
+
+       /**************enter slow mode 24M***********/
+       /*cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);*/
+       loops_per_jiffy = LPJ_24M;
+
+       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
+       clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
+       clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
+       clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
+       clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
+
+       /*wating lock state*/
+       udelay(ps->rst_dly);
+       rk3036_pll_wait_lock(hw);
+
+       /************select apll******************/
+       cru_writel(RK3036_CORE_SEL_PLL(0), RK3036_CRU_CLKSELS_CON(0));
+       /**************return slow mode***********/
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       cru_writel(RK3036_CLK_CORE_DIV(1), RK3036_CRU_CLKSELS_CON(0));
+
+       if (rate < old_rate) {
+               cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
+       }
+
+       loops_per_jiffy = ps->lpj;
+       local_irq_restore(flags);
+
+       return 0;       
+}
+static const struct clk_ops clk_pll_ops_3036_apll = {
+       .recalc_rate = clk_pll_recalc_rate_3036_apll,
+       .round_rate = clk_pll_round_rate_3036_apll,
+       .set_rate = clk_pll_set_rate_3036_apll,
+};
+
+
+/* CLK_PLL_3036_plus_autotype ops */
+
+static long clk_pll_round_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate == __clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                               __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (pll_com_get_best_set(rate, rk3036plus_pll_com_table)->rate);
+}
+
+static int clk_pll_set_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3036plus_pll_com_table);
+
+       clk_debug("******%s\n", __func__);
+       while (clk_set->rate) {
+               clk_debug("******%s clk_set->rate=%lu\n", __func__, clk_set->rate);
+               if (clk_set->rate == rate) {
+                       break;
+               }
+               clk_set++;
+       }
+       if (clk_set->rate == rate) {
+               rk3036_pll_clk_set_rate(clk_set, hw);
+       } else {
+               clk_debug("gpll is no corresponding rate=%lu\n", rate);
+               return -1;
+       }
+       clk_debug("******%s end\n", __func__);
+
+       return 0;       
+}
+
+static const struct clk_ops clk_pll_ops_3036plus_auto = {
+       .recalc_rate = clk_pll_recalc_rate_3036_apll,
+       .round_rate = clk_pll_round_rate_3036plus_auto,
+       .set_rate = clk_pll_set_rate_3036plus_auto,
+};
+
+static long clk_cpll_round_rate_312xplus(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       unsigned long best;
+
+       for (best = rate; best > 0; best--) {
+               if (!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
+                       return best;
+       }
+
+       return 0;
+}
+
+static int clk_cpll_set_rate_312xplus(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk312xplus_pll_com_table);
+       u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
+
+       while (clk_set->rate) {
+               if (clk_set->rate == rate) {
+                       break;
+               }
+               clk_set++;
+       }
+
+       if (clk_set->rate == rate) {
+               clk_debug("cpll get a rate %ld\n", rate);
+               rk3036_pll_clk_set_rate(clk_set, hw);
+
+       } else {
+               clk_debug("cpll get auto calc a rate\n");
+               if (rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac) != 0) {
+                       pr_err("cpll auto set rate error\n");
+                       return -ENOENT;
+               }
+               clk_debug("%s get rate=%lu, refdiv=%u, fbdiv=%u, postdiv1=%u, postdiv2=%u",
+                               __func__, rate, refdiv, fbdiv, postdiv1, postdiv2);
+               rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac);
+
+       }
+
+       clk_debug("setting OK\n");
+       return 0;
+}
+
+static const struct clk_ops clk_pll_ops_312xplus = {
+       .recalc_rate = clk_pll_recalc_rate_3036_apll,
+       .round_rate = clk_cpll_round_rate_312xplus,
+       .set_rate = clk_cpll_set_rate_312xplus,
+};
+
+static long clk_pll_round_rate_3368_apllb(struct clk_hw *hw, unsigned long rate,
+                                         unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate == __clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                         __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (apll_get_best_set(rate, rk3368_apllb_table)->rate);
+}
+
+/* 1: use, 0: no use */
+#define RK3368_APLLB_USE_GPLL  1
+
+/* when define 1, we will set div to make rate change gently, but it will cost
+ more time */
+#define RK3368_APLLB_DIV_MORE  1
+
+static int clk_pll_set_rate_3368_apllb(struct clk_hw *hw, unsigned long rate,
+                                      unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       struct clk *clk = hw->clk;
+       struct clk *arm_gpll = __clk_lookup("clk_gpll");
+       unsigned long arm_gpll_rate, temp_rate, old_rate;
+       const struct apll_clk_set *ps;
+       u32 temp_div;
+       unsigned long flags;
+       int sel_gpll = 0;
+
+       ps = apll_get_best_set(rate, rk3368_apllb_table);
+       clk_debug("apllb will set rate %lu\n", ps->rate);
+       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
+                 ps->pllcon0, ps->pllcon1, ps->pllcon2,
+                 ps->clksel0, ps->clksel1);
+
+#if !RK3368_APLLB_USE_GPLL
+       goto CHANGE_APLL;
+#endif
+
+       /* prepare arm_gpll before reparent clk_core to it */
+       if (!arm_gpll) {
+               clk_err("clk arm_gpll is NULL!\n");
+               goto CHANGE_APLL;
+       }
+
+       arm_gpll_rate = __clk_get_rate(arm_gpll);
+       old_rate = __clk_get_rate(clk);
+
+       temp_rate = (old_rate > rate) ? old_rate : rate;
+       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
+
+       if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
+               clk_debug("temp_div %d > max_div %d\n", temp_div,
+                         RK3368_CORE_CLK_MAX_DIV);
+               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
+                         __clk_get_rate(clk), arm_gpll_rate);
+               goto CHANGE_APLL;
+       }
+
+       local_irq_save(flags);
+
+       if (rate >= old_rate) {
+               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
+       }
+
+       /* select gpll */
+#if RK3368_APLLB_DIV_MORE
+       if (temp_div == 1) {
+               /* when old_rate/2 < (old_rate-arm_gpll_rate),
+                  we can set div to make rate change more gently */
+               if (old_rate > (2*arm_gpll_rate)) {
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                                  RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
+               } else {
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                                  RK3368_CRU_CLKSELS_CON(0));
+               }
+       } else {
+               cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
+               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                          RK3368_CRU_CLKSELS_CON(0));
+       }
+#else
+       cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
+       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                  RK3368_CRU_CLKSELS_CON(0));
+#endif
+
+       sel_gpll = 1;
+
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       clk_debug("temp select arm_gpll path, get rate %lu\n",
+                 arm_gpll_rate/temp_div);
+       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+                 temp_div);
+
+CHANGE_APLL:
+       local_irq_save(flags);
+
+       /* apll enter slow mode */
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+                  pll->mode_offset);
+
+       /* PLL enter reset */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       udelay(5);
+
+       /* return from rest */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       /* wating lock state */
+       udelay(ps->rst_dly);
+       pll_wait_lock(hw);
+
+       if (!sel_gpll) {
+               if (rate >= old_rate) {
+                       cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
+                       cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
+               }
+       }
+
+       /* apll return from slow mode */
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
+                  pll->mode_offset);
+
+       /* reparent to apll, and set div to 1 */
+       if (sel_gpll) {
+#if RK3368_APLLB_DIV_MORE
+               /* when rate/2 < (rate-arm_gpll_rate), we can set div to make
+                  rate change more gently */
+               if ((temp_div == 1) && (rate > (2*arm_gpll_rate))) {
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+                                  RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
+                       udelay(10);
+               } else
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+                                  RK3368_CRU_CLKSELS_CON(0));
+#else
+               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+                          RK3368_CRU_CLKSELS_CON(0));
+#endif
+       }
+
+       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
+
+       if (rate < old_rate) {
+               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
+               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
+       }
+
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       if (sel_gpll)
+               sel_gpll = 0;
+
+       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
+                 ps->rate,
+                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                 cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                 cru_readl(pll->reg + RK3188_PLL_CON(3)),
+                 cru_readl(RK3368_CRU_CLKSELS_CON(0)),
+                 cru_readl(RK3368_CRU_CLKSELS_CON(1)));
+
+       return 0;
+}
+
+static const struct clk_ops clk_pll_ops_3368_apllb = {
+       .recalc_rate = clk_pll_recalc_rate_3188plus,
+       .round_rate = clk_pll_round_rate_3368_apllb,
+       .set_rate = clk_pll_set_rate_3368_apllb,
+};
+
+static long clk_pll_round_rate_3368_aplll(struct clk_hw *hw, unsigned long rate,
+                                         unsigned long *prate)
+{
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       if (parent && (rate == __clk_get_rate(parent))) {
+               clk_debug("pll %s round rate=%lu equal to parent rate\n",
+                         __clk_get_name(hw->clk), rate);
+               return rate;
+       }
+
+       return (apll_get_best_set(rate, rk3368_aplll_table)->rate);
+}
+
+/* 1: use, 0: no use */
+#define RK3368_APLLL_USE_GPLL  1
+
+/* when define 1, we will set div to make rate change gently, but it will cost
+ more time */
+#define RK3368_APLLL_DIV_MORE  1
+
+static int clk_pll_set_rate_3368_aplll(struct clk_hw *hw, unsigned long rate,
+                                      unsigned long parent_rate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       struct clk *clk = hw->clk;
+       struct clk *arm_gpll = __clk_lookup("clk_gpll");
+       unsigned long arm_gpll_rate, temp_rate, old_rate;
+       const struct apll_clk_set *ps;
+       u32 temp_div;
+       unsigned long flags;
+       int sel_gpll = 0;
+
+       ps = apll_get_best_set(rate, rk3368_aplll_table);
+       clk_debug("aplll will set rate %lu\n", ps->rate);
+       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
+                 ps->pllcon0, ps->pllcon1, ps->pllcon2,
+                 ps->clksel0, ps->clksel1);
+
+#if !RK3368_APLLL_USE_GPLL
+       goto CHANGE_APLL;
+#endif
+
+       /* prepare arm_gpll before reparent clk_core to it */
+       if (!arm_gpll) {
+               clk_err("clk arm_gpll is NULL!\n");
+               goto CHANGE_APLL;
+       }
+
+       arm_gpll_rate = __clk_get_rate(arm_gpll);
+       old_rate = __clk_get_rate(clk);
+
+       temp_rate = (old_rate > rate) ? old_rate : rate;
+       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
+
+       if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
+               clk_debug("temp_div %d > max_div %d\n", temp_div,
+                         RK3368_CORE_CLK_MAX_DIV);
+               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
+                         __clk_get_rate(clk), arm_gpll_rate);
+               goto CHANGE_APLL;
+       }
+
+       local_irq_save(flags);
+
+       if (rate >= old_rate) {
+               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
+               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
+       }
+
+       /* select gpll */
+#if RK3368_APLLL_DIV_MORE
+       if (temp_div == 1) {
+               /* when old_rate/2 < (old_rate-arm_gpll_rate),
+                  we can set div to make rate change more gently */
+               if (old_rate > (2*arm_gpll_rate)) {
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                                  RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
+               } else {
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                                  RK3368_CRU_CLKSELS_CON(2));
+               }
+       } else {
+               cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
+               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                          RK3368_CRU_CLKSELS_CON(2));
+       }
+#else
+               cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
+               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
+                          RK3368_CRU_CLKSELS_CON(2));
+#endif
+
+       sel_gpll = 1;
+
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       clk_debug("temp select arm_gpll path, get rate %lu\n",
+                 arm_gpll_rate/temp_div);
+       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
+                 temp_div);
+
+CHANGE_APLL:
+       local_irq_save(flags);
+
+       /* apll enter slow mode */
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
+                  pll->mode_offset);
+
+       /* PLL enter reset */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       udelay(5);
+
+       /* return from rest */
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       /* wating lock state */
+       udelay(ps->rst_dly);
+       pll_wait_lock(hw);
+
+       if (!sel_gpll) {
+               if (rate >= old_rate) {
+                       cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
+                       cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
+               }
+       }
+
+       /* apll return from slow mode */
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
+                  pll->mode_offset);
+
+       /* reparent to apll, and set div to 1 */
+       if (sel_gpll) {
+#if RK3368_APLLL_DIV_MORE
+               /* when rate/2 < (rate-arm_gpll_rate), we can set div to make
+                  rate change more gently */
+               if ((temp_div == 1) && (rate > (2*arm_gpll_rate))) {
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+                                  RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
+                       udelay(10);
+               } else
+                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+                                  RK3368_CRU_CLKSELS_CON(2));
+#else
+               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
+                          RK3368_CRU_CLKSELS_CON(2));
+#endif
+       }
+
+       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
+
+       if (rate < old_rate) {
+               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
+               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
+       }
+
+       smp_wmb();
+
+       local_irq_restore(flags);
+
+       if (sel_gpll)
+               sel_gpll = 0;
+
+       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
+                 ps->rate,
+                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                 cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                 cru_readl(pll->reg + RK3188_PLL_CON(3)),
+                 cru_readl(RK3368_CRU_CLKSELS_CON(2)),
+                 cru_readl(RK3368_CRU_CLKSELS_CON(3)));
+
+       return 0;
+}
+
+static const struct clk_ops clk_pll_ops_3368_aplll = {
+       .recalc_rate = clk_pll_recalc_rate_3188plus,
+       .round_rate = clk_pll_round_rate_3368_aplll,
+       .set_rate = clk_pll_set_rate_3368_aplll,
+};
+
+const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
+{
+       switch (pll_flags) {
+               case CLK_PLL_3188:
+                       return &clk_pll_ops_3188;
+
+               case CLK_PLL_3188_APLL:
+                       return &clk_pll_ops_3188_apll;
+
+               case CLK_PLL_3188PLUS:
+                       return &clk_pll_ops_3188plus;
+
+               case CLK_PLL_3188PLUS_APLL:
+                       return &clk_pll_ops_3188plus_apll;
+
+               case CLK_PLL_3288_APLL:
+                       return &clk_pll_ops_3288_apll;
+
+               case CLK_PLL_3188PLUS_AUTO:
+                       return &clk_pll_ops_3188plus_auto;
+
+               case CLK_PLL_3036_APLL:
+                       return &clk_pll_ops_3036_apll;
+
+               case CLK_PLL_3036PLUS_AUTO:
+                       return &clk_pll_ops_3036plus_auto;
+
+               case CLK_PLL_312XPLUS:
+                       return &clk_pll_ops_312xplus;
+
+               case CLK_PLL_3368_APLLB:
+                       return &clk_pll_ops_3368_apllb;
+
+               case CLK_PLL_3368_APLLL:
+                       return &clk_pll_ops_3368_aplll;
+
+               case CLK_PLL_3368_LOW_JITTER:
+                       return &clk_pll_ops_3368_low_jitter;
+
+               default:
+                       clk_err("%s: unknown pll_flags!\n", __func__);
+                       return NULL;
+       }
+}
+
+struct clk *rk_clk_register_pll(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags, u32 reg,
+               u32 width, u32 mode_offset, u8 mode_shift,
+               u32 status_offset, u8 status_shift, u32 pll_flags,
+               spinlock_t *lock)
+{
+       struct clk_pll *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+
+       clk_debug("%s: pll name = %s, pll_flags = 0x%x, register start!\n",
+                       __func__, name, pll_flags);
+
+       /* allocate the pll */
+       pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
+       if (!pll) {
+               clk_err("%s: could not allocate pll clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = name;
+       init.flags = flags;
+       init.parent_names = (parent_name ? &parent_name: NULL);
+       init.num_parents = (parent_name ? 1 : 0);
+       init.ops = rk_get_pll_ops(pll_flags);
+
+       /* struct clk_pll assignments */
+       pll->reg = reg;
+       pll->width = width;
+       pll->mode_offset = mode_offset;
+       pll->mode_shift = mode_shift;
+       pll->status_offset = status_offset;
+       pll->status_shift = status_shift;
+       pll->flags = pll_flags;
+       pll->lock = lock;
+       pll->hw.init = &init;
+
+       /* register the clock */
+       clk = clk_register(dev, &pll->hw);
+
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       clk_debug("%s: pll name = %s, pll_flags = 0x%x, register finish!\n",
+                       __func__, name, pll_flags);
+
+       return clk;
+}
+
diff --git a/drivers/clk/rk/clk-pll.h b/drivers/clk/rk/clk-pll.h
new file mode 100755 (executable)
index 0000000..79804b2
--- /dev/null
@@ -0,0 +1,498 @@
+#ifndef __RK_CLK_PLL_H
+#define __RK_CLK_PLL_H
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/rockchip/cru.h>
+
+
+#define CLK_LOOPS_JIFFY_REF    (11996091ULL)
+#define CLK_LOOPS_RATE_REF     (1200UL) //Mhz
+#define CLK_LOOPS_RECALC(rate)  \
+       div_u64(CLK_LOOPS_JIFFY_REF*(rate),CLK_LOOPS_RATE_REF*MHZ)
+
+#define CLK_DIV_PLUS_ONE_SET(i, shift, width)  \
+       ((((i)-1) << (shift)) | (((2<<(width)) - 1) << ((shift)+16)))
+
+/*******************RK3188 PLL******************************/
+#define RK3188_PLL_CON(i)      ((i) * 4)
+/*******************PLL WORK MODE*************************/
+#define _RK3188_PLL_MODE_MSK           0x3
+#define _RK3188_PLL_MODE_SLOW          0x0
+#define _RK3188_PLL_MODE_NORM          0x1
+#define _RK3188_PLL_MODE_DEEP          0x2
+
+#define _RK3188_PLL_MODE_GET(offset, shift)    \
+       ((cru_readl(offset) >> (shift)) & _RK3188_PLL_MODE_MSK)
+
+#define _RK3188_PLL_MODE_IS_SLOW(offset, shift)        \
+       (_RK3188_PLL_MODE_GET(offset, shift) == _RK3188_PLL_MODE_SLOW)
+
+#define _RK3188_PLL_MODE_IS_NORM(offset, shift)        \
+       (_RK3188_PLL_MODE_GET(offset, shift) == _RK3188_PLL_MODE_NORM)
+
+#define _RK3188_PLL_MODE_IS_DEEP(offset, shift)        \
+       (_RK3188_PLL_MODE_GET(offset, shift) == _RK3188_PLL_MODE_DEEP)
+
+#define _RK3188_PLL_MODE_SET(val, shift)       \
+       ((val) << (shift)) | CRU_W_MSK(shift, _RK3188_PLL_MODE_MSK)
+
+#define _RK3188_PLL_MODE_SLOW_SET(shift)       \
+       _RK3188_PLL_MODE_SET(_RK3188_PLL_MODE_SLOW, shift)
+
+#define _RK3188_PLL_MODE_NORM_SET(shift)       \
+       _RK3188_PLL_MODE_SET(_RK3188_PLL_MODE_NORM, shift)
+
+#define _RK3188_PLL_MODE_DEEP_SET(shift)       \
+       _RK3188_PLL_MODE_SET(_RK3188_PLL_MODE_DEEP, shift)
+
+/*******************PLL OPERATION MODE*********************/
+#define _RK3188_PLL_BYPASS_SHIFT       0
+#define _RK3188_PLL_POWERDOWN_SHIFT    1
+
+#define _RK3188PLUS_PLL_BYPASS_SHIFT   0
+#define _RK3188PLUS_PLL_POWERDOWN_SHIFT        1
+#define _RK3188PLUS_PLL_RESET_SHIFT    5
+
+#define _RK3188_PLL_OP_SET(val, shift) \
+       ((val) << (shift)) | CRU_W_MSK(shift, 1)
+
+#define _RK3188_PLL_BYPASS_SET(val)    \
+       _RK3188_PLL_OP_SET(val, _RK3188_PLL_BYPASS_SHIFT)
+
+#define _RK3188_PLL_POWERDOWN_SET(val) \
+       _RK3188_PLL_OP_SET(val, _RK3188_PLL_POWERDOWN_SHIFT)
+
+#define _RK3188PLUS_PLL_BYPASS_SET(val)        \
+       _RK3188_PLL_OP_SET(val, _RK3188PLUS_PLL_BYPASS_SHIFT)
+
+#define _RK3188PLUS_PLL_POWERDOWN_SET(val)     \
+       _RK3188_PLL_OP_SET(val, _RK3188PLUS_PLL_POWERDOWN_SHIFT)
+
+#define _RK3188PLUS_PLL_RESET_SET(val) \
+       _RK3188_PLL_OP_SET(val, _RK3188PLUS_PLL_RESET_SHIFT)
+
+/*******************PLL CON0 BITS***************************/
+#define RK3188_PLL_CLKFACTOR_SET(val, shift, msk) \
+       ((((val) - 1) & (msk)) << (shift))
+
+#define RK3188_PLL_CLKFACTOR_GET(reg, shift, msk) \
+       ((((reg) >> (shift)) & (msk)) + 1)
+
+#define RK3188_PLL_OD_MSK              (0x3f)
+#define RK3188_PLL_OD_SHIFT            (0x0)
+#define RK3188_PLL_CLKOD(val)          RK3188_PLL_CLKFACTOR_SET(val, RK3188_PLL_OD_SHIFT, RK3188_PLL_OD_MSK)
+#define RK3188_PLL_NO(reg)             RK3188_PLL_CLKFACTOR_GET(reg, RK3188_PLL_OD_SHIFT, RK3188_PLL_OD_MSK)
+#define RK3188_PLL_CLKOD_SET(val)      (RK3188_PLL_CLKOD(val) | CRU_W_MSK(RK3188_PLL_OD_SHIFT, RK3188_PLL_OD_MSK))
+
+#define RK3188_PLL_NR_MSK              (0x3f)
+#define RK3188_PLL_NR_SHIFT            (8)
+#define RK3188_PLL_CLKR(val)           RK3188_PLL_CLKFACTOR_SET(val, RK3188_PLL_NR_SHIFT, RK3188_PLL_NR_MSK)
+#define RK3188_PLL_NR(reg)             RK3188_PLL_CLKFACTOR_GET(reg, RK3188_PLL_NR_SHIFT, RK3188_PLL_NR_MSK)
+#define RK3188_PLL_CLKR_SET(val)       (RK3188_PLL_CLKR(val) | CRU_W_MSK(RK3188_PLL_NR_SHIFT, RK3188_PLL_NR_MSK))
+
+#define RK3188PLUS_PLL_OD_MSK          (0xf)
+#define RK3188PLUS_PLL_OD_SHIFT        (0x0)
+#define RK3188PLUS_PLL_CLKOD(val)      RK3188_PLL_CLKFACTOR_SET(val, RK3188PLUS_PLL_OD_SHIFT, RK3188PLUS_PLL_OD_MSK)
+#define RK3188PLUS_PLL_NO(reg)         RK3188_PLL_CLKFACTOR_GET(reg, RK3188PLUS_PLL_OD_SHIFT, RK3188PLUS_PLL_OD_MSK)
+#define RK3188PLUS_PLL_CLKOD_SET(val)  (RK3188PLUS_PLL_CLKOD(val) | CRU_W_MSK(RK3188PLUS_PLL_OD_SHIFT, RK3188PLUS_PLL_OD_MSK))
+
+#define RK3188PLUS_PLL_NR_MSK          (0x3f)
+#define RK3188PLUS_PLL_NR_SHIFT                (8)
+#define RK3188PLUS_PLL_CLKR(val)       RK3188_PLL_CLKFACTOR_SET(val, RK3188PLUS_PLL_NR_SHIFT, RK3188PLUS_PLL_NR_MSK)
+#define RK3188PLUS_PLL_NR(reg)         RK3188_PLL_CLKFACTOR_GET(reg, RK3188PLUS_PLL_NR_SHIFT, RK3188PLUS_PLL_NR_MSK)
+#define RK3188PLUS_PLL_CLKR_SET(val)   (RK3188PLUS_PLL_CLKR(val) | CRU_W_MSK(RK3188PLUS_PLL_NR_SHIFT, RK3188PLUS_PLL_NR_MSK))
+
+/*******************PLL CON1 BITS***************************/
+#define RK3188_PLL_NF_MSK              (0xffff)
+#define RK3188_PLL_NF_SHIFT            (0)
+#define RK3188_PLL_CLKF(val)           RK3188_PLL_CLKFACTOR_SET(val, RK3188_PLL_NF_SHIFT, RK3188_PLL_NF_MSK)
+#define RK3188_PLL_NF(reg)             RK3188_PLL_CLKFACTOR_GET(reg, RK3188_PLL_NF_SHIFT, RK3188_PLL_NF_MSK)
+#define RK3188_PLL_CLKF_SET(val)       (RK3188_PLL_CLKF(val) | CRU_W_MSK(RK3188_PLL_NF_SHIFT, RK3188_PLL_NF_MSK))
+
+#define RK3188PLUS_PLL_NF_MSK          (0x1fff)
+#define RK3188PLUS_PLL_NF_SHIFT                (0)
+#define RK3188PLUS_PLL_CLKF(val)       RK3188_PLL_CLKFACTOR_SET(val, RK3188PLUS_PLL_NF_SHIFT, RK3188PLUS_PLL_NF_MSK)
+#define RK3188PLUS_PLL_NF(reg)         RK3188_PLL_CLKFACTOR_GET(reg, RK3188PLUS_PLL_NF_SHIFT, RK3188PLUS_PLL_NF_MSK)
+#define RK3188PLUS_PLL_CLKF_SET(val)   (RK3188PLUS_PLL_CLKF(val) | CRU_W_MSK(RK3188PLUS_PLL_NF_SHIFT, RK3188PLUS_PLL_NF_MSK))
+
+/*******************PLL CON2 BITS***************************/
+#define RK3188_PLL_BWADJ_MSK           (0xfff)
+#define RK3188_PLL_BWADJ_SHIFT         (0)
+#define RK3188_PLL_CLK_BWADJ_SET(val)  ((val) | CRU_W_MSK(RK3188_PLL_BWADJ_SHIFT, RK3188_PLL_BWADJ_MSK))
+
+#define RK3188PLUS_PLL_BWADJ_MSK       (0xfff)
+#define RK3188PLUS_PLL_BWADJ_SHIFT     (0)
+#define RK3188PLUS_PLL_CLK_BWADJ_SET(val)      ((val) | CRU_W_MSK(RK3188PLUS_PLL_BWADJ_SHIFT, RK3188PLUS_PLL_BWADJ_MSK))
+
+/*******************PLL CON3 BITS***************************/
+#define RK3188_PLL_RESET_MSK           (1 << 5)
+#define RK3188_PLL_RESET_W_MSK         (RK3188_PLL_RESET_MSK << 16)
+#define RK3188_PLL_RESET               (1 << 5)
+#define RK3188_PLL_RESET_RESUME                (0 << 5)
+
+#define RK3188_PLL_BYPASS_MSK          (1 << 0)
+#define RK3188_PLL_BYPASS              (1 << 0)
+#define RK3188_PLL_NO_BYPASS           (0 << 0)
+
+#define RK3188_PLL_PWR_DN_MSK          (1 << 1)
+#define RK3188_PLL_PWR_DN_W_MSK                (RK3188_PLL_PWR_DN_MSK << 16)
+#define RK3188_PLL_PWR_DN              (1 << 1)
+#define RK3188_PLL_PWR_ON              (0 << 1)
+
+#define RK3188_PLL_STANDBY_MSK         (1 << 2)
+#define RK3188_PLL_STANDBY             (1 << 2)
+#define RK3188_PLL_NO_STANDBY          (0 << 2)
+
+/*******************CLKSEL0 BITS***************************/
+//core_preiph div
+#define RK3188_CORE_PERIPH_W_MSK       (3 << 22)
+#define RK3188_CORE_PERIPH_MSK         (3 << 6)
+#define RK3188_CORE_PERIPH_2           (0 << 6)
+#define RK3188_CORE_PERIPH_4           (1 << 6)
+#define RK3188_CORE_PERIPH_8           (2 << 6)
+#define RK3188_CORE_PERIPH_16          (3 << 6)
+
+//clk_core
+#define RK3188_CORE_SEL_PLL_MSK                (1 << 8)
+#define RK3188_CORE_SEL_PLL_W_MSK      (1 << 24)
+#define RK3188_CORE_SEL_APLL           (0 << 8)
+#define RK3188_CORE_SEL_GPLL           (1 << 8)
+
+#define RK3188_CORE_CLK_DIV_W_MSK      (0x1F << 25)
+#define RK3188_CORE_CLK_DIV_MSK                (0x1F << 9)
+#define RK3188_CORE_CLK_DIV(i)         ((((i) - 1) & 0x1F) << 9)
+#define RK3188_CORE_CLK_MAX_DIV                32
+
+/*******************CLKSEL1 BITS***************************/
+//aclk_core div
+#define RK3188_CORE_ACLK_W_MSK         (7 << 19)
+#define RK3188_CORE_ACLK_MSK           (7 << 3)
+#define RK3188_CORE_ACLK_11            (0 << 3)
+#define RK3188_CORE_ACLK_21            (1 << 3)
+#define RK3188_CORE_ACLK_31            (2 << 3)
+#define RK3188_CORE_ACLK_41            (3 << 3)
+#define RK3188_CORE_ACLK_81            (4 << 3)
+#define RK3188_GET_CORE_ACLK_VAL(reg)  ((reg)>=4 ? 8:((reg)+1))
+
+/*******************PLL SET*********************************/
+#define _RK3188_PLL_SET_CLKS(_mhz, nr, nf, no) \
+{ \
+       .rate   = (_mhz) * KHZ, \
+       .pllcon0 = RK3188_PLL_CLKR_SET(nr)|RK3188_PLL_CLKOD_SET(no), \
+       .pllcon1 = RK3188_PLL_CLKF_SET(nf),\
+       .pllcon2 = RK3188_PLL_CLK_BWADJ_SET(nf >> 1),\
+       .rst_dly = ((nr*500)/24+1),\
+}
+
+#define _RK3188PLUS_PLL_SET_CLKS(_mhz, nr, nf, no) \
+{ \
+       .rate   = (_mhz) * KHZ, \
+       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no), \
+       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
+       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1),\
+       .rst_dly = ((nr*500)/24+1),\
+}
+
+#define _RK3188PLUS_PLL_SET_CLKS_NB(_mhz, nr, nf, no, nb) \
+{ \
+       .rate   = (_mhz) * KHZ, \
+       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no), \
+       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
+       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nb-1),\
+       .rst_dly = ((nr*500)/24+1),\
+}
+
+#define _RK3188_APLL_SET_CLKS(_mhz, nr, nf, no, _periph_div, _aclk_div) \
+{ \
+       .rate   = _mhz * MHZ, \
+       .pllcon0 = RK3188_PLL_CLKR_SET(nr) | RK3188_PLL_CLKOD_SET(no), \
+       .pllcon1 = RK3188_PLL_CLKF_SET(nf),\
+       .pllcon2 = RK3188_PLL_CLK_BWADJ_SET(nf >> 1),\
+       .rst_dly = ((nr*500)/24+1),\
+       .clksel0 = RK3188_CORE_PERIPH_W_MSK | RK3188_CORE_PERIPH_##_periph_div,\
+       .clksel1 = RK3188_CORE_ACLK_W_MSK | RK3188_CORE_ACLK_##_aclk_div,\
+       .lpj = (CLK_LOOPS_JIFFY_REF*_mhz) / CLK_LOOPS_RATE_REF,\
+}
+
+
+/*******************RK3288 PLL***********************************/
+/*******************CLKSEL0 BITS***************************/
+#define RK3288_CORE_SEL_PLL_W_MSK      (1 << 31)
+#define RK3288_CORE_SEL_APLL           (0 << 15)
+#define RK3288_CORE_SEL_GPLL           (1 << 15)
+
+#define RK3288_CORE_CLK_SHIFT          8
+#define RK3288_CORE_CLK_WIDTH          5
+#define RK3288_CORE_CLK_DIV(i) \
+       CLK_DIV_PLUS_ONE_SET(i, RK3288_CORE_CLK_SHIFT, RK3288_CORE_CLK_WIDTH)
+#define RK3288_CORE_CLK_MAX_DIV                (2<<RK3288_CORE_CLK_WIDTH)
+
+#define RK3288_ACLK_M0_SHIFT           0
+#define RK3288_ACLK_M0_WIDTH           4
+#define RK3288_ACLK_M0_DIV(i)  \
+       CLK_DIV_PLUS_ONE_SET(i, RK3288_ACLK_M0_SHIFT, RK3288_ACLK_M0_WIDTH)
+
+#define RK3288_ACLK_MP_SHIFT           4
+#define RK3288_ACLK_MP_WIDTH           4
+#define RK3288_ACLK_MP_DIV(i)  \
+       CLK_DIV_PLUS_ONE_SET(i, RK3288_ACLK_MP_SHIFT, RK3288_ACLK_MP_WIDTH)
+
+/*******************CLKSEL37 BITS***************************/
+#define RK3288_CLK_L2RAM_SHIFT         0
+#define RK3288_CLK_L2RAM_WIDTH         3
+#define RK3288_CLK_L2RAM_DIV(i)        \
+       CLK_DIV_PLUS_ONE_SET(i, RK3288_CLK_L2RAM_SHIFT, RK3288_CLK_L2RAM_WIDTH)
+
+#define RK3288_ATCLK_SHIFT             4
+#define RK3288_ATCLK_WIDTH             5
+#define RK3288_ATCLK_DIV(i)    \
+       CLK_DIV_PLUS_ONE_SET(i, RK3288_ATCLK_SHIFT, RK3288_ATCLK_WIDTH)
+
+#define RK3288_PCLK_DBG_SHIFT          9
+#define RK3288_PCLK_DBG_WIDTH          5
+#define RK3288_PCLK_DBG_DIV(i) \
+       CLK_DIV_PLUS_ONE_SET(i, RK3288_PCLK_DBG_SHIFT, RK3288_PCLK_DBG_WIDTH)
+
+#define _RK3288_APLL_SET_CLKS(_mhz, nr, nf, no, l2_div, m0_div, mp_div, atclk_div, pclk_dbg_div) \
+{ \
+       .rate   = _mhz * MHZ, \
+       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr) | RK3188PLUS_PLL_CLKOD_SET(no), \
+       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
+       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1),\
+       .rst_dly = ((nr*500)/24+1),\
+       .clksel0 = RK3288_ACLK_M0_DIV(m0_div) | RK3288_ACLK_MP_DIV(mp_div),\
+       .clksel1 = RK3288_CLK_L2RAM_DIV(l2_div) | RK3288_ATCLK_DIV(atclk_div) | RK3288_PCLK_DBG_DIV(pclk_dbg_div),\
+       .lpj = (CLK_LOOPS_JIFFY_REF*_mhz) / CLK_LOOPS_RATE_REF,\
+}
+/***************************RK3036 PLL**************************************/
+#define LPJ_24M        (CLK_LOOPS_JIFFY_REF * 24) / CLK_LOOPS_RATE_REF
+/*PLL_CON 0,1,2*/
+#define RK3036_PLL_PWR_ON                      (0)
+#define RK3036_PLL_PWR_DN                      (1)
+#define RK3036_PLL_BYPASS                      (1 << 15)
+#define RK3036_PLL_NO_BYPASS                   (0 << 15)
+/*con0*/
+#define RK3036_PLL_BYPASS_SHIFT                (15)
+
+#define RK3036_PLL_POSTDIV1_MASK               (0x7)
+#define RK3036_PLL_POSTDIV1_SHIFT              (12)
+#define RK3036_PLL_FBDIV_MASK                  (0xfff)
+#define RK3036_PLL_FBDIV_SHIFT                 (0)
+
+/*con1*/
+#define RK3036_PLL_RSTMODE_SHIFT               (15)
+#define RK3036_PLL_RST_SHIFT                   (14)
+#define RK3036_PLL_PWR_DN_SHIFT                (13)
+#define RK3036_PLL_DSMPD_SHIFT                 (12)
+#define RK3036_PLL_LOCK_SHIFT                  (10)
+
+#define RK3036_PLL_POSTDIV2_MASK               (0x7)
+#define RK3036_PLL_POSTDIV2_SHIFT              (6)
+#define RK3036_PLL_REFDIV_MASK                 (0x3f)
+#define RK3036_PLL_REFDIV_SHIFT                (0)
+
+/*con2*/
+#define RK3036_PLL_FOUT4PHASE_PWR_DN_SHIFT     (27)
+#define RK3036_PLL_FOUTVCO_PWR_DN_SHIFT        (26)
+#define RK3036_PLL_FOUTPOSTDIV_PWR_DN_SHIFT    (25)
+#define RK3036_PLL_DAC_PWR_DN_SHIFT            (24)
+
+#define RK3036_PLL_FRAC_MASK                   (0xffffff)
+#define RK3036_PLL_FRAC_SHIFT                  (0)
+
+#define CRU_GET_REG_BIT_VAL(reg, bits_shift)           (((reg) >> (bits_shift)) & (0x1))
+#define CRU_GET_REG_BITS_VAL(reg, bits_shift, msk)     (((reg) >> (bits_shift)) & (msk))
+#define CRU_SET_BIT(val, bits_shift)                   (((val) & (0x1)) << (bits_shift))
+#define CRU_W_MSK(bits_shift, msk)                     ((msk) << ((bits_shift) + 16))
+
+#define CRU_W_MSK_SETBITS(val, bits_shift, msk)        (CRU_W_MSK(bits_shift, msk)     \
+                                                       | CRU_SET_BITS(val, bits_shift, msk))
+#define CRU_W_MSK_SETBIT(val, bits_shift)              (CRU_W_MSK(bits_shift, 0x1)     \
+                                                       | CRU_SET_BIT(val, bits_shift))
+
+#define RK3036_PLL_SET_REFDIV(val)                             CRU_W_MSK_SETBITS(val, RK3036_PLL_REFDIV_SHIFT, RK3036_PLL_REFDIV_MASK)
+#define RK3036_PLL_SET_FBDIV(val)                              CRU_W_MSK_SETBITS(val, RK3036_PLL_FBDIV_SHIFT, RK3036_PLL_FBDIV_MASK)
+#define RK3036_PLL_SET_POSTDIV1(val)                           CRU_W_MSK_SETBITS(val, RK3036_PLL_POSTDIV1_SHIFT, RK3036_PLL_POSTDIV1_MASK)
+#define RK3036_PLL_SET_POSTDIV2(val)                           CRU_W_MSK_SETBITS(val, RK3036_PLL_POSTDIV2_SHIFT, RK3036_PLL_POSTDIV2_MASK)
+#define RK3036_PLL_SET_FRAC(val)                               CRU_SET_BITS(val, RK3036_PLL_FRAC_SHIFT, RK3036_PLL_FRAC_MASK)
+
+#define RK3036_PLL_GET_REFDIV(reg)                             CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_REFDIV_SHIFT, RK3036_PLL_REFDIV_MASK)
+#define RK3036_PLL_GET_FBDIV(reg)                              CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_FBDIV_SHIFT, RK3036_PLL_FBDIV_MASK)
+#define RK3036_PLL_GET_POSTDIV1(reg)                           CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_POSTDIV1_SHIFT, RK3036_PLL_POSTDIV1_MASK)
+#define RK3036_PLL_GET_POSTDIV2(reg)                           CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_POSTDIV2_SHIFT, RK3036_PLL_POSTDIV2_MASK)
+#define RK3036_PLL_GET_FRAC(reg)                               CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_FRAC_SHIFT, RK3036_PLL_FRAC_MASK)
+
+/*#define APLL_SET_BYPASS(val)                         CRU_SET_BIT(val, PLL_BYPASS_SHIFT)*/
+#define RK3036_PLL_SET_DSMPD(val)                              CRU_W_MSK_SETBIT(val, RK3036_PLL_DSMPD_SHIFT)
+#define RK3036_PLL_GET_DSMPD(reg)                              CRU_GET_REG_BIT_VAL(reg, RK3036_PLL_DSMPD_SHIFT)
+
+/*******************CLKSEL0 BITS***************************/
+#define RK3036_CLK_SET_DIV_CON_SUB1(val, bits_shift, msk)      CRU_W_MSK_SETBITS((val - 1), bits_shift, msk)
+
+#define RK3036_CPU_CLK_PLL_SEL_SHIFT           (14)
+#define RK3036_CPU_CLK_PLL_SEL_MASK    (0x3)
+#define RK3036_CORE_CLK_PLL_SEL_SHIFT          (7)
+#define RK3036_SEL_APLL                        (0)
+#define RK3036_SEL_GPLL                        (1)
+#define RK3036_CPU_SEL_PLL(plls)               CRU_W_MSK_SETBITS(plls, RK3036_CPU_CLK_PLL_SEL_SHIFT, RK3036_CPU_CLK_PLL_SEL_MASK)
+#define RK3036_CORE_SEL_PLL(plls)              CRU_W_MSK_SETBIT(plls, RK3036_CORE_CLK_PLL_SEL_SHIFT)
+
+#define RK3036_ACLK_CPU_DIV_MASK               (0x1f)
+#define RK3036_ACLK_CPU_DIV_SHIFT              (8)
+#define RK3036_A9_CORE_DIV_MASK                (0x1f)
+#define RK3036_A9_CORE_DIV_SHIFT               (0)
+
+#define RATIO_11               (1)
+#define RATIO_21               (2)
+#define RATIO_41               (4)
+#define RATIO_81               (8)
+
+#define RK3036_ACLK_CPU_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_ACLK_CPU_DIV_SHIFT, RK3036_ACLK_CPU_DIV_MASK)
+#define RK3036_CLK_CORE_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_A9_CORE_DIV_SHIFT, RK3036_A9_CORE_DIV_MASK)
+/*******************CLKSEL1 BITS***************************/
+#define RK3036_PCLK_CPU_DIV_MASK               (0x7)
+#define RK3036_PCLK_CPU_DIV_SHIFT              (12)
+#define RK3036_HCLK_CPU_DIV_MASK               (0x3)
+#define RK3036_HCLK_CPU_DIV_SHIFT              (8)
+#define RK3036_ACLK_CORE_DIV_MASK              (0x7)
+#define RK3036_ACLK_CORE_DIV_SHIFT             (4)
+#define RK3036_CORE_PERIPH_DIV_MASK            (0xf)
+#define RK3036_CORE_PERIPH_DIV_SHIFT           (0)
+
+#define RK3036_PCLK_CPU_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_PCLK_CPU_DIV_SHIFT, RK3036_PCLK_CPU_DIV_MASK)
+#define RK3036_HCLK_CPU_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_HCLK_CPU_DIV_SHIFT, RK3036_HCLK_CPU_DIV_MASK)
+#define RK3036_ACLK_CORE_DIV(val)              RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_ACLK_CORE_DIV_SHIFT, RK3036_ACLK_CORE_DIV_MASK)
+#define RK3036_CLK_CORE_PERI_DIV(val)          RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_CORE_PERIPH_DIV_SHIFT, RK3036_CORE_PERIPH_DIV_MASK)
+
+/*******************clksel10***************************/
+#define RK3036_PERI_PLL_SEL_SHIFT      14
+#define RK3036_PERI_PLL_SEL_MASK       (0x3)
+#define RK3036_PERI_PCLK_DIV_MASK      (0x3)
+#define RK3036_PERI_PCLK_DIV_SHIFT     (12)
+#define RK3036_PERI_HCLK_DIV_MASK      (0x3)
+#define RK3036_PERI_HCLK_DIV_SHIFT     (8)
+#define RK3036_PERI_ACLK_DIV_MASK      (0x1f)
+#define RK3036_PERI_ACLK_DIV_SHIFT     (0)
+
+#define RK3036_SEL_3PLL_APLL           (0)
+#define RK3036_SEL_3PLL_DPLL           (1)
+#define RK3036_SEL_3PLL_GPLL           (2)
+
+
+#define RK3036_PERI_CLK_SEL_PLL(plls)  CRU_W_MSK_SETBITS(plls, RK3036_PERI_PLL_SEL_SHIFT, RK3036_PERI_PLL_SEL_MASK)
+#define RK3036_PERI_SET_ACLK_DIV(val)          RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_PERI_ACLK_DIV_SHIFT, RK3036_PERI_ACLK_DIV_MASK)
+
+/*******************gate BITS***************************/
+#define RK3036_CLK_GATE_CLKID_CONS(i)  RK3036_CRU_CLKGATES_CON((i) / 16)
+
+#define RK3036_CLK_GATE(i)             (1 << ((i)%16))
+#define RK3036_CLK_UN_GATE(i)          (0)
+
+#define RK3036_CLK_GATE_W_MSK(i)       (1 << (((i) % 16) + 16))
+#define RK3036_CLK_GATE_CLKID(i)       (16 * (i))
+
+#define _RK3036_APLL_SET_CLKS(_mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac, \
+               _periph_div) \
+{ \
+       .rate   = (_mhz) * MHZ, \
+       .pllcon0 = RK3036_PLL_SET_POSTDIV1(_postdiv1) | RK3036_PLL_SET_FBDIV(_fbdiv),   \
+       .pllcon1 = RK3036_PLL_SET_DSMPD(_dsmpd) | RK3036_PLL_SET_POSTDIV2(_postdiv2) | RK3036_PLL_SET_REFDIV(_refdiv),  \
+       .pllcon2 = RK3036_PLL_SET_FRAC(_frac),  \
+       .clksel1 = RK3036_CLK_CORE_PERI_DIV(RATIO_##_periph_div),       \
+       .lpj    = (CLK_LOOPS_JIFFY_REF * _mhz) / CLK_LOOPS_RATE_REF,    \
+       .rst_dly = 0,\
+}
+
+#define _RK3036_PLL_SET_CLKS(_mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac) \
+{ \
+       .rate   = (_mhz) * KHZ, \
+       .pllcon0 = RK3036_PLL_SET_POSTDIV1(_postdiv1) | RK3036_PLL_SET_FBDIV(_fbdiv),   \
+       .pllcon1 = RK3036_PLL_SET_DSMPD(_dsmpd) | RK3036_PLL_SET_POSTDIV2(_postdiv2) | RK3036_PLL_SET_REFDIV(_refdiv),  \
+       .pllcon2 = RK3036_PLL_SET_FRAC(_frac),  \
+}
+
+/***************************RK3368 PLL**************************************/
+/*******************CLKSEL0/2 BITS***************************/
+#define RK3368_CORE_SEL_PLL_W_MSK      (1 << 23)
+#define RK3368_CORE_SEL_APLL           (0 << 7)
+#define RK3368_CORE_SEL_GPLL           (1 << 7)
+
+#define RK3368_CORE_CLK_SHIFT          0
+#define RK3368_CORE_CLK_WIDTH          5
+#define RK3368_CORE_CLK_DIV(i) \
+       CLK_DIV_PLUS_ONE_SET(i, RK3368_CORE_CLK_SHIFT, RK3368_CORE_CLK_WIDTH)
+#define RK3368_CORE_CLK_MAX_DIV                (2<<RK3368_CORE_CLK_WIDTH)
+
+#define RK3368_ACLKM_CORE_SHIFT                8
+#define RK3368_ACLKM_CORE_WIDTH                5
+#define RK3368_ACLKM_CORE_DIV(i)       \
+       CLK_DIV_PLUS_ONE_SET(i, RK3368_ACLKM_CORE_SHIFT, RK3368_ACLKM_CORE_WIDTH)
+
+/*******************CLKSEL1/3 BITS***************************/
+#define RK3368_ATCLK_CORE_SHIFT                0
+#define RK3368_ATCLK_CORE_WIDTH                5
+#define RK3368_ATCLK_CORE_DIV(i)       \
+       CLK_DIV_PLUS_ONE_SET(i, RK3368_ATCLK_CORE_SHIFT, RK3368_ATCLK_CORE_WIDTH)
+
+#define RK3368_PCLK_DBG_SHIFT          8
+#define RK3368_PCLK_DBG_WIDTH          5
+#define RK3368_PCLK_DBG_DIV(i) \
+       CLK_DIV_PLUS_ONE_SET(i, RK3368_PCLK_DBG_SHIFT, RK3368_PCLK_DBG_WIDTH)
+
+#define _RK3368_APLL_SET_CLKS(_mhz, nr, nf, no, aclkm_div, atclk_div, pclk_dbg_div) \
+{ \
+       .rate   = _mhz * MHZ, \
+       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr) | RK3188PLUS_PLL_CLKOD_SET(no), \
+       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
+       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1),\
+       .rst_dly = ((nr*500)/24+1),\
+       .clksel0 = RK3368_ACLKM_CORE_DIV(aclkm_div),\
+       .clksel1 = RK3368_ATCLK_CORE_DIV(atclk_div) | RK3368_PCLK_DBG_DIV(pclk_dbg_div) \
+}
+
+struct pll_clk_set {
+       unsigned long   rate;
+       u32     pllcon0;
+       u32     pllcon1;
+       u32     pllcon2;
+       unsigned long   rst_dly;//us
+};
+
+struct apll_clk_set {
+       unsigned long   rate;
+       u32     pllcon0;
+       u32     pllcon1;
+       u32     pllcon2;
+       u32     rst_dly;//us
+       u32     clksel0;
+       u32     clksel1;
+       unsigned long   lpj;
+};
+
+
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
+
+struct clk_pll {
+       struct clk_hw   hw;
+       u32             reg;
+       u32             width;
+       u32             mode_offset;
+       u8              mode_shift;
+       u32             status_offset;
+       u8              status_shift;
+       u32             flags;
+       const void      *table;
+       spinlock_t      *lock;
+};
+
+const struct clk_ops *rk_get_pll_ops(u32 pll_flags);
+
+struct clk *rk_clk_register_pll(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags, u32 reg,
+               u32 width, u32 mode_offset, u8 mode_shift,
+               u32 status_offset, u8 status_shift, u32 pll_flags,
+               spinlock_t *lock);
+
+
+#endif /* __RK_CLK_PLL_H */
diff --git a/drivers/clk/rk/clk.c b/drivers/clk/rk/clk.c
new file mode 100644 (file)
index 0000000..d198c73
--- /dev/null
@@ -0,0 +1,2279 @@
+/*
+ * Copyright (C) 2013 ROCKCHIP, Inc.
+ * Author: chenxing <chenxing@rock-chips.com>
+ *         Dai Kelin <dkl@rock-chips.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk-private.h>
+#include <asm/io.h>
+
+#include "clk-ops.h"
+#include "clk-pll.h"
+#include "clk-pd.h"
+
+static void __iomem *rk_cru_base;
+static void __iomem *rk_grf_base;
+
+u32 cru_readl(u32 offset)
+{
+       return readl_relaxed(rk_cru_base + (offset));
+}
+
+void cru_writel(u32 val, u32 offset)
+{
+       writel_relaxed(val, rk_cru_base + (offset));
+       dsb(sy);
+}
+
+u32 grf_readl(u32 offset)
+{
+       return readl_relaxed(rk_grf_base + (offset));
+}
+
+struct rkclk_muxinfo {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_mux          *mux;
+       u8                      parent_num;
+       const char              **parent_names;
+       u32                     clkops_idx;
+};
+
+struct rkclk_divinfo {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_divider      *div;
+       u32                     div_type;
+       const char              *parent_name;
+       u32                     clkops_idx;
+};
+
+struct rkclk_fracinfo {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_divider      *frac;
+       u32                     frac_type;
+       const char              *parent_name;
+       u32                     clkops_idx;
+};
+
+struct rkclk_gateinfo {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_gate         *gate;
+       const char              *parent_name;
+       //u32                   clkops_idx;
+};
+
+struct rkclk_pllinfo {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_pll          *pll;
+       const char              *parent_name;
+       u32                     clkops_idx;
+};
+
+struct rkclk_fixed_rate_info {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_fixed_rate   *fixed_rate;
+       const char              *parent_name;
+};
+
+struct rkclk_fixed_factor_info {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_fixed_factor   *fixed_factor;
+       const char              *parent_name;
+};
+
+struct rkclk_pd_info {
+       const char              *clk_name;
+       struct device_node      *np;
+       struct clk_pd           *pd;
+       const char              *parent_name;
+};
+
+
+struct rkclk {
+       const char              *clk_name;
+       //struct device_node    *np;
+       u32                     clk_type;
+       u32                     flags;
+       struct rkclk_muxinfo    *mux_info;
+       struct rkclk_divinfo    *div_info;
+       struct rkclk_fracinfo   *frac_info;
+       struct rkclk_pllinfo    *pll_info;
+       struct rkclk_gateinfo   *gate_info;
+       struct rkclk_fixed_rate_info *fixed_rate_info;
+       struct rkclk_fixed_factor_info *fixed_factor_info;
+       struct rkclk_pd_info    *pd_info;
+       struct list_head        node;
+};
+
+static DEFINE_SPINLOCK(clk_lock);
+LIST_HEAD(rk_clks);
+
+#define RKCLK_PLL_TYPE         (1 << 0)
+#define RKCLK_MUX_TYPE         (1 << 1)
+#define RKCLK_DIV_TYPE         (1 << 2)
+#define RKCLK_FRAC_TYPE                (1 << 3)
+#define RKCLK_GATE_TYPE                (1 << 4)
+#define RKCLK_FIXED_RATE_TYPE  (1 << 5)
+#define RKCLK_FIXED_FACTOR_TYPE        (1 << 6)
+#define RKCLK_PD_TYPE          (1 << 7)
+
+
+static int rkclk_init_muxinfo(struct device_node *np, void __iomem *addr)
+{
+       struct rkclk_muxinfo *muxinfo = NULL;
+       struct clk_mux *mux = NULL;
+       u32 shift, width;
+       u32 flags;
+       int cnt, i, ret = 0;
+       u8 found = 0;
+       struct rkclk *rkclk = NULL;
+
+
+       muxinfo = kzalloc(sizeof(struct rkclk_muxinfo), GFP_KERNEL);
+       if (!muxinfo) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       muxinfo->mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+       if (!muxinfo->mux) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       mux = muxinfo->mux;
+
+       ret = of_property_read_string(np, "clock-output-names",
+                       &muxinfo->clk_name);
+       if (ret != 0)
+               goto out;
+
+       muxinfo->np = np;
+
+       cnt = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+       if (cnt < 0) {
+               ret = -EINVAL;
+               goto out;
+       } else {
+               clk_debug("%s: parent cnt = %d\n", __func__, cnt);
+               muxinfo->parent_num = (u8)cnt;
+       }
+
+       muxinfo->parent_names = kzalloc(cnt * sizeof(char *), GFP_KERNEL);
+       for (i = 0; i < cnt ; i++) {
+               muxinfo->parent_names[i] = of_clk_get_parent_name(np, i);
+       }
+
+       mux->reg = addr;
+
+       ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
+       if (ret != 0) {
+               goto out;
+       } else {
+               mux->shift = (u8)shift;
+       }
+
+       ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
+       if (ret != 0)
+               goto out;
+       mux->mask = (1 << width) - 1;
+
+       mux->flags = CLK_MUX_HIWORD_MASK;
+
+       ret = of_property_read_u32(np, "rockchip,clkops-idx",
+                       &muxinfo->clkops_idx);
+       if (ret != 0) {
+               muxinfo->clkops_idx = CLKOPS_TABLE_END;
+               ret = 0;
+       }
+
+       ret = of_property_read_u32(np, "rockchip,flags", &flags);
+       if (ret != 0) {
+               flags = 0;
+               ret = 0;
+       }
+
+       found = 0;
+       list_for_each_entry(rkclk, &rk_clks, node) {
+               if (strcmp(muxinfo->clk_name, rkclk->clk_name) == 0) {
+                       if (rkclk->mux_info != NULL) {
+                               clk_err("%s %d:\n", __func__, __LINE__);
+                               clk_err("This clk(%s) has been used,"
+                                               "will be overwrited here!\n",
+                                               rkclk->clk_name);
+                       }
+                       clk_debug("%s: find match %s\n", __func__,
+                                       rkclk->clk_name);
+                       found = 1;
+                       rkclk->mux_info = muxinfo;
+                       rkclk->clk_type |= RKCLK_MUX_TYPE;
+                       rkclk->flags |= flags;
+                       break;
+               }
+       }
+
+       if (!found) {
+               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+               if (!rkclk) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               rkclk->clk_name = muxinfo->clk_name;
+               rkclk->mux_info = muxinfo;
+               rkclk->clk_type = RKCLK_MUX_TYPE;
+               rkclk->flags = flags;
+               clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
+               list_add_tail(&rkclk->node, &rk_clks);
+       }
+
+out:
+       if (ret) {
+               clk_err("%s error, ret = %d\n", __func__, ret);
+               if (muxinfo) {
+                       if (muxinfo->mux)
+                               kfree(muxinfo->mux);
+                       kfree(muxinfo);
+               }
+               if (rkclk)
+                       kfree(rkclk);
+       }
+
+       return ret;
+}
+
+static int rkclk_init_divinfo(struct device_node *np, void __iomem *addr)
+{
+       int cnt = 0, i = 0, ret = 0;
+       struct rkclk *rkclk = NULL;
+       u8 found = 0;
+       u32 flags;
+       u32 shift, width;
+       struct rkclk_divinfo *divinfo = NULL;
+       struct clk_divider *div = NULL;
+       struct clk_div_table    *table;
+       u32 table_val, table_div;
+
+
+       divinfo = kzalloc(sizeof(struct rkclk_divinfo), GFP_KERNEL);
+       if (!divinfo) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       divinfo->div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
+       if (!divinfo->div) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       div = divinfo->div;
+
+       ret = of_property_read_string(np, "clock-output-names",
+                       &divinfo->clk_name);
+       if (ret != 0)
+               goto out;
+
+       divinfo->parent_name = of_clk_get_parent_name(np, 0);
+
+       divinfo->np = np;
+
+       ret = of_property_read_u32(np, "rockchip,clkops-idx",
+                       &divinfo->clkops_idx);
+       if (ret != 0) {
+               divinfo->clkops_idx = CLKOPS_TABLE_END;
+               ret = 0;
+       }
+
+       ret = of_property_read_u32(np, "rockchip,flags", &flags);
+       if (ret != 0) {
+               flags = 0;
+               ret = 0;
+       }
+
+       ret = of_property_read_u32(np, "rockchip,div-type", &divinfo->div_type);
+       if (ret != 0)
+               goto out;
+
+       switch (divinfo->div_type) {
+               case CLK_DIVIDER_PLUS_ONE:
+               case CLK_DIVIDER_ONE_BASED:
+               case CLK_DIVIDER_POWER_OF_TWO:
+                       break;
+               case CLK_DIVIDER_USER_DEFINE:
+                       of_get_property(np, "rockchip,div-relations", &cnt);
+                       if (cnt <= 0) {
+                               ret = -EINVAL;
+                               goto out;
+                       }
+                       cnt /= 4 * 2;
+                       table = kzalloc(cnt * sizeof(struct clk_div_table),
+                                       GFP_KERNEL);
+                       if (!table) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       for (i = 0; i < cnt; i++) {
+                               ret = of_property_read_u32_index(np,
+                                               "rockchip,div-relations", i * 2,
+                                               &table_val);
+                               if (ret)
+                                       goto out;
+                               ret = of_property_read_u32_index(np,
+                                               "rockchip,div-relations",
+                                               i * 2 + 1, &table_div);
+                               if (ret)
+                                       goto out;
+                               table[i].val = (unsigned int)table_val;
+                               table[i].div = (unsigned int)table_div;
+                               clk_debug("\tGet div table %d: val=%d, div=%d\n",
+                                               i, table_val, table_div);
+                       }
+                       div->table = table;
+                       break;
+               default:
+                       clk_err("%s: %s: unknown rockchip,div-type\n", __func__,
+                                       divinfo->clk_name);
+                       ret = -EINVAL;
+                       goto out;
+       }
+
+       div->reg = addr;
+       ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
+       if (ret)
+               goto out;
+       ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
+       if (ret)
+               goto out;
+       div->shift = (u8)shift;
+       div->width = (u8)width;
+       div->flags = CLK_DIVIDER_HIWORD_MASK | divinfo->div_type;
+
+       found = 0;
+       list_for_each_entry(rkclk, &rk_clks, node) {
+               if (strcmp(divinfo->clk_name, rkclk->clk_name) == 0) {
+                       if (rkclk->div_info != NULL) {
+                               clk_err("%s %d:\n", __func__, __LINE__);
+                               clk_err("This clk(%s) has been used,"
+                                               "will be overwrited here!\n",
+                                               rkclk->clk_name);
+                       }
+                       clk_debug("%s: find match %s\n", __func__,
+                                       rkclk->clk_name);
+                       found = 1;
+                       rkclk->div_info = divinfo;
+                       rkclk->clk_type |= RKCLK_DIV_TYPE;
+                       rkclk->flags |= flags;
+                       break;
+               }
+       }
+
+       if (!found) {
+               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+               if (!rkclk) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               rkclk->clk_name = divinfo->clk_name;
+               rkclk->div_info = divinfo;
+               rkclk->clk_type = RKCLK_DIV_TYPE;
+               rkclk->flags = flags;
+               clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
+               list_add_tail(&rkclk->node, &rk_clks);
+       }
+
+out:
+       if (ret) {
+               clk_err("%s error, ret = %d\n", __func__, ret);
+               if(table)
+                       kfree(table);
+               if (divinfo) {
+                       if (divinfo->div)
+                               kfree(divinfo->div);
+                       kfree(divinfo);
+               }
+               if (rkclk)
+                       kfree(rkclk);
+       }
+
+       return ret;
+}
+
+static int rkclk_init_fracinfo(struct device_node *np, void __iomem *addr)
+{
+       struct rkclk *rkclk = NULL;
+       u8 found = 0;
+       int ret = 0;
+       struct rkclk_fracinfo *fracinfo = NULL;
+       struct clk_divider *frac = NULL;
+       u32 shift, width, flags;
+
+
+       fracinfo = kzalloc(sizeof(struct rkclk_fracinfo), GFP_KERNEL);
+       if (!fracinfo) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       fracinfo->frac = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
+       if (!fracinfo->frac) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       frac = fracinfo->frac;
+
+       ret = of_property_read_string(np, "clock-output-names",
+                       &fracinfo->clk_name);
+       if (ret != 0)
+               goto out;
+
+       fracinfo->parent_name = of_clk_get_parent_name(np, 0);
+       fracinfo->np = np;
+
+       ret = of_property_read_u32(np, "rockchip,clkops-idx",
+                       &fracinfo->clkops_idx);
+       if (ret != 0) {
+               fracinfo->clkops_idx = CLKOPS_TABLE_END;
+               clk_err("frac node without specified ops!\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = of_property_read_u32(np, "rockchip,flags", &flags);
+       if (ret != 0) {
+               clk_debug("if not specified, frac use CLK_SET_RATE_PARENT flag "
+                               "as default\n");
+               flags = CLK_SET_RATE_PARENT;
+               ret = 0;
+       }
+
+       frac->reg = addr;
+       ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
+       if (ret)
+               goto out;
+       ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
+       if (ret)
+               goto out;
+       frac->shift = (u8)shift;
+       frac->width = (u8)width;
+       frac->flags = 0;
+
+       found = 0;
+       list_for_each_entry(rkclk, &rk_clks, node) {
+               if (strcmp(fracinfo->clk_name, rkclk->clk_name) == 0) {
+                       if (rkclk->frac_info != NULL) {
+                               clk_err("%s %d:\n", __func__, __LINE__);
+                               clk_err("This clk(%s) has been used,"
+                                               "will be overwrited here!\n",
+                                               rkclk->clk_name);
+                       }
+                       clk_debug("%s: find match %s\n", __func__,
+                                       rkclk->clk_name);
+                       found = 1;
+                       rkclk->frac_info = fracinfo;
+                       rkclk->clk_type |= RKCLK_FRAC_TYPE;
+                       rkclk->flags |= flags;
+                       break;
+               }
+       }
+
+       if (!found) {
+               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+               if (!rkclk) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               rkclk->clk_name = fracinfo->clk_name;
+               rkclk->frac_info = fracinfo;
+               rkclk->clk_type = RKCLK_FRAC_TYPE;
+               rkclk->flags = flags;
+               clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
+               list_add_tail(&rkclk->node, &rk_clks);
+       }
+
+out:
+       if (ret) {
+               clk_err("%s error, ret = %d\n", __func__, ret);
+               if (fracinfo) {
+                       if (fracinfo->frac)
+                               kfree(fracinfo->frac);
+                       kfree(fracinfo);
+               }
+               if (rkclk)
+                       kfree(rkclk);
+       }
+
+       return ret;
+}
+
+static int __init rkclk_init_selcon(struct device_node *np)
+{
+       struct device_node *node_con, *node;
+       void __iomem *reg = 0;
+       int ret = 0;
+
+
+       for_each_available_child_of_node(np, node_con) {
+               reg = of_iomap(node_con, 0);
+               clk_debug("\n");
+               clk_debug("%s: reg = 0x%x\n", __func__, (u32)reg);
+
+               for_each_available_child_of_node(node_con, node) {
+                       clk_debug("\n");
+                       if (of_device_is_compatible(node,
+                                               "rockchip,rk3188-div-con"))
+                               ret = rkclk_init_divinfo(node, reg);
+
+                       else if (of_device_is_compatible(node,
+                                               "rockchip,rk3188-mux-con"))
+                               ret = rkclk_init_muxinfo(node, reg);
+
+                       else if (of_device_is_compatible(node,
+                                               "rockchip,rk3188-frac-con"))
+                               ret = rkclk_init_fracinfo(node, reg);
+
+                       else if (of_device_is_compatible(node,
+                                               "rockchip,rk3188-inv-con"))
+                               clk_debug("INV clk\n");
+
+                       else {
+                               clk_err("%s: unknown controller type\n",
+                                               __func__);
+                               ret = -EINVAL;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+static int __init rkclk_init_gatecon(struct device_node *np)
+{
+       struct device_node *node;
+       const char *clk_name;
+       void __iomem *reg;
+       int cnt;
+       int i;
+       struct rkclk_gateinfo *gateinfo;
+       u8 found = 0;
+       struct rkclk *rkclk;
+       int ret = 0;
+       struct clk_gate *gate = NULL;
+
+
+       for_each_available_child_of_node(np, node) {
+               cnt = of_property_count_strings(node, "clock-output-names");
+               if (cnt < 0) {
+                       clk_err("%s: error in clock-output-names %d\n",
+                                       __func__, cnt);
+                       continue;
+               }
+
+               if (cnt == 0) {
+                       clk_debug("%s: nothing to do\n", __func__);
+                       continue;
+               }
+
+               reg = of_iomap(node, 0);
+               clk_debug("\n");
+               clk_debug("%s: reg = 0x%x\n", __func__, (u32)reg);
+
+               for (i = 0; i < cnt; i++) {
+                       ret = of_property_read_string_index(node,
+                                       "clock-output-names", i, &clk_name);
+                       if (ret != 0)
+                               goto out;
+
+                       /* ignore empty slots */
+                       if (!strcmp("reserved", clk_name)) {
+                               clk_debug("do nothing for reserved clk\n");
+                               continue;
+                       }
+
+                       gateinfo = kzalloc(sizeof(struct rkclk_gateinfo),
+                                       GFP_KERNEL);
+                       if (!gateinfo) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+
+                       gateinfo->gate = kzalloc(sizeof(struct clk_gate),
+                                       GFP_KERNEL);
+                       if (!gateinfo->gate) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       gate = gateinfo->gate;
+
+                       gateinfo->clk_name = clk_name;
+                       gateinfo->parent_name = of_clk_get_parent_name(node, i);
+                       gateinfo->np = node;
+
+                       gate->reg = reg;
+                       gate->bit_idx = (i % 16);
+                       gate->flags = CLK_GATE_HIWORD_MASK |
+                               CLK_GATE_SET_TO_DISABLE;
+
+                       found = 0;
+                       list_for_each_entry(rkclk, &rk_clks, node) {
+                               if (strcmp(clk_name, rkclk->clk_name) == 0) {
+                                       if (rkclk->gate_info != NULL) {
+                                               clk_err("%s %d:\n", __func__,
+                                                               __LINE__);
+                                               clk_err("This clk(%s) has been used,"
+                                                               "will be overwrited here!\n",
+                                                               rkclk->clk_name);
+                                       }
+                                       clk_debug("%s: find match %s\n",
+                                                       __func__, rkclk->clk_name);
+                                       found = 1;
+                                       rkclk->gate_info = gateinfo;
+                                       rkclk->clk_type |= RKCLK_GATE_TYPE;
+                                       break;
+                               }
+                       }
+                       if (!found) {
+                               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+                               if (!rkclk) {
+                                       ret = -ENOMEM;
+                                       goto out;
+                               }
+                               rkclk->clk_name = gateinfo->clk_name;
+                               rkclk->gate_info = gateinfo;
+                               rkclk->clk_type = RKCLK_GATE_TYPE;
+                               clk_debug("%s: creat %s\n", __func__,
+                                               rkclk->clk_name);
+                               list_add_tail(&rkclk->node, &rk_clks);
+                       }
+
+out:
+                       if (ret) {
+                               clk_err("%s error, ret = %d\n", __func__, ret);
+                               if (gateinfo) {
+                                       if (gateinfo->gate)
+                                               kfree(gateinfo->gate);
+                                       kfree(gateinfo);
+                               }
+                               if (rkclk)
+                                       kfree(rkclk);
+                       }
+               }
+
+       }
+
+       return 0;
+}
+
+static int __init rkclk_init_pllcon(struct device_node *np)
+{
+       struct device_node *node = NULL;
+       struct rkclk_pllinfo *pllinfo = NULL;
+       struct clk_pll *pll = NULL;
+       u8 found = 0;
+       int ret = 0;
+       struct rkclk *rkclk = NULL;
+       u32 flags;
+       u32 mode_shift, status_shift;
+
+
+       for_each_available_child_of_node(np, node) {
+               pllinfo = kzalloc(sizeof(struct rkclk_pllinfo), GFP_KERNEL);
+               if (!pllinfo) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               pllinfo->pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
+               if (!pllinfo->pll) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               pll = pllinfo->pll;
+
+               pllinfo->np = node;
+
+               ret = of_property_read_string_index(node, "clock-output-names",
+                               0, &pllinfo->clk_name);
+               if (ret)
+                       goto out;
+
+               pllinfo->parent_name = of_clk_get_parent_name(node, 0);
+
+               ret = of_property_read_u32(np, "rockchip,flags", &flags);
+               if (ret != 0) {
+                       flags = 0;
+                       ret = 0;
+               }
+       
+               ret = of_property_read_u32_index(node, "reg", 0, &pll->reg);
+               if (ret != 0) {
+                       clk_err("%s: can not get reg addr info\n", __func__);
+                       goto out;
+               }
+
+               ret = of_property_read_u32_index(node, "reg", 1, &pll->width);
+               if (ret != 0) {
+                       clk_err("%s: can not get reg length info\n", __func__);
+                       goto out;
+               }
+
+               ret = of_property_read_u32_index(node, "mode-reg", 0,
+                               &pll->mode_offset);
+               if (ret != 0) {
+                       clk_err("%s: can not get mode_reg offset\n", __func__);
+                       goto out;
+               }
+
+               ret = of_property_read_u32_index(node, "mode-reg", 1,
+                               &mode_shift);
+               if (ret != 0) {
+                       clk_err("%s: can not get mode_reg shift\n", __func__);
+                       goto out;
+               } else {
+                       pll->mode_shift = (u8)mode_shift;
+               }
+
+               ret = of_property_read_u32_index(node, "status-reg", 0,
+                               &pll->status_offset);
+               if (ret != 0) {
+                       clk_err("%s: can not get status_reg offset\n", __func__);
+                       goto out;
+               }
+
+               ret = of_property_read_u32_index(node, "status-reg", 1,
+                               &status_shift);
+               if (ret != 0) {
+                       clk_err("%s: can not get status_reg shift\n", __func__);
+                       goto out;
+               } else {
+                       pll->status_shift= (u8)status_shift;
+               }
+
+               ret = of_property_read_u32(node, "rockchip,pll-type", &pll->flags);
+               if (ret != 0) {
+                       clk_err("%s: can not get pll-type\n", __func__);
+                       goto out;
+               }
+
+               clk_debug("%s: pllname=%s, parent=%s, flags=0x%x\n",
+                               __func__, pllinfo->clk_name,
+                               pllinfo->parent_name, flags);
+
+               clk_debug("\t\taddr=0x%x, len=0x%x, mode:offset=0x%x, shift=0x%x,"
+                               " status:offset=0x%x, shift=0x%x, pll->flags=0x%x\n",
+                               (u32)pll->reg, pll->width,
+                               pll->mode_offset, pll->mode_shift,
+                               pll->status_offset, pll->status_shift,
+                               pll->flags);
+
+               found = 0;
+               list_for_each_entry(rkclk, &rk_clks, node) {
+                       if (strcmp(pllinfo->clk_name, rkclk->clk_name) == 0) {
+                               if (rkclk->pll_info != NULL) {
+                                       clk_err("%s %d:\n", __func__, __LINE__);
+                                       clk_err("This clk(%s) has been used,"
+                                                       "will be overwrited here!\n",
+                                                       rkclk->clk_name);
+                               }
+                               clk_debug("%s: find match %s\n", __func__,
+                                               rkclk->clk_name);
+                               found = 1;
+                               rkclk->pll_info = pllinfo;
+                               rkclk->clk_type |= RKCLK_PLL_TYPE;
+                               rkclk->flags |= flags;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+                       if (!rkclk) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       rkclk->clk_name = pllinfo->clk_name;
+                       rkclk->pll_info = pllinfo;
+                       rkclk->clk_type = RKCLK_PLL_TYPE;
+                       rkclk->flags = flags;
+                       list_add_tail(&rkclk->node, &rk_clks);
+               }
+       }
+
+out:
+       if (ret) {
+               clk_err("%s error, ret = %d\n", __func__, ret);
+               if (pllinfo) {
+                       if (pllinfo->pll)
+                               kfree(pllinfo->pll);
+                       kfree(pllinfo);
+               }
+               if (rkclk)
+                       kfree(rkclk);
+       }
+
+       return ret;
+}
+
+static int __init rkclk_init_fixed_rate(struct device_node *np)
+{
+       struct device_node *node = NULL;
+       struct rkclk_fixed_rate_info *fixed_rate_info = NULL;
+       struct clk_fixed_rate *fixed_rate = NULL;
+       u32 rate;
+       int ret = 0;
+       u8 found = 0;
+       struct rkclk *rkclk = NULL;
+
+
+       for_each_available_child_of_node(np, node) {
+               fixed_rate_info = kzalloc(sizeof(struct rkclk_fixed_rate_info),
+                       GFP_KERNEL);
+               if (!fixed_rate_info) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               fixed_rate_info->fixed_rate = kzalloc(sizeof(struct clk_fixed_rate),
+                       GFP_KERNEL);
+               if (!fixed_rate_info->fixed_rate) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               fixed_rate = fixed_rate_info->fixed_rate;
+
+               fixed_rate_info->np = node;
+
+               ret = of_property_read_string_index(node, "clock-output-names",
+                               0, &fixed_rate_info->clk_name);
+               if (ret)
+                       goto out;
+
+               fixed_rate_info->parent_name = of_clk_get_parent_name(node, 0);
+
+               ret = of_property_read_u32(node, "clock-frequency", &rate);
+               if (ret != 0) {
+                       clk_err("%s: can not get clock-frequency\n", __func__);
+                       goto out;
+               }
+               fixed_rate->fixed_rate = (unsigned long)rate;
+
+               found = 0;
+               list_for_each_entry(rkclk, &rk_clks, node) {
+                       if (strcmp(fixed_rate_info->clk_name, rkclk->clk_name) == 0) {
+                               if (rkclk->fixed_rate_info != NULL) {
+                                       clk_err("%s %d:\n", __func__, __LINE__);
+                                       clk_err("This clk(%s) has been used,"
+                                                       "will be overwrited here!\n",
+                                                       rkclk->clk_name);
+                               }
+                               clk_debug("%s: find match %s\n", __func__,
+                                               rkclk->clk_name);
+                               found = 1;
+                               rkclk->fixed_rate_info = fixed_rate_info;
+                               rkclk->clk_type |= RKCLK_FIXED_RATE_TYPE;
+                               rkclk->flags |= CLK_IS_ROOT;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+                       if (!rkclk) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       rkclk->clk_name = fixed_rate_info->clk_name;
+                       rkclk->fixed_rate_info = fixed_rate_info;
+                       rkclk->clk_type = RKCLK_FIXED_RATE_TYPE;
+                       rkclk->flags = CLK_IS_ROOT;
+                       clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
+                       list_add_tail(&rkclk->node, &rk_clks);
+               }
+       }
+
+out:
+       if (ret) {
+               clk_err("%s error, ret = %d\n", __func__, ret);
+               if (fixed_rate_info) {
+                       if (fixed_rate_info->fixed_rate)
+                               kfree(fixed_rate_info->fixed_rate);
+                       kfree(fixed_rate_info);
+               }
+               if (rkclk)
+                       kfree(rkclk);
+       }
+
+       return ret;
+}
+
+static int __init rkclk_init_fixed_factor(struct device_node *np)
+{
+       struct device_node *node = NULL;
+       struct rkclk_fixed_factor_info *fixed_factor_info = NULL;
+       struct clk_fixed_factor *fixed_factor = NULL;
+       u32 flags, mult, div;
+       int ret = 0;
+       u8 found = 0;
+       struct rkclk *rkclk = NULL;
+
+
+       for_each_available_child_of_node(np, node) {
+               fixed_factor_info = kzalloc(sizeof(struct rkclk_fixed_factor_info),
+                       GFP_KERNEL);
+               if (!fixed_factor_info) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               fixed_factor_info->fixed_factor = kzalloc(sizeof(struct clk_fixed_factor),
+                       GFP_KERNEL);
+               if (!fixed_factor_info->fixed_factor) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               fixed_factor = fixed_factor_info->fixed_factor;
+
+               fixed_factor_info->np = node;
+
+               ret = of_property_read_string_index(node, "clock-output-names",
+                               0, &fixed_factor_info->clk_name);
+               if (ret)
+                       goto out;
+
+               fixed_factor_info->parent_name = of_clk_get_parent_name(node, 0);
+
+               ret = of_property_read_u32(node, "rockchip,flags", &flags);
+               if (ret != 0) {
+                       flags = 0;
+                       ret = 0;
+               }
+
+               ret = of_property_read_u32(node, "clock-mult", &mult);
+               if (ret != 0) {
+                       clk_err("%s: can not get mult\n", __func__);
+                       goto out;
+               }
+               fixed_factor->mult = (unsigned int)mult;
+
+               ret = of_property_read_u32(node, "clock-div", &div);
+               if (ret != 0) {
+                       clk_err("%s: can not get div\n", __func__);
+                       goto out;
+               }
+               fixed_factor->div = (unsigned int)div;
+
+
+               found = 0;
+               list_for_each_entry(rkclk, &rk_clks, node) {
+                       if (strcmp(fixed_factor_info->clk_name, rkclk->clk_name) == 0) {
+                               if (rkclk->fixed_factor_info != NULL) {
+                                       clk_err("%s %d:\n", __func__, __LINE__);
+                                       clk_err("This clk(%s) has been used,"
+                                                       "will be overwrited here!\n",
+                                                       rkclk->clk_name);
+                               }
+                               clk_debug("%s: find match %s\n", __func__,
+                                               rkclk->clk_name);
+                               found = 1;
+                               rkclk->fixed_factor_info = fixed_factor_info;
+                               rkclk->clk_type |= RKCLK_FIXED_FACTOR_TYPE;
+                               rkclk->flags |= flags;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+                       if (!rkclk) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       rkclk->clk_name = fixed_factor_info->clk_name;
+                       rkclk->fixed_factor_info = fixed_factor_info;
+                       rkclk->clk_type = RKCLK_FIXED_FACTOR_TYPE;
+                       rkclk->flags = flags;
+                       clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
+                       list_add_tail(&rkclk->node, &rk_clks);
+               }
+       }
+
+out:
+       if (ret) {
+               clk_err("%s error, ret = %d\n", __func__, ret);
+               if (fixed_factor_info) {
+                       if (fixed_factor_info->fixed_factor)
+                               kfree(fixed_factor_info->fixed_factor);
+                       kfree(fixed_factor_info);
+               }
+               if (rkclk)
+                       kfree(rkclk);
+       }
+
+       return ret;
+}
+
+static int __init rkclk_init_regcon(struct device_node *np)
+{
+       struct device_node *node;
+       const char *compatible;
+       int ret = 0;
+
+
+       for_each_available_child_of_node(np, node) {
+               clk_debug("\n");
+               of_property_read_string(node, "compatible", &compatible);
+
+               if (strcmp(compatible, "rockchip,rk-pll-cons") == 0) {
+                       ret = rkclk_init_pllcon(node);
+                       if (ret != 0) {
+                               clk_err("%s: init pll cons err\n", __func__);
+                               goto out;
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-sel-cons") == 0) {
+                       ret = rkclk_init_selcon(node);
+                       if (ret != 0) {
+                               clk_err("%s: init sel cons err\n", __func__);
+                               goto out;
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-gate-cons") == 0) {
+                       ret = rkclk_init_gatecon(node);
+                       if (ret != 0) {
+                               clk_err("%s: init gate cons err\n", __func__);
+                               goto out;
+                       }
+               } else {
+                       clk_err("%s: unknown\n", __func__);
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+out:
+       return ret;
+}
+
+static int __init rkclk_init_special_regs(struct device_node *np)
+{
+       struct device_node *node;
+       const char *compatible;
+       void __iomem *reg = 0;
+       int ret = 0;
+
+
+       for_each_available_child_of_node(np, node) {
+               clk_debug("\n");
+               of_property_read_string(node, "compatible", &compatible);
+               if (strcmp(compatible, "rockchip,rk3188-mux-con") == 0) {
+                       reg = of_iomap(node, 0);
+                       ret = rkclk_init_muxinfo(node, reg);
+                       if (ret != 0) {
+                               clk_err("%s: init mux con err\n", __func__);
+                               goto out;
+                       }
+               }
+       }
+
+out:
+       return ret;
+}
+
+static int __init rkclk_init_pd(struct device_node *np)
+{
+       struct device_node *node = NULL;
+       struct rkclk_pd_info *pd_info = NULL;
+       struct clk_pd *pd = NULL;
+       int ret = 0;
+       u8 found = 0;
+       struct rkclk *rkclk = NULL;
+
+
+       for_each_available_child_of_node(np, node) {
+               pd_info = kzalloc(sizeof(struct rkclk_pd_info), GFP_KERNEL);
+               if (!pd_info) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               pd_info->pd = kzalloc(sizeof(struct clk_pd), GFP_KERNEL);
+               if (!pd_info->pd) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               pd = pd_info->pd;
+
+               pd_info->np = node;
+
+               ret = of_property_read_string_index(node, "clock-output-names",
+                               0, &pd_info->clk_name);
+               if (ret)
+                       goto out;
+
+               pd_info->parent_name = of_clk_get_parent_name(node, 0);
+
+               ret = of_property_read_u32(node, "rockchip,pd-id", &pd->id);
+               if (ret != 0) {
+                       clk_err("%s: can not get pd-id\n", __func__);
+                       goto out;
+               }
+
+               found = 0;
+               list_for_each_entry(rkclk, &rk_clks, node) {
+                       if (strcmp(pd_info->clk_name, rkclk->clk_name) == 0) {
+                               clk_err("%s %d:\n", __func__, __LINE__);
+                               clk_err("This clk (%s) has been used, error!\n",
+                                       rkclk->clk_name);
+                               goto out;
+                       }
+               }
+
+               if (!found) {
+                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
+                       if (!rkclk) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       rkclk->clk_name = pd_info->clk_name;
+                       rkclk->pd_info = pd_info;
+                       rkclk->clk_type = RKCLK_PD_TYPE;
+                       rkclk->flags = 0;
+                       clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
+                       list_add_tail(&rkclk->node, &rk_clks);
+               }
+       }
+
+out:
+       if (ret) {
+               clk_err("%s error, ret = %d\n", __func__, ret);
+               if (pd_info) {
+                       if (pd_info->pd)
+                               kfree(pd_info->pd);
+                       kfree(pd_info);
+               }
+               if (rkclk)
+                       kfree(rkclk);
+       }
+
+       return ret;
+}
+
+static int rkclk_register(struct rkclk *rkclk)
+{
+       struct clk              *clk = NULL;
+       struct clk_mux          *mux = NULL;
+       struct clk_divider      *div = NULL;
+       struct clk_gate         *gate = NULL;
+       struct clk_pll          *pll = NULL;
+       struct clk_divider      *frac = NULL;
+       struct clk_fixed_rate   *fixed_rate = NULL;
+       struct clk_fixed_factor *fixed_factor = NULL;
+       struct clk_pd           *pd = NULL;
+
+       struct clk_hw           *mux_hw = NULL;
+       const struct clk_ops    *mux_ops = NULL;
+       struct clk_hw           *rate_hw = NULL;
+       const struct clk_ops    *rate_ops = NULL;
+       struct clk_hw           *gate_hw = NULL;
+       const struct clk_ops    *gate_ops = NULL;
+
+       int                     parent_num;
+       const char              **parent_names = NULL;
+       u8                      rate_type_count = 0;
+
+
+       if (rkclk && rkclk->clk_name) {
+               clk_debug("%s: clk_name=%s, clk_type=0x%x, flags=0x%x\n",
+                               __func__, rkclk->clk_name, rkclk->clk_type,
+                               rkclk->flags);
+       } else {
+               clk_err("%s: rkclk or clk_name is NULL!\n", __func__);
+               return -EINVAL;
+       }
+
+       if (rkclk->mux_info && rkclk->mux_info->mux)
+               mux = rkclk->mux_info->mux;
+       if (rkclk->div_info && rkclk->div_info->div)
+               div = rkclk->div_info->div;
+       if (rkclk->gate_info && rkclk->gate_info->gate)
+               gate = rkclk->gate_info->gate;
+       if (rkclk->pll_info && rkclk->pll_info->pll)
+               pll = rkclk->pll_info->pll;
+       if (rkclk->frac_info && rkclk->frac_info->frac)
+               frac = rkclk->frac_info->frac;
+       if (rkclk->fixed_rate_info && rkclk->fixed_rate_info->fixed_rate)
+               fixed_rate = rkclk->fixed_rate_info->fixed_rate;
+       if (rkclk->fixed_factor_info && rkclk->fixed_factor_info->fixed_factor)
+               fixed_factor = rkclk->fixed_factor_info->fixed_factor;
+       if (rkclk->pd_info && rkclk->pd_info->pd)
+               pd = rkclk->pd_info->pd;
+
+
+       switch (rkclk->clk_type) {
+               case RKCLK_MUX_TYPE:
+                       /* only mux without specified ops will be registered here */
+                       if (rkclk->mux_info->clkops_idx == CLKOPS_TABLE_END) {
+                               clk_debug("use clk_register_mux\n");
+                               clk = clk_register_mux_table(NULL, rkclk->clk_name,
+                                               rkclk->mux_info->parent_names,
+                                               rkclk->mux_info->parent_num,
+                                               rkclk->flags, mux->reg, mux->shift,
+                                               mux->mask, mux->flags, NULL, &clk_lock);
+                               goto add_lookup;
+                       } else
+                               goto rgs_comp;
+               case RKCLK_PLL_TYPE:
+                       clk_debug("use rk_clk_register_pll\n");
+                       clk = rk_clk_register_pll(NULL, rkclk->clk_name,
+                                       rkclk->pll_info->parent_name,
+                                       rkclk->flags, pll->reg, pll->width,
+                                       pll->mode_offset, pll->mode_shift,
+                                       pll->status_offset, pll->status_shift,
+                                       pll->flags, &clk_lock);
+                       //kfree!!!!!!!
+                       goto add_lookup;
+               case RKCLK_DIV_TYPE:
+                       /* only div without specified ops will be registered here */
+                       if (rkclk->div_info->clkops_idx == CLKOPS_TABLE_END) {
+                               clk_debug("use clk_register_divider\n");
+                               clk = clk_register_divider(NULL, rkclk->clk_name,
+                                               rkclk->div_info->parent_name,
+                                               rkclk->flags, div->reg, div->shift,
+                                               div->width, div->flags, &clk_lock);
+                               goto add_lookup;
+                       } else
+                               goto rgs_comp;
+               case RKCLK_FRAC_TYPE:
+                       if (rkclk->frac_info->clkops_idx == CLKOPS_TABLE_END) {
+                               clk_err("frac node without specified ops!\n");
+                               return -EINVAL;
+                       } else
+                               goto rgs_comp;
+               case RKCLK_GATE_TYPE:
+                       clk_debug("use clk_register_gate\n");
+                       clk = clk_register_gate(NULL, rkclk->clk_name,
+                                       rkclk->gate_info->parent_name, rkclk->flags,
+                                       gate->reg, gate->bit_idx, gate->flags,
+                                       &clk_lock);
+                       goto add_lookup;
+               case RKCLK_FIXED_RATE_TYPE:
+                       clk_debug("use clk_register_fixed_rate\n");
+                       clk = clk_register_fixed_rate(NULL, rkclk->clk_name,
+                                       rkclk->fixed_rate_info->parent_name,
+                                       rkclk->flags, fixed_rate->fixed_rate);
+                       goto add_lookup;
+               case RKCLK_FIXED_FACTOR_TYPE:
+                       clk_debug("use clk_register_fixed_factor\n");
+                       clk = clk_register_fixed_factor(NULL, rkclk->clk_name,
+                                       rkclk->fixed_factor_info->parent_name,
+                                       rkclk->flags, fixed_factor->mult,
+                                       fixed_factor->div);
+                       goto add_lookup;
+               case RKCLK_PD_TYPE:
+                       clk_debug("use rk_clk_register_pd\n");
+                       clk = rk_clk_register_pd(NULL, rkclk->clk_name,
+                                       rkclk->pd_info->parent_name, rkclk->flags,
+                                       pd->id, &clk_lock);
+                       goto add_lookup;
+               default:
+                       goto rgs_comp;
+       }
+
+rgs_comp:
+
+       if (rkclk->clk_type & RKCLK_DIV_TYPE)
+               rate_type_count++;
+       if (rkclk->clk_type & RKCLK_PLL_TYPE)
+               rate_type_count++;
+       if (rkclk->clk_type & RKCLK_FRAC_TYPE)
+               rate_type_count++;
+       if (rkclk->clk_type & RKCLK_FIXED_RATE_TYPE)
+               rate_type_count++;
+       if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE)
+               rate_type_count++;
+
+       if (rate_type_count > 1) {
+               clk_err("Invalid rkclk type!\n");
+               return -EINVAL;
+       }
+
+       clk_debug("use clk_register_composite\n");
+
+       /* prepare args for clk_register_composite */
+
+       /* prepare parent_num && parent_names
+        * priority: MUX > DIV=PLL=FRAC=FIXED_FACTOR > GATE
+        */
+       if (rkclk->clk_type & RKCLK_MUX_TYPE) {
+               parent_num = rkclk->mux_info->parent_num;
+               parent_names = rkclk->mux_info->parent_names;
+       } else if (rkclk->clk_type & RKCLK_DIV_TYPE ) {
+               parent_num = 1;
+               parent_names = &(rkclk->div_info->parent_name);
+       } else if (rkclk->clk_type & RKCLK_PLL_TYPE) {
+               parent_num = 1;
+               parent_names = &(rkclk->pll_info->parent_name);
+       } else if (rkclk->clk_type & RKCLK_FRAC_TYPE) {
+               parent_num = 1;
+               parent_names = &(rkclk->frac_info->parent_name);
+       } else if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE) {
+               parent_num = 1;
+               parent_names = &(rkclk->fixed_factor_info->parent_name);
+       } else if (rkclk->clk_type & RKCLK_GATE_TYPE) {
+               parent_num = 1;
+               parent_names = &(rkclk->gate_info->parent_name);
+       }
+
+       /* prepare mux_hw && mux_ops */
+       if (rkclk->clk_type & RKCLK_MUX_TYPE) {
+               mux_hw = &mux->hw;
+               mux_ops = &clk_mux_ops;
+       }
+
+       /* prepare rate_hw && rate_ops
+        * priority: DIV=PLL=FRAC=FIXED_FACTOR > MUX
+        */
+       if (rkclk->clk_type & RKCLK_DIV_TYPE) {
+               rate_hw = &div->hw;
+               if (rkclk->div_info->clkops_idx != CLKOPS_TABLE_END)
+                       rate_ops = rk_get_clkops(rkclk->div_info->clkops_idx);
+               else
+                       rate_ops = &clk_divider_ops;
+       } else if (rkclk->clk_type & RKCLK_PLL_TYPE) {
+               rate_hw = &pll->hw;
+               rate_ops = rk_get_pll_ops(pll->flags);
+       } else if (rkclk->clk_type & RKCLK_FRAC_TYPE) {
+               rate_hw = &frac->hw;
+               rate_ops = rk_get_clkops(rkclk->frac_info->clkops_idx);
+       } else if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE) {
+               rate_hw = &fixed_factor->hw;
+               rate_ops = &clk_fixed_factor_ops;
+       } else if ((rkclk->clk_type & RKCLK_MUX_TYPE) &&
+                       (rkclk->mux_info->clkops_idx != CLKOPS_TABLE_END)) {
+               /* when a mux node has specified clkops_idx, prepare rate_hw &&
+                * rate_ops and use clk_register_composite to register it later.
+                */
+               /*FIXME*/
+               rate_hw = kzalloc(sizeof(struct clk_hw), GFP_KERNEL);
+               if (!rate_hw) {
+                       clk_err("%s: fail to alloc rate_hw!\n", __func__);
+                       return -ENOMEM;
+               }
+               rate_ops = rk_get_clkops(rkclk->mux_info->clkops_idx);
+       }
+
+       if (rkclk->clk_type & RKCLK_GATE_TYPE) {
+               gate_hw = &gate->hw;
+               gate_ops = &clk_gate_ops;
+       }
+
+       clk_debug("parent_num=%d, mux_hw=%d mux_ops=%d, rate_hw=%d rate_ops=%d,"
+                       " gate_hw=%d gate_ops=%d\n",
+                       parent_num, mux_hw?1:0, mux_ops?1:0, rate_hw?1:0,
+                       rate_ops?1:0, gate_hw?1:0, gate_ops?1:0);
+
+       clk = clk_register_composite(NULL, rkclk->clk_name, parent_names,
+                       parent_num, mux_hw, mux_ops, rate_hw, rate_ops,
+                       gate_hw, gate_ops, rkclk->flags);
+
+add_lookup:
+       if (clk) {
+               clk_debug("clk name=%s, flags=0x%lx\n", clk->name, clk->flags);
+               clk_register_clkdev(clk, rkclk->clk_name, NULL);
+       } else {
+               clk_err("%s: clk(\"%s\") register clk error\n", __func__,
+                               rkclk->clk_name);
+       }
+
+       return 0;
+}
+
+static int _rkclk_add_provider(struct device_node *np)
+{
+       int i, cnt, ret = 0;
+       const char *name = NULL;
+       struct clk *clk = NULL;
+       struct clk_onecell_data *clk_data = NULL;
+
+
+       clk_debug("\n");
+
+       cnt = of_property_count_strings(np, "clock-output-names");
+       if (cnt < 0) {
+               clk_err("%s: error in clock-output-names, cnt=%d\n", __func__,
+                               cnt);
+               return -EINVAL;
+       }
+
+       clk_debug("%s: cnt = %d\n", __func__, cnt);
+
+       if (cnt == 0) {
+               clk_debug("%s: nothing to do\n", __func__);
+               return 0;
+       }
+
+       if (cnt == 1) {
+               of_property_read_string(np, "clock-output-names", &name);
+               clk_debug("clock-output-names = %s\n", name);
+
+               clk = clk_get_sys(NULL, name);
+               if (IS_ERR(clk)) {
+                       clk_err("%s: fail to get %s\n", __func__, name);
+                       return -EINVAL;
+               }
+
+               ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+               clk_debug("use of_clk_src_simple_get, ret=%d\n", ret);
+       } else {
+               clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+               if (!clk_data)
+                       return -ENOMEM;
+
+               clk_data->clks = kzalloc(cnt * sizeof(struct clk *), GFP_KERNEL);
+               if (!clk_data->clks) {
+                       kfree(clk_data);
+                       return -ENOMEM;
+               }
+
+               clk_data->clk_num = cnt;
+
+               for (i=0; i<cnt; i++) {
+                       of_property_read_string_index(np, "clock-output-names",
+                                       i, &name);
+                       clk_debug("clock-output-names[%d]=%s\n", i, name);
+
+                       /* ignore empty slots */
+                       if (!strcmp("reserved", name))
+                               continue;
+
+                       clk = clk_get_sys(NULL, name);
+                       if (IS_ERR(clk)) {
+                               clk_err("%s: fail to get %s\n", __func__, name);
+                               continue;
+                       }
+
+                       clk_data->clks[i] = clk;
+               }
+
+               ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+               clk_debug("use of_clk_src_onecell_get, ret=%d\n", ret);
+       }
+
+       return ret;
+}
+
+static void rkclk_add_provider(struct device_node *np)
+{
+       struct device_node *node, *node_reg, *node_tmp, *node_prd;
+       const char *compatible;
+
+
+       for_each_available_child_of_node(np, node) {
+               of_property_read_string(node, "compatible", &compatible);
+
+               if (strcmp(compatible, "rockchip,rk-fixed-rate-cons") == 0) {
+                       for_each_available_child_of_node(node, node_prd) {
+                                _rkclk_add_provider(node_prd);
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-fixed-factor-cons") == 0) {
+                       for_each_available_child_of_node(node, node_prd) {
+                                _rkclk_add_provider(node_prd);
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-clock-regs") == 0) {
+                       for_each_available_child_of_node(node, node_reg) {
+                               of_property_read_string(node_reg, "compatible", &compatible);
+
+                               if (strcmp(compatible, "rockchip,rk-pll-cons") == 0) {
+                                       for_each_available_child_of_node(node_reg, node_prd) {
+                                               _rkclk_add_provider(node_prd);
+                                       }
+                               } else if (strcmp(compatible, "rockchip,rk-sel-cons") == 0) {
+                                       for_each_available_child_of_node(node_reg, node_tmp) {
+                                               for_each_available_child_of_node(node_tmp,
+                                                       node_prd) {
+                                                       _rkclk_add_provider(node_prd);
+                                               }
+                                       }
+                               } else if (strcmp(compatible, "rockchip,rk-gate-cons") == 0) {
+                                       for_each_available_child_of_node(node_reg, node_prd) {
+                                                _rkclk_add_provider(node_prd);
+                                       }
+                               } else {
+                                       clk_err("%s: unknown\n", __func__);
+                               }
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-pd-cons") == 0) {
+                       for_each_available_child_of_node(node, node_prd) {
+                                _rkclk_add_provider(node_prd);
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-clock-special-regs") == 0) {
+                       for_each_available_child_of_node(node, node_prd) {
+                                _rkclk_add_provider(node_prd);
+                       }
+               } else {
+                       clk_err("%s: unknown\n", __func__);
+               }
+       }
+
+}
+
+static void rkclk_cache_parents(struct rkclk *rkclk)
+{
+       struct clk *clk, *parent;
+       u8 num_parents;
+       int i;
+
+
+       clk = clk_get(NULL, rkclk->clk_name);
+       if (IS_ERR(clk)) {
+               clk_err("%s: %s clk_get error\n",
+                               __func__, rkclk->clk_name);
+               return;
+       } else {
+               clk_debug("%s: %s clk_get success\n",
+                               __func__, __clk_get_name(clk));
+       }
+
+       num_parents = __clk_get_num_parents(clk);
+       clk_debug("\t\tnum_parents=%d, parent=%s\n", num_parents,
+                       __clk_get_name(__clk_get_parent(clk)));
+
+       for (i=0; i<num_parents; i++) {
+               /* parent will be cached after this func is called */
+               parent = clk_get_parent_by_index(clk, i);
+               if (IS_ERR(parent)) {
+                       clk_err("fail to get parents[%d]=%s\n", i,
+                                       clk->parent_names[i]);
+                       continue;
+               } else {
+                       clk_debug("\t\tparents[%d]: %s\n", i,
+                                       __clk_get_name(parent));
+               }
+       }
+}
+
+void rk_dump_cru(void)
+{
+       printk(KERN_WARNING "CRU:\n");
+       print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 32, 4, rk_cru_base,
+                      0x420, false);
+}
+EXPORT_SYMBOL_GPL(rk_dump_cru);
+
+
+#ifdef RKCLK_DEBUG
+void rkclk_dump_info(struct rkclk *rkclk)
+{
+       struct clk_mux          *mux = NULL;
+       struct clk_divider      *div = NULL;
+       struct clk_gate         *gate = NULL;
+       struct clk_pll          *pll = NULL;
+       struct clk_divider      *frac = NULL;
+       struct clk_fixed_rate   *fixed_rate = NULL;
+       struct clk_fixed_factor *fixed_factor = NULL;
+       struct clk_pd           *pd = NULL;
+       int i;
+
+
+       clk_debug("%s: clkname=%s, type=0x%x, flags=0x%x\n",
+                       __func__, (rkclk->clk_name)?(rkclk->clk_name):NULL,
+                       rkclk->clk_type, rkclk->flags);
+
+       if (rkclk->mux_info && rkclk->mux_info->mux)
+               mux = rkclk->mux_info->mux;
+       if (rkclk->div_info && rkclk->div_info->div)
+               div = rkclk->div_info->div;
+       if (rkclk->pll_info && rkclk->pll_info->pll)
+               pll = rkclk->pll_info->pll;
+       if (rkclk->frac_info && rkclk->frac_info->frac)
+               frac = rkclk->frac_info->frac;
+       if (rkclk->gate_info && rkclk->gate_info->gate)
+               gate = rkclk->gate_info->gate;
+       if (rkclk->fixed_rate_info && rkclk->fixed_rate_info->fixed_rate)
+               fixed_rate = rkclk->fixed_rate_info->fixed_rate;
+       if (rkclk->fixed_factor_info && rkclk->fixed_factor_info->fixed_factor)
+               fixed_factor = rkclk->fixed_factor_info->fixed_factor;
+       if (rkclk->pd_info && rkclk->pd_info->pd)
+               pd = rkclk->pd_info->pd;
+
+
+       if (rkclk->mux_info) {
+               clk_debug("\t\tmux_info: name=%s, clkops_idx=%u\n",
+                               rkclk->mux_info->clk_name,
+                               rkclk->mux_info->clkops_idx);
+               for (i = 0; i < rkclk->mux_info->parent_num; i++)
+                       clk_debug("\t\t\tparent[%d]: %s\n", i,
+                                       rkclk->mux_info->parent_names[i]);
+               if (mux) {
+                       clk_debug("\t\tmux: reg=0x%x, mask=0x%x, shift=0x%x, "
+                                       "mux_flags=0x%x\n", (u32)mux->reg,
+                                       mux->mask, mux->shift, mux->flags);
+               }
+       }
+
+       if (rkclk->pll_info) {
+               clk_debug("\t\tpll_info: name=%s, parent=%s, clkops_idx=0x%x\n",
+                               rkclk->pll_info->clk_name,
+                               rkclk->pll_info->parent_name,
+                               rkclk->pll_info->clkops_idx);
+               if (pll) {
+                       clk_debug("\t\tpll: reg=0x%x, width=0x%x, "
+                                       "mode_offset=0x%x, mode_shift=%u, "
+                                       "status_offset=0x%x, status_shift=%u, "
+                                       "pll->flags=%u\n",
+                                       (u32)pll->reg, pll->width,
+                                       pll->mode_offset, pll->mode_shift,
+                                       pll->status_offset, pll->status_shift,
+                                       pll->flags);
+               }
+       }
+
+       if (rkclk->div_info) {
+               clk_debug("\t\tdiv_info: name=%s, div_type=0x%x, parent=%s, "
+                               "clkops_idx=%d\n",
+                               rkclk->div_info->clk_name,
+                               rkclk->div_info->div_type,
+                               rkclk->div_info->parent_name,
+                               rkclk->div_info->clkops_idx);
+               if (div) {
+                       clk_debug("\t\tdiv: reg=0x%x, shift=0x%x, width=0x%x, "
+                                       "div_flags=0x%x\n", (u32)div->reg,
+                                       div->shift, div->width, div->flags);
+               }
+       }
+
+       if (rkclk->frac_info) {
+               clk_debug("\t\tfrac_info: name=%s, parent=%s, clkops_idx=%d\n",
+                               rkclk->frac_info->clk_name,
+                               rkclk->frac_info->parent_name,
+                               rkclk->frac_info->clkops_idx);
+               if (frac) {
+                       clk_debug("\t\tfrac: reg=0x%x, shift=0x%x, width=0x%x, "
+                                       "div_flags=0x%x\n", (u32)frac->reg,
+                                       frac->shift, frac->width, frac->flags);
+               }
+       }
+
+       if (rkclk->gate_info) {
+               clk_debug("\t\tgate_info: name=%s, parent=%s\n",
+                               rkclk->gate_info->clk_name,
+                               rkclk->gate_info->parent_name);
+               if (gate) {
+                       clk_debug("\t\tgate: reg=0x%x, bit_idx=%d, "
+                                       "gate_flags=0x%x\n", (u32)gate->reg,
+                                       gate->bit_idx, gate->flags);
+               }
+       }
+
+       if (rkclk->fixed_rate_info) {
+               clk_debug("\t\tfixed_rate_info: name=%s\n",
+                               rkclk->fixed_rate_info->clk_name);
+               if (fixed_rate) {
+                       clk_debug("\t\tfixed_rate=%lu, fixed_rate_flags=0x%x\n",
+                               fixed_rate->fixed_rate, fixed_rate->flags);
+               }
+       }
+
+       if (rkclk->fixed_factor_info) {
+               clk_debug("\t\tfixed_factor_info: name=%s, parent=%s\n",
+                               rkclk->fixed_factor_info->clk_name,
+                               rkclk->fixed_factor_info->parent_name);
+               if (fixed_factor) {
+                       clk_debug("\t\tfixed_factor: mult=%u, div=%u\n",
+                               fixed_factor->mult, fixed_factor->div);
+               }
+       }
+
+       if (rkclk->pd_info) {
+               clk_debug("\t\tpd_info: name=%s, parent=%s\n",
+                               rkclk->pd_info->clk_name,
+                               rkclk->pd_info->parent_name);
+               if (pd) {
+                       clk_debug("\t\tpd: id=%u\n", pd->id);
+               }
+       }
+}
+#else
+void rkclk_dump_info(struct rkclk *rkclk) {}
+#endif
+
+
+#ifdef RKCLK_TEST
+char* pd_table[] = {
+       "pd_gpu",
+       "pd_video",
+       "pd_vio",
+       "pd_hevc",
+};
+
+void rk_clk_pd_test(void)
+{
+       struct clk *clk;
+       bool state;
+       int j, ret;
+
+
+       for (j = 0; j < ARRAY_SIZE(pd_table); j++) {
+
+               clk = clk_get(NULL, pd_table[j]);
+
+               ret = clk_prepare_enable(clk);
+               printk("%s: clk_prepare_enable %s, ret=%d\n", __func__,
+                       __clk_get_name(clk), ret);
+
+               state = __clk_is_enabled(clk);
+               printk("%s: clk_pd %s is %s\n", __func__, __clk_get_name(clk),
+                       state ? "enable" : "disable");
+
+               clk_disable_unprepare(clk);
+               printk("%s: clk_disable_unprepare %s\n", __func__,
+                       __clk_get_name(clk));
+
+               state = __clk_is_enabled(clk);
+               printk("%s: clk_pd %s is %s\n", __func__, __clk_get_name(clk),
+                       state ? "enable" : "disable");
+
+               printk("\n");
+       }
+}
+
+struct test_table {
+       const char *name;
+       u32 rate;
+};
+
+struct test_table t_table[] = {
+       {.name = "clk_gpu",     .rate = 297000000},
+       {.name = "dclk_lcdc0",  .rate = 100000000},
+       {.name = "aclk_lcdc0",  .rate = 297000000},
+
+       {.name = "clk_sdmmc",   .rate = 50000000},
+       {.name = "clk_emmc",    .rate = 50000000},
+       {.name = "clk_sdio",    .rate = 50000000},
+
+       {.name = "clk_i2s_div", .rate = 300000000},
+       {.name = "clk_i2s_frac",.rate = 22579200},
+       {.name = "clk_i2s",     .rate = 11289600},
+       {.name = "clk_spdif",   .rate = 11289600},
+
+       {.name = "cif_out_pll", .rate = 48000000},
+       {.name = "clk_cif0",    .rate = 12000000},
+
+       {.name = "clk_uart0",   .rate = 12288000},
+       {.name = "clk_uart1",   .rate = 48000000},
+       {.name = "clk_hsadc",   .rate = 12288000},
+       {.name = "clk_mac",     .rate = 50000000},
+
+//     {.name = "clk_apll",    .rate = 500000000},
+//     {.name = "clk_dpll",    .rate = 400000000},
+       {.name = "clk_cpll",    .rate = 600000000},
+       {.name = "clk_gpll",    .rate = 800000000},
+
+       {.name = "clk_core",    .rate = 100000000},
+       {.name = "clk_core",    .rate = 24000000},
+       {.name = "clk_core",    .rate = 500000000},
+};
+
+
+void rk_clk_test(void)
+{
+       const char *clk_name;
+       struct clk *clk;
+       unsigned long rate=0, recalc_rate=0, round_rate=0, get_rate=0;
+       u32 j = 0;
+       int ret;
+
+       for (j = 0; j < ARRAY_SIZE(t_table); j++) {
+               clk_debug(">>>>>>test %u\n", j);
+
+               clk_name = t_table[j].name;
+               rate = t_table[j].rate;
+
+               clk = clk_get(NULL, clk_name);
+               if (IS_ERR(clk)) {
+                       clk_err("%s: clk(\"%s\") \tclk_get error\n",
+                                       __func__, clk_name);
+               } else
+                       clk_debug("%s: clk(\"%s\") \tclk_get success\n",
+                                       __func__, clk_name);
+
+               /* TEST: clk_round_rate */
+               round_rate = clk_round_rate(clk, rate);
+               clk_debug("%s: clk(\"%s\") \tclk_round_rate from %lu to %lu\n",
+                               __func__, clk_name, rate, round_rate);
+
+               /* TEST: clk_set_rate */
+               ret = clk_set_rate(clk, rate);
+               if (ret) {
+                       clk_err("%s: clk(\"%s\") \tclk_set_rate error, ret=%d\n",
+                                       __func__, clk_name, ret);
+               } else {
+                       clk_debug("%s: clk(\"%s\") \tclk_set_rate success\n",
+                                       __func__, clk_name);
+               }
+
+               /* TEST: recalc_rate\clk_get_rate */
+               if (clk->ops->recalc_rate) {
+                       recalc_rate = clk->ops->recalc_rate(clk->hw,
+                                       clk->parent->rate);
+                       clk_debug("%s: clk(\"%s\") \tclk_recalc_rate %lu\n",
+                                       __func__, clk_name, recalc_rate);
+               } else {
+                       clk_debug("%s: clk(\"%s\") have no recalc ops\n",
+                                       __func__, clk_name);
+                       get_rate = clk_get_rate(clk);
+                       clk_debug("%s: clk(\"%s\") \tclk_get_rate %lu\n",
+                                       __func__, clk_name, get_rate);
+               }
+
+               rk_dump_cru();
+       }
+
+       rk_clk_pd_test();
+}
+#else
+void rk_clk_test(void) {}
+#endif
+EXPORT_SYMBOL_GPL(rk_clk_test);
+
+static int rkclk_panic(struct notifier_block *this, unsigned long ev, void *ptr)
+{
+       rk_dump_cru();
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block rkclk_panic_block = {
+       .notifier_call = rkclk_panic,
+};
+
+void __init rkclk_init_clks(struct device_node *node);
+
+static struct device_node * clk_root_node=NULL;
+static void __init rk_clk_tree_init(struct device_node *np)
+{
+       struct device_node *node, *node_init;
+       struct rkclk *rkclk;
+       const char *compatible;
+
+       printk("%s start!\n", __func__);
+
+       node_init = of_find_node_by_name(NULL, "clocks-init");
+       if (!node_init) {
+               clk_err("%s: can not get clocks-init node\n", __func__);
+               return;
+       }
+
+       clk_root_node = of_find_node_by_name(NULL, "clock_regs");
+       rk_cru_base = of_iomap(clk_root_node, 0);
+       if (!rk_cru_base) {
+               clk_err("%s: could not map cru region\n", __func__);
+               return;
+       }
+
+       node = of_parse_phandle(np, "rockchip,grf", 0);
+       if (node)
+               rk_grf_base = of_iomap(node, 0);
+#ifdef CONFIG_ARM
+       if (!rk_grf_base)
+               rk_grf_base = RK_GRF_VIRT;
+#endif
+
+       for_each_available_child_of_node(np, node) {
+               clk_debug("\n");
+               of_property_read_string(node, "compatible",
+                               &compatible);
+
+               if (strcmp(compatible, "rockchip,rk-fixed-rate-cons") == 0) {
+                       if (rkclk_init_fixed_rate(node) != 0) {
+                               clk_err("%s: init fixed_rate err\n", __func__);
+                               return;
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-fixed-factor-cons") == 0) {
+                       if (rkclk_init_fixed_factor(node) != 0) {
+                               clk_err("%s: init fixed_factor err\n", __func__);
+                               return;
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-clock-regs") == 0) {
+                       if (rkclk_init_regcon(node) != 0) {
+                               clk_err("%s: init reg cons err\n", __func__);
+                               return;
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-pd-cons") == 0) {
+                       if (rkclk_init_pd(node) != 0) {
+                               clk_err("%s: init pd err\n", __func__);
+                               return;
+                       }
+               } else if (strcmp(compatible, "rockchip,rk-clock-special-regs") == 0) {
+                       if (rkclk_init_special_regs(node) != 0) {
+                               clk_err("%s: init special reg err\n", __func__);
+                               return;
+                       }
+               } else {
+                       clk_err("%s: unknown\n", __func__);
+               }
+       }
+
+       list_for_each_entry(rkclk, &rk_clks, node) {
+               clk_debug("\n");
+               rkclk_dump_info(rkclk);
+               clk_debug("\n");
+               rkclk_register(rkclk);
+       }
+
+       rkclk_add_provider(np);
+
+       /* fill clock parents cache after all clocks have been registered */
+       list_for_each_entry(rkclk, &rk_clks, node) {
+               clk_debug("\n");
+               rkclk_cache_parents(rkclk);
+       }
+
+       rkclk_init_clks(node_init);
+
+       rk_clk_test();
+
+       atomic_notifier_chain_register(&panic_notifier_list, &rkclk_panic_block);
+}
+CLK_OF_DECLARE(rk_clocks, "rockchip,rk-clocks", rk_clk_tree_init);
+
+
+/***************************** rockchip clks init******************************/
+const char *of_clk_init_rate_get_info(struct device_node *np,
+               int index,u32 *rate)
+{
+       struct of_phandle_args clkspec;
+       const char *clk_name;
+       int rc;
+
+       if (index < 0)
+               return NULL;
+
+       rc = of_parse_phandle_with_args(np, "rockchip,clocks-init-rate",
+                       "#clock-init-cells", index, &clkspec);
+       if (rc)
+               return NULL;
+
+       if (of_property_read_string_index(clkspec.np, "clock-output-names", 0,
+                               &clk_name) < 0)
+               return NULL;
+
+       *rate= clkspec.args[0];
+
+       of_node_put(clkspec.np);
+       return clk_name;
+}
+
+const char *of_clk_init_parent_get_info(struct device_node *np, int index,
+               const char **clk_child_name)
+{
+       struct of_phandle_args clkspec;
+       const char *clk_name;
+       int rc;
+       phandle phandle;
+       struct device_node *node = NULL;
+
+       if (index < 0)
+               return NULL;
+
+       rc = of_parse_phandle_with_args(np, "rockchip,clocks-init-parent",
+                       "#clock-init-cells", index, &clkspec);
+       if (rc)
+               return NULL;
+
+       if (of_property_read_string_index(clkspec.np, "clock-output-names", 0,
+                               &clk_name) < 0)
+               return NULL;
+
+
+       phandle = clkspec.args[0];
+
+       of_node_put(clkspec.np);
+
+       if (phandle) {
+
+               node = of_find_node_by_phandle(phandle);
+               if (!node) {
+                       return NULL;
+               }
+
+               if (of_property_read_string_index(node, "clock-output-names", 0,
+                                       clk_child_name) < 0)
+                       return NULL;
+
+               of_node_put(node);//???
+               node=NULL;
+       }
+       else
+               return NULL;
+
+       return clk_name;
+}
+
+static int __init rkclk_init_enable(void)
+{
+       struct device_node *node;
+       int cnt, i, ret = 0;
+       const char *clk_name;
+       struct clk *clk;
+
+
+       node = of_find_node_by_name(NULL, "clocks-enable");
+       if (!node) {
+               clk_err("%s: can not get clocks-enable node\n", __func__);
+               return -EINVAL;
+       }
+
+       cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
+       if (cnt < 0) {
+               return -EINVAL;
+       } else {
+               clk_debug("%s: cnt = %d\n", __func__, cnt);
+       }
+
+       for (i = 0; i < cnt ; i++) {
+               clk_name = of_clk_get_parent_name(node, i);
+               clk = clk_get(NULL, clk_name);
+               if (IS_ERR_OR_NULL(clk)) {
+                       clk_err("%s: fail to get %s\n", __func__, clk_name);
+                       return -EINVAL;
+               }
+
+               ret = clk_prepare_enable(clk);
+               if (ret) {
+                       clk_err("%s: fail to prepare_enable %s\n", __func__,
+                               clk_name);
+                       return ret;
+               } else {
+                       clk_debug("%s: prepare_enable %s OK\n", __func__,
+                               clk_name);
+               }
+       }
+
+       return ret;
+}
+
+static int uboot_logo_on = 0;
+
+static void __init rk_get_uboot_display_flag(void)
+{
+       struct device_node *node;
+
+       node = of_find_node_by_name(NULL, "fb");
+       if (node)
+               of_property_read_u32(node, "rockchip,uboot-logo-on", &uboot_logo_on);
+
+       printk("%s: uboot_logo_on = %d\n", __FUNCTION__, uboot_logo_on);
+}
+
+static const char *of_clk_uboot_has_init_get_name(struct device_node *np, int index)
+{
+       struct of_phandle_args clkspec;
+       const char *clk_name;
+       int rc;
+
+       if (index < 0)
+               return NULL;
+
+       rc = of_parse_phandle_with_args(np, "rockchip,clocks-uboot-has-init", 
+               "#clock-cells", index, &clkspec);
+       if (rc)
+               return NULL;
+
+       if (of_property_read_string_index(clkspec.np, "clock-output-names",
+                                         clkspec.args_count ? clkspec.args[0] : 0,
+                                         &clk_name) < 0)
+               clk_name = NULL;
+
+       of_node_put(clkspec.np);
+       return clk_name;
+}
+
+/* If clk has been inited, return 1; else return 0. */
+static int rkclk_uboot_has_init(struct device_node *np, const char *clk_name)
+{
+       int cnt, i;
+       const char *name;
+
+
+       if ((!np) || (!clk_name))
+               return 0;
+
+       cnt = of_count_phandle_with_args(np, "rockchip,clocks-uboot-has-init", 
+               "#clock-cells");
+       if (cnt < 0)
+               return 0;
+
+       for (i = 0; i < cnt ; i++) {
+               name = of_clk_uboot_has_init_get_name(np, i);
+               if (name && (!strcmp(clk_name, name)))
+                       return 1;
+       }
+
+       return 0;
+}
+
+void __init rkclk_init_clks(struct device_node *np)
+{
+       //struct device_node *np;
+       int i,cnt_parent,cnt_rate;
+       u32 clk_rate;
+       //int ret;
+       struct clk *clk_p, *clk_c;
+       const char *clk_name, *clk_parent_name;
+
+
+       rk_get_uboot_display_flag();
+
+       cnt_parent = of_count_phandle_with_args(np,
+                       "rockchip,clocks-init-parent", "#clock-init-cells");
+
+       printk("%s: cnt_parent = %d\n",__FUNCTION__,cnt_parent);
+
+       for (i = 0; i < cnt_parent; i++) {
+               clk_parent_name=NULL;
+               clk_name=of_clk_init_parent_get_info(np, i,&clk_parent_name);
+
+               if(clk_name==NULL||clk_parent_name==NULL)
+                       continue;
+
+               clk_c=clk_get(NULL,clk_name);
+               clk_p=clk_get(NULL,clk_parent_name);
+
+               if(IS_ERR(clk_c)||IS_ERR(clk_p))
+                       continue;
+
+               clk_set_parent(clk_c, clk_p);
+
+               clk_debug("%s: set %s parent = %s\n", __FUNCTION__, clk_name,
+                               clk_parent_name);
+       }
+
+       cnt_rate = of_count_phandle_with_args(np, "rockchip,clocks-init-rate",
+                       "#clock-init-cells");
+
+       printk("%s: cnt_rate = %d\n",__FUNCTION__,cnt_rate);
+
+       for (i = 0; i < cnt_rate; i++) {
+               clk_name=of_clk_init_rate_get_info(np, i, &clk_rate);
+
+               if (clk_name==NULL)
+                       continue;
+
+               if (uboot_logo_on && rkclk_uboot_has_init(np, clk_name)) {
+                       printk("%s: %s has been inited in uboot, ingored\n", 
+                               __FUNCTION__, clk_name);
+                       continue;
+               }
+
+               clk_c = clk_get(NULL, clk_name);
+
+               if(IS_ERR(clk_c))
+                       continue;
+
+               if((clk_rate<1*MHZ)||(clk_rate>2000*MHZ))
+                       clk_err("warning: clk_rate < 1*MHZ or > 2000*MHZ\n");
+
+               clk_set_rate(clk_c, clk_rate);
+
+               clk_debug("%s: set %s rate = %u\n", __FUNCTION__, clk_name,
+                               clk_rate);
+       }
+
+       rkclk_init_enable();
+
+}
+
+u32 clk_suspend_clkgt_info_get(u32 *clk_ungt_msk,u32 *clk_ungt_msk_last,u32 buf_cnt)
+{
+
+    struct device_node *node,*node_gt;
+    u32 temp_val[2];
+    int gt_cnt;
+    int ret;
+    void __iomem *cru_base,*gt_base, *reg_n, *reg_p;
+
+    gt_cnt=0;
+    cru_base= of_iomap(clk_root_node, 0);
+
+    for_each_available_child_of_node(clk_root_node, node) {
+
+           if (of_device_is_compatible(node,"rockchip,rk-gate-cons"))
+            {
+
+                for_each_available_child_of_node(node, node_gt) {
+
+                    if(gt_cnt>=buf_cnt)
+                    {
+                        clk_err("%s:save buf is overflow\n",__FUNCTION__);
+                        return 0;
+                    }
+
+                    ret = of_property_read_u32_array(node_gt,"rockchip,suspend-clkgating-setting",temp_val,2);
+                    if(!ret)
+                    {
+                        clk_ungt_msk[gt_cnt]=temp_val[0];
+                        clk_ungt_msk_last[gt_cnt]=temp_val[1];
+                    }
+                    else
+                    {
+                        clk_ungt_msk[gt_cnt]=0xffff;
+                        clk_ungt_msk_last[gt_cnt]=0xffff;
+                    }
+
+                    if(gt_cnt==0)
+                    {
+                        gt_base=of_iomap(node_gt, 0);
+                        reg_p=gt_base;
+                        reg_n=gt_base;
+                    }
+                    else
+                    {
+                        reg_n=of_iomap(node_gt, 0);
+
+                        if(((long)reg_n-(long)reg_p)!=4)
+                        {
+                            printk("%s: gt reg is not continue\n",__FUNCTION__);
+                            return 0;
+                        }
+                        reg_p=reg_n;
+                    }
+
+                    clk_debug("%s:gt%d,reg=%p,val=(%x,%x)\n",__FUNCTION__,gt_cnt, reg_n,
+                    clk_ungt_msk[gt_cnt], clk_ungt_msk_last[gt_cnt]);
+
+                    gt_cnt++;
+
+                }
+
+                break;
+            }
+    }
+
+    if(gt_cnt!=buf_cnt)
+    {
+           clk_err("%s:save buf is not  Enough\n",__FUNCTION__);
+           return 0;
+    }
+    clk_debug("%s:crubase=%x,gtbase=%x\n",__FUNCTION__,cru_base,gt_base);
+
+    return (u32)(gt_base-cru_base);
+
+}
+
+
+
+
diff --git a/drivers/clk/rk/pd-rk3368.c b/drivers/clk/rk/pd-rk3368.c
new file mode 100644 (file)
index 0000000..53fb60d
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Power domain support for Rockchip RK3368
+ *
+ * Copyright (C) 2014-2015 ROCKCHIP, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/rockchip/pmu.h>
+#include <linux/rockchip/cru.h>
+#include <linux/rockchip/cpu_axi.h>
+
+#include "clk-ops.h"
+
+static void __iomem *rk_pmu_base;
+
+static u32 pmu_readl(u32 offset)
+{
+       return readl_relaxed(rk_pmu_base + (offset));
+}
+
+static void pmu_writel(u32 val, u32 offset)
+{
+       writel_relaxed(val, rk_pmu_base + (offset));
+       dsb(sy);
+}
+
+static const u8 pmu_pd_map[] = {
+       [PD_PERI] = 13,
+       [PD_VIDEO] = 14,
+       [PD_VIO] = 15,
+       [PD_GPU_0] = 16,
+       [PD_GPU_1] = 17,
+};
+
+static const u8 pmu_st_map[] = {
+       [PD_PERI] = 12,
+       [PD_VIDEO] = 13,
+       [PD_VIO] = 14,
+       [PD_GPU_0] = 15,
+       [PD_GPU_1] = 16,
+};
+
+static bool rk3368_pmu_power_domain_is_on(enum pmu_power_domain pd)
+{
+       /* 1'b0: power on, 1'b1: power off */
+       return !(pmu_readl(RK3368_PMU_PWRDN_ST) & BIT(pmu_st_map[pd]));
+}
+
+static DEFINE_SPINLOCK(pmu_idle_lock);
+
+static const u8 pmu_idle_map[] = {
+       [IDLE_REQ_GPU] = 2,
+       [IDLE_REQ_BUS] = 4,
+       [IDLE_REQ_PERI] = 6,
+       [IDLE_REQ_VIDEO] = 7,
+       [IDLE_REQ_VIO] = 8,
+};
+
+static int rk3368_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
+{
+       u32 bit = pmu_idle_map[req];
+       u32 idle_mask = BIT(bit) | BIT(bit + 16);
+       u32 idle_target = (idle << bit) | (idle << (bit + 16));
+       u32 mask = BIT(bit);
+       u32 val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pmu_idle_lock, flags);
+
+       val = pmu_readl(RK3368_PMU_IDLE_REQ);
+       if (idle)
+               val |=  mask;
+       else
+               val &= ~mask;
+       pmu_writel(val, RK3368_PMU_IDLE_REQ);
+       dsb(sy);
+
+       while ((pmu_readl(RK3368_PMU_IDLE_ST) & idle_mask) != idle_target)
+               ;
+
+       spin_unlock_irqrestore(&pmu_idle_lock, flags);
+
+       return 0;
+}
+
+static DEFINE_SPINLOCK(pmu_pd_lock);
+
+static noinline void rk3368_do_pmu_set_power_domain
+                                       (enum pmu_power_domain domain, bool on)
+{
+       u8 pd = pmu_pd_map[domain];
+       u32 val = pmu_readl(RK3368_PMU_PWRDN_CON);
+
+       if (on)
+               val &= ~BIT(pd);
+       else
+               val |=  BIT(pd);
+
+       pmu_writel(val, RK3368_PMU_PWRDN_CON);
+       dsb(sy);
+
+       while ((pmu_readl(RK3368_PMU_PWRDN_ST) & BIT(pmu_st_map[domain])) == on)
+               ;
+}
+
+/* PD_VIO */
+static void __iomem *iep_qos_base;
+static u32 iep_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *isp_r0_qos_base;
+static u32 isp_r0_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *isp_r1_qos_base;
+static u32 isp_r1_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *isp_w0_qos_base;
+static u32 isp_w0_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *isp_w1_qos_base;
+static u32 isp_w1_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *vip_qos_base;
+static u32 vip_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *vop_qos_base;
+static u32 vop_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *rga_r_qos_base;
+static u32 rga_r_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *rga_w_qos_base;
+static u32 rga_w_qos[CPU_AXI_QOS_NUM_REGS];
+/* PD_VIDEO */
+static void __iomem *hevc_r_qos_base;
+static u32 hevc_r_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *vpu_r_qos_base;
+static u32 vpu_r_qos[CPU_AXI_QOS_NUM_REGS];
+static void __iomem *vpu_w_qos_base;
+static u32 vpu_w_qos[CPU_AXI_QOS_NUM_REGS];
+/* PD_GPU_0 */
+static void __iomem *gpu_qos_base;
+static u32 gpu_qos[CPU_AXI_QOS_NUM_REGS];
+/* PD_PERI */
+static void __iomem *peri_qos_base;
+static u32 peri_qos[CPU_AXI_QOS_NUM_REGS];
+
+#define PD_SAVE_QOS(name) CPU_AXI_SAVE_QOS(name##_qos, name##_qos_base)
+#define PD_RESTORE_QOS(name) CPU_AXI_RESTORE_QOS(name##_qos, name##_qos_base)
+
+static int rk3368_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pmu_pd_lock, flags);
+
+       if (rk3368_pmu_power_domain_is_on(pd) == on)
+               goto out;
+
+       if (!on) {
+               /* if power down, idle request to NIU first */
+               if (pd == PD_VIO) {
+                       PD_SAVE_QOS(iep);
+                       PD_SAVE_QOS(isp_r0);
+                       PD_SAVE_QOS(isp_r1);
+                       PD_SAVE_QOS(isp_w0);
+                       PD_SAVE_QOS(isp_w1);
+                       PD_SAVE_QOS(vip);
+                       PD_SAVE_QOS(vop);
+                       PD_SAVE_QOS(rga_r);
+                       PD_SAVE_QOS(rga_w);
+                       rk3368_pmu_set_idle_request(IDLE_REQ_VIO, true);
+               } else if (pd == PD_VIDEO) {
+                       PD_SAVE_QOS(hevc_r);
+                       PD_SAVE_QOS(vpu_r);
+                       PD_SAVE_QOS(vpu_w);
+                       rk3368_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
+               } else if (pd == PD_GPU_0) {
+                       PD_SAVE_QOS(gpu);
+                       rk3368_pmu_set_idle_request(IDLE_REQ_GPU, true);
+               } else if (pd == PD_PERI) {
+                       PD_SAVE_QOS(peri);
+                       rk3368_pmu_set_idle_request(IDLE_REQ_PERI, true);
+               }
+       }
+
+       rk3368_do_pmu_set_power_domain(pd, on);
+
+       if (on) {
+               /* if power up, idle request release to NIU */
+               if (pd == PD_VIO) {
+                       rk3368_pmu_set_idle_request(IDLE_REQ_VIO, false);
+                       PD_RESTORE_QOS(iep);
+                       PD_RESTORE_QOS(isp_r0);
+                       PD_RESTORE_QOS(isp_r1);
+                       PD_RESTORE_QOS(isp_w0);
+                       PD_RESTORE_QOS(isp_w1);
+                       PD_RESTORE_QOS(vip);
+                       PD_RESTORE_QOS(vop);
+                       PD_RESTORE_QOS(rga_r);
+                       PD_RESTORE_QOS(rga_w);
+               } else if (pd == PD_VIDEO) {
+                       rk3368_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
+                       PD_RESTORE_QOS(hevc_r);
+                       PD_RESTORE_QOS(vpu_r);
+                       PD_RESTORE_QOS(vpu_w);
+               } else if (pd == PD_GPU_0) {
+                       rk3368_pmu_set_idle_request(IDLE_REQ_GPU, false);
+                       PD_RESTORE_QOS(gpu);
+               } else if (pd == PD_PERI) {
+                       rk3368_pmu_set_idle_request(IDLE_REQ_PERI, false);
+                       PD_RESTORE_QOS(peri);
+               }
+       }
+
+out:
+       spin_unlock_irqrestore(&pmu_pd_lock, flags);
+       return 0;
+}
+
+static int rk3368_sys_set_power_domain(enum pmu_power_domain pd, bool on)
+{
+       u32 clks_ungating[RK3368_CRU_CLKGATES_CON_CNT];
+       u32 clks_save[RK3368_CRU_CLKGATES_CON_CNT];
+       u32 i, ret;
+
+       for (i = 0; i < RK3368_CRU_CLKGATES_CON_CNT; i++) {
+               clks_save[i] = cru_readl(RK3368_CRU_CLKGATES_CON(i));
+               clks_ungating[i] = 0;
+       }
+
+       for (i = 0; i < RK3368_CRU_CLKGATES_CON_CNT; i++)
+               cru_writel(0xffff0000, RK3368_CRU_CLKGATES_CON(i));
+
+       ret = rk3368_pmu_set_power_domain(pd, on);
+
+       for (i = 0; i < RK3368_CRU_CLKGATES_CON_CNT; i++)
+               cru_writel(clks_save[i] | 0xffff0000,
+                          RK3368_CRU_CLKGATES_CON(i));
+
+       return ret;
+}
+
+static int __init rk3368_init_rockchip_pmu_ops(void)
+{
+       struct device_node *node, *gp, *cp;
+
+       node = of_find_compatible_node(NULL, NULL, "rockchip,rk3368-pmu");
+       if (!node) {
+               pr_err("%s: could not find pmu dt node\n", __func__);
+               return -ENODEV;
+       }
+
+       rk_pmu_base = of_iomap(node, 0);
+       if (!rk_pmu_base) {
+               pr_err("%s: could not map pmu registers\n", __func__);
+               return -ENXIO;
+       }
+
+       node = of_find_compatible_node(NULL, NULL, "rockchip,cpu_axi_bus");
+       if (!node)
+               return -ENODEV;
+
+#define MAP(name)                                                      \
+       do {                                                            \
+               cp = of_get_child_by_name(gp, #name);                   \
+               if (cp)                                                 \
+                       name##_qos_base = of_iomap(cp, 0);              \
+               if (!name##_qos_base)                                   \
+                       pr_err("%s: could not map qos %s register\n",   \
+                              __func__, #name);                        \
+       } while (0)
+
+       gp = of_get_child_by_name(node, "qos");
+       if (gp) {
+               MAP(peri);
+               MAP(iep);
+               MAP(isp_r0);
+               MAP(isp_r1);
+               MAP(isp_w0);
+               MAP(isp_w1);
+               MAP(vip);
+               MAP(vop);
+               MAP(rga_r);
+               MAP(rga_w);
+               MAP(hevc_r);
+               MAP(vpu_r);
+               MAP(vpu_w);
+               MAP(gpu);
+       }
+
+#undef MAP
+
+       rockchip_pmu_ops.set_power_domain = rk3368_sys_set_power_domain;
+       rockchip_pmu_ops.power_domain_is_on = rk3368_pmu_power_domain_is_on;
+
+       return 0;
+}
+
+arch_initcall(rk3368_init_rockchip_pmu_ops);
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
deleted file mode 100644 (file)
index 9c9e0e0..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-y  += clk.o
-obj-y  += clk-ops.o
-obj-y  += clk-pll.o
-obj-y  += clk-pd.o
-obj-y  += pd-rk3368.o
diff --git a/drivers/clk/rockchip/clk-ops.c b/drivers/clk/rockchip/clk-ops.c
deleted file mode 100644 (file)
index 948ffec..0000000
+++ /dev/null
@@ -1,921 +0,0 @@
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/io.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/clk-private.h>
-#include <linux/delay.h>
-#include <linux/rockchip/common.h>
-#include <linux/rockchip/cpu.h>
-
-#include "clk-ops.h"
-
-/* mux_ops */
-struct clk_ops_table rk_clk_mux_ops_table[] = {
-       {.index = CLKOPS_TABLE_END},
-};
-
-
-/* rate_ops */
-#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
-#define div_mask(d)    ((1 << ((d)->width)) - 1)
-
-static u32 clk_gcd(u32 numerator, u32 denominator)
-{
-       u32 a, b;
-
-       if (!numerator || !denominator)
-               return 0;
-       if (numerator > denominator) {
-               a = numerator;
-               b = denominator;
-       } else {
-               a = denominator;
-               b = numerator;
-       }
-       while (b != 0) {
-               int r = b;
-               b = a % b;
-               a = r;
-       }
-
-       return a;
-}
-
-static int clk_fracdiv_get_config(unsigned long rate_out, unsigned long rate,
-               u32 *numerator, u32 *denominator)
-{
-       u32 gcd_val;
-       gcd_val = clk_gcd(rate, rate_out);
-       clk_debug("%s: frac_get_seting rate=%lu, parent=%lu, gcd=%d\n",
-                       __func__, rate_out, rate, gcd_val);
-
-       if (!gcd_val) {
-               clk_err("gcd=0, frac div is not be supported\n");
-               return -EINVAL;
-       }
-
-       *numerator = rate_out / gcd_val;
-       *denominator = rate / gcd_val;
-
-       clk_debug("%s: frac_get_seting numerator=%d, denominator=%d, times=%d\n",
-                       __func__, *numerator, *denominator,
-                       *denominator / *numerator);
-
-       if (*numerator > 0xffff || *denominator > 0xffff ||
-                       (*denominator / (*numerator)) < 20) {
-               clk_err("can't get a available nume and deno\n");
-               return -EINVAL;
-       }
-
-       return 0;
-
-}
-
-static int clk_fracdiv_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       u32 numerator, denominator;
-       struct clk_divider *div = to_clk_divider(hw);
-
-
-       if(clk_fracdiv_get_config(rate, parent_rate,
-                               &numerator, &denominator) == 0) {
-               writel(numerator << 16 | denominator, div->reg);
-               clk_debug("%s set rate=%lu,is ok\n", hw->clk->name, rate);
-       } else {
-               clk_err("clk_frac_div name=%s can't get rate=%lu\n",
-                               hw->clk->name, rate);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static unsigned long clk_fracdiv_recalc(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       unsigned long rate;
-       u64 rate64;
-       struct clk_divider *div = to_clk_divider(hw);
-       u32 numerator, denominator, reg_val;
-
-       reg_val = readl(div->reg);
-       if (reg_val == 0)
-               return parent_rate;
-
-       numerator = reg_val >> 16;
-       denominator = reg_val & 0xFFFF;
-       rate64 = (u64)parent_rate * numerator;
-       do_div(rate64, denominator);
-       rate = rate64;
-       clk_debug("%s: %s new clock rate is %lu, prate %lu (frac %u/%u)\n",
-                       __func__, hw->clk->name, rate, parent_rate,
-                       numerator, denominator);
-       return rate;
-}
-
-static long clk_fracdiv_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       struct clk *clk = hw->clk;
-       struct clk *parent = clk->parent;
-       long rate_out;
-
-       //FIXME: now just simply return rate
-       /*
-        *frac_div request a big input rate, and its parent is always a div,
-        *so we set parent->parent->rate as best_parent_rate.
-        */
-       rate_out = rate;
-       *prate = parent->parent->rate;
-
-       return rate_out;
-}
-
-static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       return clk_divider_ops.recalc_rate(hw, parent_rate);
-}
-
-static long clk_divider_round_rate(struct clk_hw *hw,
-               unsigned long rate, unsigned long *prate)
-{
-       return clk_divider_ops.round_rate(hw, rate, prate);
-}
-
-static int clk_divider_set_rate(struct clk_hw *hw,
-               unsigned long rate, unsigned long parent_rate)
-{
-       return clk_divider_ops.set_rate(hw, rate, parent_rate);
-}
-
-static long clk_mux_with_div_determine_rate(struct clk_hw *div_hw, unsigned long rate,
-               unsigned long *best_parent_rate,
-               struct clk **best_parent_p)
-{
-       struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
-       int i, num_parents;
-       unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
-
-
-       parent = __clk_get_parent(clk);
-       if(!parent){
-               best = __clk_get_rate(clk);
-               goto out;
-       }
-
-       /* if NO_REPARENT flag set, pass through to current parent */
-       if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
-               best_prate = __clk_get_rate(parent);
-               best = clk_divider_ops.round_rate(div_hw, rate, &best_prate);
-               goto out;
-       }
-
-       /* find the parent that can provide the fastest rate <= rate */
-       num_parents = clk->num_parents;
-       for (i = 0; i < num_parents; i++) {
-               parent = clk_get_parent_by_index(clk, i);
-               if (!parent)
-                       continue;
-
-               parent_rate = __clk_get_rate(parent);
-               now = clk_divider_ops.round_rate(div_hw, rate, &parent_rate);
-
-               if (now <= rate && now > best) {
-                       best_parent = parent;
-                       best_prate = parent_rate;
-                       best = now;
-               }
-       }
-
-out:
-       if(best_prate)
-               *best_parent_rate = best_prate;
-
-       if (best_parent)
-               *best_parent_p = best_parent;
-
-       clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
-                       "\tbest_parent name = %s, best_prate = %lu\n",
-                       clk->name, rate, best,
-                       __clk_get_name(*best_parent_p), *best_parent_rate);
-
-       return best;
-}
-
-const struct clk_ops clkops_rate_auto_parent = {
-       .recalc_rate    = clk_divider_recalc_rate,
-       .round_rate     = clk_divider_round_rate,
-       .set_rate       = clk_divider_set_rate,
-       .determine_rate = clk_mux_with_div_determine_rate,
-};
-
-static long clk_div_round_rate_even(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       int i = 0;
-       struct clk_divider *divider =to_clk_divider(hw);
-       int max_div = 1 << divider->width;
-
-       for (i = 1; i <= max_div; i++) {
-               if (i > 1 && (i % 2 != 0))
-                       continue;
-               if (rate >= (*prate / i))
-                       return *prate / i;
-       }
-
-       return (*prate / max_div);
-}
-
-const struct clk_ops clkops_rate_evendiv = {
-       .recalc_rate    = clk_divider_recalc_rate,
-       .round_rate     = clk_div_round_rate_even,
-       .set_rate       = clk_divider_set_rate,
-};
-
-static long clk_mux_with_evendiv_determine_rate(struct clk_hw *div_hw, unsigned long rate,
-               unsigned long *best_parent_rate,
-               struct clk **best_parent_p)
-{
-       struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
-       int i, num_parents;
-       unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
-
-
-       parent = __clk_get_parent(clk);
-       if(!parent){
-               best = __clk_get_rate(clk);
-               goto out;
-       }
-
-       /* if NO_REPARENT flag set, pass through to current parent */
-       if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
-               best_prate = __clk_get_rate(parent);
-               best = clk_div_round_rate_even(div_hw, rate, &best_prate);
-               goto out;
-       }
-
-       /* find the parent that can provide the fastest rate <= rate */
-       num_parents = clk->num_parents;
-       for (i = 0; i < num_parents; i++) {
-               parent = clk_get_parent_by_index(clk, i);
-               if (!parent)
-                       continue;
-
-               parent_rate = __clk_get_rate(parent);
-               now = clk_div_round_rate_even(div_hw, rate, &parent_rate);
-
-               if (now <= rate && now > best) {
-                       best_parent = parent;
-                       best_prate = parent_rate;
-                       best = now;
-               }
-       }
-
-out:
-       if(best_prate)
-               *best_parent_rate = best_prate;
-
-       if (best_parent)
-               *best_parent_p = best_parent;
-
-       clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
-                       "\tbest_parent name = %s, best_prate = %lu\n",
-                       clk->name, rate, best,
-                       __clk_get_name(*best_parent_p), *best_parent_rate);
-
-       return best;
-}
-
-static long clk_mux_with_evendiv_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       return clk_div_round_rate_even(hw, rate, prate);
-}
-
-const struct clk_ops clkops_rate_mux_with_evendiv = {
-       .recalc_rate    = clk_divider_recalc_rate,
-       .set_rate       = clk_divider_set_rate,
-       .round_rate     = clk_mux_with_evendiv_round_rate,
-       .determine_rate = clk_mux_with_evendiv_determine_rate,
-};
-
-static int clk_i2s_fracdiv_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       u32 numerator, denominator;
-       struct clk_divider *div = to_clk_divider(hw);
-       int i = 10;
-
-
-       if(clk_fracdiv_get_config(rate, parent_rate,
-                               &numerator, &denominator) == 0) {
-               while (i--) {
-                       writel((numerator - 1) << 16 | denominator, div->reg);
-                       mdelay(1);
-                       writel(numerator << 16 | denominator, div->reg);
-                       mdelay(1);
-               }
-               clk_debug("%s set rate=%lu,is ok\n", hw->clk->name, rate);
-       } else {
-               clk_err("clk_frac_div name=%s can't get rate=%lu\n",
-                               hw->clk->name, rate);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-const struct clk_ops clkops_rate_frac = {
-       .recalc_rate    = clk_fracdiv_recalc,
-       .round_rate     = clk_fracdiv_round_rate,
-       .set_rate       = clk_fracdiv_set_rate,
-};
-
-const struct clk_ops clkops_rate_i2s_frac = {
-       .recalc_rate    = clk_fracdiv_recalc,
-       .round_rate     = clk_fracdiv_round_rate,
-       .set_rate       = clk_i2s_fracdiv_set_rate,
-};
-
-static unsigned long clk_core_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       /* As parent rate could be changed in clk_core.set_rate
-        * ops, the passing_in parent_rate may not be the newest
-        * and we should use the parent->rate instead. As a side
-        * effect, we should NOT directly set clk_core's parent
-        * (apll) rate, otherwise we will get a wrong recalc rate
-        * with clk_core_recalc_rate.
-        */
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       return clk_divider_recalc_rate(hw, __clk_get_rate(parent));
-}
-
-static long clk_core_determine_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *best_parent_rate,
-               struct clk **best_parent_p)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (IS_ERR_OR_NULL(parent)) {
-               clk_err("fail to get parent!\n");
-               return 0;
-       }
-
-       return clk_round_rate(parent, rate);
-}
-
-static long clk_core_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       return clk_core_determine_rate(hw, rate, prate, NULL);
-}
-
-static int clk_core_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-       struct clk *grand_p = __clk_get_parent(parent);
-       int ret;
-
-       if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
-               clk_err("fail to get parent or grand_parent!\n");
-               return -EINVAL;
-       }
-
-       ret = parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p));
-       parent->rate = parent->ops->recalc_rate(parent->hw,
-                       __clk_get_rate(grand_p));
-
-       return ret;
-}
-
-const struct clk_ops clkops_rate_core = {
-       .recalc_rate    = clk_core_recalc_rate,
-       .round_rate     = clk_core_round_rate,
-       .set_rate       = clk_core_set_rate,
-       .determine_rate = clk_core_determine_rate,
-};
-
-/* Clk_ops for the child clk of clk_core, for example core_periph in rk3188 */
-const struct clk_ops clkops_rate_core_peri = {
-       .recalc_rate    = clk_divider_recalc_rate,
-       .round_rate     = clk_divider_round_rate,
-       .set_rate       = NULL,
-};
-
-
-static unsigned long clk_ddr_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       /* Same as clk_core, we should NOT set clk_ddr's parent
-        * (dpll) rate directly as a side effect.
-        */
-       return clk_core_recalc_rate(hw, parent_rate);
-}
-
-static long clk_ddr_determine_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *best_parent_rate,
-               struct clk **best_parent_p)
-{
-       long best = 0;
-
-       if (!ddr_round_rate) {
-               /* Do nothing before ddr init */
-               best = rate;//__clk_get_rate(hw->clk);
-       } else {
-               /* Func provided by ddr driver */
-               best = ddr_round_rate(rate/MHZ) * MHZ;
-       }
-
-       clk_debug("%s: from %lu to %lu\n", __func__, rate, best);
-
-       return best;
-}
-
-static long clk_ddr_round_rate(struct clk_hw *hw, unsigned long rate,
-                unsigned long *prate)
-{
-       return clk_ddr_determine_rate(hw, rate, prate, NULL);
-}
-
-static int clk_ddr_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-       struct clk *grand_p = __clk_get_parent(parent);
-
-
-       /* Do nothing before ddr init */
-       if (!ddr_change_freq)
-               return 0;
-
-       if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
-               clk_err("fail to get parent or grand_parent!\n");
-               return -EINVAL;
-       }
-
-       clk_debug("%s: will set rate = %lu\n", __func__, rate);
-
-       /* Func provided by ddr driver */
-       ddr_change_freq(rate/MHZ);
-
-       parent->rate = parent->ops->recalc_rate(parent->hw,
-                       __clk_get_rate(grand_p));
-
-       return 0;
-}
-
-const struct clk_ops clkops_rate_ddr = {
-       .recalc_rate    = clk_ddr_recalc_rate,
-       .round_rate     = clk_ddr_round_rate,
-       .set_rate       = clk_ddr_set_rate,
-       .determine_rate = clk_ddr_determine_rate,
-};
-
-static unsigned long clk_ddr_div2_recalc_rate(struct clk_hw *hw,
-                                             unsigned long parent_rate)
-{
-       /* Same as clk_core, we should NOT set clk_ddr's parent
-        * (dpll) rate directly as a side effect.
-        */
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       return clk_divider_recalc_rate(hw, __clk_get_rate(parent))/2;
-}
-
-const struct clk_ops clkops_rate_ddr_div2 = {
-       .recalc_rate    = clk_ddr_div2_recalc_rate,
-       .round_rate     = clk_ddr_round_rate,
-       .set_rate       = clk_ddr_set_rate,
-       .determine_rate = clk_ddr_determine_rate,
-};
-
-static unsigned long clk_ddr_div4_recalc_rate(struct clk_hw *hw,
-                                             unsigned long parent_rate)
-{
-       /* Same as clk_core, we should NOT set clk_ddr's parent
-        * (dpll) rate directly as a side effect.
-        */
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       return clk_divider_recalc_rate(hw, __clk_get_rate(parent))/4;
-}
-
-const struct clk_ops clkops_rate_ddr_div4 = {
-       .recalc_rate    = clk_ddr_div4_recalc_rate,
-       .round_rate     = clk_ddr_round_rate,
-       .set_rate       = clk_ddr_set_rate,
-       .determine_rate = clk_ddr_determine_rate,
-};
-
-
-static unsigned long clk_3288_i2s_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       return parent_rate;
-}
-
-static long clk_3288_i2s_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       return rate;
-}
-
-static int clk_3288_i2s_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-       struct clk *grand_p = __clk_get_parent(parent);
-
-
-       if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
-               return 0;
-       }
-
-       if (parent->ops->set_rate) {
-               parent->ops->set_rate(parent->hw, rate/2, __clk_get_rate(grand_p));
-               parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p));
-       }
-
-       return 0;
-}
-
-const struct clk_ops clkops_rate_3288_i2s = {
-       .recalc_rate    = clk_3288_i2s_recalc_rate,
-       .round_rate     = clk_3288_i2s_round_rate,
-       .set_rate       = clk_3288_i2s_set_rate,
-};
-
-static bool usb480m_state = false;
-
-static long clk_3288_usb480m_determine_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *best_parent_rate,
-               struct clk **best_parent_p)
-{
-       if(rate == 0)
-               return 0;
-       else
-               return 480*MHZ;
-}
-
-static long clk_3288_usb480m_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       return clk_3288_usb480m_determine_rate(hw, rate, prate, NULL);
-}
-
-static int clk_3288_usb480m_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       if(rate == 0)
-               usb480m_state = false;
-       else
-               usb480m_state = true;
-
-       return 0;
-}
-
-static unsigned long clk_3288_usb480m_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       if(usb480m_state)
-               return 480*MHZ;
-       else
-               return 0;
-}
-
-const struct clk_ops clkops_rate_3288_usb480m = {
-       .determine_rate = clk_3288_usb480m_determine_rate,
-       .set_rate       = clk_3288_usb480m_set_rate,
-       .round_rate     = clk_3288_usb480m_round_rate,
-       .recalc_rate    = clk_3288_usb480m_recalc_rate,
-};
-
-#define RK3288_LIMIT_PLL_VIO0 (600*MHZ)
-
-static long clk_3288_dclk_lcdc0_determine_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *best_parent_rate,
-               struct clk **best_parent_p)
-{
-       struct clk *gpll = clk_get(NULL, "clk_gpll");
-       struct clk *cpll = clk_get(NULL, "clk_cpll");
-       unsigned long best, div, prate, gpll_rate;
-
-       gpll_rate = __clk_get_rate(gpll);
-
-       if ((rate <= (297*MHZ)) && (gpll_rate%rate == 0)) {
-               *best_parent_p = gpll;
-               best = rate;
-               *best_parent_rate = gpll_rate;
-       } else {
-               *best_parent_p = cpll;
-               div = RK3288_LIMIT_PLL_VIO0/rate;
-               prate = div * rate;
-               *best_parent_rate = clk_round_rate(cpll, prate);
-               best = (*best_parent_rate)/div; 
-       }
-
-       return best;
-}
-
-static long clk_3288_dclk_lcdc0_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       return clk_3288_dclk_lcdc0_determine_rate(hw, rate, prate, NULL);
-}
-
-static int clk_3288_dclk_lcdc0_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk* aclk_vio0 = clk_get(NULL, "aclk_vio0");
-       struct clk* hclk_vio = clk_get(NULL, "hclk_vio");
-       struct clk *aclk_vio1;
-       struct clk* parent;
-       struct clk *gpll = clk_get(NULL, "clk_gpll");
-       struct clk *cpll = clk_get(NULL, "clk_cpll");
-
-       clk_divider_ops.set_rate(hw, rate, parent_rate);
-
-       /* set aclk_vio */
-       if (parent_rate == __clk_get_rate(gpll)) {
-               parent = clk_get(NULL, "clk_gpll");
-               clk_set_parent(aclk_vio0, gpll);
-               clk_set_rate(aclk_vio0, 300*MHZ);
-       } else {
-               parent = clk_get(NULL, "clk_cpll");
-               clk_set_parent(aclk_vio0, cpll);
-               clk_set_rate(aclk_vio0, __clk_get_rate(cpll));
-       }
-       clk_set_rate(hclk_vio, 100*MHZ);
-
-       /* make aclk_isp and hclk_isp share a same pll in rk3288_eco */
-       if (rockchip_get_cpu_version() > 0) {
-               aclk_vio1 = clk_get(NULL, "aclk_vio1");
-               clk_set_parent(aclk_vio1, parent);
-               clk_set_rate(aclk_vio1, __clk_get_rate(parent));
-       }
-
-       return 0;
-}
-
-const struct clk_ops clkops_rate_3288_dclk_lcdc0 = {
-       .determine_rate = clk_3288_dclk_lcdc0_determine_rate,
-       .set_rate       = clk_3288_dclk_lcdc0_set_rate,
-       .round_rate     = clk_3288_dclk_lcdc0_round_rate,
-       .recalc_rate    = clk_divider_recalc_rate,
-};
-
-#define RK3288_LIMIT_PLL_VIO1 (350*MHZ)
-
-static long clk_3288_dclk_lcdc1_determine_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *best_parent_rate,
-               struct clk **best_parent_p)
-{
-       struct clk *gpll = clk_get(NULL, "clk_gpll");
-       struct clk *cpll = clk_get(NULL, "clk_cpll");
-       unsigned long best, div, prate, gpll_rate;
-
-       gpll_rate = __clk_get_rate(gpll);
-
-       if ((rate <= (297*MHZ)) && ((gpll_rate)%rate == 0)) {
-               *best_parent_p = gpll;
-               best = rate;
-               *best_parent_rate = gpll_rate;
-       } else {
-               *best_parent_p = cpll;
-               div = RK3288_LIMIT_PLL_VIO1/rate;
-               prate = div * rate;
-               *best_parent_rate = clk_round_rate(cpll, prate);
-               best = (*best_parent_rate)/div; 
-       }
-
-       return best;
-}
-
-static long clk_3288_dclk_lcdc1_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       return clk_3288_dclk_lcdc1_determine_rate(hw, rate, prate, NULL);
-}
-
-static int clk_3288_dclk_lcdc1_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk* aclk_vio1 = clk_get(NULL, "aclk_vio1");
-       struct clk* parent;
-       struct clk *gpll = clk_get(NULL, "clk_gpll");
-       struct clk *cpll = clk_get(NULL, "clk_cpll");
-
-       clk_divider_ops.set_rate(hw, rate, parent_rate);
-
-       /* set aclk_vio */
-       if (parent_rate == __clk_get_rate(gpll)) {
-               parent = clk_get(NULL, "clk_gpll");
-               clk_set_parent(aclk_vio1, gpll);
-               clk_set_rate(aclk_vio1, 300*MHZ);
-       } else {
-               parent = clk_get(NULL, "clk_cpll");
-               clk_set_parent(aclk_vio1, cpll);
-               clk_set_rate(aclk_vio1, __clk_get_rate(cpll));
-       }
-
-       if (rockchip_get_cpu_version() == 0) {
-               clk_set_parent(aclk_vio1, parent);
-               clk_set_rate(aclk_vio1, __clk_get_rate(parent));
-       }
-
-       return 0;
-}
-
-const struct clk_ops clkops_rate_3288_dclk_lcdc1 = {
-       .determine_rate = clk_3288_dclk_lcdc1_determine_rate,
-       .set_rate       = clk_3288_dclk_lcdc1_set_rate,
-       .round_rate     = clk_3288_dclk_lcdc1_round_rate,
-       .recalc_rate    = clk_divider_recalc_rate,
-};
-
-#define CONFIG_RK3368_MUX_NO_USE_NPLL
-
-static long clk_3368_mux_div_determine_rate(struct clk_hw *div_hw,
-                                           unsigned long rate,
-                                           unsigned long *best_parent_rate,
-                                           struct clk **best_parent_p)
-{
-       struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL;
-       int i, num_parents;
-       unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0;
-
-       parent = __clk_get_parent(clk);
-       if (!parent) {
-               best = __clk_get_rate(clk);
-               goto out;
-       }
-
-       /* if NO_REPARENT flag set, pass through to current parent */
-       if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
-               best_prate = __clk_get_rate(parent);
-               best = clk_divider_ops.round_rate(div_hw, rate, &best_prate);
-               goto out;
-       }
-
-       /* find the parent that can provide the fastest rate <= rate */
-       num_parents = clk->num_parents;
-       for (i = 0; i < num_parents; i++) {
-               parent = clk_get_parent_by_index(clk, i);
-               if (!parent)
-                       continue;
-
-#ifdef CONFIG_RK3368_MUX_NO_USE_NPLL
-               if (!strcmp(__clk_get_name(parent), "clk_npll"))
-                       continue;
-#endif
-               parent_rate = __clk_get_rate(parent);
-               now = clk_divider_ops.round_rate(div_hw, rate, &parent_rate);
-
-               if (now <= rate && now > best) {
-                       best_parent = parent;
-                       best_prate = parent_rate;
-                       best = now;
-               }
-       }
-
-out:
-       if (best_prate)
-               *best_parent_rate = best_prate;
-
-       if (best_parent)
-               *best_parent_p = best_parent;
-
-       clk_debug("clk name = %s, determine rate = %lu, best = %lu\n"
-                 "\tbest_parent name = %s, best_prate = %lu\n",
-                 clk->name, rate, best,
-                 __clk_get_name(*best_parent_p), *best_parent_rate);
-
-       return best;
-}
-
-const struct clk_ops clkops_rate_3368_auto_parent = {
-       .recalc_rate    = clk_divider_recalc_rate,
-       .round_rate     = clk_divider_round_rate,
-       .set_rate       = clk_divider_set_rate,
-       .determine_rate = clk_3368_mux_div_determine_rate,
-};
-
-#define RK3368_LIMIT_NPLL (1250*MHZ)
-
-static long clk_3368_dclk_lcdc_determine_rate(struct clk_hw *hw,
-                                             unsigned long rate,
-                                             unsigned long *best_parent_rate,
-                                             struct clk **best_parent_p)
-{
-       struct clk *npll = clk_get(NULL, "clk_npll");
-       unsigned long div, prate, best, *p_prate;
-       static unsigned long rk3368_pll_rates[] = {1188*MHZ, 0};
-
-       if (best_parent_p)
-               *best_parent_p = npll;
-
-       /* first get parent_rate from table */
-       p_prate = rk3368_pll_rates;
-
-       while (*p_prate) {
-               if (!(*p_prate % (rate*2)) || (*p_prate == rate)) {
-                       clk_debug("%s: get rate from table\n", __func__);
-                       *best_parent_rate = *p_prate;
-                       best = rate;
-                       return best;
-               }
-               p_prate++;
-       }
-
-       /* if not suitable parent_rate found in table, then auto calc rate */
-       div = RK3368_LIMIT_NPLL/rate;
-       /* div should be even */
-       if (div % 2)
-               div = div - 1;
-
-       prate = div * rate;
-       *best_parent_rate = clk_round_rate(npll, prate);
-       best = (*best_parent_rate)/div;
-
-       return best;
-}
-
-static long clk_3368_dclk_lcdc_round_rate(struct clk_hw *hw, unsigned long rate,
-                                         unsigned long *prate)
-{
-       return clk_3368_dclk_lcdc_determine_rate(hw, rate, prate, NULL);
-}
-
-const struct clk_ops clkops_rate_3368_dclk_lcdc = {
-       .determine_rate = clk_3368_dclk_lcdc_determine_rate,
-       .set_rate       = clk_divider_set_rate,
-       .round_rate     = clk_3368_dclk_lcdc_round_rate,
-       .recalc_rate    = clk_divider_recalc_rate,
-};
-
-static unsigned long clk_rk3368_ddr_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       if (!ddr_recalc_rate)
-               return (clk_core_recalc_rate(hw, parent_rate)/2);
-       else
-               return ddr_recalc_rate();
-}
-
-const struct clk_ops clkops_rate_rk3368_ddr = {
-       .recalc_rate    = clk_rk3368_ddr_recalc_rate,
-       .round_rate     = clk_ddr_round_rate,
-       .set_rate       = clk_ddr_set_rate,
-       .determine_rate = clk_ddr_determine_rate,
-};
-
-
-
-struct clk_ops_table rk_clkops_rate_table[] = {
-       {.index = CLKOPS_RATE_MUX_DIV,          .clk_ops = &clkops_rate_auto_parent},
-       {.index = CLKOPS_RATE_EVENDIV,          .clk_ops = &clkops_rate_evendiv},
-       {.index = CLKOPS_RATE_MUX_EVENDIV,      .clk_ops = &clkops_rate_mux_with_evendiv},
-       {.index = CLKOPS_RATE_I2S_FRAC,         .clk_ops = &clkops_rate_i2s_frac},
-       {.index = CLKOPS_RATE_FRAC,             .clk_ops = &clkops_rate_frac},
-       {.index = CLKOPS_RATE_CORE,             .clk_ops = &clkops_rate_core},
-       {.index = CLKOPS_RATE_CORE_CHILD,       .clk_ops = &clkops_rate_core_peri},
-       {.index = CLKOPS_RATE_DDR,              .clk_ops = &clkops_rate_ddr},
-       {.index = CLKOPS_RATE_RK3288_I2S,       .clk_ops = &clkops_rate_3288_i2s},
-       {.index = CLKOPS_RATE_RK3288_USB480M,   .clk_ops = &clkops_rate_3288_usb480m},
-       {.index = CLKOPS_RATE_RK3288_DCLK_LCDC0,.clk_ops = &clkops_rate_3288_dclk_lcdc0},
-       {.index = CLKOPS_RATE_RK3288_DCLK_LCDC1,.clk_ops = &clkops_rate_3288_dclk_lcdc1},
-       {.index = CLKOPS_RATE_DDR_DIV2,         .clk_ops = &clkops_rate_ddr_div2},
-       {.index = CLKOPS_RATE_DDR_DIV4,         .clk_ops = &clkops_rate_ddr_div4},
-       {.index = CLKOPS_RATE_RK3368_MUX_DIV_NPLL,   .clk_ops = &clkops_rate_3368_auto_parent},
-       {.index = CLKOPS_RATE_RK3368_DCLK_LCDC, .clk_ops = &clkops_rate_3368_dclk_lcdc},
-       {.index = CLKOPS_RATE_RK3368_DDR,   .clk_ops = &clkops_rate_rk3368_ddr},
-       {.index = CLKOPS_RATE_I2S,              .clk_ops = NULL},
-       {.index = CLKOPS_RATE_CIFOUT,           .clk_ops = NULL},
-       {.index = CLKOPS_RATE_UART,             .clk_ops = NULL},
-       {.index = CLKOPS_RATE_HSADC,            .clk_ops = NULL},
-       {.index = CLKOPS_RATE_MAC_REF,          .clk_ops = NULL},
-       {.index = CLKOPS_TABLE_END,             .clk_ops = NULL},
-};
-
-const struct clk_ops *rk_get_clkops(unsigned int idx)
-{
-       int i = 0;
-       unsigned int now_idx;
-
-       while(1){
-               now_idx = rk_clkops_rate_table[i].index;
-
-               if ((now_idx == idx) || (now_idx == CLKOPS_TABLE_END))
-                       return rk_clkops_rate_table[i].clk_ops;
-
-               i++;
-       }
-}
-EXPORT_SYMBOL_GPL(rk_get_clkops);
diff --git a/drivers/clk/rockchip/clk-ops.h b/drivers/clk/rockchip/clk-ops.h
deleted file mode 100644 (file)
index 7d43745..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __RK_CLK_OPS_H
-#define __RK_CLK_OPS_H
-
-#include <dt-bindings/clock/rockchip,rk3188.h>
-#include <linux/rockchip/iomap.h>
-#include <linux/rockchip/grf.h>
-
-#define MHZ                    (1000UL * 1000UL)
-#define KHZ                    (1000UL)
-
-struct clk_ops_table {
-       unsigned int            index;
-       const struct clk_ops    *clk_ops;
-};
-const struct clk_ops *rk_get_clkops(unsigned int idx);
-
-//#define RKCLK_DEBUG
-//#define RKCLK_TEST
-
-#if defined(RKCLK_DEBUG)
-#define clk_debug(fmt, args...) printk(KERN_INFO "rkclk: "fmt, ##args)
-#else
-#define clk_debug(fmt, args...) do {} while(0)
-#endif
-
-#define clk_err(fmt, args...) printk(KERN_ERR "rkclk: "fmt, ##args)
-
-u32 cru_readl(u32 offset);
-void cru_writel(u32 val, u32 offset);
-
-u32 grf_readl(u32 offset);
-
-#endif /* __RK_CLKOPS_H */
diff --git a/drivers/clk/rockchip/clk-pd.c b/drivers/clk/rockchip/clk-pd.c
deleted file mode 100644 (file)
index 4748cb3..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-#include <linux/slab.h>
-
-#include "clk-ops.h"
-#include "clk-pd.h"
-
-
-static LIST_HEAD(clk_pd_notifier_list);
-
-static int __clk_pd_notify(struct clk *clk, unsigned long msg)
-{
-       struct clk_pd_notifier *cn;
-       int ret = NOTIFY_DONE;
-
-       list_for_each_entry(cn, &clk_pd_notifier_list, node) {
-               if (cn->clk == clk) {
-                       ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
-                                       NULL);
-                       break;
-               }
-       }
-
-       return ret;
-}
-
-int rk_clk_pd_notifier_register(struct clk *clk, struct notifier_block *nb)
-{
-       struct clk_pd_notifier *cn;
-       int ret = -ENOMEM;
-
-       if (!clk || !nb)
-               return -EINVAL;
-
-       //clk_prepare_lock();
-
-       /* search the list of notifiers for this clk */
-       list_for_each_entry(cn, &clk_pd_notifier_list, node)
-               if (cn->clk == clk)
-                       break;
-
-       /* if clk wasn't in the notifier list, allocate new clk_notifier */
-       if (cn->clk != clk) {
-               cn = kzalloc(sizeof(struct clk_pd_notifier), GFP_KERNEL);
-               if (!cn)
-                       goto out;
-
-               cn->clk = clk;
-               srcu_init_notifier_head(&cn->notifier_head);
-
-               list_add(&cn->node, &clk_pd_notifier_list);
-       }
-
-       ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
-
-       //clk->notifier_count++;
-
-out:
-       //clk_prepare_unlock();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(rk_clk_pd_notifier_register);
-
-int rk_clk_pd_notifier_unregister(struct clk *clk, struct notifier_block *nb)
-{
-       struct clk_pd_notifier *cn = NULL;
-       int ret = -EINVAL;
-
-       if (!clk || !nb)
-               return -EINVAL;
-
-       //clk_prepare_lock();
-
-       list_for_each_entry(cn, &clk_pd_notifier_list, node)
-               if (cn->clk == clk)
-                       break;
-
-       if (cn->clk == clk) {
-               ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
-
-               //clk->notifier_count--;
-
-               /* XXX the notifier code should handle this better */
-               if (!cn->notifier_head.head) {
-                       srcu_cleanup_notifier_head(&cn->notifier_head);
-                       list_del(&cn->node);
-                       kfree(cn);
-               }
-
-       } else {
-               ret = -ENOENT;
-       }
-
-       //clk_prepare_unlock();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(rk_clk_pd_notifier_unregister);
-
-static int clk_pd_endisable(struct clk_hw *hw, bool enable)
-{
-       struct clk_pd *pd = to_clk_pd(hw);
-       unsigned long flags = 0;
-       int ret = 0;
-
-       if (pd->lock)
-               spin_lock_irqsave(pd->lock, flags);
-
-       ret = rockchip_pmu_ops.set_power_domain(pd->id, enable);
-
-       if (pd->lock)
-               spin_unlock_irqrestore(pd->lock, flags);
-
-       return ret;     
-}
-
-static int clk_pd_enable(struct clk_hw *hw)
-{
-       int ret = 0;
-
-       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_ENABLE);
-
-       ret = clk_pd_endisable(hw, true);
-
-       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_ENABLE);
-
-       return ret;
-}
-
-static void clk_pd_disable(struct clk_hw *hw)
-{
-       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_DISABLE);
-
-       clk_pd_endisable(hw, false);
-
-       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_DISABLE);
-}
-
-static int clk_pd_is_enabled(struct clk_hw *hw)
-{
-       struct clk_pd *pd = to_clk_pd(hw);
-
-       return rockchip_pmu_ops.power_domain_is_on(pd->id);
-}
-
-static int clk_pd_prepare(struct clk_hw *hw)
-{
-       __clk_pd_notify(hw->clk, RK_CLK_PD_PREPARE);
-
-       return 0;
-}
-
-static void clk_pd_unprepare(struct clk_hw *hw)
-{
-       __clk_pd_notify(hw->clk, RK_CLK_PD_UNPREPARE);
-}
-
-const struct clk_ops clk_pd_ops = {
-       .prepare = clk_pd_prepare,
-       .unprepare = clk_pd_unprepare,
-       .enable = clk_pd_enable,
-       .disable = clk_pd_disable,
-       .is_enabled = clk_pd_is_enabled,
-};
-
-static int clk_pd_virt_enable(struct clk_hw *hw)
-{
-       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_ENABLE);
-
-       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_ENABLE);
-
-       return 0;
-}
-
-static void clk_pd_virt_disable(struct clk_hw *hw)
-{
-       __clk_pd_notify(hw->clk, RK_CLK_PD_PRE_DISABLE);
-
-       __clk_pd_notify(hw->clk, RK_CLK_PD_POST_DISABLE);
-}
-
-const struct clk_ops clk_pd_virt_ops = {
-       .prepare = clk_pd_prepare,
-       .unprepare = clk_pd_unprepare,
-       .enable = clk_pd_virt_enable,
-       .disable = clk_pd_virt_disable,
-};
-
-
-struct clk *rk_clk_register_pd(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags, 
-               u32 pd_id, spinlock_t *lock)
-{
-       struct clk_pd *pd;
-       struct clk *clk;
-       struct clk_init_data init;
-
-
-       /* allocate the pd */
-       pd = kzalloc(sizeof(struct clk_pd), GFP_KERNEL);
-       if (!pd) {
-               clk_err("%s: could not allocate pd clk\n", __func__);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       init.name = name;
-       init.flags = flags | CLK_IS_BASIC;
-       init.parent_names = (parent_name ? &parent_name: NULL);
-       init.num_parents = (parent_name ? 1 : 0);
-
-       if(pd_id == CLK_PD_VIRT)
-               init.ops = &clk_pd_virt_ops;
-       else
-               init.ops = &clk_pd_ops;
-
-       /* struct clk_pd assignments */
-       pd->id= pd_id;
-       pd->lock = lock;
-       pd->hw.init = &init;
-
-       /* register the clock */
-       clk = clk_register(dev, &pd->hw);
-
-       if (IS_ERR(clk))
-               kfree(pd);
-
-       return clk;
-}
-
diff --git a/drivers/clk/rockchip/clk-pd.h b/drivers/clk/rockchip/clk-pd.h
deleted file mode 100644 (file)
index 9983bdd..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __RK_CLK_PD_H
-#define __RK_CLK_PD_H
-
-#include <linux/clk-provider.h>
-#include <linux/rockchip/pmu.h>
-
-
-
-#define to_clk_pd(_hw) container_of(_hw, struct clk_pd, hw)
-
-struct clk_pd {
-       struct clk_hw   hw;
-       u32             id;
-       spinlock_t      *lock;
-};
-
-struct clk *rk_clk_register_pd(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags, 
-               u32 pd_id, spinlock_t *lock);
-
-
-#define RK_CLK_PD_PRE_ENABLE                   BIT(0)
-#define RK_CLK_PD_POST_ENABLE                  BIT(1)
-#define RK_CLK_PD_PRE_DISABLE                  BIT(2)
-#define RK_CLK_PD_POST_DISABLE                 BIT(3)
-#define RK_CLK_PD_PREPARE                      BIT(4)
-#define RK_CLK_PD_UNPREPARE                    BIT(5)
-
-
-struct clk_pd_notifier {
-       struct clk                      *clk;
-       struct srcu_notifier_head       notifier_head;
-       struct list_head                node;
-};
-
-int rk_clk_pd_notifier_register(struct clk *clk, struct notifier_block *nb);
-
-int rk_clk_pd_notifier_unregister(struct clk *clk, struct notifier_block *nb);
-
-#endif /* __RK_CLK_PD_H */
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
deleted file mode 100644 (file)
index 5943ca1..0000000
+++ /dev/null
@@ -1,2581 +0,0 @@
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <linux/rockchip/cpu.h>
-
-#include "clk-ops.h"
-#include "clk-pll.h"
-
-
-static const struct pll_clk_set rk3188_pll_com_table[] = {
-       _RK3188_PLL_SET_CLKS(1250000,   12,     625,    1),
-       _RK3188_PLL_SET_CLKS(1200000,   1,      50,     1),
-       _RK3188_PLL_SET_CLKS(1188000,   2,      99,     1),
-       _RK3188_PLL_SET_CLKS(891000,    8,      594,    2),
-       _RK3188_PLL_SET_CLKS(768000,    1,      64,     2),
-       _RK3188_PLL_SET_CLKS(594000,    2,      198,    4),
-       _RK3188_PLL_SET_CLKS(500000,    3,      250,    4),
-       _RK3188_PLL_SET_CLKS(408000,    1,      68,     4),
-       _RK3188_PLL_SET_CLKS(396000,    1,      66,     4),
-       _RK3188_PLL_SET_CLKS(384000,    2,      128,    4),
-       _RK3188_PLL_SET_CLKS(360000,    1,      60,     4),
-       _RK3188_PLL_SET_CLKS(300000,    1,      50,     4),
-       _RK3188_PLL_SET_CLKS(297000,    2,      198,    8),
-       _RK3188_PLL_SET_CLKS(148500,    2,      99,     8),
-       _RK3188_PLL_SET_CLKS(0,         0,      0,      0),
-};
-
-static const struct pll_clk_set rk3188plus_pll_com_table[] = {
-       _RK3188PLUS_PLL_SET_CLKS(1250000,       12,     625,    1),
-       _RK3188PLUS_PLL_SET_CLKS(1200000,       1,      50,     1),
-       _RK3188PLUS_PLL_SET_CLKS(1188000,       2,      99,     1),
-       _RK3188PLUS_PLL_SET_CLKS(891000,        8,      594,    2),
-       _RK3188PLUS_PLL_SET_CLKS(768000,        1,      64,     2),
-       _RK3188PLUS_PLL_SET_CLKS(594000,        2,      198,    4),
-       _RK3188PLUS_PLL_SET_CLKS(576000,        1,      48,     2),
-       _RK3188PLUS_PLL_SET_CLKS(500000,        3,      250,    4),
-       _RK3188PLUS_PLL_SET_CLKS(408000,        1,      68,     4),
-       _RK3188PLUS_PLL_SET_CLKS(400000,        3,      200,    4),
-       _RK3188PLUS_PLL_SET_CLKS(396000,        1,      66,     4),
-       _RK3188PLUS_PLL_SET_CLKS(384000,        2,      128,    4),
-       _RK3188PLUS_PLL_SET_CLKS(360000,        1,      60,     4),
-       _RK3188PLUS_PLL_SET_CLKS(300000,        1,      50,     4),
-       _RK3188PLUS_PLL_SET_CLKS(297000,        2,      198,    8),
-       _RK3188PLUS_PLL_SET_CLKS(148500,        2,      99,     8),
-       _RK3188PLUS_PLL_SET_CLKS(0,             0,      0,      0),
-};
-
-static const struct apll_clk_set rk3188_apll_table[] = {
-       //            (_mhz,    nr,     nf,     no,     _periph_div,    _aclk_div)
-       _RK3188_APLL_SET_CLKS(2208,     1,      92,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2184,     1,      91,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2160,     1,      90,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2136,     1,      89,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2112,     1,      88,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2088,     1,      87,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2064,     1,      86,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2040,     1,      85,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(2016,     1,      84,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1992,     1,      83,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1968,     1,      82,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1944,     1,      81,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1920,     1,      80,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1896,     1,      79,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1872,     1,      78,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1848,     1,      77,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1824,     1,      76,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1800,     1,      75,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1776,     1,      74,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1752,     1,      73,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1728,     1,      72,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1704,     1,      71,     1,      8,      81),
-       _RK3188_APLL_SET_CLKS(1680,     1,      70,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1656,     1,      69,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1632,     1,      68,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1608,     1,      67,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1560,     1,      65,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1512,     1,      63,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1488,     1,      62,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1464,     1,      61,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1440,     1,      60,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1416,     1,      59,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1392,     1,      58,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1368,     1,      57,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1344,     1,      56,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1320,     1,      55,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1296,     1,      54,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1272,     1,      53,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1248,     1,      52,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1224,     1,      51,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1200,     1,      50,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1176,     1,      49,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1128,     1,      47,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1104,     1,      46,     1,      8,      41),
-       _RK3188_APLL_SET_CLKS(1008,     1,      84,     2,      8,      41),
-       _RK3188_APLL_SET_CLKS(912,      1,      76,     2,      8,      41),
-       _RK3188_APLL_SET_CLKS(888,      1,      74,     2,      8,      41),
-       _RK3188_APLL_SET_CLKS(816,      1,      68,     2,      8,      41),
-       _RK3188_APLL_SET_CLKS(792,      1,      66,     2,      8,      41),
-       _RK3188_APLL_SET_CLKS(696,      1,      58,     2,      8,      41),
-       _RK3188_APLL_SET_CLKS(600,      1,      50,     2,      4,      41),
-       _RK3188_APLL_SET_CLKS(552,      1,      92,     4,      4,      41),
-       _RK3188_APLL_SET_CLKS(504,      1,      84,     4,      4,      41),
-       _RK3188_APLL_SET_CLKS(408,      1,      68,     4,      4,      21),
-       _RK3188_APLL_SET_CLKS(312,      1,      52,     4,      2,      21),
-       _RK3188_APLL_SET_CLKS(252,      1,      84,     8,      2,      21),
-       _RK3188_APLL_SET_CLKS(216,      1,      72,     8,      2,      21),
-       _RK3188_APLL_SET_CLKS(126,      1,      84,     16,     2,      11),
-       _RK3188_APLL_SET_CLKS(48,       1,      32,     16,     2,      11),
-       _RK3188_APLL_SET_CLKS(0,        1,      32,     16,     2,      11),
-};
-
-static const struct apll_clk_set rk3288_apll_table[] = {
-       //                   (_mhz,     nr,     nf,     no,     l2ram,  m0,     mp,     atclk,  pclk_dbg)
-       _RK3288_APLL_SET_CLKS(2208,     1,      92,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2184,     1,      91,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2160,     1,      90,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2136,     1,      89,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2112,     1,      88,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2088,     1,      87,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2064,     1,      86,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2040,     1,      85,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(2016,     1,      84,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1992,     1,      83,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1968,     1,      82,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1944,     1,      81,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1920,     1,      80,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1896,     1,      79,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1872,     1,      78,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1848,     1,      77,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1824,     1,      76,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1800,     1,      75,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1776,     1,      74,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1752,     1,      73,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1728,     1,      72,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1704,     1,      71,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1680,     1,      70,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1656,     1,      69,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1632,     1,      68,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1608,     1,      67,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1560,     1,      65,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1512,     1,      63,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1488,     1,      62,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1464,     1,      61,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1440,     1,      60,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1416,     1,      59,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1392,     1,      58,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1368,     1,      57,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1344,     1,      56,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1320,     1,      55,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1296,     1,      54,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1272,     1,      53,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1248,     1,      52,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1224,     1,      51,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1200,     1,      50,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1176,     1,      49,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1128,     1,      47,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1104,     1,      46,     1,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(1008,     1,      84,     2,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(912,      1,      76,     2,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(888,      1,      74,     2,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(816,      1,      68,     2,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(792,      1,      66,     2,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(696,      1,      58,     2,      2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(672,  1,      56,   2,     2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(648,  1,      54,   2,     2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(624,  1,      52,   2,     2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(600,  1,      50,        2,      2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(576,  1,      48,   2,     2,      2,      4,      4,      4), 
-       _RK3288_APLL_SET_CLKS(552,      1,      92,     4,      2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(528,  1,      88,   4,     2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(504,      1,      84,     4,      2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(480,  1,      80,   4,     2,      2,      4,      4,      4),
-        _RK3288_APLL_SET_CLKS(456,  1,      76,   4,     2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(252,      1,      84,     8,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(216,      1,      72,     8,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(126,      2,      84,     8,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(48,       2,      32,     8,      2,      2,      4,      4,      4),
-       _RK3288_APLL_SET_CLKS(0,        1,      32,     16,     2,      2,      4,      4,      4),
-};
-
-static const struct apll_clk_set rk3036_apll_table[] = {
-       _RK3036_APLL_SET_CLKS(1608, 1, 67, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1584, 1, 66, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1560, 1, 65, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1536, 1, 64, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1512, 1, 63, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1488, 1, 62, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1464, 1, 61, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1440, 1, 60, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1416, 1, 59, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1392, 1, 58, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1368, 1, 57, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1344, 1, 56, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1320, 1, 55, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1296, 1, 54, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1272, 1, 53, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1248, 1, 52, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1200, 1, 50, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1104, 1, 46, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1100, 12, 550, 1, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1008, 1, 84, 2, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(1000, 6, 500, 2, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(984, 1, 82, 2, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(960, 1, 80, 2, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(936, 1, 78, 2, 1, 1, 0, 81),
-       _RK3036_APLL_SET_CLKS(912, 1, 76, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(900, 4, 300, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(888, 1, 74, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(864, 1, 72, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(840, 1, 70, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(816, 1, 68, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(800, 6, 400, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(700, 6, 350, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(696, 1, 58, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(600, 1, 75, 3, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(504, 1, 63, 3, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(500, 6, 250, 2, 1, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(408, 1, 68, 2, 2, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(312, 1, 52, 2, 2, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(216, 1, 72, 4, 2, 1, 0, 41),
-       _RK3036_APLL_SET_CLKS(96, 1, 64, 4, 4, 1, 0, 21),
-       _RK3036_APLL_SET_CLKS(0, 1, 0, 1, 1, 1, 0, 21),
-};
-
-static const struct pll_clk_set rk3036plus_pll_com_table[] = {
-       _RK3036_PLL_SET_CLKS(1188000, 2, 99, 1, 1, 1, 0),
-       _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
-       /*_RK3036_PLL_SET_CLKS(297000, 2, 99, 4, 1, 1, 0),*/
-};
-
-static const struct pll_clk_set rk312xplus_pll_com_table[] = {
-       /*_RK3036_PLL_SET_CLKS(1064000, 3, 133, 1, 1, 1, 0),*/
-       /*_RK3036_PLL_SET_CLKS(798000, 2, 133, 2, 1, 1, 0),*/
-       _RK3036_PLL_SET_CLKS(1000000, 3, 125, 1,  1, 1, 0),
-       _RK3036_PLL_SET_CLKS(594000, 2, 99, 2, 1, 1, 0),
-       _RK3036_PLL_SET_CLKS(500000, 3, 125, 2, 1, 1, 0),
-       _RK3036_PLL_SET_CLKS(400000, 3, 200, 2, 2, 1, 0),
-};
-
-static const struct apll_clk_set rk3368_apllb_table[] = {
-                       /*(_mhz,        nr,     nf,     no,     aclkm,  atclk,  pclk_dbg)*/
-       _RK3368_APLL_SET_CLKS(1608,     1,      67,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1560,     1,      65,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1512,     1,      63,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1488,     1,      62,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1464,     1,      61,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1440,     1,      60,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1416,     1,      59,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1392,     1,      58,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1368,     1,      57,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1344,     1,      56,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1320,     1,      55,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1296,     1,      54,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1272,     1,      53,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1248,     1,      52,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1224,     1,      51,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1200,     1,      50,     1,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(1176,     1,      49,     1,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(1128,     1,      47,     1,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(1104,     1,      46,     1,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(1008,     1,      84,     2,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(912,      1,      76,     2,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(888,      1,      74,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(816,      1,      68,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(792,      1,      66,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(696,      1,      58,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(672,      1,      56,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(648,      1,      54,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(624,      1,      52,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(600,      1,      50,     2,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(576,      1,      48,     2,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(552,      1,      92,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(528,      1,      88,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(504,      1,      84,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(480,      1,      80,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(456,      1,      76,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(252,      1,      84,     8,      2,      1,      1),
-       _RK3368_APLL_SET_CLKS(216,      1,      72,     8,      2,      1,      1),
-       _RK3368_APLL_SET_CLKS(126,      2,      84,     8,      2,      1,      1),
-       _RK3368_APLL_SET_CLKS(48,       2,      32,     8,      2,      1,      1),
-       _RK3368_APLL_SET_CLKS(0,        1,      32,     16,     2,      1,      1),
-};
-
-static const struct apll_clk_set rk3368_aplll_table[] = {
-                       /*(_mhz,        nr,     nf,     no,     aclkm,  atclk,  pclk_dbg)*/
-       _RK3368_APLL_SET_CLKS(1608,     1,      67,     1,      2,      7,      7),
-       _RK3368_APLL_SET_CLKS(1560,     1,      65,     1,      2,      7,      7),
-       _RK3368_APLL_SET_CLKS(1512,     1,      63,     1,      2,      7,      7),
-       _RK3368_APLL_SET_CLKS(1488,     1,      62,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1464,     1,      61,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1440,     1,      60,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1416,     1,      59,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1392,     1,      58,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1368,     1,      57,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1344,     1,      56,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1320,     1,      55,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1296,     1,      54,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1272,     1,      53,     1,      2,      6,      6),
-       _RK3368_APLL_SET_CLKS(1248,     1,      52,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1224,     1,      51,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1200,     1,      50,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1176,     1,      49,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1128,     1,      47,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1104,     1,      46,     1,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(1008,     1,      84,     2,      2,      5,      5),
-       _RK3368_APLL_SET_CLKS(912,      1,      76,     2,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(888,      1,      74,     2,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(816,      1,      68,     2,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(792,      1,      66,     2,      2,      4,      4),
-       _RK3368_APLL_SET_CLKS(696,      1,      58,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(672,      1,      56,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(648,      1,      54,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(624,      1,      52,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(600,      1,      50,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(576,      1,      48,     2,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(552,      1,      92,     4,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(528,      1,      88,     4,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(504,      1,      84,     4,      2,      3,      3),
-       _RK3368_APLL_SET_CLKS(480,      1,      80,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(456,      1,      76,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(408,      1,      68,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(312,      1,      52,     4,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(252,      1,      84,     8,      2,      2,      2),
-       _RK3368_APLL_SET_CLKS(216,      1,      72,     8,      2,      1,      1),
-       _RK3368_APLL_SET_CLKS(126,      2,      84,     8,      2,      1,      1),
-       _RK3368_APLL_SET_CLKS(48,       2,      32,     8,      2,      1,      1),
-       _RK3368_APLL_SET_CLKS(0,        1,      32,     16,     2,      1,      1),
-};
-
-static const struct pll_clk_set rk3368_pll_table_low_jitter[] = {
-       /*                             _khz, nr,  nf, no, nb */
-       _RK3188PLUS_PLL_SET_CLKS_NB(1188000,  1,  99,  2,  1),
-       _RK3188PLUS_PLL_SET_CLKS_NB(400000,  1,  100,  6,  1),
-       _RK3188PLUS_PLL_SET_CLKS(         0,  0,   0,  0),
-};
-
-static void pll_wait_lock(struct clk_hw *hw)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       int delay = 24000000;
-
-       while (delay > 0) {
-               if (grf_readl(pll->status_offset) & (1 << pll->status_shift))
-                       break;
-               delay--;
-       }
-
-       if (delay == 0) {
-               clk_err("pll %s: can't lock! status_shift=%u\n"
-                               "pll_con0=%08x\npll_con1=%08x\n"
-                               "pll_con2=%08x\npll_con3=%08x\n",
-                               __clk_get_name(hw->clk),
-                               pll->status_shift,
-                               cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                               cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                               cru_readl(pll->reg + RK3188_PLL_CON(2)),
-                               cru_readl(pll->reg + RK3188_PLL_CON(3)));
-
-               while(1);
-       }
-}
-
-static void rk3036_pll_wait_lock(struct clk_hw *hw)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       int delay = 24000000;
-
-
-       while (delay > 0) {
-               if (cru_readl(pll->status_offset) & (1 << pll->status_shift))
-                       break;
-               delay--;
-       }
-
-       if (delay == 0) {
-               clk_err("pll %s: can't lock! status_shift=%u\n"
-                               "pll_con0=%08x\npll_con1=%08x\n"
-                               "pll_con2=%08x\n",
-                               __clk_get_name(hw->clk),
-                               pll->status_shift,
-                               cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                               cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                               cru_readl(pll->reg + RK3188_PLL_CON(2)));
-               while (1);
-
-       }
-}
-
-
-/* get rate that is most close to target */
-static const struct apll_clk_set *apll_get_best_set(unsigned long rate,
-               const struct apll_clk_set *table)
-{
-       const struct apll_clk_set *ps, *pt;
-
-       ps = pt = table;
-       while (pt->rate) {
-               if (pt->rate == rate) {
-                       ps = pt;
-                       break;
-               }
-
-               if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
-                       ps = pt;
-               if (pt->rate < rate)
-                       break;
-               pt++;
-       }
-
-       return ps;
-}
-
-/* get rate that is most close to target */
-static const struct pll_clk_set *pll_com_get_best_set(unsigned long rate,
-               const struct pll_clk_set *table)
-{
-       const struct pll_clk_set *ps, *pt;
-
-       ps = pt = table;
-       while (pt->rate) {
-               if (pt->rate == rate) {
-                       ps = pt;
-                       break;
-               }
-
-               if ((pt->rate > rate || (rate - pt->rate < ps->rate - rate)))
-                       ps = pt;
-               if (pt->rate < rate)
-                       break;
-               pt++;
-       }
-
-       return ps;
-}
-
-/* CLK_PLL_3188 type ops */
-static unsigned long clk_pll_recalc_rate_3188(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       unsigned long rate;
-
-
-       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
-               u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
-               u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
-
-               u64 rate64 = (u64)parent_rate * RK3188_PLL_NF(pll_con1);
-
-               do_div(rate64, RK3188_PLL_NR(pll_con0));
-               do_div(rate64, RK3188_PLL_NO(pll_con0));
-
-               rate = rate64;
-       } else {
-               /*FIXME*/
-               rate = parent_rate;
-               clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
-       }
-
-       clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
-
-       return rate;
-}
-
-static long clk_pll_round_rate_3188(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate==__clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (pll_com_get_best_set(rate, rk3188_pll_com_table)->rate);
-}
-
-static int _pll_clk_set_rate_3188(struct pll_clk_set *clk_set,
-               struct clk_hw *hw)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       unsigned long flags = 0;
-
-
-       clk_debug("%s start!\n", __func__);
-
-       if(pll->lock)
-               spin_lock_irqsave(pll->lock, flags);
-
-       //enter slowmode
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
-       //pll power down
-       cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
-
-       udelay(1);
-
-       //pll no power down
-       cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
-
-       pll_wait_lock(hw);
-
-       //return from slow
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
-
-       if (pll->lock)
-               spin_unlock_irqrestore(pll->lock, flags);
-
-       clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
-                       __clk_get_name(hw->clk),
-                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                       cru_readl(pll->mode_offset));
-
-       clk_debug("%s end!\n", __func__);
-
-       return 0;
-}
-
-static int clk_pll_set_rate_3188(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188_pll_com_table);
-       int ret = 0;
-
-
-       if (rate == parent_rate) {
-               clk_debug("pll %s set rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-                               pll->mode_offset);
-               /* pll power down */
-               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
-               clk_debug("pll %s enter slow mode, set rate OK!\n",
-                               __clk_get_name(hw->clk));
-               return 0;
-       }
-
-       while(clk_set->rate) {
-               if (clk_set->rate == rate) {
-                       break;
-               }
-               clk_set++;
-       }
-
-       if (clk_set->rate == rate) {
-               ret = _pll_clk_set_rate_3188(clk_set, hw);
-               clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
-                               rate);
-       } else {
-               clk_err("pll %s is no corresponding rate=%lu\n",
-                               __clk_get_name(hw->clk), rate);
-               return -EINVAL;
-       }
-
-       return ret;
-}
-
-static const struct clk_ops clk_pll_ops_3188 = {
-       .recalc_rate = clk_pll_recalc_rate_3188,
-       .round_rate = clk_pll_round_rate_3188,
-       .set_rate = clk_pll_set_rate_3188,
-};
-
-
-/* CLK_PLL_3188_APLL type ops */
-static unsigned long clk_pll_recalc_rate_3188_apll(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       return clk_pll_recalc_rate_3188(hw, parent_rate);
-}
-
-static long clk_pll_round_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate==__clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (apll_get_best_set(rate, rk3188_apll_table)->rate);
-}
-
-/* 1: use, 0: no use */
-#define RK3188_USE_ARM_GPLL    1
-
-static int clk_pll_set_rate_3188_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       struct clk *clk = hw->clk;
-       struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
-       unsigned long arm_gpll_rate;
-       const struct apll_clk_set *ps;
-       u32 old_aclk_div = 0, new_aclk_div = 0;
-       u32 temp_div;
-       unsigned long flags;
-       int sel_gpll = 0;
-
-
-       if (rate == parent_rate) {
-               clk_debug("pll %s set rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-                               pll->mode_offset);
-               /* pll power down */
-               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
-               clk_debug("pll %s enter slow mode, set rate OK!\n",
-                               __clk_get_name(hw->clk));
-               return 0;
-       }
-
-
-#if !RK3188_USE_ARM_GPLL
-       goto CHANGE_APLL;
-#endif
-
-       /* prepare arm_gpll before reparent clk_core to it */
-       if (!arm_gpll) {
-               clk_err("clk arm_gpll is NULL!\n");
-               goto CHANGE_APLL;
-       }
-
-       /* In rk3188, arm_gpll and cpu_gpll share a same gate,
-        * and aclk_cpu selects cpu_gpll as parent, thus this
-        * gate must keep enabled.
-        */
-#if 0
-       if (clk_prepare(arm_gpll)) {
-               clk_err("fail to prepare arm_gpll path\n");
-               clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-
-       if (clk_enable(arm_gpll)) {
-               clk_err("fail to enable arm_gpll path\n");
-               clk_disable(arm_gpll);
-               clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-#endif
-
-       arm_gpll_rate = __clk_get_rate(arm_gpll);
-       temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
-       temp_div = (temp_div == 0) ? 1 : temp_div;
-       if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
-               clk_debug("temp_div %d > max_div %d\n", temp_div,
-                               RK3188_CORE_CLK_MAX_DIV);
-               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
-                               __clk_get_rate(clk), arm_gpll_rate);
-               //clk_disable(arm_gpll);
-               //clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-
-       local_irq_save(flags);
-
-       /* firstly set div, then select arm_gpll path */
-       cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
-                       RK3188_CRU_CLKSELS_CON(0));
-       cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
-                       RK3188_CRU_CLKSELS_CON(0));
-
-       sel_gpll = 1;
-       //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       clk_debug("temp select arm_gpll path, get rate %lu\n",
-                       arm_gpll_rate/temp_div);
-       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
-                       temp_div);
-
-CHANGE_APLL:
-       ps = apll_get_best_set(rate, rk3188_apll_table);
-       clk_debug("apll will set rate %lu\n", ps->rate);
-       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
-                       ps->pllcon0, ps->pllcon1, ps->pllcon2,
-                       ps->clksel0, ps->clksel1);
-
-       local_irq_save(flags);
-
-       /* If core src don't select gpll, apll need to enter slow mode
-        * before power down
-        */
-       //FIXME
-       //if (!sel_gpll)
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
-
-       /* PLL power down */
-       cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       dsb(sy);
-       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
-
-       udelay(1);
-
-       /* PLL power up and wait for locked */
-       cru_writel((0x1<<(16+1)), pll->reg + RK3188_PLL_CON(3));
-       pll_wait_lock(hw);
-
-       old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
-                       RK3188_CORE_ACLK_MSK);
-       new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
-
-       if (new_aclk_div >= old_aclk_div) {
-               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
-       }
-
-       /* PLL return from slow mode */
-       //FIXME
-       //if (!sel_gpll)
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
-
-       /* reparent to apll, and set div to 1 */
-       if (sel_gpll) {
-               cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
-                               RK3188_CRU_CLKSELS_CON(0));
-               cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
-                               RK3188_CRU_CLKSELS_CON(0));
-       }
-
-       if (old_aclk_div > new_aclk_div) {
-               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
-       }
-
-       //loops_per_jiffy = ps->lpj;
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       if (sel_gpll) {
-               sel_gpll = 0;
-               //clk_disable(arm_gpll);
-               //clk_unprepare(arm_gpll);
-       }
-
-       //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
-
-       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
-                       ps->rate,
-                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
-                       cru_readl(RK3188_CRU_CLKSELS_CON(0)),
-                       cru_readl(RK3188_CRU_CLKSELS_CON(1)));
-
-       return 0;
-}
-
-static const struct clk_ops clk_pll_ops_3188_apll = {
-       .recalc_rate = clk_pll_recalc_rate_3188_apll,
-       .round_rate = clk_pll_round_rate_3188_apll,
-       .set_rate = clk_pll_set_rate_3188_apll,
-};
-
-
-/* CLK_PLL_3188PLUS type ops */
-static unsigned long clk_pll_recalc_rate_3188plus(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       unsigned long rate;
-
-
-       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
-               u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
-               u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
-
-               u64 rate64 = (u64)parent_rate * RK3188PLUS_PLL_NF(pll_con1);
-
-               do_div(rate64, RK3188PLUS_PLL_NR(pll_con0));
-               do_div(rate64, RK3188PLUS_PLL_NO(pll_con0));
-
-               rate = rate64;
-       } else {
-               /*FIXME*/
-               rate = parent_rate;
-               clk_debug("pll %s is in slow mode\n", __clk_get_name(hw->clk));
-       }
-
-       clk_debug("pll %s recalc rate =%lu\n", __clk_get_name(hw->clk), rate);
-
-       return rate;
-}
-
-static long clk_pll_round_rate_3188plus(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate==__clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (pll_com_get_best_set(rate, rk3188plus_pll_com_table)->rate);
-}
-
-static int _pll_clk_set_rate_3188plus(struct pll_clk_set *clk_set,
-               struct clk_hw *hw)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       unsigned long flags = 0;
-
-
-       clk_debug("%s start!\n", __func__);
-
-       if(pll->lock)
-               spin_lock_irqsave(pll->lock, flags);
-
-       //enter slowmode
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
-
-       //enter rest
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
-
-       cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
-       cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
-
-       udelay(5);
-
-       //return from rest
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
-
-       //wating lock state
-       udelay(clk_set->rst_dly);
-
-       pll_wait_lock(hw);
-
-       //return from slow
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
-
-       if (pll->lock)
-               spin_unlock_irqrestore(pll->lock, flags);
-
-       clk_debug("pll %s dump reg: con0=0x%08x, con1=0x%08x, mode=0x%08x\n",
-                       __clk_get_name(hw->clk),
-                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                       cru_readl(pll->mode_offset));
-
-       clk_debug("%s end!\n", __func__);
-
-       return 0;
-}
-
-static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       //struct clk_pll *pll = to_clk_pll(hw);
-       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3188plus_pll_com_table);
-       int ret = 0;
-
-#if 0
-       if (rate == parent_rate) {
-               clk_debug("pll %s set rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-                               pll->mode_offset);
-               /* pll power down */
-               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
-               clk_debug("pll %s enter slow mode, set rate OK!\n",
-                               __clk_get_name(hw->clk));
-               return 0;
-       }
-#endif
-
-       while(clk_set->rate) {
-               if (clk_set->rate == rate) {
-                       break;
-               }
-               clk_set++;
-       }
-
-       if (cpu_is_rk3288() && ((rate == 297*MHZ) || (rate == 594*MHZ))) {
-               if((strncmp(__clk_get_name(hw->clk), "clk_gpll",
-                       strlen("clk_gpll")) == 0)) {
-
-                       printk("rk3288 set GPLL BW 20 for HDMI!\n");
-                       clk_set->pllcon2 = RK3188_PLL_CLK_BWADJ_SET(20);
-               }
-       }
-
-       if (clk_set->rate == rate) {
-               ret = _pll_clk_set_rate_3188plus(clk_set, hw);
-               clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
-                               rate);
-       } else {
-               clk_err("pll %s is no corresponding rate=%lu\n",
-                               __clk_get_name(hw->clk), rate);
-               return -EINVAL;
-       }
-
-       return ret;
-}
-
-static int clk_pll_is_enabled_3188plus(struct clk_hw *hw)
-{
-       unsigned long flags;
-       struct clk_pll *pll = to_clk_pll(hw);
-       int ret;
-
-       if(pll->lock)
-               spin_lock_irqsave(pll->lock, flags);
-
-       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift))
-               ret = 1;
-       else
-               ret = 0;
-
-       if (pll->lock)
-               spin_unlock_irqrestore(pll->lock, flags);
-
-       return ret;
-}
-
-static int clk_pll_enable_3188plus(struct clk_hw *hw)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       unsigned long flags;
-       unsigned long rst_dly;
-       u32 nr;
-
-       clk_debug("%s enter\n", __func__);
-
-       if (clk_pll_is_enabled_3188plus(hw)) {
-               clk_debug("pll has been enabled\n");
-               return 0;
-       }
-
-       if(pll->lock)
-               spin_lock_irqsave(pll->lock, flags);
-
-       //enter slowmode
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
-
-       //power up
-       cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(0), pll->reg + RK3188_PLL_CON(3));
-
-       //enter reset
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
-
-       //cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       //cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
-       //cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
-
-       udelay(5);
-
-       //return from reset
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
-
-       //wating lock state
-       nr = RK3188PLUS_PLL_NR(cru_readl(pll->reg + RK3188_PLL_CON(0)));
-       rst_dly = ((nr*500)/24+1);
-       udelay(rst_dly);
-
-       pll_wait_lock(hw);
-
-       //return from slow
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
-
-       if (pll->lock)
-               spin_unlock_irqrestore(pll->lock, flags);
-
-       clk_debug("pll %s dump reg:\n con0=0x%08x,\n con1=0x%08x,\n con2=0x%08x,\n"
-                       "con3=0x%08x,\n mode=0x%08x\n",
-                       __clk_get_name(hw->clk),
-                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
-                       cru_readl(pll->mode_offset));
-
-       return 0;
-}
-
-static void clk_pll_disable_3188plus(struct clk_hw *hw)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       unsigned long flags;
-
-       clk_debug("%s enter\n", __func__);
-
-       if(pll->lock)
-               spin_lock_irqsave(pll->lock, flags);
-
-       //enter slowmode
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
-
-       //power down
-       cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(1), pll->reg + RK3188_PLL_CON(3));
-
-       if (pll->lock)
-               spin_unlock_irqrestore(pll->lock, flags);
-}
-
-static const struct clk_ops clk_pll_ops_3188plus = {
-       .recalc_rate = clk_pll_recalc_rate_3188plus,
-       .round_rate = clk_pll_round_rate_3188plus,
-       .set_rate = clk_pll_set_rate_3188plus,
-       .enable = clk_pll_enable_3188plus,
-       .disable = clk_pll_disable_3188plus,
-       .is_enabled = clk_pll_is_enabled_3188plus,
-};
-
-/* CLK_PLL_3188PLUS_AUTO type ops */
-#define PLL_FREF_MIN (269*KHZ)
-#define PLL_FREF_MAX (2200*MHZ)
-
-#define PLL_FVCO_MIN (440*MHZ)
-#define PLL_FVCO_MAX (2200*MHZ)
-
-#define PLL_FOUT_MIN (27500*KHZ) 
-#define PLL_FOUT_MAX (2200*MHZ)
-
-#define PLL_NF_MAX (4096)
-#define PLL_NR_MAX (64)
-#define PLL_NO_MAX (16)
-
-static u32 clk_gcd(u32 numerator, u32 denominator)
-{
-       u32 a, b;
-
-       if (!numerator || !denominator)
-               return 0;
-       if (numerator > denominator) {
-               a = numerator;
-               b = denominator;
-       } else {
-               a = denominator;
-               b = numerator;
-       }
-       while (b != 0) {
-               int r = b;
-
-               b = a % b;
-               a = r;
-       }
-
-       return a;
-}
-
-static int pll_clk_get_best_set(unsigned long fin_hz, unsigned long fout_hz,
-                               u32 *best_nr, u32 *best_nf, u32 *best_no)
-{
-       u32 nr, nf, no, nonr;
-       u32 nr_out, nf_out, no_out;
-       u32 n;
-       u32 YFfenzi;
-       u32 YFfenmu;
-       u64 fref, fvco, fout;
-       u32 gcd_val = 0;
-
-       nr_out = PLL_NR_MAX + 1;
-       no_out = 0;
-
-       if (!fin_hz || !fout_hz || fout_hz == fin_hz)
-               return -EINVAL;
-       gcd_val = clk_gcd(fin_hz, fout_hz);
-
-       YFfenzi = fout_hz / gcd_val;
-       YFfenmu = fin_hz / gcd_val;
-
-       for (n = 1;; n++) {
-               nf = YFfenzi * n;
-               nonr = YFfenmu * n;
-               if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
-                       break;
-
-               for (no = 1; no <= PLL_NO_MAX; no++) {
-                       if (!(no == 1 || !(no % 2)))
-                               continue;
-
-                       if (nonr % no)
-                               continue;
-                       nr = nonr / no;
-
-                       if (nr > PLL_NR_MAX)
-                               continue;
-
-                       fref = fin_hz / nr;
-                       if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
-                               continue;
-
-                       fvco = fref * nf;
-                       if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
-                               continue;
-
-                       fout = fvco / no;
-                       if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
-                               continue;
-
-                       /* select the best from all available PLL settings */
-                       if ((no > no_out) || ((no == no_out) && (nr < nr_out))) {
-                               nr_out = nr;
-                               nf_out = nf;
-                               no_out = no;
-                       }
-               }
-       }
-
-       /* output the best PLL setting */
-       if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) {
-               if (best_nr && best_nf && best_no) {
-                       *best_nr = nr_out;
-                       *best_nf = nf_out;
-                       *best_no = no_out;
-               }
-               return 0;
-       } else {
-               return -EINVAL;
-       }
-}
-
-static unsigned long clk_pll_recalc_rate_3188plus_auto(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       return clk_pll_recalc_rate_3188plus(hw, parent_rate);
-}
-
-static long clk_pll_round_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       unsigned long best;
-
-       for(best=rate; best>0; best--){
-               if(!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
-                       return best;
-       }
-
-       return 0;
-}
-
-static int clk_pll_set_rate_3188plus_auto(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       unsigned long best;
-       u32 nr,nf,no;
-       struct pll_clk_set clk_set;
-       int ret;
-
-
-       best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
-
-       if(!best)
-               return -EINVAL;
-
-       pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
-
-       /* prepare clk_set */
-       clk_set.rate = best;
-       clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
-       clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
-       clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
-       clk_set.rst_dly = ((nr*500)/24+1);
-
-       ret = _pll_clk_set_rate_3188plus(&clk_set, hw);
-       clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk), best);
-
-       return ret;
-}
-
-
-static const struct clk_ops clk_pll_ops_3188plus_auto = {
-       .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
-       .round_rate = clk_pll_round_rate_3188plus_auto,
-       .set_rate = clk_pll_set_rate_3188plus_auto,
-       .enable = clk_pll_enable_3188plus,
-       .disable = clk_pll_disable_3188plus,
-       .is_enabled = clk_pll_is_enabled_3188plus,
-};
-
-static long clk_pll_round_rate_3368_low_jitter(struct clk_hw *hw,
-                                              unsigned long rate,
-                                              unsigned long *prate)
-{
-       unsigned long best;
-       struct pll_clk_set *p_clk_set;
-
-       p_clk_set = (struct pll_clk_set *)(rk3368_pll_table_low_jitter);
-
-       while (p_clk_set->rate) {
-               if (p_clk_set->rate == rate)
-                       break;
-               p_clk_set++;
-       }
-
-       if (p_clk_set->rate == rate) {
-               clk_debug("get rate from table\n");
-               return rate;
-       }
-
-       for (best = rate; best > 0; best--) {
-               if (!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
-                       return best;
-       }
-
-       clk_err("%s: can't round rate %lu\n", __func__, rate);
-       return 0;
-}
-
-
-static int clk_pll_set_rate_3368_low_jitter(struct clk_hw *hw,
-                                           unsigned long rate,
-                                           unsigned long parent_rate)
-{
-       unsigned long best;
-       u32 nr, nf, no;
-       struct pll_clk_set clk_set, *p_clk_set;
-       int ret;
-
-       p_clk_set = (struct pll_clk_set *)(rk3368_pll_table_low_jitter);
-
-       while (p_clk_set->rate) {
-               if (p_clk_set->rate == rate)
-                       break;
-               p_clk_set++;
-       }
-
-       if (p_clk_set->rate == rate) {
-               clk_debug("get rate from table\n");
-               goto set_rate;
-       }
-
-       best = clk_pll_round_rate_3188plus_auto(hw, rate, &parent_rate);
-
-       if (!best)
-               return -EINVAL;
-
-       pll_clk_get_best_set(parent_rate, best, &nr, &nf, &no);
-
-       /* prepare clk_set */
-       clk_set.rate = best;
-       clk_set.pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no);
-       clk_set.pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf);
-       clk_set.pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1);
-       clk_set.rst_dly = ((nr*500)/24+1);
-
-       p_clk_set = &clk_set;
-
-set_rate:
-       ret = _pll_clk_set_rate_3188plus(p_clk_set, hw);
-       clk_debug("pll %s set rate=%lu OK!\n", __clk_get_name(hw->clk),
-                 p_clk_set->rate);
-
-       return ret;
-}
-
-static const struct clk_ops clk_pll_ops_3368_low_jitter = {
-       .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
-       .round_rate = clk_pll_round_rate_3368_low_jitter,
-       .set_rate = clk_pll_set_rate_3368_low_jitter,
-       .enable = clk_pll_enable_3188plus,
-       .disable = clk_pll_disable_3188plus,
-       .is_enabled = clk_pll_is_enabled_3188plus,
-};
-
-/* CLK_PLL_3188PLUS_APLL type ops */
-static unsigned long clk_pll_recalc_rate_3188plus_apll(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       return clk_pll_recalc_rate_3188plus(hw, parent_rate);
-}
-
-static long clk_pll_round_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       return clk_pll_round_rate_3188_apll(hw, rate, prate);
-}
-
-/* 1: use, 0: no use */
-#define RK3188PLUS_USE_ARM_GPLL        1
-
-static int clk_pll_set_rate_3188plus_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       struct clk *clk = hw->clk;
-       struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
-       unsigned long arm_gpll_rate;
-       const struct apll_clk_set *ps;
-       u32 old_aclk_div = 0, new_aclk_div = 0;
-       u32 temp_div;
-       unsigned long flags;
-       int sel_gpll = 0;
-
-#if 0
-       if (rate == parent_rate) {
-               clk_debug("pll %s set rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-                               pll->mode_offset);
-               /* pll power down */
-               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
-               clk_debug("pll %s enter slow mode, set rate OK!\n",
-                               __clk_get_name(hw->clk));
-               return 0;
-       }
-#endif
-
-
-#if !RK3188PLUS_USE_ARM_GPLL
-       goto CHANGE_APLL;
-#endif
-
-       /* prepare arm_gpll before reparent clk_core to it */
-       if (!arm_gpll) {
-               clk_err("clk arm_gpll is NULL!\n");
-               goto CHANGE_APLL;
-       }
-
-       /* In rk3188plus, arm_gpll and cpu_gpll share a same gate,
-        * and aclk_cpu selects cpu_gpll as parent, thus this
-        * gate must keep enabled.
-        */
-#if 0
-       if (clk_prepare(arm_gpll)) {
-               clk_err("fail to prepare arm_gpll path\n");
-               clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-
-       if (clk_enable(arm_gpll)) {
-               clk_err("fail to enable arm_gpll path\n");
-               clk_disable(arm_gpll);
-               clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-#endif
-
-       arm_gpll_rate = __clk_get_rate(arm_gpll);
-       temp_div = DIV_ROUND_UP(arm_gpll_rate, __clk_get_rate(clk));
-       temp_div = (temp_div == 0) ? 1 : temp_div;
-       if (temp_div > RK3188_CORE_CLK_MAX_DIV) {
-               clk_debug("temp_div %d > max_div %d\n", temp_div,
-                               RK3188_CORE_CLK_MAX_DIV);
-               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
-                               __clk_get_rate(clk), arm_gpll_rate);
-               //clk_disable(arm_gpll);
-               //clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-
-       local_irq_save(flags);
-
-       /* firstly set div, then select arm_gpll path */
-       cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(temp_div),
-                       RK3188_CRU_CLKSELS_CON(0));
-       cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_GPLL,
-                       RK3188_CRU_CLKSELS_CON(0));
-
-       sel_gpll = 1;
-       //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       clk_debug("temp select arm_gpll path, get rate %lu\n",
-                       arm_gpll_rate/temp_div);
-       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
-                       temp_div);
-
-CHANGE_APLL:
-       ps = apll_get_best_set(rate, rk3188_apll_table);
-       clk_debug("apll will set rate %lu\n", ps->rate);
-       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
-                       ps->pllcon0, ps->pllcon1, ps->pllcon2,
-                       ps->clksel0, ps->clksel1);
-
-       local_irq_save(flags);
-
-       /* If core src don't select gpll, apll need to enter slow mode
-        * before reset
-        */
-       //FIXME
-       //if (!sel_gpll)
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
-
-       /* PLL enter rest */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
-
-       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
-       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
-
-       udelay(5);
-
-       /* return from rest */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
-
-       //wating lock state
-       udelay(ps->rst_dly);
-       pll_wait_lock(hw);
-
-       old_aclk_div = RK3188_GET_CORE_ACLK_VAL(cru_readl(RK3188_CRU_CLKSELS_CON(1)) &
-                       RK3188_CORE_ACLK_MSK);
-       new_aclk_div = RK3188_GET_CORE_ACLK_VAL(ps->clksel1 & RK3188_CORE_ACLK_MSK);
-
-       if (new_aclk_div >= old_aclk_div) {
-               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
-       }
-
-       /* PLL return from slow mode */
-       //FIXME
-       //if (!sel_gpll)
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
-
-       /* reparent to apll, and set div to 1 */
-       if (sel_gpll) {
-               cru_writel(RK3188_CORE_SEL_PLL_W_MSK|RK3188_CORE_SEL_APLL,
-                               RK3188_CRU_CLKSELS_CON(0));
-               cru_writel(RK3188_CORE_CLK_DIV_W_MSK|RK3188_CORE_CLK_DIV(1),
-                               RK3188_CRU_CLKSELS_CON(0));
-       }
-
-       if (old_aclk_div > new_aclk_div) {
-               cru_writel(ps->clksel0, RK3188_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3188_CRU_CLKSELS_CON(1));
-       }
-
-       //loops_per_jiffy = ps->lpj;
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       if (sel_gpll) {
-               sel_gpll = 0;
-               //clk_disable(arm_gpll);
-               //clk_unprepare(arm_gpll);
-       }
-
-       //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
-
-       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
-                       ps->rate,
-                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
-                       cru_readl(RK3188_CRU_CLKSELS_CON(0)),
-                       cru_readl(RK3188_CRU_CLKSELS_CON(1)));
-
-       return 0;
-}
-
-static const struct clk_ops clk_pll_ops_3188plus_apll = {
-       .recalc_rate = clk_pll_recalc_rate_3188plus_apll,
-       .round_rate = clk_pll_round_rate_3188plus_apll,
-       .set_rate = clk_pll_set_rate_3188plus_apll,
-};
-
-/* CLK_PLL_3288_APLL type ops */
-static unsigned long clk_pll_recalc_rate_3288_apll(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       return clk_pll_recalc_rate_3188plus(hw, parent_rate);
-}
-
-static long clk_pll_round_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate==__clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (apll_get_best_set(rate, rk3288_apll_table)->rate);
-}
-
-/* 1: use, 0: no use */
-#define RK3288_USE_ARM_GPLL    1
-
-static int clk_pll_set_rate_3288_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       struct clk *clk = hw->clk;
-       struct clk *arm_gpll = __clk_lookup("clk_arm_gpll");
-       unsigned long arm_gpll_rate, temp_rate, old_rate;
-       const struct apll_clk_set *ps;
-//     u32 old_aclk_div = 0, new_aclk_div = 0;
-       u32 temp_div;
-       unsigned long flags;
-       int sel_gpll = 0;
-
-
-#if 0
-       if (rate == parent_rate) {
-               clk_debug("pll %s set rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-                               pll->mode_offset);
-               /* pll power down */
-               cru_writel((0x1 << (16+1)) | (0x1<<1), pll->reg + RK3188_PLL_CON(3));
-               clk_debug("pll %s enter slow mode, set rate OK!\n",
-                               __clk_get_name(hw->clk));
-               return 0;
-       }
-#endif
-
-#if !RK3288_USE_ARM_GPLL
-       goto CHANGE_APLL;
-#endif
-
-       /* prepare arm_gpll before reparent clk_core to it */
-       if (!arm_gpll) {
-               clk_err("clk arm_gpll is NULL!\n");
-               goto CHANGE_APLL;
-       }
-
-       arm_gpll_rate = __clk_get_rate(arm_gpll);
-       old_rate = __clk_get_rate(clk);
-
-       temp_rate = (old_rate > rate) ? old_rate : rate;
-       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
-
-       if (temp_div > RK3288_CORE_CLK_MAX_DIV) {
-               clk_debug("temp_div %d > max_div %d\n", temp_div,
-                               RK3288_CORE_CLK_MAX_DIV);
-               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
-                               __clk_get_rate(clk), arm_gpll_rate);
-               goto CHANGE_APLL;
-       }
-
-#if 0
-       if (clk_prepare(arm_gpll)) {
-               clk_err("fail to prepare arm_gpll path\n");
-               clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-
-       if (clk_enable(arm_gpll)) {
-               clk_err("fail to enable arm_gpll path\n");
-               clk_disable(arm_gpll);
-               clk_unprepare(arm_gpll);
-               goto CHANGE_APLL;
-       }
-#endif
-
-       local_irq_save(flags);
-
-       /* select gpll */
-       if (temp_div == 1) {
-               /* when old_rate/2 < (old_rate-arm_gpll_rate),
-                  we can set div to make rate change more gently */
-               if (old_rate > (2*arm_gpll_rate)) {
-                       cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
-                               RK3288_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
-               } else {
-                       cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
-                               RK3288_CRU_CLKSELS_CON(0));
-               }
-       } else {
-               cru_writel(RK3288_CORE_CLK_DIV(temp_div), RK3288_CRU_CLKSELS_CON(0));
-               cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_GPLL,
-                               RK3288_CRU_CLKSELS_CON(0));
-       }
-
-       sel_gpll = 1;
-       //loops_per_jiffy = CLK_LOOPS_RECALC(arm_gpll_rate) / temp_div;
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       clk_debug("temp select arm_gpll path, get rate %lu\n",
-                       arm_gpll_rate/temp_div);
-       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
-                       temp_div);
-
-CHANGE_APLL:
-       ps = apll_get_best_set(rate, rk3288_apll_table);
-       clk_debug("apll will set rate %lu\n", ps->rate);
-       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
-                       ps->pllcon0, ps->pllcon1, ps->pllcon2,
-                       ps->clksel0, ps->clksel1);
-
-       local_irq_save(flags);
-
-       /* If core src don't select gpll, apll need to enter slow mode
-        * before reset
-        */
-       //FIXME
-       //if (!sel_gpll)
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
-
-       /* PLL enter rest */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
-
-       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
-       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
-
-       udelay(5);
-
-       /* return from rest */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
-
-       //wating lock state
-       udelay(ps->rst_dly);
-       pll_wait_lock(hw);
-
-       if (rate >= __clk_get_rate(hw->clk)) {
-               cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
-       }
-
-       /* PLL return from slow mode */
-       //FIXME
-       //if (!sel_gpll)
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
-
-       /* reparent to apll, and set div to 1 */
-       if (sel_gpll) {
-               if (temp_div == 1) {
-                       /* when rate/2 < (rate-arm_gpll_rate),
-                          we can set div to make rate change more gently */
-                       if (rate > (2*arm_gpll_rate)) {
-                               cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
-                               udelay(10);
-                               cru_writel(RK3288_CORE_CLK_DIV(3), RK3288_CRU_CLKSELS_CON(0));
-                               udelay(10);
-                               cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
-                                       RK3288_CRU_CLKSELS_CON(0));
-                               udelay(10);
-                               cru_writel(RK3288_CORE_CLK_DIV(2), RK3288_CRU_CLKSELS_CON(0));
-                               udelay(10);
-                               cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
-                       } else {
-                               cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
-                                               RK3288_CRU_CLKSELS_CON(0));
-                       }
-               } else {
-                       cru_writel(RK3288_CORE_SEL_PLL_W_MSK|RK3288_CORE_SEL_APLL,
-                               RK3288_CRU_CLKSELS_CON(0));
-                       cru_writel(RK3288_CORE_CLK_DIV(1), RK3288_CRU_CLKSELS_CON(0));
-               }
-       }
-
-       if (rate < __clk_get_rate(hw->clk)) {
-               cru_writel(ps->clksel0, RK3288_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3288_CRU_CLKSELS_CON(37));
-       }
-
-       //loops_per_jiffy = ps->lpj;
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       if (sel_gpll) {
-               sel_gpll = 0;
-               //clk_disable(arm_gpll);
-               //clk_unprepare(arm_gpll);
-       }
-
-       //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
-
-       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
-                       ps->rate,
-                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
-                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
-                       cru_readl(RK3288_CRU_CLKSELS_CON(0)),
-                       cru_readl(RK3288_CRU_CLKSELS_CON(1)));
-
-       return 0;
-}
-
-
-static const struct clk_ops clk_pll_ops_3288_apll = {
-       .recalc_rate = clk_pll_recalc_rate_3288_apll,
-       .round_rate = clk_pll_round_rate_3288_apll,
-       .set_rate = clk_pll_set_rate_3288_apll,
-};
-
-/* CLK_PLL_3036_APLL type ops */
-#define FRAC_MODE      0
-static unsigned long rk3036_pll_clk_recalc(struct clk_hw *hw,
-unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       unsigned long rate;
-       unsigned int dsmp = 0;
-       u64 rate64 = 0, frac_rate64 = 0;
-
-       dsmp = RK3036_PLL_GET_DSMPD(cru_readl(pll->reg + RK3188_PLL_CON(1)));
-
-       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) {
-               u32 pll_con0 = cru_readl(pll->reg + RK3188_PLL_CON(0));
-               u32 pll_con1 = cru_readl(pll->reg + RK3188_PLL_CON(1));
-               u32 pll_con2 = cru_readl(pll->reg + RK3188_PLL_CON(2));
-               /*integer mode*/
-               rate64 = (u64)parent_rate * RK3036_PLL_GET_FBDIV(pll_con0);
-               do_div(rate64, RK3036_PLL_GET_REFDIV(pll_con1));
-
-               if (FRAC_MODE == dsmp) {
-                       /*fractional mode*/
-                       frac_rate64 = (u64)parent_rate
-                       * RK3036_PLL_GET_FRAC(pll_con2);
-                       do_div(frac_rate64, RK3036_PLL_GET_REFDIV(pll_con1));
-                       rate64 += frac_rate64 >> 24;
-                       clk_debug("%s frac_rate=%llu(%08x/2^24) by pass mode\n",
-                                       __func__, frac_rate64 >> 24,
-                                       RK3036_PLL_GET_FRAC(pll_con2));
-               }
-               do_div(rate64, RK3036_PLL_GET_POSTDIV1(pll_con0));
-               do_div(rate64, RK3036_PLL_GET_POSTDIV2(pll_con1));
-
-               rate = rate64;
-               } else {
-               rate = parent_rate;
-               clk_debug("pll_clk_recalc rate=%lu by pass mode\n", rate);
-       }
-       return rate;
-}
-
-static unsigned long clk_pll_recalc_rate_3036_apll(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       return rk3036_pll_clk_recalc(hw, parent_rate);
-}
-
-static long clk_pll_round_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate == __clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (apll_get_best_set(rate, rk3036_apll_table)->rate);
-}
-
-static  int rk3036_pll_clk_set_rate(struct pll_clk_set *clk_set,
-       struct clk_hw *hw)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-
-       /*enter slowmode*/
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-       pll->mode_offset);
-
-       cru_writel(clk_set->pllcon0,  pll->reg + RK3188_PLL_CON(0));
-       cru_writel(clk_set->pllcon1,  pll->reg + RK3188_PLL_CON(1));
-       cru_writel(clk_set->pllcon2,  pll->reg + RK3188_PLL_CON(2));
-
-       clk_debug("pllcon0%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
-       clk_debug("pllcon1%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
-       clk_debug("pllcon2%08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
-       /*wating lock state*/
-       udelay(clk_set->rst_dly);
-       rk3036_pll_wait_lock(hw);
-
-       /*return form slow*/
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
-       pll->mode_offset);
-
-       return 0;
-}
-
-#define MIN_FOUTVCO_FREQ       (400 * 1000 * 1000)
-#define MAX_FOUTVCO_FREQ       (1600 * 1000 * 1000)
-static int rk3036_pll_clk_set_postdiv(unsigned long fout_hz,
-u32 *postdiv1, u32 *postdiv2, u32 *foutvco)
-{
-       if (fout_hz < MIN_FOUTVCO_FREQ) {
-               for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++)
-                       for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) {
-                               if (fout_hz * (*postdiv1) * (*postdiv2)
-                                       >= MIN_FOUTVCO_FREQ && fout_hz
-                                       * (*postdiv1) * (*postdiv2)
-                                       <= MAX_FOUTVCO_FREQ) {
-                                       *foutvco = fout_hz * (*postdiv1)
-                                               * (*postdiv2);
-                                       return 0;
-                               }
-                       }
-               clk_debug("CANNOT FINE postdiv1/2 to make fout in range from 400M to 1600M, fout = %lu\n",
-                               fout_hz);
-       } else {
-               *postdiv1 = 1;
-               *postdiv2 = 1;
-       }
-       return 0;
-}
-
-static int rk3036_pll_clk_get_set(unsigned long fin_hz, unsigned long fout_hz,
-               u32 *refdiv, u32 *fbdiv, u32 *postdiv1,
-               u32 *postdiv2, u32 *frac)
-{
-       /* FIXME set postdiv1/2 always 1*/
-       u32 gcd, foutvco = fout_hz;
-       u64 fin_64, frac_64;
-       u32 f_frac;
-
-       if (!fin_hz || !fout_hz || fout_hz == fin_hz)
-               return -1;
-
-       rk3036_pll_clk_set_postdiv(fout_hz, postdiv1, postdiv2, &foutvco);
-       if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
-               fin_hz /= MHZ;
-               foutvco /= MHZ;
-               gcd = clk_gcd(fin_hz, foutvco);
-               *refdiv = fin_hz / gcd;
-               *fbdiv = foutvco / gcd;
-
-               *frac = 0;
-
-               clk_debug("fin=%lu,fout=%lu,gcd=%u,refdiv=%u,fbdiv=%u,postdiv1=%u,postdiv2=%u,frac=%u\n",
-                       fin_hz, fout_hz, gcd, *refdiv, *fbdiv, *postdiv1, *postdiv2, *frac);
-       } else {
-               clk_debug("******frac div running, fin_hz=%lu, fout_hz=%lu,fin_INT_mhz=%lu, fout_INT_mhz=%lu\n",
-                       fin_hz, fout_hz, fin_hz / MHZ * MHZ, fout_hz / MHZ * MHZ);
-               clk_debug("******frac get postdiv1=%u, postdiv2=%u,foutvco=%u\n",
-                       *postdiv1, *postdiv2, foutvco);
-               gcd = clk_gcd(fin_hz / MHZ, foutvco / MHZ);
-               *refdiv = fin_hz / MHZ / gcd;
-               *fbdiv = foutvco / MHZ / gcd;
-               clk_debug("******frac get refdiv=%u, fbdiv=%u\n", *refdiv, *fbdiv);
-
-               *frac = 0;
-
-               f_frac = (foutvco % MHZ);
-               fin_64 = fin_hz;
-               do_div(fin_64, (u64)*refdiv);
-               frac_64 = (u64)f_frac << 24;
-               do_div(frac_64, fin_64);
-               *frac = (u32) frac_64;
-               clk_debug("frac=%x\n", *frac);
-       }
-       return 0;
-}
-static int rk3036_pll_set_con(struct clk_hw *hw, u32 refdiv, u32 fbdiv, u32 postdiv1, u32 postdiv2, u32 frac)
-{
-       struct pll_clk_set temp_clk_set;
-       temp_clk_set.pllcon0 = RK3036_PLL_SET_FBDIV(fbdiv) | RK3036_PLL_SET_POSTDIV1(postdiv1);
-       temp_clk_set.pllcon1 = RK3036_PLL_SET_REFDIV(refdiv) | RK3036_PLL_SET_POSTDIV2(postdiv2);
-       if (frac != 0)
-               temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(0);
-       else
-               temp_clk_set.pllcon1 |= RK3036_PLL_SET_DSMPD(1);
-
-       temp_clk_set.pllcon2 = RK3036_PLL_SET_FRAC(frac);
-       temp_clk_set.rst_dly = 0;
-       clk_debug("setting....\n");
-       return rk3036_pll_clk_set_rate(&temp_clk_set, hw);
-}
-
-static int clk_pll_set_rate_3036_apll(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       struct apll_clk_set *ps = (struct apll_clk_set *)(rk3036_apll_table);
-       struct clk *arm_gpll = __clk_lookup("clk_gpll");
-       struct clk *clk = hw->clk;
-       unsigned long flags, arm_gpll_rate, old_rate, temp_rate;
-       u32 temp_div;
-
-       while (ps->rate) {
-               if (ps->rate == rate) {
-                       break;
-               }
-               ps++;
-       }
-
-       if (ps->rate != rate) {
-               clk_err("%s: unsupport arm rate %lu\n", __func__, rate);
-               return 0;
-       }
-
-       if (!arm_gpll) {
-               clk_err("clk arm_gpll is NULL!\n");
-               return 0;
-       }
-
-       old_rate = __clk_get_rate(clk);
-       arm_gpll_rate = __clk_get_rate(arm_gpll);
-       if (soc_is_rk3128() || soc_is_rk3126())
-               arm_gpll_rate /= 2;
-
-       temp_rate = (old_rate > rate) ? old_rate : rate;
-       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
-
-       local_irq_save(flags);
-
-       if (rate >= old_rate) {
-               cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
-       }
-
-       /* set div first, then select gpll */
-       if (temp_div > 1)
-               cru_writel(RK3036_CLK_CORE_DIV(temp_div), RK3036_CRU_CLKSELS_CON(0));
-       cru_writel(RK3036_CORE_SEL_PLL(1), RK3036_CRU_CLKSELS_CON(0));
-
-       clk_debug("temp select arm_gpll path, get rate %lu\n",
-                 arm_gpll_rate/temp_div);
-       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
-                 temp_div);
-
-       /**************enter slow mode 24M***********/
-       /*cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);*/
-       loops_per_jiffy = LPJ_24M;
-
-       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
-       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
-
-       clk_debug("pllcon0 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(0)));
-       clk_debug("pllcon1 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(1)));
-       clk_debug("pllcon2 %08x\n", cru_readl(pll->reg + RK3188_PLL_CON(2)));
-       clk_debug("clksel0 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(0)));
-       clk_debug("clksel1 %08x\n", cru_readl(RK3036_CRU_CLKSELS_CON(1)));
-
-       /*wating lock state*/
-       udelay(ps->rst_dly);
-       rk3036_pll_wait_lock(hw);
-
-       /************select apll******************/
-       cru_writel(RK3036_CORE_SEL_PLL(0), RK3036_CRU_CLKSELS_CON(0));
-       /**************return slow mode***********/
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
-
-       cru_writel(RK3036_CLK_CORE_DIV(1), RK3036_CRU_CLKSELS_CON(0));
-
-       if (rate < old_rate) {
-               cru_writel(ps->clksel0, RK3036_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3036_CRU_CLKSELS_CON(1));
-       }
-
-       loops_per_jiffy = ps->lpj;
-       local_irq_restore(flags);
-
-       return 0;       
-}
-static const struct clk_ops clk_pll_ops_3036_apll = {
-       .recalc_rate = clk_pll_recalc_rate_3036_apll,
-       .round_rate = clk_pll_round_rate_3036_apll,
-       .set_rate = clk_pll_set_rate_3036_apll,
-};
-
-
-/* CLK_PLL_3036_plus_autotype ops */
-
-static long clk_pll_round_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate == __clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                               __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (pll_com_get_best_set(rate, rk3036plus_pll_com_table)->rate);
-}
-
-static int clk_pll_set_rate_3036plus_auto(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk3036plus_pll_com_table);
-
-       clk_debug("******%s\n", __func__);
-       while (clk_set->rate) {
-               clk_debug("******%s clk_set->rate=%lu\n", __func__, clk_set->rate);
-               if (clk_set->rate == rate) {
-                       break;
-               }
-               clk_set++;
-       }
-       if (clk_set->rate == rate) {
-               rk3036_pll_clk_set_rate(clk_set, hw);
-       } else {
-               clk_debug("gpll is no corresponding rate=%lu\n", rate);
-               return -1;
-       }
-       clk_debug("******%s end\n", __func__);
-
-       return 0;       
-}
-
-static const struct clk_ops clk_pll_ops_3036plus_auto = {
-       .recalc_rate = clk_pll_recalc_rate_3036_apll,
-       .round_rate = clk_pll_round_rate_3036plus_auto,
-       .set_rate = clk_pll_set_rate_3036plus_auto,
-};
-
-static long clk_cpll_round_rate_312xplus(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate)
-{
-       unsigned long best;
-
-       for (best = rate; best > 0; best--) {
-               if (!pll_clk_get_best_set(*prate, best, NULL, NULL, NULL))
-                       return best;
-       }
-
-       return 0;
-}
-
-static int clk_cpll_set_rate_312xplus(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct pll_clk_set *clk_set = (struct pll_clk_set *)(rk312xplus_pll_com_table);
-       u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
-
-       while (clk_set->rate) {
-               if (clk_set->rate == rate) {
-                       break;
-               }
-               clk_set++;
-       }
-
-       if (clk_set->rate == rate) {
-               clk_debug("cpll get a rate %ld\n", rate);
-               rk3036_pll_clk_set_rate(clk_set, hw);
-
-       } else {
-               clk_debug("cpll get auto calc a rate\n");
-               if (rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac) != 0) {
-                       pr_err("cpll auto set rate error\n");
-                       return -ENOENT;
-               }
-               clk_debug("%s get rate=%lu, refdiv=%u, fbdiv=%u, postdiv1=%u, postdiv2=%u",
-                               __func__, rate, refdiv, fbdiv, postdiv1, postdiv2);
-               rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac);
-
-       }
-
-       clk_debug("setting OK\n");
-       return 0;
-}
-
-static const struct clk_ops clk_pll_ops_312xplus = {
-       .recalc_rate = clk_pll_recalc_rate_3036_apll,
-       .round_rate = clk_cpll_round_rate_312xplus,
-       .set_rate = clk_cpll_set_rate_312xplus,
-};
-
-static long clk_pll_round_rate_3368_apllb(struct clk_hw *hw, unsigned long rate,
-                                         unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate == __clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                         __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (apll_get_best_set(rate, rk3368_apllb_table)->rate);
-}
-
-/* 1: use, 0: no use */
-#define RK3368_APLLB_USE_GPLL  1
-
-/* when define 1, we will set div to make rate change gently, but it will cost
- more time */
-#define RK3368_APLLB_DIV_MORE  1
-
-static int clk_pll_set_rate_3368_apllb(struct clk_hw *hw, unsigned long rate,
-                                      unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       struct clk *clk = hw->clk;
-       struct clk *arm_gpll = __clk_lookup("clk_gpll");
-       unsigned long arm_gpll_rate, temp_rate, old_rate;
-       const struct apll_clk_set *ps;
-       u32 temp_div;
-       unsigned long flags;
-       int sel_gpll = 0;
-
-       ps = apll_get_best_set(rate, rk3368_apllb_table);
-       clk_debug("apllb will set rate %lu\n", ps->rate);
-       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
-                 ps->pllcon0, ps->pllcon1, ps->pllcon2,
-                 ps->clksel0, ps->clksel1);
-
-#if !RK3368_APLLB_USE_GPLL
-       goto CHANGE_APLL;
-#endif
-
-       /* prepare arm_gpll before reparent clk_core to it */
-       if (!arm_gpll) {
-               clk_err("clk arm_gpll is NULL!\n");
-               goto CHANGE_APLL;
-       }
-
-       arm_gpll_rate = __clk_get_rate(arm_gpll);
-       old_rate = __clk_get_rate(clk);
-
-       temp_rate = (old_rate > rate) ? old_rate : rate;
-       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
-
-       if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
-               clk_debug("temp_div %d > max_div %d\n", temp_div,
-                         RK3368_CORE_CLK_MAX_DIV);
-               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
-                         __clk_get_rate(clk), arm_gpll_rate);
-               goto CHANGE_APLL;
-       }
-
-       local_irq_save(flags);
-
-       if (rate >= old_rate) {
-               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
-       }
-
-       /* select gpll */
-#if RK3368_APLLB_DIV_MORE
-       if (temp_div == 1) {
-               /* when old_rate/2 < (old_rate-arm_gpll_rate),
-                  we can set div to make rate change more gently */
-               if (old_rate > (2*arm_gpll_rate)) {
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                                  RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
-               } else {
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                                  RK3368_CRU_CLKSELS_CON(0));
-               }
-       } else {
-               cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
-               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                          RK3368_CRU_CLKSELS_CON(0));
-       }
-#else
-       cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(0));
-       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                  RK3368_CRU_CLKSELS_CON(0));
-#endif
-
-       sel_gpll = 1;
-
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       clk_debug("temp select arm_gpll path, get rate %lu\n",
-                 arm_gpll_rate/temp_div);
-       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
-                 temp_div);
-
-CHANGE_APLL:
-       local_irq_save(flags);
-
-       /* apll enter slow mode */
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-                  pll->mode_offset);
-
-       /* PLL enter reset */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
-
-       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
-       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
-
-       udelay(5);
-
-       /* return from rest */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
-
-       /* wating lock state */
-       udelay(ps->rst_dly);
-       pll_wait_lock(hw);
-
-       if (!sel_gpll) {
-               if (rate >= old_rate) {
-                       cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
-                       cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
-               }
-       }
-
-       /* apll return from slow mode */
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
-                  pll->mode_offset);
-
-       /* reparent to apll, and set div to 1 */
-       if (sel_gpll) {
-#if RK3368_APLLB_DIV_MORE
-               /* when rate/2 < (rate-arm_gpll_rate), we can set div to make
-                  rate change more gently */
-               if ((temp_div == 1) && (rate > (2*arm_gpll_rate))) {
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
-                                  RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(0));
-                       udelay(10);
-               } else
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
-                                  RK3368_CRU_CLKSELS_CON(0));
-#else
-               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
-                          RK3368_CRU_CLKSELS_CON(0));
-#endif
-       }
-
-       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(0));
-
-       if (rate < old_rate) {
-               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(0));
-               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(1));
-       }
-
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       if (sel_gpll)
-               sel_gpll = 0;
-
-       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
-                 ps->rate,
-                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                 cru_readl(pll->reg + RK3188_PLL_CON(2)),
-                 cru_readl(pll->reg + RK3188_PLL_CON(3)),
-                 cru_readl(RK3368_CRU_CLKSELS_CON(0)),
-                 cru_readl(RK3368_CRU_CLKSELS_CON(1)));
-
-       return 0;
-}
-
-static const struct clk_ops clk_pll_ops_3368_apllb = {
-       .recalc_rate = clk_pll_recalc_rate_3188plus,
-       .round_rate = clk_pll_round_rate_3368_apllb,
-       .set_rate = clk_pll_set_rate_3368_apllb,
-};
-
-static long clk_pll_round_rate_3368_aplll(struct clk_hw *hw, unsigned long rate,
-                                         unsigned long *prate)
-{
-       struct clk *parent = __clk_get_parent(hw->clk);
-
-       if (parent && (rate == __clk_get_rate(parent))) {
-               clk_debug("pll %s round rate=%lu equal to parent rate\n",
-                         __clk_get_name(hw->clk), rate);
-               return rate;
-       }
-
-       return (apll_get_best_set(rate, rk3368_aplll_table)->rate);
-}
-
-/* 1: use, 0: no use */
-#define RK3368_APLLL_USE_GPLL  1
-
-/* when define 1, we will set div to make rate change gently, but it will cost
- more time */
-#define RK3368_APLLL_DIV_MORE  1
-
-static int clk_pll_set_rate_3368_aplll(struct clk_hw *hw, unsigned long rate,
-                                      unsigned long parent_rate)
-{
-       struct clk_pll *pll = to_clk_pll(hw);
-       struct clk *clk = hw->clk;
-       struct clk *arm_gpll = __clk_lookup("clk_gpll");
-       unsigned long arm_gpll_rate, temp_rate, old_rate;
-       const struct apll_clk_set *ps;
-       u32 temp_div;
-       unsigned long flags;
-       int sel_gpll = 0;
-
-       ps = apll_get_best_set(rate, rk3368_aplll_table);
-       clk_debug("aplll will set rate %lu\n", ps->rate);
-       clk_debug("table con:%08x,%08x,%08x, sel:%08x,%08x\n",
-                 ps->pllcon0, ps->pllcon1, ps->pllcon2,
-                 ps->clksel0, ps->clksel1);
-
-#if !RK3368_APLLL_USE_GPLL
-       goto CHANGE_APLL;
-#endif
-
-       /* prepare arm_gpll before reparent clk_core to it */
-       if (!arm_gpll) {
-               clk_err("clk arm_gpll is NULL!\n");
-               goto CHANGE_APLL;
-       }
-
-       arm_gpll_rate = __clk_get_rate(arm_gpll);
-       old_rate = __clk_get_rate(clk);
-
-       temp_rate = (old_rate > rate) ? old_rate : rate;
-       temp_div = DIV_ROUND_UP(arm_gpll_rate, temp_rate);
-
-       if (temp_div > RK3368_CORE_CLK_MAX_DIV) {
-               clk_debug("temp_div %d > max_div %d\n", temp_div,
-                         RK3368_CORE_CLK_MAX_DIV);
-               clk_debug("can't get rate %lu from arm_gpll rate %lu\n",
-                         __clk_get_rate(clk), arm_gpll_rate);
-               goto CHANGE_APLL;
-       }
-
-       local_irq_save(flags);
-
-       if (rate >= old_rate) {
-               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
-               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
-       }
-
-       /* select gpll */
-#if RK3368_APLLL_DIV_MORE
-       if (temp_div == 1) {
-               /* when old_rate/2 < (old_rate-arm_gpll_rate),
-                  we can set div to make rate change more gently */
-               if (old_rate > (2*arm_gpll_rate)) {
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                                  RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
-               } else {
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                                  RK3368_CRU_CLKSELS_CON(2));
-               }
-       } else {
-               cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
-               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                          RK3368_CRU_CLKSELS_CON(2));
-       }
-#else
-               cru_writel(RK3368_CORE_CLK_DIV(temp_div), RK3368_CRU_CLKSELS_CON(2));
-               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_GPLL,
-                          RK3368_CRU_CLKSELS_CON(2));
-#endif
-
-       sel_gpll = 1;
-
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       clk_debug("temp select arm_gpll path, get rate %lu\n",
-                 arm_gpll_rate/temp_div);
-       clk_debug("from arm_gpll rate %lu, temp_div %d\n", arm_gpll_rate,
-                 temp_div);
-
-CHANGE_APLL:
-       local_irq_save(flags);
-
-       /* apll enter slow mode */
-       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift),
-                  pll->mode_offset);
-
-       /* PLL enter reset */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
-
-       cru_writel(ps->pllcon0, pll->reg + RK3188_PLL_CON(0));
-       cru_writel(ps->pllcon1, pll->reg + RK3188_PLL_CON(1));
-       cru_writel(ps->pllcon2, pll->reg + RK3188_PLL_CON(2));
-
-       udelay(5);
-
-       /* return from rest */
-       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
-
-       /* wating lock state */
-       udelay(ps->rst_dly);
-       pll_wait_lock(hw);
-
-       if (!sel_gpll) {
-               if (rate >= old_rate) {
-                       cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
-                       cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
-               }
-       }
-
-       /* apll return from slow mode */
-       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift),
-                  pll->mode_offset);
-
-       /* reparent to apll, and set div to 1 */
-       if (sel_gpll) {
-#if RK3368_APLLL_DIV_MORE
-               /* when rate/2 < (rate-arm_gpll_rate), we can set div to make
-                  rate change more gently */
-               if ((temp_div == 1) && (rate > (2*arm_gpll_rate))) {
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(3), RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
-                                  RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-                       cru_writel(RK3368_CORE_CLK_DIV(2), RK3368_CRU_CLKSELS_CON(2));
-                       udelay(10);
-               } else
-                       cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
-                                  RK3368_CRU_CLKSELS_CON(2));
-#else
-               cru_writel(RK3368_CORE_SEL_PLL_W_MSK|RK3368_CORE_SEL_APLL,
-                          RK3368_CRU_CLKSELS_CON(2));
-#endif
-       }
-
-       cru_writel(RK3368_CORE_CLK_DIV(1), RK3368_CRU_CLKSELS_CON(2));
-
-       if (rate < old_rate) {
-               cru_writel(ps->clksel0, RK3368_CRU_CLKSELS_CON(2));
-               cru_writel(ps->clksel1, RK3368_CRU_CLKSELS_CON(3));
-       }
-
-       smp_wmb();
-
-       local_irq_restore(flags);
-
-       if (sel_gpll)
-               sel_gpll = 0;
-
-       clk_debug("apll set rate %lu, con(%x,%x,%x,%x), sel(%x,%x)\n",
-                 ps->rate,
-                 cru_readl(pll->reg + RK3188_PLL_CON(0)),
-                 cru_readl(pll->reg + RK3188_PLL_CON(1)),
-                 cru_readl(pll->reg + RK3188_PLL_CON(2)),
-                 cru_readl(pll->reg + RK3188_PLL_CON(3)),
-                 cru_readl(RK3368_CRU_CLKSELS_CON(2)),
-                 cru_readl(RK3368_CRU_CLKSELS_CON(3)));
-
-       return 0;
-}
-
-static const struct clk_ops clk_pll_ops_3368_aplll = {
-       .recalc_rate = clk_pll_recalc_rate_3188plus,
-       .round_rate = clk_pll_round_rate_3368_aplll,
-       .set_rate = clk_pll_set_rate_3368_aplll,
-};
-
-const struct clk_ops *rk_get_pll_ops(u32 pll_flags)
-{
-       switch (pll_flags) {
-               case CLK_PLL_3188:
-                       return &clk_pll_ops_3188;
-
-               case CLK_PLL_3188_APLL:
-                       return &clk_pll_ops_3188_apll;
-
-               case CLK_PLL_3188PLUS:
-                       return &clk_pll_ops_3188plus;
-
-               case CLK_PLL_3188PLUS_APLL:
-                       return &clk_pll_ops_3188plus_apll;
-
-               case CLK_PLL_3288_APLL:
-                       return &clk_pll_ops_3288_apll;
-
-               case CLK_PLL_3188PLUS_AUTO:
-                       return &clk_pll_ops_3188plus_auto;
-
-               case CLK_PLL_3036_APLL:
-                       return &clk_pll_ops_3036_apll;
-
-               case CLK_PLL_3036PLUS_AUTO:
-                       return &clk_pll_ops_3036plus_auto;
-
-               case CLK_PLL_312XPLUS:
-                       return &clk_pll_ops_312xplus;
-
-               case CLK_PLL_3368_APLLB:
-                       return &clk_pll_ops_3368_apllb;
-
-               case CLK_PLL_3368_APLLL:
-                       return &clk_pll_ops_3368_aplll;
-
-               case CLK_PLL_3368_LOW_JITTER:
-                       return &clk_pll_ops_3368_low_jitter;
-
-               default:
-                       clk_err("%s: unknown pll_flags!\n", __func__);
-                       return NULL;
-       }
-}
-
-struct clk *rk_clk_register_pll(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags, u32 reg,
-               u32 width, u32 mode_offset, u8 mode_shift,
-               u32 status_offset, u8 status_shift, u32 pll_flags,
-               spinlock_t *lock)
-{
-       struct clk_pll *pll;
-       struct clk *clk;
-       struct clk_init_data init;
-
-
-       clk_debug("%s: pll name = %s, pll_flags = 0x%x, register start!\n",
-                       __func__, name, pll_flags);
-
-       /* allocate the pll */
-       pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
-       if (!pll) {
-               clk_err("%s: could not allocate pll clk\n", __func__);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       init.name = name;
-       init.flags = flags;
-       init.parent_names = (parent_name ? &parent_name: NULL);
-       init.num_parents = (parent_name ? 1 : 0);
-       init.ops = rk_get_pll_ops(pll_flags);
-
-       /* struct clk_pll assignments */
-       pll->reg = reg;
-       pll->width = width;
-       pll->mode_offset = mode_offset;
-       pll->mode_shift = mode_shift;
-       pll->status_offset = status_offset;
-       pll->status_shift = status_shift;
-       pll->flags = pll_flags;
-       pll->lock = lock;
-       pll->hw.init = &init;
-
-       /* register the clock */
-       clk = clk_register(dev, &pll->hw);
-
-       if (IS_ERR(clk))
-               kfree(pll);
-
-       clk_debug("%s: pll name = %s, pll_flags = 0x%x, register finish!\n",
-                       __func__, name, pll_flags);
-
-       return clk;
-}
-
diff --git a/drivers/clk/rockchip/clk-pll.h b/drivers/clk/rockchip/clk-pll.h
deleted file mode 100755 (executable)
index 79804b2..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-#ifndef __RK_CLK_PLL_H
-#define __RK_CLK_PLL_H
-
-#include <linux/clk-provider.h>
-#include <linux/delay.h>
-#include <linux/rockchip/cru.h>
-
-
-#define CLK_LOOPS_JIFFY_REF    (11996091ULL)
-#define CLK_LOOPS_RATE_REF     (1200UL) //Mhz
-#define CLK_LOOPS_RECALC(rate)  \
-       div_u64(CLK_LOOPS_JIFFY_REF*(rate),CLK_LOOPS_RATE_REF*MHZ)
-
-#define CLK_DIV_PLUS_ONE_SET(i, shift, width)  \
-       ((((i)-1) << (shift)) | (((2<<(width)) - 1) << ((shift)+16)))
-
-/*******************RK3188 PLL******************************/
-#define RK3188_PLL_CON(i)      ((i) * 4)
-/*******************PLL WORK MODE*************************/
-#define _RK3188_PLL_MODE_MSK           0x3
-#define _RK3188_PLL_MODE_SLOW          0x0
-#define _RK3188_PLL_MODE_NORM          0x1
-#define _RK3188_PLL_MODE_DEEP          0x2
-
-#define _RK3188_PLL_MODE_GET(offset, shift)    \
-       ((cru_readl(offset) >> (shift)) & _RK3188_PLL_MODE_MSK)
-
-#define _RK3188_PLL_MODE_IS_SLOW(offset, shift)        \
-       (_RK3188_PLL_MODE_GET(offset, shift) == _RK3188_PLL_MODE_SLOW)
-
-#define _RK3188_PLL_MODE_IS_NORM(offset, shift)        \
-       (_RK3188_PLL_MODE_GET(offset, shift) == _RK3188_PLL_MODE_NORM)
-
-#define _RK3188_PLL_MODE_IS_DEEP(offset, shift)        \
-       (_RK3188_PLL_MODE_GET(offset, shift) == _RK3188_PLL_MODE_DEEP)
-
-#define _RK3188_PLL_MODE_SET(val, shift)       \
-       ((val) << (shift)) | CRU_W_MSK(shift, _RK3188_PLL_MODE_MSK)
-
-#define _RK3188_PLL_MODE_SLOW_SET(shift)       \
-       _RK3188_PLL_MODE_SET(_RK3188_PLL_MODE_SLOW, shift)
-
-#define _RK3188_PLL_MODE_NORM_SET(shift)       \
-       _RK3188_PLL_MODE_SET(_RK3188_PLL_MODE_NORM, shift)
-
-#define _RK3188_PLL_MODE_DEEP_SET(shift)       \
-       _RK3188_PLL_MODE_SET(_RK3188_PLL_MODE_DEEP, shift)
-
-/*******************PLL OPERATION MODE*********************/
-#define _RK3188_PLL_BYPASS_SHIFT       0
-#define _RK3188_PLL_POWERDOWN_SHIFT    1
-
-#define _RK3188PLUS_PLL_BYPASS_SHIFT   0
-#define _RK3188PLUS_PLL_POWERDOWN_SHIFT        1
-#define _RK3188PLUS_PLL_RESET_SHIFT    5
-
-#define _RK3188_PLL_OP_SET(val, shift) \
-       ((val) << (shift)) | CRU_W_MSK(shift, 1)
-
-#define _RK3188_PLL_BYPASS_SET(val)    \
-       _RK3188_PLL_OP_SET(val, _RK3188_PLL_BYPASS_SHIFT)
-
-#define _RK3188_PLL_POWERDOWN_SET(val) \
-       _RK3188_PLL_OP_SET(val, _RK3188_PLL_POWERDOWN_SHIFT)
-
-#define _RK3188PLUS_PLL_BYPASS_SET(val)        \
-       _RK3188_PLL_OP_SET(val, _RK3188PLUS_PLL_BYPASS_SHIFT)
-
-#define _RK3188PLUS_PLL_POWERDOWN_SET(val)     \
-       _RK3188_PLL_OP_SET(val, _RK3188PLUS_PLL_POWERDOWN_SHIFT)
-
-#define _RK3188PLUS_PLL_RESET_SET(val) \
-       _RK3188_PLL_OP_SET(val, _RK3188PLUS_PLL_RESET_SHIFT)
-
-/*******************PLL CON0 BITS***************************/
-#define RK3188_PLL_CLKFACTOR_SET(val, shift, msk) \
-       ((((val) - 1) & (msk)) << (shift))
-
-#define RK3188_PLL_CLKFACTOR_GET(reg, shift, msk) \
-       ((((reg) >> (shift)) & (msk)) + 1)
-
-#define RK3188_PLL_OD_MSK              (0x3f)
-#define RK3188_PLL_OD_SHIFT            (0x0)
-#define RK3188_PLL_CLKOD(val)          RK3188_PLL_CLKFACTOR_SET(val, RK3188_PLL_OD_SHIFT, RK3188_PLL_OD_MSK)
-#define RK3188_PLL_NO(reg)             RK3188_PLL_CLKFACTOR_GET(reg, RK3188_PLL_OD_SHIFT, RK3188_PLL_OD_MSK)
-#define RK3188_PLL_CLKOD_SET(val)      (RK3188_PLL_CLKOD(val) | CRU_W_MSK(RK3188_PLL_OD_SHIFT, RK3188_PLL_OD_MSK))
-
-#define RK3188_PLL_NR_MSK              (0x3f)
-#define RK3188_PLL_NR_SHIFT            (8)
-#define RK3188_PLL_CLKR(val)           RK3188_PLL_CLKFACTOR_SET(val, RK3188_PLL_NR_SHIFT, RK3188_PLL_NR_MSK)
-#define RK3188_PLL_NR(reg)             RK3188_PLL_CLKFACTOR_GET(reg, RK3188_PLL_NR_SHIFT, RK3188_PLL_NR_MSK)
-#define RK3188_PLL_CLKR_SET(val)       (RK3188_PLL_CLKR(val) | CRU_W_MSK(RK3188_PLL_NR_SHIFT, RK3188_PLL_NR_MSK))
-
-#define RK3188PLUS_PLL_OD_MSK          (0xf)
-#define RK3188PLUS_PLL_OD_SHIFT        (0x0)
-#define RK3188PLUS_PLL_CLKOD(val)      RK3188_PLL_CLKFACTOR_SET(val, RK3188PLUS_PLL_OD_SHIFT, RK3188PLUS_PLL_OD_MSK)
-#define RK3188PLUS_PLL_NO(reg)         RK3188_PLL_CLKFACTOR_GET(reg, RK3188PLUS_PLL_OD_SHIFT, RK3188PLUS_PLL_OD_MSK)
-#define RK3188PLUS_PLL_CLKOD_SET(val)  (RK3188PLUS_PLL_CLKOD(val) | CRU_W_MSK(RK3188PLUS_PLL_OD_SHIFT, RK3188PLUS_PLL_OD_MSK))
-
-#define RK3188PLUS_PLL_NR_MSK          (0x3f)
-#define RK3188PLUS_PLL_NR_SHIFT                (8)
-#define RK3188PLUS_PLL_CLKR(val)       RK3188_PLL_CLKFACTOR_SET(val, RK3188PLUS_PLL_NR_SHIFT, RK3188PLUS_PLL_NR_MSK)
-#define RK3188PLUS_PLL_NR(reg)         RK3188_PLL_CLKFACTOR_GET(reg, RK3188PLUS_PLL_NR_SHIFT, RK3188PLUS_PLL_NR_MSK)
-#define RK3188PLUS_PLL_CLKR_SET(val)   (RK3188PLUS_PLL_CLKR(val) | CRU_W_MSK(RK3188PLUS_PLL_NR_SHIFT, RK3188PLUS_PLL_NR_MSK))
-
-/*******************PLL CON1 BITS***************************/
-#define RK3188_PLL_NF_MSK              (0xffff)
-#define RK3188_PLL_NF_SHIFT            (0)
-#define RK3188_PLL_CLKF(val)           RK3188_PLL_CLKFACTOR_SET(val, RK3188_PLL_NF_SHIFT, RK3188_PLL_NF_MSK)
-#define RK3188_PLL_NF(reg)             RK3188_PLL_CLKFACTOR_GET(reg, RK3188_PLL_NF_SHIFT, RK3188_PLL_NF_MSK)
-#define RK3188_PLL_CLKF_SET(val)       (RK3188_PLL_CLKF(val) | CRU_W_MSK(RK3188_PLL_NF_SHIFT, RK3188_PLL_NF_MSK))
-
-#define RK3188PLUS_PLL_NF_MSK          (0x1fff)
-#define RK3188PLUS_PLL_NF_SHIFT                (0)
-#define RK3188PLUS_PLL_CLKF(val)       RK3188_PLL_CLKFACTOR_SET(val, RK3188PLUS_PLL_NF_SHIFT, RK3188PLUS_PLL_NF_MSK)
-#define RK3188PLUS_PLL_NF(reg)         RK3188_PLL_CLKFACTOR_GET(reg, RK3188PLUS_PLL_NF_SHIFT, RK3188PLUS_PLL_NF_MSK)
-#define RK3188PLUS_PLL_CLKF_SET(val)   (RK3188PLUS_PLL_CLKF(val) | CRU_W_MSK(RK3188PLUS_PLL_NF_SHIFT, RK3188PLUS_PLL_NF_MSK))
-
-/*******************PLL CON2 BITS***************************/
-#define RK3188_PLL_BWADJ_MSK           (0xfff)
-#define RK3188_PLL_BWADJ_SHIFT         (0)
-#define RK3188_PLL_CLK_BWADJ_SET(val)  ((val) | CRU_W_MSK(RK3188_PLL_BWADJ_SHIFT, RK3188_PLL_BWADJ_MSK))
-
-#define RK3188PLUS_PLL_BWADJ_MSK       (0xfff)
-#define RK3188PLUS_PLL_BWADJ_SHIFT     (0)
-#define RK3188PLUS_PLL_CLK_BWADJ_SET(val)      ((val) | CRU_W_MSK(RK3188PLUS_PLL_BWADJ_SHIFT, RK3188PLUS_PLL_BWADJ_MSK))
-
-/*******************PLL CON3 BITS***************************/
-#define RK3188_PLL_RESET_MSK           (1 << 5)
-#define RK3188_PLL_RESET_W_MSK         (RK3188_PLL_RESET_MSK << 16)
-#define RK3188_PLL_RESET               (1 << 5)
-#define RK3188_PLL_RESET_RESUME                (0 << 5)
-
-#define RK3188_PLL_BYPASS_MSK          (1 << 0)
-#define RK3188_PLL_BYPASS              (1 << 0)
-#define RK3188_PLL_NO_BYPASS           (0 << 0)
-
-#define RK3188_PLL_PWR_DN_MSK          (1 << 1)
-#define RK3188_PLL_PWR_DN_W_MSK                (RK3188_PLL_PWR_DN_MSK << 16)
-#define RK3188_PLL_PWR_DN              (1 << 1)
-#define RK3188_PLL_PWR_ON              (0 << 1)
-
-#define RK3188_PLL_STANDBY_MSK         (1 << 2)
-#define RK3188_PLL_STANDBY             (1 << 2)
-#define RK3188_PLL_NO_STANDBY          (0 << 2)
-
-/*******************CLKSEL0 BITS***************************/
-//core_preiph div
-#define RK3188_CORE_PERIPH_W_MSK       (3 << 22)
-#define RK3188_CORE_PERIPH_MSK         (3 << 6)
-#define RK3188_CORE_PERIPH_2           (0 << 6)
-#define RK3188_CORE_PERIPH_4           (1 << 6)
-#define RK3188_CORE_PERIPH_8           (2 << 6)
-#define RK3188_CORE_PERIPH_16          (3 << 6)
-
-//clk_core
-#define RK3188_CORE_SEL_PLL_MSK                (1 << 8)
-#define RK3188_CORE_SEL_PLL_W_MSK      (1 << 24)
-#define RK3188_CORE_SEL_APLL           (0 << 8)
-#define RK3188_CORE_SEL_GPLL           (1 << 8)
-
-#define RK3188_CORE_CLK_DIV_W_MSK      (0x1F << 25)
-#define RK3188_CORE_CLK_DIV_MSK                (0x1F << 9)
-#define RK3188_CORE_CLK_DIV(i)         ((((i) - 1) & 0x1F) << 9)
-#define RK3188_CORE_CLK_MAX_DIV                32
-
-/*******************CLKSEL1 BITS***************************/
-//aclk_core div
-#define RK3188_CORE_ACLK_W_MSK         (7 << 19)
-#define RK3188_CORE_ACLK_MSK           (7 << 3)
-#define RK3188_CORE_ACLK_11            (0 << 3)
-#define RK3188_CORE_ACLK_21            (1 << 3)
-#define RK3188_CORE_ACLK_31            (2 << 3)
-#define RK3188_CORE_ACLK_41            (3 << 3)
-#define RK3188_CORE_ACLK_81            (4 << 3)
-#define RK3188_GET_CORE_ACLK_VAL(reg)  ((reg)>=4 ? 8:((reg)+1))
-
-/*******************PLL SET*********************************/
-#define _RK3188_PLL_SET_CLKS(_mhz, nr, nf, no) \
-{ \
-       .rate   = (_mhz) * KHZ, \
-       .pllcon0 = RK3188_PLL_CLKR_SET(nr)|RK3188_PLL_CLKOD_SET(no), \
-       .pllcon1 = RK3188_PLL_CLKF_SET(nf),\
-       .pllcon2 = RK3188_PLL_CLK_BWADJ_SET(nf >> 1),\
-       .rst_dly = ((nr*500)/24+1),\
-}
-
-#define _RK3188PLUS_PLL_SET_CLKS(_mhz, nr, nf, no) \
-{ \
-       .rate   = (_mhz) * KHZ, \
-       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no), \
-       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
-       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1),\
-       .rst_dly = ((nr*500)/24+1),\
-}
-
-#define _RK3188PLUS_PLL_SET_CLKS_NB(_mhz, nr, nf, no, nb) \
-{ \
-       .rate   = (_mhz) * KHZ, \
-       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr)|RK3188PLUS_PLL_CLKOD_SET(no), \
-       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
-       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nb-1),\
-       .rst_dly = ((nr*500)/24+1),\
-}
-
-#define _RK3188_APLL_SET_CLKS(_mhz, nr, nf, no, _periph_div, _aclk_div) \
-{ \
-       .rate   = _mhz * MHZ, \
-       .pllcon0 = RK3188_PLL_CLKR_SET(nr) | RK3188_PLL_CLKOD_SET(no), \
-       .pllcon1 = RK3188_PLL_CLKF_SET(nf),\
-       .pllcon2 = RK3188_PLL_CLK_BWADJ_SET(nf >> 1),\
-       .rst_dly = ((nr*500)/24+1),\
-       .clksel0 = RK3188_CORE_PERIPH_W_MSK | RK3188_CORE_PERIPH_##_periph_div,\
-       .clksel1 = RK3188_CORE_ACLK_W_MSK | RK3188_CORE_ACLK_##_aclk_div,\
-       .lpj = (CLK_LOOPS_JIFFY_REF*_mhz) / CLK_LOOPS_RATE_REF,\
-}
-
-
-/*******************RK3288 PLL***********************************/
-/*******************CLKSEL0 BITS***************************/
-#define RK3288_CORE_SEL_PLL_W_MSK      (1 << 31)
-#define RK3288_CORE_SEL_APLL           (0 << 15)
-#define RK3288_CORE_SEL_GPLL           (1 << 15)
-
-#define RK3288_CORE_CLK_SHIFT          8
-#define RK3288_CORE_CLK_WIDTH          5
-#define RK3288_CORE_CLK_DIV(i) \
-       CLK_DIV_PLUS_ONE_SET(i, RK3288_CORE_CLK_SHIFT, RK3288_CORE_CLK_WIDTH)
-#define RK3288_CORE_CLK_MAX_DIV                (2<<RK3288_CORE_CLK_WIDTH)
-
-#define RK3288_ACLK_M0_SHIFT           0
-#define RK3288_ACLK_M0_WIDTH           4
-#define RK3288_ACLK_M0_DIV(i)  \
-       CLK_DIV_PLUS_ONE_SET(i, RK3288_ACLK_M0_SHIFT, RK3288_ACLK_M0_WIDTH)
-
-#define RK3288_ACLK_MP_SHIFT           4
-#define RK3288_ACLK_MP_WIDTH           4
-#define RK3288_ACLK_MP_DIV(i)  \
-       CLK_DIV_PLUS_ONE_SET(i, RK3288_ACLK_MP_SHIFT, RK3288_ACLK_MP_WIDTH)
-
-/*******************CLKSEL37 BITS***************************/
-#define RK3288_CLK_L2RAM_SHIFT         0
-#define RK3288_CLK_L2RAM_WIDTH         3
-#define RK3288_CLK_L2RAM_DIV(i)        \
-       CLK_DIV_PLUS_ONE_SET(i, RK3288_CLK_L2RAM_SHIFT, RK3288_CLK_L2RAM_WIDTH)
-
-#define RK3288_ATCLK_SHIFT             4
-#define RK3288_ATCLK_WIDTH             5
-#define RK3288_ATCLK_DIV(i)    \
-       CLK_DIV_PLUS_ONE_SET(i, RK3288_ATCLK_SHIFT, RK3288_ATCLK_WIDTH)
-
-#define RK3288_PCLK_DBG_SHIFT          9
-#define RK3288_PCLK_DBG_WIDTH          5
-#define RK3288_PCLK_DBG_DIV(i) \
-       CLK_DIV_PLUS_ONE_SET(i, RK3288_PCLK_DBG_SHIFT, RK3288_PCLK_DBG_WIDTH)
-
-#define _RK3288_APLL_SET_CLKS(_mhz, nr, nf, no, l2_div, m0_div, mp_div, atclk_div, pclk_dbg_div) \
-{ \
-       .rate   = _mhz * MHZ, \
-       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr) | RK3188PLUS_PLL_CLKOD_SET(no), \
-       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
-       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1),\
-       .rst_dly = ((nr*500)/24+1),\
-       .clksel0 = RK3288_ACLK_M0_DIV(m0_div) | RK3288_ACLK_MP_DIV(mp_div),\
-       .clksel1 = RK3288_CLK_L2RAM_DIV(l2_div) | RK3288_ATCLK_DIV(atclk_div) | RK3288_PCLK_DBG_DIV(pclk_dbg_div),\
-       .lpj = (CLK_LOOPS_JIFFY_REF*_mhz) / CLK_LOOPS_RATE_REF,\
-}
-/***************************RK3036 PLL**************************************/
-#define LPJ_24M        (CLK_LOOPS_JIFFY_REF * 24) / CLK_LOOPS_RATE_REF
-/*PLL_CON 0,1,2*/
-#define RK3036_PLL_PWR_ON                      (0)
-#define RK3036_PLL_PWR_DN                      (1)
-#define RK3036_PLL_BYPASS                      (1 << 15)
-#define RK3036_PLL_NO_BYPASS                   (0 << 15)
-/*con0*/
-#define RK3036_PLL_BYPASS_SHIFT                (15)
-
-#define RK3036_PLL_POSTDIV1_MASK               (0x7)
-#define RK3036_PLL_POSTDIV1_SHIFT              (12)
-#define RK3036_PLL_FBDIV_MASK                  (0xfff)
-#define RK3036_PLL_FBDIV_SHIFT                 (0)
-
-/*con1*/
-#define RK3036_PLL_RSTMODE_SHIFT               (15)
-#define RK3036_PLL_RST_SHIFT                   (14)
-#define RK3036_PLL_PWR_DN_SHIFT                (13)
-#define RK3036_PLL_DSMPD_SHIFT                 (12)
-#define RK3036_PLL_LOCK_SHIFT                  (10)
-
-#define RK3036_PLL_POSTDIV2_MASK               (0x7)
-#define RK3036_PLL_POSTDIV2_SHIFT              (6)
-#define RK3036_PLL_REFDIV_MASK                 (0x3f)
-#define RK3036_PLL_REFDIV_SHIFT                (0)
-
-/*con2*/
-#define RK3036_PLL_FOUT4PHASE_PWR_DN_SHIFT     (27)
-#define RK3036_PLL_FOUTVCO_PWR_DN_SHIFT        (26)
-#define RK3036_PLL_FOUTPOSTDIV_PWR_DN_SHIFT    (25)
-#define RK3036_PLL_DAC_PWR_DN_SHIFT            (24)
-
-#define RK3036_PLL_FRAC_MASK                   (0xffffff)
-#define RK3036_PLL_FRAC_SHIFT                  (0)
-
-#define CRU_GET_REG_BIT_VAL(reg, bits_shift)           (((reg) >> (bits_shift)) & (0x1))
-#define CRU_GET_REG_BITS_VAL(reg, bits_shift, msk)     (((reg) >> (bits_shift)) & (msk))
-#define CRU_SET_BIT(val, bits_shift)                   (((val) & (0x1)) << (bits_shift))
-#define CRU_W_MSK(bits_shift, msk)                     ((msk) << ((bits_shift) + 16))
-
-#define CRU_W_MSK_SETBITS(val, bits_shift, msk)        (CRU_W_MSK(bits_shift, msk)     \
-                                                       | CRU_SET_BITS(val, bits_shift, msk))
-#define CRU_W_MSK_SETBIT(val, bits_shift)              (CRU_W_MSK(bits_shift, 0x1)     \
-                                                       | CRU_SET_BIT(val, bits_shift))
-
-#define RK3036_PLL_SET_REFDIV(val)                             CRU_W_MSK_SETBITS(val, RK3036_PLL_REFDIV_SHIFT, RK3036_PLL_REFDIV_MASK)
-#define RK3036_PLL_SET_FBDIV(val)                              CRU_W_MSK_SETBITS(val, RK3036_PLL_FBDIV_SHIFT, RK3036_PLL_FBDIV_MASK)
-#define RK3036_PLL_SET_POSTDIV1(val)                           CRU_W_MSK_SETBITS(val, RK3036_PLL_POSTDIV1_SHIFT, RK3036_PLL_POSTDIV1_MASK)
-#define RK3036_PLL_SET_POSTDIV2(val)                           CRU_W_MSK_SETBITS(val, RK3036_PLL_POSTDIV2_SHIFT, RK3036_PLL_POSTDIV2_MASK)
-#define RK3036_PLL_SET_FRAC(val)                               CRU_SET_BITS(val, RK3036_PLL_FRAC_SHIFT, RK3036_PLL_FRAC_MASK)
-
-#define RK3036_PLL_GET_REFDIV(reg)                             CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_REFDIV_SHIFT, RK3036_PLL_REFDIV_MASK)
-#define RK3036_PLL_GET_FBDIV(reg)                              CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_FBDIV_SHIFT, RK3036_PLL_FBDIV_MASK)
-#define RK3036_PLL_GET_POSTDIV1(reg)                           CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_POSTDIV1_SHIFT, RK3036_PLL_POSTDIV1_MASK)
-#define RK3036_PLL_GET_POSTDIV2(reg)                           CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_POSTDIV2_SHIFT, RK3036_PLL_POSTDIV2_MASK)
-#define RK3036_PLL_GET_FRAC(reg)                               CRU_GET_REG_BITS_VAL(reg, RK3036_PLL_FRAC_SHIFT, RK3036_PLL_FRAC_MASK)
-
-/*#define APLL_SET_BYPASS(val)                         CRU_SET_BIT(val, PLL_BYPASS_SHIFT)*/
-#define RK3036_PLL_SET_DSMPD(val)                              CRU_W_MSK_SETBIT(val, RK3036_PLL_DSMPD_SHIFT)
-#define RK3036_PLL_GET_DSMPD(reg)                              CRU_GET_REG_BIT_VAL(reg, RK3036_PLL_DSMPD_SHIFT)
-
-/*******************CLKSEL0 BITS***************************/
-#define RK3036_CLK_SET_DIV_CON_SUB1(val, bits_shift, msk)      CRU_W_MSK_SETBITS((val - 1), bits_shift, msk)
-
-#define RK3036_CPU_CLK_PLL_SEL_SHIFT           (14)
-#define RK3036_CPU_CLK_PLL_SEL_MASK    (0x3)
-#define RK3036_CORE_CLK_PLL_SEL_SHIFT          (7)
-#define RK3036_SEL_APLL                        (0)
-#define RK3036_SEL_GPLL                        (1)
-#define RK3036_CPU_SEL_PLL(plls)               CRU_W_MSK_SETBITS(plls, RK3036_CPU_CLK_PLL_SEL_SHIFT, RK3036_CPU_CLK_PLL_SEL_MASK)
-#define RK3036_CORE_SEL_PLL(plls)              CRU_W_MSK_SETBIT(plls, RK3036_CORE_CLK_PLL_SEL_SHIFT)
-
-#define RK3036_ACLK_CPU_DIV_MASK               (0x1f)
-#define RK3036_ACLK_CPU_DIV_SHIFT              (8)
-#define RK3036_A9_CORE_DIV_MASK                (0x1f)
-#define RK3036_A9_CORE_DIV_SHIFT               (0)
-
-#define RATIO_11               (1)
-#define RATIO_21               (2)
-#define RATIO_41               (4)
-#define RATIO_81               (8)
-
-#define RK3036_ACLK_CPU_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_ACLK_CPU_DIV_SHIFT, RK3036_ACLK_CPU_DIV_MASK)
-#define RK3036_CLK_CORE_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_A9_CORE_DIV_SHIFT, RK3036_A9_CORE_DIV_MASK)
-/*******************CLKSEL1 BITS***************************/
-#define RK3036_PCLK_CPU_DIV_MASK               (0x7)
-#define RK3036_PCLK_CPU_DIV_SHIFT              (12)
-#define RK3036_HCLK_CPU_DIV_MASK               (0x3)
-#define RK3036_HCLK_CPU_DIV_SHIFT              (8)
-#define RK3036_ACLK_CORE_DIV_MASK              (0x7)
-#define RK3036_ACLK_CORE_DIV_SHIFT             (4)
-#define RK3036_CORE_PERIPH_DIV_MASK            (0xf)
-#define RK3036_CORE_PERIPH_DIV_SHIFT           (0)
-
-#define RK3036_PCLK_CPU_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_PCLK_CPU_DIV_SHIFT, RK3036_PCLK_CPU_DIV_MASK)
-#define RK3036_HCLK_CPU_DIV(val)               RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_HCLK_CPU_DIV_SHIFT, RK3036_HCLK_CPU_DIV_MASK)
-#define RK3036_ACLK_CORE_DIV(val)              RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_ACLK_CORE_DIV_SHIFT, RK3036_ACLK_CORE_DIV_MASK)
-#define RK3036_CLK_CORE_PERI_DIV(val)          RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_CORE_PERIPH_DIV_SHIFT, RK3036_CORE_PERIPH_DIV_MASK)
-
-/*******************clksel10***************************/
-#define RK3036_PERI_PLL_SEL_SHIFT      14
-#define RK3036_PERI_PLL_SEL_MASK       (0x3)
-#define RK3036_PERI_PCLK_DIV_MASK      (0x3)
-#define RK3036_PERI_PCLK_DIV_SHIFT     (12)
-#define RK3036_PERI_HCLK_DIV_MASK      (0x3)
-#define RK3036_PERI_HCLK_DIV_SHIFT     (8)
-#define RK3036_PERI_ACLK_DIV_MASK      (0x1f)
-#define RK3036_PERI_ACLK_DIV_SHIFT     (0)
-
-#define RK3036_SEL_3PLL_APLL           (0)
-#define RK3036_SEL_3PLL_DPLL           (1)
-#define RK3036_SEL_3PLL_GPLL           (2)
-
-
-#define RK3036_PERI_CLK_SEL_PLL(plls)  CRU_W_MSK_SETBITS(plls, RK3036_PERI_PLL_SEL_SHIFT, RK3036_PERI_PLL_SEL_MASK)
-#define RK3036_PERI_SET_ACLK_DIV(val)          RK3036_CLK_SET_DIV_CON_SUB1(val, RK3036_PERI_ACLK_DIV_SHIFT, RK3036_PERI_ACLK_DIV_MASK)
-
-/*******************gate BITS***************************/
-#define RK3036_CLK_GATE_CLKID_CONS(i)  RK3036_CRU_CLKGATES_CON((i) / 16)
-
-#define RK3036_CLK_GATE(i)             (1 << ((i)%16))
-#define RK3036_CLK_UN_GATE(i)          (0)
-
-#define RK3036_CLK_GATE_W_MSK(i)       (1 << (((i) % 16) + 16))
-#define RK3036_CLK_GATE_CLKID(i)       (16 * (i))
-
-#define _RK3036_APLL_SET_CLKS(_mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac, \
-               _periph_div) \
-{ \
-       .rate   = (_mhz) * MHZ, \
-       .pllcon0 = RK3036_PLL_SET_POSTDIV1(_postdiv1) | RK3036_PLL_SET_FBDIV(_fbdiv),   \
-       .pllcon1 = RK3036_PLL_SET_DSMPD(_dsmpd) | RK3036_PLL_SET_POSTDIV2(_postdiv2) | RK3036_PLL_SET_REFDIV(_refdiv),  \
-       .pllcon2 = RK3036_PLL_SET_FRAC(_frac),  \
-       .clksel1 = RK3036_CLK_CORE_PERI_DIV(RATIO_##_periph_div),       \
-       .lpj    = (CLK_LOOPS_JIFFY_REF * _mhz) / CLK_LOOPS_RATE_REF,    \
-       .rst_dly = 0,\
-}
-
-#define _RK3036_PLL_SET_CLKS(_mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac) \
-{ \
-       .rate   = (_mhz) * KHZ, \
-       .pllcon0 = RK3036_PLL_SET_POSTDIV1(_postdiv1) | RK3036_PLL_SET_FBDIV(_fbdiv),   \
-       .pllcon1 = RK3036_PLL_SET_DSMPD(_dsmpd) | RK3036_PLL_SET_POSTDIV2(_postdiv2) | RK3036_PLL_SET_REFDIV(_refdiv),  \
-       .pllcon2 = RK3036_PLL_SET_FRAC(_frac),  \
-}
-
-/***************************RK3368 PLL**************************************/
-/*******************CLKSEL0/2 BITS***************************/
-#define RK3368_CORE_SEL_PLL_W_MSK      (1 << 23)
-#define RK3368_CORE_SEL_APLL           (0 << 7)
-#define RK3368_CORE_SEL_GPLL           (1 << 7)
-
-#define RK3368_CORE_CLK_SHIFT          0
-#define RK3368_CORE_CLK_WIDTH          5
-#define RK3368_CORE_CLK_DIV(i) \
-       CLK_DIV_PLUS_ONE_SET(i, RK3368_CORE_CLK_SHIFT, RK3368_CORE_CLK_WIDTH)
-#define RK3368_CORE_CLK_MAX_DIV                (2<<RK3368_CORE_CLK_WIDTH)
-
-#define RK3368_ACLKM_CORE_SHIFT                8
-#define RK3368_ACLKM_CORE_WIDTH                5
-#define RK3368_ACLKM_CORE_DIV(i)       \
-       CLK_DIV_PLUS_ONE_SET(i, RK3368_ACLKM_CORE_SHIFT, RK3368_ACLKM_CORE_WIDTH)
-
-/*******************CLKSEL1/3 BITS***************************/
-#define RK3368_ATCLK_CORE_SHIFT                0
-#define RK3368_ATCLK_CORE_WIDTH                5
-#define RK3368_ATCLK_CORE_DIV(i)       \
-       CLK_DIV_PLUS_ONE_SET(i, RK3368_ATCLK_CORE_SHIFT, RK3368_ATCLK_CORE_WIDTH)
-
-#define RK3368_PCLK_DBG_SHIFT          8
-#define RK3368_PCLK_DBG_WIDTH          5
-#define RK3368_PCLK_DBG_DIV(i) \
-       CLK_DIV_PLUS_ONE_SET(i, RK3368_PCLK_DBG_SHIFT, RK3368_PCLK_DBG_WIDTH)
-
-#define _RK3368_APLL_SET_CLKS(_mhz, nr, nf, no, aclkm_div, atclk_div, pclk_dbg_div) \
-{ \
-       .rate   = _mhz * MHZ, \
-       .pllcon0 = RK3188PLUS_PLL_CLKR_SET(nr) | RK3188PLUS_PLL_CLKOD_SET(no), \
-       .pllcon1 = RK3188PLUS_PLL_CLKF_SET(nf),\
-       .pllcon2 = RK3188PLUS_PLL_CLK_BWADJ_SET(nf >> 1),\
-       .rst_dly = ((nr*500)/24+1),\
-       .clksel0 = RK3368_ACLKM_CORE_DIV(aclkm_div),\
-       .clksel1 = RK3368_ATCLK_CORE_DIV(atclk_div) | RK3368_PCLK_DBG_DIV(pclk_dbg_div) \
-}
-
-struct pll_clk_set {
-       unsigned long   rate;
-       u32     pllcon0;
-       u32     pllcon1;
-       u32     pllcon2;
-       unsigned long   rst_dly;//us
-};
-
-struct apll_clk_set {
-       unsigned long   rate;
-       u32     pllcon0;
-       u32     pllcon1;
-       u32     pllcon2;
-       u32     rst_dly;//us
-       u32     clksel0;
-       u32     clksel1;
-       unsigned long   lpj;
-};
-
-
-#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
-
-struct clk_pll {
-       struct clk_hw   hw;
-       u32             reg;
-       u32             width;
-       u32             mode_offset;
-       u8              mode_shift;
-       u32             status_offset;
-       u8              status_shift;
-       u32             flags;
-       const void      *table;
-       spinlock_t      *lock;
-};
-
-const struct clk_ops *rk_get_pll_ops(u32 pll_flags);
-
-struct clk *rk_clk_register_pll(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags, u32 reg,
-               u32 width, u32 mode_offset, u8 mode_shift,
-               u32 status_offset, u8 status_shift, u32 pll_flags,
-               spinlock_t *lock);
-
-
-#endif /* __RK_CLK_PLL_H */
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
deleted file mode 100644 (file)
index d198c73..0000000
+++ /dev/null
@@ -1,2279 +0,0 @@
-/*
- * Copyright (C) 2013 ROCKCHIP, Inc.
- * Author: chenxing <chenxing@rock-chips.com>
- *         Dai Kelin <dkl@rock-chips.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/clk-private.h>
-#include <asm/io.h>
-
-#include "clk-ops.h"
-#include "clk-pll.h"
-#include "clk-pd.h"
-
-static void __iomem *rk_cru_base;
-static void __iomem *rk_grf_base;
-
-u32 cru_readl(u32 offset)
-{
-       return readl_relaxed(rk_cru_base + (offset));
-}
-
-void cru_writel(u32 val, u32 offset)
-{
-       writel_relaxed(val, rk_cru_base + (offset));
-       dsb(sy);
-}
-
-u32 grf_readl(u32 offset)
-{
-       return readl_relaxed(rk_grf_base + (offset));
-}
-
-struct rkclk_muxinfo {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_mux          *mux;
-       u8                      parent_num;
-       const char              **parent_names;
-       u32                     clkops_idx;
-};
-
-struct rkclk_divinfo {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_divider      *div;
-       u32                     div_type;
-       const char              *parent_name;
-       u32                     clkops_idx;
-};
-
-struct rkclk_fracinfo {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_divider      *frac;
-       u32                     frac_type;
-       const char              *parent_name;
-       u32                     clkops_idx;
-};
-
-struct rkclk_gateinfo {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_gate         *gate;
-       const char              *parent_name;
-       //u32                   clkops_idx;
-};
-
-struct rkclk_pllinfo {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_pll          *pll;
-       const char              *parent_name;
-       u32                     clkops_idx;
-};
-
-struct rkclk_fixed_rate_info {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_fixed_rate   *fixed_rate;
-       const char              *parent_name;
-};
-
-struct rkclk_fixed_factor_info {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_fixed_factor   *fixed_factor;
-       const char              *parent_name;
-};
-
-struct rkclk_pd_info {
-       const char              *clk_name;
-       struct device_node      *np;
-       struct clk_pd           *pd;
-       const char              *parent_name;
-};
-
-
-struct rkclk {
-       const char              *clk_name;
-       //struct device_node    *np;
-       u32                     clk_type;
-       u32                     flags;
-       struct rkclk_muxinfo    *mux_info;
-       struct rkclk_divinfo    *div_info;
-       struct rkclk_fracinfo   *frac_info;
-       struct rkclk_pllinfo    *pll_info;
-       struct rkclk_gateinfo   *gate_info;
-       struct rkclk_fixed_rate_info *fixed_rate_info;
-       struct rkclk_fixed_factor_info *fixed_factor_info;
-       struct rkclk_pd_info    *pd_info;
-       struct list_head        node;
-};
-
-static DEFINE_SPINLOCK(clk_lock);
-LIST_HEAD(rk_clks);
-
-#define RKCLK_PLL_TYPE         (1 << 0)
-#define RKCLK_MUX_TYPE         (1 << 1)
-#define RKCLK_DIV_TYPE         (1 << 2)
-#define RKCLK_FRAC_TYPE                (1 << 3)
-#define RKCLK_GATE_TYPE                (1 << 4)
-#define RKCLK_FIXED_RATE_TYPE  (1 << 5)
-#define RKCLK_FIXED_FACTOR_TYPE        (1 << 6)
-#define RKCLK_PD_TYPE          (1 << 7)
-
-
-static int rkclk_init_muxinfo(struct device_node *np, void __iomem *addr)
-{
-       struct rkclk_muxinfo *muxinfo = NULL;
-       struct clk_mux *mux = NULL;
-       u32 shift, width;
-       u32 flags;
-       int cnt, i, ret = 0;
-       u8 found = 0;
-       struct rkclk *rkclk = NULL;
-
-
-       muxinfo = kzalloc(sizeof(struct rkclk_muxinfo), GFP_KERNEL);
-       if (!muxinfo) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       muxinfo->mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
-       if (!muxinfo->mux) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       mux = muxinfo->mux;
-
-       ret = of_property_read_string(np, "clock-output-names",
-                       &muxinfo->clk_name);
-       if (ret != 0)
-               goto out;
-
-       muxinfo->np = np;
-
-       cnt = of_count_phandle_with_args(np, "clocks", "#clock-cells");
-       if (cnt < 0) {
-               ret = -EINVAL;
-               goto out;
-       } else {
-               clk_debug("%s: parent cnt = %d\n", __func__, cnt);
-               muxinfo->parent_num = (u8)cnt;
-       }
-
-       muxinfo->parent_names = kzalloc(cnt * sizeof(char *), GFP_KERNEL);
-       for (i = 0; i < cnt ; i++) {
-               muxinfo->parent_names[i] = of_clk_get_parent_name(np, i);
-       }
-
-       mux->reg = addr;
-
-       ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
-       if (ret != 0) {
-               goto out;
-       } else {
-               mux->shift = (u8)shift;
-       }
-
-       ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
-       if (ret != 0)
-               goto out;
-       mux->mask = (1 << width) - 1;
-
-       mux->flags = CLK_MUX_HIWORD_MASK;
-
-       ret = of_property_read_u32(np, "rockchip,clkops-idx",
-                       &muxinfo->clkops_idx);
-       if (ret != 0) {
-               muxinfo->clkops_idx = CLKOPS_TABLE_END;
-               ret = 0;
-       }
-
-       ret = of_property_read_u32(np, "rockchip,flags", &flags);
-       if (ret != 0) {
-               flags = 0;
-               ret = 0;
-       }
-
-       found = 0;
-       list_for_each_entry(rkclk, &rk_clks, node) {
-               if (strcmp(muxinfo->clk_name, rkclk->clk_name) == 0) {
-                       if (rkclk->mux_info != NULL) {
-                               clk_err("%s %d:\n", __func__, __LINE__);
-                               clk_err("This clk(%s) has been used,"
-                                               "will be overwrited here!\n",
-                                               rkclk->clk_name);
-                       }
-                       clk_debug("%s: find match %s\n", __func__,
-                                       rkclk->clk_name);
-                       found = 1;
-                       rkclk->mux_info = muxinfo;
-                       rkclk->clk_type |= RKCLK_MUX_TYPE;
-                       rkclk->flags |= flags;
-                       break;
-               }
-       }
-
-       if (!found) {
-               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-               if (!rkclk) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               rkclk->clk_name = muxinfo->clk_name;
-               rkclk->mux_info = muxinfo;
-               rkclk->clk_type = RKCLK_MUX_TYPE;
-               rkclk->flags = flags;
-               clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
-               list_add_tail(&rkclk->node, &rk_clks);
-       }
-
-out:
-       if (ret) {
-               clk_err("%s error, ret = %d\n", __func__, ret);
-               if (muxinfo) {
-                       if (muxinfo->mux)
-                               kfree(muxinfo->mux);
-                       kfree(muxinfo);
-               }
-               if (rkclk)
-                       kfree(rkclk);
-       }
-
-       return ret;
-}
-
-static int rkclk_init_divinfo(struct device_node *np, void __iomem *addr)
-{
-       int cnt = 0, i = 0, ret = 0;
-       struct rkclk *rkclk = NULL;
-       u8 found = 0;
-       u32 flags;
-       u32 shift, width;
-       struct rkclk_divinfo *divinfo = NULL;
-       struct clk_divider *div = NULL;
-       struct clk_div_table    *table;
-       u32 table_val, table_div;
-
-
-       divinfo = kzalloc(sizeof(struct rkclk_divinfo), GFP_KERNEL);
-       if (!divinfo) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       divinfo->div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
-       if (!divinfo->div) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       div = divinfo->div;
-
-       ret = of_property_read_string(np, "clock-output-names",
-                       &divinfo->clk_name);
-       if (ret != 0)
-               goto out;
-
-       divinfo->parent_name = of_clk_get_parent_name(np, 0);
-
-       divinfo->np = np;
-
-       ret = of_property_read_u32(np, "rockchip,clkops-idx",
-                       &divinfo->clkops_idx);
-       if (ret != 0) {
-               divinfo->clkops_idx = CLKOPS_TABLE_END;
-               ret = 0;
-       }
-
-       ret = of_property_read_u32(np, "rockchip,flags", &flags);
-       if (ret != 0) {
-               flags = 0;
-               ret = 0;
-       }
-
-       ret = of_property_read_u32(np, "rockchip,div-type", &divinfo->div_type);
-       if (ret != 0)
-               goto out;
-
-       switch (divinfo->div_type) {
-               case CLK_DIVIDER_PLUS_ONE:
-               case CLK_DIVIDER_ONE_BASED:
-               case CLK_DIVIDER_POWER_OF_TWO:
-                       break;
-               case CLK_DIVIDER_USER_DEFINE:
-                       of_get_property(np, "rockchip,div-relations", &cnt);
-                       if (cnt <= 0) {
-                               ret = -EINVAL;
-                               goto out;
-                       }
-                       cnt /= 4 * 2;
-                       table = kzalloc(cnt * sizeof(struct clk_div_table),
-                                       GFP_KERNEL);
-                       if (!table) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       for (i = 0; i < cnt; i++) {
-                               ret = of_property_read_u32_index(np,
-                                               "rockchip,div-relations", i * 2,
-                                               &table_val);
-                               if (ret)
-                                       goto out;
-                               ret = of_property_read_u32_index(np,
-                                               "rockchip,div-relations",
-                                               i * 2 + 1, &table_div);
-                               if (ret)
-                                       goto out;
-                               table[i].val = (unsigned int)table_val;
-                               table[i].div = (unsigned int)table_div;
-                               clk_debug("\tGet div table %d: val=%d, div=%d\n",
-                                               i, table_val, table_div);
-                       }
-                       div->table = table;
-                       break;
-               default:
-                       clk_err("%s: %s: unknown rockchip,div-type\n", __func__,
-                                       divinfo->clk_name);
-                       ret = -EINVAL;
-                       goto out;
-       }
-
-       div->reg = addr;
-       ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
-       if (ret)
-               goto out;
-       ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
-       if (ret)
-               goto out;
-       div->shift = (u8)shift;
-       div->width = (u8)width;
-       div->flags = CLK_DIVIDER_HIWORD_MASK | divinfo->div_type;
-
-       found = 0;
-       list_for_each_entry(rkclk, &rk_clks, node) {
-               if (strcmp(divinfo->clk_name, rkclk->clk_name) == 0) {
-                       if (rkclk->div_info != NULL) {
-                               clk_err("%s %d:\n", __func__, __LINE__);
-                               clk_err("This clk(%s) has been used,"
-                                               "will be overwrited here!\n",
-                                               rkclk->clk_name);
-                       }
-                       clk_debug("%s: find match %s\n", __func__,
-                                       rkclk->clk_name);
-                       found = 1;
-                       rkclk->div_info = divinfo;
-                       rkclk->clk_type |= RKCLK_DIV_TYPE;
-                       rkclk->flags |= flags;
-                       break;
-               }
-       }
-
-       if (!found) {
-               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-               if (!rkclk) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               rkclk->clk_name = divinfo->clk_name;
-               rkclk->div_info = divinfo;
-               rkclk->clk_type = RKCLK_DIV_TYPE;
-               rkclk->flags = flags;
-               clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
-               list_add_tail(&rkclk->node, &rk_clks);
-       }
-
-out:
-       if (ret) {
-               clk_err("%s error, ret = %d\n", __func__, ret);
-               if(table)
-                       kfree(table);
-               if (divinfo) {
-                       if (divinfo->div)
-                               kfree(divinfo->div);
-                       kfree(divinfo);
-               }
-               if (rkclk)
-                       kfree(rkclk);
-       }
-
-       return ret;
-}
-
-static int rkclk_init_fracinfo(struct device_node *np, void __iomem *addr)
-{
-       struct rkclk *rkclk = NULL;
-       u8 found = 0;
-       int ret = 0;
-       struct rkclk_fracinfo *fracinfo = NULL;
-       struct clk_divider *frac = NULL;
-       u32 shift, width, flags;
-
-
-       fracinfo = kzalloc(sizeof(struct rkclk_fracinfo), GFP_KERNEL);
-       if (!fracinfo) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       fracinfo->frac = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
-       if (!fracinfo->frac) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       frac = fracinfo->frac;
-
-       ret = of_property_read_string(np, "clock-output-names",
-                       &fracinfo->clk_name);
-       if (ret != 0)
-               goto out;
-
-       fracinfo->parent_name = of_clk_get_parent_name(np, 0);
-       fracinfo->np = np;
-
-       ret = of_property_read_u32(np, "rockchip,clkops-idx",
-                       &fracinfo->clkops_idx);
-       if (ret != 0) {
-               fracinfo->clkops_idx = CLKOPS_TABLE_END;
-               clk_err("frac node without specified ops!\n");
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = of_property_read_u32(np, "rockchip,flags", &flags);
-       if (ret != 0) {
-               clk_debug("if not specified, frac use CLK_SET_RATE_PARENT flag "
-                               "as default\n");
-               flags = CLK_SET_RATE_PARENT;
-               ret = 0;
-       }
-
-       frac->reg = addr;
-       ret = of_property_read_u32_index(np, "rockchip,bits", 0, &shift);
-       if (ret)
-               goto out;
-       ret = of_property_read_u32_index(np, "rockchip,bits", 1, &width);
-       if (ret)
-               goto out;
-       frac->shift = (u8)shift;
-       frac->width = (u8)width;
-       frac->flags = 0;
-
-       found = 0;
-       list_for_each_entry(rkclk, &rk_clks, node) {
-               if (strcmp(fracinfo->clk_name, rkclk->clk_name) == 0) {
-                       if (rkclk->frac_info != NULL) {
-                               clk_err("%s %d:\n", __func__, __LINE__);
-                               clk_err("This clk(%s) has been used,"
-                                               "will be overwrited here!\n",
-                                               rkclk->clk_name);
-                       }
-                       clk_debug("%s: find match %s\n", __func__,
-                                       rkclk->clk_name);
-                       found = 1;
-                       rkclk->frac_info = fracinfo;
-                       rkclk->clk_type |= RKCLK_FRAC_TYPE;
-                       rkclk->flags |= flags;
-                       break;
-               }
-       }
-
-       if (!found) {
-               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-               if (!rkclk) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               rkclk->clk_name = fracinfo->clk_name;
-               rkclk->frac_info = fracinfo;
-               rkclk->clk_type = RKCLK_FRAC_TYPE;
-               rkclk->flags = flags;
-               clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
-               list_add_tail(&rkclk->node, &rk_clks);
-       }
-
-out:
-       if (ret) {
-               clk_err("%s error, ret = %d\n", __func__, ret);
-               if (fracinfo) {
-                       if (fracinfo->frac)
-                               kfree(fracinfo->frac);
-                       kfree(fracinfo);
-               }
-               if (rkclk)
-                       kfree(rkclk);
-       }
-
-       return ret;
-}
-
-static int __init rkclk_init_selcon(struct device_node *np)
-{
-       struct device_node *node_con, *node;
-       void __iomem *reg = 0;
-       int ret = 0;
-
-
-       for_each_available_child_of_node(np, node_con) {
-               reg = of_iomap(node_con, 0);
-               clk_debug("\n");
-               clk_debug("%s: reg = 0x%x\n", __func__, (u32)reg);
-
-               for_each_available_child_of_node(node_con, node) {
-                       clk_debug("\n");
-                       if (of_device_is_compatible(node,
-                                               "rockchip,rk3188-div-con"))
-                               ret = rkclk_init_divinfo(node, reg);
-
-                       else if (of_device_is_compatible(node,
-                                               "rockchip,rk3188-mux-con"))
-                               ret = rkclk_init_muxinfo(node, reg);
-
-                       else if (of_device_is_compatible(node,
-                                               "rockchip,rk3188-frac-con"))
-                               ret = rkclk_init_fracinfo(node, reg);
-
-                       else if (of_device_is_compatible(node,
-                                               "rockchip,rk3188-inv-con"))
-                               clk_debug("INV clk\n");
-
-                       else {
-                               clk_err("%s: unknown controller type\n",
-                                               __func__);
-                               ret = -EINVAL;
-                       }
-               }
-       }
-
-       return ret;
-}
-
-static int __init rkclk_init_gatecon(struct device_node *np)
-{
-       struct device_node *node;
-       const char *clk_name;
-       void __iomem *reg;
-       int cnt;
-       int i;
-       struct rkclk_gateinfo *gateinfo;
-       u8 found = 0;
-       struct rkclk *rkclk;
-       int ret = 0;
-       struct clk_gate *gate = NULL;
-
-
-       for_each_available_child_of_node(np, node) {
-               cnt = of_property_count_strings(node, "clock-output-names");
-               if (cnt < 0) {
-                       clk_err("%s: error in clock-output-names %d\n",
-                                       __func__, cnt);
-                       continue;
-               }
-
-               if (cnt == 0) {
-                       clk_debug("%s: nothing to do\n", __func__);
-                       continue;
-               }
-
-               reg = of_iomap(node, 0);
-               clk_debug("\n");
-               clk_debug("%s: reg = 0x%x\n", __func__, (u32)reg);
-
-               for (i = 0; i < cnt; i++) {
-                       ret = of_property_read_string_index(node,
-                                       "clock-output-names", i, &clk_name);
-                       if (ret != 0)
-                               goto out;
-
-                       /* ignore empty slots */
-                       if (!strcmp("reserved", clk_name)) {
-                               clk_debug("do nothing for reserved clk\n");
-                               continue;
-                       }
-
-                       gateinfo = kzalloc(sizeof(struct rkclk_gateinfo),
-                                       GFP_KERNEL);
-                       if (!gateinfo) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-
-                       gateinfo->gate = kzalloc(sizeof(struct clk_gate),
-                                       GFP_KERNEL);
-                       if (!gateinfo->gate) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       gate = gateinfo->gate;
-
-                       gateinfo->clk_name = clk_name;
-                       gateinfo->parent_name = of_clk_get_parent_name(node, i);
-                       gateinfo->np = node;
-
-                       gate->reg = reg;
-                       gate->bit_idx = (i % 16);
-                       gate->flags = CLK_GATE_HIWORD_MASK |
-                               CLK_GATE_SET_TO_DISABLE;
-
-                       found = 0;
-                       list_for_each_entry(rkclk, &rk_clks, node) {
-                               if (strcmp(clk_name, rkclk->clk_name) == 0) {
-                                       if (rkclk->gate_info != NULL) {
-                                               clk_err("%s %d:\n", __func__,
-                                                               __LINE__);
-                                               clk_err("This clk(%s) has been used,"
-                                                               "will be overwrited here!\n",
-                                                               rkclk->clk_name);
-                                       }
-                                       clk_debug("%s: find match %s\n",
-                                                       __func__, rkclk->clk_name);
-                                       found = 1;
-                                       rkclk->gate_info = gateinfo;
-                                       rkclk->clk_type |= RKCLK_GATE_TYPE;
-                                       break;
-                               }
-                       }
-                       if (!found) {
-                               rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-                               if (!rkclk) {
-                                       ret = -ENOMEM;
-                                       goto out;
-                               }
-                               rkclk->clk_name = gateinfo->clk_name;
-                               rkclk->gate_info = gateinfo;
-                               rkclk->clk_type = RKCLK_GATE_TYPE;
-                               clk_debug("%s: creat %s\n", __func__,
-                                               rkclk->clk_name);
-                               list_add_tail(&rkclk->node, &rk_clks);
-                       }
-
-out:
-                       if (ret) {
-                               clk_err("%s error, ret = %d\n", __func__, ret);
-                               if (gateinfo) {
-                                       if (gateinfo->gate)
-                                               kfree(gateinfo->gate);
-                                       kfree(gateinfo);
-                               }
-                               if (rkclk)
-                                       kfree(rkclk);
-                       }
-               }
-
-       }
-
-       return 0;
-}
-
-static int __init rkclk_init_pllcon(struct device_node *np)
-{
-       struct device_node *node = NULL;
-       struct rkclk_pllinfo *pllinfo = NULL;
-       struct clk_pll *pll = NULL;
-       u8 found = 0;
-       int ret = 0;
-       struct rkclk *rkclk = NULL;
-       u32 flags;
-       u32 mode_shift, status_shift;
-
-
-       for_each_available_child_of_node(np, node) {
-               pllinfo = kzalloc(sizeof(struct rkclk_pllinfo), GFP_KERNEL);
-               if (!pllinfo) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               pllinfo->pll = kzalloc(sizeof(struct clk_pll), GFP_KERNEL);
-               if (!pllinfo->pll) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               pll = pllinfo->pll;
-
-               pllinfo->np = node;
-
-               ret = of_property_read_string_index(node, "clock-output-names",
-                               0, &pllinfo->clk_name);
-               if (ret)
-                       goto out;
-
-               pllinfo->parent_name = of_clk_get_parent_name(node, 0);
-
-               ret = of_property_read_u32(np, "rockchip,flags", &flags);
-               if (ret != 0) {
-                       flags = 0;
-                       ret = 0;
-               }
-       
-               ret = of_property_read_u32_index(node, "reg", 0, &pll->reg);
-               if (ret != 0) {
-                       clk_err("%s: can not get reg addr info\n", __func__);
-                       goto out;
-               }
-
-               ret = of_property_read_u32_index(node, "reg", 1, &pll->width);
-               if (ret != 0) {
-                       clk_err("%s: can not get reg length info\n", __func__);
-                       goto out;
-               }
-
-               ret = of_property_read_u32_index(node, "mode-reg", 0,
-                               &pll->mode_offset);
-               if (ret != 0) {
-                       clk_err("%s: can not get mode_reg offset\n", __func__);
-                       goto out;
-               }
-
-               ret = of_property_read_u32_index(node, "mode-reg", 1,
-                               &mode_shift);
-               if (ret != 0) {
-                       clk_err("%s: can not get mode_reg shift\n", __func__);
-                       goto out;
-               } else {
-                       pll->mode_shift = (u8)mode_shift;
-               }
-
-               ret = of_property_read_u32_index(node, "status-reg", 0,
-                               &pll->status_offset);
-               if (ret != 0) {
-                       clk_err("%s: can not get status_reg offset\n", __func__);
-                       goto out;
-               }
-
-               ret = of_property_read_u32_index(node, "status-reg", 1,
-                               &status_shift);
-               if (ret != 0) {
-                       clk_err("%s: can not get status_reg shift\n", __func__);
-                       goto out;
-               } else {
-                       pll->status_shift= (u8)status_shift;
-               }
-
-               ret = of_property_read_u32(node, "rockchip,pll-type", &pll->flags);
-               if (ret != 0) {
-                       clk_err("%s: can not get pll-type\n", __func__);
-                       goto out;
-               }
-
-               clk_debug("%s: pllname=%s, parent=%s, flags=0x%x\n",
-                               __func__, pllinfo->clk_name,
-                               pllinfo->parent_name, flags);
-
-               clk_debug("\t\taddr=0x%x, len=0x%x, mode:offset=0x%x, shift=0x%x,"
-                               " status:offset=0x%x, shift=0x%x, pll->flags=0x%x\n",
-                               (u32)pll->reg, pll->width,
-                               pll->mode_offset, pll->mode_shift,
-                               pll->status_offset, pll->status_shift,
-                               pll->flags);
-
-               found = 0;
-               list_for_each_entry(rkclk, &rk_clks, node) {
-                       if (strcmp(pllinfo->clk_name, rkclk->clk_name) == 0) {
-                               if (rkclk->pll_info != NULL) {
-                                       clk_err("%s %d:\n", __func__, __LINE__);
-                                       clk_err("This clk(%s) has been used,"
-                                                       "will be overwrited here!\n",
-                                                       rkclk->clk_name);
-                               }
-                               clk_debug("%s: find match %s\n", __func__,
-                                               rkclk->clk_name);
-                               found = 1;
-                               rkclk->pll_info = pllinfo;
-                               rkclk->clk_type |= RKCLK_PLL_TYPE;
-                               rkclk->flags |= flags;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-                       if (!rkclk) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       rkclk->clk_name = pllinfo->clk_name;
-                       rkclk->pll_info = pllinfo;
-                       rkclk->clk_type = RKCLK_PLL_TYPE;
-                       rkclk->flags = flags;
-                       list_add_tail(&rkclk->node, &rk_clks);
-               }
-       }
-
-out:
-       if (ret) {
-               clk_err("%s error, ret = %d\n", __func__, ret);
-               if (pllinfo) {
-                       if (pllinfo->pll)
-                               kfree(pllinfo->pll);
-                       kfree(pllinfo);
-               }
-               if (rkclk)
-                       kfree(rkclk);
-       }
-
-       return ret;
-}
-
-static int __init rkclk_init_fixed_rate(struct device_node *np)
-{
-       struct device_node *node = NULL;
-       struct rkclk_fixed_rate_info *fixed_rate_info = NULL;
-       struct clk_fixed_rate *fixed_rate = NULL;
-       u32 rate;
-       int ret = 0;
-       u8 found = 0;
-       struct rkclk *rkclk = NULL;
-
-
-       for_each_available_child_of_node(np, node) {
-               fixed_rate_info = kzalloc(sizeof(struct rkclk_fixed_rate_info),
-                       GFP_KERNEL);
-               if (!fixed_rate_info) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               fixed_rate_info->fixed_rate = kzalloc(sizeof(struct clk_fixed_rate),
-                       GFP_KERNEL);
-               if (!fixed_rate_info->fixed_rate) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               fixed_rate = fixed_rate_info->fixed_rate;
-
-               fixed_rate_info->np = node;
-
-               ret = of_property_read_string_index(node, "clock-output-names",
-                               0, &fixed_rate_info->clk_name);
-               if (ret)
-                       goto out;
-
-               fixed_rate_info->parent_name = of_clk_get_parent_name(node, 0);
-
-               ret = of_property_read_u32(node, "clock-frequency", &rate);
-               if (ret != 0) {
-                       clk_err("%s: can not get clock-frequency\n", __func__);
-                       goto out;
-               }
-               fixed_rate->fixed_rate = (unsigned long)rate;
-
-               found = 0;
-               list_for_each_entry(rkclk, &rk_clks, node) {
-                       if (strcmp(fixed_rate_info->clk_name, rkclk->clk_name) == 0) {
-                               if (rkclk->fixed_rate_info != NULL) {
-                                       clk_err("%s %d:\n", __func__, __LINE__);
-                                       clk_err("This clk(%s) has been used,"
-                                                       "will be overwrited here!\n",
-                                                       rkclk->clk_name);
-                               }
-                               clk_debug("%s: find match %s\n", __func__,
-                                               rkclk->clk_name);
-                               found = 1;
-                               rkclk->fixed_rate_info = fixed_rate_info;
-                               rkclk->clk_type |= RKCLK_FIXED_RATE_TYPE;
-                               rkclk->flags |= CLK_IS_ROOT;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-                       if (!rkclk) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       rkclk->clk_name = fixed_rate_info->clk_name;
-                       rkclk->fixed_rate_info = fixed_rate_info;
-                       rkclk->clk_type = RKCLK_FIXED_RATE_TYPE;
-                       rkclk->flags = CLK_IS_ROOT;
-                       clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
-                       list_add_tail(&rkclk->node, &rk_clks);
-               }
-       }
-
-out:
-       if (ret) {
-               clk_err("%s error, ret = %d\n", __func__, ret);
-               if (fixed_rate_info) {
-                       if (fixed_rate_info->fixed_rate)
-                               kfree(fixed_rate_info->fixed_rate);
-                       kfree(fixed_rate_info);
-               }
-               if (rkclk)
-                       kfree(rkclk);
-       }
-
-       return ret;
-}
-
-static int __init rkclk_init_fixed_factor(struct device_node *np)
-{
-       struct device_node *node = NULL;
-       struct rkclk_fixed_factor_info *fixed_factor_info = NULL;
-       struct clk_fixed_factor *fixed_factor = NULL;
-       u32 flags, mult, div;
-       int ret = 0;
-       u8 found = 0;
-       struct rkclk *rkclk = NULL;
-
-
-       for_each_available_child_of_node(np, node) {
-               fixed_factor_info = kzalloc(sizeof(struct rkclk_fixed_factor_info),
-                       GFP_KERNEL);
-               if (!fixed_factor_info) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               fixed_factor_info->fixed_factor = kzalloc(sizeof(struct clk_fixed_factor),
-                       GFP_KERNEL);
-               if (!fixed_factor_info->fixed_factor) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               fixed_factor = fixed_factor_info->fixed_factor;
-
-               fixed_factor_info->np = node;
-
-               ret = of_property_read_string_index(node, "clock-output-names",
-                               0, &fixed_factor_info->clk_name);
-               if (ret)
-                       goto out;
-
-               fixed_factor_info->parent_name = of_clk_get_parent_name(node, 0);
-
-               ret = of_property_read_u32(node, "rockchip,flags", &flags);
-               if (ret != 0) {
-                       flags = 0;
-                       ret = 0;
-               }
-
-               ret = of_property_read_u32(node, "clock-mult", &mult);
-               if (ret != 0) {
-                       clk_err("%s: can not get mult\n", __func__);
-                       goto out;
-               }
-               fixed_factor->mult = (unsigned int)mult;
-
-               ret = of_property_read_u32(node, "clock-div", &div);
-               if (ret != 0) {
-                       clk_err("%s: can not get div\n", __func__);
-                       goto out;
-               }
-               fixed_factor->div = (unsigned int)div;
-
-
-               found = 0;
-               list_for_each_entry(rkclk, &rk_clks, node) {
-                       if (strcmp(fixed_factor_info->clk_name, rkclk->clk_name) == 0) {
-                               if (rkclk->fixed_factor_info != NULL) {
-                                       clk_err("%s %d:\n", __func__, __LINE__);
-                                       clk_err("This clk(%s) has been used,"
-                                                       "will be overwrited here!\n",
-                                                       rkclk->clk_name);
-                               }
-                               clk_debug("%s: find match %s\n", __func__,
-                                               rkclk->clk_name);
-                               found = 1;
-                               rkclk->fixed_factor_info = fixed_factor_info;
-                               rkclk->clk_type |= RKCLK_FIXED_FACTOR_TYPE;
-                               rkclk->flags |= flags;
-                               break;
-                       }
-               }
-
-               if (!found) {
-                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-                       if (!rkclk) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       rkclk->clk_name = fixed_factor_info->clk_name;
-                       rkclk->fixed_factor_info = fixed_factor_info;
-                       rkclk->clk_type = RKCLK_FIXED_FACTOR_TYPE;
-                       rkclk->flags = flags;
-                       clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
-                       list_add_tail(&rkclk->node, &rk_clks);
-               }
-       }
-
-out:
-       if (ret) {
-               clk_err("%s error, ret = %d\n", __func__, ret);
-               if (fixed_factor_info) {
-                       if (fixed_factor_info->fixed_factor)
-                               kfree(fixed_factor_info->fixed_factor);
-                       kfree(fixed_factor_info);
-               }
-               if (rkclk)
-                       kfree(rkclk);
-       }
-
-       return ret;
-}
-
-static int __init rkclk_init_regcon(struct device_node *np)
-{
-       struct device_node *node;
-       const char *compatible;
-       int ret = 0;
-
-
-       for_each_available_child_of_node(np, node) {
-               clk_debug("\n");
-               of_property_read_string(node, "compatible", &compatible);
-
-               if (strcmp(compatible, "rockchip,rk-pll-cons") == 0) {
-                       ret = rkclk_init_pllcon(node);
-                       if (ret != 0) {
-                               clk_err("%s: init pll cons err\n", __func__);
-                               goto out;
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-sel-cons") == 0) {
-                       ret = rkclk_init_selcon(node);
-                       if (ret != 0) {
-                               clk_err("%s: init sel cons err\n", __func__);
-                               goto out;
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-gate-cons") == 0) {
-                       ret = rkclk_init_gatecon(node);
-                       if (ret != 0) {
-                               clk_err("%s: init gate cons err\n", __func__);
-                               goto out;
-                       }
-               } else {
-                       clk_err("%s: unknown\n", __func__);
-                       ret = -EINVAL;
-                       goto out;
-               }
-       }
-out:
-       return ret;
-}
-
-static int __init rkclk_init_special_regs(struct device_node *np)
-{
-       struct device_node *node;
-       const char *compatible;
-       void __iomem *reg = 0;
-       int ret = 0;
-
-
-       for_each_available_child_of_node(np, node) {
-               clk_debug("\n");
-               of_property_read_string(node, "compatible", &compatible);
-               if (strcmp(compatible, "rockchip,rk3188-mux-con") == 0) {
-                       reg = of_iomap(node, 0);
-                       ret = rkclk_init_muxinfo(node, reg);
-                       if (ret != 0) {
-                               clk_err("%s: init mux con err\n", __func__);
-                               goto out;
-                       }
-               }
-       }
-
-out:
-       return ret;
-}
-
-static int __init rkclk_init_pd(struct device_node *np)
-{
-       struct device_node *node = NULL;
-       struct rkclk_pd_info *pd_info = NULL;
-       struct clk_pd *pd = NULL;
-       int ret = 0;
-       u8 found = 0;
-       struct rkclk *rkclk = NULL;
-
-
-       for_each_available_child_of_node(np, node) {
-               pd_info = kzalloc(sizeof(struct rkclk_pd_info), GFP_KERNEL);
-               if (!pd_info) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-
-               pd_info->pd = kzalloc(sizeof(struct clk_pd), GFP_KERNEL);
-               if (!pd_info->pd) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               pd = pd_info->pd;
-
-               pd_info->np = node;
-
-               ret = of_property_read_string_index(node, "clock-output-names",
-                               0, &pd_info->clk_name);
-               if (ret)
-                       goto out;
-
-               pd_info->parent_name = of_clk_get_parent_name(node, 0);
-
-               ret = of_property_read_u32(node, "rockchip,pd-id", &pd->id);
-               if (ret != 0) {
-                       clk_err("%s: can not get pd-id\n", __func__);
-                       goto out;
-               }
-
-               found = 0;
-               list_for_each_entry(rkclk, &rk_clks, node) {
-                       if (strcmp(pd_info->clk_name, rkclk->clk_name) == 0) {
-                               clk_err("%s %d:\n", __func__, __LINE__);
-                               clk_err("This clk (%s) has been used, error!\n",
-                                       rkclk->clk_name);
-                               goto out;
-                       }
-               }
-
-               if (!found) {
-                       rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
-                       if (!rkclk) {
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-                       rkclk->clk_name = pd_info->clk_name;
-                       rkclk->pd_info = pd_info;
-                       rkclk->clk_type = RKCLK_PD_TYPE;
-                       rkclk->flags = 0;
-                       clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
-                       list_add_tail(&rkclk->node, &rk_clks);
-               }
-       }
-
-out:
-       if (ret) {
-               clk_err("%s error, ret = %d\n", __func__, ret);
-               if (pd_info) {
-                       if (pd_info->pd)
-                               kfree(pd_info->pd);
-                       kfree(pd_info);
-               }
-               if (rkclk)
-                       kfree(rkclk);
-       }
-
-       return ret;
-}
-
-static int rkclk_register(struct rkclk *rkclk)
-{
-       struct clk              *clk = NULL;
-       struct clk_mux          *mux = NULL;
-       struct clk_divider      *div = NULL;
-       struct clk_gate         *gate = NULL;
-       struct clk_pll          *pll = NULL;
-       struct clk_divider      *frac = NULL;
-       struct clk_fixed_rate   *fixed_rate = NULL;
-       struct clk_fixed_factor *fixed_factor = NULL;
-       struct clk_pd           *pd = NULL;
-
-       struct clk_hw           *mux_hw = NULL;
-       const struct clk_ops    *mux_ops = NULL;
-       struct clk_hw           *rate_hw = NULL;
-       const struct clk_ops    *rate_ops = NULL;
-       struct clk_hw           *gate_hw = NULL;
-       const struct clk_ops    *gate_ops = NULL;
-
-       int                     parent_num;
-       const char              **parent_names = NULL;
-       u8                      rate_type_count = 0;
-
-
-       if (rkclk && rkclk->clk_name) {
-               clk_debug("%s: clk_name=%s, clk_type=0x%x, flags=0x%x\n",
-                               __func__, rkclk->clk_name, rkclk->clk_type,
-                               rkclk->flags);
-       } else {
-               clk_err("%s: rkclk or clk_name is NULL!\n", __func__);
-               return -EINVAL;
-       }
-
-       if (rkclk->mux_info && rkclk->mux_info->mux)
-               mux = rkclk->mux_info->mux;
-       if (rkclk->div_info && rkclk->div_info->div)
-               div = rkclk->div_info->div;
-       if (rkclk->gate_info && rkclk->gate_info->gate)
-               gate = rkclk->gate_info->gate;
-       if (rkclk->pll_info && rkclk->pll_info->pll)
-               pll = rkclk->pll_info->pll;
-       if (rkclk->frac_info && rkclk->frac_info->frac)
-               frac = rkclk->frac_info->frac;
-       if (rkclk->fixed_rate_info && rkclk->fixed_rate_info->fixed_rate)
-               fixed_rate = rkclk->fixed_rate_info->fixed_rate;
-       if (rkclk->fixed_factor_info && rkclk->fixed_factor_info->fixed_factor)
-               fixed_factor = rkclk->fixed_factor_info->fixed_factor;
-       if (rkclk->pd_info && rkclk->pd_info->pd)
-               pd = rkclk->pd_info->pd;
-
-
-       switch (rkclk->clk_type) {
-               case RKCLK_MUX_TYPE:
-                       /* only mux without specified ops will be registered here */
-                       if (rkclk->mux_info->clkops_idx == CLKOPS_TABLE_END) {
-                               clk_debug("use clk_register_mux\n");
-                               clk = clk_register_mux_table(NULL, rkclk->clk_name,
-                                               rkclk->mux_info->parent_names,
-                                               rkclk->mux_info->parent_num,
-                                               rkclk->flags, mux->reg, mux->shift,
-                                               mux->mask, mux->flags, NULL, &clk_lock);
-                               goto add_lookup;
-                       } else
-                               goto rgs_comp;
-               case RKCLK_PLL_TYPE:
-                       clk_debug("use rk_clk_register_pll\n");
-                       clk = rk_clk_register_pll(NULL, rkclk->clk_name,
-                                       rkclk->pll_info->parent_name,
-                                       rkclk->flags, pll->reg, pll->width,
-                                       pll->mode_offset, pll->mode_shift,
-                                       pll->status_offset, pll->status_shift,
-                                       pll->flags, &clk_lock);
-                       //kfree!!!!!!!
-                       goto add_lookup;
-               case RKCLK_DIV_TYPE:
-                       /* only div without specified ops will be registered here */
-                       if (rkclk->div_info->clkops_idx == CLKOPS_TABLE_END) {
-                               clk_debug("use clk_register_divider\n");
-                               clk = clk_register_divider(NULL, rkclk->clk_name,
-                                               rkclk->div_info->parent_name,
-                                               rkclk->flags, div->reg, div->shift,
-                                               div->width, div->flags, &clk_lock);
-                               goto add_lookup;
-                       } else
-                               goto rgs_comp;
-               case RKCLK_FRAC_TYPE:
-                       if (rkclk->frac_info->clkops_idx == CLKOPS_TABLE_END) {
-                               clk_err("frac node without specified ops!\n");
-                               return -EINVAL;
-                       } else
-                               goto rgs_comp;
-               case RKCLK_GATE_TYPE:
-                       clk_debug("use clk_register_gate\n");
-                       clk = clk_register_gate(NULL, rkclk->clk_name,
-                                       rkclk->gate_info->parent_name, rkclk->flags,
-                                       gate->reg, gate->bit_idx, gate->flags,
-                                       &clk_lock);
-                       goto add_lookup;
-               case RKCLK_FIXED_RATE_TYPE:
-                       clk_debug("use clk_register_fixed_rate\n");
-                       clk = clk_register_fixed_rate(NULL, rkclk->clk_name,
-                                       rkclk->fixed_rate_info->parent_name,
-                                       rkclk->flags, fixed_rate->fixed_rate);
-                       goto add_lookup;
-               case RKCLK_FIXED_FACTOR_TYPE:
-                       clk_debug("use clk_register_fixed_factor\n");
-                       clk = clk_register_fixed_factor(NULL, rkclk->clk_name,
-                                       rkclk->fixed_factor_info->parent_name,
-                                       rkclk->flags, fixed_factor->mult,
-                                       fixed_factor->div);
-                       goto add_lookup;
-               case RKCLK_PD_TYPE:
-                       clk_debug("use rk_clk_register_pd\n");
-                       clk = rk_clk_register_pd(NULL, rkclk->clk_name,
-                                       rkclk->pd_info->parent_name, rkclk->flags,
-                                       pd->id, &clk_lock);
-                       goto add_lookup;
-               default:
-                       goto rgs_comp;
-       }
-
-rgs_comp:
-
-       if (rkclk->clk_type & RKCLK_DIV_TYPE)
-               rate_type_count++;
-       if (rkclk->clk_type & RKCLK_PLL_TYPE)
-               rate_type_count++;
-       if (rkclk->clk_type & RKCLK_FRAC_TYPE)
-               rate_type_count++;
-       if (rkclk->clk_type & RKCLK_FIXED_RATE_TYPE)
-               rate_type_count++;
-       if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE)
-               rate_type_count++;
-
-       if (rate_type_count > 1) {
-               clk_err("Invalid rkclk type!\n");
-               return -EINVAL;
-       }
-
-       clk_debug("use clk_register_composite\n");
-
-       /* prepare args for clk_register_composite */
-
-       /* prepare parent_num && parent_names
-        * priority: MUX > DIV=PLL=FRAC=FIXED_FACTOR > GATE
-        */
-       if (rkclk->clk_type & RKCLK_MUX_TYPE) {
-               parent_num = rkclk->mux_info->parent_num;
-               parent_names = rkclk->mux_info->parent_names;
-       } else if (rkclk->clk_type & RKCLK_DIV_TYPE ) {
-               parent_num = 1;
-               parent_names = &(rkclk->div_info->parent_name);
-       } else if (rkclk->clk_type & RKCLK_PLL_TYPE) {
-               parent_num = 1;
-               parent_names = &(rkclk->pll_info->parent_name);
-       } else if (rkclk->clk_type & RKCLK_FRAC_TYPE) {
-               parent_num = 1;
-               parent_names = &(rkclk->frac_info->parent_name);
-       } else if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE) {
-               parent_num = 1;
-               parent_names = &(rkclk->fixed_factor_info->parent_name);
-       } else if (rkclk->clk_type & RKCLK_GATE_TYPE) {
-               parent_num = 1;
-               parent_names = &(rkclk->gate_info->parent_name);
-       }
-
-       /* prepare mux_hw && mux_ops */
-       if (rkclk->clk_type & RKCLK_MUX_TYPE) {
-               mux_hw = &mux->hw;
-               mux_ops = &clk_mux_ops;
-       }
-
-       /* prepare rate_hw && rate_ops
-        * priority: DIV=PLL=FRAC=FIXED_FACTOR > MUX
-        */
-       if (rkclk->clk_type & RKCLK_DIV_TYPE) {
-               rate_hw = &div->hw;
-               if (rkclk->div_info->clkops_idx != CLKOPS_TABLE_END)
-                       rate_ops = rk_get_clkops(rkclk->div_info->clkops_idx);
-               else
-                       rate_ops = &clk_divider_ops;
-       } else if (rkclk->clk_type & RKCLK_PLL_TYPE) {
-               rate_hw = &pll->hw;
-               rate_ops = rk_get_pll_ops(pll->flags);
-       } else if (rkclk->clk_type & RKCLK_FRAC_TYPE) {
-               rate_hw = &frac->hw;
-               rate_ops = rk_get_clkops(rkclk->frac_info->clkops_idx);
-       } else if (rkclk->clk_type & RKCLK_FIXED_FACTOR_TYPE) {
-               rate_hw = &fixed_factor->hw;
-               rate_ops = &clk_fixed_factor_ops;
-       } else if ((rkclk->clk_type & RKCLK_MUX_TYPE) &&
-                       (rkclk->mux_info->clkops_idx != CLKOPS_TABLE_END)) {
-               /* when a mux node has specified clkops_idx, prepare rate_hw &&
-                * rate_ops and use clk_register_composite to register it later.
-                */
-               /*FIXME*/
-               rate_hw = kzalloc(sizeof(struct clk_hw), GFP_KERNEL);
-               if (!rate_hw) {
-                       clk_err("%s: fail to alloc rate_hw!\n", __func__);
-                       return -ENOMEM;
-               }
-               rate_ops = rk_get_clkops(rkclk->mux_info->clkops_idx);
-       }
-
-       if (rkclk->clk_type & RKCLK_GATE_TYPE) {
-               gate_hw = &gate->hw;
-               gate_ops = &clk_gate_ops;
-       }
-
-       clk_debug("parent_num=%d, mux_hw=%d mux_ops=%d, rate_hw=%d rate_ops=%d,"
-                       " gate_hw=%d gate_ops=%d\n",
-                       parent_num, mux_hw?1:0, mux_ops?1:0, rate_hw?1:0,
-                       rate_ops?1:0, gate_hw?1:0, gate_ops?1:0);
-
-       clk = clk_register_composite(NULL, rkclk->clk_name, parent_names,
-                       parent_num, mux_hw, mux_ops, rate_hw, rate_ops,
-                       gate_hw, gate_ops, rkclk->flags);
-
-add_lookup:
-       if (clk) {
-               clk_debug("clk name=%s, flags=0x%lx\n", clk->name, clk->flags);
-               clk_register_clkdev(clk, rkclk->clk_name, NULL);
-       } else {
-               clk_err("%s: clk(\"%s\") register clk error\n", __func__,
-                               rkclk->clk_name);
-       }
-
-       return 0;
-}
-
-static int _rkclk_add_provider(struct device_node *np)
-{
-       int i, cnt, ret = 0;
-       const char *name = NULL;
-       struct clk *clk = NULL;
-       struct clk_onecell_data *clk_data = NULL;
-
-
-       clk_debug("\n");
-
-       cnt = of_property_count_strings(np, "clock-output-names");
-       if (cnt < 0) {
-               clk_err("%s: error in clock-output-names, cnt=%d\n", __func__,
-                               cnt);
-               return -EINVAL;
-       }
-
-       clk_debug("%s: cnt = %d\n", __func__, cnt);
-
-       if (cnt == 0) {
-               clk_debug("%s: nothing to do\n", __func__);
-               return 0;
-       }
-
-       if (cnt == 1) {
-               of_property_read_string(np, "clock-output-names", &name);
-               clk_debug("clock-output-names = %s\n", name);
-
-               clk = clk_get_sys(NULL, name);
-               if (IS_ERR(clk)) {
-                       clk_err("%s: fail to get %s\n", __func__, name);
-                       return -EINVAL;
-               }
-
-               ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
-               clk_debug("use of_clk_src_simple_get, ret=%d\n", ret);
-       } else {
-               clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
-               if (!clk_data)
-                       return -ENOMEM;
-
-               clk_data->clks = kzalloc(cnt * sizeof(struct clk *), GFP_KERNEL);
-               if (!clk_data->clks) {
-                       kfree(clk_data);
-                       return -ENOMEM;
-               }
-
-               clk_data->clk_num = cnt;
-
-               for (i=0; i<cnt; i++) {
-                       of_property_read_string_index(np, "clock-output-names",
-                                       i, &name);
-                       clk_debug("clock-output-names[%d]=%s\n", i, name);
-
-                       /* ignore empty slots */
-                       if (!strcmp("reserved", name))
-                               continue;
-
-                       clk = clk_get_sys(NULL, name);
-                       if (IS_ERR(clk)) {
-                               clk_err("%s: fail to get %s\n", __func__, name);
-                               continue;
-                       }
-
-                       clk_data->clks[i] = clk;
-               }
-
-               ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
-               clk_debug("use of_clk_src_onecell_get, ret=%d\n", ret);
-       }
-
-       return ret;
-}
-
-static void rkclk_add_provider(struct device_node *np)
-{
-       struct device_node *node, *node_reg, *node_tmp, *node_prd;
-       const char *compatible;
-
-
-       for_each_available_child_of_node(np, node) {
-               of_property_read_string(node, "compatible", &compatible);
-
-               if (strcmp(compatible, "rockchip,rk-fixed-rate-cons") == 0) {
-                       for_each_available_child_of_node(node, node_prd) {
-                                _rkclk_add_provider(node_prd);
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-fixed-factor-cons") == 0) {
-                       for_each_available_child_of_node(node, node_prd) {
-                                _rkclk_add_provider(node_prd);
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-clock-regs") == 0) {
-                       for_each_available_child_of_node(node, node_reg) {
-                               of_property_read_string(node_reg, "compatible", &compatible);
-
-                               if (strcmp(compatible, "rockchip,rk-pll-cons") == 0) {
-                                       for_each_available_child_of_node(node_reg, node_prd) {
-                                               _rkclk_add_provider(node_prd);
-                                       }
-                               } else if (strcmp(compatible, "rockchip,rk-sel-cons") == 0) {
-                                       for_each_available_child_of_node(node_reg, node_tmp) {
-                                               for_each_available_child_of_node(node_tmp,
-                                                       node_prd) {
-                                                       _rkclk_add_provider(node_prd);
-                                               }
-                                       }
-                               } else if (strcmp(compatible, "rockchip,rk-gate-cons") == 0) {
-                                       for_each_available_child_of_node(node_reg, node_prd) {
-                                                _rkclk_add_provider(node_prd);
-                                       }
-                               } else {
-                                       clk_err("%s: unknown\n", __func__);
-                               }
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-pd-cons") == 0) {
-                       for_each_available_child_of_node(node, node_prd) {
-                                _rkclk_add_provider(node_prd);
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-clock-special-regs") == 0) {
-                       for_each_available_child_of_node(node, node_prd) {
-                                _rkclk_add_provider(node_prd);
-                       }
-               } else {
-                       clk_err("%s: unknown\n", __func__);
-               }
-       }
-
-}
-
-static void rkclk_cache_parents(struct rkclk *rkclk)
-{
-       struct clk *clk, *parent;
-       u8 num_parents;
-       int i;
-
-
-       clk = clk_get(NULL, rkclk->clk_name);
-       if (IS_ERR(clk)) {
-               clk_err("%s: %s clk_get error\n",
-                               __func__, rkclk->clk_name);
-               return;
-       } else {
-               clk_debug("%s: %s clk_get success\n",
-                               __func__, __clk_get_name(clk));
-       }
-
-       num_parents = __clk_get_num_parents(clk);
-       clk_debug("\t\tnum_parents=%d, parent=%s\n", num_parents,
-                       __clk_get_name(__clk_get_parent(clk)));
-
-       for (i=0; i<num_parents; i++) {
-               /* parent will be cached after this func is called */
-               parent = clk_get_parent_by_index(clk, i);
-               if (IS_ERR(parent)) {
-                       clk_err("fail to get parents[%d]=%s\n", i,
-                                       clk->parent_names[i]);
-                       continue;
-               } else {
-                       clk_debug("\t\tparents[%d]: %s\n", i,
-                                       __clk_get_name(parent));
-               }
-       }
-}
-
-void rk_dump_cru(void)
-{
-       printk(KERN_WARNING "CRU:\n");
-       print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 32, 4, rk_cru_base,
-                      0x420, false);
-}
-EXPORT_SYMBOL_GPL(rk_dump_cru);
-
-
-#ifdef RKCLK_DEBUG
-void rkclk_dump_info(struct rkclk *rkclk)
-{
-       struct clk_mux          *mux = NULL;
-       struct clk_divider      *div = NULL;
-       struct clk_gate         *gate = NULL;
-       struct clk_pll          *pll = NULL;
-       struct clk_divider      *frac = NULL;
-       struct clk_fixed_rate   *fixed_rate = NULL;
-       struct clk_fixed_factor *fixed_factor = NULL;
-       struct clk_pd           *pd = NULL;
-       int i;
-
-
-       clk_debug("%s: clkname=%s, type=0x%x, flags=0x%x\n",
-                       __func__, (rkclk->clk_name)?(rkclk->clk_name):NULL,
-                       rkclk->clk_type, rkclk->flags);
-
-       if (rkclk->mux_info && rkclk->mux_info->mux)
-               mux = rkclk->mux_info->mux;
-       if (rkclk->div_info && rkclk->div_info->div)
-               div = rkclk->div_info->div;
-       if (rkclk->pll_info && rkclk->pll_info->pll)
-               pll = rkclk->pll_info->pll;
-       if (rkclk->frac_info && rkclk->frac_info->frac)
-               frac = rkclk->frac_info->frac;
-       if (rkclk->gate_info && rkclk->gate_info->gate)
-               gate = rkclk->gate_info->gate;
-       if (rkclk->fixed_rate_info && rkclk->fixed_rate_info->fixed_rate)
-               fixed_rate = rkclk->fixed_rate_info->fixed_rate;
-       if (rkclk->fixed_factor_info && rkclk->fixed_factor_info->fixed_factor)
-               fixed_factor = rkclk->fixed_factor_info->fixed_factor;
-       if (rkclk->pd_info && rkclk->pd_info->pd)
-               pd = rkclk->pd_info->pd;
-
-
-       if (rkclk->mux_info) {
-               clk_debug("\t\tmux_info: name=%s, clkops_idx=%u\n",
-                               rkclk->mux_info->clk_name,
-                               rkclk->mux_info->clkops_idx);
-               for (i = 0; i < rkclk->mux_info->parent_num; i++)
-                       clk_debug("\t\t\tparent[%d]: %s\n", i,
-                                       rkclk->mux_info->parent_names[i]);
-               if (mux) {
-                       clk_debug("\t\tmux: reg=0x%x, mask=0x%x, shift=0x%x, "
-                                       "mux_flags=0x%x\n", (u32)mux->reg,
-                                       mux->mask, mux->shift, mux->flags);
-               }
-       }
-
-       if (rkclk->pll_info) {
-               clk_debug("\t\tpll_info: name=%s, parent=%s, clkops_idx=0x%x\n",
-                               rkclk->pll_info->clk_name,
-                               rkclk->pll_info->parent_name,
-                               rkclk->pll_info->clkops_idx);
-               if (pll) {
-                       clk_debug("\t\tpll: reg=0x%x, width=0x%x, "
-                                       "mode_offset=0x%x, mode_shift=%u, "
-                                       "status_offset=0x%x, status_shift=%u, "
-                                       "pll->flags=%u\n",
-                                       (u32)pll->reg, pll->width,
-                                       pll->mode_offset, pll->mode_shift,
-                                       pll->status_offset, pll->status_shift,
-                                       pll->flags);
-               }
-       }
-
-       if (rkclk->div_info) {
-               clk_debug("\t\tdiv_info: name=%s, div_type=0x%x, parent=%s, "
-                               "clkops_idx=%d\n",
-                               rkclk->div_info->clk_name,
-                               rkclk->div_info->div_type,
-                               rkclk->div_info->parent_name,
-                               rkclk->div_info->clkops_idx);
-               if (div) {
-                       clk_debug("\t\tdiv: reg=0x%x, shift=0x%x, width=0x%x, "
-                                       "div_flags=0x%x\n", (u32)div->reg,
-                                       div->shift, div->width, div->flags);
-               }
-       }
-
-       if (rkclk->frac_info) {
-               clk_debug("\t\tfrac_info: name=%s, parent=%s, clkops_idx=%d\n",
-                               rkclk->frac_info->clk_name,
-                               rkclk->frac_info->parent_name,
-                               rkclk->frac_info->clkops_idx);
-               if (frac) {
-                       clk_debug("\t\tfrac: reg=0x%x, shift=0x%x, width=0x%x, "
-                                       "div_flags=0x%x\n", (u32)frac->reg,
-                                       frac->shift, frac->width, frac->flags);
-               }
-       }
-
-       if (rkclk->gate_info) {
-               clk_debug("\t\tgate_info: name=%s, parent=%s\n",
-                               rkclk->gate_info->clk_name,
-                               rkclk->gate_info->parent_name);
-               if (gate) {
-                       clk_debug("\t\tgate: reg=0x%x, bit_idx=%d, "
-                                       "gate_flags=0x%x\n", (u32)gate->reg,
-                                       gate->bit_idx, gate->flags);
-               }
-       }
-
-       if (rkclk->fixed_rate_info) {
-               clk_debug("\t\tfixed_rate_info: name=%s\n",
-                               rkclk->fixed_rate_info->clk_name);
-               if (fixed_rate) {
-                       clk_debug("\t\tfixed_rate=%lu, fixed_rate_flags=0x%x\n",
-                               fixed_rate->fixed_rate, fixed_rate->flags);
-               }
-       }
-
-       if (rkclk->fixed_factor_info) {
-               clk_debug("\t\tfixed_factor_info: name=%s, parent=%s\n",
-                               rkclk->fixed_factor_info->clk_name,
-                               rkclk->fixed_factor_info->parent_name);
-               if (fixed_factor) {
-                       clk_debug("\t\tfixed_factor: mult=%u, div=%u\n",
-                               fixed_factor->mult, fixed_factor->div);
-               }
-       }
-
-       if (rkclk->pd_info) {
-               clk_debug("\t\tpd_info: name=%s, parent=%s\n",
-                               rkclk->pd_info->clk_name,
-                               rkclk->pd_info->parent_name);
-               if (pd) {
-                       clk_debug("\t\tpd: id=%u\n", pd->id);
-               }
-       }
-}
-#else
-void rkclk_dump_info(struct rkclk *rkclk) {}
-#endif
-
-
-#ifdef RKCLK_TEST
-char* pd_table[] = {
-       "pd_gpu",
-       "pd_video",
-       "pd_vio",
-       "pd_hevc",
-};
-
-void rk_clk_pd_test(void)
-{
-       struct clk *clk;
-       bool state;
-       int j, ret;
-
-
-       for (j = 0; j < ARRAY_SIZE(pd_table); j++) {
-
-               clk = clk_get(NULL, pd_table[j]);
-
-               ret = clk_prepare_enable(clk);
-               printk("%s: clk_prepare_enable %s, ret=%d\n", __func__,
-                       __clk_get_name(clk), ret);
-
-               state = __clk_is_enabled(clk);
-               printk("%s: clk_pd %s is %s\n", __func__, __clk_get_name(clk),
-                       state ? "enable" : "disable");
-
-               clk_disable_unprepare(clk);
-               printk("%s: clk_disable_unprepare %s\n", __func__,
-                       __clk_get_name(clk));
-
-               state = __clk_is_enabled(clk);
-               printk("%s: clk_pd %s is %s\n", __func__, __clk_get_name(clk),
-                       state ? "enable" : "disable");
-
-               printk("\n");
-       }
-}
-
-struct test_table {
-       const char *name;
-       u32 rate;
-};
-
-struct test_table t_table[] = {
-       {.name = "clk_gpu",     .rate = 297000000},
-       {.name = "dclk_lcdc0",  .rate = 100000000},
-       {.name = "aclk_lcdc0",  .rate = 297000000},
-
-       {.name = "clk_sdmmc",   .rate = 50000000},
-       {.name = "clk_emmc",    .rate = 50000000},
-       {.name = "clk_sdio",    .rate = 50000000},
-
-       {.name = "clk_i2s_div", .rate = 300000000},
-       {.name = "clk_i2s_frac",.rate = 22579200},
-       {.name = "clk_i2s",     .rate = 11289600},
-       {.name = "clk_spdif",   .rate = 11289600},
-
-       {.name = "cif_out_pll", .rate = 48000000},
-       {.name = "clk_cif0",    .rate = 12000000},
-
-       {.name = "clk_uart0",   .rate = 12288000},
-       {.name = "clk_uart1",   .rate = 48000000},
-       {.name = "clk_hsadc",   .rate = 12288000},
-       {.name = "clk_mac",     .rate = 50000000},
-
-//     {.name = "clk_apll",    .rate = 500000000},
-//     {.name = "clk_dpll",    .rate = 400000000},
-       {.name = "clk_cpll",    .rate = 600000000},
-       {.name = "clk_gpll",    .rate = 800000000},
-
-       {.name = "clk_core",    .rate = 100000000},
-       {.name = "clk_core",    .rate = 24000000},
-       {.name = "clk_core",    .rate = 500000000},
-};
-
-
-void rk_clk_test(void)
-{
-       const char *clk_name;
-       struct clk *clk;
-       unsigned long rate=0, recalc_rate=0, round_rate=0, get_rate=0;
-       u32 j = 0;
-       int ret;
-
-       for (j = 0; j < ARRAY_SIZE(t_table); j++) {
-               clk_debug(">>>>>>test %u\n", j);
-
-               clk_name = t_table[j].name;
-               rate = t_table[j].rate;
-
-               clk = clk_get(NULL, clk_name);
-               if (IS_ERR(clk)) {
-                       clk_err("%s: clk(\"%s\") \tclk_get error\n",
-                                       __func__, clk_name);
-               } else
-                       clk_debug("%s: clk(\"%s\") \tclk_get success\n",
-                                       __func__, clk_name);
-
-               /* TEST: clk_round_rate */
-               round_rate = clk_round_rate(clk, rate);
-               clk_debug("%s: clk(\"%s\") \tclk_round_rate from %lu to %lu\n",
-                               __func__, clk_name, rate, round_rate);
-
-               /* TEST: clk_set_rate */
-               ret = clk_set_rate(clk, rate);
-               if (ret) {
-                       clk_err("%s: clk(\"%s\") \tclk_set_rate error, ret=%d\n",
-                                       __func__, clk_name, ret);
-               } else {
-                       clk_debug("%s: clk(\"%s\") \tclk_set_rate success\n",
-                                       __func__, clk_name);
-               }
-
-               /* TEST: recalc_rate\clk_get_rate */
-               if (clk->ops->recalc_rate) {
-                       recalc_rate = clk->ops->recalc_rate(clk->hw,
-                                       clk->parent->rate);
-                       clk_debug("%s: clk(\"%s\") \tclk_recalc_rate %lu\n",
-                                       __func__, clk_name, recalc_rate);
-               } else {
-                       clk_debug("%s: clk(\"%s\") have no recalc ops\n",
-                                       __func__, clk_name);
-                       get_rate = clk_get_rate(clk);
-                       clk_debug("%s: clk(\"%s\") \tclk_get_rate %lu\n",
-                                       __func__, clk_name, get_rate);
-               }
-
-               rk_dump_cru();
-       }
-
-       rk_clk_pd_test();
-}
-#else
-void rk_clk_test(void) {}
-#endif
-EXPORT_SYMBOL_GPL(rk_clk_test);
-
-static int rkclk_panic(struct notifier_block *this, unsigned long ev, void *ptr)
-{
-       rk_dump_cru();
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block rkclk_panic_block = {
-       .notifier_call = rkclk_panic,
-};
-
-void __init rkclk_init_clks(struct device_node *node);
-
-static struct device_node * clk_root_node=NULL;
-static void __init rk_clk_tree_init(struct device_node *np)
-{
-       struct device_node *node, *node_init;
-       struct rkclk *rkclk;
-       const char *compatible;
-
-       printk("%s start!\n", __func__);
-
-       node_init = of_find_node_by_name(NULL, "clocks-init");
-       if (!node_init) {
-               clk_err("%s: can not get clocks-init node\n", __func__);
-               return;
-       }
-
-       clk_root_node = of_find_node_by_name(NULL, "clock_regs");
-       rk_cru_base = of_iomap(clk_root_node, 0);
-       if (!rk_cru_base) {
-               clk_err("%s: could not map cru region\n", __func__);
-               return;
-       }
-
-       node = of_parse_phandle(np, "rockchip,grf", 0);
-       if (node)
-               rk_grf_base = of_iomap(node, 0);
-#ifdef CONFIG_ARM
-       if (!rk_grf_base)
-               rk_grf_base = RK_GRF_VIRT;
-#endif
-
-       for_each_available_child_of_node(np, node) {
-               clk_debug("\n");
-               of_property_read_string(node, "compatible",
-                               &compatible);
-
-               if (strcmp(compatible, "rockchip,rk-fixed-rate-cons") == 0) {
-                       if (rkclk_init_fixed_rate(node) != 0) {
-                               clk_err("%s: init fixed_rate err\n", __func__);
-                               return;
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-fixed-factor-cons") == 0) {
-                       if (rkclk_init_fixed_factor(node) != 0) {
-                               clk_err("%s: init fixed_factor err\n", __func__);
-                               return;
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-clock-regs") == 0) {
-                       if (rkclk_init_regcon(node) != 0) {
-                               clk_err("%s: init reg cons err\n", __func__);
-                               return;
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-pd-cons") == 0) {
-                       if (rkclk_init_pd(node) != 0) {
-                               clk_err("%s: init pd err\n", __func__);
-                               return;
-                       }
-               } else if (strcmp(compatible, "rockchip,rk-clock-special-regs") == 0) {
-                       if (rkclk_init_special_regs(node) != 0) {
-                               clk_err("%s: init special reg err\n", __func__);
-                               return;
-                       }
-               } else {
-                       clk_err("%s: unknown\n", __func__);
-               }
-       }
-
-       list_for_each_entry(rkclk, &rk_clks, node) {
-               clk_debug("\n");
-               rkclk_dump_info(rkclk);
-               clk_debug("\n");
-               rkclk_register(rkclk);
-       }
-
-       rkclk_add_provider(np);
-
-       /* fill clock parents cache after all clocks have been registered */
-       list_for_each_entry(rkclk, &rk_clks, node) {
-               clk_debug("\n");
-               rkclk_cache_parents(rkclk);
-       }
-
-       rkclk_init_clks(node_init);
-
-       rk_clk_test();
-
-       atomic_notifier_chain_register(&panic_notifier_list, &rkclk_panic_block);
-}
-CLK_OF_DECLARE(rk_clocks, "rockchip,rk-clocks", rk_clk_tree_init);
-
-
-/***************************** rockchip clks init******************************/
-const char *of_clk_init_rate_get_info(struct device_node *np,
-               int index,u32 *rate)
-{
-       struct of_phandle_args clkspec;
-       const char *clk_name;
-       int rc;
-
-       if (index < 0)
-               return NULL;
-
-       rc = of_parse_phandle_with_args(np, "rockchip,clocks-init-rate",
-                       "#clock-init-cells", index, &clkspec);
-       if (rc)
-               return NULL;
-
-       if (of_property_read_string_index(clkspec.np, "clock-output-names", 0,
-                               &clk_name) < 0)
-               return NULL;
-
-       *rate= clkspec.args[0];
-
-       of_node_put(clkspec.np);
-       return clk_name;
-}
-
-const char *of_clk_init_parent_get_info(struct device_node *np, int index,
-               const char **clk_child_name)
-{
-       struct of_phandle_args clkspec;
-       const char *clk_name;
-       int rc;
-       phandle phandle;
-       struct device_node *node = NULL;
-
-       if (index < 0)
-               return NULL;
-
-       rc = of_parse_phandle_with_args(np, "rockchip,clocks-init-parent",
-                       "#clock-init-cells", index, &clkspec);
-       if (rc)
-               return NULL;
-
-       if (of_property_read_string_index(clkspec.np, "clock-output-names", 0,
-                               &clk_name) < 0)
-               return NULL;
-
-
-       phandle = clkspec.args[0];
-
-       of_node_put(clkspec.np);
-
-       if (phandle) {
-
-               node = of_find_node_by_phandle(phandle);
-               if (!node) {
-                       return NULL;
-               }
-
-               if (of_property_read_string_index(node, "clock-output-names", 0,
-                                       clk_child_name) < 0)
-                       return NULL;
-
-               of_node_put(node);//???
-               node=NULL;
-       }
-       else
-               return NULL;
-
-       return clk_name;
-}
-
-static int __init rkclk_init_enable(void)
-{
-       struct device_node *node;
-       int cnt, i, ret = 0;
-       const char *clk_name;
-       struct clk *clk;
-
-
-       node = of_find_node_by_name(NULL, "clocks-enable");
-       if (!node) {
-               clk_err("%s: can not get clocks-enable node\n", __func__);
-               return -EINVAL;
-       }
-
-       cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
-       if (cnt < 0) {
-               return -EINVAL;
-       } else {
-               clk_debug("%s: cnt = %d\n", __func__, cnt);
-       }
-
-       for (i = 0; i < cnt ; i++) {
-               clk_name = of_clk_get_parent_name(node, i);
-               clk = clk_get(NULL, clk_name);
-               if (IS_ERR_OR_NULL(clk)) {
-                       clk_err("%s: fail to get %s\n", __func__, clk_name);
-                       return -EINVAL;
-               }
-
-               ret = clk_prepare_enable(clk);
-               if (ret) {
-                       clk_err("%s: fail to prepare_enable %s\n", __func__,
-                               clk_name);
-                       return ret;
-               } else {
-                       clk_debug("%s: prepare_enable %s OK\n", __func__,
-                               clk_name);
-               }
-       }
-
-       return ret;
-}
-
-static int uboot_logo_on = 0;
-
-static void __init rk_get_uboot_display_flag(void)
-{
-       struct device_node *node;
-
-       node = of_find_node_by_name(NULL, "fb");
-       if (node)
-               of_property_read_u32(node, "rockchip,uboot-logo-on", &uboot_logo_on);
-
-       printk("%s: uboot_logo_on = %d\n", __FUNCTION__, uboot_logo_on);
-}
-
-static const char *of_clk_uboot_has_init_get_name(struct device_node *np, int index)
-{
-       struct of_phandle_args clkspec;
-       const char *clk_name;
-       int rc;
-
-       if (index < 0)
-               return NULL;
-
-       rc = of_parse_phandle_with_args(np, "rockchip,clocks-uboot-has-init", 
-               "#clock-cells", index, &clkspec);
-       if (rc)
-               return NULL;
-
-       if (of_property_read_string_index(clkspec.np, "clock-output-names",
-                                         clkspec.args_count ? clkspec.args[0] : 0,
-                                         &clk_name) < 0)
-               clk_name = NULL;
-
-       of_node_put(clkspec.np);
-       return clk_name;
-}
-
-/* If clk has been inited, return 1; else return 0. */
-static int rkclk_uboot_has_init(struct device_node *np, const char *clk_name)
-{
-       int cnt, i;
-       const char *name;
-
-
-       if ((!np) || (!clk_name))
-               return 0;
-
-       cnt = of_count_phandle_with_args(np, "rockchip,clocks-uboot-has-init", 
-               "#clock-cells");
-       if (cnt < 0)
-               return 0;
-
-       for (i = 0; i < cnt ; i++) {
-               name = of_clk_uboot_has_init_get_name(np, i);
-               if (name && (!strcmp(clk_name, name)))
-                       return 1;
-       }
-
-       return 0;
-}
-
-void __init rkclk_init_clks(struct device_node *np)
-{
-       //struct device_node *np;
-       int i,cnt_parent,cnt_rate;
-       u32 clk_rate;
-       //int ret;
-       struct clk *clk_p, *clk_c;
-       const char *clk_name, *clk_parent_name;
-
-
-       rk_get_uboot_display_flag();
-
-       cnt_parent = of_count_phandle_with_args(np,
-                       "rockchip,clocks-init-parent", "#clock-init-cells");
-
-       printk("%s: cnt_parent = %d\n",__FUNCTION__,cnt_parent);
-
-       for (i = 0; i < cnt_parent; i++) {
-               clk_parent_name=NULL;
-               clk_name=of_clk_init_parent_get_info(np, i,&clk_parent_name);
-
-               if(clk_name==NULL||clk_parent_name==NULL)
-                       continue;
-
-               clk_c=clk_get(NULL,clk_name);
-               clk_p=clk_get(NULL,clk_parent_name);
-
-               if(IS_ERR(clk_c)||IS_ERR(clk_p))
-                       continue;
-
-               clk_set_parent(clk_c, clk_p);
-
-               clk_debug("%s: set %s parent = %s\n", __FUNCTION__, clk_name,
-                               clk_parent_name);
-       }
-
-       cnt_rate = of_count_phandle_with_args(np, "rockchip,clocks-init-rate",
-                       "#clock-init-cells");
-
-       printk("%s: cnt_rate = %d\n",__FUNCTION__,cnt_rate);
-
-       for (i = 0; i < cnt_rate; i++) {
-               clk_name=of_clk_init_rate_get_info(np, i, &clk_rate);
-
-               if (clk_name==NULL)
-                       continue;
-
-               if (uboot_logo_on && rkclk_uboot_has_init(np, clk_name)) {
-                       printk("%s: %s has been inited in uboot, ingored\n", 
-                               __FUNCTION__, clk_name);
-                       continue;
-               }
-
-               clk_c = clk_get(NULL, clk_name);
-
-               if(IS_ERR(clk_c))
-                       continue;
-
-               if((clk_rate<1*MHZ)||(clk_rate>2000*MHZ))
-                       clk_err("warning: clk_rate < 1*MHZ or > 2000*MHZ\n");
-
-               clk_set_rate(clk_c, clk_rate);
-
-               clk_debug("%s: set %s rate = %u\n", __FUNCTION__, clk_name,
-                               clk_rate);
-       }
-
-       rkclk_init_enable();
-
-}
-
-u32 clk_suspend_clkgt_info_get(u32 *clk_ungt_msk,u32 *clk_ungt_msk_last,u32 buf_cnt)
-{
-
-    struct device_node *node,*node_gt;
-    u32 temp_val[2];
-    int gt_cnt;
-    int ret;
-    void __iomem *cru_base,*gt_base, *reg_n, *reg_p;
-
-    gt_cnt=0;
-    cru_base= of_iomap(clk_root_node, 0);
-
-    for_each_available_child_of_node(clk_root_node, node) {
-
-           if (of_device_is_compatible(node,"rockchip,rk-gate-cons"))
-            {
-
-                for_each_available_child_of_node(node, node_gt) {
-
-                    if(gt_cnt>=buf_cnt)
-                    {
-                        clk_err("%s:save buf is overflow\n",__FUNCTION__);
-                        return 0;
-                    }
-
-                    ret = of_property_read_u32_array(node_gt,"rockchip,suspend-clkgating-setting",temp_val,2);
-                    if(!ret)
-                    {
-                        clk_ungt_msk[gt_cnt]=temp_val[0];
-                        clk_ungt_msk_last[gt_cnt]=temp_val[1];
-                    }
-                    else
-                    {
-                        clk_ungt_msk[gt_cnt]=0xffff;
-                        clk_ungt_msk_last[gt_cnt]=0xffff;
-                    }
-
-                    if(gt_cnt==0)
-                    {
-                        gt_base=of_iomap(node_gt, 0);
-                        reg_p=gt_base;
-                        reg_n=gt_base;
-                    }
-                    else
-                    {
-                        reg_n=of_iomap(node_gt, 0);
-
-                        if(((long)reg_n-(long)reg_p)!=4)
-                        {
-                            printk("%s: gt reg is not continue\n",__FUNCTION__);
-                            return 0;
-                        }
-                        reg_p=reg_n;
-                    }
-
-                    clk_debug("%s:gt%d,reg=%p,val=(%x,%x)\n",__FUNCTION__,gt_cnt, reg_n,
-                    clk_ungt_msk[gt_cnt], clk_ungt_msk_last[gt_cnt]);
-
-                    gt_cnt++;
-
-                }
-
-                break;
-            }
-    }
-
-    if(gt_cnt!=buf_cnt)
-    {
-           clk_err("%s:save buf is not  Enough\n",__FUNCTION__);
-           return 0;
-    }
-    clk_debug("%s:crubase=%x,gtbase=%x\n",__FUNCTION__,cru_base,gt_base);
-
-    return (u32)(gt_base-cru_base);
-
-}
-
-
-
-
diff --git a/drivers/clk/rockchip/pd-rk3368.c b/drivers/clk/rockchip/pd-rk3368.c
deleted file mode 100644 (file)
index 53fb60d..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Power domain support for Rockchip RK3368
- *
- * Copyright (C) 2014-2015 ROCKCHIP, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/rockchip/pmu.h>
-#include <linux/rockchip/cru.h>
-#include <linux/rockchip/cpu_axi.h>
-
-#include "clk-ops.h"
-
-static void __iomem *rk_pmu_base;
-
-static u32 pmu_readl(u32 offset)
-{
-       return readl_relaxed(rk_pmu_base + (offset));
-}
-
-static void pmu_writel(u32 val, u32 offset)
-{
-       writel_relaxed(val, rk_pmu_base + (offset));
-       dsb(sy);
-}
-
-static const u8 pmu_pd_map[] = {
-       [PD_PERI] = 13,
-       [PD_VIDEO] = 14,
-       [PD_VIO] = 15,
-       [PD_GPU_0] = 16,
-       [PD_GPU_1] = 17,
-};
-
-static const u8 pmu_st_map[] = {
-       [PD_PERI] = 12,
-       [PD_VIDEO] = 13,
-       [PD_VIO] = 14,
-       [PD_GPU_0] = 15,
-       [PD_GPU_1] = 16,
-};
-
-static bool rk3368_pmu_power_domain_is_on(enum pmu_power_domain pd)
-{
-       /* 1'b0: power on, 1'b1: power off */
-       return !(pmu_readl(RK3368_PMU_PWRDN_ST) & BIT(pmu_st_map[pd]));
-}
-
-static DEFINE_SPINLOCK(pmu_idle_lock);
-
-static const u8 pmu_idle_map[] = {
-       [IDLE_REQ_GPU] = 2,
-       [IDLE_REQ_BUS] = 4,
-       [IDLE_REQ_PERI] = 6,
-       [IDLE_REQ_VIDEO] = 7,
-       [IDLE_REQ_VIO] = 8,
-};
-
-static int rk3368_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
-{
-       u32 bit = pmu_idle_map[req];
-       u32 idle_mask = BIT(bit) | BIT(bit + 16);
-       u32 idle_target = (idle << bit) | (idle << (bit + 16));
-       u32 mask = BIT(bit);
-       u32 val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pmu_idle_lock, flags);
-
-       val = pmu_readl(RK3368_PMU_IDLE_REQ);
-       if (idle)
-               val |=  mask;
-       else
-               val &= ~mask;
-       pmu_writel(val, RK3368_PMU_IDLE_REQ);
-       dsb(sy);
-
-       while ((pmu_readl(RK3368_PMU_IDLE_ST) & idle_mask) != idle_target)
-               ;
-
-       spin_unlock_irqrestore(&pmu_idle_lock, flags);
-
-       return 0;
-}
-
-static DEFINE_SPINLOCK(pmu_pd_lock);
-
-static noinline void rk3368_do_pmu_set_power_domain
-                                       (enum pmu_power_domain domain, bool on)
-{
-       u8 pd = pmu_pd_map[domain];
-       u32 val = pmu_readl(RK3368_PMU_PWRDN_CON);
-
-       if (on)
-               val &= ~BIT(pd);
-       else
-               val |=  BIT(pd);
-
-       pmu_writel(val, RK3368_PMU_PWRDN_CON);
-       dsb(sy);
-
-       while ((pmu_readl(RK3368_PMU_PWRDN_ST) & BIT(pmu_st_map[domain])) == on)
-               ;
-}
-
-/* PD_VIO */
-static void __iomem *iep_qos_base;
-static u32 iep_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *isp_r0_qos_base;
-static u32 isp_r0_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *isp_r1_qos_base;
-static u32 isp_r1_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *isp_w0_qos_base;
-static u32 isp_w0_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *isp_w1_qos_base;
-static u32 isp_w1_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *vip_qos_base;
-static u32 vip_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *vop_qos_base;
-static u32 vop_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *rga_r_qos_base;
-static u32 rga_r_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *rga_w_qos_base;
-static u32 rga_w_qos[CPU_AXI_QOS_NUM_REGS];
-/* PD_VIDEO */
-static void __iomem *hevc_r_qos_base;
-static u32 hevc_r_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *vpu_r_qos_base;
-static u32 vpu_r_qos[CPU_AXI_QOS_NUM_REGS];
-static void __iomem *vpu_w_qos_base;
-static u32 vpu_w_qos[CPU_AXI_QOS_NUM_REGS];
-/* PD_GPU_0 */
-static void __iomem *gpu_qos_base;
-static u32 gpu_qos[CPU_AXI_QOS_NUM_REGS];
-/* PD_PERI */
-static void __iomem *peri_qos_base;
-static u32 peri_qos[CPU_AXI_QOS_NUM_REGS];
-
-#define PD_SAVE_QOS(name) CPU_AXI_SAVE_QOS(name##_qos, name##_qos_base)
-#define PD_RESTORE_QOS(name) CPU_AXI_RESTORE_QOS(name##_qos, name##_qos_base)
-
-static int rk3368_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pmu_pd_lock, flags);
-
-       if (rk3368_pmu_power_domain_is_on(pd) == on)
-               goto out;
-
-       if (!on) {
-               /* if power down, idle request to NIU first */
-               if (pd == PD_VIO) {
-                       PD_SAVE_QOS(iep);
-                       PD_SAVE_QOS(isp_r0);
-                       PD_SAVE_QOS(isp_r1);
-                       PD_SAVE_QOS(isp_w0);
-                       PD_SAVE_QOS(isp_w1);
-                       PD_SAVE_QOS(vip);
-                       PD_SAVE_QOS(vop);
-                       PD_SAVE_QOS(rga_r);
-                       PD_SAVE_QOS(rga_w);
-                       rk3368_pmu_set_idle_request(IDLE_REQ_VIO, true);
-               } else if (pd == PD_VIDEO) {
-                       PD_SAVE_QOS(hevc_r);
-                       PD_SAVE_QOS(vpu_r);
-                       PD_SAVE_QOS(vpu_w);
-                       rk3368_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
-               } else if (pd == PD_GPU_0) {
-                       PD_SAVE_QOS(gpu);
-                       rk3368_pmu_set_idle_request(IDLE_REQ_GPU, true);
-               } else if (pd == PD_PERI) {
-                       PD_SAVE_QOS(peri);
-                       rk3368_pmu_set_idle_request(IDLE_REQ_PERI, true);
-               }
-       }
-
-       rk3368_do_pmu_set_power_domain(pd, on);
-
-       if (on) {
-               /* if power up, idle request release to NIU */
-               if (pd == PD_VIO) {
-                       rk3368_pmu_set_idle_request(IDLE_REQ_VIO, false);
-                       PD_RESTORE_QOS(iep);
-                       PD_RESTORE_QOS(isp_r0);
-                       PD_RESTORE_QOS(isp_r1);
-                       PD_RESTORE_QOS(isp_w0);
-                       PD_RESTORE_QOS(isp_w1);
-                       PD_RESTORE_QOS(vip);
-                       PD_RESTORE_QOS(vop);
-                       PD_RESTORE_QOS(rga_r);
-                       PD_RESTORE_QOS(rga_w);
-               } else if (pd == PD_VIDEO) {
-                       rk3368_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
-                       PD_RESTORE_QOS(hevc_r);
-                       PD_RESTORE_QOS(vpu_r);
-                       PD_RESTORE_QOS(vpu_w);
-               } else if (pd == PD_GPU_0) {
-                       rk3368_pmu_set_idle_request(IDLE_REQ_GPU, false);
-                       PD_RESTORE_QOS(gpu);
-               } else if (pd == PD_PERI) {
-                       rk3368_pmu_set_idle_request(IDLE_REQ_PERI, false);
-                       PD_RESTORE_QOS(peri);
-               }
-       }
-
-out:
-       spin_unlock_irqrestore(&pmu_pd_lock, flags);
-       return 0;
-}
-
-static int rk3368_sys_set_power_domain(enum pmu_power_domain pd, bool on)
-{
-       u32 clks_ungating[RK3368_CRU_CLKGATES_CON_CNT];
-       u32 clks_save[RK3368_CRU_CLKGATES_CON_CNT];
-       u32 i, ret;
-
-       for (i = 0; i < RK3368_CRU_CLKGATES_CON_CNT; i++) {
-               clks_save[i] = cru_readl(RK3368_CRU_CLKGATES_CON(i));
-               clks_ungating[i] = 0;
-       }
-
-       for (i = 0; i < RK3368_CRU_CLKGATES_CON_CNT; i++)
-               cru_writel(0xffff0000, RK3368_CRU_CLKGATES_CON(i));
-
-       ret = rk3368_pmu_set_power_domain(pd, on);
-
-       for (i = 0; i < RK3368_CRU_CLKGATES_CON_CNT; i++)
-               cru_writel(clks_save[i] | 0xffff0000,
-                          RK3368_CRU_CLKGATES_CON(i));
-
-       return ret;
-}
-
-static int __init rk3368_init_rockchip_pmu_ops(void)
-{
-       struct device_node *node, *gp, *cp;
-
-       node = of_find_compatible_node(NULL, NULL, "rockchip,rk3368-pmu");
-       if (!node) {
-               pr_err("%s: could not find pmu dt node\n", __func__);
-               return -ENODEV;
-       }
-
-       rk_pmu_base = of_iomap(node, 0);
-       if (!rk_pmu_base) {
-               pr_err("%s: could not map pmu registers\n", __func__);
-               return -ENXIO;
-       }
-
-       node = of_find_compatible_node(NULL, NULL, "rockchip,cpu_axi_bus");
-       if (!node)
-               return -ENODEV;
-
-#define MAP(name)                                                      \
-       do {                                                            \
-               cp = of_get_child_by_name(gp, #name);                   \
-               if (cp)                                                 \
-                       name##_qos_base = of_iomap(cp, 0);              \
-               if (!name##_qos_base)                                   \
-                       pr_err("%s: could not map qos %s register\n",   \
-                              __func__, #name);                        \
-       } while (0)
-
-       gp = of_get_child_by_name(node, "qos");
-       if (gp) {
-               MAP(peri);
-               MAP(iep);
-               MAP(isp_r0);
-               MAP(isp_r1);
-               MAP(isp_w0);
-               MAP(isp_w1);
-               MAP(vip);
-               MAP(vop);
-               MAP(rga_r);
-               MAP(rga_w);
-               MAP(hevc_r);
-               MAP(vpu_r);
-               MAP(vpu_w);
-               MAP(gpu);
-       }
-
-#undef MAP
-
-       rockchip_pmu_ops.set_power_domain = rk3368_sys_set_power_domain;
-       rockchip_pmu_ops.power_domain_is_on = rk3368_pmu_power_domain_is_on;
-
-       return 0;
-}
-
-arch_initcall(rk3368_init_rockchip_pmu_ops);