From: Rob Herring <rob.herr...@calxeda.com>

Newer versions of Calxeda PLLs have a different frequency range. Make
the max frequency a variable and add a DT property to handle different
maximum frequencies for the PLLs.

Signed-off-by: Rob Herring <rob.herr...@calxeda.com>
Cc: Mike Turquette <mturque...@linaro.org>
---
 drivers/clk/clk-highbank.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
index dc7ca30..89efcbc 100644
--- a/drivers/clk/clk-highbank.c
+++ b/drivers/clk/clk-highbank.c
@@ -30,7 +30,7 @@
 #define HB_PLL_DIVQ_SHIFT      16
 #define HB_PLL_DIVQ_MASK       0x00070000
 #define HB_PLL_DIVR_SHIFT      8
-#define HB_PLL_DIVR_MASK       0x00001f00
+#define HB_PLL_DIVR_MASK       0x00003f00
 #define HB_PLL_RANGE_SHIFT     4
 #define HB_PLL_RANGE_MASK      0x00000070
 #define HB_PLL_BYPASS          0x00000008
@@ -38,9 +38,7 @@
 #define HB_PLL_EXT_BYPASS      0x00000002
 #define HB_PLL_EXT_ENA         0x00000001
 
-#define HB_PLL_VCO_MIN_FREQ    2133000000
-#define HB_PLL_MAX_FREQ                HB_PLL_VCO_MIN_FREQ
-#define HB_PLL_MIN_FREQ                (HB_PLL_VCO_MIN_FREQ / 64)
+#define HB_PLL_MAX_FREQ                2133000000
 
 #define HB_A9_BCLK_DIV_MASK    0x00000006
 #define HB_A9_BCLK_DIV_SHIFT   1
@@ -49,6 +47,7 @@
 struct hb_clk {
         struct clk_hw  hw;
        void __iomem    *reg;
+       u32 max_freq;
        char *parent_name;
 };
 #define to_hb_clk(p) container_of(p, struct hb_clk, hw)
@@ -119,19 +118,21 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw 
*hwclk,
        return vco_freq / (1 << divq);
 }
 
-static void clk_pll_calc(unsigned long rate, unsigned long ref_freq,
+static void clk_pll_calc(struct clk_hw *hwclk, unsigned long rate,
+                       unsigned long ref_freq,
                        u32 *pdivq, u32 *pdivf)
 {
+       u32 pll_max_freq = to_hb_clk(hwclk)->max_freq;
        u32 divq, divf;
        unsigned long vco_freq;
 
-       if (rate < HB_PLL_MIN_FREQ)
-               rate = HB_PLL_MIN_FREQ;
-       if (rate > HB_PLL_MAX_FREQ)
-               rate = HB_PLL_MAX_FREQ;
+       if (rate < (pll_max_freq / 64))
+               rate = pll_max_freq / 64;
+       if (rate > pll_max_freq)
+               rate = pll_max_freq;
 
        for (divq = 1; divq <= 6; divq++) {
-               if ((rate * (1 << divq)) >= HB_PLL_VCO_MIN_FREQ)
+               if ((rate * (1 << divq)) >= pll_max_freq)
                        break;
        }
 
@@ -149,7 +150,7 @@ static long clk_pll_round_rate(struct clk_hw *hwclk, 
unsigned long rate,
        u32 divq, divf;
        unsigned long ref_freq = *parent_rate;
 
-       clk_pll_calc(rate, ref_freq, &divq, &divf);
+       clk_pll_calc(hwclk, rate, ref_freq, &divq, &divf);
 
        return (ref_freq * (divf + 1)) / (1 << divq);
 }
@@ -161,7 +162,7 @@ static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned 
long rate,
        u32 divq, divf;
        u32 reg;
 
-       clk_pll_calc(rate, parent_rate, &divq, &divf);
+       clk_pll_calc(hwclk, rate, parent_rate, &divq, &divf);
 
        reg = readl(hbclk->reg);
        if (divf != ((reg & HB_PLL_DIVF_MASK) >> HB_PLL_DIVF_SHIFT)) {
@@ -304,6 +305,10 @@ static __init struct clk *hb_clk_init(struct device_node 
*node, const struct clk
 
        of_property_read_string(node, "clock-output-names", &clk_name);
 
+       of_property_read_u32(node, "calxeda,pll-max-hz", &hb_clk->max_freq);
+       if (!hb_clk->max_freq)
+               hb_clk->max_freq = HB_PLL_MAX_FREQ;
+
        init.name = clk_name;
        init.ops = ops;
        init.flags = 0;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to