2 * OMAP DPLL clock support
4 * Copyright (C) 2013 Texas Instruments, Inc.
6 * Tero Kristo <t-kristo@ti.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/clk-provider.h>
19 #include <linux/slab.h>
20 #include <linux/err.h>
22 #include <linux/of_address.h>
23 #include <linux/clk/ti.h>
26 #define pr_fmt(fmt) "%s: " fmt, __func__
28 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
29 defined(CONFIG_SOC_DRA7XX)
30 static const struct clk_ops dpll_m4xen_ck_ops = {
31 .enable = &omap3_noncore_dpll_enable,
32 .disable = &omap3_noncore_dpll_disable,
33 .recalc_rate = &omap4_dpll_regm4xen_recalc,
34 .round_rate = &omap4_dpll_regm4xen_round_rate,
35 .set_rate = &omap3_noncore_dpll_set_rate,
36 .set_parent = &omap3_noncore_dpll_set_parent,
37 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
38 .determine_rate = &omap4_dpll_regm4xen_determine_rate,
39 .get_parent = &omap2_init_dpll_parent,
42 static const struct clk_ops dpll_m4xen_ck_ops = {};
45 #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
46 defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \
47 defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
48 static const struct clk_ops dpll_core_ck_ops = {
49 .recalc_rate = &omap3_dpll_recalc,
50 .get_parent = &omap2_init_dpll_parent,
53 static const struct clk_ops dpll_ck_ops = {
54 .enable = &omap3_noncore_dpll_enable,
55 .disable = &omap3_noncore_dpll_disable,
56 .recalc_rate = &omap3_dpll_recalc,
57 .round_rate = &omap2_dpll_round_rate,
58 .set_rate = &omap3_noncore_dpll_set_rate,
59 .set_parent = &omap3_noncore_dpll_set_parent,
60 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
61 .determine_rate = &omap3_noncore_dpll_determine_rate,
62 .get_parent = &omap2_init_dpll_parent,
65 static const struct clk_ops dpll_no_gate_ck_ops = {
66 .recalc_rate = &omap3_dpll_recalc,
67 .get_parent = &omap2_init_dpll_parent,
68 .round_rate = &omap2_dpll_round_rate,
69 .set_rate = &omap3_noncore_dpll_set_rate,
70 .set_parent = &omap3_noncore_dpll_set_parent,
71 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
72 .determine_rate = &omap3_noncore_dpll_determine_rate,
75 static const struct clk_ops dpll_core_ck_ops = {};
76 static const struct clk_ops dpll_ck_ops = {};
77 static const struct clk_ops dpll_no_gate_ck_ops = {};
78 const struct clk_hw_omap_ops clkhwops_omap3_dpll = {};
81 #ifdef CONFIG_ARCH_OMAP2
82 static const struct clk_ops omap2_dpll_core_ck_ops = {
83 .get_parent = &omap2_init_dpll_parent,
84 .recalc_rate = &omap2_dpllcore_recalc,
85 .round_rate = &omap2_dpll_round_rate,
86 .set_rate = &omap2_reprogram_dpllcore,
89 static const struct clk_ops omap2_dpll_core_ck_ops = {};
92 #ifdef CONFIG_ARCH_OMAP3
93 static const struct clk_ops omap3_dpll_core_ck_ops = {
94 .get_parent = &omap2_init_dpll_parent,
95 .recalc_rate = &omap3_dpll_recalc,
96 .round_rate = &omap2_dpll_round_rate,
99 static const struct clk_ops omap3_dpll_core_ck_ops = {};
102 #ifdef CONFIG_ARCH_OMAP3
103 static const struct clk_ops omap3_dpll_ck_ops = {
104 .enable = &omap3_noncore_dpll_enable,
105 .disable = &omap3_noncore_dpll_disable,
106 .get_parent = &omap2_init_dpll_parent,
107 .recalc_rate = &omap3_dpll_recalc,
108 .set_rate = &omap3_noncore_dpll_set_rate,
109 .set_parent = &omap3_noncore_dpll_set_parent,
110 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
111 .determine_rate = &omap3_noncore_dpll_determine_rate,
112 .round_rate = &omap2_dpll_round_rate,
115 static const struct clk_ops omap3_dpll_per_ck_ops = {
116 .enable = &omap3_noncore_dpll_enable,
117 .disable = &omap3_noncore_dpll_disable,
118 .get_parent = &omap2_init_dpll_parent,
119 .recalc_rate = &omap3_dpll_recalc,
120 .set_rate = &omap3_dpll4_set_rate,
121 .set_parent = &omap3_noncore_dpll_set_parent,
122 .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
123 .determine_rate = &omap3_noncore_dpll_determine_rate,
124 .round_rate = &omap2_dpll_round_rate,
128 static const struct clk_ops dpll_x2_ck_ops = {
129 .recalc_rate = &omap3_clkoutx2_recalc,
133 * ti_clk_register_dpll - low level registration of a DPLL clock
134 * @hw: hardware clock definition for the clock
135 * @node: device node for the clock
137 * Finalizes DPLL registration process. In case a failure (clk-ref or
138 * clk-bypass is missing), the clock is added to retry list and
139 * the initialization is retried on later stage.
141 static void __init ti_clk_register_dpll(struct clk_hw *hw,
142 struct device_node *node)
144 struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
145 struct dpll_data *dd = clk_hw->dpll_data;
148 dd->clk_ref = of_clk_get(node, 0);
149 dd->clk_bypass = of_clk_get(node, 1);
151 if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
152 pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
154 if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll))
160 /* register the clock */
161 clk = clk_register(NULL, &clk_hw->hw);
164 omap2_init_clk_hw_omap_clocks(clk);
165 of_clk_add_provider(node, of_clk_src_simple_get, clk);
166 kfree(clk_hw->hw.init->parent_names);
167 kfree(clk_hw->hw.init);
172 kfree(clk_hw->dpll_data);
173 kfree(clk_hw->hw.init->parent_names);
174 kfree(clk_hw->hw.init);
178 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
179 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
180 defined(CONFIG_SOC_AM43XX)
182 * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock
183 * @node: device node for this clock
184 * @ops: clk_ops for this clock
185 * @hw_ops: clk_hw_ops for this clock
187 * Initializes a DPLL x 2 clock from device tree data.
189 static void ti_clk_register_dpll_x2(struct device_node *node,
190 const struct clk_ops *ops,
191 const struct clk_hw_omap_ops *hw_ops)
194 struct clk_init_data init = { NULL };
195 struct clk_hw_omap *clk_hw;
196 const char *name = node->name;
197 const char *parent_name;
199 parent_name = of_clk_get_parent_name(node, 0);
201 pr_err("%s must have parent\n", node->name);
205 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
209 clk_hw->ops = hw_ops;
210 clk_hw->hw.init = &init;
214 init.parent_names = &parent_name;
215 init.num_parents = 1;
217 /* register the clock */
218 clk = clk_register(NULL, &clk_hw->hw);
223 omap2_init_clk_hw_omap_clocks(clk);
224 of_clk_add_provider(node, of_clk_src_simple_get, clk);
230 * of_ti_dpll_setup - Setup function for OMAP DPLL clocks
231 * @node: device node containing the DPLL info
232 * @ops: ops for the DPLL
233 * @ddt: DPLL data template to use
235 * Initializes a DPLL clock from device tree data.
237 static void __init of_ti_dpll_setup(struct device_node *node,
238 const struct clk_ops *ops,
239 const struct dpll_data *ddt)
241 struct clk_hw_omap *clk_hw = NULL;
242 struct clk_init_data *init = NULL;
243 const char **parent_names = NULL;
244 struct dpll_data *dd = NULL;
248 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
249 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
250 init = kzalloc(sizeof(*init), GFP_KERNEL);
251 if (!dd || !clk_hw || !init)
254 memcpy(dd, ddt, sizeof(*dd));
256 clk_hw->dpll_data = dd;
257 clk_hw->ops = &clkhwops_omap3_dpll;
258 clk_hw->hw.init = init;
259 clk_hw->flags = MEMMAP_ADDRESSING;
261 init->name = node->name;
264 init->num_parents = of_clk_get_parent_count(node);
265 if (init->num_parents < 1) {
266 pr_err("%s must have parent(s)\n", node->name);
270 parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL);
274 for (i = 0; i < init->num_parents; i++)
275 parent_names[i] = of_clk_get_parent_name(node, i);
277 init->parent_names = parent_names;
279 dd->control_reg = ti_clk_get_reg_addr(node, 0);
282 * Special case for OMAP2 DPLL, register order is different due to
283 * missing idlest_reg, also clkhwops is different. Detected from
284 * missing idlest_mask.
286 if (!dd->idlest_mask) {
287 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1);
288 #ifdef CONFIG_ARCH_OMAP2
289 clk_hw->ops = &clkhwops_omap2xxx_dpll;
290 omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
293 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
297 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
300 if (!dd->control_reg || !dd->mult_div1_reg)
303 if (dd->autoidle_mask) {
304 dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
305 if (!dd->autoidle_reg)
309 if (of_property_read_bool(node, "ti,low-power-stop"))
310 dpll_mode |= 1 << DPLL_LOW_POWER_STOP;
312 if (of_property_read_bool(node, "ti,low-power-bypass"))
313 dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS;
315 if (of_property_read_bool(node, "ti,lock"))
316 dpll_mode |= 1 << DPLL_LOCKED;
319 dd->modes = dpll_mode;
321 ti_clk_register_dpll(&clk_hw->hw, node);
331 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
332 defined(CONFIG_SOC_DRA7XX)
333 static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
335 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
337 CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
338 of_ti_omap4_dpll_x2_setup);
341 #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
342 static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
344 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
346 CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
347 of_ti_am3_dpll_x2_setup);
350 #ifdef CONFIG_ARCH_OMAP3
351 static void __init of_ti_omap3_dpll_setup(struct device_node *node)
353 const struct dpll_data dd = {
356 .autoidle_mask = 0x7,
357 .mult_mask = 0x7ff << 8,
359 .max_multiplier = 2047,
362 .freqsel_mask = 0xf0,
363 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
366 of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
368 CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
369 of_ti_omap3_dpll_setup);
371 static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
373 const struct dpll_data dd = {
376 .autoidle_mask = 0x7,
377 .mult_mask = 0x7ff << 16,
378 .div1_mask = 0x7f << 8,
379 .max_multiplier = 2047,
382 .freqsel_mask = 0xf0,
385 of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd);
387 CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
388 of_ti_omap3_core_dpll_setup);
390 static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
392 const struct dpll_data dd = {
393 .idlest_mask = 0x1 << 1,
394 .enable_mask = 0x7 << 16,
395 .autoidle_mask = 0x7 << 3,
396 .mult_mask = 0x7ff << 8,
398 .max_multiplier = 2047,
401 .freqsel_mask = 0xf00000,
402 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
405 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
407 CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
408 of_ti_omap3_per_dpll_setup);
410 static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
412 const struct dpll_data dd = {
413 .idlest_mask = 0x1 << 1,
414 .enable_mask = 0x7 << 16,
415 .autoidle_mask = 0x7 << 3,
416 .mult_mask = 0xfff << 8,
418 .max_multiplier = 4095,
421 .sddiv_mask = 0xff << 24,
422 .dco_mask = 0xe << 20,
423 .flags = DPLL_J_TYPE,
424 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
427 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
429 CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
430 of_ti_omap3_per_jtype_dpll_setup);
433 static void __init of_ti_omap4_dpll_setup(struct device_node *node)
435 const struct dpll_data dd = {
438 .autoidle_mask = 0x7,
439 .mult_mask = 0x7ff << 8,
441 .max_multiplier = 2047,
444 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
447 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
449 CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
450 of_ti_omap4_dpll_setup);
452 static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node)
454 const struct dpll_data dd = {
457 .autoidle_mask = 0x7,
458 .mult_mask = 0x7ff << 8,
460 .max_multiplier = 2047,
463 .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */
465 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
468 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
470 CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock",
471 of_ti_omap5_mpu_dpll_setup);
473 static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
475 const struct dpll_data dd = {
478 .autoidle_mask = 0x7,
479 .mult_mask = 0x7ff << 8,
481 .max_multiplier = 2047,
484 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
487 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
489 CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
490 of_ti_omap4_core_dpll_setup);
492 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
493 defined(CONFIG_SOC_DRA7XX)
494 static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
496 const struct dpll_data dd = {
499 .autoidle_mask = 0x7,
500 .mult_mask = 0x7ff << 8,
502 .max_multiplier = 2047,
506 .lpmode_mask = 1 << 10,
507 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
510 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
512 CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
513 of_ti_omap4_m4xen_dpll_setup);
515 static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
517 const struct dpll_data dd = {
520 .autoidle_mask = 0x7,
521 .mult_mask = 0xfff << 8,
523 .max_multiplier = 4095,
526 .sddiv_mask = 0xff << 24,
527 .flags = DPLL_J_TYPE,
528 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
531 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
533 CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
534 of_ti_omap4_jtype_dpll_setup);
537 static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
539 const struct dpll_data dd = {
542 .mult_mask = 0x7ff << 8,
544 .max_multiplier = 2047,
547 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
550 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
552 CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
553 of_ti_am3_no_gate_dpll_setup);
555 static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
557 const struct dpll_data dd = {
560 .mult_mask = 0x7ff << 8,
562 .max_multiplier = 4095,
565 .flags = DPLL_J_TYPE,
566 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
569 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
571 CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
572 of_ti_am3_jtype_dpll_setup);
574 static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
576 const struct dpll_data dd = {
579 .mult_mask = 0x7ff << 8,
581 .max_multiplier = 2047,
584 .flags = DPLL_J_TYPE,
585 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
588 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
590 CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
591 "ti,am3-dpll-no-gate-j-type-clock",
592 of_ti_am3_no_gate_jtype_dpll_setup);
594 static void __init of_ti_am3_dpll_setup(struct device_node *node)
596 const struct dpll_data dd = {
599 .mult_mask = 0x7ff << 8,
601 .max_multiplier = 2047,
604 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
607 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
609 CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
611 static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
613 const struct dpll_data dd = {
616 .mult_mask = 0x7ff << 8,
618 .max_multiplier = 2047,
621 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
624 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
626 CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
627 of_ti_am3_core_dpll_setup);
629 static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
631 const struct dpll_data dd = {
633 .mult_mask = 0x3ff << 12,
634 .div1_mask = 0xf << 8,
639 of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
641 CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
642 of_ti_omap2_core_dpll_setup);