Skip to contentSkip to conversation

clk: sunxi: add PLL5 and PLL6 support

PATCH Superseded Emilio López 4 participants 24 messages Dec 23, 2013 – May 18, 2014 1 message not in the archive

Subsystems (4)
lore
Share & tools
lore

Emilio López

author maintainer
#0 lore raw

v3 cover clk: sunxi: add PLL5 and PLL6 support

Hi everyone,

This is v3 of the sunxi clock series. For those seeing this for the first time, it adds PLL4, PLL5, PLL6 and mod0 clock 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.

v2 -> v3 changelog:
* clean magic 5 on parent char arrays
* drop special consideration for pll5, as the clock protection function should be enough to keep that clock enabled.
* rework the mod0 and mbus nodes as suggested by Maxime, and add a bit of code to keep the old nodes working.
* add Acked-by tags from Mike

Cheers,

Emilio

Emilio L?pez (13):
clk: sunxi: register factors clocks behind composite
clk: sunxi: clean the magic number of mux parents
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
clk: sunxi: support better factor DT nodes
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                  | 146 ++++++++-
 arch/arm/boot/dts/sun5i-a10s.dtsi                 | 122 ++++++-
 arch/arm/boot/dts/sun5i-a13.dtsi                  | 122 ++++++-
 arch/arm/boot/dts/sun7i-a20.dtsi                  | 161 ++++++++-
 drivers/clk/sunxi/clk-factors.c                   |  63 +---
 drivers/clk/sunxi/clk-factors.h                   |  16 +-
 drivers/clk/sunxi/clk-sunxi.c                     | 378 +++++++++++++++++++++-
 8 files changed, 921 insertions(+), 96 deletions(-)
Signature · 1 line
1.8.5.2
author maintainer
#1 lore raw

PATCH v3 1/13 clk: sunxi: register factors clocks behind composite

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.

---
 drivers/clk/sunxi/clk-factors.c | 63 +------------------------------------
 drivers/clk/sunxi/clk-factors.h | 16 +++++-----
 drivers/clk/sunxi/clk-sunxi.c   | 70 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 76 insertions(+), 73 deletions(-)
drivers/clk/sunxi/clk-factors.c +1 -62
index f05207a..9e23264 100644
@@ -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;
-}
drivers/clk/sunxi/clk-factors.h +9 -7
index f49851c..02e1a43 100644
@@ -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
drivers/clk/sunxi/clk-sunxi.c +66 -4

95 lines not on this page · raw message

Signature · 1 line
1.8.5.2
#2 lore raw

PATCH v3 1/13 clk: sunxi: register factors clocks behind composite

Hello Emilio, Mike,

Quoted 211 lines · Emilio L?pez

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.

---
  drivers/clk/sunxi/clk-factors.c | 63 +------------------------------------
  drivers/clk/sunxi/clk-factors.h | 16 +++++-----
  drivers/clk/sunxi/clk-sunxi.c   | 70 ++++++++++++++++++++++++++++++++++++++---
  3 files changed, 76 insertions(+), 73 deletions(-)
drivers/clk/sunxi/clk-factors.c +1 -62
index f05207a..9e23264 100644
@@ -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;
-}
drivers/clk/sunxi/clk-factors.h +9 -7
index f49851c..02e1a43 100644
@@ -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
drivers/clk/sunxi/clk-sunxi.c +60 -2
index 8fc1375..b823613 100644
@@ -23,6 +23,9 @@
 
  static DEFINE_SPINLOCK(clk_lock);
 
+/* Maximum number of parents our clocks have */
+#define SUNXI_MAX_PARENTS	5
+
  /**
   * sun4i_osc_clk_setup() - Setup function for gatable oscillator
   */
@@ -255,7 +258,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 +313,71 @@ 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[SUNXI_MAX_PARENTS];
  	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 < SUNXI_MAX_PARENTS &&
+	       (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+		i++;
+
+	factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+	if (!factors)
+		return;
+
+	/* 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;

drivers/clk/sunxi/clk-sunxi.c static void __init sunxi_factors_clk_setup(struct device_node *node, · line 381

Quoted 10 lines
drivers/clk/sunxi/clk-sunxi.c +6 -2
 
-	clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
-				   data->table, data->getter, &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);
 

I'm currently working on the sunxi NFC (Nand Flash Controller) driver and I need to set the NAND clk (which is a mod0 clk type) rate.

It seems that the composite clk fallbacks to the mux_hw's determine_rate instead of calling the rate_hw's (or factors hw) round_rate, if rate_hw does not implement determine_rate.

In the sunxi specific case, this leads to a DIV by 0 error when later calling set_rate on this composite clk, because the requested freq is set to 0 (result from mux_hw determine_rate):

[    0.632125] Division by zero in kernel.
[    0.635970] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
3.13.0-rc1-00005-ge2b2be1-dirty #203
[    0.644230] [<c00139bc>] (unwind_backtrace+0x0/0xf8) from 
[<c0010fb8>] (show_stack+0x10/0x14)
[    0.652765] [<c0010fb8>] (show_stack+0x10/0x14) from [<c029276c>] 
(dump_stack+0x68/0x84)
[    0.660861] [<c029276c>] (dump_stack+0x68/0x84) from [<c015e8b0>] 
(Ldiv0+0x8/0x10)
[    0.668438] [<c015e8b0>] (Ldiv0+0x8/0x10) from [<c020d63c>] 
(sun4i_get_mod0_factors+0x6c/0xa8)
[    0.677057] [<c020d63c>] (sun4i_get_mod0_factors+0x6c/0xa8) from 
[<c020d87c>] (clk_factors_set_rate+0x50/0x138)
[    0.687149] [<c020d87c>] (clk_factors_set_rate+0x50/0x138) from 
[<c020cf18>] (clk_composite_set_rate+0x20/0x24)
[    0.697241] [<c020cf18>] (clk_composite_set_rate+0x20/0x24) from 
[<c020b538>] (clk_change_rate+0x5c/0xf8)
[    0.706812] [<c020b538>] (clk_change_rate+0x5c/0xf8) from 
[<c020b64c>] (clk_set_rate+0x78/0xb0)
[    0.715518] [<c020b64c>] (clk_set_rate+0x78/0xb0) from [<c01cc370>] 
(sunxi_nfc_probe+0x1ec/0x5e0)
[    0.724383] [<c01cc370>] (sunxi_nfc_probe+0x1ec/0x5e0) from 
[<c01b50d4>] (platform_drv_probe+0x18/0x48)
[    0.733779] [<c01b50d4>] (platform_drv_probe+0x18/0x48) from 
[<c01b37f0>] (driver_probe_device+0x100/0x210)
[    0.743521] [<c01b37f0>] (driver_probe_device+0x100/0x210) from 
[<c01b398c>] (__driver_attach+0x8c/0x90)
[    0.753005] [<c01b398c>] (__driver_attach+0x8c/0x90) from 
[<c01b2178>] (bus_for_each_dev+0x54/0x88)
[    0.762058] [<c01b2178>] (bus_for_each_dev+0x54/0x88) from 
[<c01b2fd4>] (bus_add_driver+0xd8/0x1cc)
[    0.771108] [<c01b2fd4>] (bus_add_driver+0xd8/0x1cc) from 
[<c01b3fc8>] (driver_register+0x78/0xf4)
[    0.780069] [<c01b3fc8>] (driver_register+0x78/0xf4) from 
[<c00087c8>] (do_one_initcall+0x38/0x160)
[    0.789118] [<c00087c8>] (do_one_initcall+0x38/0x160) from 
[<c0372bc0>] (kernel_init_freeable+0xfc/0x1c8)
[    0.798688] [<c0372bc0>] (kernel_init_freeable+0xfc/0x1c8) from 
[<c028fd00>] (kernel_init+0x8/0x110)
[    0.807825] [<c028fd00>] (kernel_init+0x8/0x110) from [<c000e2b8>] 

(ret_from_fork+0x14/0x3c)

We should definitely check the requested freq and gracefully handle the 0 case.

But anyway, I think there is a drawback in the way composite clk implement the determine_rate handler.
Mike, shouldn't we choose the best parent (using mux) fullfilling the rate_hw needs ?

I'll post a proposal...

Best Regards,

Boris

Quoted 3 lines
drivers/clk/sunxi/clk-sunxi.c +0 -0
  	if (!IS_ERR(clk)) {
  		of_clk_add_provider(node, of_clk_src_simple_get, clk);
author maintainer
#3 lore raw

PATCH v3 1/13 clk: sunxi: register factors clocks behind composite

Hi Boris,

[ Apologies if the email looks weird and for using a link; I'm not using my typical email client ]

Quoted 6 lines

I'm currently working on the sunxi NFC (Nand Flash Controller) driver and I need to set the NAND clk (which is a mod0 clk type) rate.

It seems that the composite clk fallbacks to the mux_hw's determine_rate instead of calling the rate_hw's (or factors hw) round_rate, if rate_hw does not implement determine_rate.

That is to be expected; if you have a composite clock that has all fixed parents you'd not implement the determine_rate on the rate component but on the mux one.

(...)

Quoted 4 lines

But anyway, I think there is a drawback in the way composite clk implement the determine_rate handler.
Mike, shouldn't we choose the best parent (using mux) fullfilling the rate_hw needs ?

Someone using the composite clock may not want their clocks to start changing parents though. I believe it's easier and better to just implement determine_rate as on this patch on my tree (which I haven't sent yet, but it's literally the next in queue.)

http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0

Let me know if that resolves your issue.

Cheers,

Emilio

#4 lore raw

PATCH v3 1/13 clk: sunxi: register factors clocks behind composite

"Emilio L?pez" <[email protected]> a ?crit?:

Quoted 9 lines

Hi Boris,

[ Apologies if the email looks weird and for using a link; I'm not using my typical email client ]

Quoted 4 lines

I'm currently working on the sunxi NFC (Nand Flash Controller) driver and I need to set the NAND clk (which is a mod0 clk type) rate.

It seems that the composite clk fallbacks to the mux_hw's

Quoted 9 lines

determine_rate

Quoted 1 line

instead of calling the rate_hw's (or factors hw) round_rate, if

rate_hw

Quoted 1 line

does not implement determine_rate.

That is to be expected; if you have a composite clock that has all fixed parents you'd not implement the determine_rate on the rate component but on the mux one.

Right, but this is not the case for mod0
clks, is it ?

Quoted 7 lines

(...)

Quoted 4 lines

But anyway, I think there is a drawback in the way composite clk implement the determine_rate handler.
Mike, shouldn't we choose the best parent (using mux) fullfilling the rate_hw needs ?

Quoted 5 lines

Someone using the composite clock may not want their clocks to start changing parents though. I believe it's easier and better to just implement determine_rate as on this patch on my tree (which I haven't sent yet, but it's literally the next in queue.)

Fair enough (I did pretty much the same thing in my first attempt to fix this bug ;-))

Quoted 3 lines

http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0

Let me know if that resolves your issue.

I'll try it tomorrow.

BTW, I managed to get a working NAND driver (without DMA and hw ECC).

I'll post it on the ML soon (just need to clean it up a little bit).

Best regards,

Boris

Quoted 4 lines

Cheers,

Emilio

#5 lore raw

PATCH v3 1/13 clk: sunxi: register factors clocks behind composite

In reply to Emilio López
Quoted 21 lines · Emilio L?pez

Hi Boris,

[ Apologies if the email looks weird and for using a link; I'm not using my typical email client ]

Quoted 6 lines

I'm currently working on the sunxi NFC (Nand Flash Controller) driver and I need to set the NAND clk (which is a mod0 clk type) rate.

It seems that the composite clk fallbacks to the mux_hw's determine_rate instead of calling the rate_hw's (or factors hw) round_rate, if rate_hw does not implement determine_rate.

That is to be expected; if you have a composite clock that has all fixed parents you'd not implement the determine_rate on the rate component but on the mux one.

(...)

Quoted 4 lines

But anyway, I think there is a drawback in the way composite clk implement the determine_rate handler.
Mike, shouldn't we choose the best parent (using mux) fullfilling the rate_hw needs ?

Quoted 8 lines

Someone using the composite clock may not want their clocks to start changing parents though. I believe it's easier and better to just implement determine_rate as on this patch on my tree (which I haven't sent yet, but it's literally the next in queue.)

http://git.elopez.com.ar/linux/commits/5b4eb3ac406b9c98965714d40e8dd6da943d1ab0

Let me know if that resolves your issue.

Yes, it works.
Thanks.

Can you submit it on LAKML so that I can state the dependency in my NFC driver series ?

Best Regards,

Boris

Quoted 4 lines

Cheers,

Emilio

#6 lore raw

RFC PATCH 1/1 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent

In reply to Emilio López

In case the rate_hw does not implement determine_rate, but only round_rate we fallback to best_parent selection if mux_hw is present and support reparenting.

---
 drivers/clk/clk-composite.c |   49 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)
drivers/clk/clk-composite.c +48 -1
index 753d0b7..d3cf49a 100644
@@ -64,11 +64,57 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
 	const struct clk_ops *mux_ops = composite->mux_ops;
 	struct clk_hw *rate_hw = composite->rate_hw;
 	struct clk_hw *mux_hw = composite->mux_hw;
+	struct clk *parent;
+	unsigned long parent_rate;
+	long tmp_rate;
+	unsigned long rate_diff;
+	unsigned long best_rate_diff = ULONG_MAX;
+	int i;
 
 	if (rate_hw && rate_ops && rate_ops->determine_rate) {
 		rate_hw->clk = hw->clk;
 		return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
 						best_parent_p);
+	} else if (rate_hw && rate_ops && rate_ops->round_rate &&
+		   mux_hw && mux_ops && mux_ops->set_parent) {
+		*best_parent_p = NULL;
+
+		if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
+			*best_parent_p = clk_get_parent(mux_hw->clk);
+			*best_parent_rate = __clk_get_rate(*best_parent_p);
+
+			return rate_ops->round_rate(rate_hw, rate,
+						    best_parent_rate);
+		}
+
+		for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
+			parent = clk_get_parent_by_index(mux_hw->clk, i);
+			if (!parent)
+				continue;
+
+			parent_rate = __clk_get_rate(parent);
+
+			tmp_rate = rate_ops->round_rate(rate_hw, rate,
+							&parent_rate);
+			if (tmp_rate < 0)
+				continue;
+
+			if (tmp_rate < rate)
+				rate_diff = rate - tmp_rate;
+			else
+				rate_diff = tmp_rate - rate;
+
+			if (!rate_diff || !*best_parent_p || best_rate_diff > rate_diff) {
+				*best_parent_p = parent;
+				*best_parent_rate = parent_rate;
+				best_rate_diff = rate_diff;
+			}
+
+			if (!rate_diff)
+				return rate;
+		}
+
+		return best_rate_diff;
 	} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
 		mux_hw->clk = hw->clk;
 		return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
@@ -196,7 +242,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 		composite->rate_hw = rate_hw;
 		composite->rate_ops = rate_ops;
 		clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
-		if (rate_ops->determine_rate)
+		if (rate_ops->determine_rate ||
+		    (rate_ops->round_rate && clk_composite_ops->set_parent))
 			clk_composite_ops->determine_rate = clk_composite_determine_rate;
 	}
 
Signature · 1 line
1.7.9.5
#7 lore raw

RFC PATCH 1/1 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent

In reply to Emilio López

In case the rate_hw does not implement determine_rate, but only round_rate we fallback to best_parent selection if mux_hw is present and support reparenting.

---
 drivers/clk/clk-composite.c |   49 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)
drivers/clk/clk-composite.c +48 -1
index 753d0b7..d3cf49a 100644
@@ -64,11 +64,57 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
 	const struct clk_ops *mux_ops = composite->mux_ops;
 	struct clk_hw *rate_hw = composite->rate_hw;
 	struct clk_hw *mux_hw = composite->mux_hw;
+	struct clk *parent;
+	unsigned long parent_rate;
+	long tmp_rate;
+	unsigned long rate_diff;
+	unsigned long best_rate_diff = ULONG_MAX;
+	int i;
 
 	if (rate_hw && rate_ops && rate_ops->determine_rate) {
 		rate_hw->clk = hw->clk;
 		return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
 						best_parent_p);
+	} else if (rate_hw && rate_ops && rate_ops->round_rate &&
+		   mux_hw && mux_ops && mux_ops->set_parent) {
+		*best_parent_p = NULL;
+
+		if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
+			*best_parent_p = clk_get_parent(mux_hw->clk);
+			*best_parent_rate = __clk_get_rate(*best_parent_p);
+
+			return rate_ops->round_rate(rate_hw, rate,
+						    best_parent_rate);
+		}
+
+		for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
+			parent = clk_get_parent_by_index(mux_hw->clk, i);
+			if (!parent)
+				continue;
+
+			parent_rate = __clk_get_rate(parent);
+
+			tmp_rate = rate_ops->round_rate(rate_hw, rate,
+							&parent_rate);
+			if (tmp_rate < 0)
+				continue;
+
+			if (tmp_rate < rate)
+				rate_diff = rate - tmp_rate;
+			else
+				rate_diff = tmp_rate - rate;
+
+			if (!rate_diff || !*best_parent_p || best_rate_diff > rate_diff) {
+				*best_parent_p = parent;
+				*best_parent_rate = parent_rate;
+				best_rate_diff = rate_diff;
+			}
+
+			if (!rate_diff)
+				return rate;
+		}
+
+		return best_rate_diff;
 	} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
 		mux_hw->clk = hw->clk;
 		return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
@@ -196,7 +242,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 		composite->rate_hw = rate_hw;
 		composite->rate_ops = rate_ops;
 		clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
-		if (rate_ops->determine_rate)
+		if (rate_ops->determine_rate ||
+		    (rate_ops->round_rate && clk_composite_ops->set_parent))
 			clk_composite_ops->determine_rate = clk_composite_determine_rate;
 	}
 
Signature · 1 line
1.7.9.5
#8 lore raw

RFC PATCH 1/1 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent

Quoting Boris BREZILLON (2014-01-07 09:03:52)

Quoted 5 lines

In case the rate_hw does not implement determine_rate, but only round_rate we fallback to best_parent selection if mux_hw is present and support reparenting.

Hi Boris,

Since this change affects users of the composite clock type I will hold off reviewing/applying this patch until after the merge window.

Thanks,
Mike

Quoted 79 lines
---
 drivers/clk/clk-composite.c |   49 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)
drivers/clk/clk-composite.c +48 -1
index 753d0b7..d3cf49a 100644
@@ -64,11 +64,57 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
        const struct clk_ops *mux_ops = composite->mux_ops;
        struct clk_hw *rate_hw = composite->rate_hw;
        struct clk_hw *mux_hw = composite->mux_hw;
+       struct clk *parent;
+       unsigned long parent_rate;
+       long tmp_rate;
+       unsigned long rate_diff;
+       unsigned long best_rate_diff = ULONG_MAX;
+       int i;
 
        if (rate_hw && rate_ops && rate_ops->determine_rate) {
                rate_hw->clk = hw->clk;
                return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
                                                best_parent_p);
+       } else if (rate_hw && rate_ops && rate_ops->round_rate &&
+                  mux_hw && mux_ops && mux_ops->set_parent) {
+               *best_parent_p = NULL;
+
+               if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
+                       *best_parent_p = clk_get_parent(mux_hw->clk);
+                       *best_parent_rate = __clk_get_rate(*best_parent_p);
+
+                       return rate_ops->round_rate(rate_hw, rate,
+                                                   best_parent_rate);
+               }
+
+               for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
+                       parent = clk_get_parent_by_index(mux_hw->clk, i);
+                       if (!parent)
+                               continue;
+
+                       parent_rate = __clk_get_rate(parent);
+
+                       tmp_rate = rate_ops->round_rate(rate_hw, rate,
+                                                       &parent_rate);
+                       if (tmp_rate < 0)
+                               continue;
+
+                       if (tmp_rate < rate)
+                               rate_diff = rate - tmp_rate;
+                       else
+                               rate_diff = tmp_rate - rate;
+
+                       if (!rate_diff || !*best_parent_p || best_rate_diff > rate_diff) {
+                               *best_parent_p = parent;
+                               *best_parent_rate = parent_rate;
+                               best_rate_diff = rate_diff;
+                       }
+
+                       if (!rate_diff)
+                               return rate;
+               }
+
+               return best_rate_diff;
        } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
                mux_hw->clk = hw->clk;
                return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
@@ -196,7 +242,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
                composite->rate_hw = rate_hw;
                composite->rate_ops = rate_ops;
                clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
-               if (rate_ops->determine_rate)
+               if (rate_ops->determine_rate ||
+                   (rate_ops->round_rate && clk_composite_ops->set_parent))
                        clk_composite_ops->determine_rate = clk_composite_determine_rate;
        }
 
Signature · 1 line
1.7.9.5
#9 lore raw

RFC PATCH 1/1 clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent

Am Dienstag, 14. Januar 2014, 12:41:46 schrieb Mike Turquette:

Quoted 10 lines

Quoting Boris BREZILLON (2014-01-07 09:03:52)

Quoted 5 lines

In case the rate_hw does not implement determine_rate, but only round_rate we fallback to best_parent selection if mux_hw is present and support reparenting.

Since this change affects users of the composite clock type I will hold off reviewing/applying this patch until after the merge window.

sorry for resurrecting this old code, but it looks like it was forgotten somehow and I'm currently hit by a problem that this patch fixes.

When using a composite clk containing both a divider and mux using the standard clock ops, all rate changes ignore the divider completely and only handle the mux. In my case the parents provide 800 and 600MHz while I'm requesting 300MHz. As only mux_ops->determine_rate runs, I get 600MHz instead of anything <= 300 when using the included divider.

Boris' patch fixes this issue for me, so

The patch applies nicely after adapting it according to 5d2043fbe4ddc6cc16ba71b49c2c13f4cb2fe932 ("clk: composite: pass mux_hw into determine_rate")

Heiko

Quoted 100 lines
Quoted 91 lines

---

 drivers/clk/clk-composite.c |   49

++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-)

drivers/clk/clk-composite.c +13 -0
index 753d0b7..d3cf49a 100644
@@ -64,11 +64,57 @@ static long clk_composite_determine_rate(struct clk_hw
 *hw, unsigned long rate,> 
        const struct clk_ops *mux_ops = composite->mux_ops;
        struct clk_hw *rate_hw = composite->rate_hw;
        struct clk_hw *mux_hw = composite->mux_hw;
 
+       struct clk *parent;
+       unsigned long parent_rate;
+       long tmp_rate;
+       unsigned long rate_diff;
+       unsigned long best_rate_diff = ULONG_MAX;
+       int i;
 
        if (rate_hw && rate_ops && rate_ops->determine_rate) {
 
                rate_hw->clk = hw->clk;
                return rate_ops->determine_rate(rate_hw, rate,
                best_parent_rate,
 
                                                best_parent_p);
 
+       } else if (rate_hw && rate_ops && rate_ops->round_rate &&
+                  mux_hw && mux_ops && mux_ops->set_parent) {
+               *best_parent_p = NULL;
+
+               if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
+                       *best_parent_p = clk_get_parent(mux_hw->clk);
+                       *best_parent_rate =

__clk_get_rate(*best_parent_p);

drivers/clk/clk-composite.c +23 -0
+
+                       return rate_ops->round_rate(rate_hw, rate,
+                                                   best_parent_rate);
+               }
+
+               for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
+                       parent = clk_get_parent_by_index(mux_hw->clk, i);
+                       if (!parent)
+                               continue;
+
+                       parent_rate = __clk_get_rate(parent);
+
+                       tmp_rate = rate_ops->round_rate(rate_hw, rate,
+                                                       &parent_rate);
+                       if (tmp_rate < 0)
+                               continue;
+
+                       if (tmp_rate < rate)
+                               rate_diff = rate - tmp_rate;
+                       else
+                               rate_diff = tmp_rate - rate;
+
+                       if (!rate_diff || !*best_parent_p ||

best_rate_diff > rate_diff) { +
*best_parent_p = parent;

drivers/clk/clk-composite.c +9 -0
+                               *best_parent_rate = parent_rate;
+                               best_rate_diff = rate_diff;
+                       }
+
+                       if (!rate_diff)
+                               return rate;
+               }
+
+               return best_rate_diff;
 
        } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
 
                mux_hw->clk = hw->clk;
                return mux_ops->determine_rate(rate_hw, rate,
                best_parent_rate,
@@ -196,7 +242,8 @@ struct clk *clk_register_composite(struct device *dev,

const char *name,>

                composite->rate_hw = rate_hw;
                composite->rate_ops = rate_ops;
                clk_composite_ops->recalc_rate =
                clk_composite_recalc_rate;
drivers/clk/clk-composite.c +2 -1
-               if (rate_ops->determine_rate)
+               if (rate_ops->determine_rate ||
+                   (rate_ops->round_rate &&

clk_composite_ops->set_parent))>

Quoted 4 lines
                        clk_composite_ops->determine_rate =
                        clk_composite_determine_rate;
        
        }

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

author maintainer
#10 lore raw

PATCH v3 2/13 clk: sunxi: clean the magic number of mux parents

In reply to Emilio López

This was pointed out during the review of the factor patches. Let's indicate what does that magic 5 mean.

---
 drivers/clk/sunxi/clk-sunxi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/clk/sunxi/clk-sunxi.c +3 -2
index b823613..ce42c92 100644
@@ -414,13 +414,14 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
 {
 	struct clk *clk;
 	const char *clk_name = node->name;
-	const char *parents[5];
+	const char *parents[SUNXI_MAX_PARENTS];
 	void *reg;
 	int i = 0;
 
 	reg = of_iomap(node, 0);
 
-	while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+	while (i < SUNXI_MAX_PARENTS &&
+	       (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
 		i++;
 
 	clk = clk_register_mux(NULL, clk_name, parents, i,
Signature · 1 line
1.8.5.2
author maintainer
#11 lore raw

PATCH v3 3/13 clk: sunxi: add gating support to PLL1

In reply to Emilio López

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

---
 Documentation/devicetree/bindings/clock/sunxi.txt | 2 +-
 drivers/clk/sunxi/clk-sunxi.c                     | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/clock/sunxi.txt +1 -1
index 91a748f..b8c6cc4 100644
@@ -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
drivers/clk/sunxi/clk-sunxi.c +2 -0
index ce42c92..42e8690 100644
@@ -295,11 +295,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,
 };
Signature · 1 line
1.8.5.2
author maintainer
#12 lore raw

PATCH v3 4/13 ARM: sunxi: add PLL4 support

In reply to Emilio López

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

---
 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(+)
arch/arm/boot/dts/sun4i-a10.dtsi +7 -0
index 5b158d2..3833c14 100644
@@ -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>;
arch/arm/boot/dts/sun5i-a10s.dtsi +7 -0
index b4764be..3252aa8 100644
@@ -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>;
arch/arm/boot/dts/sun5i-a13.dtsi +7 -0
index ce8ef2a..8c4a9c3 100644
@@ -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>;
arch/arm/boot/dts/sun7i-a20.dtsi +7 -0
index d62d693..2b2d3847 100644
@@ -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
Signature · 1 line
1.8.5.2
author maintainer
#13 lore raw

PATCH v3 5/13 clk: sunxi: make factors_clk_setup return the clock it registers

In reply to Emilio López

We will be needing this to register a factor clock as parent with leaf divisors on a single call.

---
 drivers/clk/sunxi/clk-sunxi.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/clk/sunxi/clk-sunxi.c +8 -7
index 42e8690..0f23d16 100644
@@ -311,8 +311,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;
@@ -334,14 +334,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 */
@@ -357,7 +357,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 */
@@ -378,13 +378,14 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
 			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, 0);
 
 	if (!IS_ERR(clk)) {
 		of_clk_add_provider(node, of_clk_src_simple_get, clk);
 		clk_register_clkdev(clk, clk_name, NULL);
 	}
+
+	return clk;
 }
 
 
Signature · 1 line
1.8.5.2
author maintainer
#14 lore raw

PATCH v3 6/13 clk: sunxi: add PLL5 and PLL6 support

In reply to Emilio López

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

---
 Documentation/devicetree/bindings/clock/sunxi.txt |   2 +
 drivers/clk/sunxi/clk-sunxi.c                     | 230 ++++++++++++++++++++++
 2 files changed, 232 insertions(+)
Documentation/devicetree/bindings/clock/sunxi.txt +2 -0
index b8c6cc4..80b2a39 100644
@@ -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
drivers/clk/sunxi/clk-sunxi.c +230 -0

266 lines not on this page · raw message

Signature · 1 line
1.8.5.2
author maintainer
#15 lore raw

PATCH v3 7/13 ARM: sunxi: add PLL5 and PLL6 support

In reply to Emilio López

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

---
 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(-)
arch/arm/boot/dts/sun4i-a10.dtsi +17 -2
index 3833c14..ebacb5d 100644
@@ -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 {
arch/arm/boot/dts/sun5i-a10s.dtsi +17 -2
index 3252aa8..86e06e4 100644
@@ -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 {
arch/arm/boot/dts/sun5i-a13.dtsi +17 -2
index 8c4a9c3..cded3c7 100644
@@ -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 {
arch/arm/boot/dts/sun7i-a20.dtsi +16 -12
index 2b2d3847..7949028 100644
@@ -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 {
Signature · 1 line
1.8.5.2
author maintainer
#16 lore raw

PATCH v3 8/13 clk: sunxi: mod0 support

In reply to Emilio López

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

---
 Documentation/devicetree/bindings/clock/sunxi.txt |  5 +-
 drivers/clk/sunxi/clk-sunxi.c                     | 57 +++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/clock/sunxi.txt +4 -1
index 80b2a39..46d8433 100644
@@ -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
 
drivers/clk/sunxi/clk-sunxi.c +57 -0

81 lines not on this page · raw message

Signature · 1 line
1.8.5.2
author maintainer
#17 lore raw

PATCH v3 9/13 clk: sunxi: support better factor DT nodes

In reply to Emilio López

The DT nodes should look like

    abc_clk: clk at deadbeef {
        ...
        clock-output-names = "abc";
    }

But our old DT nodes look like

    abc: abc at deadbeef {
        ...
    }

So, let's support both formats, until we can transition everything to the new, correct one.

---
 drivers/clk/sunxi/clk-sunxi.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/clk/sunxi/clk-sunxi.c +9 -0
index 3497a29..2be4e46 100644
@@ -435,6 +435,15 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
 	       (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
 		i++;
 
+	/* Nodes should be providing the name via clock-output-names
+	 * but originally our dts didn't, and so we used node->name.
+	 * The new, better nodes look like clk at deadbeef, so we pull the
+	 * name just in this case */
+	if (!strcmp("clk", clk_name)) {
+		of_property_read_string_index(node, "clock-output-names",
+					      0, &clk_name);
+	}
+
 	factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
 	if (!factors)
 		return NULL;
Signature · 1 line
1.8.5.2
author maintainer
#18 lore raw

PATCH v3 10/13 ARM: sun4i: dt: mod0 clocks

In reply to Emilio López

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

---
 arch/arm/boot/dts/sun4i-a10.dtsi | 120 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)
arch/arm/boot/dts/sun4i-a10.dtsi +120 -0
index ebacb5d..834b37e 100644
@@ -184,6 +184,126 @@
 				"apb1_uart4", "apb1_uart5", "apb1_uart6",
 				"apb1_uart7";
 		};
+
+		nand_clk: clk at 01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "nand";
+		};
+
+		ms_clk: clk at 01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ms";
+		};
+
+		mmc0_clk: clk at 01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc0";
+		};
+
+		mmc1_clk: clk at 01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc1";
+		};
+
+		mmc2_clk: clk at 01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc2";
+		};
+
+		mmc3_clk: clk at 01c20094 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20094 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc3";
+		};
+
+		ts_clk: clk at 01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ts";
+		};
+
+		ss_clk: clk at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ss";
+		};
+
+		spi0_clk: clk at 01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi0";
+		};
+
+		spi1_clk: clk at 01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi1";
+		};
+
+		spi2_clk: clk at 01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi2";
+		};
+
+		pata_clk: clk at 01c200ac {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200ac 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "pata";
+		};
+
+		ir0_clk: clk at 01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir0";
+		};
+
+		ir1_clk: clk at 01c200b4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir1";
+		};
+
+		spi3_clk: clk at 01c200d4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200d4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi3";
+		};
 	};
 
 	soc at 01c00000 {
Signature · 1 line
1.8.5.2
author maintainer
#19 lore raw

PATCH v3 11/13 ARM: sun5i: dt: mod0 clocks

In reply to Emilio López

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.

---
 arch/arm/boot/dts/sun5i-a10s.dtsi | 88 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/sun5i-a13.dtsi  | 88 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 176 insertions(+)
arch/arm/boot/dts/sun5i-a10s.dtsi +88 -0
index 86e06e4..5012c27 100644
@@ -173,6 +173,94 @@
 				"apb1_i2c2", "apb1_uart0", "apb1_uart1",
 				"apb1_uart2", "apb1_uart3";
 		};
+
+		nand_clk: clk at 01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "nand";
+		};
+
+		ms_clk: clk at 01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ms";
+		};
+
+		mmc0_clk: clk at 01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc0";
+		};
+
+		mmc1_clk: clk at 01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc1";
+		};
+
+		mmc2_clk: clk at 01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc2";
+		};
+
+		ts_clk: clk at 01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ts";
+		};
+
+		ss_clk: clk at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ss";
+		};
+
+		spi0_clk: clk at 01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi0";
+		};
+
+		spi1_clk: clk at 01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi1";
+		};
+
+		spi2_clk: clk at 01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi2";
+		};
+
+		ir0_clk: clk at 01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir0";
+		};
 	};
 
 	soc at 01c00000 {
arch/arm/boot/dts/sun5i-a13.dtsi +88 -0

94 lines not on this page · raw message

Signature · 1 line
1.8.5.2
author maintainer
#20 lore raw

PATCH v3 12/13 ARM: sun7i: dt: mod0 clocks

In reply to Emilio López

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.

---
 arch/arm/boot/dts/sun7i-a20.dtsi | 120 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)
arch/arm/boot/dts/sun7i-a20.dtsi +120 -0
index 7949028..9a2e356 100644
@@ -174,6 +174,126 @@
 				"apb1_uart2", "apb1_uart3", "apb1_uart4",
 				"apb1_uart5", "apb1_uart6", "apb1_uart7";
 		};
+
+		nand_clk: clk at 01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "nand";
+		};
+
+		ms_clk: clk at 01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ms";
+		};
+
+		mmc0_clk: clk at 01c20088 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc0";
+		};
+
+		mmc1_clk: clk at 01c2008c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc1";
+		};
+
+		mmc2_clk: clk at 01c20090 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc2";
+		};
+
+		mmc3_clk: clk at 01c20094 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20094 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc3";
+		};
+
+		ts_clk: clk at 01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ts";
+		};
+
+		ss_clk: clk at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ss";
+		};
+
+		spi0_clk: clk at 01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi0";
+		};
+
+		spi1_clk: clk at 01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi1";
+		};
+
+		spi2_clk: clk at 01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi2";
+		};
+
+		pata_clk: clk at 01c200ac {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200ac 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "pata";
+		};
+
+		ir0_clk: clk at 01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir0";
+		};
+
+		ir1_clk: clk at 01c200b4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200b4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir1";
+		};
+
+		spi3_clk: clk at 01c200d4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c200d4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi3";
+		};
 	};
 
 	soc at 01c00000 {
Signature · 1 line
1.8.5.2
author maintainer
#21 lore raw

PATCH v3 13/13 ARM: sunxi: dt: add nodes for the mbus clock

In reply to Emilio López

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.

---
 arch/arm/boot/dts/sun5i-a10s.dtsi | 8 ++++++++
 arch/arm/boot/dts/sun5i-a13.dtsi  | 8 ++++++++
 arch/arm/boot/dts/sun7i-a20.dtsi  | 8 ++++++++
 3 files changed, 24 insertions(+)
arch/arm/boot/dts/sun5i-a10s.dtsi +8 -0
index 5012c27..50f34fd 100644
@@ -261,6 +261,14 @@
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clock-output-names = "ir0";
 		};
+
+		mbus_clk: clk at 01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mbus";
+		};
 	};
 
 	soc at 01c00000 {
arch/arm/boot/dts/sun5i-a13.dtsi +8 -0
index c46ac65..227be94 100644
@@ -258,6 +258,14 @@
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clock-output-names = "ir0";
 		};
+
+		mbus_clk: clk at 01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mbus";
+		};
 	};
 
 	soc at 01c00000 {
arch/arm/boot/dts/sun7i-a20.dtsi +8 -0
index 9a2e356..1ba8532 100644
@@ -294,6 +294,14 @@
 			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
 			clock-output-names = "spi3";
 		};
+
+		mbus_clk: clk at 01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-mod0-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
+			clock-output-names = "mbus";
+		};
 	};
 
 	soc at 01c00000 {
Signature · 1 line
1.8.5.2

A message that is not in the archive (sent off-list or not yet received): 20131223054401.22761.10523@quantum

author maintainer
#23 lore raw

v3 cover clk: sunxi: add PLL5 and PLL6 support

Hi Mike,

El 23/12/13 02:44, Mike Turquette escribi?:

Quoted 9 lines

Quoting Emilio L?pez (2013-12-22 19:32:31)

Quoted 7 lines

Hi everyone,

This is v3 of the sunxi clock series. For those seeing this for the first time, it adds PLL4, PLL5, PLL6 and mod0 clock 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.

Quoted 3 lines

For all the clock patches missing my Ack (I think just the first three):

Great; if nobody else has any other objection I'd like to get these merged for 3.14. I assume you'll want a pull request as agreed on earlier; do you have a branch I can use as a base? These patches depend on the pull Maxime sent last time and is currently sitting on clk-next.

Cheers!

Emilio

#24 lore raw

v3 cover clk: sunxi: add PLL5 and PLL6 support

Quoting Emilio L?pez (2013-12-23 05:22:05)

Quoted 12 lines

Hi Mike,

El 23/12/13 02:44, Mike Turquette escribi?:

Quoted 9 lines

Quoting Emilio L?pez (2013-12-22 19:32:31)

Quoted 7 lines

Hi everyone,

This is v3 of the sunxi clock series. For those seeing this for the first time, it adds PLL4, PLL5, PLL6 and mod0 clock 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.

Quoted 8 lines
Quoted 3 lines

For all the clock patches missing my Ack (I think just the first three):

Great; if nobody else has any other objection I'd like to get these merged for 3.14. I assume you'll want a pull request as agreed on earlier; do you have a branch I can use as a base? These patches depend on the pull Maxime sent last time and is currently sitting on clk-next.

I can assure you that 0903ea60, "clk: add accuracy support for fixed clock" will not change, so feel free to base on that.

Also feel free to roll in "[PATCH 1/4] clk: sunxi: Allwinner A20 output clock support" with your pull request if you like.

Regards,
Mike

Quoted 4 lines

Cheers!

Emilio