Recommit "clk: rockchip: add clk init data and enable clk init"
authordkl <dkl@rock-chips.com>
Fri, 7 Feb 2014 01:50:53 +0000 (09:50 +0800)
committerdkl <dkl@rock-chips.com>
Fri, 7 Feb 2014 01:50:53 +0000 (09:50 +0800)
This recommit commit 4673090895385ded057a23dcbdfff2ebe1f80f1b with
fix that lower clk_core init rate to 594 MHZ.

arch/arm/boot/dts/rk3188-clocks.dtsi
arch/arm/boot/dts/rk3188.dtsi
drivers/clk/rockchip/clk-pll.c
drivers/clk/rockchip/clk.c

index 807503d41ae79cb309508dbb8222193bc6e3c67c..441cfa75abd86daee05b9b831f22018c7b371374 100755 (executable)
                                        #address-cells = <1>;
                                        #size-cells = <1>;
 
-                                       aclk_cpu_div: aclk_cpu_div {
+                                       aclk_cpu: aclk_cpu_div {
                                                compatible = "rockchip,rk3188-div-con";
                                                rockchip,bits = <0 5>;
-                                               clocks = <&aclk_cpu>;
+                                               clocks = <&aclk_cpu_mux>;
+                                               clock-output-names = "aclk_cpu";
+                                               #clock-cells = <0>;
                                                rockchip,div-type = <CLK_DIVIDER_PLUS_ONE>;
+                                               #clock-init-cells = <1>;
                                        };
 
-                                       aclk_cpuclk_cpu_mux {
+                                       aclk_cpu_mux: aclk_cpu_mux {
                                                compatible = "rockchip,rk3188-mux-con";
                                                rockchip,bits = <5 1>;
-                                               clocks = <&clk_apll>, <&clk_gpll>;
-                                               clock-output-names = "aclk_cpu";
+                                               clocks = <&clk_apll>, <&clk_gpll>;/*FIXME*/
+                                               clock-output-names = "aclk_cpu_mux";
                                                #clock-cells = <0>;
                                                #clock-init-cells = <1>;
                                        };
                                                rockchip,flags = <(CLK_GET_RATE_NOCACHE |
                                                                        CLK_SET_RATE_NO_REPARENT)>;
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
 
                                        clk_core_div: clk_core_div {
                                                rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
                                                clock-output-names = "hclk_cpu";
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
 
                                        /* reg[11:10]: reserved */
                                                rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
                                                clock-output-names = "pclk_cpu";
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
 
                                        pclk_ahb2apb: pclk_ahb2apb_div {
                                                rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
                                                clock-output-names = "pclk_ahb2apb";
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
 
                                };
                                                clocks = <&clk_gpll>, <&clk_cpll>;
                                                clock-output-names = "clk_i2s_pll";
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
                                };
 
                                                clock-output-names = "aclk_peri";
                                                rockchip,div-type = <CLK_DIVIDER_PLUS_ONE>;
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
 
                                        /* reg[7:5]: reserved */
                                                clock-output-names = "hclk_peri";
                                                rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
 
                                        /* reg[11:10]: reserved */
                                                clock-output-names = "pclk_peri";
                                                rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
 
                                        /* reg[14]: reserved */
                                                clocks = <&clk_gpll>, <&clk_cpll>;
                                                clock-output-names = "clk_uart_pll";
                                                #clock-cells = <0>;
+                                               #clock-init-cells = <1>;
                                        };
                                };
 
index 3878e073ab2733750ff1b335ce5058405d953da2..bbc3462b07f561c2d08250d05b05ee522bcda20b 100755 (executable)
 
        clocks-init{
                compatible = "rockchip,clocks-init";
-               rockchip,clocks-init-rate =<&clk_cpll 768000000>,<&clk_gpll 594000000>;
-               rockchip,clocks-init-parent =<&aclk_peri_mux &clk_gpll>,<&aclk_cpu &clk_gpll>;
+               rockchip,clocks-init-parent =
+                       <&clk_core &clk_apll>,  <&aclk_cpu_mux &clk_gpll>,/*FIXME*/
+                       <&aclk_peri_mux &clk_gpll>,     <&clk_i2s_pll_mux &clk_cpll>,
+                       <&clk_uart_pll_mux &clk_gpll>;
+               rockchip,clocks-init-rate =
+                       <&clk_core 594000000>,  <&clk_gpll 768000000>,
+                       <&clk_cpll 594000000>,  <&aclk_cpu 192000000>,
+                       <&hclk_cpu 96000000>,   <&pclk_cpu 48000000>,
+                       <&pclk_ahb2apb 48000000>,       <&aclk_peri 192000000>,
+                       <&hclk_peri 96000000>,  <&pclk_peri 48000000>;
        };
 
        fb: fb{
                compatible = "rockchip,rk-fb";
                rockchip,disp-mode = <DUAL>;
        };
-       
+
        lcdc0:lcdc@1010c000 {
                compatible = "rockchip,rk3188-lcdc";
                rockchip,prop = <PRMRY>;
index eafc7cec0d28b6b3edf3731561628d5a13f3b047..dba8f386e367998bf6f5723c90a017b052e57fbe 100644 (file)
@@ -369,6 +369,11 @@ static int clk_apll_set_rate(struct clk_hw *hw, unsigned long rate,
                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);
@@ -381,6 +386,7 @@ static int clk_apll_set_rate(struct clk_hw *hw, unsigned long rate,
                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));
@@ -390,8 +396,8 @@ static int clk_apll_set_rate(struct clk_hw *hw, unsigned long rate,
                                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);
+               //clk_disable(arm_gpll);
+               //clk_unprepare(arm_gpll);
                goto CHANGE_APLL;
        }
 
@@ -425,7 +431,7 @@ CHANGE_APLL:
         * before power down
         */
        //FIXME
-       //if(!sel_gpll)
+       //if (!sel_gpll)
        cru_writel(PLL_MODE_SLOW(pll->id), CRU_MODE_CON);
 
        /* PLL power down */
@@ -456,7 +462,7 @@ CHANGE_APLL:
 
        /* PLL return from slow mode */
        //FIXME
-       //if(!sel_gpll)
+       //if (!sel_gpll)
        cru_writel(PLL_MODE_NORM(pll->id), CRU_MODE_CON);
 
        /* reparent to apll, and set div to 1 */
@@ -477,8 +483,8 @@ CHANGE_APLL:
 
        if (sel_gpll) {
                sel_gpll = 0;
-               clk_disable(arm_gpll);
-               clk_unprepare(arm_gpll);
+               //clk_disable(arm_gpll);
+               //clk_unprepare(arm_gpll);
        }
 
        //clk_debug("apll set loops_per_jiffy =%lu\n", loops_per_jiffy);
index ffa95223b40eda18228e890f0f16803d1794bb87..79cb6a7370097113ed35a6670b7975b2924be197 100755 (executable)
@@ -51,7 +51,7 @@ struct rkclk_muxinfo {
        u32             width;
        u32             parent_num;
        u32             clkops_idx;
-       u32             flags;
+       //u8            mux_flags;
        const char      *clk_name;
        const char      **parent_names;
        struct list_head        node;
@@ -95,6 +95,7 @@ struct rkclk_pllinfo {
 struct rkclk {
        const char      *clk_name;
        u32             clk_type;
+       u32             flags;
        /*
         * store nodes creat this rkclk
         * */
@@ -123,10 +124,15 @@ static int rkclk_init_muxinfo(struct device_node *np,
        int cnt, i, ret = 0;
        u8 found = 0;
        struct rkclk *rkclk;
+       u32 flags;
 
        mux = kzalloc(sizeof(struct rkclk_muxinfo), GFP_KERNEL);
        if (!mux)
                return -ENOMEM;
+
+       ret = of_property_read_u32(np, "rockchip,flags", &flags);
+       if (ret != 0)
+               flags = 0;
        /*
         * Get control bit addr
         */
@@ -134,10 +140,6 @@ static int rkclk_init_muxinfo(struct device_node *np,
        if (ret != 0)
                return -EINVAL;
 
-       ret = of_property_read_u32(np, "rockchip,flags", &mux->flags);
-       if (ret != 0)
-               mux->flags = 0;
-
        ret = of_property_read_u32(np, "rockchip,clkops-idx", &mux->clkops_idx);
        if (ret != 0)
                mux->clkops_idx = CLKOPS_TABLE_END;
@@ -177,6 +179,7 @@ static int rkclk_init_muxinfo(struct device_node *np,
                        found = 1;
                        rkclk->mux_info = mux;
                        rkclk->clk_type |= RKCLK_MUX_TYPE;
+                       rkclk->flags |= flags;
                        break;
                }
        }
@@ -184,7 +187,8 @@ static int rkclk_init_muxinfo(struct device_node *np,
                rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
                rkclk->clk_name = mux->clk_name;
                rkclk->mux_info = mux;
-               rkclk->clk_type |= RKCLK_MUX_TYPE;
+               rkclk->clk_type = RKCLK_MUX_TYPE;
+               rkclk->flags = flags;
                rkclk->np = np;
                clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
 
@@ -319,6 +323,7 @@ static int rkclk_init_fracinfo(struct device_node *np,
                        found = 1;
                        rkclk->frac_info = frac;
                        rkclk->clk_type |= RKCLK_FRAC_TYPE;
+                       rkclk->flags |= CLK_SET_RATE_PARENT;
                        break;
                }
        }
@@ -326,7 +331,8 @@ static int rkclk_init_fracinfo(struct device_node *np,
                rkclk = kzalloc(sizeof(struct rkclk), GFP_KERNEL);
                rkclk->clk_name = frac->clk_name;
                rkclk->frac_info = frac;
-               rkclk->clk_type |= RKCLK_FRAC_TYPE;
+               rkclk->clk_type = RKCLK_FRAC_TYPE;
+               rkclk->flags = CLK_SET_RATE_PARENT;
                rkclk->np = np;
                clk_debug("%s: creat %s\n", __func__, rkclk->clk_name);
 
@@ -577,7 +583,6 @@ static int rkclk_register(struct rkclk *rkclk)
        struct clk_hw           *rate_hw;
        int                     parent_num;
        struct device_node      *node = rkclk->np;
-       unsigned long           flags = 0;
 
 
        clk_debug("%s >>>>>start: clk_name=%s, clk_type=%x\n",
@@ -608,8 +613,6 @@ static int rkclk_register(struct rkclk *rkclk)
                parent_num = 1;
                parent_names = &rkclk->frac_info->parent_name;
 
-               flags |= CLK_SET_RATE_PARENT;
-
        } else if (rkclk->clk_type & RKCLK_DIV_TYPE) {
                div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
                if (rkclk->div_info->clkops_idx != CLKOPS_TABLE_END)
@@ -648,7 +651,6 @@ static int rkclk_register(struct rkclk *rkclk)
 
                parent_num = rkclk->mux_info->parent_num;
                parent_names = rkclk->mux_info->parent_names;
-               flags |= rkclk->mux_info->flags;
        }
 
        if (rkclk->clk_type & RKCLK_GATE_TYPE) {
@@ -666,26 +668,26 @@ static int rkclk_register(struct rkclk *rkclk)
                clk = clk_register_mux(NULL, rkclk->clk_name,
                                rkclk->mux_info->parent_names,
                                (u8)rkclk->mux_info->parent_num,
-                               flags, mux->reg, mux->shift, mux->mask,
-                               0, &clk_lock);
+                               rkclk->flags, mux->reg, mux->shift, mux->mask,
+                               mux->flags, &clk_lock);
        } else if (rkclk->clk_type == RKCLK_DIV_TYPE) {
                clk_debug("use clk_register_divider\n");
                clk = clk_register_divider(NULL, rkclk->clk_name,
                                rkclk->div_info->parent_name,
-                               flags, div->reg, div->shift,
+                               rkclk->flags, div->reg, div->shift,
                                div->width, div->flags, &clk_lock);
        } else if (rkclk->clk_type == RKCLK_GATE_TYPE) {
                clk_debug("use clk_register_gate\n");
                clk = clk_register_gate(NULL, rkclk->clk_name,
                                rkclk->gate_info->parent_name,
-                               flags, gate->reg,
+                               rkclk->flags, gate->reg,
                                gate->bit_idx,
                                gate->flags, &clk_lock);
        } else if (rkclk->clk_type == 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,
-                               flags, pll->reg, pll->width,
+                               rkclk->flags, pll->reg, pll->width,
                                pll->id, &clk_lock);
        } else {
                clk_debug("use clk_register_composite\n");
@@ -694,7 +696,7 @@ static int rkclk_register(struct rkclk *rkclk)
                                mux ? &mux->hw : NULL, mux ? mux_ops : NULL,
                                rate_hw, rate_ops,
                                gate ? &gate->hw : NULL, gate ? &clk_gate_ops : NULL,
-                               flags);
+                               rkclk->flags);
        }
 
        if (clk) {
@@ -761,6 +763,10 @@ struct test_table t_table[] = {
        {.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)
@@ -834,9 +840,8 @@ static void __init rk_clk_tree_init(struct device_node *np)
        struct rkclk *rkclk;
 
        node_init=of_find_node_by_name(NULL,"clocks-init");
-       if(!node_init)
-       {
-               printk("%s:can not get  clocks-init node\n",__FUNCTION__);
+       if (!node_init) {
+               clk_err("%s:can not get clocks-init node\n",__FUNCTION__);
                return;
        }
 
@@ -1028,15 +1033,13 @@ void rkclk_init_clks(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;
+       struct clk *clk_p, *clk_c;
+       const char *clk_name, *clk_parent_name;
 
 
        cnt_parent = of_count_phandle_with_args(np, "rockchip,clocks-init-parent", "#clock-init-cells");
 
-       printk("%s:cnt_parent =%d\n",__FUNCTION__,cnt_parent);
-
+       clk_debug("%s:cnt_parent =%d\n",__FUNCTION__,cnt_parent);
 
        for (i = 0; i < cnt_parent; i++) {
                clk_parent_name=NULL;
@@ -1048,30 +1051,37 @@ void rkclk_init_clks(struct device_node *np)
                clk_c=clk_get(NULL,clk_name);
                clk_p=clk_get(NULL,clk_parent_name);
 
-               printk("%s: set parent %s=%x,%s=%x\n",__FUNCTION__,clk_name,(u32)clk_c,clk_parent_name,(u32)clk_p);
                if(IS_ERR(clk_c)||IS_ERR(clk_p))
                        continue;
-               //clk_set_parent(clk_name, clk_parent_name);
+
+               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:rate cnt=%d\n",__FUNCTION__,cnt_rate);
+       clk_debug("%s:rate cnt=%d\n",__FUNCTION__,cnt_rate);
 
        for (i = 0; i < cnt_rate; i++) {
-               clk_name=of_clk_init_rate_get_info(np, i,&clk_rate);
+               clk_name=of_clk_init_rate_get_info(np, i, &clk_rate);
 
                if(clk_name==NULL)
                        continue;
 
-               clk_p=clk_get(NULL,clk_name);
+               clk_c = clk_get(NULL, clk_name);
 
-               printk("%s: set rate %s=%x,rate=%d\n",__FUNCTION__,clk_name,(u32)clk_p,clk_rate);
-
-               if(IS_ERR(clk_c)||(clk_rate<1*1000*1000)||(clk_rate>2000*1000*1000))
+               if(IS_ERR(clk_c))
                        continue;
-               //clk_set_rate(clk_p,clk_rate);
 
+               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);
        }
 
 }