diff options
author | Thierry Reding <treding@nvidia.com> | 2015-03-26 17:43:56 +0100 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2015-04-10 16:04:20 +0200 |
commit | 63cc5a4da1fafedee24d8f5af67c1dd9d08f95c7 (patch) | |
tree | cd2e48fa02b4982784ad5cf7c09bd0eb90fc06c8 /drivers/clk/tegra/clk-tegra-fixed.c | |
parent | clk: tegra: Add peripheral registers for bank Y (diff) | |
download | linux-63cc5a4da1fafedee24d8f5af67c1dd9d08f95c7.tar.xz linux-63cc5a4da1fafedee24d8f5af67c1dd9d08f95c7.zip |
clk: tegra: Model oscillator as clock
Currently the Tegra clock driver simplifies the clock tree somewhat by
taking advantage of the fact that clk_m runs at the same frequency as
the oscillator. While that's true on all currently supported SoCs, it
does not apply to Tegra210 anymore. On Tegra210 clk_m is typically
divided down from the oscillator frequency. To support that setup, add
a separate clock for the oscillator that both clk_m and pll_ref derive
from.
Modify the tegra_osc_clk_init() function to take an additional divider
parameter for clk_m. Existing SoCs always pass in 1, whereas Tegra210
will read the divider from a register in the clock & reset controller.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/clk/tegra/clk-tegra-fixed.c')
-rw-r--r-- | drivers/clk/tegra/clk-tegra-fixed.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c index f3b773833429..605676d368eb 100644 --- a/drivers/clk/tegra/clk-tegra-fixed.c +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -30,13 +30,12 @@ #define OSC_CTRL_OSC_FREQ_SHIFT 28 #define OSC_CTRL_PLL_REF_DIV_SHIFT 26 -int __init tegra_osc_clk_init(void __iomem *clk_base, - struct tegra_clk *tegra_clks, - unsigned long *input_freqs, int num, - unsigned long *osc_freq, - unsigned long *pll_ref_freq) +int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, + unsigned long *input_freqs, unsigned int num, + unsigned int clk_m_div, unsigned long *osc_freq, + unsigned long *pll_ref_freq) { - struct clk *clk; + struct clk *clk, *osc; struct clk **dt_clk; u32 val, pll_ref_div; unsigned osc_idx; @@ -54,22 +53,25 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, return -EINVAL; } - dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, tegra_clks); + osc = clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, + *osc_freq); + + dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, clks); if (!dt_clk) return 0; - clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, - *osc_freq); + clk = clk_register_fixed_factor(NULL, "clk_m", "osc", + 0, 1, clk_m_div); *dt_clk = clk; /* pll_ref */ val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; pll_ref_div = 1 << val; - dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, tegra_clks); + dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, clks); if (!dt_clk) return 0; - clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", + clk = clk_register_fixed_factor(NULL, "pll_ref", "osc", 0, 1, pll_ref_div); *dt_clk = clk; |