aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/ingenic/cgu.c
diff options
context:
space:
mode:
author周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>2020-05-28 11:15:44 +0800
committerStephen Boyd <sboyd@kernel.org>2020-05-28 16:13:15 -0700
commit9d9cc58aff468c1589df09ac12e4e79b1eaba6db (patch)
tree80a1b469fa7564e180458cb9c6d732f9753441ae /drivers/clk/ingenic/cgu.c
parentclk: Ingenic: Remove unnecessary spinlock when reading registers. (diff)
downloadlinux-dev-9d9cc58aff468c1589df09ac12e4e79b1eaba6db.tar.xz
linux-dev-9d9cc58aff468c1589df09ac12e4e79b1eaba6db.zip
clk: Ingenic: Adjust cgu code to make it compatible with X1830.
The PLL of X1830 Soc from Ingenic has been greatly changed, the bypass control is placed in another register, so now two registers may needed to control the PLL. To this end, a new "bypass_reg" was introduced. In addition, when calculating rate, the PLL of X1830 introduced an extra 2x multiplier, so a new "rate_multiplier" was introduced. And adjust the code in jz47xx-cgu.c and x1000-cgu.c, make it to be compatible with the new cgu code. Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com> Reviewed-by: Paul Cercueil <paul@crapouillou.net> Link: https://lkml.kernel.org/r/20200528031549.13846-3-zhouyanjie@wanyeetech.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/ingenic/cgu.c')
-rw-r--r--drivers/clk/ingenic/cgu.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index ab1302ad1450..d7981b670221 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -90,6 +90,9 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
n += pll_info->n_offset;
od_enc = ctl >> pll_info->od_shift;
od_enc &= GENMASK(pll_info->od_bits - 1, 0);
+
+ ctl = readl(cgu->base + pll_info->bypass_reg);
+
bypass = !pll_info->no_bypass_bit &&
!!(ctl & BIT(pll_info->bypass_bit));
@@ -103,7 +106,8 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
BUG_ON(od == pll_info->od_max);
od++;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static unsigned long
@@ -136,7 +140,8 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
if (pod)
*pod = od;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static inline const struct ingenic_cgu_clk_info *to_clk_info(
@@ -209,9 +214,14 @@ static int ingenic_pll_enable(struct clk_hw *hw)
u32 ctl;
spin_lock_irqsave(&cgu->lock, flags);
- ctl = readl(cgu->base + pll_info->reg);
+ ctl = readl(cgu->base + pll_info->bypass_reg);
ctl &= ~BIT(pll_info->bypass_bit);
+
+ writel(ctl, cgu->base + pll_info->bypass_reg);
+
+ ctl = readl(cgu->base + pll_info->reg);
+
ctl |= BIT(pll_info->enable_bit);
writel(ctl, cgu->base + pll_info->reg);