These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / clk / qcom / clk-pll.c
index 245d506..5b940d6 100644 (file)
@@ -135,19 +135,19 @@ struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate)
        return NULL;
 }
 
-static long
-clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate,
-                      unsigned long min_rate, unsigned long max_rate,
-                      unsigned long *p_rate, struct clk_hw **p)
+static int
+clk_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
 {
        struct clk_pll *pll = to_clk_pll(hw);
        const struct pll_freq_tbl *f;
 
-       f = find_freq(pll->freq_tbl, rate);
+       f = find_freq(pll->freq_tbl, req->rate);
        if (!f)
-               return clk_pll_recalc_rate(hw, *p_rate);
+               req->rate = clk_pll_recalc_rate(hw, req->best_parent_rate);
+       else
+               req->rate = f->freq;
 
-       return f->freq;
+       return 0;
 }
 
 static int
@@ -194,7 +194,7 @@ static int wait_for_pll(struct clk_pll *pll)
        u32 val;
        int count;
        int ret;
-       const char *name = __clk_get_name(pll->clkr.hw.clk);
+       const char *name = clk_hw_get_name(&pll->clkr.hw);
 
        /* Wait for pll to enable. */
        for (count = 200; count > 0; count--) {
@@ -213,7 +213,7 @@ static int wait_for_pll(struct clk_pll *pll)
 static int clk_pll_vote_enable(struct clk_hw *hw)
 {
        int ret;
-       struct clk_pll *p = to_clk_pll(__clk_get_hw(__clk_get_parent(hw->clk)));
+       struct clk_pll *p = to_clk_pll(clk_hw_get_parent(hw));
 
        ret = clk_enable_regmap(hw);
        if (ret)
@@ -292,3 +292,78 @@ void clk_pll_configure_sr_hpm_lp(struct clk_pll *pll, struct regmap *regmap,
                clk_pll_set_fsm_mode(pll, regmap, 0);
 }
 EXPORT_SYMBOL_GPL(clk_pll_configure_sr_hpm_lp);
+
+static int clk_pll_sr2_enable(struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       int ret;
+       u32 mode;
+
+       ret = regmap_read(pll->clkr.regmap, pll->mode_reg, &mode);
+       if (ret)
+               return ret;
+
+       /* Disable PLL bypass mode. */
+       ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_BYPASSNL,
+                                PLL_BYPASSNL);
+       if (ret)
+               return ret;
+
+       /*
+        * H/W requires a 5us delay between disabling the bypass and
+        * de-asserting the reset. Delay 10us just to be safe.
+        */
+       udelay(10);
+
+       /* De-assert active-low PLL reset. */
+       ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_RESET_N,
+                                PLL_RESET_N);
+       if (ret)
+               return ret;
+
+       ret = wait_for_pll(pll);
+       if (ret)
+               return ret;
+
+       /* Enable PLL output. */
+       return regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_OUTCTRL,
+                                PLL_OUTCTRL);
+}
+
+static int
+clk_pll_sr2_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       const struct pll_freq_tbl *f;
+       bool enabled;
+       u32 mode;
+       u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N;
+
+       f = find_freq(pll->freq_tbl, rate);
+       if (!f)
+               return -EINVAL;
+
+       regmap_read(pll->clkr.regmap, pll->mode_reg, &mode);
+       enabled = (mode & enable_mask) == enable_mask;
+
+       if (enabled)
+               clk_pll_disable(hw);
+
+       regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, f->l);
+       regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, f->m);
+       regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, f->n);
+
+       if (enabled)
+               clk_pll_sr2_enable(hw);
+
+       return 0;
+}
+
+const struct clk_ops clk_pll_sr2_ops = {
+       .enable = clk_pll_sr2_enable,
+       .disable = clk_pll_disable,
+       .set_rate = clk_pll_sr2_set_rate,
+       .recalc_rate = clk_pll_recalc_rate,
+       .determine_rate = clk_pll_determine_rate,
+};
+EXPORT_SYMBOL_GPL(clk_pll_sr2_ops);