Data needed for CPU-gear change (cpufreq).

Note:
At this moment, some clock data for Pro5/Pxs2 (32bit SoCs) are
a bit faked because clock rates greater than LONG_MAX (~2.15 GHz)
must be avoided on 32 bit systems.

Signed-off-by: Masahiro Yamada <[email protected]>
---

I raised a flag in the following post:
https://www.spinics.net/lists/kernel/msg2361374.html

I have not had any comments.
Anyway, I am moving forward.
I can fix the data arrays to reflect the real
clock topology.


 drivers/clk/uniphier/clk-uniphier-sys.c | 111 ++++++++++++++++++++++++++++++++
 drivers/clk/uniphier/clk-uniphier.h     |  35 +++++++++-
 2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c 
b/drivers/clk/uniphier/clk-uniphier-sys.c
index 5d02999..74ab179 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -41,6 +41,19 @@
 #define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch)                            \
        UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch))
 
+#define UNIPHIER_PRO5_SYS_CPUGEARS                                     \
+       UNIPHIER_CLK_DIV8("cpll", 2, 3, 4, 6, 8, 12, 16, 24),           \
+       UNIPHIER_CLK_DIV8("spll", 2, 3, 4, 6, 8, 12, 16, 24),           \
+       UNIPHIER_CLK_DIV8("ippll", 2, 3, 4, 6, 8, 12, 16, 24),          \
+       UNIPHIER_CLK_CPUGEAR("cpu-ca9", 32, 0x8000, 0x1f, 16,           \
+                            "cpll/2", "spll/2", "cpll/3", "spll/3",    \
+                            "cpll/4", "spll/4", "cpll/6", "spll/6",    \
+                            "cpll/8", "spll/8", "cpll/12", "spll/12",  \
+                            "cpll/16", "spll/16", "cpll/24", "spll/24"),\
+       UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8,             \
+                            "ippll/2", "spll/2", "ippll/3", "spll/3",  \
+                            "spll/4", "spll/8", "ippll/4", "ippll/8")
+
 const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = {
        UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1),          /* 1597.44 MHz 
*/
        UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512),      /* 288 MHz */
@@ -96,6 +109,8 @@
 };
 
 const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = {
+       UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 140, 1),         /* 2800 MHz */
+       UNIPHIER_CLK_FACTOR("ippll", -1, "ref", 130, 1),        /* 2600 MHz */
        UNIPHIER_CLK_FACTOR("spll", -1, "ref", 120, 1),         /* 2400 MHz */
        UNIPHIER_CLK_FACTOR("dapll1", -1, "ref", 128, 1),       /* 2560 MHz */
        UNIPHIER_CLK_FACTOR("dapll2", -1, "ref", 144, 125),     /* 2949.12 MHz 
*/
@@ -106,10 +121,43 @@
        UNIPHIER_PRO4_SYS_CLK_GIO(12),                          /* PCIe, USB3 */
        UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
        UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
+#if 1
+       /*
+        * TODO:
+        * The return type of .round_rate() is "long", which is 32 bit wide on
+        * 32 bit systems.  Clock rate greater than LONG_MAX (~ 2.15 GHz) is
+        * treated as an error.  Needs a workaround until the problem is fixed.
+        */
+       UNIPHIER_CLK_FACTOR("cpll/2", -1, "ref", 70, 1),
+       UNIPHIER_CLK_FACTOR("cpll/3", -1, "ref", 140, 3),
+       UNIPHIER_CLK_FACTOR("cpll/4", -1, "ref", 35, 1),
+       UNIPHIER_CLK_FACTOR("cpll/6", -1, "ref", 70, 3),
+       UNIPHIER_CLK_FACTOR("cpll/8", -1, "ref", 35, 2),
+       UNIPHIER_CLK_FACTOR("cpll/12", -1, "ref", 35, 3),
+       UNIPHIER_CLK_FACTOR("cpll/16", -1, "ref", 35, 4),
+       UNIPHIER_CLK_FACTOR("cpll/24", -1, "ref", 35, 6),
+       UNIPHIER_CLK_FACTOR("spll/2", -1, "ref", 60, 1),
+       UNIPHIER_CLK_FACTOR("spll/3", -1, "ref", 40, 1),
+       UNIPHIER_CLK_FACTOR("spll/4", -1, "ref", 30, 1),
+       UNIPHIER_CLK_FACTOR("spll/6", -1, "ref", 20, 1),
+       UNIPHIER_CLK_FACTOR("spll/8", -1, "ref", 15, 1),
+       UNIPHIER_CLK_FACTOR("spll/12", -1, "ref", 10, 1),
+       UNIPHIER_CLK_FACTOR("spll/16", -1, "ref", 15, 2),
+       UNIPHIER_CLK_FACTOR("spll/24", -1, "ref", 5, 1),
+       UNIPHIER_CLK_CPUGEAR("cpu-ca9", 32, 0x8000, 0x1f, 16,
+                            "cpll/2", "spll/2", "cpll/3", "spll/3",
+                            "cpll/4", "spll/4", "cpll/6", "spll/6",
+                            "cpll/8", "spll/8", "cpll/12", "spll/12",
+                            "cpll/16", "spll/16", "cpll/24", "spll/24"),
+#else
+       UNIPHIER_PRO5_SYS_CPUGEARS,
+#endif
        { /* sentinel */ }
 };
 
 const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = {
+       UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 96, 1),          /* 2400 MHz */
+       UNIPHIER_CLK_FACTOR("ippll", -1, "ref", 96, 1),         /* 2400 MHz */
        UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1),          /* 2400 MHz */
        UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27),
        UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
@@ -121,20 +169,70 @@
        /* The document mentions 0x2104 bit 18, but not functional */
        UNIPHIER_CLK_GATE("usb30-phy", 16, NULL, 0x2104, 19),
        UNIPHIER_CLK_GATE("usb31-phy", 20, NULL, 0x2104, 20),
+#if 1
+       /*
+        * TODO:
+        * The return type of .round_rate() is "long", which is 32 bit wide on
+        * 32 bit systems.  Clock rate greater than LONG_MAX (~ 2.15 GHz) is
+        * treated as an error.  Needs a workaround until the problem is fixed.
+        */
+       UNIPHIER_CLK_FACTOR("cpll/2", -1, "ref", 48, 1),
+       UNIPHIER_CLK_FACTOR("cpll/3", -1, "ref", 32, 1),
+       UNIPHIER_CLK_FACTOR("cpll/4", -1, "ref", 24, 1),
+       UNIPHIER_CLK_FACTOR("cpll/6", -1, "ref", 16, 1),
+       UNIPHIER_CLK_FACTOR("cpll/8", -1, "ref", 12, 1),
+       UNIPHIER_CLK_FACTOR("cpll/12", -1, "ref", 8, 1),
+       UNIPHIER_CLK_FACTOR("cpll/16", -1, "ref", 6, 1),
+       UNIPHIER_CLK_FACTOR("cpll/24", -1, "ref", 4, 1),
+       UNIPHIER_CLK_FACTOR("spll/2", -1, "ref", 48, 1),
+       UNIPHIER_CLK_FACTOR("spll/3", -1, "ref", 32, 1),
+       UNIPHIER_CLK_FACTOR("spll/4", -1, "ref", 24, 1),
+       UNIPHIER_CLK_FACTOR("spll/6", -1, "ref", 16, 1),
+       UNIPHIER_CLK_FACTOR("spll/8", -1, "ref", 12, 1),
+       UNIPHIER_CLK_FACTOR("spll/12", -1, "ref", 8, 1),
+       UNIPHIER_CLK_FACTOR("spll/16", -1, "ref", 6, 1),
+       UNIPHIER_CLK_FACTOR("spll/24", -1, "ref", 4, 1),
+       UNIPHIER_CLK_CPUGEAR("cpu-ca9", 32, 0x8000, 0x1f, 16,
+                            "cpll/2", "spll/2", "cpll/3", "spll/3",
+                            "cpll/4", "spll/4", "cpll/6", "spll/6",
+                            "cpll/8", "spll/8", "cpll/12", "spll/12",
+                            "cpll/16", "spll/16", "cpll/24", "spll/24"),
+#else
+       UNIPHIER_PRO5_SYS_CPUGEARS,
+#endif
        { /* sentinel */ }
 };
 
 const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = {
+       UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 392, 5),         /* 1960 MHz */
+       UNIPHIER_CLK_FACTOR("mpll", -1, "ref", 64, 1),          /* 1600 MHz */
        UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1),          /* 2000 MHz */
+       UNIPHIER_CLK_FACTOR("vspll", -1, "ref", 80, 1),         /* 2000 MHz */
        UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
        UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
        UNIPHIER_LD11_SYS_CLK_STDMAC(8),                        /* HSC, MIO */
        UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25),
+       /* CPU gears */
+       UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
+       UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8),
+       UNIPHIER_CLK_DIV3("spll", 3, 4, 8),
+       /* Note: both gear1 and gear4 are spll/4.  This is not a bug. */
+       UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8,
+                            "cpll/2", "spll/4", "cpll/3", "spll/3",
+                            "spll/4", "spll/8", "cpll/4", "cpll/8"),
+       UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8,
+                            "mpll/2", "spll/4", "mpll/3", "spll/3",
+                            "spll/4", "spll/8", "mpll/4", "mpll/8"),
        { /* sentinel */ }
 };
 
 const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
+       UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 88, 1),          /* ARM: 2200 
MHz */
+       UNIPHIER_CLK_FACTOR("gppll", -1, "ref", 52, 1),         /* Mali: 1300 
MHz */
+       UNIPHIER_CLK_FACTOR("mpll", -1, "ref", 64, 1),          /* Codec: 1600 
MHz */
        UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1),          /* 2000 MHz */
+       UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1),         /* IPP: 2200 
MHz */
+       UNIPHIER_CLK_FACTOR("vppll", -1, "ref", 504, 5),        /* 2520 MHz */
        UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
        UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
        UNIPHIER_LD20_SYS_CLK_SD,
@@ -147,5 +245,18 @@
        UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14),
        UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12),
        UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13),
+       /* CPU gears */
+       UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
+       UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8),
+       UNIPHIER_CLK_DIV4("s2pll", 2, 3, 4, 8),
+       UNIPHIER_CLK_CPUGEAR("cpu-ca72", 32, 0x8000, 0xf, 8,
+                            "cpll/2", "spll/2", "cpll/3", "spll/3",
+                            "spll/4", "spll/8", "cpll/4", "cpll/8"),
+       UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8,
+                            "cpll/2", "spll/2", "cpll/3", "spll/3",
+                            "spll/4", "spll/8", "cpll/4", "cpll/8"),
+       UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8,
+                            "s2pll/2", "spll/2", "s2pll/3", "spll/3",
+                            "spll/4", "spll/8", "s2pll/4", "s2pll/8"),
        { /* sentinel */ }
 };
diff --git a/drivers/clk/uniphier/clk-uniphier.h 
b/drivers/clk/uniphier/clk-uniphier.h
index 9707b0f..849824a 100644
--- a/drivers/clk/uniphier/clk-uniphier.h
+++ b/drivers/clk/uniphier/clk-uniphier.h
@@ -75,6 +75,20 @@ struct uniphier_clk_data {
        } data;
 };
 
+#define UNIPHIER_CLK_CPUGEAR(_name, _idx, _regbase, _mask,     \
+                            _num_parents, ...)                 \
+       {                                                       \
+               .name = (_name),                                \
+               .type = UNIPHIER_CLK_TYPE_CPUGEAR,              \
+               .idx = (_idx),                                  \
+               .data.cpugear = {                               \
+                       .parent_names = { __VA_ARGS__ },        \
+                       .num_parents = (_num_parents),          \
+                       .regbase = (_regbase),                  \
+                       .mask = (_mask)                         \
+                },                                             \
+       }
+
 #define UNIPHIER_CLK_FACTOR(_name, _idx, _parent, _mult, _div) \
        {                                                       \
                .name = (_name),                                \
@@ -87,7 +101,6 @@ struct uniphier_clk_data {
                },                                              \
        }
 
-
 #define UNIPHIER_CLK_GATE(_name, _idx, _parent, _reg, _bit)    \
        {                                                       \
                .name = (_name),                                \
@@ -100,6 +113,26 @@ struct uniphier_clk_data {
                },                                              \
        }
 
+#define UNIPHIER_CLK_DIV(parent, div)                          \
+       UNIPHIER_CLK_FACTOR(parent "/" #div, -1, parent, 1, div)
+
+#define UNIPHIER_CLK_DIV2(parent, div0, div1)                  \
+       UNIPHIER_CLK_DIV(parent, div0),                         \
+       UNIPHIER_CLK_DIV(parent, div1)
+
+#define UNIPHIER_CLK_DIV3(parent, div0, div1, div2)            \
+       UNIPHIER_CLK_DIV2(parent, div0, div1),                  \
+       UNIPHIER_CLK_DIV(parent, div2)
+
+#define UNIPHIER_CLK_DIV4(parent, div0, div1, div2, div3)      \
+       UNIPHIER_CLK_DIV2(parent, div0, div1),                  \
+       UNIPHIER_CLK_DIV2(parent, div2, div3)
+
+#define UNIPHIER_CLK_DIV8(parent, div0, div1, div2, div3,      \
+                         div4, div5, div6, div7)               \
+       UNIPHIER_CLK_DIV4(parent, div0, div1, div2, div3),      \
+       UNIPHIER_CLK_DIV4(parent, div4, div5, div6, div7)
+
 struct clk_hw *uniphier_clk_register_cpugear(struct device *dev,
                                             struct regmap *regmap,
                                             const char *name,
-- 
1.9.1

Reply via email to