diff options
author | Tony Lindgren <tony@atomide.com> | 2011-11-11 13:15:11 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2011-11-11 13:15:11 -0500 |
commit | e9b7086b80c4d9e354f4edc9e280ae85a60df408 (patch) | |
tree | 2598427ece342e0cbe34c7521f81efb6caea33bd /arch/arm/mach-omap1/clock_data.c | |
parent | 7be620f79714b6598275bd5c71d89bb24dfe332e (diff) |
ARM: OMAP: Fix reprogramming of dpll1 rate
Commit a66cb3454f220f49f900646ebdc76cb943319eb7 (ARM: OMAP: Map SRAM
later on with ioremap_exec()) moved the SRAM init to happen later
to remove a dependency to early SoC detection for map_io.
This broke booting on some boards not using Kconfig option for
OMAP_CLOCKS_SET_BY_BOOTLOADER as the dpll1 reprogramming would
cause the following error:
kernel BUG at arch/arm/plat-omap/sram.c:226!
Internal error: Oops - undefined instruction: 0 [#1] PREEMPT
Modules linked in:
CPU: 0 Not tainted (3.2.0-rc1-e3 #9)
PC is at omap_sram_reprogram_clock+0x28/0x30
LR is at omap1_select_table_rate+0x88/0xb4
pc : [<c001b0c4>] lr : [<c0019f54>] psr: 600000d3
sp : c035bf10 ip : c035bf20 fp : c035bf1c
r10: c035bfd4 r9 : 54029252 r8 : c03f8120
r7 : c0362b50 r6 : 00b71b00 r5 : c03873cc r4 : c0362b40
r3 : 00000000 r2 : c0362b40 r1 : 0000010a r0 : 00002cb0
Flags: nZCv IRQs off FIQs off Mode SVC_32 ISA ARM Segment kernel
Control: 0000317f Table: 10004000 DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc035a270)
Stack: (0xc035bf10 to 0xc035c000)
bf00: c035bf3c c035bf20 c0019f54 c001b0ac
bf20: 00001000 00002cb3 00000004 c035ed4c c035bf74 c035bf40 c033ea24 c0019edc
bf40: c02f526c 00000002 00000015 bc058c9b 93111a16 c035335c 02000000 c035ed4c
bf60: c035ed4c c03f8120 c035bf84 c035bf78 c00194c4 c033e8ec c035bfc4 c035bf88
bf80: c033bc24 c00194a0 c035bf90 c035bf98 00000000 00000000 00000000 00000000
bfa0: 00000001 00000000 c0354678 c035ece4 10004000 103532f4 c035bff4 c035bfc8
bfc0: c0338574 c033b598 00000000 00000000 00000000 c035467c 0000317d c035c03c
bfe0: c0354678 c035ece4 00000000 c035bff8 10008040 c0338508 00000000 00000000
Backtrace:
[<c001b09c>] (omap_sram_reprogram_clock+0x0/0x30) from [<c0019f54>] (omap1_select_table_rate+0x88/0xb4)
[<c0019ecc>] (omap1_select_table_rate+0x0/0xb4) from [<c033ea24>] (omap1_clk_init+0x148/0x334)
r7:c035ed4c r6:00000004 r5:00002cb3 r4:00001000
[<c033e8dc>] (omap1_clk_init+0x0/0x334) from [<c00194c4>] (omap1_init_early+0x34/0x48)
r8:c03f8120 r7:c035ed4c r6:c035ed4c r5:02000000 r4:c035335c
[<c0019490>] (omap1_init_early+0x0/0x48) from [<c033bc24>] (setup_arch+0x69c/0x79c)
[<c033b588>] (setup_arch+0x0/0x79c) from [<c0338574>] (start_kernel+0x7c/0x2f4)
[<c03384f8>] (start_kernel+0x0/0x2f4) from [<10008040>] (0x10008040)
r7:c035ece4 r6:c0354678 r5:c035c03c r4:0000317d
Code: 0a000002 e1a0e00f e12fff13 e89da800 (e7f001f2)
Fix this by adding omap1_clk_late_init() that only reprograms dpll1
if the bootloader rate is less than 60MHz. This also allows removing
of the OMAP_CLOCKS_SET_BY_BOOTLOADER option.
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap1/clock_data.c')
-rw-r--r-- | arch/arm/mach-omap1/clock_data.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 92400b9eb69f..1297bb58869c 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c | |||
@@ -767,6 +767,15 @@ static struct clk_functions omap1_clk_functions = { | |||
767 | .clk_disable_unused = omap1_clk_disable_unused, | 767 | .clk_disable_unused = omap1_clk_disable_unused, |
768 | }; | 768 | }; |
769 | 769 | ||
770 | static void __init omap1_show_rates(void) | ||
771 | { | ||
772 | pr_notice("Clocking rate (xtal/DPLL1/MPU): " | ||
773 | "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", | ||
774 | ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, | ||
775 | ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, | ||
776 | arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); | ||
777 | } | ||
778 | |||
770 | int __init omap1_clk_init(void) | 779 | int __init omap1_clk_init(void) |
771 | { | 780 | { |
772 | struct omap_clk *c; | 781 | struct omap_clk *c; |
@@ -835,9 +844,12 @@ int __init omap1_clk_init(void) | |||
835 | /* We want to be in syncronous scalable mode */ | 844 | /* We want to be in syncronous scalable mode */ |
836 | omap_writew(0x1000, ARM_SYSST); | 845 | omap_writew(0x1000, ARM_SYSST); |
837 | 846 | ||
838 | #ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER | 847 | |
839 | /* Use values set by bootloader. Determine PLL rate and recalculate | 848 | /* |
840 | * dependent clocks as if kernel had changed PLL or divisors. | 849 | * Initially use the values set by bootloader. Determine PLL rate and |
850 | * recalculate dependent clocks as if kernel had changed PLL or | ||
851 | * divisors. See also omap1_clk_late_init() that can reprogram dpll1 | ||
852 | * after the SRAM is initialized. | ||
841 | */ | 853 | */ |
842 | { | 854 | { |
843 | unsigned pll_ctl_val = omap_readw(DPLL_CTL); | 855 | unsigned pll_ctl_val = omap_readw(DPLL_CTL); |
@@ -862,25 +874,10 @@ int __init omap1_clk_init(void) | |||
862 | } | 874 | } |
863 | } | 875 | } |
864 | } | 876 | } |
865 | #else | ||
866 | /* Find the highest supported frequency and enable it */ | ||
867 | if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { | ||
868 | printk(KERN_ERR "System frequencies not set. Check your config.\n"); | ||
869 | /* Guess sane values (60MHz) */ | ||
870 | omap_writew(0x2290, DPLL_CTL); | ||
871 | omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL); | ||
872 | ck_dpll1.rate = 60000000; | ||
873 | } | ||
874 | #endif | ||
875 | propagate_rate(&ck_dpll1); | 877 | propagate_rate(&ck_dpll1); |
876 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ | 878 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ |
877 | propagate_rate(&ck_ref); | 879 | propagate_rate(&ck_ref); |
878 | printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " | 880 | omap1_show_rates(); |
879 | "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", | ||
880 | ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, | ||
881 | ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, | ||
882 | arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); | ||
883 | |||
884 | if (machine_is_omap_perseus2() || machine_is_omap_fsample()) { | 881 | if (machine_is_omap_perseus2() || machine_is_omap_fsample()) { |
885 | /* Select slicer output as OMAP input clock */ | 882 | /* Select slicer output as OMAP input clock */ |
886 | omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1, | 883 | omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1, |
@@ -925,3 +922,21 @@ int __init omap1_clk_init(void) | |||
925 | 922 | ||
926 | return 0; | 923 | return 0; |
927 | } | 924 | } |
925 | |||
926 | #define OMAP1_DPLL1_SANE_VALUE 60000000 | ||
927 | |||
928 | void __init omap1_clk_late_init(void) | ||
929 | { | ||
930 | if (ck_dpll1.rate >= OMAP1_DPLL1_SANE_VALUE) | ||
931 | return; | ||
932 | |||
933 | /* Find the highest supported frequency and enable it */ | ||
934 | if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { | ||
935 | pr_err("System frequencies not set, using default. Check your config.\n"); | ||
936 | omap_writew(0x2290, DPLL_CTL); | ||
937 | omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL); | ||
938 | ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; | ||
939 | } | ||
940 | propagate_rate(&ck_dpll1); | ||
941 | omap1_show_rates(); | ||
942 | } | ||