ipq806x: update clk and cpufreq drivers
authorPavel Kubelun <be.dissent@gmail.com>
Sat, 9 Dec 2017 17:15:05 +0000 (20:15 +0300)
committerFelix Fietkau <nbd@nbd.name>
Wed, 17 Jan 2018 10:02:05 +0000 (11:02 +0100)
A newer clk and cpufreq drivers for ipq806x platform had been sent upstream.

A change that i have noticed is that now it's possible to set min, cur and max frequencies from sysfs (previously it was bugged and caused nothing).

Following patches are removed:
 - 0036-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch - seems it was dropped from the patchset by current committer.
 - 0044-clk-qcom-krait-Remove-CLK_IS_ROOT.patch - already applied to the driver itself in the corresponding patch.
 - 0057-clk-qcom-Add-regmap-mux-div-clocks-support.patch - seem to be irrelevant to ipq806x.

Signed-off-by: Pavel Kubelun <be.dissent@gmail.com>
16 files changed:
target/linux/ipq806x/patches-4.9/0034-ARM-Add-Krait-L2-register-accessor-functions.patch
target/linux/ipq806x/patches-4.9/0035-clk-mux-Split-out-register-accessors-for-reuse.patch
target/linux/ipq806x/patches-4.9/0036-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch [deleted file]
target/linux/ipq806x/patches-4.9/0037-clk-Add-safe-switch-hook.patch [deleted file]
target/linux/ipq806x/patches-4.9/0038-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
target/linux/ipq806x/patches-4.9/0039-clk-qcom-Add-HFPLL-driver.patch
target/linux/ipq806x/patches-4.9/0040-clk-qcom-Add-IPQ806X-s-HFPLLs.patch
target/linux/ipq806x/patches-4.9/0041-clk-qcom-Add-support-for-Krait-clocks.patch
target/linux/ipq806x/patches-4.9/0042-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
target/linux/ipq806x/patches-4.9/0043-clk-qcom-Add-Krait-clock-controller-driver.patch
target/linux/ipq806x/patches-4.9/0044-clk-Add-safe-switch-hook.patch [new file with mode: 0644]
target/linux/ipq806x/patches-4.9/0044-clk-qcom-krait-Remove-CLK_IS_ROOT.patch [deleted file]
target/linux/ipq806x/patches-4.9/0045-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch
target/linux/ipq806x/patches-4.9/0046-cpufreq-qcom-independent-core-clocks.patch
target/linux/ipq806x/patches-4.9/0057-clk-qcom-Add-regmap-mux-div-clocks-support.patch [deleted file]
target/linux/ipq806x/patches-4.9/0062-ipq806x-gcc-Added-the-enable-regs-and-mask-for-PRNG.patch

index 8c69b97cc4064f2b8d8371a2fc5055407e7489cb..019170b6dcd0a9776a847e29b70ad2f8094de0d1 100644 (file)
@@ -1,7 +1,21 @@
-From 1d6b12f73c98ecf252743936a53242356cc50a34 Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:19 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,01/12] ARM: Add Krait L2 register accessor functions
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102101
+Message-Id: <1512726150-7204-2-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org, Mark Rutland <mark.rutland@arm.com>,
+ Russell King <linux@arm.linux.org.uk>,
+ Courtney Cavin <courtney.cavin@sonymobile.com>
+Date: Fri,  8 Dec 2017 15:12:19 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:20 -0700
-Subject: [PATCH 34/69] ARM: Add Krait L2 register accessor functions
 
 Krait CPUs have a handful of L2 cache controller registers that
 live behind a cp15 based indirection register. First you program
index 426cabd4e4e3a3706f22786f4263f494dd36efc4..5a64e6c56e6b3b72a4e78a297fb18004aec88231 100644 (file)
@@ -1,7 +1,19 @@
-From 9d381d65eae163d8f50d97a3ad9033bba176f62b Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:20 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,02/12] clk: mux: Split out register accessors for reuse
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102103
+Message-Id: <1512726150-7204-3-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:20 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:21 -0700
-Subject: [PATCH 35/69] clk: mux: Split out register accessors for reuse
 
 We want to reuse the logic in clk-mux.c for other clock drivers
 that don't use readl as register accessors. Fortunately, there
@@ -12,28 +24,25 @@ that operate on an optional table and some flags so that other
 drivers can use the same logic.
 
 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
 ---
- drivers/clk/clk-mux.c        | 76 ++++++++++++++++++++++++++++----------------
- include/linux/clk-provider.h | 11 +++++--
- 2 files changed, 57 insertions(+), 30 deletions(-)
+ drivers/clk/clk-mux.c        | 75 +++++++++++++++++++++++++++-----------------
+ include/linux/clk-provider.h |  9 ++++--
+ 2 files changed, 54 insertions(+), 30 deletions(-)
 
 --- a/drivers/clk/clk-mux.c
 +++ b/drivers/clk/clk-mux.c
-@@ -26,35 +26,27 @@
+@@ -26,35 +26,24 @@
   * parent - parent is adjustable through clk_set_parent
   */
  
 -static u8 clk_mux_get_parent(struct clk_hw *hw)
-+#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
-+
 +unsigned int clk_mux_get_parent(struct clk_hw *hw, unsigned int val,
 +                              unsigned int *table, unsigned long flags)
  {
-       struct clk_mux *mux = to_clk_mux(hw);
+-      struct clk_mux *mux = to_clk_mux(hw);
        int num_parents = clk_hw_get_num_parents(hw);
 -      u32 val;
+-
 -      /*
 -       * FIXME need a mux-specific flag to determine if val is bitwise or numeric
 -       * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
@@ -43,7 +52,7 @@ Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
 -       */
 -      val = clk_readl(mux->reg) >> mux->shift;
 -      val &= mux->mask;
--
 -      if (mux->table) {
 +      if (table) {
                int i;
@@ -64,7 +73,7 @@ Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
                val--;
  
        if (val >= num_parents)
-@@ -62,23 +54,53 @@ static u8 clk_mux_get_parent(struct clk_
+@@ -62,23 +51,53 @@ static u8 clk_mux_get_parent(struct clk_
  
        return val;
  }
@@ -80,9 +89,9 @@ Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
 -      if (mux->table) {
 -              index = mux->table[index];
 +      /*
-+       * FIXME need a mux-specific flag to determine if val is bitwise or numeric
-+       * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
-+       * to 0x7 (index starts at one)
++       * FIXME need a mux-specific flag to determine if val is bitwise or
++       * numeric e.g. sys_clkin_ck's clksel field is 3 bits wide,
++       * but ranges from 0x1 to 0x7 (index starts at one)
 +       * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
 +       * val = 0x4 really means "bit 2, index starts at bit 0"
 +       */
@@ -126,7 +135,7 @@ Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
        if (mux->lock)
                spin_lock_irqsave(mux->lock, flags);
        else
-@@ -102,14 +124,14 @@ static int clk_mux_set_parent(struct clk
+@@ -102,14 +121,14 @@ static int clk_mux_set_parent(struct clk
  }
  
  const struct clk_ops clk_mux_ops = {
@@ -143,7 +152,7 @@ Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
  };
  EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
  
-@@ -117,7 +139,7 @@ struct clk_hw *clk_hw_register_mux_table
+@@ -117,7 +136,7 @@ struct clk_hw *clk_hw_register_mux_table
                const char * const *parent_names, u8 num_parents,
                unsigned long flags,
                void __iomem *reg, u8 shift, u32 mask,
@@ -175,13 +184,7 @@ Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
  struct clk *clk_register_mux(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents,
                unsigned long flags,
-@@ -499,12 +504,12 @@ struct clk *clk_register_mux_table(struc
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
--              u8 clk_mux_flags, u32 *table, spinlock_t *lock);
-+              u8 clk_mux_flags, unsigned int *table, spinlock_t *lock);
- struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
+@@ -504,7 +509,7 @@ struct clk_hw *clk_hw_register_mux_table
                const char * const *parent_names, u8 num_parents,
                unsigned long flags,
                void __iomem *reg, u8 shift, u32 mask,
diff --git a/target/linux/ipq806x/patches-4.9/0036-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch b/target/linux/ipq806x/patches-4.9/0036-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch
deleted file mode 100644 (file)
index f4a47c7..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-From 88e1d6d9c113fe50810d1b03eb1fdbf015e5d1bd Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:22 -0700
-Subject: [PATCH 36/69] clk: Avoid sending high rates to downstream clocks
- during set_rate
-
-If a clock is on and we call clk_set_rate() on it we may get into
-a situation where the clock temporarily increases in rate
-dramatically while we walk the tree and call .set_rate() ops. For
-example, consider a case where a PLL feeds into a divider.
-Initially the divider is set to divide by 1 and the PLL is
-running fairly slow (100MHz). The downstream consumer of the
-divider output can only handle rates =< 400 MHz, but the divider
-can only choose between divisors of 1 and 4.
-
- +-----+   +----------------+
- | PLL |-->| div 1 or div 4 |---> consumer device
- +-----+   +----------------+
-
-To achieve a rate of 400MHz on the output of the divider, we
-would have to set the rate of the PLL to 1.6 GHz and then divide
-it by 4. The current code would set the PLL to 1.6GHz first while
-the divider is still set to 1, thus causing the downstream
-consumer of the clock to receive a few clock cycles of 1.6GHz
-clock (far beyond it's maximum acceptable rate). We should be
-changing the divider first before increasing the PLL rate to
-avoid this problem.
-
-Therefore, set the rate of any child clocks that are increasing
-in rate from their current rate so that they can increase their
-dividers if necessary. We assume that there isn't such a thing as
-minimum rate requirements.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-
-Conflicts:
-       drivers/clk/clk.c
----
- drivers/clk/clk.c | 22 +++++++++++++++-------
- 1 file changed, 15 insertions(+), 7 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -1466,12 +1466,12 @@ static struct clk_core *clk_propagate_ra
-  * walk down a subtree and set the new rates notifying the rate
-  * change on the way
-  */
--static void clk_change_rate(struct clk_core *core)
-+static void
-+clk_change_rate(struct clk_core *core, unsigned long best_parent_rate)
- {
-       struct clk_core *child;
-       struct hlist_node *tmp;
-       unsigned long old_rate;
--      unsigned long best_parent_rate = 0;
-       bool skip_set_rate = false;
-       struct clk_core *old_parent;
-       struct clk_core *parent = NULL;
-@@ -1523,6 +1523,7 @@ static void clk_change_rate(struct clk_c
-       trace_clk_set_rate_complete(core, core->new_rate);
-       core->rate = clk_recalc(core, best_parent_rate);
-+      core->rate = core->new_rate;
-       if (core->flags & CLK_SET_RATE_UNGATE) {
-               unsigned long flags;
-@@ -1550,12 +1551,13 @@ static void clk_change_rate(struct clk_c
-               /* Skip children who will be reparented to another clock */
-               if (child->new_parent && child->new_parent != core)
-                       continue;
--              clk_change_rate(child);
-+              if (child->new_rate != child->rate)
-+                      clk_change_rate(child, core->new_rate);
-       }
--      /* handle the new child who might not be in core->children yet */
--      if (core->new_child)
--              clk_change_rate(core->new_child);
-+      /* handle the new child who might not be in clk->children yet */
-+      if (core->new_child && core->new_child->new_rate != core->new_child->rate)
-+              clk_change_rate(core->new_child, core->new_rate);
- }
- static int clk_core_set_rate_nolock(struct clk_core *core,
-@@ -1563,6 +1565,7 @@ static int clk_core_set_rate_nolock(stru
- {
-       struct clk_core *top, *fail_clk;
-       unsigned long rate = req_rate;
-+      unsigned long parent_rate;
-       if (!core)
-               return 0;
-@@ -1588,8 +1591,13 @@ static int clk_core_set_rate_nolock(stru
-               return -EBUSY;
-       }
-+      if (top->parent)
-+              parent_rate = top->parent->rate;
-+      else
-+              parent_rate = 0;
-+
-       /* change the rates */
--      clk_change_rate(top);
-+      clk_change_rate(top, parent_rate);
-       core->req_rate = req_rate;
diff --git a/target/linux/ipq806x/patches-4.9/0037-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches-4.9/0037-clk-Add-safe-switch-hook.patch
deleted file mode 100644 (file)
index bff605f..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-From a1adfb782789ae9b25c928dfe3d639288563a86c Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:23 -0700
-Subject: [PATCH 37/69] clk: Add safe switch hook
-
-Sometimes clocks can't accept their parent source turning off
-while the source is reprogrammed to a different rate. Most
-notably CPU clocks require a way to switch away from the current
-PLL they're running on, reprogram that PLL to a new rate, and
-then switch back to the PLL with the new rate once they're done.
-Add a hook that drivers can implement allowing them to return a
-'safe parent' and 'safe frequency' that they can switch their
-parent to while the upstream source is reprogrammed to support
-this.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
----
- drivers/clk/clk.c            | 73 +++++++++++++++++++++++++++++++++++++++++---
- include/linux/clk-provider.h |  2 ++
- 2 files changed, 70 insertions(+), 5 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -51,9 +51,13 @@ struct clk_core {
-       struct clk_core         **parents;
-       u8                      num_parents;
-       u8                      new_parent_index;
-+      u8                      safe_parent_index;
-       unsigned long           rate;
-       unsigned long           req_rate;
-+      unsigned long           old_rate;
-       unsigned long           new_rate;
-+      unsigned long           safe_freq;
-+      struct clk_core         *safe_parent;
-       struct clk_core         *new_parent;
-       struct clk_core         *new_child;
-       unsigned long           flags;
-@@ -1310,7 +1314,9 @@ out:
- static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
-                            struct clk_core *new_parent, u8 p_index)
- {
--      struct clk_core *child;
-+      struct clk_core *child, *parent;
-+      struct clk_hw *parent_hw;
-+      unsigned long safe_freq = 0;
-       core->new_rate = new_rate;
-       core->new_parent = new_parent;
-@@ -1320,6 +1326,23 @@ static void clk_calc_subtree(struct clk_
-       if (new_parent && new_parent != core->parent)
-               new_parent->new_child = core;
-+      if (core->ops->get_safe_parent) {
-+              parent_hw = core->ops->get_safe_parent(core->hw, &safe_freq);
-+              if (parent_hw) {
-+                      parent = parent_hw->core;
-+                      p_index = clk_fetch_parent_index(core, parent);
-+                      core->safe_parent_index = p_index;
-+                      core->safe_parent = parent;
-+                      if (safe_freq)
-+                              core->safe_freq = safe_freq;
-+                      else
-+                              core->safe_freq = 0;
-+              }
-+      } else {
-+              core->safe_parent = NULL;
-+              core->safe_freq = 0;
-+      }
-+
-       hlist_for_each_entry(child, &core->children, child_node) {
-               child->new_rate = clk_recalc(child, new_rate);
-               clk_calc_subtree(child, child->new_rate, NULL, 0);
-@@ -1432,14 +1455,51 @@ static struct clk_core *clk_propagate_ra
-                                                 unsigned long event)
- {
-       struct clk_core *child, *tmp_clk, *fail_clk = NULL;
-+      struct clk_core *old_parent;
-       int ret = NOTIFY_DONE;
--      if (core->rate == core->new_rate)
-+      if (core->rate == core->new_rate && event != POST_RATE_CHANGE)
-               return NULL;
-+      switch (event) {
-+      case PRE_RATE_CHANGE:
-+              if (core->safe_parent) {
-+                      if (core->safe_freq)
-+                              core->ops->set_rate_and_parent(core->hw,
-+                                              core->safe_freq,
-+                                              core->safe_parent->rate,
-+                                              core->safe_parent_index);
-+                      else
-+                              core->ops->set_parent(core->hw,
-+                                              core->safe_parent_index);
-+              }
-+              core->old_rate = core->rate;
-+              break;
-+      case POST_RATE_CHANGE:
-+              if (core->safe_parent) {
-+                      old_parent = __clk_set_parent_before(core,
-+                                                           core->new_parent);
-+                      if (core->ops->set_rate_and_parent) {
-+                              core->ops->set_rate_and_parent(core->hw,
-+                                              core->new_rate,
-+                                              core->new_parent ?
-+                                              core->new_parent->rate : 0,
-+                                              core->new_parent_index);
-+                      } else if (core->ops->set_parent) {
-+                              core->ops->set_parent(core->hw,
-+                                              core->new_parent_index);
-+                      }
-+                      __clk_set_parent_after(core, core->new_parent,
-+                                             old_parent);
-+              }
-+              break;
-+      }
-+
-       if (core->notifier_count) {
--              ret = __clk_notify(core, event, core->rate, core->new_rate);
--              if (ret & NOTIFY_STOP_MASK)
-+              if (event != POST_RATE_CHANGE || core->old_rate != core->rate)
-+                      ret = __clk_notify(core, event, core->old_rate,
-+                                         core->new_rate);
-+              if (ret & NOTIFY_STOP_MASK && event != POST_RATE_CHANGE)
-                       fail_clk = core;
-       }
-@@ -1495,7 +1555,8 @@ clk_change_rate(struct clk_core *core, u
-               clk_enable_unlock(flags);
-       }
--      if (core->new_parent && core->new_parent != core->parent) {
-+      if (core->new_parent && core->new_parent != core->parent &&
-+          !core->safe_parent) {
-               old_parent = __clk_set_parent_before(core, core->new_parent);
-               trace_clk_set_parent(core, core->new_parent);
-@@ -1601,6 +1662,8 @@ static int clk_core_set_rate_nolock(stru
-       core->req_rate = req_rate;
-+      clk_propagate_rate_change(top, POST_RATE_CHANGE);
-+
-       return 0;
- }
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -206,6 +206,8 @@ struct clk_ops {
-                                         struct clk_rate_request *req);
-       int             (*set_parent)(struct clk_hw *hw, u8 index);
-       u8              (*get_parent)(struct clk_hw *hw);
-+      struct clk_hw   *(*get_safe_parent)(struct clk_hw *hw,
-+                                          unsigned long *safe_freq);
-       int             (*set_rate)(struct clk_hw *hw, unsigned long rate,
-                                   unsigned long parent_rate);
-       int             (*set_rate_and_parent)(struct clk_hw *hw,
index e3797cfb710ca99275ccbe382c5f9f405d00ca67..70926143ec72655ae170e78b8a567a3bb74fa3b6 100644 (file)
@@ -1,7 +1,19 @@
-From f044ffe2d612dcaa2de36c918aaab79c8db1482e Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:21 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,03/12] clk: qcom: Add support for High-Frequency PLLs (HFPLLs)
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102083
+Message-Id: <1512726150-7204-4-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:21 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:24 -0700
-Subject: [PATCH 38/69] clk: qcom: Add support for High-Frequency PLLs (HFPLLs)
 
 HFPLLs are the main frequency source for Krait CPU clocks. Add
 support for changing the rate of these PLLs.
@@ -105,7 +117,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +       * H/W requires a 5us delay between disabling the bypass and
 +       * de-asserting the reset. Delay 10us just to be safe.
 +       */
-+      udelay(10);
++      usleep_range(10, 100);
 +
 +      /* De-assert active-low PLL reset. */
 +      regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N);
@@ -116,7 +128,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +                      regmap_read(regmap, hd->status_reg, &val);
 +              } while (!(val & BIT(hd->lock_bit)));
 +      } else {
-+              udelay(60);
++              usleep_range(60, 100);
 +      }
 +
 +      /* Enable PLL output. */
@@ -151,7 +163,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +       * and assert the reset.
 +       */
 +      regmap_update_bits(regmap, hd->mode_reg,
-+                      PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0);
++                         PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0);
 +}
 +
 +static void clk_hfpll_disable(struct clk_hw *hw)
@@ -252,7 +264,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +              regmap_read(regmap, hd->status_reg, &status);
 +              if (!(status & BIT(hd->lock_bit))) {
 +                      WARN(1, "HFPLL %s is ON, but not locked!\n",
-+                                      __clk_get_name(hw->clk));
++                           __clk_get_name(hw->clk));
 +                      clk_hfpll_disable(hw);
 +                      __clk_hfpll_init_once(hw);
 +              }
index 92266f763a4dd65c8f58b9bf53fefa65679564bb..d9ad391d02f09c71fa2d5201b8cc77d48aaf5933 100644 (file)
@@ -1,7 +1,19 @@
-From 23f680d03e5894f494572a5162d21328bd86890c Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:22 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,04/12] clk: qcom: Add HFPLL driver
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102079
+Message-Id: <1512726150-7204-5-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:22 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:25 -0700
-Subject: [PATCH 39/69] clk: qcom: Add HFPLL driver
 
 On some devices (MSM8974 for example), the HFPLLs are
 instantiated within the Krait processor subsystem as separate
@@ -10,7 +22,6 @@ provide HFPLL clocks for use by the system.
 
 Cc: <devicetree@vger.kernel.org>
 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
 ---
  .../devicetree/bindings/clock/qcom,hfpll.txt       |  40 ++++++++
  drivers/clk/qcom/Kconfig                           |   8 ++
@@ -171,7 +182,7 @@ Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
 +              return PTR_ERR(regmap);
 +
 +      if (of_property_read_string_index(dev->of_node, "clock-output-names",
-+                                                0, &init.name))
++                                        0, &init.name))
 +              return -ENODEV;
 +
 +      h->d = &hdata;
index 8a51af79dfffb1a03a2d3a210a539bdae39bc0fb..c3af0fa55ccb438f253a02ffb43597bf9a138c70 100644 (file)
@@ -1,14 +1,26 @@
-From 0dfdf84ee3982e88a62123b3de1c094d2c0829af Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:24 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,06/12] clk: qcom: Add IPQ806X's HFPLLs
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102047
+Message-Id: <1512726150-7204-7-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:24 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:27 -0700
-Subject: [PATCH 40/69] clk: qcom: Add IPQ806X's HFPLLs
 
 Describe the HFPLLs present on IPQ806X devices.
 
 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 ---
- drivers/clk/qcom/gcc-ipq806x.c | 83 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 83 insertions(+)
+ drivers/clk/qcom/gcc-ipq806x.c | 82 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 82 insertions(+)
 
 --- a/drivers/clk/qcom/gcc-ipq806x.c
 +++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -20,7 +32,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  #include "reset.h"
  
  static struct clk_pll pll0 = {
-@@ -113,6 +114,85 @@ static struct clk_regmap pll8_vote = {
+@@ -113,6 +114,84 @@ static struct clk_regmap pll8_vote = {
        },
  };
  
@@ -101,12 +113,11 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +      },
 +      .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
 +};
-+
 +
  static struct clk_pll pll14 = {
        .l_reg = 0x31c4,
        .m_reg = 0x31c8,
-@@ -2801,6 +2881,9 @@ static struct clk_regmap *gcc_ipq806x_cl
+@@ -2801,6 +2880,9 @@ static struct clk_regmap *gcc_ipq806x_cl
        [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
        [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
        [NSSTCM_CLK] = &nss_tcm_clk.clkr,
index 902e49d60cb221e2ce3993c787fa89a8954d7329..a6d0f0d7a6d39ff4e26b3ff03cf5ea434ac7f298 100644 (file)
@@ -1,7 +1,19 @@
-From b9747125a8e7633ed2701a70e32dbb0442193774 Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:25 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,07/12] clk: qcom: Add support for Krait clocks
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102051
+Message-Id: <1512726150-7204-8-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:25 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:28 -0700
-Subject: [PATCH 41/69] clk: qcom: Add support for Krait clocks
 
 The Krait clocks are made up of a series of muxes and a divider
 that choose between a fixed rate clock and dedicated HFPLLs for
@@ -13,9 +25,9 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 ---
  drivers/clk/qcom/Kconfig     |   4 ++
  drivers/clk/qcom/Makefile    |   1 +
- drivers/clk/qcom/clk-krait.c | 167 +++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-krait.h |  4+++++++++++++
- 4 files changed, 221 insertions(+)
+ drivers/clk/qcom/clk-krait.c | 134 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/clk/qcom/clk-krait.h |  48 ++++++++++++++++
+ 4 files changed, 187 insertions(+)
  create mode 100644 drivers/clk/qcom/clk-krait.c
  create mode 100644 drivers/clk/qcom/clk-krait.h
 
@@ -41,7 +53,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
 --- /dev/null
 +++ b/drivers/clk/qcom/clk-krait.c
-@@ -0,0 +1,167 @@
+@@ -0,0 +1,134 @@
 +/*
 + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 + *
@@ -103,6 +115,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +      /* Don't touch mux if CPU is off as it won't work */
 +      if (__clk_is_enabled(hw->clk))
 +              __krait_mux_set_sel(mux, sel);
++
 +      return 0;
 +}
 +
@@ -119,44 +132,10 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +      return clk_mux_get_parent(hw, sel, mux->parent_map, 0);
 +}
 +
-+static struct clk_hw *krait_mux_get_safe_parent(struct clk_hw *hw,
-+                                              unsigned long *safe_freq)
-+{
-+      int i;
-+      struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+      int num_parents = clk_hw_get_num_parents(hw);
-+
-+      i = mux->safe_sel;
-+      for (i = 0; i < num_parents; i++)
-+              if (mux->safe_sel == mux->parent_map[i])
-+                      break;
-+
-+      return clk_hw_get_parent_by_index(hw, i);
-+}
-+
-+static int krait_mux_enable(struct clk_hw *hw)
-+{
-+      struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+
-+      __krait_mux_set_sel(mux, mux->en_mask);
-+
-+      return 0;
-+}
-+
-+static void krait_mux_disable(struct clk_hw *hw)
-+{
-+      struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+
-+      __krait_mux_set_sel(mux, mux->safe_sel);
-+}
-+
 +const struct clk_ops krait_mux_clk_ops = {
-+      .enable = krait_mux_enable,
-+      .disable = krait_mux_disable,
 +      .set_parent = krait_mux_set_parent,
 +      .get_parent = krait_mux_get_parent,
 +      .determine_rate = __clk_mux_determine_rate_closest,
-+      .get_safe_parent = krait_mux_get_safe_parent,
 +};
 +EXPORT_SYMBOL_GPL(krait_mux_clk_ops);
 +
@@ -169,7 +148,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +}
 +
 +static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
-+                      unsigned long parent_rate)
++                             unsigned long parent_rate)
 +{
 +      struct krait_div2_clk *d = to_krait_div2_clk(hw);
 +      unsigned long flags;
@@ -211,7 +190,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +EXPORT_SYMBOL_GPL(krait_div2_clk_ops);
 --- /dev/null
 +++ b/drivers/clk/qcom/clk-krait.h
-@@ -0,0 +1,49 @@
+@@ -0,0 +1,48 @@
 +/*
 + * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 + *
@@ -232,8 +211,6 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +
 +struct krait_mux_clk {
 +      unsigned int    *parent_map;
-+      bool            has_safe_parent;
-+      u8              safe_sel;
 +      u32             offset;
 +      u32             mask;
 +      u32             shift;
@@ -241,6 +218,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +      bool            lpl;
 +
 +      struct clk_hw   hw;
++      struct notifier_block   clk_nb;
 +};
 +
 +#define to_krait_mux_clk(_hw) container_of(_hw, struct krait_mux_clk, hw)
index c499436478d1f35d3a5bbce961b47a2e7dadf46b..5a76fbc8b6d5e629cc4087c5d31f48735d0d1599 100644 (file)
@@ -1,7 +1,19 @@
-From 6039eb63fabdd6871fc70940aa98102665c78eed Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:26 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,08/12] clk: qcom: Add KPSS ACC/GCC driver
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102023
+Message-Id: <1512726150-7204-9-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:26 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:29 -0700
-Subject: [PATCH 42/69] clk: qcom: Add KPSS ACC/GCC driver
 
 The ACC and GCC regions present in KPSSv1 contain registers to
 control clocks and power to each Krait CPU and L2. For CPUfreq
@@ -15,8 +27,8 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  .../devicetree/bindings/arm/msm/qcom,kpss-gcc.txt  | 28 +++++++
  drivers/clk/qcom/Kconfig                           |  8 ++
  drivers/clk/qcom/Makefile                          |  1 +
- drivers/clk/qcom/kpss-xcc.c                        | 95 ++++++++++++++++++++++
- 5 files changed, 139 insertions(+)
+ drivers/clk/qcom/kpss-xcc.c                        | 96 ++++++++++++++++++++++
+ 5 files changed, 140 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt
  create mode 100644 drivers/clk/qcom/kpss-xcc.c
 
@@ -98,7 +110,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
 --- /dev/null
 +++ b/drivers/clk/qcom/kpss-xcc.c
-@@ -0,0 +1,95 @@
+@@ -0,0 +1,96 @@
 +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 + *
 + * This program is free software; you can redistribute it and/or modify
@@ -158,7 +170,8 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +
 +      if (id->data) {
 +              if (of_property_read_string_index(pdev->dev.of_node,
-+                                      "clock-output-names", 0, &name))
++                                                "clock-output-names",
++                                                0, &name))
 +                      return -ENODEV;
 +              base += 0x14;
 +      } else {
index 7e2e41e3bbee718ae85b6c9ef43125028dcc7cff..1d32b2b05d92a6be29c7acd9911f5ba9439f60d9 100644 (file)
@@ -1,7 +1,19 @@
-From 7fb5976eb0231a06f484a6bde5e5fbfee7ee4f4a Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:27 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,09/12] clk: qcom: Add Krait clock controller driver
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102061
+Message-Id: <1512726150-7204-10-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:27 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:30 -0700
-Subject: [PATCH 43/69] clk: qcom: Add Krait clock controller driver
 
 The Krait CPU clocks are made up of a primary mux and secondary
 mux for each CPU and the L2, controlled via cp15 accessors. For
@@ -15,8 +27,8 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  .../devicetree/bindings/clock/qcom,krait-cc.txt    |  22 ++
  drivers/clk/qcom/Kconfig                           |   8 +
  drivers/clk/qcom/Makefile                          |   1 +
- drivers/clk/qcom/krait-cc.c                        | 352 +++++++++++++++++++++
- 4 files changed, 383 insertions(+)
+ drivers/clk/qcom/krait-cc.c                        | 350 +++++++++++++++++++++
+ 4 files changed, 381 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/clock/qcom,krait-cc.txt
  create mode 100644 drivers/clk/qcom/krait-cc.c
 
@@ -71,7 +83,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +obj-$(CONFIG_KRAITCC) += krait-cc.o
 --- /dev/null
 +++ b/drivers/clk/qcom/krait-cc.c
-@@ -0,0 +1,352 @@
+@@ -0,0 +1,350 @@
 +/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 + *
 + * This program is free software; you can redistribute it and/or modify
@@ -110,7 +122,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +};
 +
 +static int
-+krait_add_div(struct device *dev, int id, const char *s, unsigned offset)
++krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
 +{
 +      struct krait_div2_clk *div;
 +      struct clk_init_data init = {
@@ -150,8 +162,8 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +}
 +
 +static int
-+krait_add_sec_mux(struct device *dev, int id, const char *s, unsigned offset,
-+                bool unique_aux)
++krait_add_sec_mux(struct device *dev, int id, const char *s,
++                unsigned int offset, bool unique_aux)
 +{
 +      struct krait_mux_clk *mux;
 +      static const char *sec_mux_list[] = {
@@ -172,8 +184,6 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +
 +      mux->offset = offset;
 +      mux->lpl = id >= 0;
-+      mux->has_safe_parent = true;
-+      mux->safe_sel = 2;
 +      mux->mask = 0x3;
 +      mux->shift = 2;
 +      mux->parent_map = sec_mux_map;
@@ -201,7 +211,8 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +}
 +
 +static struct clk *
-+krait_add_pri_mux(struct device *dev, int id, const char *s, unsigned offset)
++krait_add_pri_mux(struct device *dev, int id, const char *s,
++                unsigned int offset)
 +{
 +      struct krait_mux_clk *mux;
 +      const char *p_names[3];
@@ -217,8 +228,6 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +      if (!mux)
 +              return ERR_PTR(-ENOMEM);
 +
-+      mux->has_safe_parent = true;
-+      mux->safe_sel = 0;
 +      mux->mask = 0x3;
 +      mux->shift = 0;
 +      mux->offset = offset;
@@ -264,7 +273,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
 +{
 +      int ret;
-+      unsigned offset;
++      unsigned int offset;
 +      void *p = NULL;
 +      const char *s;
 +      struct clk *clk;
@@ -332,7 +341,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +              return -ENODEV;
 +
 +      /* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */
-+      clk = clk_register_fixed_rate(dev, "qsb", NULL, CLK_IS_ROOT, 1);
++      clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1);
 +      if (IS_ERR(clk))
 +              return PTR_ERR(clk);
 +
@@ -370,7 +379,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +      for_each_online_cpu(cpu) {
 +              clk_prepare_enable(l2_pri_mux_clk);
 +              WARN(clk_prepare_enable(clks[cpu]),
-+                      "Unable to turn on CPU%d clock", cpu);
++                   "Unable to turn on CPU%d clock", cpu);
 +      }
 +
 +      /*
@@ -401,6 +410,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +                      pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu);
 +                      cur_rate = aux_rate;
 +              }
++
 +              clk_set_rate(clk, aux_rate);
 +              clk_set_rate(clk, 2);
 +              clk_set_rate(clk, cur_rate);
diff --git a/target/linux/ipq806x/patches-4.9/0044-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches-4.9/0044-clk-Add-safe-switch-hook.patch
new file mode 100644 (file)
index 0000000..d0eddc6
--- /dev/null
@@ -0,0 +1,160 @@
+From patchwork Fri Dec  8 09:42:28 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,10/12] clk: qcom: Add safe switch hook for krait mux clocks
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102057
+Message-Id: <1512726150-7204-11-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:28 +0530
+
+When the Hfplls are reprogrammed during the rate change,
+the primary muxes which are sourced from the same hfpll
+for higher frequencies, needs to be switched to the 'safe
+secondary mux' as the parent for that small window. This
+is done by registering a clk notifier for the muxes and
+switching to the safe parent in the PRE_RATE_CHANGE notifier
+and back to the original parent in the POST_RATE_CHANGE notifier.
+
+Signed-off-by: Sricharan R <sricharan@codeaurora.org>
+---
+ drivers/clk/qcom/clk-krait.c |  2 ++
+ drivers/clk/qcom/clk-krait.h |  3 +++
+ drivers/clk/qcom/krait-cc.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 61 insertions(+)
+
+--- a/drivers/clk/qcom/clk-krait.c
++++ b/drivers/clk/qcom/clk-krait.c
+@@ -60,6 +60,8 @@ static int krait_mux_set_parent(struct c
+       if (__clk_is_enabled(hw->clk))
+               __krait_mux_set_sel(mux, sel);
++      mux->reparent = true;
++
+       return 0;
+ }
+--- a/drivers/clk/qcom/clk-krait.h
++++ b/drivers/clk/qcom/clk-krait.h
+@@ -23,6 +23,9 @@ struct krait_mux_clk {
+       u32             shift;
+       u32             en_mask;
+       bool            lpl;
++      u8              safe_sel;
++      u8              old_index;
++      bool            reparent;
+       struct clk_hw   hw;
+       struct notifier_block   clk_nb;
+--- a/drivers/clk/qcom/krait-cc.c
++++ b/drivers/clk/qcom/krait-cc.c
+@@ -35,6 +35,49 @@ static unsigned int pri_mux_map[] = {
+       0,
+ };
++/*
++ * Notifier function for switching the muxes to safe parent
++ * while the hfpll is getting reprogrammed.
++ */
++static int krait_notifier_cb(struct notifier_block *nb,
++                           unsigned long event,
++                           void *data)
++{
++      int ret = 0;
++      struct krait_mux_clk *mux = container_of(nb, struct krait_mux_clk,
++                                               clk_nb);
++      /* Switch to safe parent */
++      if (event == PRE_RATE_CHANGE) {
++              mux->old_index = krait_mux_clk_ops.get_parent(&mux->hw);
++              ret = krait_mux_clk_ops.set_parent(&mux->hw, mux->safe_sel);
++              mux->reparent = false;
++      /*
++       * By the time POST_RATE_CHANGE notifier is called,
++       * clk framework itself would have changed the parent for the new rate.
++       * Only otherwise, put back to the old parent.
++       */
++      } else if (event == POST_RATE_CHANGE) {
++              if (!mux->reparent)
++                      ret = krait_mux_clk_ops.set_parent(&mux->hw,
++                                                         mux->old_index);
++      }
++
++      return notifier_from_errno(ret);
++}
++
++static int krait_notifier_register(struct device *dev, struct clk *clk,
++                                 struct krait_mux_clk *mux)
++{
++      int ret = 0;
++
++      mux->clk_nb.notifier_call = krait_notifier_cb;
++      ret = clk_notifier_register(clk, &mux->clk_nb);
++      if (ret)
++              dev_err(dev, "failed to register clock notifier: %d\n", ret);
++
++      return ret;
++}
++
+ static int
+ krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
+ {
+@@ -79,6 +122,7 @@ static int
+ krait_add_sec_mux(struct device *dev, int id, const char *s,
+                 unsigned int offset, bool unique_aux)
+ {
++      int ret;
+       struct krait_mux_clk *mux;
+       static const char *sec_mux_list[] = {
+               "acpu_aux",
+@@ -102,6 +146,7 @@ krait_add_sec_mux(struct device *dev, in
+       mux->shift = 2;
+       mux->parent_map = sec_mux_map;
+       mux->hw.init = &init;
++      mux->safe_sel = 0;
+       init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
+       if (!init.name)
+@@ -117,6 +162,11 @@ krait_add_sec_mux(struct device *dev, in
+       clk = devm_clk_register(dev, &mux->hw);
++      ret = krait_notifier_register(dev, clk, mux);
++      if (ret)
++              goto unique_aux;
++
++unique_aux:
+       if (unique_aux)
+               kfree(sec_mux_list[0]);
+ err_aux:
+@@ -128,6 +178,7 @@ static struct clk *
+ krait_add_pri_mux(struct device *dev, int id, const char *s,
+                 unsigned int offset)
+ {
++      int ret;
+       struct krait_mux_clk *mux;
+       const char *p_names[3];
+       struct clk_init_data init = {
+@@ -148,6 +199,7 @@ krait_add_pri_mux(struct device *dev, in
+       mux->lpl = id >= 0;
+       mux->parent_map = pri_mux_map;
+       mux->hw.init = &init;
++      mux->safe_sel = 2;
+       init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s);
+       if (!init.name)
+@@ -173,6 +225,10 @@ krait_add_pri_mux(struct device *dev, in
+       clk = devm_clk_register(dev, &mux->hw);
++      ret = krait_notifier_register(dev, clk, mux);
++      if (ret)
++              goto err_p3;
++err_p3:
+       kfree(p_names[2]);
+ err_p2:
+       kfree(p_names[1]);
diff --git a/target/linux/ipq806x/patches-4.9/0044-clk-qcom-krait-Remove-CLK_IS_ROOT.patch b/target/linux/ipq806x/patches-4.9/0044-clk-qcom-krait-Remove-CLK_IS_ROOT.patch
deleted file mode 100644 (file)
index c3761ee..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-From 58f8215f1d9397f9130657cc2c15a956bd99210e Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <georgi.djakov@linaro.org>
-Date: Wed, 13 Jul 2016 15:22:25 +0300
-Subject: [PATCH 44/69] clk: qcom: krait: Remove CLK_IS_ROOT
-
-The flag CLK_IS_ROOT is no-op now. Remove it.
-
-Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
----
- drivers/clk/qcom/krait-cc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/krait-cc.c
-+++ b/drivers/clk/qcom/krait-cc.c
-@@ -258,7 +258,7 @@ static int krait_cc_probe(struct platfor
-               return -ENODEV;
-       /* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */
--      clk = clk_register_fixed_rate(dev, "qsb", NULL, CLK_IS_ROOT, 1);
-+      clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
index f5b5ea0fdbc8c0fe21c4bd73b782e342d9048335..820d13f3c9d500c7d0c829885efe1771cba753c8 100644 (file)
@@ -1,7 +1,19 @@
-From 42eea6bc2858ab9649cf6931455e391e48939685 Mon Sep 17 00:00:00 2001
+From patchwork Fri Dec  8 09:42:29 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,11/12] cpufreq: Add module to register cpufreq on Krait CPUs
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102075
+Message-Id: <1512726150-7204-12-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:29 +0530
+
 From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:31 -0700
-Subject: [PATCH 45/69] cpufreq: Add module to register cpufreq on Krait CPUs
 
 Register a cpufreq-generic device whenever we detect that a
 "qcom,krait" compatible CPU is present in DT.
@@ -111,7 +123,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +#include <linux/platform_device.h>
 +#include <linux/pm_opp.h>
 +#include <linux/slab.h>
-+#include <linux/cpufreq-dt.h>
++#include "cpufreq-dt.h"
 +
 +static void __init get_krait_bin_format_a(int *speed, int *pvs, int *pvs_ver)
 +{
@@ -227,7 +239,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
 +      }
 +
 +      snprintf(table_name, sizeof(table_name),
-+                      "qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver);
++               "qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver);
 +
 +      if (!of_find_property(np, table_name, &len))
 +              return -EINVAL;
index 8d2861ce9eeae53c40bb2620b33704ce89d5174f..d767dbf5f04e9de361912e19d1ade697eed0dd6b 100644 (file)
@@ -1,25 +1,31 @@
-ipq806x: support independent core clocks with kernel 4.9+
+From patchwork Fri Dec  8 09:42:30 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v4,12/12] cpufreq: dt: Reintroduce independent_clocks platform data
+From: Sricharan R <sricharan@codeaurora.org>
+X-Patchwork-Id: 10102073
+Message-Id: <1512726150-7204-13-git-send-email-sricharan@codeaurora.org>
+To: mturquette@baylibre.com, sboyd@codeaurora.org,
+ devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
+ linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
+ viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
+Cc: sricharan@codeaurora.org
+Date: Fri,  8 Dec 2017 15:12:30 +0530
 
-Add back support for the independent_clocks definition that has been
-removed between kernel 4.4 and 4.9 by upstream commits
-eb96924acddc709db58221c210ca05cd9effb1df and
-e86eee6bc2aaa6b3637f6497b26beee09a91bde9
+The Platform data was removed earlier by,
+'commit eb96924acddc ("cpufreq: dt: Kill platform-data")'
+since there were no users at that time.
+Now this is required when the each of the cpu clocks
+can be scaled independently, which is the case
+for krait cores. So reintroduce it.
 
-* extend the new cpufreq_dt_platform_data definition in cpufreq-dt.h
-* use new cpufreq-dt.h in qcom-cpufreq.c
+Signed-off-by: Sricharan R <sricharan@codeaurora.org>
+---
+ drivers/cpufreq/cpufreq-dt.c | 7 ++++++-
+ drivers/cpufreq/cpufreq-dt.h | 6 ++++++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
 
-Signed-off-by: Hannu Nyman <hannu.nyman@iki.fi>
-
---- a/drivers/cpufreq/cpufreq-dt.h
-+++ b/drivers/cpufreq/cpufreq-dt.h
-@@ -14,6 +14,7 @@
- struct cpufreq_dt_platform_data {
-       bool have_governor_per_policy;
-+      bool independent_clocks;
- };
- #endif /* __CPUFREQ_DT_H__ */
 --- a/drivers/cpufreq/cpufreq-dt.c
 +++ b/drivers/cpufreq/cpufreq-dt.c
 @@ -221,7 +221,10 @@ static int cpufreq_init(struct cpufreq_p
@@ -38,19 +44,23 @@ Signed-off-by: Hannu Nyman <hannu.nyman@iki.fi>
        if (data && data->have_governor_per_policy)
                dt_cpufreq_driver.flags |= CPUFREQ_HAVE_GOVERNOR_PER_POLICY;
  
-+      dt_cpufreq_driver.driver_data = dev_get_platdata(&pdev->dev);
++      dt_cpufreq_driver.driver_data = data;
 +
        ret = cpufreq_register_driver(&dt_cpufreq_driver);
        if (ret)
                dev_err(&pdev->dev, "failed register driver: %d\n", ret);
---- a/drivers/cpufreq/qcom-cpufreq.c
-+++ b/drivers/cpufreq/qcom-cpufreq.c
-@@ -20,7 +20,7 @@
- #include <linux/platform_device.h>
- #include <linux/pm_opp.h>
- #include <linux/slab.h>
--#include <linux/cpufreq-dt.h>
-+#include "cpufreq-dt.h"
+--- a/drivers/cpufreq/cpufreq-dt.h
++++ b/drivers/cpufreq/cpufreq-dt.h
+@@ -13,6 +13,12 @@
+ #include <linux/types.h>
+ struct cpufreq_dt_platform_data {
++      /*
++       * True when each CPU has its own clock to control its
++       * frequency, false when all CPUs are controlled by a single
++       * clock.
++       */
++      bool independent_clocks;
+       bool have_governor_per_policy;
+ };
  
- static void __init get_krait_bin_format_a(int *speed, int *pvs, int *pvs_ver)
- {
diff --git a/target/linux/ipq806x/patches-4.9/0057-clk-qcom-Add-regmap-mux-div-clocks-support.patch b/target/linux/ipq806x/patches-4.9/0057-clk-qcom-Add-regmap-mux-div-clocks-support.patch
deleted file mode 100644 (file)
index c5cdc79..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-From f72c5aa18281c44945fea6181d0d816a7605505c Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <georgi.djakov@linaro.org>
-Date: Wed, 18 Mar 2015 17:23:29 +0200
-Subject: [PATCH 57/69] clk: qcom: Add regmap mux-div clocks support
-
-Add support for hardware that can switch both parent clocks and divider
-at the same time. This avoids generating intermediate frequencies from
-either the old parent clock and new divider or new parent clock and
-old divider combinations.
-
-Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
----
- drivers/clk/qcom/Makefile             |   1 +
- drivers/clk/qcom/clk-regmap-mux-div.c | 272 ++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-regmap-mux-div.h |  65 ++++++++
- 3 files changed, 338 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-regmap-mux-div.c
- create mode 100644 drivers/clk/qcom/clk-regmap-mux-div.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -9,6 +9,7 @@ clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-regmap-divider.o
- clk-qcom-y += clk-regmap-mux.o
-+clk-qcom-y += clk-regmap-mux-div.o
- clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
- clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-regmap-mux-div.c
-@@ -0,0 +1,272 @@
-+/*
-+ * Copyright (c) 2015, Linaro Limited
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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.
-+ */
-+
-+#include <linux/bitops.h>
-+#include <linux/delay.h>
-+#include <linux/export.h>
-+#include <linux/kernel.h>
-+#include <linux/regmap.h>
-+
-+#include "clk-regmap-mux-div.h"
-+
-+#define CMD_RCGR                      0x0
-+#define CMD_RCGR_UPDATE                       BIT(0)
-+#define CMD_RCGR_DIRTY_CFG            BIT(4)
-+#define CMD_RCGR_ROOT_OFF             BIT(31)
-+#define CFG_RCGR                      0x4
-+
-+#define to_clk_regmap_mux_div(_hw) \
-+      container_of(to_clk_regmap(_hw), struct clk_regmap_mux_div, clkr)
-+
-+int __mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div)
-+{
-+      int ret, count;
-+      u32 val, mask;
-+      const char *name = clk_hw_get_name(&md->clkr.hw);
-+
-+      val = (div << md->hid_shift) | (src << md->src_shift);
-+      mask = ((BIT(md->hid_width) - 1) << md->hid_shift) |
-+             ((BIT(md->src_width) - 1) << md->src_shift);
-+
-+      ret = regmap_update_bits(md->clkr.regmap, CFG_RCGR + md->reg_offset,
-+                               mask, val);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_update_bits(md->clkr.regmap, CMD_RCGR + md->reg_offset,
-+                               CMD_RCGR_UPDATE, CMD_RCGR_UPDATE);
-+      if (ret)
-+              return ret;
-+
-+      /* Wait for update to take effect */
-+      for (count = 500; count > 0; count--) {
-+              ret = regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset,
-+                                &val);
-+              if (ret)
-+                      return ret;
-+              if (!(val & CMD_RCGR_UPDATE))
-+                      return 0;
-+              udelay(1);
-+      }
-+
-+      pr_err("%s: RCG did not update its configuration", name);
-+      return -EBUSY;
-+}
-+
-+static void __mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src,
-+                                u32 *div)
-+{
-+      u32 val, __div, __src;
-+      const char *name = clk_hw_get_name(&md->clkr.hw);
-+
-+      regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val);
-+
-+      if (val & CMD_RCGR_DIRTY_CFG) {
-+              pr_err("%s: RCG configuration is pending\n", name);
-+              return;
-+      }
-+
-+      regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val);
-+      __src = (val >> md->src_shift);
-+      __src &= BIT(md->src_width) - 1;
-+      *src = __src;
-+
-+      __div = (val >> md->hid_shift);
-+      __div &= BIT(md->hid_width) - 1;
-+      *div = __div;
-+}
-+
-+static int mux_div_enable(struct clk_hw *hw)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+      return __mux_div_set_src_div(md, md->src, md->div);
-+}
-+
-+static inline bool is_better_rate(unsigned long req, unsigned long best,
-+                                unsigned long new)
-+{
-+      return (req <= new && new < best) || (best < req && best < new);
-+}
-+
-+static int mux_div_determine_rate(struct clk_hw *hw,
-+                                struct clk_rate_request *req)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+      unsigned int i, div, max_div;
-+      unsigned long actual_rate, best_rate = 0;
-+      unsigned long req_rate = req->rate;
-+
-+      for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
-+              struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
-+              unsigned long parent_rate = clk_hw_get_rate(parent);
-+
-+              max_div = BIT(md->hid_width) - 1;
-+              for (div = 1; div < max_div; div++) {
-+                      parent_rate = mult_frac(req_rate, div, 2);
-+                      parent_rate = clk_hw_round_rate(parent, parent_rate);
-+                      actual_rate = mult_frac(parent_rate, 2, div);
-+
-+                      if (is_better_rate(req_rate, best_rate, actual_rate)) {
-+                              best_rate = actual_rate;
-+                              req->rate = best_rate;
-+                              req->best_parent_rate = parent_rate;
-+                              req->best_parent_hw = parent;
-+                      }
-+
-+                      if (actual_rate < req_rate || best_rate <= req_rate)
-+                              break;
-+              }
-+      }
-+
-+      if (!best_rate)
-+              return -EINVAL;
-+
-+      return 0;
-+}
-+
-+static int __mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
-+                                       unsigned long prate, u32 src)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+      int ret;
-+      u32 div, max_div, best_src = 0, best_div = 0;
-+      unsigned int i;
-+      unsigned long actual_rate, best_rate = 0;
-+
-+      for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
-+              struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
-+              unsigned long parent_rate = clk_hw_get_rate(parent);
-+
-+              max_div = BIT(md->hid_width) - 1;
-+              for (div = 1; div < max_div; div++) {
-+                      parent_rate = mult_frac(rate, div, 2);
-+                      parent_rate = clk_hw_round_rate(parent, parent_rate);
-+                      actual_rate = mult_frac(parent_rate, 2, div);
-+
-+                      if (is_better_rate(rate, best_rate, actual_rate)) {
-+                              best_rate = actual_rate;
-+                              best_src = md->parent_map[i].cfg;
-+                              best_div = div - 1;
-+                      }
-+
-+                      if (actual_rate < rate || best_rate <= rate)
-+                              break;
-+              }
-+      }
-+
-+      ret = __mux_div_set_src_div(md, best_src, best_div);
-+      if (!ret) {
-+              md->div = best_div;
-+              md->src = best_src;
-+      }
-+
-+      return ret;
-+}
-+
-+static u8 mux_div_get_parent(struct clk_hw *hw)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+      const char *name = clk_hw_get_name(hw);
-+      u32 i, div, src = 0;
-+
-+      __mux_div_get_src_div(md, &src, &div);
-+
-+      for (i = 0; i < clk_hw_get_num_parents(hw); i++)
-+              if (src == md->parent_map[i].cfg)
-+                      return i;
-+
-+      pr_err("%s: Can't find parent with src %d\n", name, src);
-+      return 0;
-+}
-+
-+static int mux_div_set_parent(struct clk_hw *hw, u8 index)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+      return __mux_div_set_src_div(md, md->parent_map[index].cfg, md->div);
-+}
-+
-+static int mux_div_set_rate(struct clk_hw *hw,
-+                          unsigned long rate, unsigned long prate)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+      return __mux_div_set_rate_and_parent(hw, rate, prate, md->src);
-+}
-+
-+static int mux_div_set_rate_and_parent(struct clk_hw *hw,  unsigned long rate,
-+                                     unsigned long prate, u8 index)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+      return __mux_div_set_rate_and_parent(hw, rate, prate,
-+                                           md->parent_map[index].cfg);
-+}
-+
-+static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+      u32 div, src;
-+      int i, num_parents = clk_hw_get_num_parents(hw);
-+      const char *name = clk_hw_get_name(hw);
-+
-+      __mux_div_get_src_div(md, &src, &div);
-+      for (i = 0; i < num_parents; i++)
-+              if (src == md->parent_map[i].cfg) {
-+                      struct clk_hw *p = clk_hw_get_parent_by_index(hw, i);
-+                      unsigned long parent_rate = clk_hw_get_rate(p);
-+
-+                      return mult_frac(parent_rate, 2, div + 1);
-+              }
-+
-+      pr_err("%s: Can't find parent %d\n", name, src);
-+      return 0;
-+}
-+
-+static struct clk_hw *mux_div_get_safe_parent(struct clk_hw *hw,
-+                                            unsigned long *safe_freq)
-+{
-+      int i;
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+      if (md->safe_freq)
-+              *safe_freq = md->safe_freq;
-+
-+      for (i = 0; i < clk_hw_get_num_parents(hw); i++)
-+              if (md->safe_src == md->parent_map[i].cfg)
-+                      break;
-+
-+      return clk_hw_get_parent_by_index(hw, i);
-+}
-+
-+static void mux_div_disable(struct clk_hw *hw)
-+{
-+      struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+      __mux_div_set_src_div(md, md->safe_src, md->safe_div);
-+}
-+
-+const struct clk_ops clk_regmap_mux_div_ops = {
-+      .enable = mux_div_enable,
-+      .disable = mux_div_disable,
-+      .get_parent = mux_div_get_parent,
-+      .set_parent = mux_div_set_parent,
-+      .set_rate = mux_div_set_rate,
-+      .set_rate_and_parent = mux_div_set_rate_and_parent,
-+      .determine_rate = mux_div_determine_rate,
-+      .recalc_rate = mux_div_recalc_rate,
-+      .get_safe_parent = mux_div_get_safe_parent,
-+};
-+EXPORT_SYMBOL_GPL(clk_regmap_mux_div_ops);
---- /dev/null
-+++ b/drivers/clk/qcom/clk-regmap-mux-div.h
-@@ -0,0 +1,65 @@
-+/*
-+ * Copyright (c) 2015, Linaro Limited
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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 __QCOM_CLK_REGMAP_MUX_DIV_H__
-+#define __QCOM_CLK_REGMAP_MUX_DIV_H__
-+
-+#include <linux/clk-provider.h>
-+#include "clk-rcg.h"
-+#include "clk-regmap.h"
-+
-+/**
-+ * struct mux_div_clk - combined mux/divider clock
-+ * @reg_offset: offset of the mux/divider register
-+ * @hid_width:        number of bits in half integer divider
-+ * @hid_shift:        lowest bit of hid value field
-+ * @src_width:        number of bits in source select
-+ * @src_shift:        lowest bit of source select field
-+ * @div:      the divider raw configuration value
-+ * @src:      the mux index which will be used if the clock is enabled
-+ * @safe_src: the safe source mux value we switch to, while the main PLL is
-+ *            reconfigured
-+ * @safe_div: the safe divider value that we set, while the main PLL is
-+ *            reconfigured
-+ * @safe_freq:        When switching rates from A to B, the mux div clock will
-+ *            instead switch from A -> safe_freq -> B. This allows the
-+ *            mux_div clock to change rates while enabled, even if this
-+ *            behavior is not supported by the parent clocks.
-+ *            If changing the rate of parent A also causes the rate of
-+ *            parent B to change, then safe_freq must be defined.
-+ *            safe_freq is expected to have a source clock which is always
-+ *            on and runs at only one rate.
-+ * @parent_map:       pointer to parent_map struct
-+ * @clkr:     handle between common and hardware-specific interfaces
-+ */
-+
-+struct clk_regmap_mux_div {
-+      u32                             reg_offset;
-+      u32                             hid_width;
-+      u32                             hid_shift;
-+      u32                             src_width;
-+      u32                             src_shift;
-+      u32                             div;
-+      u32                             src;
-+      u32                             safe_src;
-+      u32                             safe_div;
-+      unsigned long                   safe_freq;
-+      const struct parent_map         *parent_map;
-+      struct clk_regmap               clkr;
-+};
-+
-+extern const struct clk_ops clk_regmap_mux_div_ops;
-+int __mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div);
-+
-+#endif
index a3e0a1dc5d00ebd80bc065d804d73518c11cf568..717934315aad276a4ec9bd9f71808c5fc030008b 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
 
 --- a/drivers/clk/qcom/gcc-ipq806x.c
 +++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -1234,6 +1234,8 @@ static struct clk_rcg prng_src = {
+@@ -1233,6 +1233,8 @@ static struct clk_rcg prng_src = {
                .parent_map = gcc_pxo_pll8_map,
        },
        .clkr = {