diff options
author | Rajendra Nayak <rnayak@ti.com> | 2013-08-23 06:48:42 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2013-08-23 06:48:42 -0400 |
commit | eeb6603fdde253a8e9129712ce24128d732bd4e7 (patch) | |
tree | f518b8de3d450a0c038f965cd2ccce8cd3170084 | |
parent | b36f4be3de1b123d8601de062e7dbfc904f305fb (diff) |
ARM: OMAP4: clock: Lock PLLs in the right sequence
On OMAP4 we have clk_set_rate()s being done for a few
DPLL clock nodes, as part of the clock init code, since
the bootloaders no longer locks these DPLLs.
So we have a clk_set_rate() done for a ABE DPLL node (which
inturn locks it) followed by a clk_set_rate() for the USB DPLL.
With USB DPLL being in bypass, we have this parent->child
relationship thats formed while the clocks get registered.
dpll_abe_ck
|
V
dpll_abe_x2_ck
|
V
dpll_abe_m3x2_ck
|
V
usb_hs_clk_div_ck
|
V
dpll_usb_ck
This is because usb_hs_clk_div_ck is bypass clock for dpll_usb_ck.
So with this parent->child relationship in place, a clk_set_rate()
on ABE DPLL results eventually in a clk_set_rate() call on USB DPLL,
because CCF does a clk_change_rate() (as part of clk_set_rate()) on
all downstream clocks resulting from a rate change on the top clock.
So its important that we lock USB DPLL before we lock ABE DPLL.
Without which we see these error logs at boot.
[These error logs will not be seen if using a bootloader that locks
USB DPLL]
[ 0.000000] clock: dpll_usb_ck failed transition to 'locked'
[ 0.000000] Division by zero in kernel.
[ 0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.0-03445-gfb2af00-dirty #7
[ 0.000000] [<c001bfe8>] (unwind_backtrace+0x0/0xf4) from [<c001868c>] (show_stack+0x10/0x14)
[ 0.000000] [<c001868c>] (show_stack+0x10/0x14) from [<c02deb28>] (Ldiv0+0x8/0x10)
[ 0.000000] [<c02deb28>] (Ldiv0+0x8/0x10) from [<c0477030>] (clk_divider_set_rate+0x10/0x114)
[ 0.000000] [<c0477030>] (clk_divider_set_rate+0x10/0x114) from [<c0476ef4>] (clk_change_rate+0x38/0xb8)
[ 0.000000] [<c0476ef4>] (clk_change_rate+0x38/0xb8) from [<c0476f5c>] (clk_change_rate+0xa0/0xb8)
[ 0.000000] Division by zero in kernel.
[ 0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.0-03445-gfb2af00-dirty #7
[ 0.000000] [<c001bfe8>] (unwind_backtrace+0x0/0xf4) from [<c001868c>] (show_stack+0x10/0x14)
[ 0.000000] [<c001868c>] (show_stack+0x10/0x14) from [<c02deb28>] (Ldiv0+0x8/0x10)
[ 0.000000] [<c02deb28>] (Ldiv0+0x8/0x10) from [<c0477030>] (clk_divider_set_rate+0x10/0x114)
[ 0.000000] [<c0477030>] (clk_divider_set_rate+0x10/0x114) from [<c0476ef4>] (clk_change_rate+0x38/0xb8)
[ 0.000000] [<c0476ef4>] (clk_change_rate+0x38/0xb8) from [<c0476f5c>] (clk_change_rate+0xa0/0xb8)
[ 0.000000] Division by zero in kernel.
[ 0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.0-03445-gfb2af00-dirty #7
[ 0.000000] [<c001bfe8>] (unwind_backtrace+0x0/0xf4) from [<c001868c>] (show_stack+0x10/0x14)
[ 0.000000] [<c001868c>] (show_stack+0x10/0x14) from [<c02deb28>] (Ldiv0+0x8/0x10)
[ 0.000000] [<c02deb28>] (Ldiv0+0x8/0x10) from [<c0477030>] (clk_divider_set_rate+0x10/0x114)
[ 0.000000] [<c0477030>] (clk_divider_set_rate+0x10/0x114) from [<c0476ef4>] (clk_change_rate+0x38/0xb8)
[ 0.000000] [<c0476ef4>] (clk_change_rate+0x38/0xb8) from [<c0476f5c>] (clk_change_rate+0xa0/0xb8)
[ 0.000000] Division by zero in kernel.
[ 0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.0-03445-gfb2af00-dirty #7
[ 0.000000] [<c001bfe8>] (unwind_backtrace+0x0/0xf4) from [<c001868c>] (show_stack+0x10/0x14)
[ 0.000000] [<c001868c>] (show_stack+0x10/0x14) from [<c02deb28>] (Ldiv0+0x8/0x10)
[ 0.000000] [<c02deb28>] (Ldiv0+0x8/0x10) from [<c0477030>] (clk_divider_set_rate+0x10/0x114)
[ 0.000000] [<c0477030>] (clk_divider_set_rate+0x10/0x114) from [<c0476ef4>] (clk_change_rate+0x38/0xb8)
[ 0.000000] [<c0476ef4>] (clk_change_rate+0x38/0xb8) from [<c0476f5c>] (clk_change_rate+0xa0/0xb8)
[ 0.000000] Division by zero in kernel.
[ 0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.0-03445-gfb2af00-dirty #7
[ 0.000000] [<c001bfe8>] (unwind_backtrace+0x0/0xf4) from [<c001868c>] (show_stack+0x10/0x14)
[ 0.000000] [<c001868c>] (show_stack+0x10/0x14) from [<c02deb28>] (Ldiv0+0x8/0x10)
[ 0.000000] [<c02deb28>] (Ldiv0+0x8/0x10) from [<c0477030>] (clk_divider_set_rate+0x10/0x114)
[ 0.000000] [<c0477030>] (clk_divider_set_rate+0x10/0x114) from [<c0476ef4>] (clk_change_rate+0x38/0xb8)
[ 0.000000] [<c0476ef4>] (clk_change_rate+0x38/0xb8) from [<c0476f5c>] (clk_change_rate+0xa0/0xb8)
[ 0.000000] Division by zero in kernel.
[ 0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.0-03445-gfb2af00-dirty #7
[ 0.000000] [<c001bfe8>] (unwind_backtrace+0x0/0xf4) from [<c001868c>] (show_stack+0x10/0x14)
[ 0.000000] [<c001868c>] (show_stack+0x10/0x14) from [<c02deb28>] (Ldiv0+0x8/0x10)
[ 0.000000] [<c02deb28>] (Ldiv0+0x8/0x10) from [<c0477030>] (clk_divider_set_rate+0x10/0x114)
[ 0.000000] [<c0477030>] (clk_divider_set_rate+0x10/0x114) from [<c0476ef4>] (clk_change_rate+0x38/0xb8)
[ 0.000000] [<c0476ef4>] (clk_change_rate+0x38/0xb8) from [<c0476f5c>] (clk_change_rate+0xa0/0xb8)
[ 0.000000] clock: trace_clk_div_ck: could not find divisor for target rate 0 for parent pmd_trace_clk_mux_ck
[ 0.000000] Division by zero in kernel.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
-rw-r--r-- | arch/arm/mach-omap2/cclock44xx_data.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c index 88e37a474334..1d5b5290d2af 100644 --- a/arch/arm/mach-omap2/cclock44xx_data.c +++ b/arch/arm/mach-omap2/cclock44xx_data.c | |||
@@ -1707,6 +1707,18 @@ int __init omap4xxx_clk_init(void) | |||
1707 | omap2_clk_disable_autoidle_all(); | 1707 | omap2_clk_disable_autoidle_all(); |
1708 | 1708 | ||
1709 | /* | 1709 | /* |
1710 | * A set rate of ABE DPLL inturn triggers a set rate of USB DPLL | ||
1711 | * when its in bypass. So always lock USB before ABE DPLL. | ||
1712 | */ | ||
1713 | /* | ||
1714 | * Lock USB DPLL on OMAP4 devices so that the L3INIT power | ||
1715 | * domain can transition to retention state when not in use. | ||
1716 | */ | ||
1717 | rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ); | ||
1718 | if (rc) | ||
1719 | pr_err("%s: failed to configure USB DPLL!\n", __func__); | ||
1720 | |||
1721 | /* | ||
1710 | * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power | 1722 | * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power |
1711 | * state when turning the ABE clock domain. Workaround this by | 1723 | * state when turning the ABE clock domain. Workaround this by |
1712 | * locking the ABE DPLL on boot. | 1724 | * locking the ABE DPLL on boot. |
@@ -1718,13 +1730,5 @@ int __init omap4xxx_clk_init(void) | |||
1718 | if (rc) | 1730 | if (rc) |
1719 | pr_err("%s: failed to configure ABE DPLL!\n", __func__); | 1731 | pr_err("%s: failed to configure ABE DPLL!\n", __func__); |
1720 | 1732 | ||
1721 | /* | ||
1722 | * Lock USB DPLL on OMAP4 devices so that the L3INIT power | ||
1723 | * domain can transition to retention state when not in use. | ||
1724 | */ | ||
1725 | rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ); | ||
1726 | if (rc) | ||
1727 | pr_err("%s: failed to configure USB DPLL!\n", __func__); | ||
1728 | |||
1729 | return 0; | 1733 | return 0; |
1730 | } | 1734 | } |