clk: meson: rework and clean drivers dependencies
authorJerome Brunet <jbrunet@baylibre.com>
Fri, 1 Feb 2019 12:58:41 +0000 (13:58 +0100)
committerNeil Armstrong <narmstrong@baylibre.com>
Sat, 2 Feb 2019 16:43:32 +0000 (17:43 +0100)
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.

Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.

The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
30 files changed:
drivers/clk/meson/Kconfig
drivers/clk/meson/Makefile
drivers/clk/meson/axg-aoclk.c
drivers/clk/meson/axg-audio.c
drivers/clk/meson/axg.c
drivers/clk/meson/clk-dualdiv.c
drivers/clk/meson/clk-dualdiv.h [new file with mode: 0644]
drivers/clk/meson/clk-input.c
drivers/clk/meson/clk-input.h [new file with mode: 0644]
drivers/clk/meson/clk-mpll.c
drivers/clk/meson/clk-mpll.h [new file with mode: 0644]
drivers/clk/meson/clk-phase.c
drivers/clk/meson/clk-phase.h [new file with mode: 0644]
drivers/clk/meson/clk-pll.c
drivers/clk/meson/clk-pll.h [new file with mode: 0644]
drivers/clk/meson/clk-regmap.c
drivers/clk/meson/clk-regmap.h
drivers/clk/meson/clk-triphase.c [deleted file]
drivers/clk/meson/clkc-audio.h [deleted file]
drivers/clk/meson/clkc.h [deleted file]
drivers/clk/meson/gxbb-aoclk.c
drivers/clk/meson/gxbb.c
drivers/clk/meson/meson-aoclk.c
drivers/clk/meson/meson-aoclk.h
drivers/clk/meson/meson8b.c
drivers/clk/meson/parm.h [new file with mode: 0644]
drivers/clk/meson/sclk-div.c
drivers/clk/meson/sclk-div.h [new file with mode: 0644]
drivers/clk/meson/vid-pll-div.c
drivers/clk/meson/vid-pll-div.h [new file with mode: 0644]

index 2479dab09d70bdb217e2bb551f223267584b8117..f2e757aea4f17f47c01d41a70d0592b8763132a4 100644 (file)
@@ -1,27 +1,47 @@
-config COMMON_CLK_AMLOGIC
-       bool
-       depends on ARCH_MESON || COMPILE_TEST
-       select COMMON_CLK_REGMAP_MESON
+config COMMON_CLK_MESON_INPUT
+       tristate
 
-config COMMON_CLK_AMLOGIC_AUDIO
-       bool
-       depends on ARCH_MESON || COMPILE_TEST
-       select COMMON_CLK_AMLOGIC
+config COMMON_CLK_MESON_REGMAP
+       tristate
+       select REGMAP
 
-config COMMON_CLK_MESON_AO
-       bool
-       depends on OF
-       depends on ARCH_MESON || COMPILE_TEST
-       select COMMON_CLK_REGMAP_MESON
-       select RESET_CONTROLLER
+config COMMON_CLK_MESON_DUALDIV
+       tristate
+       select COMMON_CLK_MESON_REGMAP
 
-config COMMON_CLK_REGMAP_MESON
-       bool
-       select REGMAP
+config COMMON_CLK_MESON_MPLL
+       tristate
+       select COMMON_CLK_MESON_REGMAP
+
+config COMMON_CLK_MESON_PHASE
+       tristate
+       select COMMON_CLK_MESON_REGMAP
+
+config COMMON_CLK_MESON_PLL
+       tristate
+       select COMMON_CLK_MESON_REGMAP
+
+config COMMON_CLK_MESON_SCLK_DIV
+       tristate
+       select COMMON_CLK_MESON_REGMAP
+
+config COMMON_CLK_MESON_VID_PLL_DIV
+       tristate
+       select COMMON_CLK_MESON_REGMAP
+
+config COMMON_CLK_MESON_AO_CLKC
+       tristate
+       select COMMON_CLK_MESON_REGMAP
+       select COMMON_CLK_MESON_INPUT
+       select RESET_CONTROLLER
 
 config COMMON_CLK_MESON8B
        bool
-       select COMMON_CLK_AMLOGIC
+       depends on ARCH_MESON
+       select COMMON_CLK_MESON_REGMAP
+       select COMMON_CLK_MESON_MPLL
+       select COMMON_CLK_MESON_PLL
+       select MFD_SYSCON
        select RESET_CONTROLLER
        help
          Support for the clock controller on AmLogic S802 (Meson8),
@@ -30,8 +50,14 @@ config COMMON_CLK_MESON8B
 
 config COMMON_CLK_GXBB
        bool
-       select COMMON_CLK_AMLOGIC
-       select COMMON_CLK_MESON_AO
+       depends on ARCH_MESON
+       select COMMON_CLK_MESON_INPUT
+       select COMMON_CLK_MESON_REGMAP
+       select COMMON_CLK_MESON_DUALDIV
+       select COMMON_CLK_MESON_VID_PLL_DIV
+       select COMMON_CLK_MESON_MPLL
+       select COMMON_CLK_MESON_PLL
+       select COMMON_CLK_MESON_AO_CLKC
        select MFD_SYSCON
        help
          Support for the clock controller on AmLogic S905 devices, aka gxbb.
@@ -39,8 +65,13 @@ config COMMON_CLK_GXBB
 
 config COMMON_CLK_AXG
        bool
-       select COMMON_CLK_AMLOGIC
-       select COMMON_CLK_MESON_AO
+       depends on ARCH_MESON
+       select COMMON_CLK_MESON_INPUT
+       select COMMON_CLK_MESON_REGMAP
+       select COMMON_CLK_MESON_DUALDIV
+       select COMMON_CLK_MESON_MPLL
+       select COMMON_CLK_MESON_PLL
+       select COMMON_CLK_MESON_AO_CLKC
        select MFD_SYSCON
        help
          Support for the clock controller on AmLogic A113D devices, aka axg.
@@ -48,8 +79,11 @@ config COMMON_CLK_AXG
 
 config COMMON_CLK_AXG_AUDIO
        tristate "Meson AXG Audio Clock Controller Driver"
-       depends on COMMON_CLK_AXG
-       select COMMON_CLK_AMLOGIC_AUDIO
+       depends on ARCH_MESON
+       select COMMON_CLK_MESON_INPUT
+       select COMMON_CLK_MESON_REGMAP
+       select COMMON_CLK_MESON_PHASE
+       select COMMON_CLK_MESON_SCLK_DIV
        select REGMAP_MMIO
        help
          Support for the audio clock controller on AmLogic A113D devices,
index 8234e92eea3853277ad01424066480c7192c3981..e339d8f5848894dd0584ccd885cff5a9767c4e0e 100644 (file)
@@ -1,13 +1,18 @@
-#
-# Makefile for Meson specific clk
-#
+# Amlogic clock drivers
 
-obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o vid-pll-div.o
-obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-input.o clk-dualdiv.o
-obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o
-obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o
+obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o
+obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o
+obj-$(CONFIG_COMMON_CLK_MESON_INPUT) += clk-input.o
+obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
+obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o
+obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
+obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
+obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
+obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
+
+# Amlogic Clock controllers
+
+obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
+obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
-obj-$(CONFIG_COMMON_CLK_GXBB)   += gxbb.o gxbb-aoclk.o
-obj-$(CONFIG_COMMON_CLK_AXG)    += axg.o axg-aoclk.o
-obj-$(CONFIG_COMMON_CLK_AXG_AUDIO)     += axg-audio.o
-obj-$(CONFIG_COMMON_CLK_REGMAP_MESON)  += clk-regmap.o
index 5701f5840b75c96468fb3a0be681f6a40f0aca7b..0086f31288eb8621bc38a0c4a104cd2c664079ed 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
 #include <linux/mfd/syscon.h>
-#include "clkc.h"
 #include "meson-aoclk.h"
 #include "axg-aoclk.h"
 
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+
 #define IN_PREFIX "ao-in-"
 
 /*
index 8ac3a22954734a58876b4fc643558a7ee6e8a58b..7ab200b6c3bff5a18080368550eb850d37ce5d6d 100644 (file)
 #include <linux/reset.h>
 #include <linux/slab.h>
 
-#include "clkc-audio.h"
 #include "axg-audio.h"
+#include "clk-input.h"
+#include "clk-regmap.h"
+#include "clk-phase.h"
+#include "sclk-div.h"
 
 #define AXG_MST_IN_COUNT       8
 #define AXG_SLV_SCLK_COUNT     10
index 1c6539eeee7c2856bb83b9286383342d423f4bff..cbbdd93b175d7c287c74dbcdaf8237deec4f76e0 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#include "clkc.h"
+#include "clk-input.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-mpll.h"
 #include "axg.h"
 
 #define IN_PREFIX "ee-in-"
index 4d9e161de6271a8a6707be40be6e71a9889e8750..c5ca23a5e3e8cb4673affd444e15210329b95596 100644 (file)
  */
 
 #include <linux/clk-provider.h>
-#include "clkc.h"
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
 
 static inline struct meson_clk_dualdiv_data *
 meson_clk_dualdiv_data(struct clk_regmap *clk)
@@ -128,3 +131,8 @@ const struct clk_ops meson_clk_dualdiv_ro_ops = {
        .recalc_rate    = meson_clk_dualdiv_recalc_rate,
 };
 EXPORT_SYMBOL_GPL(meson_clk_dualdiv_ro_ops);
+
+MODULE_DESCRIPTION("Amlogic dual divider driver");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-dualdiv.h b/drivers/clk/meson/clk-dualdiv.h
new file mode 100644 (file)
index 0000000..4aa9390
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_DUALDIV_H
+#define __MESON_CLK_DUALDIV_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_dualdiv_param {
+       unsigned int n1;
+       unsigned int n2;
+       unsigned int m1;
+       unsigned int m2;
+       unsigned int dual;
+};
+
+struct meson_clk_dualdiv_data {
+       struct parm n1;
+       struct parm n2;
+       struct parm m1;
+       struct parm m2;
+       struct parm dual;
+       const struct meson_clk_dualdiv_param *table;
+};
+
+extern const struct clk_ops meson_clk_dualdiv_ops;
+extern const struct clk_ops meson_clk_dualdiv_ro_ops;
+
+#endif /* __MESON_CLK_DUALDIV_H */
index 06b3e3bb6a66ff38d31f98215847d1ee47226938..086226e9dba640f173110da556cffb69784d1d81 100644 (file)
@@ -7,7 +7,8 @@
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/device.h>
-#include "clkc.h"
+#include <linux/module.h>
+#include "clk-input.h"
 
 static const struct clk_ops meson_clk_no_ops = {};
 
@@ -42,3 +43,7 @@ struct clk_hw *meson_clk_hw_register_input(struct device *dev,
        return ret ? ERR_PTR(ret) : hw;
 }
 EXPORT_SYMBOL_GPL(meson_clk_hw_register_input);
+
+MODULE_DESCRIPTION("Amlogic clock input helper");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-input.h b/drivers/clk/meson/clk-input.h
new file mode 100644 (file)
index 0000000..4a541b9
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_INPUT_H
+#define __MESON_CLK_INPUT_H
+
+#include <linux/clk-provider.h>
+
+struct device;
+
+struct clk_hw *meson_clk_hw_register_input(struct device *dev,
+                                          const char *of_name,
+                                          const char *clk_name,
+                                          unsigned long flags);
+
+#endif /* __MESON_CLK_INPUT_H */
index 650f75cc15a93f6a3f41a4a50262c144cffd8320..f76850d99e591b1fb817665519863986356c736c 100644 (file)
  */
 
 #include <linux/clk-provider.h>
-#include "clkc.h"
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include "clk-regmap.h"
+#include "clk-mpll.h"
 
 #define SDM_DEN 16384
 #define N2_MIN 4
@@ -138,9 +142,15 @@ const struct clk_ops meson_clk_mpll_ro_ops = {
        .recalc_rate    = mpll_recalc_rate,
        .round_rate     = mpll_round_rate,
 };
+EXPORT_SYMBOL_GPL(meson_clk_mpll_ro_ops);
 
 const struct clk_ops meson_clk_mpll_ops = {
        .recalc_rate    = mpll_recalc_rate,
        .round_rate     = mpll_round_rate,
        .set_rate       = mpll_set_rate,
 };
+EXPORT_SYMBOL_GPL(meson_clk_mpll_ops);
+
+MODULE_DESCRIPTION("Amlogic MPLL driver");
+MODULE_AUTHOR("Michael Turquette <mturquette@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-mpll.h b/drivers/clk/meson/clk-mpll.h
new file mode 100644 (file)
index 0000000..cf79340
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_MPLL_H
+#define __MESON_CLK_MPLL_H
+
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+
+#include "parm.h"
+
+struct meson_clk_mpll_data {
+       struct parm sdm;
+       struct parm sdm_en;
+       struct parm n2;
+       struct parm ssen;
+       struct parm misc;
+       spinlock_t *lock;
+       u8 flags;
+};
+
+#define CLK_MESON_MPLL_ROUND_CLOSEST   BIT(0)
+
+extern const struct clk_ops meson_clk_mpll_ro_ops;
+extern const struct clk_ops meson_clk_mpll_ops;
+
+#endif /* __MESON_CLK_MPLL_H */
index cba43748ce3df0ba0024e3a3447384637884cb8c..80c3ada193a43f8d6598a6f2b5d03116810c1a3c 100644 (file)
@@ -5,7 +5,10 @@
  */
 
 #include <linux/clk-provider.h>
-#include "clkc.h"
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-phase.h"
 
 #define phase_step(_width) (360 / (1 << (_width)))
 
@@ -15,13 +18,12 @@ meson_clk_phase_data(struct clk_regmap *clk)
        return (struct meson_clk_phase_data *)clk->data;
 }
 
-int meson_clk_degrees_from_val(unsigned int val, unsigned int width)
+static int meson_clk_degrees_from_val(unsigned int val, unsigned int width)
 {
        return phase_step(width) * val;
 }
-EXPORT_SYMBOL_GPL(meson_clk_degrees_from_val);
 
-unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width)
+static unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width)
 {
        unsigned int val = DIV_ROUND_CLOSEST(degrees, phase_step(width));
 
@@ -31,7 +33,6 @@ unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width)
         */
        return val % (1 << width);
 }
-EXPORT_SYMBOL_GPL(meson_clk_degrees_to_val);
 
 static int meson_clk_phase_get_phase(struct clk_hw *hw)
 {
@@ -61,3 +62,67 @@ const struct clk_ops meson_clk_phase_ops = {
        .set_phase      = meson_clk_phase_set_phase,
 };
 EXPORT_SYMBOL_GPL(meson_clk_phase_ops);
+
+/*
+ * This is a special clock for the audio controller.
+ * The phase of mst_sclk clock output can be controlled independently
+ * for the outside world (ph0), the tdmout (ph1) and tdmin (ph2).
+ * Controlling these 3 phases as just one makes things simpler and
+ * give the same clock view to all the element on the i2s bus.
+ * If necessary, we can still control the phase in the tdm block
+ * which makes these independent control redundant.
+ */
+static inline struct meson_clk_triphase_data *
+meson_clk_triphase_data(struct clk_regmap *clk)
+{
+       return (struct meson_clk_triphase_data *)clk->data;
+}
+
+static void meson_clk_triphase_sync(struct clk_hw *hw)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
+       unsigned int val;
+
+       /* Get phase 0 and sync it to phase 1 and 2 */
+       val = meson_parm_read(clk->map, &tph->ph0);
+       meson_parm_write(clk->map, &tph->ph1, val);
+       meson_parm_write(clk->map, &tph->ph2, val);
+}
+
+static int meson_clk_triphase_get_phase(struct clk_hw *hw)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
+       unsigned int val;
+
+       /* Phase are in sync, reading phase 0 is enough */
+       val = meson_parm_read(clk->map, &tph->ph0);
+
+       return meson_clk_degrees_from_val(val, tph->ph0.width);
+}
+
+static int meson_clk_triphase_set_phase(struct clk_hw *hw, int degrees)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
+       unsigned int val;
+
+       val = meson_clk_degrees_to_val(degrees, tph->ph0.width);
+       meson_parm_write(clk->map, &tph->ph0, val);
+       meson_parm_write(clk->map, &tph->ph1, val);
+       meson_parm_write(clk->map, &tph->ph2, val);
+
+       return 0;
+}
+
+const struct clk_ops meson_clk_triphase_ops = {
+       .init           = meson_clk_triphase_sync,
+       .get_phase      = meson_clk_triphase_get_phase,
+       .set_phase      = meson_clk_triphase_set_phase,
+};
+EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
+
+MODULE_DESCRIPTION("Amlogic phase driver");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-phase.h b/drivers/clk/meson/clk-phase.h
new file mode 100644 (file)
index 0000000..5579f9c
--- /dev/null
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_PHASE_H
+#define __MESON_CLK_PHASE_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_phase_data {
+       struct parm ph;
+};
+
+struct meson_clk_triphase_data {
+       struct parm ph0;
+       struct parm ph1;
+       struct parm ph2;
+};
+
+extern const struct clk_ops meson_clk_phase_ops;
+extern const struct clk_ops meson_clk_triphase_ops;
+
+#endif /* __MESON_CLK_PHASE_H */
index afffc1547e20e076bd241882eb8161c96542bdde..4a8c68ae88016953d0a65aca3c7fa7abf8b8d4b7 100644 (file)
 #include <linux/io.h>
 #include <linux/math64.h>
 #include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/slab.h>
-#include <linux/string.h>
 
-#include "clkc.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
 
 static inline struct meson_clk_pll_data *
 meson_clk_pll_data(struct clk_regmap *clk)
@@ -309,8 +307,15 @@ const struct clk_ops meson_clk_pll_ops = {
        .enable         = meson_clk_pll_enable,
        .disable        = meson_clk_pll_disable
 };
+EXPORT_SYMBOL_GPL(meson_clk_pll_ops);
 
 const struct clk_ops meson_clk_pll_ro_ops = {
        .recalc_rate    = meson_clk_pll_recalc_rate,
        .is_enabled     = meson_clk_pll_is_enabled,
 };
+EXPORT_SYMBOL_GPL(meson_clk_pll_ro_ops);
+
+MODULE_DESCRIPTION("Amlogic PLL driver");
+MODULE_AUTHOR("Carlo Caione <carlo@endlessm.com>");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
new file mode 100644 (file)
index 0000000..5ccf085
--- /dev/null
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_PLL_H
+#define __MESON_CLK_PLL_H
+
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include "parm.h"
+
+struct pll_params_table {
+       u16             m;
+       u16             n;
+};
+
+#define PLL_PARAMS(_m, _n)                                             \
+       {                                                               \
+               .m              = (_m),                                 \
+               .n              = (_n),                                 \
+       }
+
+#define CLK_MESON_PLL_ROUND_CLOSEST    BIT(0)
+
+struct meson_clk_pll_data {
+       struct parm en;
+       struct parm m;
+       struct parm n;
+       struct parm frac;
+       struct parm l;
+       struct parm rst;
+       const struct reg_sequence *init_regs;
+       unsigned int init_count;
+       const struct pll_params_table *table;
+       u8 flags;
+};
+
+extern const struct clk_ops meson_clk_pll_ro_ops;
+extern const struct clk_ops meson_clk_pll_ops;
+
+#endif /* __MESON_CLK_PLL_H */
index c515f67322a3aec05332b931279413f71c2fc51c..dcd1757cc5dff6ce632ef9a0fc5048dca63ec401 100644 (file)
@@ -4,6 +4,7 @@
  * Author: Jerome Brunet <jbrunet@baylibre.com>
  */
 
+#include <linux/module.h>
 #include "clk-regmap.h"
 
 static int clk_regmap_gate_endisable(struct clk_hw *hw, int enable)
@@ -180,3 +181,7 @@ const struct clk_ops clk_regmap_mux_ro_ops = {
        .get_parent = clk_regmap_mux_get_parent,
 };
 EXPORT_SYMBOL_GPL(clk_regmap_mux_ro_ops);
+
+MODULE_DESCRIPTION("Amlogic regmap backed clock driver");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL v2");
index e9c5728d40eb471e53a6e7b4abe397006f23a8e8..b7a085bbf072d4ab0b9c79b2f89f0d8759a52a6c 100644 (file)
@@ -111,4 +111,19 @@ clk_get_regmap_mux_data(struct clk_regmap *clk)
 extern const struct clk_ops clk_regmap_mux_ops;
 extern const struct clk_ops clk_regmap_mux_ro_ops;
 
+#define MESON_GATE(_name, _reg, _bit)                                  \
+struct clk_regmap _name = {                                            \
+       .data = &(struct clk_regmap_gate_data){                         \
+               .offset = (_reg),                                       \
+               .bit_idx = (_bit),                                      \
+       },                                                              \
+       .hw.init = &(struct clk_init_data) {                            \
+               .name = #_name,                                         \
+               .ops = &clk_regmap_gate_ops,                            \
+               .parent_names = (const char *[]){ "clk81" },            \
+               .num_parents = 1,                                       \
+               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),     \
+       },                                                              \
+}
+
 #endif /* __CLK_REGMAP_H */
diff --git a/drivers/clk/meson/clk-triphase.c b/drivers/clk/meson/clk-triphase.c
deleted file mode 100644 (file)
index 4a59936..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (c) 2018 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#include <linux/clk-provider.h>
-#include "clkc-audio.h"
-
-/*
- * This is a special clock for the audio controller.
- * The phase of mst_sclk clock output can be controlled independently
- * for the outside world (ph0), the tdmout (ph1) and tdmin (ph2).
- * Controlling these 3 phases as just one makes things simpler and
- * give the same clock view to all the element on the i2s bus.
- * If necessary, we can still control the phase in the tdm block
- * which makes these independent control redundant.
- */
-static inline struct meson_clk_triphase_data *
-meson_clk_triphase_data(struct clk_regmap *clk)
-{
-       return (struct meson_clk_triphase_data *)clk->data;
-}
-
-static void meson_clk_triphase_sync(struct clk_hw *hw)
-{
-       struct clk_regmap *clk = to_clk_regmap(hw);
-       struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
-       unsigned int val;
-
-       /* Get phase 0 and sync it to phase 1 and 2 */
-       val = meson_parm_read(clk->map, &tph->ph0);
-       meson_parm_write(clk->map, &tph->ph1, val);
-       meson_parm_write(clk->map, &tph->ph2, val);
-}
-
-static int meson_clk_triphase_get_phase(struct clk_hw *hw)
-{
-       struct clk_regmap *clk = to_clk_regmap(hw);
-       struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
-       unsigned int val;
-
-       /* Phase are in sync, reading phase 0 is enough */
-       val = meson_parm_read(clk->map, &tph->ph0);
-
-       return meson_clk_degrees_from_val(val, tph->ph0.width);
-}
-
-static int meson_clk_triphase_set_phase(struct clk_hw *hw, int degrees)
-{
-       struct clk_regmap *clk = to_clk_regmap(hw);
-       struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
-       unsigned int val;
-
-       val = meson_clk_degrees_to_val(degrees, tph->ph0.width);
-       meson_parm_write(clk->map, &tph->ph0, val);
-       meson_parm_write(clk->map, &tph->ph1, val);
-       meson_parm_write(clk->map, &tph->ph2, val);
-
-       return 0;
-}
-
-const struct clk_ops meson_clk_triphase_ops = {
-       .init           = meson_clk_triphase_sync,
-       .get_phase      = meson_clk_triphase_get_phase,
-       .set_phase      = meson_clk_triphase_set_phase,
-};
-EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
diff --git a/drivers/clk/meson/clkc-audio.h b/drivers/clk/meson/clkc-audio.h
deleted file mode 100644 (file)
index 0a7c157..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2018 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#ifndef __MESON_CLKC_AUDIO_H
-#define __MESON_CLKC_AUDIO_H
-
-#include "clkc.h"
-
-struct meson_clk_triphase_data {
-       struct parm ph0;
-       struct parm ph1;
-       struct parm ph2;
-};
-
-struct meson_sclk_div_data {
-       struct parm div;
-       struct parm hi;
-       unsigned int cached_div;
-       struct clk_duty cached_duty;
-};
-
-extern const struct clk_ops meson_clk_triphase_ops;
-extern const struct clk_ops meson_sclk_div_ops;
-
-#endif /* __MESON_CLKC_AUDIO_H */
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
deleted file mode 100644 (file)
index e3cd442..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2015 Endless Mobile, Inc.
- * Author: Carlo Caione <carlo@endlessm.com>
- */
-
-#ifndef __CLKC_H
-#define __CLKC_H
-
-#include <linux/clk-provider.h>
-#include "clk-regmap.h"
-
-#define PMASK(width)                   GENMASK(width - 1, 0)
-#define SETPMASK(width, shift)         GENMASK(shift + width - 1, shift)
-#define CLRPMASK(width, shift)         (~SETPMASK(width, shift))
-
-#define PARM_GET(width, shift, reg)                                    \
-       (((reg) & SETPMASK(width, shift)) >> (shift))
-#define PARM_SET(width, shift, reg, val)                               \
-       (((reg) & CLRPMASK(width, shift)) | ((val) << (shift)))
-
-#define MESON_PARM_APPLICABLE(p)               (!!((p)->width))
-
-struct parm {
-       u16     reg_off;
-       u8      shift;
-       u8      width;
-};
-
-static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
-{
-       unsigned int val;
-
-       regmap_read(map, p->reg_off, &val);
-       return PARM_GET(p->width, p->shift, val);
-}
-
-static inline void meson_parm_write(struct regmap *map, struct parm *p,
-                                   unsigned int val)
-{
-       regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
-                          val << p->shift);
-}
-
-
-struct pll_params_table {
-       u16             m;
-       u16             n;
-};
-
-#define PLL_PARAMS(_m, _n)                                             \
-       {                                                               \
-               .m              = (_m),                                 \
-               .n              = (_n),                                 \
-       }
-
-#define CLK_MESON_PLL_ROUND_CLOSEST    BIT(0)
-
-struct meson_clk_pll_data {
-       struct parm en;
-       struct parm m;
-       struct parm n;
-       struct parm frac;
-       struct parm l;
-       struct parm rst;
-       const struct reg_sequence *init_regs;
-       unsigned int init_count;
-       const struct pll_params_table *table;
-       u8 flags;
-};
-
-#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
-
-struct meson_clk_mpll_data {
-       struct parm sdm;
-       struct parm sdm_en;
-       struct parm n2;
-       struct parm ssen;
-       struct parm misc;
-       spinlock_t *lock;
-       u8 flags;
-};
-
-#define CLK_MESON_MPLL_ROUND_CLOSEST   BIT(0)
-
-struct meson_clk_phase_data {
-       struct parm ph;
-};
-
-int meson_clk_degrees_from_val(unsigned int val, unsigned int width);
-unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width);
-
-struct meson_vid_pll_div_data {
-       struct parm val;
-       struct parm sel;
-};
-
-#define MESON_GATE(_name, _reg, _bit)                                  \
-struct clk_regmap _name = {                                            \
-       .data = &(struct clk_regmap_gate_data){                         \
-               .offset = (_reg),                                       \
-               .bit_idx = (_bit),                                      \
-       },                                                              \
-       .hw.init = &(struct clk_init_data) {                            \
-               .name = #_name,                                         \
-               .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ "clk81" },            \
-               .num_parents = 1,                                       \
-               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),     \
-       },                                                              \
-};
-
-struct meson_clk_dualdiv_param {
-       unsigned int n1;
-       unsigned int n2;
-       unsigned int m1;
-       unsigned int m2;
-       unsigned int dual;
-};
-
-struct meson_clk_dualdiv_data {
-       struct parm n1;
-       struct parm n2;
-       struct parm m1;
-       struct parm m2;
-       struct parm dual;
-       const struct meson_clk_dualdiv_param *table;
-};
-
-/* clk_ops */
-extern const struct clk_ops meson_clk_pll_ro_ops;
-extern const struct clk_ops meson_clk_pll_ops;
-extern const struct clk_ops meson_clk_cpu_ops;
-extern const struct clk_ops meson_clk_mpll_ro_ops;
-extern const struct clk_ops meson_clk_mpll_ops;
-extern const struct clk_ops meson_clk_phase_ops;
-extern const struct clk_ops meson_vid_pll_div_ro_ops;
-extern const struct clk_ops meson_clk_dualdiv_ops;
-extern const struct clk_ops meson_clk_dualdiv_ro_ops;
-
-struct clk_hw *meson_clk_hw_register_input(struct device *dev,
-                                          const char *of_name,
-                                          const char *clk_name,
-                                          unsigned long flags);
-
-#endif /* __CLKC_H */
index 510b6a7d2f1811b1f3bad5cae489950df5093c68..449f6ac189d86ea59fcb0d66ea0efe4d40dea9ac 100644 (file)
@@ -5,10 +5,12 @@
  */
 #include <linux/platform_device.h>
 #include <linux/mfd/syscon.h>
-#include "clkc.h"
 #include "meson-aoclk.h"
 #include "gxbb-aoclk.h"
 
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+
 #define IN_PREFIX "ao-in-"
 
 /* AO Configuration Clock registers offsets */
index ecf9a8f6281c8192d50d10480c959b14b7628e04..3741db9a9fe10603412bf3552247e95eafb460d4 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#include "clkc.h"
 #include "gxbb.h"
+#include "clk-input.h"
 #include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-mpll.h"
+#include "vid-pll-div.h"
 
 #define IN_PREFIX "ee-in-"
 
index 7b9d194ccc3b8c41b4c016160ed2863388689571..b67951909e04955730cddb6d0f252a95980f867d 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/slab.h>
 #include "meson-aoclk.h"
 
+#include "clk-input.h"
+
 static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev,
                               unsigned long id)
 {
index 0758b35d44273e56cfa60b3cc86cdb38c1c6e8e1..999cde3868f7f38982c2a7bebe12b8ee352551ec 100644 (file)
 #ifndef __MESON_AOCLK_H__
 #define __MESON_AOCLK_H__
 
+#include <linux/clk-provider.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/reset-controller.h>
-#include "clkc.h"
+
+#include "clk-regmap.h"
 
 struct meson_aoclk_input {
        const char *name;
index 748552c5f6c8dc2e8e810339fd86ffe49e6e742e..23b1e355a849db695cf1784bc3fd8ed82107e5e5 100644 (file)
 #include <linux/slab.h>
 #include <linux/regmap.h>
 
-#include "clkc.h"
 #include "meson8b.h"
 #include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-mpll.h"
 
 static DEFINE_SPINLOCK(meson_clk_lock);
 
diff --git a/drivers/clk/meson/parm.h b/drivers/clk/meson/parm.h
new file mode 100644 (file)
index 0000000..3c9ef1b
--- /dev/null
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2015 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ */
+
+#ifndef __MESON_PARM_H
+#define __MESON_PARM_H
+
+#include <linux/bits.h>
+#include <linux/regmap.h>
+
+#define PMASK(width)                   GENMASK(width - 1, 0)
+#define SETPMASK(width, shift)         GENMASK(shift + width - 1, shift)
+#define CLRPMASK(width, shift)         (~SETPMASK(width, shift))
+
+#define PARM_GET(width, shift, reg)                                    \
+       (((reg) & SETPMASK(width, shift)) >> (shift))
+#define PARM_SET(width, shift, reg, val)                               \
+       (((reg) & CLRPMASK(width, shift)) | ((val) << (shift)))
+
+#define MESON_PARM_APPLICABLE(p)               (!!((p)->width))
+
+struct parm {
+       u16     reg_off;
+       u8      shift;
+       u8      width;
+};
+
+static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
+{
+       unsigned int val;
+
+       regmap_read(map, p->reg_off, &val);
+       return PARM_GET(p->width, p->shift, val);
+}
+
+static inline void meson_parm_write(struct regmap *map, struct parm *p,
+                                   unsigned int val)
+{
+       regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
+                          val << p->shift);
+}
+
+#endif /* __MESON_PARM_H */
+
index bc64019b8eeb122de779e85509f9b95d51fb890b..3acf037802215cd7972543991853fe2ce279f381 100644 (file)
  * duty_cycle = (1 + hi) / (1 + val)
  */
 
-#include "clkc-audio.h"
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "sclk-div.h"
 
 static inline struct meson_sclk_div_data *
 meson_sclk_div_data(struct clk_regmap *clk)
@@ -241,3 +245,7 @@ const struct clk_ops meson_sclk_div_ops = {
        .init           = sclk_div_init,
 };
 EXPORT_SYMBOL_GPL(meson_sclk_div_ops);
+
+MODULE_DESCRIPTION("Amlogic Sample divider driver");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/sclk-div.h b/drivers/clk/meson/sclk-div.h
new file mode 100644 (file)
index 0000000..b64b2a3
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __MESON_SCLK_DIV_H
+#define __MESON_SCLK_DIV_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_sclk_div_data {
+       struct parm div;
+       struct parm hi;
+       unsigned int cached_div;
+       struct clk_duty cached_duty;
+};
+
+extern const struct clk_ops meson_sclk_div_ops;
+
+#endif /* __MESON_SCLK_DIV_H */
index 88af0e282ea06c21d57b68de09aa1ef4c7964b92..08bcc01c0923863790d32dafbc1274bdf2358a28 100644 (file)
@@ -5,7 +5,10 @@
  */
 
 #include <linux/clk-provider.h>
-#include "clkc.h"
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "vid-pll-div.h"
 
 static inline struct meson_vid_pll_div_data *
 meson_vid_pll_div_data(struct clk_regmap *clk)
@@ -89,3 +92,8 @@ static unsigned long meson_vid_pll_div_recalc_rate(struct clk_hw *hw,
 const struct clk_ops meson_vid_pll_div_ro_ops = {
        .recalc_rate    = meson_vid_pll_div_recalc_rate,
 };
+EXPORT_SYMBOL_GPL(meson_vid_pll_div_ro_ops);
+
+MODULE_DESCRIPTION("Amlogic video pll divider driver");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/vid-pll-div.h b/drivers/clk/meson/vid-pll-div.h
new file mode 100644 (file)
index 0000000..c0128e3
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __MESON_VID_PLL_DIV_H
+#define __MESON_VID_PLL_DIV_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_vid_pll_div_data {
+       struct parm val;
+       struct parm sel;
+};
+
+extern const struct clk_ops meson_vid_pll_div_ro_ops;
+
+#endif /* __MESON_VID_PLL_DIV_H */