From 0ef9db6cf24dbb58118818e64198d9a030e4697e Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Thu, 18 Jun 2015 17:28:33 -0400 Subject: [PATCH] clk: tegra: pll: Add logic for SS Add some logic for Spread Spectrum control. It is used in conjuncture with SDM fractional dividers. SSC has to be disabled when we configure the divider settings. Signed-off-by: Bill Huang Signed-off-by: Rhyland Klein Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 25 ++++++++++++++++++++++++- drivers/clk/tegra/clk.h | 4 ++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 8901004025e7..7ef08861c35d 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -658,6 +658,26 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, pll_writel_misc(val, pll); } +static void pll_clk_start_ss(struct tegra_clk_pll *pll) +{ + if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { + u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); + + val |= pll->params->ssc_ctrl_en_mask; + pll_writel(val, pll->params->ssc_ctrl_reg, pll); + } +} + +static void pll_clk_stop_ss(struct tegra_clk_pll *pll) +{ + if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { + u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); + + val &= ~pll->params->ssc_ctrl_en_mask; + pll_writel(val, pll->params->ssc_ctrl_reg, pll); + } +} + static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, unsigned long rate) { @@ -676,8 +696,10 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, return 0; } - if (state) + if (state) { + pll_clk_stop_ss(pll); _clk_pll_disable(hw); + } if (!pll->params->defaults_set && pll->params->set_defaults) pll->params->set_defaults(pll); @@ -690,6 +712,7 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, if (state) { _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); + pll_clk_start_ss(pll); } return ret; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 8dac213fa672..4883507c59dc 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -184,6 +184,8 @@ struct tegra_clk_pll; * @sdm_din_mask: Mask of SDM divider bits * @sdm_ctrl_reg: Register offset where SDM enable is * @sdm_ctrl_en_mask: Mask of SDM enable bit + * @ssc_ctrl_reg: Register offset where SSC settings are + * @ssc_ctrl_en_mask: Mask of SSC enable bit * @aux_reg: AUX register offset * @dyn_ramp_reg: Dynamic ramp control register offset * @ext_misc_reg: Miscellaneous control register offsets @@ -262,6 +264,8 @@ struct tegra_clk_pll_params { u32 sdm_din_mask; u32 sdm_ctrl_reg; u32 sdm_ctrl_en_mask; + u32 ssc_ctrl_reg; + u32 ssc_ctrl_en_mask; u32 aux_reg; u32 dyn_ramp_reg; u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT];