clk: qcom: handle alpha PLLs with 16bit alpha val registers
authorRajendra Nayak <rnayak@codeaurora.org>
Thu, 29 Sep 2016 08:35:44 +0000 (14:05 +0530)
committerStephen Boyd <sboyd@codeaurora.org>
Wed, 2 Nov 2016 01:39:16 +0000 (18:39 -0700)
Some alpha PLLs have support for only a 16bit programable Alpha Value
(as against the default 40bits). Add a flag to handle the 16bit alpha
registers

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/qcom/clk-alpha-pll.c
drivers/clk/qcom/clk-alpha-pll.h

index a1188c8..fd3e32c 100644 (file)
@@ -59,6 +59,7 @@
  */
 #define ALPHA_REG_BITWIDTH     40
 #define ALPHA_BITWIDTH         32
+#define ALPHA_16BIT_MASK       0xffff
 
 #define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \
                                           struct clk_alpha_pll, clkr)
@@ -334,9 +335,14 @@ clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
        regmap_read(pll->clkr.regmap, off + PLL_USER_CTL, &ctl);
        if (ctl & PLL_ALPHA_EN) {
                regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL, &low);
-               regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, &high);
-               a = (u64)high << 32 | low;
-               a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
+               if (pll->flags & SUPPORTS_16BIT_ALPHA) {
+                       a = low & ALPHA_16BIT_MASK;
+               } else {
+                       regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL_U,
+                                   &high);
+                       a = (u64)high << 32 | low;
+                       a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
+               }
        }
 
        return alpha_pll_calc_rate(prate, l, a);
@@ -357,11 +363,15 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
                return -EINVAL;
        }
 
-       a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
-
        regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
-       regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL, a);
-       regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32);
+
+       if (pll->flags & SUPPORTS_16BIT_ALPHA) {
+               regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL,
+                            a & ALPHA_16BIT_MASK);
+       } else {
+               a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+               regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32);
+       }
 
        regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
                           PLL_VCO_MASK << PLL_VCO_SHIFT,
index 2f48530..4808ff7 100644 (file)
@@ -35,6 +35,7 @@ struct clk_alpha_pll {
        const struct pll_vco *vco_table;
        size_t num_vco;
 #define SUPPORTS_OFFLINE_REQ   BIT(0)
+#define SUPPORTS_16BIT_ALPHA   BIT(1)
        u8 flags;
 
        struct clk_regmap clkr;