aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti/dpll.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/ti/dpll.c')
-rw-r--r--drivers/clk/ti/dpll.c138
1 files changed, 103 insertions, 35 deletions
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 7e498a44f97d..abd956d5f838 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -25,8 +25,6 @@
25#undef pr_fmt 25#undef pr_fmt
26#define pr_fmt(fmt) "%s: " fmt, __func__ 26#define pr_fmt(fmt) "%s: " fmt, __func__
27 27
28#define DPLL_HAS_AUTOIDLE 0x1
29
30#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ 28#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
31 defined(CONFIG_SOC_DRA7XX) 29 defined(CONFIG_SOC_DRA7XX)
32static const struct clk_ops dpll_m4xen_ck_ops = { 30static const struct clk_ops dpll_m4xen_ck_ops = {
@@ -37,21 +35,18 @@ static const struct clk_ops dpll_m4xen_ck_ops = {
37 .set_rate = &omap3_noncore_dpll_set_rate, 35 .set_rate = &omap3_noncore_dpll_set_rate,
38 .get_parent = &omap2_init_dpll_parent, 36 .get_parent = &omap2_init_dpll_parent,
39}; 37};
38#else
39static const struct clk_ops dpll_m4xen_ck_ops = {};
40#endif 40#endif
41 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)
42static const struct clk_ops dpll_core_ck_ops = { 45static const struct clk_ops dpll_core_ck_ops = {
43 .recalc_rate = &omap3_dpll_recalc, 46 .recalc_rate = &omap3_dpll_recalc,
44 .get_parent = &omap2_init_dpll_parent, 47 .get_parent = &omap2_init_dpll_parent,
45}; 48};
46 49
47#ifdef CONFIG_ARCH_OMAP3
48static const struct clk_ops omap3_dpll_core_ck_ops = {
49 .get_parent = &omap2_init_dpll_parent,
50 .recalc_rate = &omap3_dpll_recalc,
51 .round_rate = &omap2_dpll_round_rate,
52};
53#endif
54
55static const struct clk_ops dpll_ck_ops = { 50static const struct clk_ops dpll_ck_ops = {
56 .enable = &omap3_noncore_dpll_enable, 51 .enable = &omap3_noncore_dpll_enable,
57 .disable = &omap3_noncore_dpll_disable, 52 .disable = &omap3_noncore_dpll_disable,
@@ -67,6 +62,33 @@ static const struct clk_ops dpll_no_gate_ck_ops = {
67 .round_rate = &omap2_dpll_round_rate, 62 .round_rate = &omap2_dpll_round_rate,
68 .set_rate = &omap3_noncore_dpll_set_rate, 63 .set_rate = &omap3_noncore_dpll_set_rate,
69}; 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
70 92
71#ifdef CONFIG_ARCH_OMAP3 93#ifdef CONFIG_ARCH_OMAP3
72static const struct clk_ops omap3_dpll_ck_ops = { 94static const struct clk_ops omap3_dpll_ck_ops = {
@@ -193,14 +215,12 @@ static void ti_clk_register_dpll_x2(struct device_node *node,
193 * @node: device node containing the DPLL info 215 * @node: device node containing the DPLL info
194 * @ops: ops for the DPLL 216 * @ops: ops for the DPLL
195 * @ddt: DPLL data template to use 217 * @ddt: DPLL data template to use
196 * @init_flags: flags for controlling init types
197 * 218 *
198 * Initializes a DPLL clock from device tree data. 219 * Initializes a DPLL clock from device tree data.
199 */ 220 */
200static void __init of_ti_dpll_setup(struct device_node *node, 221static void __init of_ti_dpll_setup(struct device_node *node,
201 const struct clk_ops *ops, 222 const struct clk_ops *ops,
202 const struct dpll_data *ddt, 223 const struct dpll_data *ddt)
203 u8 init_flags)
204{ 224{
205 struct clk_hw_omap *clk_hw = NULL; 225 struct clk_hw_omap *clk_hw = NULL;
206 struct clk_init_data *init = NULL; 226 struct clk_init_data *init = NULL;
@@ -241,13 +261,30 @@ static void __init of_ti_dpll_setup(struct device_node *node,
241 init->parent_names = parent_names; 261 init->parent_names = parent_names;
242 262
243 dd->control_reg = ti_clk_get_reg_addr(node, 0); 263 dd->control_reg = ti_clk_get_reg_addr(node, 0);
244 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
245 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
246 264
247 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)
248 goto cleanup; 285 goto cleanup;
249 286
250 if (init_flags & DPLL_HAS_AUTOIDLE) { 287 if (dd->autoidle_mask) {
251 dd->autoidle_reg = ti_clk_get_reg_addr(node, 3); 288 dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
252 if (!dd->autoidle_reg) 289 if (!dd->autoidle_reg)
253 goto cleanup; 290 goto cleanup;
@@ -310,7 +347,7 @@ static void __init of_ti_omap3_dpll_setup(struct device_node *node)
310 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 347 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
311 }; 348 };
312 349
313 of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 350 of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
314} 351}
315CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock", 352CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
316 of_ti_omap3_dpll_setup); 353 of_ti_omap3_dpll_setup);
@@ -329,7 +366,7 @@ static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
329 .freqsel_mask = 0xf0, 366 .freqsel_mask = 0xf0,
330 }; 367 };
331 368
332 of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 369 of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd);
333} 370}
334CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock", 371CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
335 of_ti_omap3_core_dpll_setup); 372 of_ti_omap3_core_dpll_setup);
@@ -349,7 +386,7 @@ static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
349 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), 386 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
350 }; 387 };
351 388
352 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 389 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
353} 390}
354CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock", 391CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
355 of_ti_omap3_per_dpll_setup); 392 of_ti_omap3_per_dpll_setup);
@@ -371,7 +408,7 @@ static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
371 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), 408 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
372 }; 409 };
373 410
374 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 411 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd);
375} 412}
376CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock", 413CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
377 of_ti_omap3_per_jtype_dpll_setup); 414 of_ti_omap3_per_jtype_dpll_setup);
@@ -391,11 +428,32 @@ static void __init of_ti_omap4_dpll_setup(struct device_node *node)
391 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 428 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
392 }; 429 };
393 430
394 of_ti_dpll_setup(node, &dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 431 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
395} 432}
396CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock", 433CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
397 of_ti_omap4_dpll_setup); 434 of_ti_omap4_dpll_setup);
398 435
436static void __init of_ti_omap5_mpu_dpll_setup(struct device_node *node)
437{
438 const struct dpll_data dd = {
439 .idlest_mask = 0x1,
440 .enable_mask = 0x7,
441 .autoidle_mask = 0x7,
442 .mult_mask = 0x7ff << 8,
443 .div1_mask = 0x7f,
444 .max_multiplier = 2047,
445 .max_divider = 128,
446 .dcc_mask = BIT(22),
447 .dcc_rate = 1400000000, /* DCC beyond 1.4GHz */
448 .min_divider = 1,
449 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
450 };
451
452 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
453}
454CLK_OF_DECLARE(of_ti_omap5_mpu_dpll_clock, "ti,omap5-mpu-dpll-clock",
455 of_ti_omap5_mpu_dpll_setup);
456
399static void __init of_ti_omap4_core_dpll_setup(struct device_node *node) 457static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
400{ 458{
401 const struct dpll_data dd = { 459 const struct dpll_data dd = {
@@ -410,7 +468,7 @@ static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
410 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 468 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
411 }; 469 };
412 470
413 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 471 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
414} 472}
415CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock", 473CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
416 of_ti_omap4_core_dpll_setup); 474 of_ti_omap4_core_dpll_setup);
@@ -433,7 +491,7 @@ static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
433 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 491 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
434 }; 492 };
435 493
436 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 494 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
437} 495}
438CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock", 496CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
439 of_ti_omap4_m4xen_dpll_setup); 497 of_ti_omap4_m4xen_dpll_setup);
@@ -454,7 +512,7 @@ static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
454 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 512 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
455 }; 513 };
456 514
457 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE); 515 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd);
458} 516}
459CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock", 517CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
460 of_ti_omap4_jtype_dpll_setup); 518 of_ti_omap4_jtype_dpll_setup);
@@ -465,7 +523,6 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
465 const struct dpll_data dd = { 523 const struct dpll_data dd = {
466 .idlest_mask = 0x1, 524 .idlest_mask = 0x1,
467 .enable_mask = 0x7, 525 .enable_mask = 0x7,
468 .autoidle_mask = 0x7,
469 .mult_mask = 0x7ff << 8, 526 .mult_mask = 0x7ff << 8,
470 .div1_mask = 0x7f, 527 .div1_mask = 0x7f,
471 .max_multiplier = 2047, 528 .max_multiplier = 2047,
@@ -474,7 +531,7 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
474 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 531 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
475 }; 532 };
476 533
477 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); 534 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
478} 535}
479CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock", 536CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
480 of_ti_am3_no_gate_dpll_setup); 537 of_ti_am3_no_gate_dpll_setup);
@@ -484,7 +541,6 @@ static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
484 const struct dpll_data dd = { 541 const struct dpll_data dd = {
485 .idlest_mask = 0x1, 542 .idlest_mask = 0x1,
486 .enable_mask = 0x7, 543 .enable_mask = 0x7,
487 .autoidle_mask = 0x7,
488 .mult_mask = 0x7ff << 8, 544 .mult_mask = 0x7ff << 8,
489 .div1_mask = 0x7f, 545 .div1_mask = 0x7f,
490 .max_multiplier = 4095, 546 .max_multiplier = 4095,
@@ -494,7 +550,7 @@ static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
494 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 550 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
495 }; 551 };
496 552
497 of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); 553 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
498} 554}
499CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock", 555CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
500 of_ti_am3_jtype_dpll_setup); 556 of_ti_am3_jtype_dpll_setup);
@@ -504,7 +560,6 @@ static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
504 const struct dpll_data dd = { 560 const struct dpll_data dd = {
505 .idlest_mask = 0x1, 561 .idlest_mask = 0x1,
506 .enable_mask = 0x7, 562 .enable_mask = 0x7,
507 .autoidle_mask = 0x7,
508 .mult_mask = 0x7ff << 8, 563 .mult_mask = 0x7ff << 8,
509 .div1_mask = 0x7f, 564 .div1_mask = 0x7f,
510 .max_multiplier = 2047, 565 .max_multiplier = 2047,
@@ -514,7 +569,7 @@ static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
514 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 569 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
515 }; 570 };
516 571
517 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0); 572 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd);
518} 573}
519CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock, 574CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
520 "ti,am3-dpll-no-gate-j-type-clock", 575 "ti,am3-dpll-no-gate-j-type-clock",
@@ -525,7 +580,6 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node)
525 const struct dpll_data dd = { 580 const struct dpll_data dd = {
526 .idlest_mask = 0x1, 581 .idlest_mask = 0x1,
527 .enable_mask = 0x7, 582 .enable_mask = 0x7,
528 .autoidle_mask = 0x7,
529 .mult_mask = 0x7ff << 8, 583 .mult_mask = 0x7ff << 8,
530 .div1_mask = 0x7f, 584 .div1_mask = 0x7f,
531 .max_multiplier = 2047, 585 .max_multiplier = 2047,
@@ -534,7 +588,7 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node)
534 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 588 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
535 }; 589 };
536 590
537 of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0); 591 of_ti_dpll_setup(node, &dpll_ck_ops, &dd);
538} 592}
539CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup); 593CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
540 594
@@ -543,7 +597,6 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
543 const struct dpll_data dd = { 597 const struct dpll_data dd = {
544 .idlest_mask = 0x1, 598 .idlest_mask = 0x1,
545 .enable_mask = 0x7, 599 .enable_mask = 0x7,
546 .autoidle_mask = 0x7,
547 .mult_mask = 0x7ff << 8, 600 .mult_mask = 0x7ff << 8,
548 .div1_mask = 0x7f, 601 .div1_mask = 0x7f,
549 .max_multiplier = 2047, 602 .max_multiplier = 2047,
@@ -552,7 +605,22 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
552 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 605 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
553 }; 606 };
554 607
555 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, 0); 608 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd);
556} 609}
557CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", 610CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
558 of_ti_am3_core_dpll_setup); 611 of_ti_am3_core_dpll_setup);
612
613static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
614{
615 const struct dpll_data dd = {
616 .enable_mask = 0x3,
617 .mult_mask = 0x3ff << 12,
618 .div1_mask = 0xf << 8,
619 .max_divider = 16,
620 .min_divider = 1,
621 };
622
623 of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
624}
625CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
626 of_ti_omap2_core_dpll_setup);