All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support
@ 2013-12-18  0:44 Emilio López
  2013-12-18  0:44 ` [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite Emilio López
                   ` (10 more replies)
  0 siblings, 11 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi everyone,

This is a v2 of the sunxi clock series I posted some time ago. It adds 
PLL4, PLL5, PLL6 and mod0 support on sun4i, sun5i and sun7i. Additionally,
mbus is supported on sun5i and sun7i. I would like to see this merged 
for 3.14 as clock users are progressing rapidly and will be needing this 
code, so all feedback is appreciated.

It's been some time since I worked on this series, so I cannot make a 
detailed changelog, but in general, I addressed the comments made by 
Maxime on the previous iteration, and reworked the PLL5/6 clk patch to 
fix an issue with a gate that the people working on the SATA driver made 
me aware of.

Cheers,

Emilio

Emilio L?pez (11):
  clk: sunxi: register factors clocks behind composite
  clk: sunxi: add gating support to PLL1
  ARM: sunxi: add PLL4 support
  clk: sunxi: make factors_clk_setup return the clock it registers
  clk: sunxi: add PLL5 and PLL6 support
  ARM: sunxi: add PLL5 and PLL6 support
  clk: sunxi: mod0 support
  ARM: sun4i: dt: mod0 clocks
  ARM: sun5i: dt: mod0 clocks
  ARM: sun7i: dt: mod0 clocks
  ARM: sunxi: dt: add nodes for the mbus clock

 Documentation/devicetree/bindings/clock/sunxi.txt |   9 +-
 arch/arm/boot/dts/sun4i-a10.dtsi                  | 131 +++++++-
 arch/arm/boot/dts/sun5i-a10s.dtsi                 | 110 ++++++-
 arch/arm/boot/dts/sun5i-a13.dtsi                  | 110 ++++++-
 arch/arm/boot/dts/sun7i-a20.dtsi                  | 145 ++++++++-
 drivers/clk/sunxi/clk-factors.c                   |  63 +---
 drivers/clk/sunxi/clk-factors.h                   |  16 +-
 drivers/clk/sunxi/clk-sunxi.c                     | 364 +++++++++++++++++++++-
 8 files changed, 854 insertions(+), 94 deletions(-)

-- 
1.8.5.1

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

* [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
@ 2013-12-18  0:44 ` Emilio López
  2013-12-18  2:55   ` Mike Turquette
  2013-12-18  0:44 ` [PATCH v2 02/11] clk: sunxi: add gating support to PLL1 Emilio López
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

This commit reworks factors clock registration to be done behind a
composite clock. This allows us to additionally add a gate, mux or
divisors, as it will be needed by some future PLLs.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi/clk-factors.c | 63 +--------------------------------------
 drivers/clk/sunxi/clk-factors.h | 16 +++++-----
 drivers/clk/sunxi/clk-sunxi.c   | 66 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 72 insertions(+), 73 deletions(-)

diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index f05207a..9e23264 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -30,14 +30,6 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
-struct clk_factors {
-	struct clk_hw hw;
-	void __iomem *reg;
-	struct clk_factors_config *config;
-	void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
-	spinlock_t *lock;
-};
-
 #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
 
 #define SETMASK(len, pos)		(((1U << (len)) - 1) << (pos))
@@ -120,61 +112,8 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
-static const struct clk_ops clk_factors_ops = {
+const struct clk_ops clk_factors_ops = {
 	.recalc_rate = clk_factors_recalc_rate,
 	.round_rate = clk_factors_round_rate,
 	.set_rate = clk_factors_set_rate,
 };
-
-/**
- * clk_register_factors - register a factors clock with
- * the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust factors
- * @config: shift and width of factors n, k, m and p
- * @get_factors: function to calculate the factors for a given frequency
- * @lock: shared register lock for this clock
- */
-struct clk *clk_register_factors(struct device *dev, const char *name,
-				 const char *parent_name,
-				 unsigned long flags, void __iomem *reg,
-				 struct clk_factors_config *config,
-				 void (*get_factors)(u32 *rate, u32 parent,
-						     u8 *n, u8 *k, u8 *m, u8 *p),
-				 spinlock_t *lock)
-{
-	struct clk_factors *factors;
-	struct clk *clk;
-	struct clk_init_data init;
-
-	/* allocate the factors */
-	factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
-	if (!factors) {
-		pr_err("%s: could not allocate factors clk\n", __func__);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	init.name = name;
-	init.ops = &clk_factors_ops;
-	init.flags = flags;
-	init.parent_names = (parent_name ? &parent_name : NULL);
-	init.num_parents = (parent_name ? 1 : 0);
-
-	/* struct clk_factors assignments */
-	factors->reg = reg;
-	factors->config = config;
-	factors->lock = lock;
-	factors->hw.init = &init;
-	factors->get_factors = get_factors;
-
-	/* register the clock */
-	clk = clk_register(dev, &factors->hw);
-
-	if (IS_ERR(clk))
-		kfree(factors);
-
-	return clk;
-}
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index f49851c..02e1a43 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -17,11 +17,13 @@ struct clk_factors_config {
 	u8 pwidth;
 };
 
-struct clk *clk_register_factors(struct device *dev, const char *name,
-				 const char *parent_name,
-				 unsigned long flags, void __iomem *reg,
-				 struct clk_factors_config *config,
-				 void (*get_factors) (u32 *rate, u32 parent_rate,
-						      u8 *n, u8 *k, u8 *m, u8 *p),
-				 spinlock_t *lock);
+struct clk_factors {
+	struct clk_hw hw;
+	void __iomem *reg;
+	struct clk_factors_config *config;
+	void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
+	spinlock_t *lock;
+};
+
+extern const struct clk_ops clk_factors_ops;
 #endif
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 8fc1375..6f756f4 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -255,7 +255,11 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
  * sunxi_factors_clk_setup() - Setup function for factor clocks
  */
 
+#define SUNXI_FACTORS_MUX_MASK 0x3
+
 struct factors_data {
+	int enable;
+	int mux;
 	struct clk_factors_config *table;
 	void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
 };
@@ -306,16 +310,70 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
 					   struct factors_data *data)
 {
 	struct clk *clk;
+	struct clk_factors *factors;
+	struct clk_gate *gate = NULL;
+	struct clk_mux *mux = NULL;
+	struct clk_hw *gate_hw = NULL;
+	struct clk_hw *mux_hw = NULL;
 	const char *clk_name = node->name;
-	const char *parent;
+	const char *parents[5];
 	void *reg;
+	int i = 0;
 
 	reg = of_iomap(node, 0);
 
-	parent = of_clk_get_parent_name(node, 0);
+	/* if we have a mux, we will have >1 parents */
+	while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+		i++;
+
+	factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+	if (!factors)
+		return;
 
-	clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
-				   data->table, data->getter, &clk_lock);
+	/* Add a gate if this factor clock can be gated */
+	if (data->enable) {
+		gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+		if (!gate) {
+			kfree(factors);
+			return;
+		}
+
+		/* set up gate properties */
+		gate->reg = reg;
+		gate->bit_idx = data->enable;
+		gate->lock = &clk_lock;
+		gate_hw = &gate->hw;
+	}
+
+	/* Add a mux if this factor clock can be muxed */
+	if (data->mux) {
+		mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+		if (!mux) {
+			kfree(factors);
+			kfree(gate);
+			return;
+		}
+
+		/* set up gate properties */
+		mux->reg = reg;
+		mux->shift = data->mux;
+		mux->mask = SUNXI_FACTORS_MUX_MASK;
+		mux->lock = &clk_lock;
+		mux_hw = &mux->hw;
+	}
+
+	/* set up factors properties */
+	factors->reg = reg;
+	factors->config = data->table;
+	factors->get_factors = data->getter;
+	factors->lock = &clk_lock;
+
+	clk = clk_register_composite(NULL, clk_name,
+			parents, i,
+			mux_hw, &clk_mux_ops,
+			&factors->hw, &clk_factors_ops,
+			gate_hw, &clk_gate_ops,
+			i ? 0 : CLK_IS_ROOT);
 
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
-- 
1.8.5.1

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

* [PATCH v2 02/11] clk: sunxi: add gating support to PLL1
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
  2013-12-18  0:44 ` [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite Emilio López
@ 2013-12-18  0:44 ` Emilio López
  2013-12-18  2:57   ` Mike Turquette
  2013-12-18  0:44 ` [PATCH v2 03/11] ARM: sunxi: add PLL4 support Emilio López
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds gating support to PLL1 on the clock driver. This makes
the PLL1 implementation fully compatible with PLL4 as well.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 Documentation/devicetree/bindings/clock/sunxi.txt | 2 +-
 drivers/clk/sunxi/clk-sunxi.c                     | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 91a748f..b8c6cc4 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -7,7 +7,7 @@ This binding uses the common clock binding[1].
 Required properties:
 - compatible : shall be one of the following:
 	"allwinner,sun4i-osc-clk" - for a gatable oscillator
-	"allwinner,sun4i-pll1-clk" - for the main PLL clock
+	"allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
 	"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
 	"allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
 	"allwinner,sun4i-axi-clk" - for the AXI clock
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 6f756f4..5b86234 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -292,11 +292,13 @@ static struct clk_factors_config sun4i_apb1_config = {
 };
 
 static const struct factors_data sun4i_pll1_data __initconst = {
+	.enable = 31,
 	.table = &sun4i_pll1_config,
 	.getter = sun4i_get_pll1_factors,
 };
 
 static const struct factors_data sun6i_a31_pll1_data __initconst = {
+	.enable = 31,
 	.table = &sun6i_a31_pll1_config,
 	.getter = sun6i_a31_get_pll1_factors,
 };
-- 
1.8.5.1

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

* [PATCH v2 03/11] ARM: sunxi: add PLL4 support
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
  2013-12-18  0:44 ` [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite Emilio López
  2013-12-18  0:44 ` [PATCH v2 02/11] clk: sunxi: add gating support to PLL1 Emilio López
@ 2013-12-18  0:44 ` Emilio López
  2013-12-18  0:44 ` [PATCH v2 04/11] clk: sunxi: make factors_clk_setup return the clock it registers Emilio López
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds the PLL4 definition to the sun4i, sun5i and sun7i
device trees. PLL4 is compatible with PLL1.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun4i-a10.dtsi  | 7 +++++++
 arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
 arch/arm/boot/dts/sun5i-a13.dtsi  | 7 +++++++
 arch/arm/boot/dts/sun7i-a20.dtsi  | 7 +++++++
 4 files changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 5b158d2..3833c14 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -70,6 +70,13 @@
 			clocks = <&osc24M>;
 		};
 
+		pll4: pll4 at 01c20018 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-pll1-clk";
+			reg = <0x01c20018 0x4>;
+			clocks = <&osc24M>;
+		};
+
 		/* dummy is 200M */
 		cpu: cpu at 01c20054 {
 			#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index b4764be..3252aa8 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -67,6 +67,13 @@
 			clocks = <&osc24M>;
 		};
 
+		pll4: pll4 at 01c20018 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-pll1-clk";
+			reg = <0x01c20018 0x4>;
+			clocks = <&osc24M>;
+		};
+
 		/* dummy is 200M */
 		cpu: cpu at 01c20054 {
 			#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index ce8ef2a..8c4a9c3 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -67,6 +67,13 @@
 			clocks = <&osc24M>;
 		};
 
+		pll4: pll4 at 01c20018 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-pll1-clk";
+			reg = <0x01c20018 0x4>;
+			clocks = <&osc24M>;
+		};
+
 		/* dummy is 200M */
 		cpu: cpu at 01c20054 {
 			#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index d62d693..2b2d3847 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -66,6 +66,13 @@
 			clocks = <&osc24M>;
 		};
 
+		pll4: pll4 at 01c20018 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-pll1-clk";
+			reg = <0x01c20018 0x4>;
+			clocks = <&osc24M>;
+		};
+
 		/*
 		 * This is a dummy clock, to be used as placeholder on
 		 * other mux clocks when a specific parent clock is not
-- 
1.8.5.1

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

* [PATCH v2 04/11] clk: sunxi: make factors_clk_setup return the clock it registers
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (2 preceding siblings ...)
  2013-12-18  0:44 ` [PATCH v2 03/11] ARM: sunxi: add PLL4 support Emilio López
@ 2013-12-18  0:44 ` Emilio López
  2013-12-18  3:01   ` Mike Turquette
  2013-12-18  0:44 ` [PATCH v2 05/11] clk: sunxi: add PLL5 and PLL6 support Emilio López
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

We will be needing this to register a factor clock as parent with leaf
divisors on a single call. While at it, also prepare the function to set
the ignore flag on pll5, so our RAM keeps working.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
---
 drivers/clk/sunxi/clk-sunxi.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 5b86234..401169b 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -308,8 +308,8 @@ static const struct factors_data sun4i_apb1_data __initconst = {
 	.getter = sun4i_get_apb1_factors,
 };
 
-static void __init sunxi_factors_clk_setup(struct device_node *node,
-					   struct factors_data *data)
+static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
+						const struct factors_data *data)
 {
 	struct clk *clk;
 	struct clk_factors *factors;
@@ -320,6 +320,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
 	const char *clk_name = node->name;
 	const char *parents[5];
 	void *reg;
+	unsigned long flags;
 	int i = 0;
 
 	reg = of_iomap(node, 0);
@@ -330,14 +331,14 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
 
 	factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
 	if (!factors)
-		return;
+		return NULL;
 
 	/* Add a gate if this factor clock can be gated */
 	if (data->enable) {
 		gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
 		if (!gate) {
 			kfree(factors);
-			return;
+			return NULL;
 		}
 
 		/* set up gate properties */
@@ -353,7 +354,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
 		if (!mux) {
 			kfree(factors);
 			kfree(gate);
-			return;
+			return NULL;
 		}
 
 		/* set up gate properties */
@@ -370,17 +371,21 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
 	factors->get_factors = data->getter;
 	factors->lock = &clk_lock;
 
+	/* We should not disable pll5, it powers the RAM */
+	flags = !strcmp("pll5", clk_name) ? CLK_IGNORE_UNUSED : 0;
+
 	clk = clk_register_composite(NULL, clk_name,
 			parents, i,
 			mux_hw, &clk_mux_ops,
 			&factors->hw, &clk_factors_ops,
-			gate_hw, &clk_gate_ops,
-			i ? 0 : CLK_IS_ROOT);
+			gate_hw, &clk_gate_ops, flags);
 
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		clk_register_clkdev(clk, clk_name, NULL);
 	}
+
+	return clk;
 }
 
 
-- 
1.8.5.1

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

* [PATCH v2 05/11] clk: sunxi: add PLL5 and PLL6 support
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (3 preceding siblings ...)
  2013-12-18  0:44 ` [PATCH v2 04/11] clk: sunxi: make factors_clk_setup return the clock it registers Emilio López
@ 2013-12-18  0:44 ` Emilio López
  2013-12-19  4:59   ` Mike Turquette
  2013-12-18  0:44 ` [PATCH v2 06/11] ARM: " Emilio López
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

This commit implements PLL5 and PLL6 support on the sunxi clock driver.
These PLLs use a similar factor clock, but differ on their outputs.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
---
 Documentation/devicetree/bindings/clock/sunxi.txt |   2 +
 drivers/clk/sunxi/clk-sunxi.c                     | 230 ++++++++++++++++++++++
 2 files changed, 232 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index b8c6cc4..80b2a39 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -9,6 +9,8 @@ Required properties:
 	"allwinner,sun4i-osc-clk" - for a gatable oscillator
 	"allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
 	"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
+	"allwinner,sun4i-pll5-clk" - for the PLL5 clock
+	"allwinner,sun4i-pll6-clk" - for the PLL6 clock
 	"allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
 	"allwinner,sun4i-axi-clk" - for the AXI clock
 	"allwinner,sun4i-axi-gates-clk" - for the AXI gates
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 401169b..84e2186 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -209,6 +209,40 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
 }
 
 /**
+ * sun4i_get_pll5_factors() - calculates n, k factors for PLL5
+ * PLL5 rate is calculated as follows
+ * rate = parent_rate * n * (k + 1)
+ * parent_rate is always 24Mhz
+ */
+
+static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
+				   u8 *n, u8 *k, u8 *m, u8 *p)
+{
+	u8 div;
+
+	/* Normalize value to a parent_rate multiple (24M) */
+	div = *freq / parent_rate;
+	*freq = parent_rate * div;
+
+	/* we were called to round the frequency, we can now return */
+	if (n == NULL)
+		return;
+
+	if (div < 31)
+		*k = 0;
+	else if (div / 2 < 31)
+		*k = 1;
+	else if (div / 3 < 31)
+		*k = 2;
+	else
+		*k = 3;
+
+	*n = DIV_ROUND_UP(div, (*k+1));
+}
+
+
+
+/**
  * sun4i_get_apb1_factors() - calculates m, p factors for APB1
  * APB1 rate is calculated as follows
  * rate = (parent_rate >> p) / (m + 1);
@@ -284,6 +318,13 @@ static struct clk_factors_config sun6i_a31_pll1_config = {
 	.mwidth = 2,
 };
 
+static struct clk_factors_config sun4i_pll5_config = {
+	.nshift = 8,
+	.nwidth = 5,
+	.kshift = 4,
+	.kwidth = 2,
+};
+
 static struct clk_factors_config sun4i_apb1_config = {
 	.mshift = 0,
 	.mwidth = 5,
@@ -303,6 +344,12 @@ static const struct factors_data sun6i_a31_pll1_data __initconst = {
 	.getter = sun6i_a31_get_pll1_factors,
 };
 
+static const struct factors_data sun4i_pll5_data __initconst = {
+	.enable = 31,
+	.table = &sun4i_pll5_config,
+	.getter = sun4i_get_pll5_factors,
+};
+
 static const struct factors_data sun4i_apb1_data __initconst = {
 	.table = &sun4i_apb1_config,
 	.getter = sun4i_get_apb1_factors,
@@ -620,6 +667,179 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
 	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 }
 
+
+
+/**
+ * sunxi_divs_clk_setup() helper data
+ */
+
+#define SUNXI_DIVS_MAX_QTY	2
+#define SUNXI_DIVISOR_WIDTH	2
+
+struct divs_data {
+	const struct factors_data *factors; /* data for the factor clock */
+	struct {
+		u8 fixed; /* is it a fixed divisor? if not... */
+		struct clk_div_table *table; /* is it a table based divisor? */
+		u8 shift; /* otherwise it's a normal divisor with this shift */
+		u8 pow;   /* is it power-of-two based? */
+		u8 gate;  /* is it independently gateable? */
+	} div[SUNXI_DIVS_MAX_QTY];
+};
+
+static struct clk_div_table pll6_sata_tbl[] = {
+	{ .val = 0, .div = 6, },
+	{ .val = 1, .div = 12, },
+	{ .val = 2, .div = 18, },
+	{ .val = 3, .div = 24, },
+	{ } /* sentinel */
+};
+
+static const struct divs_data pll5_divs_data __initconst = {
+	.factors = &sun4i_pll5_data,
+	.div = {
+		{ .shift = 0, .pow = 0, }, /* M, DDR */
+		{ .shift = 16, .pow = 1, }, /* P, other */
+	}
+};
+
+static const struct divs_data pll6_divs_data __initconst = {
+	.factors = &sun4i_pll5_data,
+	.div = {
+		{ .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
+		{ .fixed = 2 }, /* P, other */
+	}
+};
+
+/**
+ * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
+ *
+ * These clocks look something like this
+ *            ________________________
+ *           |         ___divisor 1---|----> to consumer
+ * parent >--|  pll___/___divisor 2---|----> to consumer
+ *           |        \_______________|____> to consumer
+ *           |________________________|
+ */
+
+static void __init sunxi_divs_clk_setup(struct device_node *node,
+					struct divs_data *data)
+{
+	struct clk_onecell_data *clk_data;
+	const char *parent  = node->name;
+	const char *clk_name;
+	struct clk **clks, *pclk;
+	struct clk_hw *gate_hw, *rate_hw;
+	const struct clk_ops *rate_ops;
+	struct clk_gate *gate = NULL;
+	struct clk_fixed_factor *fix_factor;
+	struct clk_divider *divider;
+	void *reg;
+	int i = 0;
+	int flags, clkflags;
+
+	/* Set up factor clock that we will be dividing */
+	pclk = sunxi_factors_clk_setup(node, data->factors);
+
+	reg = of_iomap(node, 0);
+
+	clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+	if (!clk_data)
+		return;
+
+	clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
+	if (!clks)
+		goto free_clkdata;
+
+	clk_data->clks = clks;
+
+	/* It's not a good idea to have automatic reparenting changing
+	 * our RAM clock! */
+	clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
+
+	for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) {
+		if (of_property_read_string_index(node, "clock-output-names",
+						  i, &clk_name) != 0)
+			break;
+
+		gate_hw = NULL;
+		rate_hw = NULL;
+		rate_ops = NULL;
+
+		/* If this leaf clock can be gated, create a gate */
+		if (data->div[i].gate) {
+			gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+			if (!gate)
+				goto free_clks;
+
+			gate->reg = reg;
+			gate->bit_idx = data->div[i].gate;
+			gate->lock = &clk_lock;
+
+			gate_hw = &gate->hw;
+		}
+
+		/* Leaves can be fixed or configurable divisors */
+		if (data->div[i].fixed) {
+			fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL);
+			if (!fix_factor)
+				goto free_gate;
+
+			fix_factor->mult = 1;
+			fix_factor->div = data->div[i].fixed;
+
+			rate_hw = &fix_factor->hw;
+			rate_ops = &clk_fixed_factor_ops;
+		} else {
+			divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+			if (!divider)
+				goto free_gate;
+
+			flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
+
+			divider->reg = reg;
+			divider->shift = data->div[i].shift;
+			divider->width = SUNXI_DIVISOR_WIDTH;
+			divider->flags = flags;
+			divider->lock = &clk_lock;
+			divider->table = data->div[i].table;
+
+			rate_hw = &divider->hw;
+			rate_ops = &clk_divider_ops;
+		}
+
+		/* Wrap the (potential) gate and the divisor on a composite
+		 * clock to unify them */
+		clks[i] = clk_register_composite(NULL, clk_name, &parent, 1,
+						 NULL, NULL,
+						 rate_hw, rate_ops,
+						 gate_hw, &clk_gate_ops,
+						 clkflags);
+
+		WARN_ON(IS_ERR(clk_data->clks[i]));
+		clk_register_clkdev(clks[i], clk_name, NULL);
+	}
+
+	/* The last clock available on the getter is the parent */
+	clks[i++] = pclk;
+
+	/* Adjust to the real max */
+	clk_data->clk_num = i;
+
+	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	return;
+
+free_gate:
+	kfree(gate);
+free_clks:
+	kfree(clks);
+free_clkdata:
+	kfree(clk_data);
+}
+
+
+
 /* Matches for factors clocks */
 static const struct of_device_id clk_factors_match[] __initconst = {
 	{.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
@@ -637,6 +857,13 @@ static const struct of_device_id clk_div_match[] __initconst = {
 	{}
 };
 
+/* Matches for divided outputs */
+static const struct of_device_id clk_divs_match[] __initconst = {
+	{.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,},
+	{.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,},
+	{}
+};
+
 /* Matches for mux clocks */
 static const struct of_device_id clk_mux_match[] __initconst = {
 	{.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
@@ -714,6 +941,9 @@ static void __init sunxi_init_clocks(struct device_node *np)
 	/* Register divider clocks */
 	of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
 
+	/* Register divided output clocks */
+	of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup);
+
 	/* Register mux clocks */
 	of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
 
-- 
1.8.5.1

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

* [PATCH v2 06/11] ARM: sunxi: add PLL5 and PLL6 support
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (4 preceding siblings ...)
  2013-12-18  0:44 ` [PATCH v2 05/11] clk: sunxi: add PLL5 and PLL6 support Emilio López
@ 2013-12-18  0:44 ` Emilio López
  2013-12-18  0:44 ` [PATCH v2 07/11] clk: sunxi: mod0 support Emilio López
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds PLL5 and PLL6 nodes to the sun4i, sun5i and sun7i
device trees.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun4i-a10.dtsi  | 19 +++++++++++++++++--
 arch/arm/boot/dts/sun5i-a10s.dtsi | 19 +++++++++++++++++--
 arch/arm/boot/dts/sun5i-a13.dtsi  | 19 +++++++++++++++++--
 arch/arm/boot/dts/sun7i-a20.dtsi  | 28 ++++++++++++++++------------
 4 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 3833c14..ebacb5d 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -77,6 +77,22 @@
 			clocks = <&osc24M>;
 		};
 
+		pll5: pll5 at 01c20020 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll5-clk";
+			reg = <0x01c20020 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll5_ddr", "pll5_other";
+		};
+
+		pll6: pll6 at 01c20028 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll6-clk";
+			reg = <0x01c20028 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll6_sata", "pll6_other", "pll6";
+		};
+
 		/* dummy is 200M */
 		cpu: cpu at 01c20054 {
 			#clock-cells = <0>;
@@ -142,12 +158,11 @@
 				"apb0_ir1", "apb0_keypad";
 		};
 
-		/* dummy is pll62 */
 		apb1_mux: apb1_mux at 01c20058 {
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-apb1-mux-clk";
 			reg = <0x01c20058 0x4>;
-			clocks = <&osc24M>, <&dummy>, <&osc32k>;
+			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
 		};
 
 		apb1: apb1 at 01c20058 {
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 3252aa8..86e06e4 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -74,6 +74,22 @@
 			clocks = <&osc24M>;
 		};
 
+		pll5: pll5 at 01c20020 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll5-clk";
+			reg = <0x01c20020 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll5_ddr", "pll5_other";
+		};
+
+		pll6: pll6 at 01c20028 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll6-clk";
+			reg = <0x01c20028 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll6_sata", "pll6_other", "pll6";
+		};
+
 		/* dummy is 200M */
 		cpu: cpu at 01c20054 {
 			#clock-cells = <0>;
@@ -134,12 +150,11 @@
 				"apb0_ir", "apb0_keypad";
 		};
 
-		/* dummy is pll62 */
 		apb1_mux: apb1_mux at 01c20058 {
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-apb1-mux-clk";
 			reg = <0x01c20058 0x4>;
-			clocks = <&osc24M>, <&dummy>, <&osc32k>;
+			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
 		};
 
 		apb1: apb1 at 01c20058 {
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 8c4a9c3..cded3c7 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -74,6 +74,22 @@
 			clocks = <&osc24M>;
 		};
 
+		pll5: pll5 at 01c20020 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll5-clk";
+			reg = <0x01c20020 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll5_ddr", "pll5_other";
+		};
+
+		pll6: pll6 at 01c20028 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll6-clk";
+			reg = <0x01c20028 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll6_sata", "pll6_other", "pll6";
+		};
+
 		/* dummy is 200M */
 		cpu: cpu at 01c20054 {
 			#clock-cells = <0>;
@@ -132,12 +148,11 @@
 			clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
 		};
 
-		/* dummy is pll6 */
 		apb1_mux: apb1_mux at 01c20058 {
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-apb1-mux-clk";
 			reg = <0x01c20058 0x4>;
-			clocks = <&osc24M>, <&dummy>, <&osc32k>;
+			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
 		};
 
 		apb1: apb1 at 01c20058 {
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 2b2d3847..7949028 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -73,23 +73,27 @@
 			clocks = <&osc24M>;
 		};
 
-		/*
-		 * This is a dummy clock, to be used as placeholder on
-		 * other mux clocks when a specific parent clock is not
-		 * yet implemented. It should be dropped when the driver
-		 * is complete.
-		 */
-		pll6: pll6 {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <0>;
+		pll5: pll5 at 01c20020 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll5-clk";
+			reg = <0x01c20020 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll5_ddr", "pll5_other";
+		};
+
+		pll6: pll6 at 01c20028 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-pll6-clk";
+			reg = <0x01c20028 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll6_sata", "pll6_other", "pll6";
 		};
 
 		cpu: cpu at 01c20054 {
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-cpu-clk";
 			reg = <0x01c20054 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6>;
+			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>;
 		};
 
 		axi: axi at 01c20054 {
@@ -148,7 +152,7 @@
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-apb1-mux-clk";
 			reg = <0x01c20058 0x4>;
-			clocks = <&osc24M>, <&pll6>, <&osc32k>;
+			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
 		};
 
 		apb1: apb1 at 01c20058 {
-- 
1.8.5.1

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

* [PATCH v2 07/11] clk: sunxi: mod0 support
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (5 preceding siblings ...)
  2013-12-18  0:44 ` [PATCH v2 06/11] ARM: " Emilio López
@ 2013-12-18  0:44 ` Emilio López
  2013-12-19  4:59   ` Mike Turquette
  2013-12-18  0:45 ` [PATCH v2 08/11] ARM: sun4i: dt: mod0 clocks Emilio López
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

This commit implements support for the "module 0" type of clocks, as
used by MMC, IR, NAND, SATA and other components.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
---
 Documentation/devicetree/bindings/clock/sunxi.txt |  5 +-
 drivers/clk/sunxi/clk-sunxi.c                     | 57 +++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 80b2a39..46d8433 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -35,10 +35,13 @@ Required properties:
 	"allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20
 	"allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
 	"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
+	"allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
 
 Required properties for all clocks:
 - reg : shall be the control register address for the clock.
-- clocks : shall be the input parent clock(s) phandle for the clock
+- clocks : shall be the input parent clock(s) phandle for the clock. For
+	multiplexed clocks, the list order must match the hardware
+	programming order.
 - #clock-cells : from common clock binding; shall be set to 0 except for
 	"allwinner,*-gates-clk" where it shall be set to 1
 
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 84e2186..b40cf30 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -286,6 +286,47 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
 
 
 /**
+ * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
+ * MMC rate is calculated as follows
+ * rate = (parent_rate >> p) / (m + 1);
+ */
+
+static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
+				   u8 *n, u8 *k, u8 *m, u8 *p)
+{
+	u8 div, calcm, calcp;
+
+	/* These clocks can only divide, so we will never be able to achieve
+	 * frequencies higher than the parent frequency */
+	if (*freq > parent_rate)
+		*freq = parent_rate;
+
+	div = parent_rate / *freq;
+
+	if (div < 16)
+		calcp = 0;
+	else if (div / 2 < 16)
+		calcp = 1;
+	else if (div / 4 < 16)
+		calcp = 2;
+	else
+		calcp = 3;
+
+	calcm = DIV_ROUND_UP(div, 1 << calcp);
+
+	*freq = (parent_rate >> calcp) / calcm;
+
+	/* we were called to round the frequency, we can now return */
+	if (n == NULL)
+		return;
+
+	*m = calcm - 1;
+	*p = calcp;
+}
+
+
+
+/**
  * sunxi_factors_clk_setup() - Setup function for factor clocks
  */
 
@@ -332,6 +373,14 @@ static struct clk_factors_config sun4i_apb1_config = {
 	.pwidth = 2,
 };
 
+/* user manual says "n" but it's really "p" */
+static struct clk_factors_config sun4i_mod0_config = {
+	.mshift = 0,
+	.mwidth = 4,
+	.pshift = 16,
+	.pwidth = 2,
+};
+
 static const struct factors_data sun4i_pll1_data __initconst = {
 	.enable = 31,
 	.table = &sun4i_pll1_config,
@@ -355,6 +404,13 @@ static const struct factors_data sun4i_apb1_data __initconst = {
 	.getter = sun4i_get_apb1_factors,
 };
 
+static const struct factors_data sun4i_mod0_data __initconst = {
+	.enable = 31,
+	.mux = 24,
+	.table = &sun4i_mod0_config,
+	.getter = sun4i_get_mod0_factors,
+};
+
 static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
 						const struct factors_data *data)
 {
@@ -845,6 +901,7 @@ static const struct of_device_id clk_factors_match[] __initconst = {
 	{.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
 	{.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
 	{.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
+	{.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
 	{}
 };
 
-- 
1.8.5.1

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

* [PATCH v2 08/11] ARM: sun4i: dt: mod0 clocks
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (6 preceding siblings ...)
  2013-12-18  0:44 ` [PATCH v2 07/11] clk: sunxi: mod0 support Emilio López
@ 2013-12-18  0:45 ` Emilio López
  2013-12-18  9:48   ` Maxime Ripard
  2013-12-18  0:45 ` [PATCH v2 09/11] ARM: sun5i: " Emilio López
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:45 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds all the mod0 clocks present on sun4i to its device tree

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun4i-a10.dtsi | 105 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index ebacb5d..2828427 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -184,6 +184,111 @@
 				"apb1_uart4", "apb1_uart5", "apb1_uart6",
 				"apb1_uart7";
 		};
+
+		nand: nand at 01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ms: ms at 01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc0: mmc0 at 01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc1: mmc1 at 01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc2: mmc2 at 01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc3: mmc3 at 01c20094 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20094 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ts: ts at 01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ss: ss at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi0: spi0 at 01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi1: spi1 at 01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi2: spi2 at 01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		pata: pata at 01c200ac {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200ac 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ir0: ir0 at 01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ir1: ir1 at 01c200b4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi3: spi3 at 01c200d4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200d4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
 	};
 
 	soc at 01c00000 {
-- 
1.8.5.1

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

* [PATCH v2 09/11] ARM: sun5i: dt: mod0 clocks
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (7 preceding siblings ...)
  2013-12-18  0:45 ` [PATCH v2 08/11] ARM: sun4i: dt: mod0 clocks Emilio López
@ 2013-12-18  0:45 ` Emilio López
  2013-12-18  0:45 ` [PATCH v2 10/11] ARM: sun7i: " Emilio López
  2013-12-18  0:45 ` [PATCH v2 11/11] ARM: sunxi: dt: add nodes for the mbus clock Emilio López
  10 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:45 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds all the mod0 clocks available on A10 and A13. The list
has been constructed by looking at the Allwinner code release for A10S
and A13.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun5i-a10s.dtsi | 77 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/sun5i-a13.dtsi  | 77 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 154 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 86e06e4..82b5ce6 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -173,6 +173,83 @@
 				"apb1_i2c2", "apb1_uart0", "apb1_uart1",
 				"apb1_uart2", "apb1_uart3";
 		};
+
+		nand: nand at 01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ms: ms at 01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc0: mmc0 at 01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc1: mmc1 at 01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc2: mmc2 at 01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ts: ts at 01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ss: ss at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi0: spi0 at 01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi1: spi1 at 01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi2: spi2 at 01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ir0: ir0 at 01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
 	};
 
 	soc at 01c00000 {
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index cded3c7..938e6d3 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -170,6 +170,83 @@
 			clock-output-names = "apb1_i2c0", "apb1_i2c1",
 				"apb1_i2c2", "apb1_uart1", "apb1_uart3";
 		};
+
+		nand: nand at 01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ms: ms at 01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc0: mmc0 at 01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc1: mmc1 at 01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc2: mmc2 at 01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ts: ts at 01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ss: ss at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi0: spi0 at 01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi1: spi1 at 01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi2: spi2 at 01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ir0: ir0 at 01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
 	};
 
 	soc at 01c00000 {
-- 
1.8.5.1

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

* [PATCH v2 10/11] ARM: sun7i: dt: mod0 clocks
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (8 preceding siblings ...)
  2013-12-18  0:45 ` [PATCH v2 09/11] ARM: sun5i: " Emilio López
@ 2013-12-18  0:45 ` Emilio López
  2013-12-18  0:45 ` [PATCH v2 11/11] ARM: sunxi: dt: add nodes for the mbus clock Emilio López
  10 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:45 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds all the mod0 clocks available on A20 to its device
tree. This list was created by looking at AW's code release.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi | 105 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 7949028..41df384 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -174,6 +174,111 @@
 				"apb1_uart2", "apb1_uart3", "apb1_uart4",
 				"apb1_uart5", "apb1_uart6", "apb1_uart7";
 		};
+
+		nand: nand at 01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ms: ms at 01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc0: mmc0 at 01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc1: mmc1 at 01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc2: mmc2 at 01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		mmc3: mmc3 at 01c20094 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20094 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ts: ts at 01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ss: ss at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi0: spi0 at 01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi1: spi1 at 01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi2: spi2 at 01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		pata: pata at 01c200ac {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200ac 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ir0: ir0 at 01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		ir1: ir1 at 01c200b4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
+
+		spi3: spi3 at 01c200d4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200d4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
 	};
 
 	soc at 01c00000 {
-- 
1.8.5.1

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

* [PATCH v2 11/11] ARM: sunxi: dt: add nodes for the mbus clock
  2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
                   ` (9 preceding siblings ...)
  2013-12-18  0:45 ` [PATCH v2 10/11] ARM: sun7i: " Emilio López
@ 2013-12-18  0:45 ` Emilio López
  10 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18  0:45 UTC (permalink / raw)
  To: linux-arm-kernel

mbus is the memory bus clock, and it is present on both sun5i and sun7i
machines. Its register layout is compatible with the mod0 one.

Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
 arch/arm/boot/dts/sun5i-a13.dtsi  | 7 +++++++
 arch/arm/boot/dts/sun7i-a20.dtsi  | 7 +++++++
 3 files changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 82b5ce6..60bd3f7 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -250,6 +250,13 @@
 			reg = <0x01c200b0 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 		};
+
+		mbus: mbus at 01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
 	};
 
 	soc at 01c00000 {
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 938e6d3..3e616a0 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -247,6 +247,13 @@
 			reg = <0x01c200b0 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 		};
+
+		mbus: mbus at 01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+		};
 	};
 
 	soc at 01c00000 {
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 41df384..8c88f7d 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -279,6 +279,13 @@
 			reg = <0x01c200d4 0x4>;
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 		};
+
+		mbus: mbus at 01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
+		};
 	};
 
 	soc at 01c00000 {
-- 
1.8.5.1

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

* [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite
  2013-12-18  0:44 ` [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite Emilio López
@ 2013-12-18  2:55   ` Mike Turquette
  2013-12-18 11:27     ` Emilio López
  0 siblings, 1 reply; 22+ messages in thread
From: Mike Turquette @ 2013-12-18  2:55 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Emilio L?pez (2013-12-17 16:44:53)
> This commit reworks factors clock registration to be done behind a
> composite clock. This allows us to additionally add a gate, mux or
> divisors, as it will be needed by some future PLLs.
> 
> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/sunxi/clk-factors.c | 63 +--------------------------------------
>  drivers/clk/sunxi/clk-factors.h | 16 +++++-----
>  drivers/clk/sunxi/clk-sunxi.c   | 66 ++++++++++++++++++++++++++++++++++++++---
>  3 files changed, 72 insertions(+), 73 deletions(-)
> 
> diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
> index f05207a..9e23264 100644
> --- a/drivers/clk/sunxi/clk-factors.c
> +++ b/drivers/clk/sunxi/clk-factors.c
> @@ -30,14 +30,6 @@
>   * parent - fixed parent.  No clk_set_parent support
>   */
>  
> -struct clk_factors {
> -       struct clk_hw hw;
> -       void __iomem *reg;
> -       struct clk_factors_config *config;
> -       void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
> -       spinlock_t *lock;
> -};
> -
>  #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
>  
>  #define SETMASK(len, pos)              (((1U << (len)) - 1) << (pos))
> @@ -120,61 +112,8 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
>         return 0;
>  }
>  
> -static const struct clk_ops clk_factors_ops = {
> +const struct clk_ops clk_factors_ops = {
>         .recalc_rate = clk_factors_recalc_rate,
>         .round_rate = clk_factors_round_rate,
>         .set_rate = clk_factors_set_rate,
>  };
> -
> -/**
> - * clk_register_factors - register a factors clock with
> - * the clock framework
> - * @dev: device registering this clock
> - * @name: name of this clock
> - * @parent_name: name of clock's parent
> - * @flags: framework-specific flags
> - * @reg: register address to adjust factors
> - * @config: shift and width of factors n, k, m and p
> - * @get_factors: function to calculate the factors for a given frequency
> - * @lock: shared register lock for this clock
> - */
> -struct clk *clk_register_factors(struct device *dev, const char *name,
> -                                const char *parent_name,
> -                                unsigned long flags, void __iomem *reg,
> -                                struct clk_factors_config *config,
> -                                void (*get_factors)(u32 *rate, u32 parent,
> -                                                    u8 *n, u8 *k, u8 *m, u8 *p),
> -                                spinlock_t *lock)
> -{
> -       struct clk_factors *factors;
> -       struct clk *clk;
> -       struct clk_init_data init;
> -
> -       /* allocate the factors */
> -       factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
> -       if (!factors) {
> -               pr_err("%s: could not allocate factors clk\n", __func__);
> -               return ERR_PTR(-ENOMEM);
> -       }
> -
> -       init.name = name;
> -       init.ops = &clk_factors_ops;
> -       init.flags = flags;
> -       init.parent_names = (parent_name ? &parent_name : NULL);
> -       init.num_parents = (parent_name ? 1 : 0);
> -
> -       /* struct clk_factors assignments */
> -       factors->reg = reg;
> -       factors->config = config;
> -       factors->lock = lock;
> -       factors->hw.init = &init;
> -       factors->get_factors = get_factors;
> -
> -       /* register the clock */
> -       clk = clk_register(dev, &factors->hw);
> -
> -       if (IS_ERR(clk))
> -               kfree(factors);
> -
> -       return clk;
> -}
> diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
> index f49851c..02e1a43 100644
> --- a/drivers/clk/sunxi/clk-factors.h
> +++ b/drivers/clk/sunxi/clk-factors.h
> @@ -17,11 +17,13 @@ struct clk_factors_config {
>         u8 pwidth;
>  };
>  
> -struct clk *clk_register_factors(struct device *dev, const char *name,
> -                                const char *parent_name,
> -                                unsigned long flags, void __iomem *reg,
> -                                struct clk_factors_config *config,
> -                                void (*get_factors) (u32 *rate, u32 parent_rate,
> -                                                     u8 *n, u8 *k, u8 *m, u8 *p),
> -                                spinlock_t *lock);
> +struct clk_factors {
> +       struct clk_hw hw;
> +       void __iomem *reg;
> +       struct clk_factors_config *config;
> +       void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
> +       spinlock_t *lock;
> +};
> +
> +extern const struct clk_ops clk_factors_ops;
>  #endif
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 8fc1375..6f756f4 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -255,7 +255,11 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
>   * sunxi_factors_clk_setup() - Setup function for factor clocks
>   */
>  
> +#define SUNXI_FACTORS_MUX_MASK 0x3
> +
>  struct factors_data {
> +       int enable;
> +       int mux;
>         struct clk_factors_config *table;
>         void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
>  };
> @@ -306,16 +310,70 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
>                                            struct factors_data *data)
>  {
>         struct clk *clk;
> +       struct clk_factors *factors;
> +       struct clk_gate *gate = NULL;
> +       struct clk_mux *mux = NULL;
> +       struct clk_hw *gate_hw = NULL;
> +       struct clk_hw *mux_hw = NULL;
>         const char *clk_name = node->name;
> -       const char *parent;
> +       const char *parents[5];

Seems like 5 is a magic number? I guess this type of clock always has
the same number of parents? Might be good to use a preprocessor macro
here.

Otherwise the patch looks good to me.

Regards,
Mike

>         void *reg;
> +       int i = 0;
>  
>         reg = of_iomap(node, 0);
>  
> -       parent = of_clk_get_parent_name(node, 0);
> +       /* if we have a mux, we will have >1 parents */
> +       while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
> +               i++;
> +
> +       factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
> +       if (!factors)
> +               return;
>  
> -       clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
> -                                  data->table, data->getter, &clk_lock);
> +       /* Add a gate if this factor clock can be gated */
> +       if (data->enable) {
> +               gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
> +               if (!gate) {
> +                       kfree(factors);
> +                       return;
> +               }
> +
> +               /* set up gate properties */
> +               gate->reg = reg;
> +               gate->bit_idx = data->enable;
> +               gate->lock = &clk_lock;
> +               gate_hw = &gate->hw;
> +       }
> +
> +       /* Add a mux if this factor clock can be muxed */
> +       if (data->mux) {
> +               mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
> +               if (!mux) {
> +                       kfree(factors);
> +                       kfree(gate);
> +                       return;
> +               }
> +
> +               /* set up gate properties */
> +               mux->reg = reg;
> +               mux->shift = data->mux;
> +               mux->mask = SUNXI_FACTORS_MUX_MASK;
> +               mux->lock = &clk_lock;
> +               mux_hw = &mux->hw;
> +       }
> +
> +       /* set up factors properties */
> +       factors->reg = reg;
> +       factors->config = data->table;
> +       factors->get_factors = data->getter;
> +       factors->lock = &clk_lock;
> +
> +       clk = clk_register_composite(NULL, clk_name,
> +                       parents, i,
> +                       mux_hw, &clk_mux_ops,
> +                       &factors->hw, &clk_factors_ops,
> +                       gate_hw, &clk_gate_ops,
> +                       i ? 0 : CLK_IS_ROOT);
>  
>         if (!IS_ERR(clk)) {
>                 of_clk_add_provider(node, of_clk_src_simple_get, clk);
> -- 
> 1.8.5.1
> 

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

* [PATCH v2 02/11] clk: sunxi: add gating support to PLL1
  2013-12-18  0:44 ` [PATCH v2 02/11] clk: sunxi: add gating support to PLL1 Emilio López
@ 2013-12-18  2:57   ` Mike Turquette
  0 siblings, 0 replies; 22+ messages in thread
From: Mike Turquette @ 2013-12-18  2:57 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Emilio L?pez (2013-12-17 16:44:54)
> This commit adds gating support to PLL1 on the clock driver. This makes
> the PLL1 implementation fully compatible with PLL4 as well.
> 
> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  Documentation/devicetree/bindings/clock/sunxi.txt | 2 +-
>  drivers/clk/sunxi/clk-sunxi.c                     | 2 ++
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index 91a748f..b8c6cc4 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -7,7 +7,7 @@ This binding uses the common clock binding[1].
>  Required properties:
>  - compatible : shall be one of the following:
>         "allwinner,sun4i-osc-clk" - for a gatable oscillator
> -       "allwinner,sun4i-pll1-clk" - for the main PLL clock
> +       "allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
>         "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
>         "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
>         "allwinner,sun4i-axi-clk" - for the AXI clock
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 6f756f4..5b86234 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -292,11 +292,13 @@ static struct clk_factors_config sun4i_apb1_config = {
>  };
>  
>  static const struct factors_data sun4i_pll1_data __initconst = {
> +       .enable = 31,
>         .table = &sun4i_pll1_config,
>         .getter = sun4i_get_pll1_factors,
>  };
>  
>  static const struct factors_data sun6i_a31_pll1_data __initconst = {
> +       .enable = 31,
>         .table = &sun6i_a31_pll1_config,
>         .getter = sun6i_a31_get_pll1_factors,
>  };
> -- 
> 1.8.5.1
> 

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

* [PATCH v2 04/11] clk: sunxi: make factors_clk_setup return the clock it registers
  2013-12-18  0:44 ` [PATCH v2 04/11] clk: sunxi: make factors_clk_setup return the clock it registers Emilio López
@ 2013-12-18  3:01   ` Mike Turquette
  2013-12-18 11:34     ` Emilio López
  0 siblings, 1 reply; 22+ messages in thread
From: Mike Turquette @ 2013-12-18  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Emilio L?pez (2013-12-17 16:44:56)
> We will be needing this to register a factor clock as parent with leaf
> divisors on a single call. While at it, also prepare the function to set
> the ignore flag on pll5, so our RAM keeps working.
> 
> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
> ---
>  drivers/clk/sunxi/clk-sunxi.c | 19 ++++++++++++-------
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 5b86234..401169b 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -308,8 +308,8 @@ static const struct factors_data sun4i_apb1_data __initconst = {
>         .getter = sun4i_get_apb1_factors,
>  };
>  
> -static void __init sunxi_factors_clk_setup(struct device_node *node,
> -                                          struct factors_data *data)
> +static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
> +                                               const struct factors_data *data)
>  {
>         struct clk *clk;
>         struct clk_factors *factors;
> @@ -320,6 +320,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
>         const char *clk_name = node->name;
>         const char *parents[5];
>         void *reg;
> +       unsigned long flags;
>         int i = 0;
>  
>         reg = of_iomap(node, 0);
> @@ -330,14 +331,14 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
>  
>         factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
>         if (!factors)
> -               return;
> +               return NULL;
>  
>         /* Add a gate if this factor clock can be gated */
>         if (data->enable) {
>                 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
>                 if (!gate) {
>                         kfree(factors);
> -                       return;
> +                       return NULL;
>                 }
>  
>                 /* set up gate properties */
> @@ -353,7 +354,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
>                 if (!mux) {
>                         kfree(factors);
>                         kfree(gate);
> -                       return;
> +                       return NULL;
>                 }
>  
>                 /* set up gate properties */
> @@ -370,17 +371,21 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
>         factors->get_factors = data->getter;
>         factors->lock = &clk_lock;
>  
> +       /* We should not disable pll5, it powers the RAM */
> +       flags = !strcmp("pll5", clk_name) ? CLK_IGNORE_UNUSED : 0;

For hardware-agnostic flags like CLK_IGNORE_UNUSED I think that we can
add a property to the binding description instead of hard-coding a
string name in here.

Rest of the patch looks good to me. Ack.

Regards,
Mike

> +
>         clk = clk_register_composite(NULL, clk_name,
>                         parents, i,
>                         mux_hw, &clk_mux_ops,
>                         &factors->hw, &clk_factors_ops,
> -                       gate_hw, &clk_gate_ops,
> -                       i ? 0 : CLK_IS_ROOT);
> +                       gate_hw, &clk_gate_ops, flags);
>  
>         if (!IS_ERR(clk)) {
>                 of_clk_add_provider(node, of_clk_src_simple_get, clk);
>                 clk_register_clkdev(clk, clk_name, NULL);
>         }
> +
> +       return clk;
>  }
>  
>  
> -- 
> 1.8.5.1
> 

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

* [PATCH v2 08/11] ARM: sun4i: dt: mod0 clocks
  2013-12-18  0:45 ` [PATCH v2 08/11] ARM: sun4i: dt: mod0 clocks Emilio López
@ 2013-12-18  9:48   ` Maxime Ripard
  2013-12-18 11:40     ` Emilio López
  0 siblings, 1 reply; 22+ messages in thread
From: Maxime Ripard @ 2013-12-18  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Emilio,

On Tue, Dec 17, 2013 at 09:45:00PM -0300, Emilio L?pez wrote:
> This commit adds all the mod0 clocks present on sun4i to its device tree
> 
> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Even though I gave my Acked-by, could you rename the nodes to
something like: "foo_clk: clk at deadbeef"

The node name is supposed to be the class of devices, and we're likely
to use all those labels for the actual controllers, and not the clocks
themselves.

Thanks
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131218/fc455678/attachment.sig>

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

* [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite
  2013-12-18  2:55   ` Mike Turquette
@ 2013-12-18 11:27     ` Emilio López
  0 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mike,

Thanks for the prompt review! It's much appreciated.

El 17/12/13 23:55, Mike Turquette escribi?:
> Quoting Emilio L?pez (2013-12-17 16:44:53)
>> This commit reworks factors clock registration to be done behind a
>> composite clock. This allows us to additionally add a gate, mux or
>> divisors, as it will be needed by some future PLLs.
>>
>> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
>> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>> ---
(...)
> Seems like 5 is a magic number? I guess this type of clock always has
> the same number of parents? Might be good to use a preprocessor macro
> here.

Indeed, these clocks always have less than 5 parents. I'll use a macro 
to make it clearer.

Cheers,

Emilio

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

* [PATCH v2 04/11] clk: sunxi: make factors_clk_setup return the clock it registers
  2013-12-18  3:01   ` Mike Turquette
@ 2013-12-18 11:34     ` Emilio López
  0 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18 11:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mike,

El 18/12/13 00:01, Mike Turquette escribi?:
> Quoting Emilio L?pez (2013-12-17 16:44:56)
>> We will be needing this to register a factor clock as parent with leaf
>> divisors on a single call. While at it, also prepare the function to set
>> the ignore flag on pll5, so our RAM keeps working.
>>
>> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
>> ---
(...)
>>
>> +       /* We should not disable pll5, it powers the RAM */
>> +       flags = !strcmp("pll5", clk_name) ? CLK_IGNORE_UNUSED : 0;
>
> For hardware-agnostic flags like CLK_IGNORE_UNUSED I think that we can
> add a property to the binding description instead of hard-coding a
> string name in here.

Hm, I don't know if something like that would really belong to the DT. 
In any case, I should be able to drop this from here now that the clock 
protection stuff is in place, so it should be a non-issue.

> Rest of the patch looks good to me. Ack.

Thanks for reviewing this!

Emilio

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

* [PATCH v2 08/11] ARM: sun4i: dt: mod0 clocks
  2013-12-18  9:48   ` Maxime Ripard
@ 2013-12-18 11:40     ` Emilio López
  0 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-18 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Maxime,

El 18/12/13 06:48, Maxime Ripard escribi?:
> Hi Emilio,
>
> On Tue, Dec 17, 2013 at 09:45:00PM -0300, Emilio L?pez wrote:
>> This commit adds all the mod0 clocks present on sun4i to its device tree
>>
>> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
>> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>
> Even though I gave my Acked-by, could you rename the nodes to
> something like: "foo_clk: clk at deadbeef"
>
> The node name is supposed to be the class of devices, and we're likely
> to use all those labels for the actual controllers, and not the clocks
> themselves.

Ok, I'll get that fixed before sending v3.

Thanks!

Emilio

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

* [PATCH v2 05/11] clk: sunxi: add PLL5 and PLL6 support
  2013-12-18  0:44 ` [PATCH v2 05/11] clk: sunxi: add PLL5 and PLL6 support Emilio López
@ 2013-12-19  4:59   ` Mike Turquette
  2013-12-21  2:26     ` Emilio López
  0 siblings, 1 reply; 22+ messages in thread
From: Mike Turquette @ 2013-12-19  4:59 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Emilio L?pez (2013-12-17 16:44:57)
> +/**
> + * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
> + *
> + * These clocks look something like this
> + *            ________________________
> + *           |         ___divisor 1---|----> to consumer
> + * parent >--|  pll___/___divisor 2---|----> to consumer
> + *           |        \_______________|____> to consumer
> + *           |________________________|
> + */

+1 for ASCII art.

> +
> +static void __init sunxi_divs_clk_setup(struct device_node *node,
> +                                       struct divs_data *data)
> +{
> +       struct clk_onecell_data *clk_data;
> +       const char *parent  = node->name;
> +       const char *clk_name;
> +       struct clk **clks, *pclk;
> +       struct clk_hw *gate_hw, *rate_hw;
> +       const struct clk_ops *rate_ops;
> +       struct clk_gate *gate = NULL;
> +       struct clk_fixed_factor *fix_factor;
> +       struct clk_divider *divider;
> +       void *reg;
> +       int i = 0;
> +       int flags, clkflags;
> +
> +       /* Set up factor clock that we will be dividing */
> +       pclk = sunxi_factors_clk_setup(node, data->factors);
> +
> +       reg = of_iomap(node, 0);
> +
> +       clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
> +       if (!clk_data)
> +               return;
> +
> +       clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
> +       if (!clks)
> +               goto free_clkdata;
> +
> +       clk_data->clks = clks;
> +
> +       /* It's not a good idea to have automatic reparenting changing
> +        * our RAM clock! */
> +       clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;

Just out of curiosity, did you hit this problem in testing?

Acked-by: Mike Turquette <mturquette@linaro.org>

> +
> +       for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) {
> +               if (of_property_read_string_index(node, "clock-output-names",
> +                                                 i, &clk_name) != 0)
> +                       break;
> +
> +               gate_hw = NULL;
> +               rate_hw = NULL;
> +               rate_ops = NULL;
> +
> +               /* If this leaf clock can be gated, create a gate */
> +               if (data->div[i].gate) {
> +                       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +                       if (!gate)
> +                               goto free_clks;
> +
> +                       gate->reg = reg;
> +                       gate->bit_idx = data->div[i].gate;
> +                       gate->lock = &clk_lock;
> +
> +                       gate_hw = &gate->hw;
> +               }
> +
> +               /* Leaves can be fixed or configurable divisors */
> +               if (data->div[i].fixed) {
> +                       fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL);
> +                       if (!fix_factor)
> +                               goto free_gate;
> +
> +                       fix_factor->mult = 1;
> +                       fix_factor->div = data->div[i].fixed;
> +
> +                       rate_hw = &fix_factor->hw;
> +                       rate_ops = &clk_fixed_factor_ops;
> +               } else {
> +                       divider = kzalloc(sizeof(*divider), GFP_KERNEL);
> +                       if (!divider)
> +                               goto free_gate;
> +
> +                       flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
> +
> +                       divider->reg = reg;
> +                       divider->shift = data->div[i].shift;
> +                       divider->width = SUNXI_DIVISOR_WIDTH;
> +                       divider->flags = flags;
> +                       divider->lock = &clk_lock;
> +                       divider->table = data->div[i].table;
> +
> +                       rate_hw = &divider->hw;
> +                       rate_ops = &clk_divider_ops;
> +               }
> +
> +               /* Wrap the (potential) gate and the divisor on a composite
> +                * clock to unify them */
> +               clks[i] = clk_register_composite(NULL, clk_name, &parent, 1,
> +                                                NULL, NULL,
> +                                                rate_hw, rate_ops,
> +                                                gate_hw, &clk_gate_ops,
> +                                                clkflags);
> +
> +               WARN_ON(IS_ERR(clk_data->clks[i]));
> +               clk_register_clkdev(clks[i], clk_name, NULL);
> +       }
> +
> +       /* The last clock available on the getter is the parent */
> +       clks[i++] = pclk;
> +
> +       /* Adjust to the real max */
> +       clk_data->clk_num = i;
> +
> +       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +
> +       return;
> +
> +free_gate:
> +       kfree(gate);
> +free_clks:
> +       kfree(clks);
> +free_clkdata:
> +       kfree(clk_data);
> +}
> +
> +
> +
>  /* Matches for factors clocks */
>  static const struct of_device_id clk_factors_match[] __initconst = {
>         {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
> @@ -637,6 +857,13 @@ static const struct of_device_id clk_div_match[] __initconst = {
>         {}
>  };
>  
> +/* Matches for divided outputs */
> +static const struct of_device_id clk_divs_match[] __initconst = {
> +       {.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,},
> +       {.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,},
> +       {}
> +};
> +
>  /* Matches for mux clocks */
>  static const struct of_device_id clk_mux_match[] __initconst = {
>         {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
> @@ -714,6 +941,9 @@ static void __init sunxi_init_clocks(struct device_node *np)
>         /* Register divider clocks */
>         of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
>  
> +       /* Register divided output clocks */
> +       of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup);
> +
>         /* Register mux clocks */
>         of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
>  
> -- 
> 1.8.5.1
> 

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

* [PATCH v2 07/11] clk: sunxi: mod0 support
  2013-12-18  0:44 ` [PATCH v2 07/11] clk: sunxi: mod0 support Emilio López
@ 2013-12-19  4:59   ` Mike Turquette
  0 siblings, 0 replies; 22+ messages in thread
From: Mike Turquette @ 2013-12-19  4:59 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Emilio L?pez (2013-12-17 16:44:59)
> This commit implements support for the "module 0" type of clocks, as
> used by MMC, IR, NAND, SATA and other components.
> 
> Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  Documentation/devicetree/bindings/clock/sunxi.txt |  5 +-
>  drivers/clk/sunxi/clk-sunxi.c                     | 57 +++++++++++++++++++++++
>  2 files changed, 61 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index 80b2a39..46d8433 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -35,10 +35,13 @@ Required properties:
>         "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20
>         "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
>         "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
> +       "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
>  
>  Required properties for all clocks:
>  - reg : shall be the control register address for the clock.
> -- clocks : shall be the input parent clock(s) phandle for the clock
> +- clocks : shall be the input parent clock(s) phandle for the clock. For
> +       multiplexed clocks, the list order must match the hardware
> +       programming order.
>  - #clock-cells : from common clock binding; shall be set to 0 except for
>         "allwinner,*-gates-clk" where it shall be set to 1
>  
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 84e2186..b40cf30 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -286,6 +286,47 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
>  
>  
>  /**
> + * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
> + * MMC rate is calculated as follows
> + * rate = (parent_rate >> p) / (m + 1);
> + */
> +
> +static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
> +                                  u8 *n, u8 *k, u8 *m, u8 *p)
> +{
> +       u8 div, calcm, calcp;
> +
> +       /* These clocks can only divide, so we will never be able to achieve
> +        * frequencies higher than the parent frequency */
> +       if (*freq > parent_rate)
> +               *freq = parent_rate;
> +
> +       div = parent_rate / *freq;
> +
> +       if (div < 16)
> +               calcp = 0;
> +       else if (div / 2 < 16)
> +               calcp = 1;
> +       else if (div / 4 < 16)
> +               calcp = 2;
> +       else
> +               calcp = 3;
> +
> +       calcm = DIV_ROUND_UP(div, 1 << calcp);
> +
> +       *freq = (parent_rate >> calcp) / calcm;
> +
> +       /* we were called to round the frequency, we can now return */
> +       if (n == NULL)
> +               return;
> +
> +       *m = calcm - 1;
> +       *p = calcp;
> +}
> +
> +
> +
> +/**
>   * sunxi_factors_clk_setup() - Setup function for factor clocks
>   */
>  
> @@ -332,6 +373,14 @@ static struct clk_factors_config sun4i_apb1_config = {
>         .pwidth = 2,
>  };
>  
> +/* user manual says "n" but it's really "p" */
> +static struct clk_factors_config sun4i_mod0_config = {
> +       .mshift = 0,
> +       .mwidth = 4,
> +       .pshift = 16,
> +       .pwidth = 2,
> +};
> +
>  static const struct factors_data sun4i_pll1_data __initconst = {
>         .enable = 31,
>         .table = &sun4i_pll1_config,
> @@ -355,6 +404,13 @@ static const struct factors_data sun4i_apb1_data __initconst = {
>         .getter = sun4i_get_apb1_factors,
>  };
>  
> +static const struct factors_data sun4i_mod0_data __initconst = {
> +       .enable = 31,
> +       .mux = 24,
> +       .table = &sun4i_mod0_config,
> +       .getter = sun4i_get_mod0_factors,
> +};
> +
>  static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
>                                                 const struct factors_data *data)
>  {
> @@ -845,6 +901,7 @@ static const struct of_device_id clk_factors_match[] __initconst = {
>         {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
>         {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
>         {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
> +       {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
>         {}
>  };
>  
> -- 
> 1.8.5.1
> 

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

* [PATCH v2 05/11] clk: sunxi: add PLL5 and PLL6 support
  2013-12-19  4:59   ` Mike Turquette
@ 2013-12-21  2:26     ` Emilio López
  0 siblings, 0 replies; 22+ messages in thread
From: Emilio López @ 2013-12-21  2:26 UTC (permalink / raw)
  To: linux-arm-kernel

El 19/12/13 01:59, Mike Turquette escribi?:
> Quoting Emilio L?pez (2013-12-17 16:44:57)
>> +
>> +       /* It's not a good idea to have automatic reparenting changing
>> +        * our RAM clock! */
>> +       clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
>
> Just out of curiosity, did you hit this problem in testing?

Yes, I believe it was the case that, with automatic reparenting 
implemented, reconfiguring the mmc or similar clock ended up choosing 
pll5_other as ideal parent, and was trying to tune its frequency.

> Acked-by: Mike Turquette <mturquette@linaro.org>

Thanks!

Emilio

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

end of thread, other threads:[~2013-12-21  2:26 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-18  0:44 [PATCH v2 00/11] clk: sunxi: PLL4/5/6, mod0 and mbus support Emilio López
2013-12-18  0:44 ` [PATCH v2 01/11] clk: sunxi: register factors clocks behind composite Emilio López
2013-12-18  2:55   ` Mike Turquette
2013-12-18 11:27     ` Emilio López
2013-12-18  0:44 ` [PATCH v2 02/11] clk: sunxi: add gating support to PLL1 Emilio López
2013-12-18  2:57   ` Mike Turquette
2013-12-18  0:44 ` [PATCH v2 03/11] ARM: sunxi: add PLL4 support Emilio López
2013-12-18  0:44 ` [PATCH v2 04/11] clk: sunxi: make factors_clk_setup return the clock it registers Emilio López
2013-12-18  3:01   ` Mike Turquette
2013-12-18 11:34     ` Emilio López
2013-12-18  0:44 ` [PATCH v2 05/11] clk: sunxi: add PLL5 and PLL6 support Emilio López
2013-12-19  4:59   ` Mike Turquette
2013-12-21  2:26     ` Emilio López
2013-12-18  0:44 ` [PATCH v2 06/11] ARM: " Emilio López
2013-12-18  0:44 ` [PATCH v2 07/11] clk: sunxi: mod0 support Emilio López
2013-12-19  4:59   ` Mike Turquette
2013-12-18  0:45 ` [PATCH v2 08/11] ARM: sun4i: dt: mod0 clocks Emilio López
2013-12-18  9:48   ` Maxime Ripard
2013-12-18 11:40     ` Emilio López
2013-12-18  0:45 ` [PATCH v2 09/11] ARM: sun5i: " Emilio López
2013-12-18  0:45 ` [PATCH v2 10/11] ARM: sun7i: " Emilio López
2013-12-18  0:45 ` [PATCH v2 11/11] ARM: sunxi: dt: add nodes for the mbus clock Emilio López

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.