clk: starfive: jh7100: Make hw clock implementation reusable
authorEmil Renner Berthing <kernel@esmil.dk>
Wed, 26 Jan 2022 17:39:51 +0000 (18:39 +0100)
committerStephen Boyd <sboyd@kernel.org>
Fri, 11 Mar 2022 02:17:32 +0000 (18:17 -0800)
The JH7100 has additional audio and video clocks at different memory
ranges, but they use the same register layout. Add a header and export
the starfive_jh7100_clk_ops function so the clock implementation can be
reused by drivers handling these clocks.

Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
Link: https://lore.kernel.org/r/20220126173953.1016706-6-kernel@esmil.dk
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/clk/starfive/clk-starfive-jh7100.c
drivers/clk/starfive/clk-starfive-jh7100.h [new file with mode: 0644]

index 4b59338b5d7d418af4ef4078854d09b9768c6afe..a6708f9ebf4c53fac7e20676c5826da624ba954d 100644 (file)
 
 #include <dt-bindings/clock/starfive-jh7100.h>
 
+#include "clk-starfive-jh7100.h"
+
 /* external clocks */
 #define JH7100_CLK_OSC_SYS             (JH7100_CLK_END + 0)
 #define JH7100_CLK_OSC_AUD             (JH7100_CLK_END + 1)
 #define JH7100_CLK_GMAC_RMII_REF       (JH7100_CLK_END + 2)
 #define JH7100_CLK_GMAC_GR_MII_RX      (JH7100_CLK_END + 3)
 
-/* register fields */
-#define JH7100_CLK_ENABLE      BIT(31)
-#define JH7100_CLK_INVERT      BIT(30)
-#define JH7100_CLK_MUX_MASK    GENMASK(27, 24)
-#define JH7100_CLK_MUX_SHIFT   24
-#define JH7100_CLK_DIV_MASK    GENMASK(23, 0)
-#define JH7100_CLK_FRAC_MASK   GENMASK(15, 8)
-#define JH7100_CLK_FRAC_SHIFT  8
-#define JH7100_CLK_INT_MASK    GENMASK(7, 0)
-
-/* fractional divider min/max */
-#define JH7100_CLK_FRAC_MIN    100UL
-#define JH7100_CLK_FRAC_MAX    25599UL
-
-/* clock data */
-#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = {           \
-       .name = _name,                                                  \
-       .flags = CLK_SET_RATE_PARENT | (_flags),                        \
-       .max = JH7100_CLK_ENABLE,                                       \
-       .parents = { [0] = _parent },                                   \
-}
-
-#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = {             \
-       .name = _name,                                                  \
-       .flags = 0,                                                     \
-       .max = _max,                                                    \
-       .parents = { [0] = _parent },                                   \
-}
-
-#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = {     \
-       .name = _name,                                                  \
-       .flags = _flags,                                                \
-       .max = JH7100_CLK_ENABLE | (_max),                              \
-       .parents = { [0] = _parent },                                   \
-}
-
-#define JH7100_FDIV(_idx, _name, _parent) [_idx] = {                   \
-       .name = _name,                                                  \
-       .flags = 0,                                                     \
-       .max = JH7100_CLK_FRAC_MAX,                                     \
-       .parents = { [0] = _parent },                                   \
-}
-
-#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = {            \
-       .name = _name,                                                  \
-       .flags = 0,                                                     \
-       .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT,               \
-       .parents = { __VA_ARGS__ },                                     \
-}
-
-#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = {    \
-       .name = _name,                                                  \
-       .flags = _flags,                                                \
-       .max = JH7100_CLK_ENABLE |                                      \
-               (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT),            \
-       .parents = { __VA_ARGS__ },                                     \
-}
-
-#define JH7100__INV(_idx, _name, _parent) [_idx] = {                   \
-       .name = _name,                                                  \
-       .flags = CLK_SET_RATE_PARENT,                                   \
-       .max = JH7100_CLK_INVERT,                                       \
-       .parents = { [0] = _parent },                                   \
-}
-
-static const struct {
-       const char *name;
-       unsigned long flags;
-       u32 max;
-       u8 parents[4];
-} jh7100_clk_data[] __initconst = {
+static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
        JH7100__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
                    JH7100_CLK_OSC_SYS,
                    JH7100_CLK_PLL0_OUT,
@@ -337,21 +269,6 @@ static const struct {
        JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
 };
 
-struct jh7100_clk {
-       struct clk_hw hw;
-       unsigned int idx;
-       unsigned int max_div;
-};
-
-struct jh7100_clk_priv {
-       /* protect clk enable and set rate/parent from happening at the same time */
-       spinlock_t rmw_lock;
-       struct device *dev;
-       void __iomem *base;
-       struct clk_hw *pll[3];
-       struct jh7100_clk reg[JH7100_CLK_PLL0_OUT];
-};
-
 static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
 {
        return container_of(hw, struct jh7100_clk, hw);
@@ -623,7 +540,7 @@ static const struct clk_ops jh7100_clk_inv_ops = {
        .debug_init = jh7100_clk_debug_init,
 };
 
-static const struct clk_ops *__init jh7100_clk_ops(u32 max)
+const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
 {
        if (max & JH7100_CLK_DIV_MASK) {
                if (max & JH7100_CLK_ENABLE)
@@ -644,6 +561,7 @@ static const struct clk_ops *__init jh7100_clk_ops(u32 max)
 
        return &jh7100_clk_inv_ops;
 }
+EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
 
 static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
 {
@@ -665,7 +583,7 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
        unsigned int idx;
        int ret;
 
-       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7100_CLK_PLL0_OUT), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
@@ -695,7 +613,7 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
                struct clk_parent_data parents[4] = {};
                struct clk_init_data init = {
                        .name = jh7100_clk_data[idx].name,
-                       .ops = jh7100_clk_ops(max),
+                       .ops = starfive_jh7100_clk_ops(max),
                        .parent_data = parents,
                        .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
                        .flags = jh7100_clk_data[idx].flags,
diff --git a/drivers/clk/starfive/clk-starfive-jh7100.h b/drivers/clk/starfive/clk-starfive-jh7100.h
new file mode 100644 (file)
index 0000000..8eccd8c
--- /dev/null
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __CLK_STARFIVE_JH7100_H
+#define __CLK_STARFIVE_JH7100_H
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+
+/* register fields */
+#define JH7100_CLK_ENABLE      BIT(31)
+#define JH7100_CLK_INVERT      BIT(30)
+#define JH7100_CLK_MUX_MASK    GENMASK(27, 24)
+#define JH7100_CLK_MUX_SHIFT   24
+#define JH7100_CLK_DIV_MASK    GENMASK(23, 0)
+#define JH7100_CLK_FRAC_MASK   GENMASK(15, 8)
+#define JH7100_CLK_FRAC_SHIFT  8
+#define JH7100_CLK_INT_MASK    GENMASK(7, 0)
+
+/* fractional divider min/max */
+#define JH7100_CLK_FRAC_MIN    100UL
+#define JH7100_CLK_FRAC_MAX    25599UL
+
+/* clock data */
+struct jh7100_clk_data {
+       const char *name;
+       unsigned long flags;
+       u32 max;
+       u8 parents[4];
+};
+
+#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = {                   \
+       .name = _name,                                                          \
+       .flags = CLK_SET_RATE_PARENT | (_flags),                                \
+       .max = JH7100_CLK_ENABLE,                                               \
+       .parents = { [0] = _parent },                                           \
+}
+
+#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = {                     \
+       .name = _name,                                                          \
+       .flags = 0,                                                             \
+       .max = _max,                                                            \
+       .parents = { [0] = _parent },                                           \
+}
+
+#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = {             \
+       .name = _name,                                                          \
+       .flags = _flags,                                                        \
+       .max = JH7100_CLK_ENABLE | (_max),                                      \
+       .parents = { [0] = _parent },                                           \
+}
+
+#define JH7100_FDIV(_idx, _name, _parent) [_idx] = {                           \
+       .name = _name,                                                          \
+       .flags = 0,                                                             \
+       .max = JH7100_CLK_FRAC_MAX,                                             \
+       .parents = { [0] = _parent },                                           \
+}
+
+#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = {                    \
+       .name = _name,                                                          \
+       .flags = 0,                                                             \
+       .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT,                       \
+       .parents = { __VA_ARGS__ },                                             \
+}
+
+#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = {            \
+       .name = _name,                                                          \
+       .flags = _flags,                                                        \
+       .max = JH7100_CLK_ENABLE |                                              \
+               (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT),                    \
+       .parents = { __VA_ARGS__ },                                             \
+}
+
+#define JH7100__INV(_idx, _name, _parent) [_idx] = {                           \
+       .name = _name,                                                          \
+       .flags = CLK_SET_RATE_PARENT,                                           \
+       .max = JH7100_CLK_INVERT,                                               \
+       .parents = { [0] = _parent },                                           \
+}
+
+struct jh7100_clk {
+       struct clk_hw hw;
+       unsigned int idx;
+       unsigned int max_div;
+};
+
+struct jh7100_clk_priv {
+       /* protect clk enable and set rate/parent from happening at the same time */
+       spinlock_t rmw_lock;
+       struct device *dev;
+       void __iomem *base;
+       struct clk_hw *pll[3];
+       struct jh7100_clk reg[];
+};
+
+const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
+
+#endif