From 8291ffea4b5d0b6bd3bd1df1c9099558890d615e Mon Sep 17 00:00:00 2001 From: dkl Date: Tue, 25 Nov 2014 16:53:24 +0800 Subject: [PATCH] clk: rk3126b: add support and fix clk_pll_set_rate_3036_apll --- arch/arm/boot/dts/rk3126-86v.dts | 2 +- arch/arm/boot/dts/rk3126-sdk.dts | 2 +- arch/arm/boot/dts/rk3126-sdk.dtsi | 26 ++++++++ arch/arm/boot/dts/rk312x.dtsi | 2 +- drivers/clk/rockchip/clk-pll.c | 101 +++++++++++++++++++----------- 5 files changed, 92 insertions(+), 41 deletions(-) create mode 100755 arch/arm/boot/dts/rk3126-sdk.dtsi diff --git a/arch/arm/boot/dts/rk3126-86v.dts b/arch/arm/boot/dts/rk3126-86v.dts index 214f35c7ef72..d145d917c149 100755 --- a/arch/arm/boot/dts/rk3126-86v.dts +++ b/arch/arm/boot/dts/rk3126-86v.dts @@ -1,4 +1,4 @@ -#include "rk312x-sdk.dtsi" +#include "rk3126-sdk.dtsi" #include "lcd-86v-rgb1024x600.dtsi" //#include "lcd-y81349.dtsi" diff --git a/arch/arm/boot/dts/rk3126-sdk.dts b/arch/arm/boot/dts/rk3126-sdk.dts index 81f6ca18d3af..3ed08e3c3a6c 100755 --- a/arch/arm/boot/dts/rk3126-sdk.dts +++ b/arch/arm/boot/dts/rk3126-sdk.dts @@ -1,4 +1,4 @@ -#include "rk312x-sdk.dtsi" +#include "rk3126-sdk.dtsi" #include "lcd-b101ew05.dtsi" / { diff --git a/arch/arm/boot/dts/rk3126-sdk.dtsi b/arch/arm/boot/dts/rk3126-sdk.dtsi new file mode 100755 index 000000000000..24b1f5afa85c --- /dev/null +++ b/arch/arm/boot/dts/rk3126-sdk.dtsi @@ -0,0 +1,26 @@ +#include "rk312x-sdk.dtsi" + +&clk_gpll_div2 { + clocks = <&dummy>; +}; + +&clk_gpll_div3 { + clocks = <&dummy>; +}; + +&rockchip_clocks_init { + rockchip,clocks-init-parent = + <&clk_core &clk_apll>, <&aclk_cpu &clk_gpll>, + <&aclk_peri &clk_gpll>, <&clk_uart0_pll &clk_gpll>, + <&clk_uart2_pll &clk_gpll>, <&clk_i2s_2ch_pll &clk_gpll>, + <&clk_i2s_8ch_pll &clk_gpll>, <&clk_spdif_pll &clk_gpll>, + <&clk_vepu &clk_gpll>, <&clk_vdpu &clk_gpll>, + <&clk_hevc_core &clk_gpll>, <&aclk_vio0_pre &clk_gpll>, + <&aclk_vio1_pre &clk_gpll>, <&hclk_vio_pre &clk_gpll>, + <&sclk_lcdc0 &clk_cpll>, <&clk_gpu &clk_gpll>, + <&clk_cif_pll &clk_gpll>, <&dclk_ebc &clk_gpll>, + <&clk_emmc &clk_gpll>, <&clk_sdio &clk_gpll>, + <&clk_sfc &clk_gpll>, <&clk_sdmmc0 &clk_gpll>, + <&clk_tsp &clk_gpll>, <&clk_nandc &clk_gpll>, + <&clk_mac_pll &clk_cpll>; +}; diff --git a/arch/arm/boot/dts/rk312x.dtsi b/arch/arm/boot/dts/rk312x.dtsi index 795e112edb16..f9104f2d8986 100755 --- a/arch/arm/boot/dts/rk312x.dtsi +++ b/arch/arm/boot/dts/rk312x.dtsi @@ -271,7 +271,7 @@ status = "disabled"; }; - clocks-init{ + rockchip_clocks_init: clocks-init{ compatible = "rockchip,clocks-init"; rockchip,clocks-init-parent = <&clk_core &clk_apll>, <&aclk_cpu &clk_gpll_div2>, diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 63f1b295fe40..40a2f9873e95 100755 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -1718,9 +1718,11 @@ 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); - unsigned long flags; - u32 refdiv, fbdiv, postdiv1, postdiv2, frac; 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) { @@ -1729,50 +1731,73 @@ static int clk_pll_set_rate_3036_apll(struct clk_hw *hw, unsigned long rate, ps++; } - clk_debug("%s %lu\n", __func__, rate); + 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))); - if (ps->rate == rate) { - clk_debug("apll get a rate\n"); - - local_irq_save(flags); - /************select gpll_div2******************/ - cru_writel(RK3036_CORE_SEL_PLL(1), RK3036_CRU_CLKSELS_CON(0)); - /**************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)); + + /*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)); - - 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);*/ - loops_per_jiffy = ps->lpj; - local_irq_restore(flags); - } else { - /*FIXME*/ - rk3036_pll_clk_get_set(parent_rate, rate, &refdiv, &fbdiv, &postdiv1, &postdiv2, &frac); - rk3036_pll_set_con(hw, refdiv, fbdiv, postdiv1, postdiv2, frac); } - clk_debug("setting OK\n"); + + loops_per_jiffy = ps->lpj; + local_irq_restore(flags); return 0; } -- 2.34.1