mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user