summaryrefslogtreecommitdiffstats
path: root/drivers/clk/tegra/clk-pll.c
diff options
context:
space:
mode:
authorBill Huang <bilhuang@nvidia.com>2015-06-18 23:28:33 +0200
committerThierry Reding <treding@nvidia.com>2015-12-17 13:37:55 +0100
commit0ef9db6cf24dbb58118818e64198d9a030e4697e (patch)
treebb0b0cb78ca6f1c3ae91d3dded430beafbb696ef /drivers/clk/tegra/clk-pll.c
parentclk: tegra: pll: Add dyn_ramp callback (diff)
downloadlinux-0ef9db6cf24dbb58118818e64198d9a030e4697e.tar.xz
linux-0ef9db6cf24dbb58118818e64198d9a030e4697e.zip
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 <bilhuang@nvidia.com> Signed-off-by: Rhyland Klein <rklein@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/clk/tegra/clk-pll.c')
-rw-r--r--drivers/clk/tegra/clk-pll.c25
1 files changed, 24 insertions, 1 deletions
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;