clk: qcom: Add support for SR2 PLLs

Add support for SR2 type pll operations. SR2 is optimized for Time Interval
Error (TIE) or absolute jitter.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
Georgi Djakov 2015-06-12 11:41:55 +03:00 committed by Stephen Boyd
parent a8a8db4799
commit d4f76de374
2 changed files with 76 additions and 0 deletions

View file

@ -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);

View file

@ -62,6 +62,7 @@ struct clk_pll {
extern const struct clk_ops clk_pll_ops;
extern const struct clk_ops clk_pll_vote_ops;
extern const struct clk_ops clk_pll_sr2_ops;
#define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr)