]> git.baikalelectronics.ru Git - kernel.git/commitdiff
clk: Ingenic: Adjust cgu code to make it compatible with X1830.
author周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Thu, 28 May 2020 03:15:44 +0000 (11:15 +0800)
committerStephen Boyd <sboyd@kernel.org>
Thu, 28 May 2020 23:13:15 +0000 (16:13 -0700)
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>
drivers/clk/ingenic/cgu.c
drivers/clk/ingenic/cgu.h
drivers/clk/ingenic/jz4725b-cgu.c
drivers/clk/ingenic/jz4740-cgu.c
drivers/clk/ingenic/jz4770-cgu.c
drivers/clk/ingenic/jz4780-cgu.c
drivers/clk/ingenic/x1000-cgu.c

index ab1302ad1450b9deb3f725fe65367b16a9237368..d7981b670221f442535942138fd7f6c727477c0b 100644 (file)
@@ -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);
index 0dc8004079ee24426cc855da459763d0c23d2693..2c75ef4a36f5c9c68a46c04d0b265dd5e7c4dd25 100644 (file)
@@ -17,6 +17,7 @@
 /**
  * struct ingenic_cgu_pll_info - information about a PLL
  * @reg: the offset of the PLL's control register within the CGU
+ * @rate_multiplier: the multiplier needed by pll rate calculation
  * @m_shift: the number of bits to shift the multiplier value by (ie. the
  *           index of the lowest bit of the multiplier value in the PLL's
  *           control register)
@@ -37,6 +38,7 @@
  * @od_encoding: a pointer to an array mapping post-VCO divider values to
  *               their encoded values in the PLL control register, or -1 for
  *               unsupported values
+ * @bypass_reg: the offset of the bypass control register within the CGU
  * @bypass_bit: the index of the bypass bit in the PLL control register
  * @enable_bit: the index of the enable bit in the PLL control register
  * @stable_bit: the index of the stable bit in the PLL control register
  */
 struct ingenic_cgu_pll_info {
        unsigned reg;
+       unsigned rate_multiplier;
        const s8 *od_encoding;
        u8 m_shift, m_bits, m_offset;
        u8 n_shift, n_bits, n_offset;
        u8 od_shift, od_bits, od_max;
+       unsigned bypass_reg;
        u8 bypass_bit;
        u8 enable_bit;
        u8 stable_bit;
index a3b4635f6278463f9afdd4a4ef02f04f50d49e74..8c38e72d14a79919f51569ee226f4b94558f6722 100644 (file)
@@ -9,7 +9,9 @@
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/of.h>
+
 #include <dt-bindings/clock/jz4725b-cgu.h>
+
 #include "cgu.h"
 #include "pm.h"
 
@@ -54,6 +56,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
                .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
                .pll = {
                        .reg = CGU_REG_CPPCR,
+                       .rate_multiplier = 1,
                        .m_shift = 23,
                        .m_bits = 9,
                        .m_offset = 2,
@@ -65,6 +68,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
                        .od_max = 4,
                        .od_encoding = pll_od_encoding,
                        .stable_bit = 10,
+                       .bypass_reg = CGU_REG_CPPCR,
                        .bypass_bit = 9,
                        .enable_bit = 8,
                },
index 4f0e92c877d65057850d2f81f5736a51634ec33a..c0ac9196a5819b94ff2b1b97b18bcaf893114334 100644 (file)
@@ -10,7 +10,9 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
+
 #include <dt-bindings/clock/jz4740-cgu.h>
+
 #include "cgu.h"
 #include "pm.h"
 
@@ -69,6 +71,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
                .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
                .pll = {
                        .reg = CGU_REG_CPPCR,
+                       .rate_multiplier = 1,
                        .m_shift = 23,
                        .m_bits = 9,
                        .m_offset = 2,
@@ -80,6 +83,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
                        .od_max = 4,
                        .od_encoding = pll_od_encoding,
                        .stable_bit = 10,
+                       .bypass_reg = CGU_REG_CPPCR,
                        .bypass_bit = 9,
                        .enable_bit = 8,
                },
index c051ecba5cf8e7079c7811d8b7b98e1d7502696b..9ea4490ecb7f181e23e6f02976fd3eff16d1177e 100644 (file)
@@ -9,7 +9,9 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
+
 #include <dt-bindings/clock/jz4770-cgu.h>
+
 #include "cgu.h"
 #include "pm.h"
 
@@ -102,6 +104,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
                .parents = { JZ4770_CLK_EXT },
                .pll = {
                        .reg = CGU_REG_CPPCR0,
+                       .rate_multiplier = 1,
                        .m_shift = 24,
                        .m_bits = 7,
                        .m_offset = 1,
@@ -112,6 +115,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
                        .od_bits = 2,
                        .od_max = 8,
                        .od_encoding = pll_od_encoding,
+                       .bypass_reg = CGU_REG_CPPCR0,
                        .bypass_bit = 9,
                        .enable_bit = 8,
                        .stable_bit = 10,
@@ -124,6 +128,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
                .parents = { JZ4770_CLK_EXT },
                .pll = {
                        .reg = CGU_REG_CPPCR1,
+                       .rate_multiplier = 1,
                        .m_shift = 24,
                        .m_bits = 7,
                        .m_offset = 1,
@@ -134,9 +139,10 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
                        .od_bits = 2,
                        .od_max = 8,
                        .od_encoding = pll_od_encoding,
+                       .bypass_reg = CGU_REG_CPPCR1,
+                       .no_bypass_bit = true,
                        .enable_bit = 7,
                        .stable_bit = 6,
-                       .no_bypass_bit = true,
                },
        },
 
index c758f16430677a22c75399774b3520e3d6e04765..6c5b8029cc8ab615e60241fc3ac01aa0e77a30e7 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 
 #include <dt-bindings/clock/jz4780-cgu.h>
+
 #include "cgu.h"
 #include "pm.h"
 
@@ -266,6 +267,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
 
 #define DEF_PLL(name) { \
        .reg = CGU_REG_ ## name, \
+       .rate_multiplier = 1, \
        .m_shift = 19, \
        .m_bits = 13, \
        .m_offset = 1, \
@@ -277,6 +279,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
        .od_max = 16, \
        .od_encoding = pll_od_encoding, \
        .stable_bit = 6, \
+       .bypass_reg = CGU_REG_ ## name, \
        .bypass_bit = 1, \
        .enable_bit = 0, \
 }
index b22d87b3f555bfcf19f66abd757eb57a576ae657..c33934d8ac14deb7a03f5e3435c824904d9f939d 100644 (file)
@@ -7,7 +7,9 @@
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/of.h>
+
 #include <dt-bindings/clock/x1000-cgu.h>
+
 #include "cgu.h"
 #include "pm.h"
 
@@ -58,6 +60,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
                .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
                .pll = {
                        .reg = CGU_REG_APLL,
+                       .rate_multiplier = 1,
                        .m_shift = 24,
                        .m_bits = 7,
                        .m_offset = 1,
@@ -68,6 +71,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
                        .od_bits = 2,
                        .od_max = 8,
                        .od_encoding = pll_od_encoding,
+                       .bypass_reg = CGU_REG_APLL,
                        .bypass_bit = 9,
                        .enable_bit = 8,
                        .stable_bit = 10,
@@ -79,6 +83,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
                .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
                .pll = {
                        .reg = CGU_REG_MPLL,
+                       .rate_multiplier = 1,
                        .m_shift = 24,
                        .m_bits = 7,
                        .m_offset = 1,
@@ -89,6 +94,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
                        .od_bits = 2,
                        .od_max = 8,
                        .od_encoding = pll_od_encoding,
+                       .bypass_reg = CGU_REG_MPLL,
                        .bypass_bit = 6,
                        .enable_bit = 7,
                        .stable_bit = 0,