From: Huang, Tao Date: Thu, 22 Dec 2016 06:23:30 +0000 (+0800) Subject: rk: rm drivers/clk/rk X-Git-Tag: firefly_0821_release~1005 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fa25ca731857056b67bbf5b348e82a1e04cb6aab;p=firefly-linux-kernel-4.4.55.git rk: rm drivers/clk/rk Change-Id: I8c541c0edb446a285ca5097b597216635e755460 Signed-off-by: Huang, Tao --- diff --git a/drivers/clk/rk/Makefile b/drivers/clk/rk/Makefile deleted file mode 100644 index 9c9e0e099596..000000000000 --- a/drivers/clk/rk/Makefile +++ /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/rk/clk-ops.c b/drivers/clk/rk/clk-ops.c deleted file mode 100644 index 948ffec080f0..000000000000 --- a/drivers/clk/rk/clk-ops.c +++ /dev/null @@ -1,921 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 deleted file mode 100644 index 7d43745de399..000000000000 --- a/drivers/clk/rk/clk-ops.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __RK_CLK_OPS_H -#define __RK_CLK_OPS_H - -#include -#include -#include - -#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 deleted file mode 100644 index 4748cb3b15e9..000000000000 --- a/drivers/clk/rk/clk-pd.c +++ /dev/null @@ -1,228 +0,0 @@ -#include - -#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 deleted file mode 100644 index 9983bdd0ea4d..000000000000 --- a/drivers/clk/rk/clk-pd.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __RK_CLK_PD_H -#define __RK_CLK_PD_H - -#include -#include - - - -#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 deleted file mode 100644 index 5943ca12f8c2..000000000000 --- a/drivers/clk/rk/clk-pll.c +++ /dev/null @@ -1,2581 +0,0 @@ -#include -#include -#include - -#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 deleted file mode 100755 index 79804b2ab775..000000000000 --- a/drivers/clk/rk/clk-pll.h +++ /dev/null @@ -1,498 +0,0 @@ -#ifndef __RK_CLK_PLL_H -#define __RK_CLK_PLL_H - -#include -#include -#include - - -#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<> 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<> 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 deleted file mode 100644 index d198c73001a7..000000000000 --- a/drivers/clk/rk/clk.c +++ /dev/null @@ -1,2279 +0,0 @@ -/* - * Copyright (C) 2013 ROCKCHIP, Inc. - * Author: chenxing - * Dai Kelin - * - * 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 -#include -#include -#include -#include -#include - -#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; iclks[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; iparent_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 deleted file mode 100644 index 53fb60db62ad..000000000000 --- a/drivers/clk/rk/pd-rk3368.c +++ /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 -#include -#include -#include -#include - -#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/include/linux/rockchip/cpu_axi.h b/include/linux/rockchip/cpu_axi.h deleted file mode 100644 index 9af5a7ac359c..000000000000 --- a/include/linux/rockchip/cpu_axi.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef __CPU_AXI_H -#define __CPU_AXI_H - -#define CPU_AXI_QOS_PRIORITY 0x08 -#define CPU_AXI_QOS_MODE 0x0c -#define CPU_AXI_QOS_BANDWIDTH 0x10 -#define CPU_AXI_QOS_SATURATION 0x14 -#define CPU_AXI_QOS_EXTCONTROL 0x18 - -#define CPU_AXI_QOS_MODE_NONE 0 -#define CPU_AXI_QOS_MODE_FIXED 1 -#define CPU_AXI_QOS_MODE_LIMITER 2 -#define CPU_AXI_QOS_MODE_REGULATOR 3 - -#define CPU_AXI_QOS_PRIORITY_LEVEL(h, l) \ - ((((h) & 3) << 8) | (((h) & 3) << 2) | ((l) & 3)) -#define CPU_AXI_SET_QOS_PRIORITY(h, l, base) \ - writel_relaxed(CPU_AXI_QOS_PRIORITY_LEVEL(h, l), base + CPU_AXI_QOS_PRIORITY) - -#define CPU_AXI_SET_QOS_MODE(mode, base) \ - writel_relaxed((mode) & 3, base + CPU_AXI_QOS_MODE) - -#define CPU_AXI_SET_QOS_BANDWIDTH(bandwidth, base) \ - writel_relaxed((bandwidth) & 0x7ff, base + CPU_AXI_QOS_BANDWIDTH) - -#define CPU_AXI_SET_QOS_SATURATION(saturation, base) \ - writel_relaxed((saturation) & 0x3ff, base + CPU_AXI_QOS_SATURATION) - -#define CPU_AXI_SET_QOS_EXTCONTROL(extcontrol, base) \ - writel_relaxed((extcontrol) & 7, base + CPU_AXI_QOS_EXTCONTROL) - -#define CPU_AXI_QOS_NUM_REGS 5 -#define CPU_AXI_SAVE_QOS(array, base) do { \ - array[0] = readl_relaxed(base + CPU_AXI_QOS_PRIORITY); \ - array[1] = readl_relaxed(base + CPU_AXI_QOS_MODE); \ - array[2] = readl_relaxed(base + CPU_AXI_QOS_BANDWIDTH); \ - array[3] = readl_relaxed(base + CPU_AXI_QOS_SATURATION); \ - array[4] = readl_relaxed(base + CPU_AXI_QOS_EXTCONTROL); \ -} while (0) -#define CPU_AXI_RESTORE_QOS(array, base) do { \ - writel_relaxed(array[0], base + CPU_AXI_QOS_PRIORITY); \ - writel_relaxed(array[1], base + CPU_AXI_QOS_MODE); \ - writel_relaxed(array[2], base + CPU_AXI_QOS_BANDWIDTH); \ - writel_relaxed(array[3], base + CPU_AXI_QOS_SATURATION); \ - writel_relaxed(array[4], base + CPU_AXI_QOS_EXTCONTROL); \ -} while (0) - -#define RK3188_CPU_AXI_DMAC_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x1000) -#define RK3188_CPU_AXI_CPU0_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x2000) -#define RK3188_CPU_AXI_CPU1R_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x2080) -#define RK3188_CPU_AXI_CPU1W_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x2100) -#define RK3188_CPU_AXI_PERI_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x4000) -#define RK3188_CPU_AXI_GPU_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x5000) -#define RK3188_CPU_AXI_VPU_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x6000) -#define RK3188_CPU_AXI_LCDC0_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7000) -#define RK3188_CPU_AXI_CIF0_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7080) -#define RK3188_CPU_AXI_IPP_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7100) -#define RK3188_CPU_AXI_LCDC1_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7180) -#define RK3188_CPU_AXI_CIF1_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7200) -#define RK3188_CPU_AXI_RGA_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7280) - -/* service core */ -#define RK3288_SERVICE_CORE_VIRT RK_CPU_AXI_BUS_VIRT -#define RK3288_CPU_AXI_CPUM_R_QOS_VIRT (RK3288_SERVICE_CORE_VIRT + 0x80) -#define RK3288_CPU_AXI_CPUM_W_QOS_VIRT (RK3288_SERVICE_CORE_VIRT + 0x100) -#define RK3288_CPU_AXI_CPUP_QOS_VIRT (RK3288_SERVICE_CORE_VIRT + 0x0) -/* service dmac */ -#define RK3288_SERVICE_DMAC_VIRT (RK3288_SERVICE_CORE_VIRT + RK3288_SERVICE_CORE_SIZE) -#define RK3288_CPU_AXI_BUS_DMAC_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x0) -#define RK3288_CPU_AXI_CCP_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x180) -#define RK3288_CPU_AXI_CRYPTO_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x100) -#define RK3288_CPU_AXI_CCS_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x200) -#define RK3288_CPU_AXI_HOST_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x80) -/* service gpu */ -#define RK3288_SERVICE_GPU_VIRT (RK3288_SERVICE_DMAC_VIRT + RK3288_SERVICE_DMAC_SIZE) -#define RK3288_CPU_AXI_GPU_R_QOS_VIRT (RK3288_SERVICE_GPU_VIRT + 0x0) -#define RK3288_CPU_AXI_GPU_W_QOS_VIRT (RK3288_SERVICE_GPU_VIRT + 0x80) -/* service peri */ -#define RK3288_SERVICE_PERI_VIRT (RK3288_SERVICE_GPU_VIRT + RK3288_SERVICE_GPU_SIZE) -#define RK3288_CPU_AXI_PERI_QOS_VIRT (RK3288_SERVICE_PERI_VIRT + 0x0) -/* service bus */ -#define RK3288_SERVICE_BUS_VIRT (RK3288_SERVICE_PERI_VIRT + RK3288_SERVICE_PERI_SIZE) -/* service vio */ -#define RK3288_SERVICE_VIO_VIRT (RK3288_SERVICE_BUS_VIRT + RK3288_SERVICE_BUS_SIZE) -#define RK3288_CPU_AXI_VIO0_IEP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x500) -#define RK3288_CPU_AXI_VIO0_VIP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x480) -#define RK3288_CPU_AXI_VIO0_VOP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x400) -#define RK3288_CPU_AXI_VIO1_ISP_R_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x900) -#define RK3288_CPU_AXI_VIO1_ISP_W0_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x100) -#define RK3288_CPU_AXI_VIO1_ISP_W1_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x180) -#define RK3288_CPU_AXI_VIO1_VOP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x0) -#define RK3288_CPU_AXI_VIO2_RGA_R_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x800) -#define RK3288_CPU_AXI_VIO2_RGA_W_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x880) -/* service video */ -#define RK3288_SERVICE_VIDEO_VIRT (RK3288_SERVICE_VIO_VIRT + RK3288_SERVICE_VIO_SIZE) -#define RK3288_CPU_AXI_VIDEO_QOS_VIRT (RK3288_SERVICE_VIDEO_VIRT + 0x0) -/* service hevc */ -#define RK3288_SERVICE_HEVC_VIRT (RK3288_SERVICE_VIDEO_VIRT + RK3288_SERVICE_VIDEO_SIZE) -#define RK3288_CPU_AXI_HEVC_R_QOS_VIRT (RK3288_SERVICE_HEVC_VIRT + 0x0) -#define RK3288_CPU_AXI_HEVC_W_QOS_VIRT (RK3288_SERVICE_HEVC_VIRT + 0x100) - -#define RK312X_CPU_AXI_QOS_NUM_REGS 4 -#define RK312X_CPU_AXI_SAVE_QOS(array, base) do { \ - array[0] = readl_relaxed(base + CPU_AXI_QOS_PRIORITY); \ - array[1] = readl_relaxed(base + CPU_AXI_QOS_MODE); \ - array[2] = readl_relaxed(base + CPU_AXI_QOS_BANDWIDTH); \ - array[3] = readl_relaxed(base + CPU_AXI_QOS_SATURATION); \ -} while (0) -#define RK312X_CPU_AXI_RESTORE_QOS(array, base) do { \ - writel_relaxed(array[0], base + CPU_AXI_QOS_PRIORITY); \ - writel_relaxed(array[1], base + CPU_AXI_QOS_MODE); \ - writel_relaxed(array[2], base + CPU_AXI_QOS_BANDWIDTH); \ - writel_relaxed(array[3], base + CPU_AXI_QOS_SATURATION); \ -} while (0) -#define RK312X_SERVICE_VIO_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7000) - -#define RK312X_CPU_AXI_VIO_RGA_QOS_VIRT (RK312X_SERVICE_VIO_VIRT) -#define RK312X_CPU_AXI_VIO_EBC_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x80) -#define RK312X_CPU_AXI_VIO_IEP_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x100) -#define RK312X_CPU_AXI_VIO_LCDC0_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x180) -#define RK312X_CPU_AXI_VIO_VIP0_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x200) - -#define RK312X_SERVICE_GPU_VIRT (RK_CPU_AXI_BUS_VIRT + 0x5000) -#define RK312X_CPU_AXI_GPU_QOS_VIRT (RK312X_SERVICE_GPU_VIRT) - -#define RK312X_SERVICE_VIDEO_VIRT (RK_CPU_AXI_BUS_VIRT + 0x6000) -#define RK312X_CPU_AXI_VIDEO_QOS_VIRT (RK312X_SERVICE_VIDEO_VIRT) -#endif