sunxi: refresh clock framework
authorZoltan Herpai <wigyori@uid0.hu>
Sat, 4 Jan 2014 09:47:50 +0000 (09:47 +0000)
committerZoltan Herpai <wigyori@uid0.hu>
Sat, 4 Jan 2014 09:47:50 +0000 (09:47 +0000)
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
SVN-Revision: 39186

17 files changed:
target/linux/sunxi/patches-3.12/100-1-clk-sunxi_register_factors.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/100-2-fix-off-by-one-masks.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/100-3-clk-factors-clear-vars.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/100-clk-sunxi_register_factors.patch [deleted file]
target/linux/sunxi/patches-3.12/106-dt-sun7i-add-mod0-clk.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/107-dt-sun5i-add-mod0-clk.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/108-dt-sun4i-add-mod0-clk.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/109-mach-sunxi-add-clkprovider.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/110-clk-sunxi-fix-pll5-6.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/111-clk-composite-determine-rate.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/112-clk-sunxi-automatic-reparenting.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/113-clk-sunxi-unify-apb1.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/114-dt-unify-apb1.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/115-clk-sunxi-muxable-ahb-clock.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/116-dt-update-ahb-clock.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/117-clk-sunxi-declare-OF-provider.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.12/118-sunxi-clk-core-clock-protect.patch [new file with mode: 0644]

diff --git a/target/linux/sunxi/patches-3.12/100-1-clk-sunxi_register_factors.patch b/target/linux/sunxi/patches-3.12/100-1-clk-sunxi_register_factors.patch
new file mode 100644 (file)
index 0000000..c949eeb
--- /dev/null
@@ -0,0 +1,220 @@
+From 337d479970b0c8493ee3e8b8d89fb80ee39333a6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sun, 5 May 2013 21:26:23 -0300
+Subject: [PATCH] clk: sunxi: register factors clocks behind composite
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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>
+---
+ 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 88523f9..6e3926c 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) >> (31-len))  << (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 34ee69f..6aed57f 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -256,7 +256,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);
+ };
+@@ -307,16 +311,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;
++      struct clk_mux *mux;
++      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;
++
++      /* 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;
++      }
+-      clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
+-                                 data->table, data->getter, &clk_lock);
++      /* 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.4
+
diff --git a/target/linux/sunxi/patches-3.12/100-2-fix-off-by-one-masks.patch b/target/linux/sunxi/patches-3.12/100-2-fix-off-by-one-masks.patch
new file mode 100644 (file)
index 0000000..4dba064
--- /dev/null
@@ -0,0 +1,33 @@
+From 04609953e11377c0705b0aba5c25ebdcbb9e4aa7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:47:20 -0300
+Subject: [PATCH] clk: sunxi: factors: fix off-by-one masks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The previous code would generate one bit too long masks, and was
+needlessly complicated. This patch replaces it by simpler code that can
+generate the masks correctly.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-factors.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 88523f9..5687ac9 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -40,7 +40,7 @@ struct clk_factors {
+ #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+-#define SETMASK(len, pos)             (((-1U) >> (31-len))  << (pos))
++#define SETMASK(len, pos)             (((1U << (len)) - 1) << (pos))
+ #define CLRMASK(len, pos)             (~(SETMASK(len, pos)))
+ #define FACTOR_GET(bit, len, reg)     (((reg) & SETMASK(len, bit)) >> (bit))
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/100-3-clk-factors-clear-vars.patch b/target/linux/sunxi/patches-3.12/100-3-clk-factors-clear-vars.patch
new file mode 100644 (file)
index 0000000..a1323ea
--- /dev/null
@@ -0,0 +1,31 @@
+From 29aef2f23ca8c91bce0a356fd5f120404389125a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:50:46 -0300
+Subject: [PATCH] clk: sunxi: factors: clear variables before using them
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Random bits may get into our factors if we don't clear n, k, m and p.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-factors.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 5687ac9..f05207a 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -88,7 +88,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+ {
+-      u8 n, k, m, p;
++      u8 n = 0, k = 0, m = 0, p = 0;
+       u32 reg;
+       struct clk_factors *factors = to_clk_factors(hw);
+       struct clk_factors_config *config = factors->config;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/100-clk-sunxi_register_factors.patch b/target/linux/sunxi/patches-3.12/100-clk-sunxi_register_factors.patch
deleted file mode 100644 (file)
index c949eeb..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-From 337d479970b0c8493ee3e8b8d89fb80ee39333a6 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
-Date: Sun, 5 May 2013 21:26:23 -0300
-Subject: [PATCH] clk: sunxi: register factors clocks behind composite
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-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>
----
- 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 88523f9..6e3926c 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) >> (31-len))  << (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 34ee69f..6aed57f 100644
---- a/drivers/clk/sunxi/clk-sunxi.c
-+++ b/drivers/clk/sunxi/clk-sunxi.c
-@@ -256,7 +256,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);
- };
-@@ -307,16 +311,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;
-+      struct clk_mux *mux;
-+      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;
-+
-+      /* 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;
-+      }
--      clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
--                                 data->table, data->getter, &clk_lock);
-+      /* 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.4
-
diff --git a/target/linux/sunxi/patches-3.12/106-dt-sun7i-add-mod0-clk.patch b/target/linux/sunxi/patches-3.12/106-dt-sun7i-add-mod0-clk.patch
new file mode 100644 (file)
index 0000000..fbd30c6
--- /dev/null
@@ -0,0 +1,136 @@
+From 8cf7164b32f2ce228b0c8116fd712484f67c65b5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Wed, 4 Sep 2013 21:28:49 -0300
+Subject: [PATCH] ARM: sun7i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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 0af287e..0596e82 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@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ms: ms@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc0: mmc0@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc1: mmc1@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc2: mmc2@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc3: mmc3@01c20094 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20094 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ts: ts@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ss: ss@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi0: spi0@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi1: spi1@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi2: spi2@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              pata: pata@01c200ac {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200ac 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ir0: ir0@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ir1: ir1@01c200b4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi3: spi3@01c200d4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200d4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
+       };
+       soc@01c00000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/107-dt-sun5i-add-mod0-clk.patch b/target/linux/sunxi/patches-3.12/107-dt-sun5i-add-mod0-clk.patch
new file mode 100644 (file)
index 0000000..63fbdd1
--- /dev/null
@@ -0,0 +1,198 @@
+From 0ae543fe8ae8b9ea7166c39b00e977506eccdf4b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Wed, 4 Sep 2013 21:21:16 -0300
+Subject: [PATCH] ARM: sun5i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ms: ms@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc0: mmc0@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc1: mmc1@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc2: mmc2@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ts: ts@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ss: ss@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi0: spi0@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi1: spi1@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi2: spi2@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ir0: ir0@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
+       };
+       soc@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@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ms: ms@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc0: mmc0@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc1: mmc1@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc2: mmc2@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ts: ts@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ss: ss@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi0: spi0@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi1: spi1@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi2: spi2@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ir0: ir0@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
+       };
+       soc@01c00000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/108-dt-sun4i-add-mod0-clk.patch b/target/linux/sunxi/patches-3.12/108-dt-sun4i-add-mod0-clk.patch
new file mode 100644 (file)
index 0000000..d72335b
--- /dev/null
@@ -0,0 +1,135 @@
+From 5f554ea6757748c2fc45228030a20e08f6053ff7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Tue, 21 May 2013 21:28:32 -0300
+Subject: [PATCH] ARM: sun4i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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..2828427e 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@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ms: ms@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc0: mmc0@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc1: mmc1@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc2: mmc2@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              mmc3: mmc3@01c20094 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20094 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ts: ts@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ss: ss@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi0: spi0@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi1: spi1@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi2: spi2@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              pata: pata@01c200ac {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200ac 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ir0: ir0@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              ir1: ir1@01c200b4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
++
++              spi3: spi3@01c200d4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200d4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++              };
+       };
+       soc@01c00000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/109-mach-sunxi-add-clkprovider.patch b/target/linux/sunxi/patches-3.12/109-mach-sunxi-add-clkprovider.patch
new file mode 100644 (file)
index 0000000..7ef6ea2
--- /dev/null
@@ -0,0 +1,11 @@
+diff -ruN old/arch/arm/mach-sunxi/sunxi.c new/arch/arm/mach-sunxi/sunxi.c
+--- old/arch/arm/mach-sunxi/sunxi.c    2014-01-04 01:57:31.000000000 +0100
++++ new/arch/arm/mach-sunxi/sunxi.c    2014-01-04 01:11:47.000000000 +0100
+@@ -10,6 +10,7 @@
+  * warranty of any kind, whether express or implied.
+  */
++#include <linux/clk-provider.h>
+ #include <linux/clocksource.h>
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
diff --git a/target/linux/sunxi/patches-3.12/110-clk-sunxi-fix-pll5-6.patch b/target/linux/sunxi/patches-3.12/110-clk-sunxi-fix-pll5-6.patch
new file mode 100644 (file)
index 0000000..ad5935c
--- /dev/null
@@ -0,0 +1,149 @@
+From 11e7ff129807394d87c937b880bb58972dc91fc0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 28 Nov 2013 09:00:47 -0300
+Subject: [PATCH] fixup! clk: sunxi: add PLL5 and PLL6 support
+
+---
+ drivers/clk/sunxi/clk-sunxi.c | 83 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 69 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index d2b8d3c..3ce33b8 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -807,10 +807,11 @@ struct divs_data {
+               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_table[] = {
++static struct clk_div_table pll6_sata_tbl[] = {
+       { .val = 0, .div = 6, },
+       { .val = 1, .div = 12, },
+       { .val = 2, .div = 18, },
+@@ -829,7 +830,7 @@ struct divs_data {
+ static const struct divs_data pll6_divs_data __initconst = {
+       .factors = &sun4i_pll5_data,
+       .div = {
+-              { .shift = 0, .table = pll6_sata_table }, /* M, SATA */
++              { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
+               { .fixed = 2 }, /* P, other */
+       }
+ };
+@@ -852,6 +853,11 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+       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;
+@@ -866,10 +872,9 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+               return;
+       clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
+-      if (!clks) {
+-              kfree(clk_data);
+-              return;
+-      }
++      if (!clks)
++              goto free_clkdata;
++
+       clk_data->clks = clks;
+       /* It's not a good idea to have automatic reparenting changing
+@@ -881,19 +886,60 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+                                                 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) {
+-                      clks[i] = clk_register_fixed_factor(NULL, clk_name,
+-                                              parent, clkflags,
+-                                              1, 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;
+-                      clks[i] = clk_register_divider_table(NULL, clk_name,
+-                                              parent, clkflags, reg,
+-                                              data->div[i].shift,
+-                                              SUNXI_DIVISOR_WIDTH, flags,
+-                                              data->div[i].table, &clk_lock);
++
++                      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);
+       }
+@@ -905,6 +951,15 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+       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);
+ }
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/111-clk-composite-determine-rate.patch b/target/linux/sunxi/patches-3.12/111-clk-composite-determine-rate.patch
new file mode 100644 (file)
index 0000000..0b4697a
--- /dev/null
@@ -0,0 +1,74 @@
+From de7bfadd1022613ab2c7eeca124bb1e4a6f4c072 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:43:33 -0300
+Subject: [PATCH] clk: composite: .determine_rate support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds .determine_rate support to the composite clock. It will
+use the .determine_rate callback from the rate component if available,
+and fall back on the mux component otherwise. This allows composite
+clocks to enjoy the benefits of automatic clock reparenting.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/clk-composite.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
+index a33f46f..753d0b7 100644
+--- a/drivers/clk/clk-composite.c
++++ b/drivers/clk/clk-composite.c
+@@ -55,6 +55,30 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
+       return rate_ops->recalc_rate(rate_hw, parent_rate);
+ }
++static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
++                                      unsigned long *best_parent_rate,
++                                      struct clk **best_parent_p)
++{
++      struct clk_composite *composite = to_clk_composite(hw);
++      const struct clk_ops *rate_ops = composite->rate_ops;
++      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;
++
++      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 (mux_hw && mux_ops && mux_ops->determine_rate) {
++              mux_hw->clk = hw->clk;
++              return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
++                                             best_parent_p);
++      } else {
++              pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
++              return 0;
++      }
++}
++
+ static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *prate)
+ {
+@@ -147,6 +171,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
+               composite->mux_ops = mux_ops;
+               clk_composite_ops->get_parent = clk_composite_get_parent;
+               clk_composite_ops->set_parent = clk_composite_set_parent;
++              if (mux_ops->determine_rate)
++                      clk_composite_ops->determine_rate = clk_composite_determine_rate;
+       }
+       if (rate_hw && rate_ops) {
+@@ -170,6 +196,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)
++                      clk_composite_ops->determine_rate = clk_composite_determine_rate;
+       }
+       if (gate_hw && gate_ops) {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/112-clk-sunxi-automatic-reparenting.patch b/target/linux/sunxi/patches-3.12/112-clk-sunxi-automatic-reparenting.patch
new file mode 100644 (file)
index 0000000..1ed5754
--- /dev/null
@@ -0,0 +1,73 @@
+From 679e8db359d0c1994e88f3a4a2aa0697ce001ad4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:52:41 -0300
+Subject: [PATCH] clk: sunxi: factors: automatic reparenting support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit implements .determine_rate, so that our factor clocks can be
+reparented when needed.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-factors.c | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 9e23264..3806d97 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+       return rate;
+ }
++static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
++                                     unsigned long *best_parent_rate,
++                                     struct clk **best_parent_p)
++{
++      struct clk *clk = hw->clk, *parent, *best_parent = NULL;
++      int i, num_parents;
++      unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
++
++      /* find the parent that can help provide the fastest rate <= rate */
++      num_parents = __clk_get_num_parents(clk);
++      for (i = 0; i < num_parents; i++) {
++              parent = clk_get_parent_by_index(clk, i);
++              if (!parent)
++                      continue;
++              if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
++                      parent_rate = __clk_round_rate(parent, rate);
++              else
++                      parent_rate = __clk_get_rate(parent);
++
++              child_rate = clk_factors_round_rate(hw, rate, &parent_rate);
++
++              if (child_rate <= rate && child_rate > best_child_rate) {
++                      best_parent = parent;
++                      best = parent_rate;
++                      best_child_rate = child_rate;
++              }
++      }
++
++      if (best_parent)
++              *best_parent_p = best_parent;
++      *best_parent_rate = best;
++
++      return best_child_rate;
++}
++
+ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+ {
+@@ -113,6 +148,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+ }
+ const struct clk_ops clk_factors_ops = {
++      .determine_rate = clk_factors_determine_rate,
+       .recalc_rate = clk_factors_recalc_rate,
+       .round_rate = clk_factors_round_rate,
+       .set_rate = clk_factors_set_rate,
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/113-clk-sunxi-unify-apb1.patch b/target/linux/sunxi/patches-3.12/113-clk-sunxi-unify-apb1.patch
new file mode 100644 (file)
index 0000000..951eaff
--- /dev/null
@@ -0,0 +1,63 @@
+From 75d3fa72634a4943f0f03146916094b6f4908552 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sun, 8 Sep 2013 18:14:52 -0300
+Subject: [PATCH] clk: sunxi: unify APB1 clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit unifies the APB1 mux with the APB1 clock, using the new
+factors infrastructure.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt | 1 -
+ drivers/clk/sunxi/clk-sunxi.c                     | 6 +-----
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index 46d8433..e840cb2 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -27,7 +27,6 @@ Required properties:
+       "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s
+       "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
+       "allwinner,sun4i-apb1-clk" - for the APB1 clock
+-      "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
+       "allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10
+       "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13
+       "allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 06c4f01..0ecaa18 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -400,6 +400,7 @@ struct factors_data {
+ };
+ static const struct factors_data sun4i_apb1_data __initconst = {
++      .mux = 24,
+       .table = &sun4i_apb1_config,
+       .getter = sun4i_get_apb1_factors,
+ };
+@@ -511,10 +512,6 @@ struct mux_data {
+       .shift = 12,
+ };
+-static const struct mux_data sun4i_apb1_mux_data __initconst = {
+-      .shift = 24,
+-};
+-
+ static void __init sunxi_mux_clk_setup(struct device_node *node,
+                                      struct mux_data *data)
+ {
+@@ -869,7 +866,6 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ /* Matches for mux clocks */
+ static const struct of_device_id clk_mux_match[] __initconst = {
+       {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
+-      {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,},
+       {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
+       {}
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/114-dt-unify-apb1.patch b/target/linux/sunxi/patches-3.12/114-dt-unify-apb1.patch
new file mode 100644 (file)
index 0000000..7652391
--- /dev/null
@@ -0,0 +1,118 @@
+From f3443f6d43a69a520ae1e636d69a71c4a6bee21e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sun, 8 Sep 2013 18:12:28 -0300
+Subject: [PATCH] ARM: sunxi: dt: unify APB1 clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With the new factors infrastructure in place, we can unify apb1 and
+apb1_mux as a single clock now.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi  | 9 +--------
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 9 +--------
+ arch/arm/boot/dts/sun5i-a13.dtsi  | 9 +--------
+ arch/arm/boot/dts/sun7i-a20.dtsi  | 9 +--------
+ 4 files changed, 4 insertions(+), 32 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 2828427e..4dccdb0 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -158,18 +158,11 @@
+                               "apb0_ir1", "apb0_keypad";
+               };
+-              apb1_mux: apb1_mux@01c20058 {
+-                      #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-apb1-mux-clk";
+-                      reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+-              };
+-
+               apb1: apb1@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&apb1_mux>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1_gates: apb1_gates@01c2006c {
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 60bd3f7..9cb1b14 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -150,18 +150,11 @@
+                               "apb0_ir", "apb0_keypad";
+               };
+-              apb1_mux: apb1_mux@01c20058 {
+-                      #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-apb1-mux-clk";
+-                      reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+-              };
+-
+               apb1: apb1@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&apb1_mux>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1_gates: apb1_gates@01c2006c {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 3e616a0..6b74dd0 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -148,18 +148,11 @@
+                       clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
+               };
+-              apb1_mux: apb1_mux@01c20058 {
+-                      #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-apb1-mux-clk";
+-                      reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+-              };
+-
+               apb1: apb1@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&apb1_mux>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1_gates: apb1_gates@01c2006c {
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 0bf5d07..55d3e14 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -148,18 +148,11 @@
+                               "apb0_iis2", "apb0_keypad";
+               };
+-              apb1_mux: apb1_mux@01c20058 {
+-                      #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-apb1-mux-clk";
+-                      reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+-              };
+-
+               apb1: apb1@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&apb1_mux>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1_gates: apb1_gates@01c2006c {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/115-clk-sunxi-muxable-ahb-clock.patch b/target/linux/sunxi/patches-3.12/115-clk-sunxi-muxable-ahb-clock.patch
new file mode 100644 (file)
index 0000000..3446b37
--- /dev/null
@@ -0,0 +1,102 @@
+From 147a46beeb49c6baabb85126d570f330a2ba7cad Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:48:40 -0300
+Subject: [PATCH] clk: sunxi: Implement muxable AHB clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+sun5i and sun7i have a mux to change the AHB clock parent, this commit
+adds support for it on the driver.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt |  1 +
+ drivers/clk/sunxi/clk-sunxi.c                     | 37 +++++++++++++++++++++++
+ 2 files changed, 38 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index e840cb2..941bd93 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -15,6 +15,7 @@ Required properties:
+       "allwinner,sun4i-axi-clk" - for the AXI clock
+       "allwinner,sun4i-axi-gates-clk" - for the AXI gates
+       "allwinner,sun4i-ahb-clk" - for the AHB clock
++      "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
+       "allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10
+       "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
+       "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 0ecaa18..360d705 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -240,7 +240,32 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
+       *n = DIV_ROUND_UP(div, (*k+1));
+ }
++/**
++ * sun5i_get_ahb_factors() - calculates p factor for AHB
++ * AHB rate is calculated as follows
++ * rate = parent_rate >> p
++ */
++static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate,
++                                    u8 *n, u8 *k, u8 *m, u8 *p)
++{
++      u8 div;
++
++      /* This clock can only divide, so we will never achieve a higher
++       * rate than the parent's */
++      if (*freq > parent_rate)
++              *freq = parent_rate;
++
++      /* Normalize value to a parent multiple */
++      div = *freq / parent_rate;
++      *freq = parent_rate * div;
++
++      /* we were called to round the frequency, we can now return */
++      if (n == NULL)
++              return;
++
++      *p = div;
++}
+ /**
+  * sun4i_get_apb1_factors() - calculates m, p factors for APB1
+@@ -366,6 +391,11 @@ struct factors_data {
+       .kwidth = 2,
+ };
++static struct clk_factors_config sun5i_a13_ahb_config = {
++      .pshift = 4,
++      .pwidth = 2,
++};
++
+ static struct clk_factors_config sun4i_apb1_config = {
+       .mshift = 0,
+       .mwidth = 5,
+@@ -399,6 +429,12 @@ struct factors_data {
+       .getter = sun4i_get_pll5_factors,
+ };
++static const struct factors_data sun5i_a13_ahb_data __initconst = {
++      .mux = 6,
++      .table = &sun5i_a13_ahb_config,
++      .getter = sun5i_a13_get_ahb_factors,
++};
++
+ static const struct factors_data sun4i_apb1_data __initconst = {
+       .mux = 24,
+       .table = &sun4i_apb1_config,
+@@ -842,6 +878,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ 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,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,},
+       {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
+       {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
+       {}
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/116-dt-update-ahb-clock.patch b/target/linux/sunxi/patches-3.12/116-dt-update-ahb-clock.patch
new file mode 100644 (file)
index 0000000..3d48a60
--- /dev/null
@@ -0,0 +1,69 @@
+From 051f43def45e53d93b9998728e398a68c4948114 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:44:03 -0300
+Subject: [PATCH] ARM: sunxi: dt: Update AHB clock to be muxable on sun[57]i
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+sun5i and sun7i have a mux to select the parent clock for AHB. This
+commit implements the required changes on the device trees.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 4 ++--
+ arch/arm/boot/dts/sun5i-a13.dtsi  | 4 ++--
+ arch/arm/boot/dts/sun7i-a20.dtsi  | 4 ++--
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 9cb1b14..83e183c 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -115,9 +115,9 @@
+               ahb: ahb@01c20054 {
+                       #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-ahb-clk";
++                      compatible = "allwinner,sun5i-a13-ahb-clk";
+                       reg = <0x01c20054 0x4>;
+-                      clocks = <&axi>;
++                      clocks = <&axi>, <&cpu>, <&pll6 1>;
+               };
+               ahb_gates: ahb_gates@01c20060 {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 6b74dd0..0bb4300 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -115,9 +115,9 @@
+               ahb: ahb@01c20054 {
+                       #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-ahb-clk";
++                      compatible = "allwinner,sun5i-a13-ahb-clk";
+                       reg = <0x01c20054 0x4>;
+-                      clocks = <&axi>;
++                      clocks = <&axi>, <&cpu>, <&pll6 1>;
+               };
+               ahb_gates: ahb_gates@01c20060 {
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 55d3e14..63757c5 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -105,9 +105,9 @@
+               ahb: ahb@01c20054 {
+                       #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-ahb-clk";
++                      compatible = "allwinner,sun5i-a13-ahb-clk";
+                       reg = <0x01c20054 0x4>;
+-                      clocks = <&axi>;
++                      clocks = <&axi>, <&pll6 1>, <&pll6 2>;
+               };
+               ahb_gates: ahb_gates@01c20060 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/117-clk-sunxi-declare-OF-provider.patch b/target/linux/sunxi/patches-3.12/117-clk-sunxi-declare-OF-provider.patch
new file mode 100644 (file)
index 0000000..296e0e4
--- /dev/null
@@ -0,0 +1,108 @@
+From be0804513a506de96925f9ed1aa8dc1facd4c180 Mon Sep 17 00:00:00 2001
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Fri, 6 Sep 2013 14:59:57 +0200
+Subject: [PATCH] clk: sunxi: declare OF clock provider
+
+Common clock framework allows to register clock providers to get called
+on of_clk_init() by using CLK_OF_DECLARE. This converts sunxi clock
+providers to make use of it and get rid of the mach specific clk init
+call. As sunxi has a bunch of independent clk provider nodes, we hook
+current clock init to board compatible to make it called once.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Acked-by: Mike Turquette <mturquette@linaro.org>
+---
+ arch/arm/mach-sunxi/sunxi.c   |  4 +---
+ drivers/clk/sunxi/clk-sunxi.c | 11 ++++++-----
+ include/linux/clk/sunxi.h     | 22 ----------------------
+ 3 files changed, 7 insertions(+), 30 deletions(-)
+ delete mode 100644 include/linux/clk/sunxi.h
+
+diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
+index e79fb34..e5a6975 100644
+--- a/arch/arm/mach-sunxi/sunxi.c
++++ b/arch/arm/mach-sunxi/sunxi.c
+@@ -20,8 +20,6 @@
+ #include <linux/io.h>
+ #include <linux/reboot.h>
+-#include <linux/clk/sunxi.h>
+-
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/system_misc.h>
+@@ -118,7 +116,7 @@ static void sunxi_setup_restart(void)
+ static void __init sunxi_timer_init(void)
+ {
+-      sunxi_init_clocks();
++      of_clk_init(NULL);
+       clocksource_of_init();
+ }
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 34ee69f..9bbd035 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -16,7 +16,6 @@
+ #include <linux/clk-provider.h>
+ #include <linux/clkdev.h>
+-#include <linux/clk/sunxi.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+@@ -617,11 +616,8 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
+       }
+ }
+-void __init sunxi_init_clocks(void)
++static void __init sunxi_init_clocks(struct device_node *np)
+ {
+-      /* Register all the simple and basic clocks on DT */
+-      of_clk_init(NULL);
+-
+       /* Register factor clocks */
+       of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
+@@ -634,3 +630,8 @@ void __init sunxi_init_clocks(void)
+       /* Register gate clocks */
+       of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
+ }
++CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
++CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
++CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sunxi_init_clocks);
++CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sunxi_init_clocks);
++CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sunxi_init_clocks);
+diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
+deleted file mode 100644
+index e074fdd..0000000
+--- a/include/linux/clk/sunxi.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-/*
+- * Copyright 2012 Maxime Ripard
+- *
+- * Maxime Ripard <maxime.ripard@free-electrons.com>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- */
+-
+-#ifndef __LINUX_CLK_SUNXI_H_
+-#define __LINUX_CLK_SUNXI_H_
+-
+-void __init sunxi_init_clocks(void);
+-
+-#endif
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.12/118-sunxi-clk-core-clock-protect.patch b/target/linux/sunxi/patches-3.12/118-sunxi-clk-core-clock-protect.patch
new file mode 100644 (file)
index 0000000..50536d1
--- /dev/null
@@ -0,0 +1,67 @@
+From d1bcc34ce6cb7601ce27f3090aee0e8a3e8076e3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:54:42 -0300
+Subject: [PATCH] clk: sunxi: protect core clocks from accidental shutdown
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some important clocks may get disabled as a side effect of another clock
+being disabled, because they have no consumers. This patch implements a
+mechanism so those clocks can be claimed by the driver and therefore
+remain enabled at all times.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 9bbd035..8fc1375 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -616,6 +616,31 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
+       }
+ }
++/**
++ * System clock protection
++ *
++ * By enabling these critical clocks, we prevent their accidental gating
++ * by the framework
++ */
++static void __init sunxi_clock_protect(void)
++{
++      struct clk *clk;
++
++      /* memory bus clock - sun5i+ */
++      clk = clk_get(NULL, "mbus");
++      if (!IS_ERR(clk)) {
++              clk_prepare_enable(clk);
++              clk_put(clk);
++      }
++
++      /* DDR clock - sun4i+ */
++      clk = clk_get(NULL, "pll5_ddr");
++      if (!IS_ERR(clk)) {
++              clk_prepare_enable(clk);
++              clk_put(clk);
++      }
++}
++
+ static void __init sunxi_init_clocks(struct device_node *np)
+ {
+       /* Register factor clocks */
+@@ -629,6 +654,9 @@ static void __init sunxi_init_clocks(struct device_node *np)
+       /* Register gate clocks */
+       of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
++
++      /* Enable core system clocks */
++      sunxi_clock_protect();
+ }
+ CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
+ CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
+-- 
+1.8.5.1
+