aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/rockchip/clk-pll.c50
-rw-r--r--drivers/clk/rockchip/clk.h6
2 files changed, 56 insertions, 0 deletions
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 1bb68910a76b..f8d3baf275b2 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -258,6 +258,55 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
258 return !(pllcon & RK3066_PLLCON3_PWRDOWN); 258 return !(pllcon & RK3066_PLLCON3_PWRDOWN);
259} 259}
260 260
261static void rockchip_rk3066_pll_init(struct clk_hw *hw)
262{
263 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
264 const struct rockchip_pll_rate_table *rate;
265 unsigned int nf, nr, no, bwadj;
266 unsigned long drate;
267 u32 pllcon;
268
269 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
270 return;
271
272 drate = __clk_get_rate(hw->clk);
273 rate = rockchip_get_pll_settings(pll, drate);
274
275 /* when no rate setting for the current rate, rely on clk_set_rate */
276 if (!rate)
277 return;
278
279 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
280 nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
281 no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
282
283 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
284 nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
285
286 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
287 bwadj = (pllcon >> RK3066_PLLCON2_BWADJ_SHIFT) & RK3066_PLLCON2_BWADJ_MASK;
288
289 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), bwadj(%d:%d)\n",
290 __func__, __clk_get_name(hw->clk), drate, rate->nr, nr,
291 rate->no, no, rate->nf, nf, rate->bwadj, bwadj);
292 if (rate->nr != nr || rate->no != no || rate->nf != nf
293 || rate->bwadj != bwadj) {
294 struct clk *parent = __clk_get_parent(hw->clk);
295 unsigned long prate;
296
297 if (!parent) {
298 pr_warn("%s: parent of %s not available\n",
299 __func__, __clk_get_name(hw->clk));
300 return;
301 }
302
303 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
304 __func__, __clk_get_name(hw->clk));
305 prate = __clk_get_rate(parent);
306 rockchip_rk3066_pll_set_rate(hw, drate, prate);
307 }
308}
309
261static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { 310static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
262 .recalc_rate = rockchip_rk3066_pll_recalc_rate, 311 .recalc_rate = rockchip_rk3066_pll_recalc_rate,
263 .enable = rockchip_rk3066_pll_enable, 312 .enable = rockchip_rk3066_pll_enable,
@@ -272,6 +321,7 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
272 .enable = rockchip_rk3066_pll_enable, 321 .enable = rockchip_rk3066_pll_enable,
273 .disable = rockchip_rk3066_pll_disable, 322 .disable = rockchip_rk3066_pll_disable,
274 .is_enabled = rockchip_rk3066_pll_is_enabled, 323 .is_enabled = rockchip_rk3066_pll_is_enabled,
324 .init = rockchip_rk3066_pll_init,
275}; 325};
276 326
277/* 327/*
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index eefd39a3820b..dc9468132ef1 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -92,6 +92,10 @@ struct rockchip_pll_rate_table {
92 * @type: Type of PLL to be registered. 92 * @type: Type of PLL to be registered.
93 * @pll_flags: hardware-specific flags 93 * @pll_flags: hardware-specific flags
94 * @rate_table: Table of usable pll rates 94 * @rate_table: Table of usable pll rates
95 *
96 * Flags:
97 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
98 * rate_table parameters and ajust them if necessary.
95 */ 99 */
96struct rockchip_pll_clock { 100struct rockchip_pll_clock {
97 unsigned int id; 101 unsigned int id;
@@ -108,6 +112,8 @@ struct rockchip_pll_clock {
108 struct rockchip_pll_rate_table *rate_table; 112 struct rockchip_pll_rate_table *rate_table;
109}; 113};
110 114
115#define ROCKCHIP_PLL_SYNC_RATE BIT(0)
116
111#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ 117#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \
112 _lshift, _pflags, _rtable) \ 118 _lshift, _pflags, _rtable) \
113 { \ 119 { \