aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2014-02-21 10:36:21 -0500
committerTero Kristo <t-kristo@ti.com>2014-05-28 05:28:20 -0400
commitaa76fcf473f6bfa839f37f77b6fdb71f0fb88d8f (patch)
treed8696ea988e4a1e54e6017b31fd8fd268a97a76a /drivers/clk/ti
parenta6fe3771d389cc660933509b7dfb945c596636f5 (diff)
CLK: TI: DPLL: add support for omap2 core dpll
OMAP2 has slightly different DPLL compared to later OMAP generations. This patch adds support for the ti,omap2-dpll-core-clock and also adds the bindings documentation. Signed-off-by: Tero Kristo <t-kristo@ti.com>
Diffstat (limited to 'drivers/clk/ti')
-rw-r--r--drivers/clk/ti/dpll.c78
1 files changed, 67 insertions, 11 deletions
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index dda262db42ea..34e233990212 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -35,21 +35,18 @@ static const struct clk_ops dpll_m4xen_ck_ops = {
35 .set_rate = &omap3_noncore_dpll_set_rate, 35 .set_rate = &omap3_noncore_dpll_set_rate,
36 .get_parent = &omap2_init_dpll_parent, 36 .get_parent = &omap2_init_dpll_parent,
37}; 37};
38#else
39static const struct clk_ops dpll_m4xen_ck_ops = {};
38#endif 40#endif
39 41
42#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
43 defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \
44 defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
40static const struct clk_ops dpll_core_ck_ops = { 45static const struct clk_ops dpll_core_ck_ops = {
41 .recalc_rate = &omap3_dpll_recalc, 46 .recalc_rate = &omap3_dpll_recalc,
42 .get_parent = &omap2_init_dpll_parent, 47 .get_parent = &omap2_init_dpll_parent,
43}; 48};
44 49
45#ifdef CONFIG_ARCH_OMAP3
46static const struct clk_ops omap3_dpll_core_ck_ops = {
47 .get_parent = &omap2_init_dpll_parent,
48 .recalc_rate = &omap3_dpll_recalc,
49 .round_rate = &omap2_dpll_round_rate,
50};
51#endif
52
53static const struct clk_ops dpll_ck_ops = { 50static const struct clk_ops dpll_ck_ops = {
54 .enable = &omap3_noncore_dpll_enable, 51 .enable = &omap3_noncore_dpll_enable,
55 .disable = &omap3_noncore_dpll_disable, 52 .disable = &omap3_noncore_dpll_disable,
@@ -65,6 +62,33 @@ static const struct clk_ops dpll_no_gate_ck_ops = {
65 .round_rate = &omap2_dpll_round_rate, 62 .round_rate = &omap2_dpll_round_rate,
66 .set_rate = &omap3_noncore_dpll_set_rate, 63 .set_rate = &omap3_noncore_dpll_set_rate,
67}; 64};
65#else
66static const struct clk_ops dpll_core_ck_ops = {};
67static const struct clk_ops dpll_ck_ops = {};
68static const struct clk_ops dpll_no_gate_ck_ops = {};
69const struct clk_hw_omap_ops clkhwops_omap3_dpll = {};
70#endif
71
72#ifdef CONFIG_ARCH_OMAP2
73static const struct clk_ops omap2_dpll_core_ck_ops = {
74 .get_parent = &omap2_init_dpll_parent,
75 .recalc_rate = &omap2_dpllcore_recalc,
76 .round_rate = &omap2_dpll_round_rate,
77 .set_rate = &omap2_reprogram_dpllcore,
78};
79#else
80static const struct clk_ops omap2_dpll_core_ck_ops = {};
81#endif
82
83#ifdef CONFIG_ARCH_OMAP3
84static const struct clk_ops omap3_dpll_core_ck_ops = {
85 .get_parent = &omap2_init_dpll_parent,
86 .recalc_rate = &omap3_dpll_recalc,
87 .round_rate = &omap2_dpll_round_rate,
88};
89#else
90static const struct clk_ops omap3_dpll_core_ck_ops = {};
91#endif
68 92
69#ifdef CONFIG_ARCH_OMAP3 93#ifdef CONFIG_ARCH_OMAP3
70static const struct clk_ops omap3_dpll_ck_ops = { 94static const struct clk_ops omap3_dpll_ck_ops = {
@@ -237,10 +261,27 @@ static void __init of_ti_dpll_setup(struct device_node *node,
237 init->parent_names = parent_names; 261 init->parent_names = parent_names;
238 262
239 dd->control_reg = ti_clk_get_reg_addr(node, 0); 263 dd->control_reg = ti_clk_get_reg_addr(node, 0);
240 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
241 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
242 264
243 if (!dd->control_reg || !dd->idlest_reg || !dd->mult_div1_reg) 265 /*
266 * Special case for OMAP2 DPLL, register order is different due to
267 * missing idlest_reg, also clkhwops is different. Detected from
268 * missing idlest_mask.
269 */
270 if (!dd->idlest_mask) {
271 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1);
272#ifdef CONFIG_ARCH_OMAP2
273 clk_hw->ops = &clkhwops_omap2xxx_dpll;
274 omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
275#endif
276 } else {
277 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
278 if (!dd->idlest_reg)
279 goto cleanup;
280
281 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
282 }
283
284 if (!dd->control_reg || !dd->mult_div1_reg)
244 goto cleanup; 285 goto cleanup;
245 286
246 if (dd->autoidle_mask) { 287 if (dd->autoidle_mask) {
@@ -547,3 +588,18 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
547} 588}
548CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", 589CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
549 of_ti_am3_core_dpll_setup); 590 of_ti_am3_core_dpll_setup);
591
592static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
593{
594 const struct dpll_data dd = {
595 .enable_mask = 0x3,
596 .mult_mask = 0x3ff << 12,
597 .div1_mask = 0xf << 8,
598 .max_divider = 16,
599 .min_divider = 1,
600 };
601
602 of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
603}
604CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
605 of_ti_omap2_core_dpll_setup);