X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fclk%2Frockchip%2Fclk-pll.c;h=d61d2a170496c69e019c9bb2cfa1f95354764934;hb=HEAD;hp=05b40eacaf2f042fd30e2a2afe4700603115e19e;hpb=c98c6d78734dc43dad4ebdca16f5d5470dff7c22;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 05b40eacaf2f..d61d2a170496 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -30,6 +30,7 @@ #define PLL_MODE_SLOW 0x0 #define PLL_MODE_NORM 0x1 #define PLL_MODE_DEEP 0x2 +#define PLL_RK3328_MODE_MASK 0x1 struct rockchip_clk_pll { struct clk_hw hw; @@ -105,9 +106,9 @@ static int rockchip_pll_clk_set_postdiv(unsigned long fout_hz, return 0; } } - pr_err("CANNOT FIND postdiv1/2 to make fout in range from 800M to 2000M,fout = %lu\n", - fout_hz); } + pr_err("CANNOT FIND postdiv1/2 to make fout in range from 800M to 2000M,fout = %lu\n", + fout_hz); } else { *postdiv1 = 1; *postdiv2 = 1; @@ -191,6 +192,7 @@ rockchip_rk3066_pll_clk_set_by_auto(struct rockchip_clk_pll *pll, nr_out = PLL_NR_MAX + 1; no_out = 0; + nf_out = 0; if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz) return NULL; @@ -241,11 +243,9 @@ rockchip_rk3066_pll_clk_set_by_auto(struct rockchip_clk_pll *pll, /* output the best PLL setting */ if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) { - if (rate_table->nr && rate_table->nf && rate_table->no) { - rate_table->nr = nr_out; - rate_table->nf = nf_out; - rate_table->no = no_out; - } + rate_table->nr = nr_out; + rate_table->nf = nf_out; + rate_table->no = no_out; } else { return NULL; } @@ -473,6 +473,7 @@ static int rockchip_rk3036_pll_enable(struct clk_hw *hw) writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0), pll->reg_base + RK3036_PLLCON(1)); + rockchip_pll_wait_lock(pll); return 0; } @@ -718,6 +719,7 @@ static int rockchip_rk3066_pll_enable(struct clk_hw *hw) writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3066_PLLCON(3)); + rockchip_pll_wait_lock(pll); return 0; } @@ -1130,6 +1132,7 @@ static int rockchip_rk3399_pll_enable(struct clk_hw *hw) writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0), pll->reg_base + RK3399_PLLCON(3)); + rockchip_rk3399_pll_wait_lock(pll); return 0; } @@ -1223,7 +1226,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, u8 num_parents, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - u8 clk_pll_flags) + unsigned long flags, u8 clk_pll_flags) { const char *pll_parents[3]; struct clk_init_data init; @@ -1232,7 +1235,8 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, struct clk *pll_clk, *mux_clk; char pll_name[20]; - if (num_parents != 2) { + if ((pll_type != pll_rk3328 && num_parents != 2) || + (pll_type == pll_rk3328 && num_parents != 1)) { pr_err("%s: needs two parent clocks\n", __func__); return ERR_PTR(-EINVAL); } @@ -1249,13 +1253,17 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, pll_mux = &pll->pll_mux; pll_mux->reg = ctx->reg_base + mode_offset; pll_mux->shift = mode_shift; - pll_mux->mask = PLL_MODE_MASK; + if (pll_type == pll_rk3328) + pll_mux->mask = PLL_RK3328_MODE_MASK; + else + pll_mux->mask = PLL_MODE_MASK; pll_mux->flags = 0; pll_mux->lock = &ctx->lock; pll_mux->hw.init = &init; if (pll_type == pll_rk3036 || pll_type == pll_rk3066 || + pll_type == pll_rk3328 || pll_type == pll_rk3366 || pll_type == pll_rk3399) pll_mux->flags |= CLK_MUX_HIWORD_MASK; @@ -1269,7 +1277,10 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, init.flags = CLK_SET_RATE_PARENT; init.ops = pll->pll_mux_ops; init.parent_names = pll_parents; - init.num_parents = ARRAY_SIZE(pll_parents); + if (pll_type == pll_rk3328) + init.num_parents = 2; + else + init.num_parents = ARRAY_SIZE(pll_parents); mux_clk = clk_register(NULL, &pll_mux->hw); if (IS_ERR(mux_clk)) @@ -1279,7 +1290,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, init.name = pll_name; /* keep all plls untouched for now */ - init.flags = CLK_IGNORE_UNUSED; + init.flags = flags | CLK_IGNORE_UNUSED; init.parent_names = &parent_names[0]; init.num_parents = 1; @@ -1303,6 +1314,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, switch (pll_type) { case pll_rk3036: + case pll_rk3328: if (!pll->rate_table) init.ops = &rockchip_rk3036_pll_clk_norate_ops; else