Commit bff1cef5 authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Stephen Boyd

clk: tegra: Don't enable already enabled PLLs

Initially Common Clock Framework isn't aware of the clock-enable status,
this results in enabling of clocks that were enabled by bootloader. This
is not a big deal for a regular clock-gates, but for PLL's it may have
some unpleasant consequences. Thus re-enabling PLLX (the main CPU parent
clock) may result in extra long period of PLL re-locking.
Acked-by: default avatarPeter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 9e98c678
...@@ -444,6 +444,9 @@ static int clk_pll_enable(struct clk_hw *hw) ...@@ -444,6 +444,9 @@ static int clk_pll_enable(struct clk_hw *hw)
unsigned long flags = 0; unsigned long flags = 0;
int ret; int ret;
if (clk_pll_is_enabled(hw))
return 0;
if (pll->lock) if (pll->lock)
spin_lock_irqsave(pll->lock, flags); spin_lock_irqsave(pll->lock, flags);
...@@ -940,11 +943,16 @@ static int clk_plle_training(struct tegra_clk_pll *pll) ...@@ -940,11 +943,16 @@ static int clk_plle_training(struct tegra_clk_pll *pll)
static int clk_plle_enable(struct clk_hw *hw) static int clk_plle_enable(struct clk_hw *hw)
{ {
struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll *pll = to_clk_pll(hw);
unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
struct tegra_clk_pll_freq_table sel; struct tegra_clk_pll_freq_table sel;
unsigned long input_rate;
u32 val; u32 val;
int err; int err;
if (clk_pll_is_enabled(hw))
return 0;
input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate))
return -EINVAL; return -EINVAL;
...@@ -1355,6 +1363,9 @@ static int clk_pllc_enable(struct clk_hw *hw) ...@@ -1355,6 +1363,9 @@ static int clk_pllc_enable(struct clk_hw *hw)
int ret; int ret;
unsigned long flags = 0; unsigned long flags = 0;
if (clk_pll_is_enabled(hw))
return 0;
if (pll->lock) if (pll->lock)
spin_lock_irqsave(pll->lock, flags); spin_lock_irqsave(pll->lock, flags);
...@@ -1567,7 +1578,12 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) ...@@ -1567,7 +1578,12 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw)
u32 val; u32 val;
int ret; int ret;
unsigned long flags = 0; unsigned long flags = 0;
unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); unsigned long input_rate;
if (clk_pll_is_enabled(hw))
return 0;
input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate))
return -EINVAL; return -EINVAL;
...@@ -1704,6 +1720,9 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw) ...@@ -1704,6 +1720,9 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw)
return -EINVAL; return -EINVAL;
} }
if (clk_pll_is_enabled(hw))
return 0;
input_rate = clk_hw_get_rate(__clk_get_hw(osc)); input_rate = clk_hw_get_rate(__clk_get_hw(osc));
if (pll->lock) if (pll->lock)
...@@ -2379,6 +2398,16 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name, ...@@ -2379,6 +2398,16 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
return clk; return clk;
} }
static int clk_plle_tegra210_is_enabled(struct clk_hw *hw)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
u32 val;
val = pll_readl_base(pll);
return val & PLLE_BASE_ENABLE ? 1 : 0;
}
static int clk_plle_tegra210_enable(struct clk_hw *hw) static int clk_plle_tegra210_enable(struct clk_hw *hw)
{ {
struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll *pll = to_clk_pll(hw);
...@@ -2386,7 +2415,12 @@ static int clk_plle_tegra210_enable(struct clk_hw *hw) ...@@ -2386,7 +2415,12 @@ static int clk_plle_tegra210_enable(struct clk_hw *hw)
u32 val; u32 val;
int ret = 0; int ret = 0;
unsigned long flags = 0; unsigned long flags = 0;
unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); unsigned long input_rate;
if (clk_plle_tegra210_is_enabled(hw))
return 0;
input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate))
return -EINVAL; return -EINVAL;
...@@ -2497,16 +2531,6 @@ static void clk_plle_tegra210_disable(struct clk_hw *hw) ...@@ -2497,16 +2531,6 @@ static void clk_plle_tegra210_disable(struct clk_hw *hw)
spin_unlock_irqrestore(pll->lock, flags); spin_unlock_irqrestore(pll->lock, flags);
} }
static int clk_plle_tegra210_is_enabled(struct clk_hw *hw)
{
struct tegra_clk_pll *pll = to_clk_pll(hw);
u32 val;
val = pll_readl_base(pll);
return val & PLLE_BASE_ENABLE ? 1 : 0;
}
static const struct clk_ops tegra_clk_plle_tegra210_ops = { static const struct clk_ops tegra_clk_plle_tegra210_ops = {
.is_enabled = clk_plle_tegra210_is_enabled, .is_enabled = clk_plle_tegra210_is_enabled,
.enable = clk_plle_tegra210_enable, .enable = clk_plle_tegra210_enable,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment