diff options
| -rw-r--r-- | arch/arm/mach-omap2/cclock3xxx_data.c | 6 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clock.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clock.h | 1 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clock3xxx.c | 38 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 179 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/dpll44xx.c | 41 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 2 | ||||
| -rw-r--r-- | drivers/clk/ti/dpll.c | 15 | ||||
| -rw-r--r-- | include/linux/clk/ti.h | 15 |
9 files changed, 238 insertions, 63 deletions
diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c index eb8c75ec3b1a..5c5ebb4db5f7 100644 --- a/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/arch/arm/mach-omap2/cclock3xxx_data.c | |||
| @@ -257,6 +257,9 @@ static const struct clk_ops dpll1_ck_ops = { | |||
| 257 | .get_parent = &omap2_init_dpll_parent, | 257 | .get_parent = &omap2_init_dpll_parent, |
| 258 | .recalc_rate = &omap3_dpll_recalc, | 258 | .recalc_rate = &omap3_dpll_recalc, |
| 259 | .set_rate = &omap3_noncore_dpll_set_rate, | 259 | .set_rate = &omap3_noncore_dpll_set_rate, |
| 260 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
| 261 | .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, | ||
| 262 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
| 260 | .round_rate = &omap2_dpll_round_rate, | 263 | .round_rate = &omap2_dpll_round_rate, |
| 261 | }; | 264 | }; |
| 262 | 265 | ||
| @@ -367,6 +370,9 @@ static const struct clk_ops dpll4_ck_ops = { | |||
| 367 | .get_parent = &omap2_init_dpll_parent, | 370 | .get_parent = &omap2_init_dpll_parent, |
| 368 | .recalc_rate = &omap3_dpll_recalc, | 371 | .recalc_rate = &omap3_dpll_recalc, |
| 369 | .set_rate = &omap3_dpll4_set_rate, | 372 | .set_rate = &omap3_dpll4_set_rate, |
| 373 | .set_parent = &omap3_noncore_dpll_set_parent, | ||
| 374 | .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent, | ||
| 375 | .determine_rate = &omap3_noncore_dpll_determine_rate, | ||
| 370 | .round_rate = &omap2_dpll_round_rate, | 376 | .round_rate = &omap2_dpll_round_rate, |
| 371 | }; | 377 | }; |
| 372 | 378 | ||
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 500530d1364a..c2b239857cc4 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
| @@ -771,4 +771,8 @@ void __init ti_clk_init_features(void) | |||
| 771 | ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; | 771 | ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; |
| 772 | else if (cpu_is_omap34xx()) | 772 | else if (cpu_is_omap34xx()) |
| 773 | ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; | 773 | ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; |
| 774 | |||
| 775 | /* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */ | ||
| 776 | if (omap_rev() == OMAP3430_REV_ES1_0) | ||
| 777 | ti_clk_features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM; | ||
| 774 | } | 778 | } |
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 4592a2762592..641337c6cde9 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
| @@ -234,6 +234,7 @@ struct ti_clk_features { | |||
| 234 | }; | 234 | }; |
| 235 | 235 | ||
| 236 | #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) | 236 | #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) |
| 237 | #define TI_CLK_DPLL4_DENY_REPROGRAM (1 << 1) | ||
| 237 | 238 | ||
| 238 | extern struct ti_clk_features ti_clk_features; | 239 | extern struct ti_clk_features ti_clk_features; |
| 239 | 240 | ||
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c index 0b02b4161d71..a9e86db5daf9 100644 --- a/arch/arm/mach-omap2/clock3xxx.c +++ b/arch/arm/mach-omap2/clock3xxx.c | |||
| @@ -38,6 +38,18 @@ | |||
| 38 | 38 | ||
| 39 | /* needed by omap3_core_dpll_m2_set_rate() */ | 39 | /* needed by omap3_core_dpll_m2_set_rate() */ |
| 40 | struct clk *sdrc_ick_p, *arm_fck_p; | 40 | struct clk *sdrc_ick_p, *arm_fck_p; |
| 41 | |||
| 42 | /** | ||
| 43 | * omap3_dpll4_set_rate - set rate for omap3 per-dpll | ||
| 44 | * @hw: clock to change | ||
| 45 | * @rate: target rate for clock | ||
| 46 | * @parent_rate: rate of the parent clock | ||
| 47 | * | ||
| 48 | * Check if the current SoC supports the per-dpll reprogram operation | ||
| 49 | * or not, and then do the rate change if supported. Returns -EINVAL | ||
| 50 | * if not supported, 0 for success, and potential error codes from the | ||
| 51 | * clock rate change. | ||
| 52 | */ | ||
| 41 | int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, | 53 | int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, |
| 42 | unsigned long parent_rate) | 54 | unsigned long parent_rate) |
| 43 | { | 55 | { |
| @@ -46,7 +58,7 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 46 | * on 3430ES1 prevents us from changing DPLL multipliers or dividers | 58 | * on 3430ES1 prevents us from changing DPLL multipliers or dividers |
| 47 | * on DPLL4. | 59 | * on DPLL4. |
| 48 | */ | 60 | */ |
| 49 | if (omap_rev() == OMAP3430_REV_ES1_0) { | 61 | if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) { |
| 50 | pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); | 62 | pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); |
| 51 | return -EINVAL; | 63 | return -EINVAL; |
| 52 | } | 64 | } |
| @@ -54,6 +66,30 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 54 | return omap3_noncore_dpll_set_rate(hw, rate, parent_rate); | 66 | return omap3_noncore_dpll_set_rate(hw, rate, parent_rate); |
| 55 | } | 67 | } |
| 56 | 68 | ||
| 69 | /** | ||
| 70 | * omap3_dpll4_set_rate_and_parent - set rate and parent for omap3 per-dpll | ||
| 71 | * @hw: clock to change | ||
| 72 | * @rate: target rate for clock | ||
| 73 | * @parent_rate: rate of the parent clock | ||
| 74 | * @index: parent index, 0 - reference clock, 1 - bypass clock | ||
| 75 | * | ||
| 76 | * Check if the current SoC support the per-dpll reprogram operation | ||
| 77 | * or not, and then do the rate + parent change if supported. Returns | ||
| 78 | * -EINVAL if not supported, 0 for success, and potential error codes | ||
| 79 | * from the clock rate change. | ||
| 80 | */ | ||
| 81 | int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, | ||
| 82 | unsigned long parent_rate, u8 index) | ||
| 83 | { | ||
| 84 | if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) { | ||
| 85 | pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); | ||
| 86 | return -EINVAL; | ||
| 87 | } | ||
| 88 | |||
| 89 | return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate, | ||
| 90 | index); | ||
| 91 | } | ||
| 92 | |||
| 57 | void __init omap3_clk_lock_dpll5(void) | 93 | void __init omap3_clk_lock_dpll5(void) |
| 58 | { | 94 | { |
| 59 | struct clk *dpll5_clk; | 95 | struct clk *dpll5_clk; |
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index ac3d789ac3cd..20e120d071dd 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c | |||
| @@ -460,25 +460,24 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw) | |||
| 460 | /* Non-CORE DPLL rate set code */ | 460 | /* Non-CORE DPLL rate set code */ |
| 461 | 461 | ||
| 462 | /** | 462 | /** |
| 463 | * omap3_noncore_dpll_set_rate - set non-core DPLL rate | 463 | * omap3_noncore_dpll_determine_rate - determine rate for a DPLL |
| 464 | * @clk: struct clk * of DPLL to set | 464 | * @hw: pointer to the clock to determine rate for |
| 465 | * @rate: rounded target rate | 465 | * @rate: target rate for the DPLL |
| 466 | * @best_parent_rate: pointer for returning best parent rate | ||
| 467 | * @best_parent_clk: pointer for returning best parent clock | ||
| 466 | * | 468 | * |
| 467 | * Set the DPLL CLKOUT to the target rate. If the DPLL can enter | 469 | * Determines which DPLL mode to use for reaching a desired target rate. |
| 468 | * low-power bypass, and the target rate is the bypass source clock | 470 | * Checks whether the DPLL shall be in bypass or locked mode, and if |
| 469 | * rate, then configure the DPLL for bypass. Otherwise, round the | 471 | * locked, calculates the M,N values for the DPLL via round-rate. |
| 470 | * target rate if it hasn't been done already, then program and lock | 472 | * Returns a positive clock rate with success, negative error value |
| 471 | * the DPLL. Returns -EINVAL upon error, or 0 upon success. | 473 | * in failure. |
| 472 | */ | 474 | */ |
| 473 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | 475 | long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate, |
| 474 | unsigned long parent_rate) | 476 | unsigned long *best_parent_rate, |
| 477 | struct clk **best_parent_clk) | ||
| 475 | { | 478 | { |
| 476 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | 479 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); |
| 477 | struct clk *new_parent = NULL; | ||
| 478 | unsigned long rrate; | ||
| 479 | u16 freqsel = 0; | ||
| 480 | struct dpll_data *dd; | 480 | struct dpll_data *dd; |
| 481 | int ret; | ||
| 482 | 481 | ||
| 483 | if (!hw || !rate) | 482 | if (!hw || !rate) |
| 484 | return -EINVAL; | 483 | return -EINVAL; |
| @@ -489,61 +488,121 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 489 | 488 | ||
| 490 | if (__clk_get_rate(dd->clk_bypass) == rate && | 489 | if (__clk_get_rate(dd->clk_bypass) == rate && |
| 491 | (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { | 490 | (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { |
| 492 | pr_debug("%s: %s: set rate: entering bypass.\n", | 491 | *best_parent_clk = dd->clk_bypass; |
| 493 | __func__, __clk_get_name(hw->clk)); | 492 | } else { |
| 493 | rate = omap2_dpll_round_rate(hw, rate, best_parent_rate); | ||
| 494 | *best_parent_clk = dd->clk_ref; | ||
| 495 | } | ||
| 496 | |||
| 497 | *best_parent_rate = rate; | ||
| 498 | |||
| 499 | return rate; | ||
| 500 | } | ||
| 501 | |||
| 502 | /** | ||
| 503 | * omap3_noncore_dpll_set_parent - set parent for a DPLL clock | ||
| 504 | * @hw: pointer to the clock to set parent for | ||
| 505 | * @index: parent index to select | ||
| 506 | * | ||
| 507 | * Sets parent for a DPLL clock. This sets the DPLL into bypass or | ||
| 508 | * locked mode. Returns 0 with success, negative error value otherwise. | ||
| 509 | */ | ||
| 510 | int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index) | ||
| 511 | { | ||
| 512 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | ||
| 513 | int ret; | ||
| 494 | 514 | ||
| 495 | __clk_prepare(dd->clk_bypass); | 515 | if (!hw) |
| 496 | clk_enable(dd->clk_bypass); | 516 | return -EINVAL; |
| 517 | |||
| 518 | if (index) | ||
| 497 | ret = _omap3_noncore_dpll_bypass(clk); | 519 | ret = _omap3_noncore_dpll_bypass(clk); |
| 498 | if (!ret) | 520 | else |
| 499 | new_parent = dd->clk_bypass; | 521 | ret = _omap3_noncore_dpll_lock(clk); |
| 500 | clk_disable(dd->clk_bypass); | ||
| 501 | __clk_unprepare(dd->clk_bypass); | ||
| 502 | } else { | ||
| 503 | __clk_prepare(dd->clk_ref); | ||
| 504 | clk_enable(dd->clk_ref); | ||
| 505 | |||
| 506 | /* XXX this check is probably pointless in the CCF context */ | ||
| 507 | if (dd->last_rounded_rate != rate) { | ||
| 508 | rrate = __clk_round_rate(hw->clk, rate); | ||
| 509 | if (rrate != rate) { | ||
| 510 | pr_warn("%s: %s: final rate %lu does not match desired rate %lu\n", | ||
| 511 | __func__, __clk_get_name(hw->clk), | ||
| 512 | rrate, rate); | ||
| 513 | rate = rrate; | ||
| 514 | } | ||
| 515 | } | ||
| 516 | 522 | ||
| 517 | if (dd->last_rounded_rate == 0) | 523 | return ret; |
| 518 | return -EINVAL; | 524 | } |
| 519 | 525 | ||
| 520 | /* Freqsel is available only on OMAP343X devices */ | 526 | /** |
| 521 | if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) { | 527 | * omap3_noncore_dpll_set_rate - set rate for a DPLL clock |
| 522 | freqsel = _omap3_dpll_compute_freqsel(clk, | 528 | * @hw: pointer to the clock to set parent for |
| 523 | dd->last_rounded_n); | 529 | * @rate: target rate for the clock |
| 524 | WARN_ON(!freqsel); | 530 | * @parent_rate: rate of the parent clock |
| 525 | } | 531 | * |
| 532 | * Sets rate for a DPLL clock. First checks if the clock parent is | ||
| 533 | * reference clock (in bypass mode, the rate of the clock can't be | ||
| 534 | * changed) and proceeds with the rate change operation. Returns 0 | ||
| 535 | * with success, negative error value otherwise. | ||
| 536 | */ | ||
| 537 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
| 538 | unsigned long parent_rate) | ||
| 539 | { | ||
| 540 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | ||
| 541 | struct dpll_data *dd; | ||
| 542 | u16 freqsel = 0; | ||
| 543 | int ret; | ||
| 544 | |||
| 545 | if (!hw || !rate) | ||
| 546 | return -EINVAL; | ||
| 547 | |||
| 548 | dd = clk->dpll_data; | ||
| 549 | if (!dd) | ||
| 550 | return -EINVAL; | ||
| 526 | 551 | ||
| 527 | pr_debug("%s: %s: set rate: locking rate to %lu.\n", | 552 | if (__clk_get_parent(hw->clk) != dd->clk_ref) |
| 528 | __func__, __clk_get_name(hw->clk), rate); | 553 | return -EINVAL; |
| 554 | |||
| 555 | if (dd->last_rounded_rate == 0) | ||
| 556 | return -EINVAL; | ||
| 529 | 557 | ||
| 530 | ret = omap3_noncore_dpll_program(clk, freqsel); | 558 | /* Freqsel is available only on OMAP343X devices */ |
| 531 | if (!ret) | 559 | if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) { |
| 532 | new_parent = dd->clk_ref; | 560 | freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n); |
| 533 | clk_disable(dd->clk_ref); | 561 | WARN_ON(!freqsel); |
| 534 | __clk_unprepare(dd->clk_ref); | ||
| 535 | } | 562 | } |
| 536 | /* | ||
| 537 | * FIXME - this is all wrong. common code handles reparenting and | ||
| 538 | * migrating prepare/enable counts. dplls should be a multiplexer | ||
| 539 | * clock and this should be a set_parent operation so that all of that | ||
| 540 | * stuff is inherited for free | ||
| 541 | */ | ||
| 542 | 563 | ||
| 543 | if (!ret && clk_get_parent(hw->clk) != new_parent) | 564 | pr_debug("%s: %s: set rate: locking rate to %lu.\n", __func__, |
| 544 | __clk_reparent(hw->clk, new_parent); | 565 | __clk_get_name(hw->clk), rate); |
| 545 | 566 | ||
| 546 | return 0; | 567 | ret = omap3_noncore_dpll_program(clk, freqsel); |
| 568 | |||
| 569 | return ret; | ||
| 570 | } | ||
| 571 | |||
| 572 | /** | ||
| 573 | * omap3_noncore_dpll_set_rate_and_parent - set rate and parent for a DPLL clock | ||
| 574 | * @hw: pointer to the clock to set rate and parent for | ||
| 575 | * @rate: target rate for the DPLL | ||
| 576 | * @parent_rate: clock rate of the DPLL parent | ||
| 577 | * @index: new parent index for the DPLL, 0 - reference, 1 - bypass | ||
| 578 | * | ||
| 579 | * Sets rate and parent for a DPLL clock. If new parent is the bypass | ||
| 580 | * clock, only selects the parent. Otherwise proceeds with a rate | ||
| 581 | * change, as this will effectively also change the parent as the | ||
| 582 | * DPLL is put into locked mode. Returns 0 with success, negative error | ||
| 583 | * value otherwise. | ||
| 584 | */ | ||
| 585 | int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw, | ||
| 586 | unsigned long rate, | ||
| 587 | unsigned long parent_rate, | ||
| 588 | u8 index) | ||
| 589 | { | ||
| 590 | int ret; | ||
| 591 | |||
| 592 | if (!hw || !rate) | ||
| 593 | return -EINVAL; | ||
| 594 | |||
| 595 | /* | ||
| 596 | * clk-ref at index[0], in which case we only need to set rate, | ||
| 597 | * the parent will be changed automatically with the lock sequence. | ||
| 598 | * With clk-bypass case we only need to change parent. | ||
| 599 | */ | ||
| 600 | if (index) | ||
| 601 | ret = omap3_noncore_dpll_set_parent(hw, index); | ||
| 602 | else | ||
| 603 | ret = omap3_noncore_dpll_set_rate(hw, rate, parent_rate); | ||
| 604 | |||
| 605 | return ret; | ||
| 547 | } | 606 | } |
| 548 | 607 | ||
| 549 | /* DPLL autoidle read/set code */ | 608 | /* DPLL autoidle read/set code */ |
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c index 4613f1e86988..535822fcf4bb 100644 --- a/arch/arm/mach-omap2/dpll44xx.c +++ b/arch/arm/mach-omap2/dpll44xx.c | |||
| @@ -207,3 +207,44 @@ out: | |||
| 207 | 207 | ||
| 208 | return dd->last_rounded_rate; | 208 | return dd->last_rounded_rate; |
| 209 | } | 209 | } |
| 210 | |||
| 211 | /** | ||
| 212 | * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL | ||
| 213 | * @hw: pointer to the clock to determine rate for | ||
| 214 | * @rate: target rate for the DPLL | ||
| 215 | * @best_parent_rate: pointer for returning best parent rate | ||
| 216 | * @best_parent_clk: pointer for returning best parent clock | ||
| 217 | * | ||
| 218 | * Determines which DPLL mode to use for reaching a desired rate. | ||
| 219 | * Checks whether the DPLL shall be in bypass or locked mode, and if | ||
| 220 | * locked, calculates the M,N values for the DPLL via round-rate. | ||
| 221 | * Returns a positive clock rate with success, negative error value | ||
| 222 | * in failure. | ||
| 223 | */ | ||
| 224 | long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate, | ||
| 225 | unsigned long *best_parent_rate, | ||
| 226 | struct clk **best_parent_clk) | ||
| 227 | { | ||
| 228 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | ||
| 229 | struct dpll_data *dd; | ||
| 230 | |||
| 231 | if (!hw || !rate) | ||
| 232 | return -EINVAL; | ||
| 233 | |||
| 234 | dd = clk->dpll_data; | ||
| 235 | if (!dd) | ||
| 236 | return -EINVAL; | ||
| 237 | |||
| 238 | if (__clk_get_rate(dd->clk_bypass) == rate && | ||
| 239 | (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { | ||
| 240 | *best_parent_clk = dd->clk_bypass; | ||
| 241 | } else { | ||
| 242 | rate = omap4_dpll_regm4xen_round_rate(hw, rate, | ||
| 243 | best_parent_rate); | ||
| 244 | *best_parent_clk = dd->clk_ref; | ||
| 245 | } | ||
| 246 | |||
| 247 | *best_parent_rate = rate; | ||
| 248 | |||
| 249 | return rate; | ||
| 250 | } | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 716247ed9e0c..acae6d5d1151 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
| @@ -2832,12 +2832,10 @@ static int __init _add_link(struct omap_hwmod_ocp_if *oi) | |||
| 2832 | _alloc_links(&ml, &sl); | 2832 | _alloc_links(&ml, &sl); |
| 2833 | 2833 | ||
| 2834 | ml->ocp_if = oi; | 2834 | ml->ocp_if = oi; |
| 2835 | INIT_LIST_HEAD(&ml->node); | ||
| 2836 | list_add(&ml->node, &oi->master->master_ports); | 2835 | list_add(&ml->node, &oi->master->master_ports); |
| 2837 | oi->master->masters_cnt++; | 2836 | oi->master->masters_cnt++; |
| 2838 | 2837 | ||
| 2839 | sl->ocp_if = oi; | 2838 | sl->ocp_if = oi; |
| 2840 | INIT_LIST_HEAD(&sl->node); | ||
| 2841 | list_add(&sl->node, &oi->slave->slave_ports); | 2839 | list_add(&sl->node, &oi->slave->slave_ports); |
| 2842 | oi->slave->slaves_cnt++; | 2840 | oi->slave->slaves_cnt++; |
| 2843 | 2841 | ||
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 79791e1bf282..85ac0dd501de 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c | |||
| @@ -33,6 +33,9 @@ static const struct clk_ops dpll_m4xen_ck_ops = { | |||
| 33 | .recalc_rate = &omap4_dpll_regm4xen_recalc, | 33 | .recalc_rate = &omap4_dpll_regm4xen_recalc, |
| 34 | .round_rate = &omap4_dpll_regm4xen_round_rate, | 34 | .round_rate = &omap4_dpll_regm4xen_round_rate, |
| 35 | .set_rate = &omap3_noncore_dpll_set_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, | ||
| 36 | .get_parent = &omap2_init_dpll_parent, | 39 | .get_parent = &omap2_init_dpll_parent, |
| 37 | }; | 40 | }; |
| 38 | #else | 41 | #else |
| @@ -53,6 +56,9 @@ static const struct clk_ops dpll_ck_ops = { | |||
| 53 | .recalc_rate = &omap3_dpll_recalc, | 56 | .recalc_rate = &omap3_dpll_recalc, |
| 54 | .round_rate = &omap2_dpll_round_rate, | 57 | .round_rate = &omap2_dpll_round_rate, |
| 55 | .set_rate = &omap3_noncore_dpll_set_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, | ||
| 56 | .get_parent = &omap2_init_dpll_parent, | 62 | .get_parent = &omap2_init_dpll_parent, |
| 57 | }; | 63 | }; |
| 58 | 64 | ||
| @@ -61,6 +67,9 @@ static const struct clk_ops dpll_no_gate_ck_ops = { | |||
| 61 | .get_parent = &omap2_init_dpll_parent, | 67 | .get_parent = &omap2_init_dpll_parent, |
| 62 | .round_rate = &omap2_dpll_round_rate, | 68 | .round_rate = &omap2_dpll_round_rate, |
| 63 | .set_rate = &omap3_noncore_dpll_set_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, | ||
| 64 | }; | 73 | }; |
| 65 | #else | 74 | #else |
| 66 | static const struct clk_ops dpll_core_ck_ops = {}; | 75 | static const struct clk_ops dpll_core_ck_ops = {}; |
| @@ -97,6 +106,9 @@ static const struct clk_ops omap3_dpll_ck_ops = { | |||
| 97 | .get_parent = &omap2_init_dpll_parent, | 106 | .get_parent = &omap2_init_dpll_parent, |
| 98 | .recalc_rate = &omap3_dpll_recalc, | 107 | .recalc_rate = &omap3_dpll_recalc, |
| 99 | .set_rate = &omap3_noncore_dpll_set_rate, | 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, | ||
| 100 | .round_rate = &omap2_dpll_round_rate, | 112 | .round_rate = &omap2_dpll_round_rate, |
| 101 | }; | 113 | }; |
| 102 | 114 | ||
| @@ -106,6 +118,9 @@ static const struct clk_ops omap3_dpll_per_ck_ops = { | |||
| 106 | .get_parent = &omap2_init_dpll_parent, | 118 | .get_parent = &omap2_init_dpll_parent, |
| 107 | .recalc_rate = &omap3_dpll_recalc, | 119 | .recalc_rate = &omap3_dpll_recalc, |
| 108 | .set_rate = &omap3_dpll4_set_rate, | 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, | ||
| 109 | .round_rate = &omap2_dpll_round_rate, | 124 | .round_rate = &omap2_dpll_round_rate, |
| 110 | }; | 125 | }; |
| 111 | #endif | 126 | #endif |
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index f75acbf70e96..74e5341463c9 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h | |||
| @@ -254,13 +254,26 @@ extern const struct clk_ops ti_clk_mux_ops; | |||
| 254 | void omap2_init_clk_hw_omap_clocks(struct clk *clk); | 254 | void omap2_init_clk_hw_omap_clocks(struct clk *clk); |
| 255 | int omap3_noncore_dpll_enable(struct clk_hw *hw); | 255 | int omap3_noncore_dpll_enable(struct clk_hw *hw); |
| 256 | void omap3_noncore_dpll_disable(struct clk_hw *hw); | 256 | void omap3_noncore_dpll_disable(struct clk_hw *hw); |
| 257 | int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index); | ||
| 257 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | 258 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, |
| 258 | unsigned long parent_rate); | 259 | unsigned long parent_rate); |
| 260 | int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw, | ||
| 261 | unsigned long rate, | ||
| 262 | unsigned long parent_rate, | ||
| 263 | u8 index); | ||
| 264 | long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, | ||
| 265 | unsigned long rate, | ||
| 266 | unsigned long *best_parent_rate, | ||
| 267 | struct clk **best_parent_clk); | ||
| 259 | unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, | 268 | unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, |
| 260 | unsigned long parent_rate); | 269 | unsigned long parent_rate); |
| 261 | long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, | 270 | long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, |
| 262 | unsigned long target_rate, | 271 | unsigned long target_rate, |
| 263 | unsigned long *parent_rate); | 272 | unsigned long *parent_rate); |
| 273 | long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, | ||
| 274 | unsigned long rate, | ||
| 275 | unsigned long *best_parent_rate, | ||
| 276 | struct clk **best_parent_clk); | ||
| 264 | u8 omap2_init_dpll_parent(struct clk_hw *hw); | 277 | u8 omap2_init_dpll_parent(struct clk_hw *hw); |
| 265 | unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); | 278 | unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); |
| 266 | long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, | 279 | long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, |
| @@ -278,6 +291,8 @@ int omap2_clk_disable_autoidle_all(void); | |||
| 278 | void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); | 291 | void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); |
| 279 | int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, | 292 | int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, |
| 280 | unsigned long parent_rate); | 293 | unsigned long parent_rate); |
| 294 | int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, | ||
| 295 | unsigned long parent_rate, u8 index); | ||
| 281 | int omap2_dflt_clk_enable(struct clk_hw *hw); | 296 | int omap2_dflt_clk_enable(struct clk_hw *hw); |
| 282 | void omap2_dflt_clk_disable(struct clk_hw *hw); | 297 | void omap2_dflt_clk_disable(struct clk_hw *hw); |
| 283 | int omap2_dflt_clk_is_enabled(struct clk_hw *hw); | 298 | int omap2_dflt_clk_is_enabled(struct clk_hw *hw); |
