clk: rk3126b: add support and fix clk_pll_set_rate_3036_apll
authordkl <dkl@rock-chips.com>
Tue, 25 Nov 2014 08:53:24 +0000 (16:53 +0800)
committerdkl <dkl@rock-chips.com>
Wed, 26 Nov 2014 09:08:45 +0000 (17:08 +0800)
arch/arm/boot/dts/rk3126-86v.dts
arch/arm/boot/dts/rk3126-sdk.dts
arch/arm/boot/dts/rk3126-sdk.dtsi [new file with mode: 0755]
arch/arm/boot/dts/rk312x.dtsi
drivers/clk/rockchip/clk-pll.c

index 214f35c7ef7234ab08865600b4deb022928332d6..d145d917c14915be83609794fd331f6ce82868ab 100755 (executable)
@@ -1,4 +1,4 @@
-#include "rk312x-sdk.dtsi"
+#include "rk3126-sdk.dtsi"
 #include "lcd-86v-rgb1024x600.dtsi"
 //#include "lcd-y81349.dtsi"
 
index 81f6ca18d3af61c464724003e5266528c2cb7ddd..3ed08e3c3a6c4c9358f32c14c193e483f94109ea 100755 (executable)
@@ -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 (executable)
index 0000000..24b1f5a
--- /dev/null
@@ -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>;
+};
index 795e112edb1611ec2745f5933954245e39fe2ca1..f9104f2d8986a2d7a2187ac920902182cdb95d72 100755 (executable)
                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>,
index 63f1b295fe405f34d6d4f32e272b63a7f3093f12..40a2f9873e95b9508de5d3b7416711b6402431b0 100755 (executable)
@@ -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;       
 }