clk: rockchip: add clk init data and enable clk init

Mainly add rk3188 clk_core\cpu_clks\peri_clks init data and apply
it.
This commit is contained in:
dkl
2014-01-23 17:23:47 +08:00
parent 247134ec9e
commit 4673090895
4 changed files with 84 additions and 48 deletions

View File

@@ -133,18 +133,21 @@
#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_cpu: clk_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>;
};
@@ -172,6 +175,7 @@
rockchip,flags = <(CLK_GET_RATE_NOCACHE |
CLK_SET_RATE_NO_REPARENT)>;
#clock-cells = <0>;
#clock-init-cells = <1>;
};
clk_core_div: clk_core_div {
@@ -218,6 +222,7 @@
rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
clock-output-names = "hclk_cpu";
#clock-cells = <0>;
#clock-init-cells = <1>;
};
/* reg[11:10]: reserved */
@@ -229,6 +234,7 @@
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 {
@@ -238,6 +244,7 @@
rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
clock-output-names = "pclk_ahb2apb";
#clock-cells = <0>;
#clock-init-cells = <1>;
};
};
@@ -255,6 +262,7 @@
clocks = <&clk_gpll>, <&clk_cpll>;
clock-output-names = "clk_i2s_pll";
#clock-cells = <0>;
#clock-init-cells = <1>;
};
};
@@ -372,6 +380,7 @@
clock-output-names = "aclk_peri";
rockchip,div-type = <CLK_DIVIDER_PLUS_ONE>;
#clock-cells = <0>;
#clock-init-cells = <1>;
};
/* reg[7:5]: reserved */
@@ -383,6 +392,7 @@
clock-output-names = "hclk_peri";
rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
#clock-cells = <0>;
#clock-init-cells = <1>;
};
/* reg[11:10]: reserved */
@@ -394,6 +404,7 @@
clock-output-names = "pclk_peri";
rockchip,div-type = <CLK_DIVIDER_POWER_OF_TWO>;
#clock-cells = <0>;
#clock-init-cells = <1>;
};
/* reg[14]: reserved */
@@ -476,6 +487,7 @@
clocks = <&clk_gpll>, <&clk_cpll>;
clock-output-names = "clk_uart_pll";
#clock-cells = <0>;
#clock-init-cells = <1>;
};
};

View File

@@ -334,15 +334,23 @@
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 792000000>, <&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>;

View 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);

View File

@@ -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);
}
}