summaryrefslogtreecommitdiff
path: root/drivers/clk/tegra/clk-tegra-fixed.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-03-26 16:43:56 (GMT)
committerThierry Reding <treding@nvidia.com>2015-04-10 14:04:20 (GMT)
commit63cc5a4da1fafedee24d8f5af67c1dd9d08f95c7 (patch)
treecd2e48fa02b4982784ad5cf7c09bd0eb90fc06c8 /drivers/clk/tegra/clk-tegra-fixed.c
parent699b477a0d3a5bc68034a1520a4337ea0a20f63b (diff)
downloadlinux-63cc5a4da1fafedee24d8f5af67c1dd9d08f95c7.tar.xz
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.c24
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 f3b7738..605676d 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;