diff options
author | Danny Huang <dahuang@nvidia.com> | 2015-06-18 17:28:27 -0400 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2015-11-20 18:07:35 +0100 |
commit | 267b62a969511236e91121cd27f4cc1558385855 (patch) | |
tree | 4b8bb88a584c67966c3b94ecae9ed4c26f3f4c28 /drivers/clk/tegra | |
parent | 86c679a52294d4c4b989903a75e31495c04d688a (diff) | |
download | linux-267b62a969511236e91121cd27f4cc1558385855.tar.bz2 |
clk: tegra: pll: Update PLLM handling
PLLM is fixed for Tegra30 up through Tegra114. Starting with Tegra124
PLLM can change rate. Mark PLLM as TEGRA_PLL_FIXED for the generations
where it should be. Modify the check in clk_pll_round_rate() and
clk_pll_recalc_rate() to allow for the non-fixed version to return the
correct rate.
Note that there is no change for Tegra20. This is because PLLM is not
distinguished in that driver, and adding either the PLLM or FIXED_RATE
flags will cause potential problems.
PLLM never supported dynamic ramping. On Tegra20 and Tegra30, there is
no dynamic ramping at all, and on Tegra114, Tegra124 and Tegra132, only
PLLX and PLLC support dynamic ramping, so we can go ahead and remove the
specialized pllm_ops.
Signed-off-by: Danny Huang <dahuang@nvidia.com>
Signed-off-by: Rhyland Klein <rklein@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/clk/tegra')
-rw-r--r-- | drivers/clk/tegra/clk-pll.c | 56 | ||||
-rw-r--r-- | drivers/clk/tegra/clk-tegra114.c | 3 | ||||
-rw-r--r-- | drivers/clk/tegra/clk-tegra30.c | 2 |
3 files changed, 10 insertions, 51 deletions
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index b8b3fc6dc39b..7319de770e3a 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -726,12 +726,12 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; - if (pll->params->flags & TEGRA_PLL_FIXED) + if (pll->params->flags & TEGRA_PLL_FIXED) { + /* PLLM are used for memory; we do not change rate */ + if (pll->params->flags & TEGRA_PLLM) + return clk_hw_get_rate(hw); return pll->params->fixed_rate; - - /* PLLM is used for memory; we do not change rate */ - if (pll->params->flags & TEGRA_PLLM) - return clk_hw_get_rate(hw); + } if (_get_table_rate(hw, &cfg, rate, *prate) && pll->params->calc_rate(hw, &cfg, rate, *prate)) @@ -755,6 +755,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, return parent_rate; if ((pll->params->flags & TEGRA_PLL_FIXED) && + !(pll->params->flags & TEGRA_PLLM) && !(val & PLL_BASE_OVERRIDE)) { struct tegra_clk_pll_freq_table sel; if (_get_table_rate(hw, &sel, pll->params->fixed_rate, @@ -1093,40 +1094,6 @@ static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, return output_rate; } -static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct tegra_clk_pll_freq_table cfg; - struct tegra_clk_pll *pll = to_clk_pll(hw); - unsigned long flags = 0; - int state, ret = 0; - - if (pll->lock) - spin_lock_irqsave(pll->lock, flags); - - state = clk_pll_is_enabled(hw); - if (state) { - if (rate != clk_get_rate(hw->clk)) { - pr_err("%s: Cannot change active PLLM\n", __func__); - ret = -EINVAL; - goto out; - } - goto out; - } - - ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate); - if (ret < 0) - goto out; - - _update_pll_mnp(pll, &cfg); - -out: - if (pll->lock) - spin_unlock_irqrestore(pll->lock, flags); - - return ret; -} - static void _pllcx_strobe(struct tegra_clk_pll *pll) { u32 val; @@ -1598,15 +1565,6 @@ static const struct clk_ops tegra_clk_pllxc_ops = { .set_rate = clk_pllxc_set_rate, }; -static const struct clk_ops tegra_clk_pllm_ops = { - .is_enabled = clk_pll_is_enabled, - .enable = clk_pll_enable, - .disable = clk_pll_disable, - .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_ramp_round_rate, - .set_rate = clk_pllm_set_rate, -}; - static const struct clk_ops tegra_clk_pllc_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pllc_enable, @@ -1760,7 +1718,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, return ERR_CAST(pll); clk = _tegra_clk_register_pll(pll, name, parent_name, flags, - &tegra_clk_pllm_ops); + &tegra_clk_pll_ops); if (IS_ERR(clk)) kfree(pll); diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9411a1577d85..4a24aa4bbdea 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -351,7 +351,8 @@ static struct tegra_clk_pll_params pll_m_params = { .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, .freq_table = pll_m_freq_table, - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE | + TEGRA_PLL_FIXED, }; static struct div_nmp pllp_nmp = { diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 8493dd90f685..0478565cf292 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -460,7 +460,7 @@ static struct tegra_clk_pll_params pll_m_params = { .freq_table = pll_m_freq_table, .flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK | - TEGRA_PLL_HAS_LOCK_ENABLE, + TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_FIXED, }; static struct tegra_clk_pll_params pll_p_params = { |