aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-03-26 12:43:56 -0400
committerThierry Reding <treding@nvidia.com>2015-04-10 10:04:20 -0400
commit63cc5a4da1fafedee24d8f5af67c1dd9d08f95c7 (patch)
treecd2e48fa02b4982784ad5cf7c09bd0eb90fc06c8 /drivers/clk
parent699b477a0d3a5bc68034a1520a4337ea0a20f63b (diff)
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')
-rw-r--r--drivers/clk/tegra/clk-tegra-fixed.c24
-rw-r--r--drivers/clk/tegra/clk-tegra124.c3
-rw-r--r--drivers/clk/tegra/clk-tegra30.c3
-rw-r--r--drivers/clk/tegra/clk.h8
4 files changed, 21 insertions, 17 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 @@
30#define OSC_CTRL_OSC_FREQ_SHIFT 28 30#define OSC_CTRL_OSC_FREQ_SHIFT 28
31#define OSC_CTRL_PLL_REF_DIV_SHIFT 26 31#define OSC_CTRL_PLL_REF_DIV_SHIFT 26
32 32
33int __init tegra_osc_clk_init(void __iomem *clk_base, 33int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
34 struct tegra_clk *tegra_clks, 34 unsigned long *input_freqs, unsigned int num,
35 unsigned long *input_freqs, int num, 35 unsigned int clk_m_div, unsigned long *osc_freq,
36 unsigned long *osc_freq, 36 unsigned long *pll_ref_freq)
37 unsigned long *pll_ref_freq)
38{ 37{
39 struct clk *clk; 38 struct clk *clk, *osc;
40 struct clk **dt_clk; 39 struct clk **dt_clk;
41 u32 val, pll_ref_div; 40 u32 val, pll_ref_div;
42 unsigned osc_idx; 41 unsigned osc_idx;
@@ -54,22 +53,25 @@ int __init tegra_osc_clk_init(void __iomem *clk_base,
54 return -EINVAL; 53 return -EINVAL;
55 } 54 }
56 55
57 dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, tegra_clks); 56 osc = clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT,
57 *osc_freq);
58
59 dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, clks);
58 if (!dt_clk) 60 if (!dt_clk)
59 return 0; 61 return 0;
60 62
61 clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, 63 clk = clk_register_fixed_factor(NULL, "clk_m", "osc",
62 *osc_freq); 64 0, 1, clk_m_div);
63 *dt_clk = clk; 65 *dt_clk = clk;
64 66
65 /* pll_ref */ 67 /* pll_ref */
66 val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; 68 val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3;
67 pll_ref_div = 1 << val; 69 pll_ref_div = 1 << val;
68 dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, tegra_clks); 70 dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, clks);
69 if (!dt_clk) 71 if (!dt_clk)
70 return 0; 72 return 0;
71 73
72 clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", 74 clk = clk_register_fixed_factor(NULL, "pll_ref", "osc",
73 0, 1, pll_ref_div); 75 0, 1, pll_ref_div);
74 *dt_clk = clk; 76 *dt_clk = clk;
75 77
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 29b39c8c3151..f1fa29ec7951 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1480,7 +1480,8 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
1480 return; 1480 return;
1481 1481
1482 if (tegra_osc_clk_init(clk_base, tegra124_clks, tegra124_input_freq, 1482 if (tegra_osc_clk_init(clk_base, tegra124_clks, tegra124_input_freq,
1483 ARRAY_SIZE(tegra124_input_freq), &osc_freq, &pll_ref_freq) < 0) 1483 ARRAY_SIZE(tegra124_input_freq), 1, &osc_freq,
1484 &pll_ref_freq) < 0)
1484 return; 1485 return;
1485 1486
1486 tegra_fixed_clk_init(tegra124_clks); 1487 tegra_fixed_clk_init(tegra124_clks);
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 0659db79d1c5..4b26509fc218 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -1434,7 +1434,8 @@ static void __init tegra30_clock_init(struct device_node *np)
1434 return; 1434 return;
1435 1435
1436 if (tegra_osc_clk_init(clk_base, tegra30_clks, tegra30_input_freq, 1436 if (tegra_osc_clk_init(clk_base, tegra30_clks, tegra30_input_freq,
1437 ARRAY_SIZE(tegra30_input_freq), &input_freq, NULL) < 0) 1437 ARRAY_SIZE(tegra30_input_freq), 1, &input_freq,
1438 NULL) < 0)
1438 return; 1439 return;
1439 1440
1440 1441
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 48cb1c13ede5..d6ac00647faf 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -615,10 +615,10 @@ void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
615 615
616void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks); 616void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks);
617void tegra_fixed_clk_init(struct tegra_clk *tegra_clks); 617void tegra_fixed_clk_init(struct tegra_clk *tegra_clks);
618int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *tegra_clks, 618int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
619 unsigned long *input_freqs, int num, 619 unsigned long *input_freqs, unsigned int num,
620 unsigned long *osc_freq, 620 unsigned int clk_m_div, unsigned long *osc_freq,
621 unsigned long *pll_ref_freq); 621 unsigned long *pll_ref_freq);
622void tegra_super_clk_gen4_init(void __iomem *clk_base, 622void tegra_super_clk_gen4_init(void __iomem *clk_base,
623 void __iomem *pmc_base, struct tegra_clk *tegra_clks, 623 void __iomem *pmc_base, struct tegra_clk *tegra_clks,
624 struct tegra_clk_pll_params *pll_params); 624 struct tegra_clk_pll_params *pll_params);