All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] meson8b clock driver rewrite/cleanup
@ 2016-06-10  0:27 ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

This series came about while writing the clock driver for the AmLogic
GXBB clock controller. GXBB shares much of the same clock controller IP
as the Meson8b clock controller and the source for the drivers is very
similar. However, I wanted the GXBB driver to actually be a real
platform_driver, and not an early initcall, which led to the same
changes in the Meson8b driver. From there a lot of other changes came
about.

This series improves documentation, refactors statically initialized
data, removes unnecessary registration functions and converts the
meson8b clock controller code into a proper platform_driver. It also
changes up the Kconfig bits to prepare for the gxbb clock controller.
The diffstat is -190, which is nice as well.

As a consequence of the shift to platform_driver, all of clocks are
registered at module_init time. If any are needed very early during boot
then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
necessary.

Additionally this series makes use of some of the nice clk_hw helper
introduced by Stephen, especially clk_hw_onecell_data.

Michael Turquette (10):
  clk: meson8b: rectify reg offsets with datasheet
  clk: meson8b: clean up fixed rate clocks
  clk: meson8b: clean up pll clocks
  clk: meson8b: clean up fixed factor clocks
  clk: meson8b: clean up cpu clocks
  clk: meson8b: remove mali clk
  clk: meson8b: clean up composite clocks
  clk: meson8b: convert to platform_driver
  arm: meson: explicitly select clk drivers
  clk: meson: only build selected platforms

 arch/arm/mach-meson/Kconfig              |   3 +
 drivers/clk/Kconfig                      |   1 +
 drivers/clk/Makefile                     |   2 +-
 drivers/clk/meson/Kconfig                |  12 +
 drivers/clk/meson/Makefile               |   4 +-
 drivers/clk/meson/clk-cpu.c              |  73 +-----
 drivers/clk/meson/clk-pll.c              |  72 +----
 drivers/clk/meson/clkc.c                 | 249 ------------------
 drivers/clk/meson/clkc.h                 | 150 ++---------
 drivers/clk/meson/meson8b-clkc.c         | 436 +++++++++++++++++++++++++------
 include/dt-bindings/clock/meson8b-clkc.h |   4 +-
 11 files changed, 408 insertions(+), 598 deletions(-)
 create mode 100644 drivers/clk/meson/Kconfig
 delete mode 100644 drivers/clk/meson/clkc.c

-- 
2.1.4

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 00/10] meson8b clock driver rewrite/cleanup
@ 2016-06-10  0:27 ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

This series came about while writing the clock driver for the AmLogic
GXBB clock controller. GXBB shares much of the same clock controller IP
as the Meson8b clock controller and the source for the drivers is very
similar. However, I wanted the GXBB driver to actually be a real
platform_driver, and not an early initcall, which led to the same
changes in the Meson8b driver. From there a lot of other changes came
about.

This series improves documentation, refactors statically initialized
data, removes unnecessary registration functions and converts the
meson8b clock controller code into a proper platform_driver. It also
changes up the Kconfig bits to prepare for the gxbb clock controller.
The diffstat is -190, which is nice as well.

As a consequence of the shift to platform_driver, all of clocks are
registered at module_init time. If any are needed very early during boot
then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
necessary.

Additionally this series makes use of some of the nice clk_hw helper
introduced by Stephen, especially clk_hw_onecell_data.

Michael Turquette (10):
  clk: meson8b: rectify reg offsets with datasheet
  clk: meson8b: clean up fixed rate clocks
  clk: meson8b: clean up pll clocks
  clk: meson8b: clean up fixed factor clocks
  clk: meson8b: clean up cpu clocks
  clk: meson8b: remove mali clk
  clk: meson8b: clean up composite clocks
  clk: meson8b: convert to platform_driver
  arm: meson: explicitly select clk drivers
  clk: meson: only build selected platforms

 arch/arm/mach-meson/Kconfig              |   3 +
 drivers/clk/Kconfig                      |   1 +
 drivers/clk/Makefile                     |   2 +-
 drivers/clk/meson/Kconfig                |  12 +
 drivers/clk/meson/Makefile               |   4 +-
 drivers/clk/meson/clk-cpu.c              |  73 +-----
 drivers/clk/meson/clk-pll.c              |  72 +----
 drivers/clk/meson/clkc.c                 | 249 ------------------
 drivers/clk/meson/clkc.h                 | 150 ++---------
 drivers/clk/meson/meson8b-clkc.c         | 436 +++++++++++++++++++++++++------
 include/dt-bindings/clock/meson8b-clkc.h |   4 +-
 11 files changed, 408 insertions(+), 598 deletions(-)
 create mode 100644 drivers/clk/meson/Kconfig
 delete mode 100644 drivers/clk/meson/clkc.c

-- 
2.1.4

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/10] clk: meson8b: rectify reg offsets with datasheet
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

The register offsets in the data sheet are confusing. Document them more
thoroughly.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/meson8b-clkc.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 4d057b3..444ef94 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -24,10 +24,19 @@
 
 #include "clkc.h"
 
+/*
+ * Clock controller register offsets
+ *
+ * Register offsets from the HardKernel[0] data sheet are listed in comment
+ * blocks below. Those offsets must be multiplied by 4 before adding them to
+ * the base address to get the right value
+ *
+ * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
+ */
 #define MESON8B_REG_CTL0_ADDR		0x0000
-#define MESON8B_REG_SYS_CPU_CNTL1	0x015c
-#define MESON8B_REG_HHI_MPEG		0x0174
-#define MESON8B_REG_MALI		0x01b0
+#define MESON8B_REG_SYS_CPU_CNTL1	0x015c /* 0x57 offset in data sheet */
+#define MESON8B_REG_HHI_MPEG		0x0174 /* 0x5d offset in data sheet */
+#define MESON8B_REG_MALI		0x01b0 /* 0x6c offset in data sheet */
 #define MESON8B_REG_PLL_FIXED		0x0280
 #define MESON8B_REG_PLL_SYS		0x0300
 #define MESON8B_REG_PLL_VID		0x0320
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 01/10] clk: meson8b: rectify reg offsets with datasheet
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

The register offsets in the data sheet are confusing. Document them more
thoroughly.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/meson8b-clkc.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 4d057b3..444ef94 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -24,10 +24,19 @@
 
 #include "clkc.h"
 
+/*
+ * Clock controller register offsets
+ *
+ * Register offsets from the HardKernel[0] data sheet are listed in comment
+ * blocks below. Those offsets must be multiplied by 4 before adding them to
+ * the base address to get the right value
+ *
+ * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
+ */
 #define MESON8B_REG_CTL0_ADDR		0x0000
-#define MESON8B_REG_SYS_CPU_CNTL1	0x015c
-#define MESON8B_REG_HHI_MPEG		0x0174
-#define MESON8B_REG_MALI		0x01b0
+#define MESON8B_REG_SYS_CPU_CNTL1	0x015c /* 0x57 offset in data sheet */
+#define MESON8B_REG_HHI_MPEG		0x0174 /* 0x5d offset in data sheet */
+#define MESON8B_REG_MALI		0x01b0 /* 0x6c offset in data sheet */
 #define MESON8B_REG_PLL_FIXED		0x0280
 #define MESON8B_REG_PLL_SYS		0x0300
 #define MESON8B_REG_PLL_VID		0x0320
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/10] clk: meson8b: clean up fixed rate clocks
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

Remove the fixed_rate registration function and helpers from clkc.[ch].
Replace unnecessary configuration struct with static initialization of
the desired clock type.

While we're here, begin the transition to a proper platform_driver and
call of_clk_add_hw_provider with a shiny new struct clk_hw_onecell_data.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clkc.c         | 34 --------------------
 drivers/clk/meson/clkc.h         | 26 ---------------
 drivers/clk/meson/meson8b-clkc.c | 69 +++++++++++++++++++++++++++++++---------
 3 files changed, 54 insertions(+), 75 deletions(-)

diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index d920d41..c6802fd 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -167,36 +167,6 @@ meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,
 	return clk;
 }
 
-static struct clk * __init
-meson_clk_register_fixed_rate(const struct clk_conf *clk_conf,
-			      void __iomem *clk_base)
-{
-	struct clk *clk;
-	const struct fixed_rate_conf *fixed_rate_conf;
-	const struct parm *r;
-	unsigned long rate;
-	u32 reg;
-
-	fixed_rate_conf = &clk_conf->conf.fixed_rate;
-	rate = fixed_rate_conf->rate;
-
-	if (!rate) {
-		r = &fixed_rate_conf->rate_parm;
-		reg = readl(clk_base + clk_conf->reg_off + r->reg_off);
-		rate = PARM_GET(r->width, r->shift, reg);
-	}
-
-	rate *= 1000000;
-
-	clk = clk_register_fixed_rate(NULL,
-			clk_conf->clk_name,
-			clk_conf->num_parents
-				? clk_conf->clks_parent[0] : NULL,
-			clk_conf->flags, rate);
-
-	return clk;
-}
-
 void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 				    unsigned int nr_confs,
 				    void __iomem *clk_base)
@@ -208,10 +178,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 		const struct clk_conf *clk_conf = &clk_confs[i];
 
 		switch (clk_conf->clk_type) {
-		case CLK_FIXED_RATE:
-			clk = meson_clk_register_fixed_rate(clk_conf,
-							    clk_base);
-			break;
 		case CLK_FIXED_FACTOR:
 			clk = meson_clk_register_fixed_factor(clk_conf,
 							      clk_base);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 609ae92..b23b057 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -69,11 +69,6 @@ struct fixed_fact_conf {
 	struct parm	mult_parm;
 };
 
-struct fixed_rate_conf {
-	unsigned long	rate;
-	struct parm	rate_parm;
-};
-
 struct composite_conf {
 	struct parm		mux_parm;
 	struct parm		div_parm;
@@ -89,7 +84,6 @@ struct composite_conf {
 
 enum clk_type {
 	CLK_FIXED_FACTOR,
-	CLK_FIXED_RATE,
 	CLK_COMPOSITE,
 	CLK_CPU,
 	CLK_PLL,
@@ -105,32 +99,12 @@ struct clk_conf {
 	unsigned long			flags;
 	union {
 		struct fixed_fact_conf		fixed_fact;
-		struct fixed_rate_conf		fixed_rate;
 		const struct composite_conf		*composite;
 		struct pll_conf			*pll;
 		const struct clk_div_table	*div_table;
 	} conf;
 };
 
-#define FIXED_RATE_P(_ro, _ci, _cn, _f, _c)				\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_FIXED_RATE,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.flags				= (_f),			\
-		.conf.fixed_rate.rate_parm	= _c,			\
-	}								\
-
-#define FIXED_RATE(_ci, _cn, _f, _r)					\
-	{								\
-		.clk_type			= CLK_FIXED_RATE,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.flags				= (_f),			\
-		.conf.fixed_rate.rate		= (_r),			\
-	}								\
-
 #define PLL(_ro, _ci, _cn, _cp, _f, _c)					\
 	{								\
 		.reg_off			= (_ro),		\
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 444ef94..9afd480 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -33,7 +33,6 @@
  *
  * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
  */
-#define MESON8B_REG_CTL0_ADDR		0x0000
 #define MESON8B_REG_SYS_CPU_CNTL1	0x015c /* 0x57 offset in data sheet */
 #define MESON8B_REG_HHI_MPEG		0x0174 /* 0x5d offset in data sheet */
 #define MESON8B_REG_MALI		0x01b0 /* 0x6c offset in data sheet */
@@ -149,12 +148,25 @@ static const struct composite_conf mali_conf __initconst = {
 	.gate_parm		= PARM(0x00, 8, 1),
 };
 
-static const struct clk_conf meson8b_xtal_conf __initconst =
-	FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 0,
-			PARM(0x00, 4, 7));
+static struct clk_fixed_rate meson8b_xtal = {
+	.fixed_rate = 24000000,
+	.hw.init = &(struct clk_init_data){
+		.name = "xtal",
+		.num_parents = 0,
+		.ops = &clk_fixed_rate_ops,
+	},
+};
+
+static struct clk_fixed_rate meson8b_zero = {
+	.fixed_rate = 0,
+	.hw.init = &(struct clk_init_data){
+		.name = "zero",
+		.num_parents = 0,
+		.ops = &clk_fixed_rate_ops,
+	},
+};
 
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	FIXED_RATE(CLKID_ZERO, "zero", 0, 0),
 	PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
 	    p_xtal, 0, &pll_confs),
 	PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
@@ -174,23 +186,29 @@ static const struct clk_conf meson8b_clk_confs[] __initconst = {
 		  CLK_IGNORE_UNUSED, &mali_conf),
 };
 
+/*
+ * FIXME we cannot register two providers w/o breaking things. Luckily only
+ * clk81 is actually used by any drivers. Convert clk81 to use
+ * clk_hw_onecell_data last and flip the switch to call of_clk_add_hw_provider
+ * instead of of_clk_add_provider in the clk81 conversion patch to keep from
+ * breaking bisect. Then delete this comment ;-)
+ */
+static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
+	.hws = {
+		[CLKID_XTAL] = &meson8b_xtal.hw,
+		[CLKID_ZERO] = &meson8b_zero.hw,
+	},
+	.num = CLK_NR_CLKS,
+};
+
 static void __init meson8b_clkc_init(struct device_node *np)
 {
 	void __iomem *clk_base;
+	int ret, clkid;
 
 	if (!meson_clk_init(np, CLK_NR_CLKS))
 		return;
 
-	/* XTAL */
-	clk_base = of_iomap(np, 0);
-	if (!clk_base) {
-		pr_err("%s: Unable to map xtal base\n", __func__);
-		return;
-	}
-
-	meson_clk_register_clks(&meson8b_xtal_conf, 1, clk_base);
-	iounmap(clk_base);
-
 	/*  Generic clocks and PLLs */
 	clk_base = of_iomap(np, 1);
 	if (!clk_base) {
@@ -198,8 +216,29 @@ static void __init meson8b_clkc_init(struct device_node *np)
 		return;
 	}
 
+	/*
+	 * register all clks
+	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
+	 */
+	for (clkid = CLKID_XTAL; clkid < CLK_NR_CLKS; clkid++) {
+		/* array might be sparse */
+		if (!meson8b_hw_onecell_data.hws[clkid])
+			continue;
+
+		/* FIXME convert to devm_clk_register */
+		ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[clkid]);
+		if (ret)
+			goto unregister;
+	}
+
 	meson_clk_register_clks(meson8b_clk_confs,
 				ARRAY_SIZE(meson8b_clk_confs),
 				clk_base);
+	return;
+
+/* FIXME remove after converting to platform_driver/devm_clk_register */
+unregister:
+	for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--)
+		clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);
 }
 CLK_OF_DECLARE(meson8b_clock, "amlogic,meson8b-clkc", meson8b_clkc_init);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/10] clk: meson8b: clean up fixed rate clocks
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

Remove the fixed_rate registration function and helpers from clkc.[ch].
Replace unnecessary configuration struct with static initialization of
the desired clock type.

While we're here, begin the transition to a proper platform_driver and
call of_clk_add_hw_provider with a shiny new struct clk_hw_onecell_data.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clkc.c         | 34 --------------------
 drivers/clk/meson/clkc.h         | 26 ---------------
 drivers/clk/meson/meson8b-clkc.c | 69 +++++++++++++++++++++++++++++++---------
 3 files changed, 54 insertions(+), 75 deletions(-)

diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index d920d41..c6802fd 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -167,36 +167,6 @@ meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,
 	return clk;
 }
 
-static struct clk * __init
-meson_clk_register_fixed_rate(const struct clk_conf *clk_conf,
-			      void __iomem *clk_base)
-{
-	struct clk *clk;
-	const struct fixed_rate_conf *fixed_rate_conf;
-	const struct parm *r;
-	unsigned long rate;
-	u32 reg;
-
-	fixed_rate_conf = &clk_conf->conf.fixed_rate;
-	rate = fixed_rate_conf->rate;
-
-	if (!rate) {
-		r = &fixed_rate_conf->rate_parm;
-		reg = readl(clk_base + clk_conf->reg_off + r->reg_off);
-		rate = PARM_GET(r->width, r->shift, reg);
-	}
-
-	rate *= 1000000;
-
-	clk = clk_register_fixed_rate(NULL,
-			clk_conf->clk_name,
-			clk_conf->num_parents
-				? clk_conf->clks_parent[0] : NULL,
-			clk_conf->flags, rate);
-
-	return clk;
-}
-
 void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 				    unsigned int nr_confs,
 				    void __iomem *clk_base)
@@ -208,10 +178,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 		const struct clk_conf *clk_conf = &clk_confs[i];
 
 		switch (clk_conf->clk_type) {
-		case CLK_FIXED_RATE:
-			clk = meson_clk_register_fixed_rate(clk_conf,
-							    clk_base);
-			break;
 		case CLK_FIXED_FACTOR:
 			clk = meson_clk_register_fixed_factor(clk_conf,
 							      clk_base);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 609ae92..b23b057 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -69,11 +69,6 @@ struct fixed_fact_conf {
 	struct parm	mult_parm;
 };
 
-struct fixed_rate_conf {
-	unsigned long	rate;
-	struct parm	rate_parm;
-};
-
 struct composite_conf {
 	struct parm		mux_parm;
 	struct parm		div_parm;
@@ -89,7 +84,6 @@ struct composite_conf {
 
 enum clk_type {
 	CLK_FIXED_FACTOR,
-	CLK_FIXED_RATE,
 	CLK_COMPOSITE,
 	CLK_CPU,
 	CLK_PLL,
@@ -105,32 +99,12 @@ struct clk_conf {
 	unsigned long			flags;
 	union {
 		struct fixed_fact_conf		fixed_fact;
-		struct fixed_rate_conf		fixed_rate;
 		const struct composite_conf		*composite;
 		struct pll_conf			*pll;
 		const struct clk_div_table	*div_table;
 	} conf;
 };
 
-#define FIXED_RATE_P(_ro, _ci, _cn, _f, _c)				\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_FIXED_RATE,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.flags				= (_f),			\
-		.conf.fixed_rate.rate_parm	= _c,			\
-	}								\
-
-#define FIXED_RATE(_ci, _cn, _f, _r)					\
-	{								\
-		.clk_type			= CLK_FIXED_RATE,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.flags				= (_f),			\
-		.conf.fixed_rate.rate		= (_r),			\
-	}								\
-
 #define PLL(_ro, _ci, _cn, _cp, _f, _c)					\
 	{								\
 		.reg_off			= (_ro),		\
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 444ef94..9afd480 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -33,7 +33,6 @@
  *
  * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
  */
-#define MESON8B_REG_CTL0_ADDR		0x0000
 #define MESON8B_REG_SYS_CPU_CNTL1	0x015c /* 0x57 offset in data sheet */
 #define MESON8B_REG_HHI_MPEG		0x0174 /* 0x5d offset in data sheet */
 #define MESON8B_REG_MALI		0x01b0 /* 0x6c offset in data sheet */
@@ -149,12 +148,25 @@ static const struct composite_conf mali_conf __initconst = {
 	.gate_parm		= PARM(0x00, 8, 1),
 };
 
-static const struct clk_conf meson8b_xtal_conf __initconst =
-	FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 0,
-			PARM(0x00, 4, 7));
+static struct clk_fixed_rate meson8b_xtal = {
+	.fixed_rate = 24000000,
+	.hw.init = &(struct clk_init_data){
+		.name = "xtal",
+		.num_parents = 0,
+		.ops = &clk_fixed_rate_ops,
+	},
+};
+
+static struct clk_fixed_rate meson8b_zero = {
+	.fixed_rate = 0,
+	.hw.init = &(struct clk_init_data){
+		.name = "zero",
+		.num_parents = 0,
+		.ops = &clk_fixed_rate_ops,
+	},
+};
 
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	FIXED_RATE(CLKID_ZERO, "zero", 0, 0),
 	PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
 	    p_xtal, 0, &pll_confs),
 	PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
@@ -174,23 +186,29 @@ static const struct clk_conf meson8b_clk_confs[] __initconst = {
 		  CLK_IGNORE_UNUSED, &mali_conf),
 };
 
+/*
+ * FIXME we cannot register two providers w/o breaking things. Luckily only
+ * clk81 is actually used by any drivers. Convert clk81 to use
+ * clk_hw_onecell_data last and flip the switch to call of_clk_add_hw_provider
+ * instead of of_clk_add_provider in the clk81 conversion patch to keep from
+ * breaking bisect. Then delete this comment ;-)
+ */
+static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
+	.hws = {
+		[CLKID_XTAL] = &meson8b_xtal.hw,
+		[CLKID_ZERO] = &meson8b_zero.hw,
+	},
+	.num = CLK_NR_CLKS,
+};
+
 static void __init meson8b_clkc_init(struct device_node *np)
 {
 	void __iomem *clk_base;
+	int ret, clkid;
 
 	if (!meson_clk_init(np, CLK_NR_CLKS))
 		return;
 
-	/* XTAL */
-	clk_base = of_iomap(np, 0);
-	if (!clk_base) {
-		pr_err("%s: Unable to map xtal base\n", __func__);
-		return;
-	}
-
-	meson_clk_register_clks(&meson8b_xtal_conf, 1, clk_base);
-	iounmap(clk_base);
-
 	/*  Generic clocks and PLLs */
 	clk_base = of_iomap(np, 1);
 	if (!clk_base) {
@@ -198,8 +216,29 @@ static void __init meson8b_clkc_init(struct device_node *np)
 		return;
 	}
 
+	/*
+	 * register all clks
+	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
+	 */
+	for (clkid = CLKID_XTAL; clkid < CLK_NR_CLKS; clkid++) {
+		/* array might be sparse */
+		if (!meson8b_hw_onecell_data.hws[clkid])
+			continue;
+
+		/* FIXME convert to devm_clk_register */
+		ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[clkid]);
+		if (ret)
+			goto unregister;
+	}
+
 	meson_clk_register_clks(meson8b_clk_confs,
 				ARRAY_SIZE(meson8b_clk_confs),
 				clk_base);
+	return;
+
+/* FIXME remove after converting to platform_driver/devm_clk_register */
+unregister:
+	for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--)
+		clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);
 }
 CLK_OF_DECLARE(meson8b_clock, "amlogic,meson8b-clkc", meson8b_clkc_init);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/10] clk: meson8b: clean up pll clocks
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

Remove the pll registration function and helpers. Replace unnecessary
configuration struct with static initialization of the desired clock
type.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clk-pll.c      |  72 ++++--------------------
 drivers/clk/meson/clkc.c         |   6 +-
 drivers/clk/meson/clkc.h         |  52 +++++++++---------
 drivers/clk/meson/meson8b-clkc.c | 115 ++++++++++++++++++++++++++++++++-------
 4 files changed, 131 insertions(+), 114 deletions(-)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 664edf0..60c6b94 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -44,13 +44,6 @@
 #define MESON_PLL_RESET				BIT(29)
 #define MESON_PLL_LOCK				BIT(31)
 
-struct meson_clk_pll {
-	struct clk_hw	hw;
-	void __iomem	*base;
-	struct pll_conf	*conf;
-	unsigned int	rate_count;
-	spinlock_t	*lock;
-};
 #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 
 static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
@@ -63,15 +56,15 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
 	u16 n, m, od;
 	u32 reg;
 
-	p = &pll->conf->n;
+	p = &pll->n;
 	reg = readl(pll->base + p->reg_off);
 	n = PARM_GET(p->width, p->shift, reg);
 
-	p = &pll->conf->m;
+	p = &pll->m;
 	reg = readl(pll->base + p->reg_off);
 	m = PARM_GET(p->width, p->shift, reg);
 
-	p = &pll->conf->od;
+	p = &pll->od;
 	reg = readl(pll->base + p->reg_off);
 	od = PARM_GET(p->width, p->shift, reg);
 
@@ -84,7 +77,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long *parent_rate)
 {
 	struct meson_clk_pll *pll = to_meson_clk_pll(hw);
-	const struct pll_rate_table *rate_table = pll->conf->rate_table;
+	const struct pll_rate_table *rate_table = pll->rate_table;
 	int i;
 
 	for (i = 0; i < pll->rate_count; i++) {
@@ -99,7 +92,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll,
 							       unsigned long rate)
 {
-	const struct pll_rate_table *rate_table = pll->conf->rate_table;
+	const struct pll_rate_table *rate_table = pll->rate_table;
 	int i;
 
 	for (i = 0; i < pll->rate_count; i++) {
@@ -145,24 +138,24 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 		return -EINVAL;
 
 	/* PLL reset */
-	p = &pll->conf->n;
+	p = &pll->n;
 	reg = readl(pll->base + p->reg_off);
 	writel(reg | MESON_PLL_RESET, pll->base + p->reg_off);
 
 	reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
 	writel(reg, pll->base + p->reg_off);
 
-	p = &pll->conf->m;
+	p = &pll->m;
 	reg = readl(pll->base + p->reg_off);
 	reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
 	writel(reg, pll->base + p->reg_off);
 
-	p = &pll->conf->od;
+	p = &pll->od;
 	reg = readl(pll->base + p->reg_off);
 	reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
 	writel(reg, pll->base + p->reg_off);
 
-	p = &pll->conf->n;
+	p = &pll->n;
 	ret = meson_clk_pll_wait_lock(pll, p);
 	if (ret) {
 		pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
@@ -173,55 +166,12 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	return ret;
 }
 
-static const struct clk_ops meson_clk_pll_ops = {
+const struct clk_ops meson_clk_pll_ops = {
 	.recalc_rate	= meson_clk_pll_recalc_rate,
 	.round_rate	= meson_clk_pll_round_rate,
 	.set_rate	= meson_clk_pll_set_rate,
 };
 
-static const struct clk_ops meson_clk_pll_ro_ops = {
+const struct clk_ops meson_clk_pll_ro_ops = {
 	.recalc_rate	= meson_clk_pll_recalc_rate,
 };
-
-struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base,
-				   spinlock_t *lock)
-{
-	struct clk *clk;
-	struct meson_clk_pll *clk_pll;
-	struct clk_init_data init;
-
-	clk_pll = kzalloc(sizeof(*clk_pll), GFP_KERNEL);
-	if (!clk_pll)
-		return ERR_PTR(-ENOMEM);
-
-	clk_pll->base = reg_base + clk_conf->reg_off;
-	clk_pll->lock = lock;
-	clk_pll->conf = clk_conf->conf.pll;
-
-	init.name = clk_conf->clk_name;
-	init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
-
-	init.parent_names = &clk_conf->clks_parent[0];
-	init.num_parents = 1;
-	init.ops = &meson_clk_pll_ro_ops;
-
-	/* If no rate_table is specified we assume the PLL is read-only */
-	if (clk_pll->conf->rate_table) {
-		int len;
-
-		for (len = 0; clk_pll->conf->rate_table[len].rate != 0; )
-			len++;
-
-		 clk_pll->rate_count = len;
-		 init.ops = &meson_clk_pll_ops;
-	}
-
-	clk_pll->hw.init = &init;
-
-	clk = clk_register(NULL, &clk_pll->hw);
-	if (IS_ERR(clk))
-		kfree(clk_pll);
-
-	return clk;
-}
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index c6802fd..2161ea3 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -21,7 +21,7 @@
 
 #include "clkc.h"
 
-static DEFINE_SPINLOCK(clk_lock);
+DEFINE_SPINLOCK(clk_lock);
 
 static struct clk **clks;
 static struct clk_onecell_data clk_data;
@@ -190,10 +190,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 			clk = meson_clk_register_cpu(clk_conf, clk_base,
 						     &clk_lock);
 			break;
-		case CLK_PLL:
-			clk = meson_clk_register_pll(clk_conf, clk_base,
-						     &clk_lock);
-			break;
 		default:
 			clk = NULL;
 		}
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index b23b057..0bb4fb8 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -34,12 +34,13 @@ struct parm {
 	u8	shift;
 	u8	width;
 };
-#define PARM(_r, _s, _w)						\
-	{								\
-		.reg_off	= (_r),					\
-		.shift		= (_s),					\
-		.width		= (_w),					\
-	}								\
+
+#define PARM(_r, _s, _w)                                               \
+{                                                                      \
+	.reg_off        = (_r),                                        \
+	.shift          = (_s),                                        \
+	.width          = (_w),                                        \
+}                                                                      \
 
 struct pll_rate_table {
 	unsigned long	rate;
@@ -55,13 +56,19 @@ struct pll_rate_table {
 		.od		= (_od),				\
 	}								\
 
-struct pll_conf {
-	const struct pll_rate_table	*rate_table;
-	struct parm			m;
-	struct parm			n;
-	struct parm			od;
+struct meson_clk_pll {
+	struct clk_hw hw;
+	void __iomem *base;
+	struct parm m;
+	struct parm n;
+	struct parm od;
+	const struct pll_rate_table *rate_table;
+	unsigned int rate_count;
+	spinlock_t *lock;
 };
 
+#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
+
 struct fixed_fact_conf {
 	unsigned int	div;
 	unsigned int	mult;
@@ -86,7 +93,6 @@ enum clk_type {
 	CLK_FIXED_FACTOR,
 	CLK_COMPOSITE,
 	CLK_CPU,
-	CLK_PLL,
 };
 
 struct clk_conf {
@@ -100,23 +106,10 @@ struct clk_conf {
 	union {
 		struct fixed_fact_conf		fixed_fact;
 		const struct composite_conf		*composite;
-		struct pll_conf			*pll;
 		const struct clk_div_table	*div_table;
 	} conf;
 };
 
-#define PLL(_ro, _ci, _cn, _cp, _f, _c)					\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_PLL,		\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.flags				= (_f),			\
-		.conf.pll			= (_c),			\
-	}								\
-
 #define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d)				\
 	{								\
 		.clk_type			= CLK_FIXED_FACTOR,	\
@@ -155,7 +148,12 @@ void meson_clk_register_clks(const struct clk_conf *clk_confs,
 			     unsigned int nr_confs, void __iomem *clk_base);
 struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
 				   void __iomem *reg_base, spinlock_t *lock);
-struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base, spinlock_t *lock);
+
+/* shared data */
+extern spinlock_t clk_lock;
+
+/* clk_ops */
+extern const struct clk_ops meson_clk_pll_ro_ops;
+extern const struct clk_ops meson_clk_pll_ops;
 
 #endif /* __CLKC_H */
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 9afd480..a3d8e66 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -110,7 +110,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_xtal)		= { "xtal" };
 PNAME(p_fclk_div)	= { "fixed_pll" };
 PNAME(p_cpu_clk)	= { "sys_pll" };
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
@@ -120,19 +119,6 @@ PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
 static u32 mux_table_clk81[]	= { 6, 5, 7 };
 static u32 mux_table_mali[]	= { 6, 5, 7, 4, 0 };
 
-static struct pll_conf pll_confs = {
-	.m		= PARM(0x00, 0,  9),
-	.n		= PARM(0x00, 9,  5),
-	.od		= PARM(0x00, 16, 2),
-};
-
-static struct pll_conf sys_pll_conf = {
-	.m		= PARM(0x00, 0,  9),
-	.n		= PARM(0x00, 9,  5),
-	.od		= PARM(0x00, 16, 2),
-	.rate_table	= sys_pll_rate_table,
-};
-
 static const struct composite_conf clk81_conf __initconst = {
 	.mux_table		= mux_table_clk81,
 	.mux_flags		= CLK_MUX_READ_ONLY,
@@ -166,13 +152,87 @@ static struct clk_fixed_rate meson8b_zero = {
 	},
 };
 
+static struct meson_clk_pll meson8b_fixed_pll = {
+	.m = {
+		.reg_off = MESON8B_REG_PLL_FIXED,
+		.shift   = 0,
+		.width   = 9,
+	},
+	.n = {
+		.reg_off = MESON8B_REG_PLL_FIXED,
+		.shift   = 9,
+		.width   = 5,
+	},
+	.od = {
+		.reg_off = MESON8B_REG_PLL_FIXED,
+		.shift   = 16,
+		.width   = 2,
+	},
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "fixed_pll",
+		.ops = &meson_clk_pll_ro_ops,
+		.parent_names = (const char *[]){ "xtal" },
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct meson_clk_pll meson8b_vid_pll = {
+	.m = {
+		.reg_off = MESON8B_REG_PLL_VID,
+		.shift   = 0,
+		.width   = 9,
+	},
+	.n = {
+		.reg_off = MESON8B_REG_PLL_VID,
+		.shift   = 9,
+		.width   = 5,
+	},
+	.od = {
+		.reg_off = MESON8B_REG_PLL_VID,
+		.shift   = 16,
+		.width   = 2,
+	},
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "vid_pll",
+		.ops = &meson_clk_pll_ro_ops,
+		.parent_names = (const char *[]){ "xtal" },
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct meson_clk_pll meson8b_sys_pll = {
+	.m = {
+		.reg_off = MESON8B_REG_PLL_SYS,
+		.shift   = 0,
+		.width   = 9,
+	},
+	.n = {
+		.reg_off = MESON8B_REG_PLL_SYS,
+		.shift   = 9,
+		.width   = 5,
+	},
+	.od = {
+		.reg_off = MESON8B_REG_PLL_SYS,
+		.shift   = 16,
+		.width   = 2,
+	},
+	.rate_table = sys_pll_rate_table,
+	.rate_count = ARRAY_SIZE(sys_pll_rate_table),
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_pll",
+		.ops = &meson_clk_pll_ops,
+		.parent_names = (const char *[]){ "xtal" },
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
-	    p_xtal, 0, &pll_confs),
-	PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
-	    p_xtal, 0, &pll_confs),
-	PLL(MESON8B_REG_PLL_SYS, CLKID_PLL_SYS, "sys_pll",
-	    p_xtal, 0, &sys_pll_conf),
 	FIXED_FACTOR_DIV(CLKID_FCLK_DIV2, "fclk_div2", p_fclk_div, 0, 2),
 	FIXED_FACTOR_DIV(CLKID_FCLK_DIV3, "fclk_div3", p_fclk_div, 0, 3),
 	FIXED_FACTOR_DIV(CLKID_FCLK_DIV4, "fclk_div4", p_fclk_div, 0, 4),
@@ -197,14 +257,23 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 	.hws = {
 		[CLKID_XTAL] = &meson8b_xtal.hw,
 		[CLKID_ZERO] = &meson8b_zero.hw,
+		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
+		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
+		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
 
+static struct meson_clk_pll *const meson8b_clk_plls[] = {
+	&meson8b_fixed_pll,
+	&meson8b_vid_pll,
+	&meson8b_sys_pll,
+};
+
 static void __init meson8b_clkc_init(struct device_node *np)
 {
 	void __iomem *clk_base;
-	int ret, clkid;
+	int ret, clkid, i;
 
 	if (!meson_clk_init(np, CLK_NR_CLKS))
 		return;
@@ -216,6 +285,10 @@ static void __init meson8b_clkc_init(struct device_node *np)
 		return;
 	}
 
+	/* Populate base address for PLLs */
+	for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
+		meson8b_clk_plls[i]->base = clk_base;
+
 	/*
 	 * register all clks
 	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/10] clk: meson8b: clean up pll clocks
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

Remove the pll registration function and helpers. Replace unnecessary
configuration struct with static initialization of the desired clock
type.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clk-pll.c      |  72 ++++--------------------
 drivers/clk/meson/clkc.c         |   6 +-
 drivers/clk/meson/clkc.h         |  52 +++++++++---------
 drivers/clk/meson/meson8b-clkc.c | 115 ++++++++++++++++++++++++++++++++-------
 4 files changed, 131 insertions(+), 114 deletions(-)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 664edf0..60c6b94 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -44,13 +44,6 @@
 #define MESON_PLL_RESET				BIT(29)
 #define MESON_PLL_LOCK				BIT(31)
 
-struct meson_clk_pll {
-	struct clk_hw	hw;
-	void __iomem	*base;
-	struct pll_conf	*conf;
-	unsigned int	rate_count;
-	spinlock_t	*lock;
-};
 #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 
 static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
@@ -63,15 +56,15 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
 	u16 n, m, od;
 	u32 reg;
 
-	p = &pll->conf->n;
+	p = &pll->n;
 	reg = readl(pll->base + p->reg_off);
 	n = PARM_GET(p->width, p->shift, reg);
 
-	p = &pll->conf->m;
+	p = &pll->m;
 	reg = readl(pll->base + p->reg_off);
 	m = PARM_GET(p->width, p->shift, reg);
 
-	p = &pll->conf->od;
+	p = &pll->od;
 	reg = readl(pll->base + p->reg_off);
 	od = PARM_GET(p->width, p->shift, reg);
 
@@ -84,7 +77,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long *parent_rate)
 {
 	struct meson_clk_pll *pll = to_meson_clk_pll(hw);
-	const struct pll_rate_table *rate_table = pll->conf->rate_table;
+	const struct pll_rate_table *rate_table = pll->rate_table;
 	int i;
 
 	for (i = 0; i < pll->rate_count; i++) {
@@ -99,7 +92,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll,
 							       unsigned long rate)
 {
-	const struct pll_rate_table *rate_table = pll->conf->rate_table;
+	const struct pll_rate_table *rate_table = pll->rate_table;
 	int i;
 
 	for (i = 0; i < pll->rate_count; i++) {
@@ -145,24 +138,24 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 		return -EINVAL;
 
 	/* PLL reset */
-	p = &pll->conf->n;
+	p = &pll->n;
 	reg = readl(pll->base + p->reg_off);
 	writel(reg | MESON_PLL_RESET, pll->base + p->reg_off);
 
 	reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
 	writel(reg, pll->base + p->reg_off);
 
-	p = &pll->conf->m;
+	p = &pll->m;
 	reg = readl(pll->base + p->reg_off);
 	reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
 	writel(reg, pll->base + p->reg_off);
 
-	p = &pll->conf->od;
+	p = &pll->od;
 	reg = readl(pll->base + p->reg_off);
 	reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
 	writel(reg, pll->base + p->reg_off);
 
-	p = &pll->conf->n;
+	p = &pll->n;
 	ret = meson_clk_pll_wait_lock(pll, p);
 	if (ret) {
 		pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
@@ -173,55 +166,12 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	return ret;
 }
 
-static const struct clk_ops meson_clk_pll_ops = {
+const struct clk_ops meson_clk_pll_ops = {
 	.recalc_rate	= meson_clk_pll_recalc_rate,
 	.round_rate	= meson_clk_pll_round_rate,
 	.set_rate	= meson_clk_pll_set_rate,
 };
 
-static const struct clk_ops meson_clk_pll_ro_ops = {
+const struct clk_ops meson_clk_pll_ro_ops = {
 	.recalc_rate	= meson_clk_pll_recalc_rate,
 };
-
-struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base,
-				   spinlock_t *lock)
-{
-	struct clk *clk;
-	struct meson_clk_pll *clk_pll;
-	struct clk_init_data init;
-
-	clk_pll = kzalloc(sizeof(*clk_pll), GFP_KERNEL);
-	if (!clk_pll)
-		return ERR_PTR(-ENOMEM);
-
-	clk_pll->base = reg_base + clk_conf->reg_off;
-	clk_pll->lock = lock;
-	clk_pll->conf = clk_conf->conf.pll;
-
-	init.name = clk_conf->clk_name;
-	init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
-
-	init.parent_names = &clk_conf->clks_parent[0];
-	init.num_parents = 1;
-	init.ops = &meson_clk_pll_ro_ops;
-
-	/* If no rate_table is specified we assume the PLL is read-only */
-	if (clk_pll->conf->rate_table) {
-		int len;
-
-		for (len = 0; clk_pll->conf->rate_table[len].rate != 0; )
-			len++;
-
-		 clk_pll->rate_count = len;
-		 init.ops = &meson_clk_pll_ops;
-	}
-
-	clk_pll->hw.init = &init;
-
-	clk = clk_register(NULL, &clk_pll->hw);
-	if (IS_ERR(clk))
-		kfree(clk_pll);
-
-	return clk;
-}
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index c6802fd..2161ea3 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -21,7 +21,7 @@
 
 #include "clkc.h"
 
-static DEFINE_SPINLOCK(clk_lock);
+DEFINE_SPINLOCK(clk_lock);
 
 static struct clk **clks;
 static struct clk_onecell_data clk_data;
@@ -190,10 +190,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 			clk = meson_clk_register_cpu(clk_conf, clk_base,
 						     &clk_lock);
 			break;
-		case CLK_PLL:
-			clk = meson_clk_register_pll(clk_conf, clk_base,
-						     &clk_lock);
-			break;
 		default:
 			clk = NULL;
 		}
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index b23b057..0bb4fb8 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -34,12 +34,13 @@ struct parm {
 	u8	shift;
 	u8	width;
 };
-#define PARM(_r, _s, _w)						\
-	{								\
-		.reg_off	= (_r),					\
-		.shift		= (_s),					\
-		.width		= (_w),					\
-	}								\
+
+#define PARM(_r, _s, _w)                                               \
+{                                                                      \
+	.reg_off        = (_r),                                        \
+	.shift          = (_s),                                        \
+	.width          = (_w),                                        \
+}                                                                      \
 
 struct pll_rate_table {
 	unsigned long	rate;
@@ -55,13 +56,19 @@ struct pll_rate_table {
 		.od		= (_od),				\
 	}								\
 
-struct pll_conf {
-	const struct pll_rate_table	*rate_table;
-	struct parm			m;
-	struct parm			n;
-	struct parm			od;
+struct meson_clk_pll {
+	struct clk_hw hw;
+	void __iomem *base;
+	struct parm m;
+	struct parm n;
+	struct parm od;
+	const struct pll_rate_table *rate_table;
+	unsigned int rate_count;
+	spinlock_t *lock;
 };
 
+#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
+
 struct fixed_fact_conf {
 	unsigned int	div;
 	unsigned int	mult;
@@ -86,7 +93,6 @@ enum clk_type {
 	CLK_FIXED_FACTOR,
 	CLK_COMPOSITE,
 	CLK_CPU,
-	CLK_PLL,
 };
 
 struct clk_conf {
@@ -100,23 +106,10 @@ struct clk_conf {
 	union {
 		struct fixed_fact_conf		fixed_fact;
 		const struct composite_conf		*composite;
-		struct pll_conf			*pll;
 		const struct clk_div_table	*div_table;
 	} conf;
 };
 
-#define PLL(_ro, _ci, _cn, _cp, _f, _c)					\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_PLL,		\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.flags				= (_f),			\
-		.conf.pll			= (_c),			\
-	}								\
-
 #define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d)				\
 	{								\
 		.clk_type			= CLK_FIXED_FACTOR,	\
@@ -155,7 +148,12 @@ void meson_clk_register_clks(const struct clk_conf *clk_confs,
 			     unsigned int nr_confs, void __iomem *clk_base);
 struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
 				   void __iomem *reg_base, spinlock_t *lock);
-struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base, spinlock_t *lock);
+
+/* shared data */
+extern spinlock_t clk_lock;
+
+/* clk_ops */
+extern const struct clk_ops meson_clk_pll_ro_ops;
+extern const struct clk_ops meson_clk_pll_ops;
 
 #endif /* __CLKC_H */
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 9afd480..a3d8e66 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -110,7 +110,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_xtal)		= { "xtal" };
 PNAME(p_fclk_div)	= { "fixed_pll" };
 PNAME(p_cpu_clk)	= { "sys_pll" };
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
@@ -120,19 +119,6 @@ PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
 static u32 mux_table_clk81[]	= { 6, 5, 7 };
 static u32 mux_table_mali[]	= { 6, 5, 7, 4, 0 };
 
-static struct pll_conf pll_confs = {
-	.m		= PARM(0x00, 0,  9),
-	.n		= PARM(0x00, 9,  5),
-	.od		= PARM(0x00, 16, 2),
-};
-
-static struct pll_conf sys_pll_conf = {
-	.m		= PARM(0x00, 0,  9),
-	.n		= PARM(0x00, 9,  5),
-	.od		= PARM(0x00, 16, 2),
-	.rate_table	= sys_pll_rate_table,
-};
-
 static const struct composite_conf clk81_conf __initconst = {
 	.mux_table		= mux_table_clk81,
 	.mux_flags		= CLK_MUX_READ_ONLY,
@@ -166,13 +152,87 @@ static struct clk_fixed_rate meson8b_zero = {
 	},
 };
 
+static struct meson_clk_pll meson8b_fixed_pll = {
+	.m = {
+		.reg_off = MESON8B_REG_PLL_FIXED,
+		.shift   = 0,
+		.width   = 9,
+	},
+	.n = {
+		.reg_off = MESON8B_REG_PLL_FIXED,
+		.shift   = 9,
+		.width   = 5,
+	},
+	.od = {
+		.reg_off = MESON8B_REG_PLL_FIXED,
+		.shift   = 16,
+		.width   = 2,
+	},
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "fixed_pll",
+		.ops = &meson_clk_pll_ro_ops,
+		.parent_names = (const char *[]){ "xtal" },
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct meson_clk_pll meson8b_vid_pll = {
+	.m = {
+		.reg_off = MESON8B_REG_PLL_VID,
+		.shift   = 0,
+		.width   = 9,
+	},
+	.n = {
+		.reg_off = MESON8B_REG_PLL_VID,
+		.shift   = 9,
+		.width   = 5,
+	},
+	.od = {
+		.reg_off = MESON8B_REG_PLL_VID,
+		.shift   = 16,
+		.width   = 2,
+	},
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "vid_pll",
+		.ops = &meson_clk_pll_ro_ops,
+		.parent_names = (const char *[]){ "xtal" },
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct meson_clk_pll meson8b_sys_pll = {
+	.m = {
+		.reg_off = MESON8B_REG_PLL_SYS,
+		.shift   = 0,
+		.width   = 9,
+	},
+	.n = {
+		.reg_off = MESON8B_REG_PLL_SYS,
+		.shift   = 9,
+		.width   = 5,
+	},
+	.od = {
+		.reg_off = MESON8B_REG_PLL_SYS,
+		.shift   = 16,
+		.width   = 2,
+	},
+	.rate_table = sys_pll_rate_table,
+	.rate_count = ARRAY_SIZE(sys_pll_rate_table),
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_pll",
+		.ops = &meson_clk_pll_ops,
+		.parent_names = (const char *[]){ "xtal" },
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
-	    p_xtal, 0, &pll_confs),
-	PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
-	    p_xtal, 0, &pll_confs),
-	PLL(MESON8B_REG_PLL_SYS, CLKID_PLL_SYS, "sys_pll",
-	    p_xtal, 0, &sys_pll_conf),
 	FIXED_FACTOR_DIV(CLKID_FCLK_DIV2, "fclk_div2", p_fclk_div, 0, 2),
 	FIXED_FACTOR_DIV(CLKID_FCLK_DIV3, "fclk_div3", p_fclk_div, 0, 3),
 	FIXED_FACTOR_DIV(CLKID_FCLK_DIV4, "fclk_div4", p_fclk_div, 0, 4),
@@ -197,14 +257,23 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 	.hws = {
 		[CLKID_XTAL] = &meson8b_xtal.hw,
 		[CLKID_ZERO] = &meson8b_zero.hw,
+		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
+		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
+		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
 
+static struct meson_clk_pll *const meson8b_clk_plls[] = {
+	&meson8b_fixed_pll,
+	&meson8b_vid_pll,
+	&meson8b_sys_pll,
+};
+
 static void __init meson8b_clkc_init(struct device_node *np)
 {
 	void __iomem *clk_base;
-	int ret, clkid;
+	int ret, clkid, i;
 
 	if (!meson_clk_init(np, CLK_NR_CLKS))
 		return;
@@ -216,6 +285,10 @@ static void __init meson8b_clkc_init(struct device_node *np)
 		return;
 	}
 
+	/* Populate base address for PLLs */
+	for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
+		meson8b_clk_plls[i]->base = clk_base;
+
 	/*
 	 * register all clks
 	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/10] clk: meson8b: clean up fixed factor clocks
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

Remove the fixed factor registration function and helpers. Replace
unnecessary configuration struct with static initialization of the
desired clock type.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clkc.c         | 46 ----------------------------
 drivers/clk/meson/clkc.h         | 19 ------------
 drivers/clk/meson/meson8b-clkc.c | 66 ++++++++++++++++++++++++++++++++++++----
 3 files changed, 60 insertions(+), 71 deletions(-)

diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index 2161ea3..275da27 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -125,48 +125,6 @@ error:
 	return clk;
 }
 
-static struct clk * __init
-meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,
-				void __iomem *clk_base)
-{
-	struct clk *clk;
-	const struct fixed_fact_conf *fixed_fact_conf;
-	const struct parm *p;
-	unsigned int mult, div;
-	u32 reg;
-
-	fixed_fact_conf = &clk_conf->conf.fixed_fact;
-
-	mult = clk_conf->conf.fixed_fact.mult;
-	div = clk_conf->conf.fixed_fact.div;
-
-	if (!mult) {
-		mult = 1;
-		p = &fixed_fact_conf->mult_parm;
-		if (MESON_PARM_APPLICABLE(p)) {
-			reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
-			mult = PARM_GET(p->width, p->shift, reg);
-		}
-	}
-
-	if (!div) {
-		div = 1;
-		p = &fixed_fact_conf->div_parm;
-		if (MESON_PARM_APPLICABLE(p)) {
-			reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
-			mult = PARM_GET(p->width, p->shift, reg);
-		}
-	}
-
-	clk = clk_register_fixed_factor(NULL,
-			clk_conf->clk_name,
-			clk_conf->clks_parent[0],
-			clk_conf->flags,
-			mult, div);
-
-	return clk;
-}
-
 void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 				    unsigned int nr_confs,
 				    void __iomem *clk_base)
@@ -178,10 +136,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 		const struct clk_conf *clk_conf = &clk_confs[i];
 
 		switch (clk_conf->clk_type) {
-		case CLK_FIXED_FACTOR:
-			clk = meson_clk_register_fixed_factor(clk_conf,
-							      clk_base);
-			break;
 		case CLK_COMPOSITE:
 			clk = meson_clk_register_composite(clk_conf,
 							   clk_base);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 0bb4fb8..97dd4d7 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -69,13 +69,6 @@ struct meson_clk_pll {
 
 #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 
-struct fixed_fact_conf {
-	unsigned int	div;
-	unsigned int	mult;
-	struct parm	div_parm;
-	struct parm	mult_parm;
-};
-
 struct composite_conf {
 	struct parm		mux_parm;
 	struct parm		div_parm;
@@ -90,7 +83,6 @@ struct composite_conf {
 #define PNAME(x) static const char *x[]
 
 enum clk_type {
-	CLK_FIXED_FACTOR,
 	CLK_COMPOSITE,
 	CLK_CPU,
 };
@@ -104,22 +96,11 @@ struct clk_conf {
 	int				num_parents;
 	unsigned long			flags;
 	union {
-		struct fixed_fact_conf		fixed_fact;
 		const struct composite_conf		*composite;
 		const struct clk_div_table	*div_table;
 	} conf;
 };
 
-#define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d)				\
-	{								\
-		.clk_type			= CLK_FIXED_FACTOR,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.conf.fixed_fact.div		= (_d),			\
-	}								\
-
 #define CPU(_ro, _ci, _cn, _cp, _dt)					\
 	{								\
 		.reg_off			= (_ro),		\
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index a3d8e66..6571e66 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -110,7 +110,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_fclk_div)	= { "fixed_pll" };
 PNAME(p_cpu_clk)	= { "sys_pll" };
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
 PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
@@ -232,12 +231,62 @@ static struct meson_clk_pll meson8b_sys_pll = {
 	},
 };
 
+static struct clk_fixed_factor meson8b_fclk_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div3 = {
+	.mult = 1,
+	.div = 3,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div3",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div5 = {
+	.mult = 1,
+	.div = 5,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div5",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div7 = {
+	.mult = 1,
+	.div = 7,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div7",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV2, "fclk_div2", p_fclk_div, 0, 2),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV3, "fclk_div3", p_fclk_div, 0, 3),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV4, "fclk_div4", p_fclk_div, 0, 4),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV5, "fclk_div5", p_fclk_div, 0, 5),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV7, "fclk_div7", p_fclk_div, 0, 7),
 	CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk,
 	    cpu_div_table),
 	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
@@ -260,6 +309,11 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
 		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
 		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
+		[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
+		[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
+		[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
+		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
+		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/10] clk: meson8b: clean up fixed factor clocks
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

Remove the fixed factor registration function and helpers. Replace
unnecessary configuration struct with static initialization of the
desired clock type.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clkc.c         | 46 ----------------------------
 drivers/clk/meson/clkc.h         | 19 ------------
 drivers/clk/meson/meson8b-clkc.c | 66 ++++++++++++++++++++++++++++++++++++----
 3 files changed, 60 insertions(+), 71 deletions(-)

diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index 2161ea3..275da27 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -125,48 +125,6 @@ error:
 	return clk;
 }
 
-static struct clk * __init
-meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,
-				void __iomem *clk_base)
-{
-	struct clk *clk;
-	const struct fixed_fact_conf *fixed_fact_conf;
-	const struct parm *p;
-	unsigned int mult, div;
-	u32 reg;
-
-	fixed_fact_conf = &clk_conf->conf.fixed_fact;
-
-	mult = clk_conf->conf.fixed_fact.mult;
-	div = clk_conf->conf.fixed_fact.div;
-
-	if (!mult) {
-		mult = 1;
-		p = &fixed_fact_conf->mult_parm;
-		if (MESON_PARM_APPLICABLE(p)) {
-			reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
-			mult = PARM_GET(p->width, p->shift, reg);
-		}
-	}
-
-	if (!div) {
-		div = 1;
-		p = &fixed_fact_conf->div_parm;
-		if (MESON_PARM_APPLICABLE(p)) {
-			reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
-			mult = PARM_GET(p->width, p->shift, reg);
-		}
-	}
-
-	clk = clk_register_fixed_factor(NULL,
-			clk_conf->clk_name,
-			clk_conf->clks_parent[0],
-			clk_conf->flags,
-			mult, div);
-
-	return clk;
-}
-
 void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 				    unsigned int nr_confs,
 				    void __iomem *clk_base)
@@ -178,10 +136,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 		const struct clk_conf *clk_conf = &clk_confs[i];
 
 		switch (clk_conf->clk_type) {
-		case CLK_FIXED_FACTOR:
-			clk = meson_clk_register_fixed_factor(clk_conf,
-							      clk_base);
-			break;
 		case CLK_COMPOSITE:
 			clk = meson_clk_register_composite(clk_conf,
 							   clk_base);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 0bb4fb8..97dd4d7 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -69,13 +69,6 @@ struct meson_clk_pll {
 
 #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 
-struct fixed_fact_conf {
-	unsigned int	div;
-	unsigned int	mult;
-	struct parm	div_parm;
-	struct parm	mult_parm;
-};
-
 struct composite_conf {
 	struct parm		mux_parm;
 	struct parm		div_parm;
@@ -90,7 +83,6 @@ struct composite_conf {
 #define PNAME(x) static const char *x[]
 
 enum clk_type {
-	CLK_FIXED_FACTOR,
 	CLK_COMPOSITE,
 	CLK_CPU,
 };
@@ -104,22 +96,11 @@ struct clk_conf {
 	int				num_parents;
 	unsigned long			flags;
 	union {
-		struct fixed_fact_conf		fixed_fact;
 		const struct composite_conf		*composite;
 		const struct clk_div_table	*div_table;
 	} conf;
 };
 
-#define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d)				\
-	{								\
-		.clk_type			= CLK_FIXED_FACTOR,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.conf.fixed_fact.div		= (_d),			\
-	}								\
-
 #define CPU(_ro, _ci, _cn, _cp, _dt)					\
 	{								\
 		.reg_off			= (_ro),		\
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index a3d8e66..6571e66 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -110,7 +110,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_fclk_div)	= { "fixed_pll" };
 PNAME(p_cpu_clk)	= { "sys_pll" };
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
 PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
@@ -232,12 +231,62 @@ static struct meson_clk_pll meson8b_sys_pll = {
 	},
 };
 
+static struct clk_fixed_factor meson8b_fclk_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div3 = {
+	.mult = 1,
+	.div = 3,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div3",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div5 = {
+	.mult = 1,
+	.div = 5,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div5",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor meson8b_fclk_div7 = {
+	.mult = 1,
+	.div = 7,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div7",
+		.ops = &clk_fixed_factor_ops,
+		.parent_names = (const char *[]){ "fixed_pll" },
+		.num_parents = 1,
+	},
+};
+
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV2, "fclk_div2", p_fclk_div, 0, 2),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV3, "fclk_div3", p_fclk_div, 0, 3),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV4, "fclk_div4", p_fclk_div, 0, 4),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV5, "fclk_div5", p_fclk_div, 0, 5),
-	FIXED_FACTOR_DIV(CLKID_FCLK_DIV7, "fclk_div7", p_fclk_div, 0, 7),
 	CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk,
 	    cpu_div_table),
 	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
@@ -260,6 +309,11 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
 		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
 		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
+		[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
+		[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
+		[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
+		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
+		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/10] clk: meson8b: clean up cpu clocks
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

Remove the cpu clock registration function and helpers. Replace
unnecessary configuration struct with static initialization of the
desired clock type.

Ninja rename a5_clk to cpu_clk to better align with cpufreq convention.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clk-cpu.c      | 73 +++-------------------------------------
 drivers/clk/meson/clkc.c         |  4 ---
 drivers/clk/meson/clkc.h         | 25 ++++++--------
 drivers/clk/meson/meson8b-clkc.c | 47 ++++++++++++++++++++++++--
 4 files changed, 59 insertions(+), 90 deletions(-)

diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c
index f7c30ea..f8b2b7e 100644
--- a/drivers/clk/meson/clk-cpu.c
+++ b/drivers/clk/meson/clk-cpu.c
@@ -51,13 +51,6 @@
 
 #include "clkc.h"
 
-struct meson_clk_cpu {
-	struct notifier_block		clk_nb;
-	const struct clk_div_table	*div_table;
-	struct clk_hw			hw;
-	void __iomem			*base;
-	u16				reg_off;
-};
 #define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
 #define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
 
@@ -119,6 +112,7 @@ static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
 	return parent_rate / div;
 }
 
+/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
 static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
 					 struct clk_notifier_data *ndata)
 {
@@ -140,6 +134,7 @@ static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
 	return 0;
 }
 
+/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
 static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
 					  struct clk_notifier_data *ndata)
 {
@@ -161,7 +156,7 @@ static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
  * PLL clock is to be changed. We use the xtal input as temporary parent
  * while the PLL frequency is stabilized.
  */
-static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
+int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
 				     unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
@@ -176,68 +171,8 @@ static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
 	return notifier_from_errno(ret);
 }
 
-static const struct clk_ops meson_clk_cpu_ops = {
+const struct clk_ops meson_clk_cpu_ops = {
 	.recalc_rate	= meson_clk_cpu_recalc_rate,
 	.round_rate	= meson_clk_cpu_round_rate,
 	.set_rate	= meson_clk_cpu_set_rate,
 };
-
-struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base,
-				   spinlock_t *lock)
-{
-	struct clk *clk;
-	struct clk *pclk;
-	struct meson_clk_cpu *clk_cpu;
-	struct clk_init_data init;
-	int ret;
-
-	clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL);
-	if (!clk_cpu)
-		return ERR_PTR(-ENOMEM);
-
-	clk_cpu->base = reg_base;
-	clk_cpu->reg_off = clk_conf->reg_off;
-	clk_cpu->div_table = clk_conf->conf.div_table;
-	clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb;
-
-	init.name = clk_conf->clk_name;
-	init.ops = &meson_clk_cpu_ops;
-	init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
-	init.flags |= CLK_SET_RATE_PARENT;
-	init.parent_names = clk_conf->clks_parent;
-	init.num_parents = 1;
-
-	clk_cpu->hw.init = &init;
-
-	pclk = __clk_lookup(clk_conf->clks_parent[0]);
-	if (!pclk) {
-		pr_err("%s: could not lookup parent clock %s\n",
-				__func__, clk_conf->clks_parent[0]);
-		ret = -EINVAL;
-		goto free_clk;
-	}
-
-	ret = clk_notifier_register(pclk, &clk_cpu->clk_nb);
-	if (ret) {
-		pr_err("%s: failed to register clock notifier for %s\n",
-				__func__, clk_conf->clk_name);
-		goto free_clk;
-	}
-
-	clk = clk_register(NULL, &clk_cpu->hw);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-		goto unregister_clk_nb;
-	}
-
-	return clk;
-
-unregister_clk_nb:
-	clk_notifier_unregister(pclk, &clk_cpu->clk_nb);
-free_clk:
-	kfree(clk_cpu);
-
-	return ERR_PTR(ret);
-}
-
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index 275da27..0f96553 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -140,10 +140,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 			clk = meson_clk_register_composite(clk_conf,
 							   clk_base);
 			break;
-		case CLK_CPU:
-			clk = meson_clk_register_cpu(clk_conf, clk_base,
-						     &clk_lock);
-			break;
 		default:
 			clk = NULL;
 		}
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 97dd4d7..bfa5ae2 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -69,6 +69,14 @@ struct meson_clk_pll {
 
 #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 
+struct meson_clk_cpu {
+	struct clk_hw hw;
+	void __iomem *base;
+	u16 reg_off;
+	struct notifier_block clk_nb;
+	const struct clk_div_table *div_table;
+};
+
 struct composite_conf {
 	struct parm		mux_parm;
 	struct parm		div_parm;
@@ -84,7 +92,6 @@ struct composite_conf {
 
 enum clk_type {
 	CLK_COMPOSITE,
-	CLK_CPU,
 };
 
 struct clk_conf {
@@ -101,17 +108,6 @@ struct clk_conf {
 	} conf;
 };
 
-#define CPU(_ro, _ci, _cn, _cp, _dt)					\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_CPU,		\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.conf.div_table			= (_dt),		\
-	}								\
-
 #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c)				\
 	{								\
 		.reg_off			= (_ro),		\
@@ -127,8 +123,8 @@ struct clk_conf {
 struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
 void meson_clk_register_clks(const struct clk_conf *clk_confs,
 			     unsigned int nr_confs, void __iomem *clk_base);
-struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base, spinlock_t *lock);
+int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
+		void *data);
 
 /* shared data */
 extern spinlock_t clk_lock;
@@ -136,5 +132,6 @@ extern spinlock_t clk_lock;
 /* 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;
 
 #endif /* __CLKC_H */
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 6571e66..94512b6 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -15,6 +15,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
@@ -110,7 +111,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_cpu_clk)	= { "sys_pll" };
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
 PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
 			    "fclk_div7", "zero" };
@@ -286,9 +286,19 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
 	},
 };
 
+static struct meson_clk_cpu meson8b_cpu_clk = {
+	.reg_off = MESON8B_REG_SYS_CPU_CNTL1,
+	.div_table = cpu_div_table,
+	.clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
+	.hw.init = &(struct clk_init_data){
+		.name = "cpu_clk",
+		.ops = &meson_clk_cpu_ops,
+		.parent_names = (const char *[]){ "sys_pll" },
+		.num_parents = 1,
+	},
+};
+
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk,
-	    cpu_div_table),
 	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
 		  CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
 	COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali,
@@ -314,6 +324,7 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 		[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
 		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
 		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
+		[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
@@ -328,6 +339,8 @@ static void __init meson8b_clkc_init(struct device_node *np)
 {
 	void __iomem *clk_base;
 	int ret, clkid, i;
+	struct clk_hw *parent_hw;
+	struct clk *parent_clk;
 
 	if (!meson_clk_init(np, CLK_NR_CLKS))
 		return;
@@ -343,6 +356,9 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
 		meson8b_clk_plls[i]->base = clk_base;
 
+	/* Populate the base address for CPU clk */
+	meson8b_cpu_clk.base = clk_base;
+
 	/*
 	 * register all clks
 	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
@@ -358,12 +374,37 @@ static void __init meson8b_clkc_init(struct device_node *np)
 			goto unregister;
 	}
 
+	/*
+	 * Register CPU clk notifier
+	 *
+	 * FIXME this is wrong for a lot of reasons. First, the muxes should be
+	 * struct clk_hw objects. Second, we shouldn't program the muxes in
+	 * notifier handlers. The tricky programming sequence will be handled
+	 * by the forthcoming coordinated clock rates mechanism once that
+	 * feature is released.
+	 *
+	 * Furthermore, looking up the parent this way is terrible. At some
+	 * point we will stop allocating a default struct clk when registering
+	 * a new clk_hw, and this hack will no longer work. Releasing the ccr
+	 * feature before that time solves the problem :-)
+	 */
+	parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw);
+	parent_clk = parent_hw->clk;
+	ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb);
+	if (ret) {
+		pr_err("%s: failed to register clock notifier for cpu_clk\n",
+				__func__);
+		goto unregister_clk_nb;
+	}
+
 	meson_clk_register_clks(meson8b_clk_confs,
 				ARRAY_SIZE(meson8b_clk_confs),
 				clk_base);
 	return;
 
 /* FIXME remove after converting to platform_driver/devm_clk_register */
+unregister_clk_nb:
+	clk_notifier_unregister(parent_clk, &meson8b_a5_clk.clk_nb);
 unregister:
 	for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--)
 		clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/10] clk: meson8b: clean up cpu clocks
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

Remove the cpu clock registration function and helpers. Replace
unnecessary configuration struct with static initialization of the
desired clock type.

Ninja rename a5_clk to cpu_clk to better align with cpufreq convention.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/clk-cpu.c      | 73 +++-------------------------------------
 drivers/clk/meson/clkc.c         |  4 ---
 drivers/clk/meson/clkc.h         | 25 ++++++--------
 drivers/clk/meson/meson8b-clkc.c | 47 ++++++++++++++++++++++++--
 4 files changed, 59 insertions(+), 90 deletions(-)

diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c
index f7c30ea..f8b2b7e 100644
--- a/drivers/clk/meson/clk-cpu.c
+++ b/drivers/clk/meson/clk-cpu.c
@@ -51,13 +51,6 @@
 
 #include "clkc.h"
 
-struct meson_clk_cpu {
-	struct notifier_block		clk_nb;
-	const struct clk_div_table	*div_table;
-	struct clk_hw			hw;
-	void __iomem			*base;
-	u16				reg_off;
-};
 #define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
 #define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
 
@@ -119,6 +112,7 @@ static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
 	return parent_rate / div;
 }
 
+/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
 static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
 					 struct clk_notifier_data *ndata)
 {
@@ -140,6 +134,7 @@ static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
 	return 0;
 }
 
+/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
 static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
 					  struct clk_notifier_data *ndata)
 {
@@ -161,7 +156,7 @@ static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
  * PLL clock is to be changed. We use the xtal input as temporary parent
  * while the PLL frequency is stabilized.
  */
-static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
+int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
 				     unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
@@ -176,68 +171,8 @@ static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
 	return notifier_from_errno(ret);
 }
 
-static const struct clk_ops meson_clk_cpu_ops = {
+const struct clk_ops meson_clk_cpu_ops = {
 	.recalc_rate	= meson_clk_cpu_recalc_rate,
 	.round_rate	= meson_clk_cpu_round_rate,
 	.set_rate	= meson_clk_cpu_set_rate,
 };
-
-struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base,
-				   spinlock_t *lock)
-{
-	struct clk *clk;
-	struct clk *pclk;
-	struct meson_clk_cpu *clk_cpu;
-	struct clk_init_data init;
-	int ret;
-
-	clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL);
-	if (!clk_cpu)
-		return ERR_PTR(-ENOMEM);
-
-	clk_cpu->base = reg_base;
-	clk_cpu->reg_off = clk_conf->reg_off;
-	clk_cpu->div_table = clk_conf->conf.div_table;
-	clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb;
-
-	init.name = clk_conf->clk_name;
-	init.ops = &meson_clk_cpu_ops;
-	init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
-	init.flags |= CLK_SET_RATE_PARENT;
-	init.parent_names = clk_conf->clks_parent;
-	init.num_parents = 1;
-
-	clk_cpu->hw.init = &init;
-
-	pclk = __clk_lookup(clk_conf->clks_parent[0]);
-	if (!pclk) {
-		pr_err("%s: could not lookup parent clock %s\n",
-				__func__, clk_conf->clks_parent[0]);
-		ret = -EINVAL;
-		goto free_clk;
-	}
-
-	ret = clk_notifier_register(pclk, &clk_cpu->clk_nb);
-	if (ret) {
-		pr_err("%s: failed to register clock notifier for %s\n",
-				__func__, clk_conf->clk_name);
-		goto free_clk;
-	}
-
-	clk = clk_register(NULL, &clk_cpu->hw);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-		goto unregister_clk_nb;
-	}
-
-	return clk;
-
-unregister_clk_nb:
-	clk_notifier_unregister(pclk, &clk_cpu->clk_nb);
-free_clk:
-	kfree(clk_cpu);
-
-	return ERR_PTR(ret);
-}
-
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
index 275da27..0f96553 100644
--- a/drivers/clk/meson/clkc.c
+++ b/drivers/clk/meson/clkc.c
@@ -140,10 +140,6 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
 			clk = meson_clk_register_composite(clk_conf,
 							   clk_base);
 			break;
-		case CLK_CPU:
-			clk = meson_clk_register_cpu(clk_conf, clk_base,
-						     &clk_lock);
-			break;
 		default:
 			clk = NULL;
 		}
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index 97dd4d7..bfa5ae2 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -69,6 +69,14 @@ struct meson_clk_pll {
 
 #define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 
+struct meson_clk_cpu {
+	struct clk_hw hw;
+	void __iomem *base;
+	u16 reg_off;
+	struct notifier_block clk_nb;
+	const struct clk_div_table *div_table;
+};
+
 struct composite_conf {
 	struct parm		mux_parm;
 	struct parm		div_parm;
@@ -84,7 +92,6 @@ struct composite_conf {
 
 enum clk_type {
 	CLK_COMPOSITE,
-	CLK_CPU,
 };
 
 struct clk_conf {
@@ -101,17 +108,6 @@ struct clk_conf {
 	} conf;
 };
 
-#define CPU(_ro, _ci, _cn, _cp, _dt)					\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_CPU,		\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.conf.div_table			= (_dt),		\
-	}								\
-
 #define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c)				\
 	{								\
 		.reg_off			= (_ro),		\
@@ -127,8 +123,8 @@ struct clk_conf {
 struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
 void meson_clk_register_clks(const struct clk_conf *clk_confs,
 			     unsigned int nr_confs, void __iomem *clk_base);
-struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
-				   void __iomem *reg_base, spinlock_t *lock);
+int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
+		void *data);
 
 /* shared data */
 extern spinlock_t clk_lock;
@@ -136,5 +132,6 @@ extern spinlock_t clk_lock;
 /* 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;
 
 #endif /* __CLKC_H */
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 6571e66..94512b6 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -15,6 +15,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
@@ -110,7 +111,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_cpu_clk)	= { "sys_pll" };
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
 PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
 			    "fclk_div7", "zero" };
@@ -286,9 +286,19 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
 	},
 };
 
+static struct meson_clk_cpu meson8b_cpu_clk = {
+	.reg_off = MESON8B_REG_SYS_CPU_CNTL1,
+	.div_table = cpu_div_table,
+	.clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
+	.hw.init = &(struct clk_init_data){
+		.name = "cpu_clk",
+		.ops = &meson_clk_cpu_ops,
+		.parent_names = (const char *[]){ "sys_pll" },
+		.num_parents = 1,
+	},
+};
+
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk,
-	    cpu_div_table),
 	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
 		  CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
 	COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali,
@@ -314,6 +324,7 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 		[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
 		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
 		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
+		[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
@@ -328,6 +339,8 @@ static void __init meson8b_clkc_init(struct device_node *np)
 {
 	void __iomem *clk_base;
 	int ret, clkid, i;
+	struct clk_hw *parent_hw;
+	struct clk *parent_clk;
 
 	if (!meson_clk_init(np, CLK_NR_CLKS))
 		return;
@@ -343,6 +356,9 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
 		meson8b_clk_plls[i]->base = clk_base;
 
+	/* Populate the base address for CPU clk */
+	meson8b_cpu_clk.base = clk_base;
+
 	/*
 	 * register all clks
 	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
@@ -358,12 +374,37 @@ static void __init meson8b_clkc_init(struct device_node *np)
 			goto unregister;
 	}
 
+	/*
+	 * Register CPU clk notifier
+	 *
+	 * FIXME this is wrong for a lot of reasons. First, the muxes should be
+	 * struct clk_hw objects. Second, we shouldn't program the muxes in
+	 * notifier handlers. The tricky programming sequence will be handled
+	 * by the forthcoming coordinated clock rates mechanism once that
+	 * feature is released.
+	 *
+	 * Furthermore, looking up the parent this way is terrible. At some
+	 * point we will stop allocating a default struct clk when registering
+	 * a new clk_hw, and this hack will no longer work. Releasing the ccr
+	 * feature before that time solves the problem :-)
+	 */
+	parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw);
+	parent_clk = parent_hw->clk;
+	ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb);
+	if (ret) {
+		pr_err("%s: failed to register clock notifier for cpu_clk\n",
+				__func__);
+		goto unregister_clk_nb;
+	}
+
 	meson_clk_register_clks(meson8b_clk_confs,
 				ARRAY_SIZE(meson8b_clk_confs),
 				clk_base);
 	return;
 
 /* FIXME remove after converting to platform_driver/devm_clk_register */
+unregister_clk_nb:
+	clk_notifier_unregister(parent_clk, &meson8b_a5_clk.clk_nb);
 unregister:
 	for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--)
 		clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/10] clk: meson8b: remove mali clk
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

This clock is undocumented and always orphaned. Get rid of it until we
have more complete clock tree documentation.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/meson8b-clkc.c | 22 ----------------------
 1 file changed, 22 deletions(-)

diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 94512b6..dcd8f03 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -112,11 +112,8 @@ static const struct clk_div_table cpu_div_table[] = {
 };
 
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
-PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
-			    "fclk_div7", "zero" };
 
 static u32 mux_table_clk81[]	= { 6, 5, 7 };
-static u32 mux_table_mali[]	= { 6, 5, 7, 4, 0 };
 
 static const struct composite_conf clk81_conf __initconst = {
 	.mux_table		= mux_table_clk81,
@@ -126,13 +123,6 @@ static const struct composite_conf clk81_conf __initconst = {
 	.gate_parm		= PARM(0x00, 7, 1),
 };
 
-static const struct composite_conf mali_conf __initconst = {
-	.mux_table		= mux_table_mali,
-	.mux_parm		= PARM(0x00, 9, 3),
-	.div_parm		= PARM(0x00, 0, 7),
-	.gate_parm		= PARM(0x00, 8, 1),
-};
-
 static struct clk_fixed_rate meson8b_xtal = {
 	.fixed_rate = 24000000,
 	.hw.init = &(struct clk_init_data){
@@ -142,15 +132,6 @@ static struct clk_fixed_rate meson8b_xtal = {
 	},
 };
 
-static struct clk_fixed_rate meson8b_zero = {
-	.fixed_rate = 0,
-	.hw.init = &(struct clk_init_data){
-		.name = "zero",
-		.num_parents = 0,
-		.ops = &clk_fixed_rate_ops,
-	},
-};
-
 static struct meson_clk_pll meson8b_fixed_pll = {
 	.m = {
 		.reg_off = MESON8B_REG_PLL_FIXED,
@@ -301,8 +282,6 @@ static struct meson_clk_cpu meson8b_cpu_clk = {
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
 	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
 		  CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
-	COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali,
-		  CLK_IGNORE_UNUSED, &mali_conf),
 };
 
 /*
@@ -315,7 +294,6 @@ static const struct clk_conf meson8b_clk_confs[] __initconst = {
 static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 	.hws = {
 		[CLKID_XTAL] = &meson8b_xtal.hw,
-		[CLKID_ZERO] = &meson8b_zero.hw,
 		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
 		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
 		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/10] clk: meson8b: remove mali clk
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

This clock is undocumented and always orphaned. Get rid of it until we
have more complete clock tree documentation.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/meson8b-clkc.c | 22 ----------------------
 1 file changed, 22 deletions(-)

diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 94512b6..dcd8f03 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -112,11 +112,8 @@ static const struct clk_div_table cpu_div_table[] = {
 };
 
 PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
-PNAME(p_mali)		= { "fclk_div3", "fclk_div4", "fclk_div5",
-			    "fclk_div7", "zero" };
 
 static u32 mux_table_clk81[]	= { 6, 5, 7 };
-static u32 mux_table_mali[]	= { 6, 5, 7, 4, 0 };
 
 static const struct composite_conf clk81_conf __initconst = {
 	.mux_table		= mux_table_clk81,
@@ -126,13 +123,6 @@ static const struct composite_conf clk81_conf __initconst = {
 	.gate_parm		= PARM(0x00, 7, 1),
 };
 
-static const struct composite_conf mali_conf __initconst = {
-	.mux_table		= mux_table_mali,
-	.mux_parm		= PARM(0x00, 9, 3),
-	.div_parm		= PARM(0x00, 0, 7),
-	.gate_parm		= PARM(0x00, 8, 1),
-};
-
 static struct clk_fixed_rate meson8b_xtal = {
 	.fixed_rate = 24000000,
 	.hw.init = &(struct clk_init_data){
@@ -142,15 +132,6 @@ static struct clk_fixed_rate meson8b_xtal = {
 	},
 };
 
-static struct clk_fixed_rate meson8b_zero = {
-	.fixed_rate = 0,
-	.hw.init = &(struct clk_init_data){
-		.name = "zero",
-		.num_parents = 0,
-		.ops = &clk_fixed_rate_ops,
-	},
-};
-
 static struct meson_clk_pll meson8b_fixed_pll = {
 	.m = {
 		.reg_off = MESON8B_REG_PLL_FIXED,
@@ -301,8 +282,6 @@ static struct meson_clk_cpu meson8b_cpu_clk = {
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
 	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
 		  CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
-	COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali,
-		  CLK_IGNORE_UNUSED, &mali_conf),
 };
 
 /*
@@ -315,7 +294,6 @@ static const struct clk_conf meson8b_clk_confs[] __initconst = {
 static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 	.hws = {
 		[CLKID_XTAL] = &meson8b_xtal.hw,
-		[CLKID_ZERO] = &meson8b_zero.hw,
 		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
 		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
 		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/10] clk: meson8b: clean up composite clocks
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

Remove the composite clock registration function and helpers. Replace
unnecessary configuration struct with static initialization of the
desired clock type.

To preserve git bisect this patch also flips the switch and starts using
of_clk_add_hw_provider instead of the deprecated meson_clk_register_clks
method. As a byproduct clk.c can be deleted.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/Makefile               |   2 +-
 drivers/clk/meson/clkc.c                 | 161 -------------------------------
 drivers/clk/meson/clkc.h                 |  56 -----------
 drivers/clk/meson/meson8b-clkc.c         |  93 ++++++++++++------
 include/dt-bindings/clock/meson8b-clkc.h |   4 +-
 5 files changed, 69 insertions(+), 247 deletions(-)
 delete mode 100644 drivers/clk/meson/clkc.c

diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 6d45531..901b5d4 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,5 +2,5 @@
 # Makefile for Meson specific clk
 #
 
-obj-y += clkc.o clk-pll.o clk-cpu.o
+obj-y += clk-pll.o clk-cpu.o
 obj-y += meson8b-clkc.o
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
deleted file mode 100644
index 0f96553..0000000
--- a/drivers/clk/meson/clkc.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2015 Endless Mobile, Inc.
- * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/clk-provider.h>
-#include <linux/mfd/syscon.h>
-#include <linux/slab.h>
-
-#include "clkc.h"
-
-DEFINE_SPINLOCK(clk_lock);
-
-static struct clk **clks;
-static struct clk_onecell_data clk_data;
-
-struct clk ** __init meson_clk_init(struct device_node *np,
-				   unsigned long nr_clks)
-{
-	clks = kcalloc(nr_clks, sizeof(*clks), GFP_KERNEL);
-	if (!clks)
-		return ERR_PTR(-ENOMEM);
-
-	clk_data.clks = clks;
-	clk_data.clk_num = nr_clks;
-	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-
-	return clks;
-}
-
-static void meson_clk_add_lookup(struct clk *clk, unsigned int id)
-{
-	if (clks && id)
-		clks[id] = clk;
-}
-
-static struct clk * __init
-meson_clk_register_composite(const struct clk_conf *clk_conf,
-			     void __iomem *clk_base)
-{
-	struct clk *clk;
-	struct clk_mux *mux = NULL;
-	struct clk_divider *div = NULL;
-	struct clk_gate *gate = NULL;
-	const struct clk_ops *mux_ops = NULL;
-	const struct composite_conf *composite_conf;
-
-	composite_conf = clk_conf->conf.composite;
-
-	if (clk_conf->num_parents > 1) {
-		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
-		if (!mux)
-			return ERR_PTR(-ENOMEM);
-
-		mux->reg = clk_base + clk_conf->reg_off
-				+ composite_conf->mux_parm.reg_off;
-		mux->shift = composite_conf->mux_parm.shift;
-		mux->mask = BIT(composite_conf->mux_parm.width) - 1;
-		mux->flags = composite_conf->mux_flags;
-		mux->lock = &clk_lock;
-		mux->table = composite_conf->mux_table;
-		mux_ops = (composite_conf->mux_flags & CLK_MUX_READ_ONLY) ?
-			  &clk_mux_ro_ops : &clk_mux_ops;
-	}
-
-	if (MESON_PARM_APPLICABLE(&composite_conf->div_parm)) {
-		div = kzalloc(sizeof(*div), GFP_KERNEL);
-		if (!div) {
-			clk = ERR_PTR(-ENOMEM);
-			goto error;
-		}
-
-		div->reg = clk_base + clk_conf->reg_off
-				+ composite_conf->div_parm.reg_off;
-		div->shift = composite_conf->div_parm.shift;
-		div->width = composite_conf->div_parm.width;
-		div->lock = &clk_lock;
-		div->flags = composite_conf->div_flags;
-		div->table = composite_conf->div_table;
-	}
-
-	if (MESON_PARM_APPLICABLE(&composite_conf->gate_parm)) {
-		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
-		if (!gate) {
-			clk = ERR_PTR(-ENOMEM);
-			goto error;
-		}
-
-		gate->reg = clk_base + clk_conf->reg_off
-				+ composite_conf->div_parm.reg_off;
-		gate->bit_idx = composite_conf->gate_parm.shift;
-		gate->flags = composite_conf->gate_flags;
-		gate->lock = &clk_lock;
-	}
-
-	clk = clk_register_composite(NULL, clk_conf->clk_name,
-				    clk_conf->clks_parent,
-				    clk_conf->num_parents,
-				    mux ? &mux->hw : NULL, mux_ops,
-				    div ? &div->hw : NULL, &clk_divider_ops,
-				    gate ? &gate->hw : NULL, &clk_gate_ops,
-				    clk_conf->flags);
-	if (IS_ERR(clk))
-		goto error;
-
-	return clk;
-
-error:
-	kfree(gate);
-	kfree(div);
-	kfree(mux);
-
-	return clk;
-}
-
-void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
-				    unsigned int nr_confs,
-				    void __iomem *clk_base)
-{
-	unsigned int i;
-	struct clk *clk = NULL;
-
-	for (i = 0; i < nr_confs; i++) {
-		const struct clk_conf *clk_conf = &clk_confs[i];
-
-		switch (clk_conf->clk_type) {
-		case CLK_COMPOSITE:
-			clk = meson_clk_register_composite(clk_conf,
-							   clk_base);
-			break;
-		default:
-			clk = NULL;
-		}
-
-		if (!clk) {
-			pr_err("%s: unknown clock type %d\n", __func__,
-			       clk_conf->clk_type);
-			continue;
-		}
-
-		if (IS_ERR(clk)) {
-			pr_warn("%s: Unable to create %s clock\n", __func__,
-				clk_conf->clk_name);
-			continue;
-		}
-
-		meson_clk_add_lookup(clk, clk_conf->clk_id);
-	}
-}
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index bfa5ae2..f3f3961 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -35,13 +35,6 @@ struct parm {
 	u8	width;
 };
 
-#define PARM(_r, _s, _w)                                               \
-{                                                                      \
-	.reg_off        = (_r),                                        \
-	.shift          = (_s),                                        \
-	.width          = (_w),                                        \
-}                                                                      \
-
 struct pll_rate_table {
 	unsigned long	rate;
 	u16		m;
@@ -77,58 +70,9 @@ struct meson_clk_cpu {
 	const struct clk_div_table *div_table;
 };
 
-struct composite_conf {
-	struct parm		mux_parm;
-	struct parm		div_parm;
-	struct parm		gate_parm;
-	struct clk_div_table	*div_table;
-	u32			*mux_table;
-	u8			mux_flags;
-	u8			div_flags;
-	u8			gate_flags;
-};
-
-#define PNAME(x) static const char *x[]
-
-enum clk_type {
-	CLK_COMPOSITE,
-};
-
-struct clk_conf {
-	u16				reg_off;
-	enum clk_type			clk_type;
-	unsigned int			clk_id;
-	const char			*clk_name;
-	const char			**clks_parent;
-	int				num_parents;
-	unsigned long			flags;
-	union {
-		const struct composite_conf		*composite;
-		const struct clk_div_table	*div_table;
-	} conf;
-};
-
-#define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c)				\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_COMPOSITE,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.flags				= (_f),			\
-		.conf.composite			= (_c),			\
-	}								\
-
-struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
-void meson_clk_register_clks(const struct clk_conf *clk_confs,
-			     unsigned int nr_confs, void __iomem *clk_base);
 int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
 		void *data);
 
-/* shared data */
-extern spinlock_t clk_lock;
-
 /* clk_ops */
 extern const struct clk_ops meson_clk_pll_ro_ops;
 extern const struct clk_ops meson_clk_pll_ops;
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index dcd8f03..57dea03 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -41,6 +41,8 @@
 #define MESON8B_REG_PLL_SYS		0x0300
 #define MESON8B_REG_PLL_VID		0x0320
 
+static DEFINE_SPINLOCK(clk_lock);
+
 static const struct pll_rate_table sys_pll_rate_table[] = {
 	PLL_RATE(312000000, 52, 1, 2),
 	PLL_RATE(336000000, 56, 1, 2),
@@ -111,18 +113,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
-
-static u32 mux_table_clk81[]	= { 6, 5, 7 };
-
-static const struct composite_conf clk81_conf __initconst = {
-	.mux_table		= mux_table_clk81,
-	.mux_flags		= CLK_MUX_READ_ONLY,
-	.mux_parm		= PARM(0x00, 12, 3),
-	.div_parm		= PARM(0x00, 0, 7),
-	.gate_parm		= PARM(0x00, 7, 1),
-};
-
 static struct clk_fixed_rate meson8b_xtal = {
 	.fixed_rate = 24000000,
 	.hw.init = &(struct clk_init_data){
@@ -267,6 +257,11 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
 	},
 };
 
+/*
+ * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
+ * post-dividers and should be modeled with their respective PLLs via the
+ * forthcoming coordinated clock rates feature
+ */
 static struct meson_clk_cpu meson8b_cpu_clk = {
 	.reg_off = MESON8B_REG_SYS_CPU_CNTL1,
 	.div_table = cpu_div_table,
@@ -279,18 +274,57 @@ static struct meson_clk_cpu meson8b_cpu_clk = {
 	},
 };
 
-static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
-		  CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
+static u32 mux_table_clk81[]	= { 6, 5, 7 };
+
+struct clk_mux meson8b_mpeg_clk_sel = {
+	.reg = (void *)MESON8B_REG_HHI_MPEG,
+	.mask = 0x7,
+	.shift = 12,
+	.flags = CLK_MUX_READ_ONLY,
+	.table = mux_table_clk81,
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "mpeg_clk_sel",
+		.ops = &clk_mux_ro_ops,
+		/*
+		 * FIXME bits 14:12 selects from 8 possible parents:
+		 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
+		 * fclk_div4, fclk_div3, fclk_div5
+		 */
+		.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
+			"fclk_div5" },
+		.num_parents = 3,
+		.flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
+	},
+};
+
+struct clk_divider meson8b_mpeg_clk_div = {
+	.reg = (void *)MESON8B_REG_HHI_MPEG,
+	.shift = 0,
+	.width = 7,
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "mpeg_clk_div",
+		.ops = &clk_divider_ops,
+		.parent_names = (const char *[]){ "mpeg_clk_sel" },
+		.num_parents = 1,
+		.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+	},
+};
+
+struct clk_gate meson8b_clk81 = {
+	.reg = (void *)MESON8B_REG_HHI_MPEG,
+	.bit_idx = 7,
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "clk81",
+		.ops = &clk_gate_ops,
+		.parent_names = (const char *[]){ "mpeg_clk_div" },
+		.num_parents = 1,
+		.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+	},
 };
 
-/*
- * FIXME we cannot register two providers w/o breaking things. Luckily only
- * clk81 is actually used by any drivers. Convert clk81 to use
- * clk_hw_onecell_data last and flip the switch to call of_clk_add_hw_provider
- * instead of of_clk_add_provider in the clk81 conversion patch to keep from
- * breaking bisect. Then delete this comment ;-)
- */
 static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 	.hws = {
 		[CLKID_XTAL] = &meson8b_xtal.hw,
@@ -303,6 +337,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
 		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
 		[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
+		[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
+		[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
+		[CLKID_CLK81] = &meson8b_clk81.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
@@ -320,9 +357,6 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	struct clk_hw *parent_hw;
 	struct clk *parent_clk;
 
-	if (!meson_clk_init(np, CLK_NR_CLKS))
-		return;
-
 	/*  Generic clocks and PLLs */
 	clk_base = of_iomap(np, 1);
 	if (!clk_base) {
@@ -337,6 +371,11 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	/* Populate the base address for CPU clk */
 	meson8b_cpu_clk.base = clk_base;
 
+	/* Populate the base address for the MPEG clks */
+	meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
+	meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
+	meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
+
 	/*
 	 * register all clks
 	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
@@ -375,9 +414,7 @@ static void __init meson8b_clkc_init(struct device_node *np)
 		goto unregister_clk_nb;
 	}
 
-	meson_clk_register_clks(meson8b_clk_confs,
-				ARRAY_SIZE(meson8b_clk_confs),
-				clk_base);
+	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &meson8b_hw_onecell_data);
 	return;
 
 /* FIXME remove after converting to platform_driver/devm_clk_register */
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
index bd2720d..595a58d 100644
--- a/include/dt-bindings/clock/meson8b-clkc.h
+++ b/include/dt-bindings/clock/meson8b-clkc.h
@@ -19,7 +19,9 @@
 #define CLKID_MALI		11
 #define CLKID_CPUCLK		12
 #define CLKID_ZERO		13
+#define CLKID_MPEG_SEL		14
+#define CLKID_MPEG_DIV		15
 
-#define CLK_NR_CLKS		(CLKID_ZERO + 1)
+#define CLK_NR_CLKS		(CLKID_MPEG_DIV + 1)
 
 #endif /* __MESON8B_CLKC_H */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/10] clk: meson8b: clean up composite clocks
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

Remove the composite clock registration function and helpers. Replace
unnecessary configuration struct with static initialization of the
desired clock type.

To preserve git bisect this patch also flips the switch and starts using
of_clk_add_hw_provider instead of the deprecated meson_clk_register_clks
method. As a byproduct clk.c can be deleted.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/Makefile               |   2 +-
 drivers/clk/meson/clkc.c                 | 161 -------------------------------
 drivers/clk/meson/clkc.h                 |  56 -----------
 drivers/clk/meson/meson8b-clkc.c         |  93 ++++++++++++------
 include/dt-bindings/clock/meson8b-clkc.h |   4 +-
 5 files changed, 69 insertions(+), 247 deletions(-)
 delete mode 100644 drivers/clk/meson/clkc.c

diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 6d45531..901b5d4 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,5 +2,5 @@
 # Makefile for Meson specific clk
 #
 
-obj-y += clkc.o clk-pll.o clk-cpu.o
+obj-y += clk-pll.o clk-cpu.o
 obj-y += meson8b-clkc.o
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
deleted file mode 100644
index 0f96553..0000000
--- a/drivers/clk/meson/clkc.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2015 Endless Mobile, Inc.
- * Author: Carlo Caione <carlo@endlessm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/clk-provider.h>
-#include <linux/mfd/syscon.h>
-#include <linux/slab.h>
-
-#include "clkc.h"
-
-DEFINE_SPINLOCK(clk_lock);
-
-static struct clk **clks;
-static struct clk_onecell_data clk_data;
-
-struct clk ** __init meson_clk_init(struct device_node *np,
-				   unsigned long nr_clks)
-{
-	clks = kcalloc(nr_clks, sizeof(*clks), GFP_KERNEL);
-	if (!clks)
-		return ERR_PTR(-ENOMEM);
-
-	clk_data.clks = clks;
-	clk_data.clk_num = nr_clks;
-	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-
-	return clks;
-}
-
-static void meson_clk_add_lookup(struct clk *clk, unsigned int id)
-{
-	if (clks && id)
-		clks[id] = clk;
-}
-
-static struct clk * __init
-meson_clk_register_composite(const struct clk_conf *clk_conf,
-			     void __iomem *clk_base)
-{
-	struct clk *clk;
-	struct clk_mux *mux = NULL;
-	struct clk_divider *div = NULL;
-	struct clk_gate *gate = NULL;
-	const struct clk_ops *mux_ops = NULL;
-	const struct composite_conf *composite_conf;
-
-	composite_conf = clk_conf->conf.composite;
-
-	if (clk_conf->num_parents > 1) {
-		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
-		if (!mux)
-			return ERR_PTR(-ENOMEM);
-
-		mux->reg = clk_base + clk_conf->reg_off
-				+ composite_conf->mux_parm.reg_off;
-		mux->shift = composite_conf->mux_parm.shift;
-		mux->mask = BIT(composite_conf->mux_parm.width) - 1;
-		mux->flags = composite_conf->mux_flags;
-		mux->lock = &clk_lock;
-		mux->table = composite_conf->mux_table;
-		mux_ops = (composite_conf->mux_flags & CLK_MUX_READ_ONLY) ?
-			  &clk_mux_ro_ops : &clk_mux_ops;
-	}
-
-	if (MESON_PARM_APPLICABLE(&composite_conf->div_parm)) {
-		div = kzalloc(sizeof(*div), GFP_KERNEL);
-		if (!div) {
-			clk = ERR_PTR(-ENOMEM);
-			goto error;
-		}
-
-		div->reg = clk_base + clk_conf->reg_off
-				+ composite_conf->div_parm.reg_off;
-		div->shift = composite_conf->div_parm.shift;
-		div->width = composite_conf->div_parm.width;
-		div->lock = &clk_lock;
-		div->flags = composite_conf->div_flags;
-		div->table = composite_conf->div_table;
-	}
-
-	if (MESON_PARM_APPLICABLE(&composite_conf->gate_parm)) {
-		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
-		if (!gate) {
-			clk = ERR_PTR(-ENOMEM);
-			goto error;
-		}
-
-		gate->reg = clk_base + clk_conf->reg_off
-				+ composite_conf->div_parm.reg_off;
-		gate->bit_idx = composite_conf->gate_parm.shift;
-		gate->flags = composite_conf->gate_flags;
-		gate->lock = &clk_lock;
-	}
-
-	clk = clk_register_composite(NULL, clk_conf->clk_name,
-				    clk_conf->clks_parent,
-				    clk_conf->num_parents,
-				    mux ? &mux->hw : NULL, mux_ops,
-				    div ? &div->hw : NULL, &clk_divider_ops,
-				    gate ? &gate->hw : NULL, &clk_gate_ops,
-				    clk_conf->flags);
-	if (IS_ERR(clk))
-		goto error;
-
-	return clk;
-
-error:
-	kfree(gate);
-	kfree(div);
-	kfree(mux);
-
-	return clk;
-}
-
-void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
-				    unsigned int nr_confs,
-				    void __iomem *clk_base)
-{
-	unsigned int i;
-	struct clk *clk = NULL;
-
-	for (i = 0; i < nr_confs; i++) {
-		const struct clk_conf *clk_conf = &clk_confs[i];
-
-		switch (clk_conf->clk_type) {
-		case CLK_COMPOSITE:
-			clk = meson_clk_register_composite(clk_conf,
-							   clk_base);
-			break;
-		default:
-			clk = NULL;
-		}
-
-		if (!clk) {
-			pr_err("%s: unknown clock type %d\n", __func__,
-			       clk_conf->clk_type);
-			continue;
-		}
-
-		if (IS_ERR(clk)) {
-			pr_warn("%s: Unable to create %s clock\n", __func__,
-				clk_conf->clk_name);
-			continue;
-		}
-
-		meson_clk_add_lookup(clk, clk_conf->clk_id);
-	}
-}
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index bfa5ae2..f3f3961 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -35,13 +35,6 @@ struct parm {
 	u8	width;
 };
 
-#define PARM(_r, _s, _w)                                               \
-{                                                                      \
-	.reg_off        = (_r),                                        \
-	.shift          = (_s),                                        \
-	.width          = (_w),                                        \
-}                                                                      \
-
 struct pll_rate_table {
 	unsigned long	rate;
 	u16		m;
@@ -77,58 +70,9 @@ struct meson_clk_cpu {
 	const struct clk_div_table *div_table;
 };
 
-struct composite_conf {
-	struct parm		mux_parm;
-	struct parm		div_parm;
-	struct parm		gate_parm;
-	struct clk_div_table	*div_table;
-	u32			*mux_table;
-	u8			mux_flags;
-	u8			div_flags;
-	u8			gate_flags;
-};
-
-#define PNAME(x) static const char *x[]
-
-enum clk_type {
-	CLK_COMPOSITE,
-};
-
-struct clk_conf {
-	u16				reg_off;
-	enum clk_type			clk_type;
-	unsigned int			clk_id;
-	const char			*clk_name;
-	const char			**clks_parent;
-	int				num_parents;
-	unsigned long			flags;
-	union {
-		const struct composite_conf		*composite;
-		const struct clk_div_table	*div_table;
-	} conf;
-};
-
-#define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c)				\
-	{								\
-		.reg_off			= (_ro),		\
-		.clk_type			= CLK_COMPOSITE,	\
-		.clk_id				= (_ci),		\
-		.clk_name			= (_cn),		\
-		.clks_parent			= (_cp),		\
-		.num_parents			= ARRAY_SIZE(_cp),	\
-		.flags				= (_f),			\
-		.conf.composite			= (_c),			\
-	}								\
-
-struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
-void meson_clk_register_clks(const struct clk_conf *clk_confs,
-			     unsigned int nr_confs, void __iomem *clk_base);
 int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
 		void *data);
 
-/* shared data */
-extern spinlock_t clk_lock;
-
 /* clk_ops */
 extern const struct clk_ops meson_clk_pll_ro_ops;
 extern const struct clk_ops meson_clk_pll_ops;
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index dcd8f03..57dea03 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -41,6 +41,8 @@
 #define MESON8B_REG_PLL_SYS		0x0300
 #define MESON8B_REG_PLL_VID		0x0320
 
+static DEFINE_SPINLOCK(clk_lock);
+
 static const struct pll_rate_table sys_pll_rate_table[] = {
 	PLL_RATE(312000000, 52, 1, 2),
 	PLL_RATE(336000000, 56, 1, 2),
@@ -111,18 +113,6 @@ static const struct clk_div_table cpu_div_table[] = {
 	{ /* sentinel */ },
 };
 
-PNAME(p_clk81)		= { "fclk_div3", "fclk_div4", "fclk_div5" };
-
-static u32 mux_table_clk81[]	= { 6, 5, 7 };
-
-static const struct composite_conf clk81_conf __initconst = {
-	.mux_table		= mux_table_clk81,
-	.mux_flags		= CLK_MUX_READ_ONLY,
-	.mux_parm		= PARM(0x00, 12, 3),
-	.div_parm		= PARM(0x00, 0, 7),
-	.gate_parm		= PARM(0x00, 7, 1),
-};
-
 static struct clk_fixed_rate meson8b_xtal = {
 	.fixed_rate = 24000000,
 	.hw.init = &(struct clk_init_data){
@@ -267,6 +257,11 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
 	},
 };
 
+/*
+ * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
+ * post-dividers and should be modeled with their respective PLLs via the
+ * forthcoming coordinated clock rates feature
+ */
 static struct meson_clk_cpu meson8b_cpu_clk = {
 	.reg_off = MESON8B_REG_SYS_CPU_CNTL1,
 	.div_table = cpu_div_table,
@@ -279,18 +274,57 @@ static struct meson_clk_cpu meson8b_cpu_clk = {
 	},
 };
 
-static const struct clk_conf meson8b_clk_confs[] __initconst = {
-	COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
-		  CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
+static u32 mux_table_clk81[]	= { 6, 5, 7 };
+
+struct clk_mux meson8b_mpeg_clk_sel = {
+	.reg = (void *)MESON8B_REG_HHI_MPEG,
+	.mask = 0x7,
+	.shift = 12,
+	.flags = CLK_MUX_READ_ONLY,
+	.table = mux_table_clk81,
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "mpeg_clk_sel",
+		.ops = &clk_mux_ro_ops,
+		/*
+		 * FIXME bits 14:12 selects from 8 possible parents:
+		 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
+		 * fclk_div4, fclk_div3, fclk_div5
+		 */
+		.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
+			"fclk_div5" },
+		.num_parents = 3,
+		.flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
+	},
+};
+
+struct clk_divider meson8b_mpeg_clk_div = {
+	.reg = (void *)MESON8B_REG_HHI_MPEG,
+	.shift = 0,
+	.width = 7,
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "mpeg_clk_div",
+		.ops = &clk_divider_ops,
+		.parent_names = (const char *[]){ "mpeg_clk_sel" },
+		.num_parents = 1,
+		.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+	},
+};
+
+struct clk_gate meson8b_clk81 = {
+	.reg = (void *)MESON8B_REG_HHI_MPEG,
+	.bit_idx = 7,
+	.lock = &clk_lock,
+	.hw.init = &(struct clk_init_data){
+		.name = "clk81",
+		.ops = &clk_gate_ops,
+		.parent_names = (const char *[]){ "mpeg_clk_div" },
+		.num_parents = 1,
+		.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+	},
 };
 
-/*
- * FIXME we cannot register two providers w/o breaking things. Luckily only
- * clk81 is actually used by any drivers. Convert clk81 to use
- * clk_hw_onecell_data last and flip the switch to call of_clk_add_hw_provider
- * instead of of_clk_add_provider in the clk81 conversion patch to keep from
- * breaking bisect. Then delete this comment ;-)
- */
 static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 	.hws = {
 		[CLKID_XTAL] = &meson8b_xtal.hw,
@@ -303,6 +337,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
 		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
 		[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
+		[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
+		[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
+		[CLKID_CLK81] = &meson8b_clk81.hw,
 	},
 	.num = CLK_NR_CLKS,
 };
@@ -320,9 +357,6 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	struct clk_hw *parent_hw;
 	struct clk *parent_clk;
 
-	if (!meson_clk_init(np, CLK_NR_CLKS))
-		return;
-
 	/*  Generic clocks and PLLs */
 	clk_base = of_iomap(np, 1);
 	if (!clk_base) {
@@ -337,6 +371,11 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	/* Populate the base address for CPU clk */
 	meson8b_cpu_clk.base = clk_base;
 
+	/* Populate the base address for the MPEG clks */
+	meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
+	meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
+	meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
+
 	/*
 	 * register all clks
 	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
@@ -375,9 +414,7 @@ static void __init meson8b_clkc_init(struct device_node *np)
 		goto unregister_clk_nb;
 	}
 
-	meson_clk_register_clks(meson8b_clk_confs,
-				ARRAY_SIZE(meson8b_clk_confs),
-				clk_base);
+	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &meson8b_hw_onecell_data);
 	return;
 
 /* FIXME remove after converting to platform_driver/devm_clk_register */
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
index bd2720d..595a58d 100644
--- a/include/dt-bindings/clock/meson8b-clkc.h
+++ b/include/dt-bindings/clock/meson8b-clkc.h
@@ -19,7 +19,9 @@
 #define CLKID_MALI		11
 #define CLKID_CPUCLK		12
 #define CLKID_ZERO		13
+#define CLKID_MPEG_SEL		14
+#define CLKID_MPEG_DIV		15
 
-#define CLK_NR_CLKS		(CLKID_ZERO + 1)
+#define CLK_NR_CLKS		(CLKID_MPEG_DIV + 1)
 
 #endif /* __MESON8B_CLKC_H */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/10] clk: meson8b: convert to platform_driver
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

This patch creates a proper platform_driver for the meson8b clock
controller. Use of CLK_OF_DECLARE is removed, and can be added back in
later if very early registration of some clocks is required.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/meson8b-clkc.c | 67 +++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 57dea03..b1902e9 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -2,6 +2,9 @@
  * Copyright (c) 2015 Endless Mobile, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
  *
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Michael Turquette <mturquette@baylibre.com>
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  * version 2, as published by the Free Software Foundation.
@@ -17,11 +20,10 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/slab.h>
 #include <dt-bindings/clock/meson8b-clkc.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
 
 #include "clkc.h"
 
@@ -350,18 +352,19 @@ static struct meson_clk_pll *const meson8b_clk_plls[] = {
 	&meson8b_sys_pll,
 };
 
-static void __init meson8b_clkc_init(struct device_node *np)
+static int meson8b_clkc_probe(struct platform_device *pdev)
 {
 	void __iomem *clk_base;
 	int ret, clkid, i;
 	struct clk_hw *parent_hw;
 	struct clk *parent_clk;
+	struct device *dev = &pdev->dev;
 
 	/*  Generic clocks and PLLs */
-	clk_base = of_iomap(np, 1);
+	clk_base = of_iomap(dev->of_node, 1);
 	if (!clk_base) {
 		pr_err("%s: Unable to map clk base\n", __func__);
-		return;
+		return -ENXIO;
 	}
 
 	/* Populate base address for PLLs */
@@ -386,9 +389,9 @@ static void __init meson8b_clkc_init(struct device_node *np)
 			continue;
 
 		/* FIXME convert to devm_clk_register */
-		ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[clkid]);
+		ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
 		if (ret)
-			goto unregister;
+			goto iounmap;
 	}
 
 	/*
@@ -411,17 +414,45 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for cpu_clk\n",
 				__func__);
-		goto unregister_clk_nb;
+		goto iounmap;
 	}
 
-	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &meson8b_hw_onecell_data);
-	return;
+	return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+			&meson8b_hw_onecell_data);
 
-/* FIXME remove after converting to platform_driver/devm_clk_register */
-unregister_clk_nb:
-	clk_notifier_unregister(parent_clk, &meson8b_a5_clk.clk_nb);
-unregister:
-	for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--)
-		clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);
+iounmap:
+	iounmap(clk_base);
+	return ret;
 }
-CLK_OF_DECLARE(meson8b_clock, "amlogic,meson8b-clkc", meson8b_clkc_init);
+
+static const struct of_device_id meson8b_clkc_match_table[] = {
+	{ .compatible = "amlogic,meson8b-clkc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson8b_match_table);
+
+static struct platform_driver meson8b_driver = {
+	.probe		= meson8b_clkc_probe,
+	.driver		= {
+		.name	= "meson8b-clkc",
+		.of_match_table = meson8b_clkc_match_table,
+	},
+};
+
+static int __init meson8b_clkc_init(void)
+{
+	return platform_driver_register(&meson8b_driver);
+}
+module_init(meson8b_clkc_init);
+
+static void __exit meson8b_clkc_exit(void)
+{
+	platform_driver_unregister(&meson8b_driver);
+}
+module_exit(meson8b_clkc_exit);
+
+MODULE_DESCRIPTION("AmLogic S805 / Meson8b Clock Controller Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:meson8b-clkc");
+MODULE_AUTHOR("Michael Turquette <mturquette@baylibre.com>");
+MODULE_AUTHOR("Carlo Caione <carlo@endlessm.com>");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/10] clk: meson8b: convert to platform_driver
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

This patch creates a proper platform_driver for the meson8b clock
controller. Use of CLK_OF_DECLARE is removed, and can be added back in
later if very early registration of some clocks is required.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/meson/meson8b-clkc.c | 67 +++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 57dea03..b1902e9 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -2,6 +2,9 @@
  * Copyright (c) 2015 Endless Mobile, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
  *
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Michael Turquette <mturquette@baylibre.com>
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  * version 2, as published by the Free Software Foundation.
@@ -17,11 +20,10 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/slab.h>
 #include <dt-bindings/clock/meson8b-clkc.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
 
 #include "clkc.h"
 
@@ -350,18 +352,19 @@ static struct meson_clk_pll *const meson8b_clk_plls[] = {
 	&meson8b_sys_pll,
 };
 
-static void __init meson8b_clkc_init(struct device_node *np)
+static int meson8b_clkc_probe(struct platform_device *pdev)
 {
 	void __iomem *clk_base;
 	int ret, clkid, i;
 	struct clk_hw *parent_hw;
 	struct clk *parent_clk;
+	struct device *dev = &pdev->dev;
 
 	/*  Generic clocks and PLLs */
-	clk_base = of_iomap(np, 1);
+	clk_base = of_iomap(dev->of_node, 1);
 	if (!clk_base) {
 		pr_err("%s: Unable to map clk base\n", __func__);
-		return;
+		return -ENXIO;
 	}
 
 	/* Populate base address for PLLs */
@@ -386,9 +389,9 @@ static void __init meson8b_clkc_init(struct device_node *np)
 			continue;
 
 		/* FIXME convert to devm_clk_register */
-		ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[clkid]);
+		ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
 		if (ret)
-			goto unregister;
+			goto iounmap;
 	}
 
 	/*
@@ -411,17 +414,45 @@ static void __init meson8b_clkc_init(struct device_node *np)
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for cpu_clk\n",
 				__func__);
-		goto unregister_clk_nb;
+		goto iounmap;
 	}
 
-	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &meson8b_hw_onecell_data);
-	return;
+	return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+			&meson8b_hw_onecell_data);
 
-/* FIXME remove after converting to platform_driver/devm_clk_register */
-unregister_clk_nb:
-	clk_notifier_unregister(parent_clk, &meson8b_a5_clk.clk_nb);
-unregister:
-	for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--)
-		clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);
+iounmap:
+	iounmap(clk_base);
+	return ret;
 }
-CLK_OF_DECLARE(meson8b_clock, "amlogic,meson8b-clkc", meson8b_clkc_init);
+
+static const struct of_device_id meson8b_clkc_match_table[] = {
+	{ .compatible = "amlogic,meson8b-clkc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson8b_match_table);
+
+static struct platform_driver meson8b_driver = {
+	.probe		= meson8b_clkc_probe,
+	.driver		= {
+		.name	= "meson8b-clkc",
+		.of_match_table = meson8b_clkc_match_table,
+	},
+};
+
+static int __init meson8b_clkc_init(void)
+{
+	return platform_driver_register(&meson8b_driver);
+}
+module_init(meson8b_clkc_init);
+
+static void __exit meson8b_clkc_exit(void)
+{
+	platform_driver_unregister(&meson8b_driver);
+}
+module_exit(meson8b_clkc_exit);
+
+MODULE_DESCRIPTION("AmLogic S805 / Meson8b Clock Controller Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:meson8b-clkc");
+MODULE_AUTHOR("Michael Turquette <mturquette@baylibre.com>");
+MODULE_AUTHOR("Carlo Caione <carlo@endlessm.com>");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/10] arm: meson: explicitly select clk drivers
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

The AmLogic clock controller code is used by both arm and arm64
architectures. Explicitly select the core code for all Meson (32-bit
arm) builds, and also select the Meson8b driver when that machine is
built.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 arch/arm/mach-meson/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index 31bdd91..c689219 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -7,6 +7,8 @@ menuconfig ARCH_MESON
 	select CACHE_L2X0
 	select PINCTRL
 	select PINCTRL_MESON
+	select COMMON_CLK
+	select COMMON_CLK_AMLOGIC
 
 if ARCH_MESON
 
@@ -24,5 +26,6 @@ config MACH_MESON8B
 	bool "Amlogic Meson8b SoCs support"
 	default ARCH_MESON
 	select MESON6_TIMER
+	select COMMON_CLK_MESON8B
 
 endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/10] arm: meson: explicitly select clk drivers
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

The AmLogic clock controller code is used by both arm and arm64
architectures. Explicitly select the core code for all Meson (32-bit
arm) builds, and also select the Meson8b driver when that machine is
built.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 arch/arm/mach-meson/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index 31bdd91..c689219 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -7,6 +7,8 @@ menuconfig ARCH_MESON
 	select CACHE_L2X0
 	select PINCTRL
 	select PINCTRL_MESON
+	select COMMON_CLK
+	select COMMON_CLK_AMLOGIC
 
 if ARCH_MESON
 
@@ -24,5 +26,6 @@ config MACH_MESON8B
 	bool "Amlogic Meson8b SoCs support"
 	default ARCH_MESON
 	select MESON6_TIMER
+	select COMMON_CLK_MESON8B
 
 endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/10] clk: meson: only build selected platforms
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-10  0:27   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

Break the AmLogic clock code up so that only the necessary parts are
compiled and linked. The core code is selected by both arm and arm64
builds with COMMON_CLK_AMLOGIC. The individual drivers have their own
config options as well.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/Kconfig        |  1 +
 drivers/clk/Makefile       |  2 +-
 drivers/clk/meson/Kconfig  | 12 ++++++++++++
 drivers/clk/meson/Makefile |  4 ++--
 4 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 drivers/clk/meson/Kconfig

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 53ddba2..30feb6b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -208,6 +208,7 @@ config COMMON_CLK_OXNAS
 
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
+source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/renesas/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index dcc5e69..af03eb2 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -65,7 +65,7 @@ ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
 endif
 obj-y					+= mvebu/
-obj-$(CONFIG_ARCH_MESON)		+= meson/
+obj-$(CONFIG_COMMON_CLK_AMLOGIC)	+= meson/
 obj-$(CONFIG_ARCH_MXS)			+= mxs/
 obj-$(CONFIG_MACH_PISTACHIO)		+= pistachio/
 obj-$(CONFIG_COMMON_CLK_NXP)		+= nxp/
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
new file mode 100644
index 0000000..7bb19ad
--- /dev/null
+++ b/drivers/clk/meson/Kconfig
@@ -0,0 +1,12 @@
+config COMMON_CLK_AMLOGIC
+	bool
+	depends on OF
+	depends on ARCH_MESON || COMPILE_TEST
+
+config COMMON_CLK_MESON8B
+	bool
+	depends on COMMON_CLK_AMLOGIC
+	help
+	  Support for the clock controller on AmLogic S805 devices, aka
+	  meson8b. Say Y if you want peripherals and CPU frequency scaling to
+	  work.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 901b5d4..b3d60fe 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,5 +2,5 @@
 # Makefile for Meson specific clk
 #
 
-obj-y += clk-pll.o clk-cpu.o
-obj-y += meson8b-clkc.o
+obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o
+obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b-clkc.o
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/10] clk: meson: only build selected platforms
@ 2016-06-10  0:27   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-10  0:27 UTC (permalink / raw)
  To: linus-amlogic

Break the AmLogic clock code up so that only the necessary parts are
compiled and linked. The core code is selected by both arm and arm64
builds with COMMON_CLK_AMLOGIC. The individual drivers have their own
config options as well.

Signed-off-by: Michael Turquette <mturquette@baylibre.com>
---
 drivers/clk/Kconfig        |  1 +
 drivers/clk/Makefile       |  2 +-
 drivers/clk/meson/Kconfig  | 12 ++++++++++++
 drivers/clk/meson/Makefile |  4 ++--
 4 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 drivers/clk/meson/Kconfig

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 53ddba2..30feb6b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -208,6 +208,7 @@ config COMMON_CLK_OXNAS
 
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
+source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/renesas/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index dcc5e69..af03eb2 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -65,7 +65,7 @@ ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
 endif
 obj-y					+= mvebu/
-obj-$(CONFIG_ARCH_MESON)		+= meson/
+obj-$(CONFIG_COMMON_CLK_AMLOGIC)	+= meson/
 obj-$(CONFIG_ARCH_MXS)			+= mxs/
 obj-$(CONFIG_MACH_PISTACHIO)		+= pistachio/
 obj-$(CONFIG_COMMON_CLK_NXP)		+= nxp/
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
new file mode 100644
index 0000000..7bb19ad
--- /dev/null
+++ b/drivers/clk/meson/Kconfig
@@ -0,0 +1,12 @@
+config COMMON_CLK_AMLOGIC
+	bool
+	depends on OF
+	depends on ARCH_MESON || COMPILE_TEST
+
+config COMMON_CLK_MESON8B
+	bool
+	depends on COMMON_CLK_AMLOGIC
+	help
+	  Support for the clock controller on AmLogic S805 devices, aka
+	  meson8b. Say Y if you want peripherals and CPU frequency scaling to
+	  work.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 901b5d4..b3d60fe 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,5 +2,5 @@
 # Makefile for Meson specific clk
 #
 
-obj-y += clk-pll.o clk-cpu.o
-obj-y += meson8b-clkc.o
+obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o
+obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b-clkc.o
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/10] meson8b clock driver rewrite/cleanup
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-14 19:12   ` Kevin Hilman
  -1 siblings, 0 replies; 28+ messages in thread
From: Kevin Hilman @ 2016-06-14 19:12 UTC (permalink / raw)
  To: Michael Turquette
  Cc: linux-clk, linux-amlogic, carlo, victor.wan, jerry.cao, xing.xu

Michael Turquette <mturquette@baylibre.com> writes:

> This series came about while writing the clock driver for the AmLogic
> GXBB clock controller. GXBB shares much of the same clock controller IP
> as the Meson8b clock controller and the source for the drivers is very
> similar. However, I wanted the GXBB driver to actually be a real
> platform_driver, and not an early initcall, which led to the same
> changes in the Meson8b driver. From there a lot of other changes came
> about.
>
> This series improves documentation, refactors statically initialized
> data, removes unnecessary registration functions and converts the
> meson8b clock controller code into a proper platform_driver. It also
> changes up the Kconfig bits to prepare for the gxbb clock controller.
> The diffstat is -190, which is nice as well.
>
> As a consequence of the shift to platform_driver, all of clocks are
> registered at module_init time. If any are needed very early during boot
> then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
> necessary.
>
> Additionally this series makes use of some of the nice clk_hw helper
> introduced by Stephen, especially clk_hw_onecell_data.

Not sure if it qualifies as much of a clock test, but I at least boot
tested this on meson8b-odroidc1 and nothing exploded, and the
clk_summary looks sane:

/ # cat /debug/clk/clk_summary
   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase
   ----------------------------------------------------------------------------------------
    xtal                                     0            0    24000000   0 0
       sys_pll                               0            0  1200000000   0 0
          cpu_clk                            0            0  1200000000   0 0
       vid_pll                               0            0   732000000   0 0
       fixed_pll                             0            0  2550000000   0 0
          fclk_div7                          0            0   364285714   0 0
          fclk_div5                          0            0   510000000   0 0
          fclk_div4                          0            0   637500000   0 0
             mpeg_clk_sel                    0            0   637500000   0 0
                mpeg_clk_div                 0            0   159375000   0 0
                   clk81                     0            0   159375000   0 0
          fclk_div3                          0            0   850000000   0 0
          fclk_div2                          0            0  1275000000   0 0

Kevin

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 00/10] meson8b clock driver rewrite/cleanup
@ 2016-06-14 19:12   ` Kevin Hilman
  0 siblings, 0 replies; 28+ messages in thread
From: Kevin Hilman @ 2016-06-14 19:12 UTC (permalink / raw)
  To: linus-amlogic

Michael Turquette <mturquette@baylibre.com> writes:

> This series came about while writing the clock driver for the AmLogic
> GXBB clock controller. GXBB shares much of the same clock controller IP
> as the Meson8b clock controller and the source for the drivers is very
> similar. However, I wanted the GXBB driver to actually be a real
> platform_driver, and not an early initcall, which led to the same
> changes in the Meson8b driver. From there a lot of other changes came
> about.
>
> This series improves documentation, refactors statically initialized
> data, removes unnecessary registration functions and converts the
> meson8b clock controller code into a proper platform_driver. It also
> changes up the Kconfig bits to prepare for the gxbb clock controller.
> The diffstat is -190, which is nice as well.
>
> As a consequence of the shift to platform_driver, all of clocks are
> registered at module_init time. If any are needed very early during boot
> then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
> necessary.
>
> Additionally this series makes use of some of the nice clk_hw helper
> introduced by Stephen, especially clk_hw_onecell_data.

Not sure if it qualifies as much of a clock test, but I at least boot
tested this on meson8b-odroidc1 and nothing exploded, and the
clk_summary looks sane:

/ # cat /debug/clk/clk_summary
   clock                         enable_cnt  prepare_cnt        rate   accuracy   phase
   ----------------------------------------------------------------------------------------
    xtal                                     0            0    24000000   0 0
       sys_pll                               0            0  1200000000   0 0
          cpu_clk                            0            0  1200000000   0 0
       vid_pll                               0            0   732000000   0 0
       fixed_pll                             0            0  2550000000   0 0
          fclk_div7                          0            0   364285714   0 0
          fclk_div5                          0            0   510000000   0 0
          fclk_div4                          0            0   637500000   0 0
             mpeg_clk_sel                    0            0   637500000   0 0
                mpeg_clk_div                 0            0   159375000   0 0
                   clk81                     0            0   159375000   0 0
          fclk_div3                          0            0   850000000   0 0
          fclk_div2                          0            0  1275000000   0 0

Kevin

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/10] meson8b clock driver rewrite/cleanup
  2016-06-14 19:12   ` Kevin Hilman
@ 2016-06-17  4:48     ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-17  4:48 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-clk, linux-amlogic, carlo, victor.wan, jerry.cao, xing.xu

Quoting Kevin Hilman (2016-06-14 12:12:50)
> Michael Turquette <mturquette@baylibre.com> writes:
> =

> > This series came about while writing the clock driver for the AmLogic
> > GXBB clock controller. GXBB shares much of the same clock controller IP
> > as the Meson8b clock controller and the source for the drivers is very
> > similar. However, I wanted the GXBB driver to actually be a real
> > platform_driver, and not an early initcall, which led to the same
> > changes in the Meson8b driver. From there a lot of other changes came
> > about.
> >
> > This series improves documentation, refactors statically initialized
> > data, removes unnecessary registration functions and converts the
> > meson8b clock controller code into a proper platform_driver. It also
> > changes up the Kconfig bits to prepare for the gxbb clock controller.
> > The diffstat is -190, which is nice as well.
> >
> > As a consequence of the shift to platform_driver, all of clocks are
> > registered at module_init time. If any are needed very early during boot
> > then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
> > necessary.
> >
> > Additionally this series makes use of some of the nice clk_hw helper
> > introduced by Stephen, especially clk_hw_onecell_data.
> =

> Not sure if it qualifies as much of a clock test, but I at least boot
> tested this on meson8b-odroidc1 and nothing exploded, and the
> clk_summary looks sane:
> =

> / # cat /debug/clk/clk_summary
>    clock                         enable_cnt  prepare_cnt        rate   ac=
curacy   phase
>    ----------------------------------------------------------------------=
------------------
>     xtal                                     0            0    24000000  =
 0 0
>        sys_pll                               0            0  1200000000  =
 0 0
>           cpu_clk                            0            0  1200000000  =
 0 0
>        vid_pll                               0            0   732000000  =
 0 0
>        fixed_pll                             0            0  2550000000  =
 0 0
>           fclk_div7                          0            0   364285714  =
 0 0
>           fclk_div5                          0            0   510000000  =
 0 0
>           fclk_div4                          0            0   637500000  =
 0 0
>              mpeg_clk_sel                    0            0   637500000  =
 0 0
>                 mpeg_clk_div                 0            0   159375000  =
 0 0
>                    clk81                     0            0   159375000  =
 0 0
>           fclk_div3                          0            0   850000000  =
 0 0
>           fclk_div2                          0            0  1275000000  =
 0 0

Thanks Kevin. I'll take that as a Tested-by.

Regards,
Mike

> =

> Kevin

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 00/10] meson8b clock driver rewrite/cleanup
@ 2016-06-17  4:48     ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-17  4:48 UTC (permalink / raw)
  To: linus-amlogic

Quoting Kevin Hilman (2016-06-14 12:12:50)
> Michael Turquette <mturquette@baylibre.com> writes:
> 
> > This series came about while writing the clock driver for the AmLogic
> > GXBB clock controller. GXBB shares much of the same clock controller IP
> > as the Meson8b clock controller and the source for the drivers is very
> > similar. However, I wanted the GXBB driver to actually be a real
> > platform_driver, and not an early initcall, which led to the same
> > changes in the Meson8b driver. From there a lot of other changes came
> > about.
> >
> > This series improves documentation, refactors statically initialized
> > data, removes unnecessary registration functions and converts the
> > meson8b clock controller code into a proper platform_driver. It also
> > changes up the Kconfig bits to prepare for the gxbb clock controller.
> > The diffstat is -190, which is nice as well.
> >
> > As a consequence of the shift to platform_driver, all of clocks are
> > registered at module_init time. If any are needed very early during boot
> > then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
> > necessary.
> >
> > Additionally this series makes use of some of the nice clk_hw helper
> > introduced by Stephen, especially clk_hw_onecell_data.
> 
> Not sure if it qualifies as much of a clock test, but I at least boot
> tested this on meson8b-odroidc1 and nothing exploded, and the
> clk_summary looks sane:
> 
> / # cat /debug/clk/clk_summary
>    clock                         enable_cnt  prepare_cnt        rate   accuracy   phase
>    ----------------------------------------------------------------------------------------
>     xtal                                     0            0    24000000   0 0
>        sys_pll                               0            0  1200000000   0 0
>           cpu_clk                            0            0  1200000000   0 0
>        vid_pll                               0            0   732000000   0 0
>        fixed_pll                             0            0  2550000000   0 0
>           fclk_div7                          0            0   364285714   0 0
>           fclk_div5                          0            0   510000000   0 0
>           fclk_div4                          0            0   637500000   0 0
>              mpeg_clk_sel                    0            0   637500000   0 0
>                 mpeg_clk_div                 0            0   159375000   0 0
>                    clk81                     0            0   159375000   0 0
>           fclk_div3                          0            0   850000000   0 0
>           fclk_div2                          0            0  1275000000   0 0

Thanks Kevin. I'll take that as a Tested-by.

Regards,
Mike

> 
> Kevin

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/10] meson8b clock driver rewrite/cleanup
  2016-06-10  0:27 ` Michael Turquette
@ 2016-06-23  2:07   ` Michael Turquette
  -1 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-23  2:07 UTC (permalink / raw)
  To: linux-clk; +Cc: linux-amlogic, khilman, carlo, victor.wan, jerry.cao, xing.xu

Quoting Michael Turquette (2016-06-09 17:27:37)
> This series came about while writing the clock driver for the AmLogic
> GXBB clock controller. GXBB shares much of the same clock controller IP
> as the Meson8b clock controller and the source for the drivers is very
> similar. However, I wanted the GXBB driver to actually be a real
> platform_driver, and not an early initcall, which led to the same
> changes in the Meson8b driver. From there a lot of other changes came
> about.

Applied to clk-next.

Regards,
Mike

> =

> This series improves documentation, refactors statically initialized
> data, removes unnecessary registration functions and converts the
> meson8b clock controller code into a proper platform_driver. It also
> changes up the Kconfig bits to prepare for the gxbb clock controller.
> The diffstat is -190, which is nice as well.
> =

> As a consequence of the shift to platform_driver, all of clocks are
> registered at module_init time. If any are needed very early during boot
> then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
> necessary.
> =

> Additionally this series makes use of some of the nice clk_hw helper
> introduced by Stephen, especially clk_hw_onecell_data.
> =

> Michael Turquette (10):
>   clk: meson8b: rectify reg offsets with datasheet
>   clk: meson8b: clean up fixed rate clocks
>   clk: meson8b: clean up pll clocks
>   clk: meson8b: clean up fixed factor clocks
>   clk: meson8b: clean up cpu clocks
>   clk: meson8b: remove mali clk
>   clk: meson8b: clean up composite clocks
>   clk: meson8b: convert to platform_driver
>   arm: meson: explicitly select clk drivers
>   clk: meson: only build selected platforms
> =

>  arch/arm/mach-meson/Kconfig              |   3 +
>  drivers/clk/Kconfig                      |   1 +
>  drivers/clk/Makefile                     |   2 +-
>  drivers/clk/meson/Kconfig                |  12 +
>  drivers/clk/meson/Makefile               |   4 +-
>  drivers/clk/meson/clk-cpu.c              |  73 +-----
>  drivers/clk/meson/clk-pll.c              |  72 +----
>  drivers/clk/meson/clkc.c                 | 249 ------------------
>  drivers/clk/meson/clkc.h                 | 150 ++---------
>  drivers/clk/meson/meson8b-clkc.c         | 436 +++++++++++++++++++++++++=
------
>  include/dt-bindings/clock/meson8b-clkc.h |   4 +-
>  11 files changed, 408 insertions(+), 598 deletions(-)
>  create mode 100644 drivers/clk/meson/Kconfig
>  delete mode 100644 drivers/clk/meson/clkc.c
> =

> -- =

> 2.1.4
>=20

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 00/10] meson8b clock driver rewrite/cleanup
@ 2016-06-23  2:07   ` Michael Turquette
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Turquette @ 2016-06-23  2:07 UTC (permalink / raw)
  To: linus-amlogic

Quoting Michael Turquette (2016-06-09 17:27:37)
> This series came about while writing the clock driver for the AmLogic
> GXBB clock controller. GXBB shares much of the same clock controller IP
> as the Meson8b clock controller and the source for the drivers is very
> similar. However, I wanted the GXBB driver to actually be a real
> platform_driver, and not an early initcall, which led to the same
> changes in the Meson8b driver. From there a lot of other changes came
> about.

Applied to clk-next.

Regards,
Mike

> 
> This series improves documentation, refactors statically initialized
> data, removes unnecessary registration functions and converts the
> meson8b clock controller code into a proper platform_driver. It also
> changes up the Kconfig bits to prepare for the gxbb clock controller.
> The diffstat is -190, which is nice as well.
> 
> As a consequence of the shift to platform_driver, all of clocks are
> registered at module_init time. If any are needed very early during boot
> then the OF_CLK_DECLARE stuff can be added back in, but I doubt it is
> necessary.
> 
> Additionally this series makes use of some of the nice clk_hw helper
> introduced by Stephen, especially clk_hw_onecell_data.
> 
> Michael Turquette (10):
>   clk: meson8b: rectify reg offsets with datasheet
>   clk: meson8b: clean up fixed rate clocks
>   clk: meson8b: clean up pll clocks
>   clk: meson8b: clean up fixed factor clocks
>   clk: meson8b: clean up cpu clocks
>   clk: meson8b: remove mali clk
>   clk: meson8b: clean up composite clocks
>   clk: meson8b: convert to platform_driver
>   arm: meson: explicitly select clk drivers
>   clk: meson: only build selected platforms
> 
>  arch/arm/mach-meson/Kconfig              |   3 +
>  drivers/clk/Kconfig                      |   1 +
>  drivers/clk/Makefile                     |   2 +-
>  drivers/clk/meson/Kconfig                |  12 +
>  drivers/clk/meson/Makefile               |   4 +-
>  drivers/clk/meson/clk-cpu.c              |  73 +-----
>  drivers/clk/meson/clk-pll.c              |  72 +----
>  drivers/clk/meson/clkc.c                 | 249 ------------------
>  drivers/clk/meson/clkc.h                 | 150 ++---------
>  drivers/clk/meson/meson8b-clkc.c         | 436 +++++++++++++++++++++++++------
>  include/dt-bindings/clock/meson8b-clkc.h |   4 +-
>  11 files changed, 408 insertions(+), 598 deletions(-)
>  create mode 100644 drivers/clk/meson/Kconfig
>  delete mode 100644 drivers/clk/meson/clkc.c
> 
> -- 
> 2.1.4
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2016-06-23  2:07 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-10  0:27 [PATCH 00/10] meson8b clock driver rewrite/cleanup Michael Turquette
2016-06-10  0:27 ` Michael Turquette
2016-06-10  0:27 ` [PATCH 01/10] clk: meson8b: rectify reg offsets with datasheet Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 02/10] clk: meson8b: clean up fixed rate clocks Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 03/10] clk: meson8b: clean up pll clocks Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 04/10] clk: meson8b: clean up fixed factor clocks Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 05/10] clk: meson8b: clean up cpu clocks Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 06/10] clk: meson8b: remove mali clk Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 07/10] clk: meson8b: clean up composite clocks Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 08/10] clk: meson8b: convert to platform_driver Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 09/10] arm: meson: explicitly select clk drivers Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-10  0:27 ` [PATCH 10/10] clk: meson: only build selected platforms Michael Turquette
2016-06-10  0:27   ` Michael Turquette
2016-06-14 19:12 ` [PATCH 00/10] meson8b clock driver rewrite/cleanup Kevin Hilman
2016-06-14 19:12   ` Kevin Hilman
2016-06-17  4:48   ` Michael Turquette
2016-06-17  4:48     ` Michael Turquette
2016-06-23  2:07 ` Michael Turquette
2016-06-23  2:07   ` Michael Turquette

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.