From 650f7a72b8cc235ffe4a0e3eff37954349026721 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 1 Dec 2011 17:47:06 -0800 Subject: [PATCH 1/8] ARM: OMAP1: Fix reprogramming of DPLL1 for systems that boot at rates below 60MHz Commit e9b7086b80c4d9e354f4edc9e280ae85a60df408 (ARM: OMAP: Fix reprogramming of dpll1 rate) fixed a regression for systems that did not rely on bootloader set rates. However, it also introduced a new problem where the rates selected in .config would not take affect as omap1_select_table_rate currently refuses to reprogram DPLL1 if it's already initialized. This was not a problem earlier, as the reprogramming was done earlier with ck_dpll1_p->rate uninitialized. Fix this by forcing the reprogramming on systems booting at rates below 60MHz. Note that the long term fix is to make the rates SoC specific later on. Thanks for Janusz Krzysztofik for figuring this one out. Reported-by: Janusz Krzysztofik Acked-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/clock_data.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 1297bb58869c..3f305610efa0 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -930,6 +930,9 @@ void __init omap1_clk_late_init(void) if (ck_dpll1.rate >= OMAP1_DPLL1_SANE_VALUE) return; + /* System booting at unusable rate, force reprogramming of DPLL1 */ + ck_dpll1_p->rate = 0; + /* Find the highest supported frequency and enable it */ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { pr_err("System frequencies not set, using default. Check your config.\n"); From b29e23547ecb2a609777288cd81fc83b01f9f43f Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 1 Dec 2011 21:30:39 +0100 Subject: [PATCH 2/8] ARM: OMAP1: Remove unsafe clock values from omap1_defconfig DPLL1 reprogramming to a different rate is actually blocked inside omap1_select_table_rate(), resulting in the defalut rate of 60 MHz always used instead of the one selected in .config. OTOH, in omap1_defconfig we currently rely on Kconfig options for the supported MHz rates in case of boards which boot with dpll1 not set correctly by their boot loaders. This means that before we allow for reprogramming of dpll1 rate, we should remove all unsafe clock selections from omap1_defconfig, otherwise it will stop booting on boards with imperfect boot loaders, as it would always try to change to 216MHz. Keep only one safe clock rate per each supported xtal frequency, i.e. 60MHZ dpll1 for 12MHz xtal and 182MHz dpll1 for 13MHz xtal. BTW, this change goes into the direction of removing all OMAP1 clock rate options, planned for next merge window. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/configs/omap1_defconfig | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index a7e777581378..945a34f2a34d 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -48,12 +48,7 @@ CONFIG_MACH_SX1=y CONFIG_MACH_NOKIA770=y CONFIG_MACH_AMS_DELTA=y CONFIG_MACH_OMAP_GENERIC=y -CONFIG_OMAP_ARM_216MHZ=y -CONFIG_OMAP_ARM_195MHZ=y -CONFIG_OMAP_ARM_192MHZ=y CONFIG_OMAP_ARM_182MHZ=y -CONFIG_OMAP_ARM_168MHZ=y -# CONFIG_OMAP_ARM_60MHZ is not set # CONFIG_ARM_THUMB is not set CONFIG_PCCARD=y CONFIG_OMAP_CF=y From c2cb211116192690605eaa70d39deb04241003e2 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 1 Dec 2011 21:13:01 +0100 Subject: [PATCH 3/8] ARM: OMAP1: Fix ckctl value used for dpll1 defualt rate Use the exact value found in omap1_rate_table, otherwise I have been experiencing issues with correct timekeeping on my Amstrad Delta. Signed-off-by: Janusz Krzysztofik [tony@atomide.com: removed comment referencing a development branch] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/clock_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 3f305610efa0..86b2dec11788 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -937,7 +937,7 @@ void __init omap1_clk_late_init(void) if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { pr_err("System frequencies not set, using default. Check your config.\n"); omap_writew(0x2290, DPLL_CTL); - omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL); + omap_writew(cpu_is_omap7xx() ? 0x2005 : 0x0005, ARM_CKCTL); ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; } propagate_rate(&ck_dpll1); From 6560ee07dc946e94f7cc2cd8e3b5a5f5ee7340c1 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 1 Dec 2011 21:13:02 +0100 Subject: [PATCH 4/8] ARM: OMAP1: recalculate loops per jiffy after dpll1 reprogram Otherwise timing is inaccurate, resulting in devices which depend on it, like omap-keypad, broken. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik [tony@atomide.com: removed comment referencing a development branch] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/clock_data.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 86b2dec11788..9ff90a744a21 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include /* for machine_is_* */ @@ -927,7 +929,9 @@ int __init omap1_clk_init(void) void __init omap1_clk_late_init(void) { - if (ck_dpll1.rate >= OMAP1_DPLL1_SANE_VALUE) + unsigned long rate = ck_dpll1.rate; + + if (rate >= OMAP1_DPLL1_SANE_VALUE) return; /* System booting at unusable rate, force reprogramming of DPLL1 */ @@ -942,4 +946,5 @@ void __init omap1_clk_late_init(void) } propagate_rate(&ck_dpll1); omap1_show_rates(); + loops_per_jiffy = cpufreq_scale(loops_per_jiffy, rate, ck_dpll1.rate); } From ee62e93a3c135ae18f2fa18615ce065fe5487259 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 8 Dec 2011 14:58:38 -0800 Subject: [PATCH 5/8] ARM: OMAP1: Set the omap1623 sram size to 16K Now that we're always reprogramming the core clock we must make sure SRAM works. It seems that neither omap1621 or omap1623 has 256K of SRAM. Set the SRAM size to safe value of 16K. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/sram.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 8b28664d1c62..574351902c83 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -141,11 +141,9 @@ static void __init omap_detect_sram(void) omap_sram_size = 0x32000; /* 200K */ else if (cpu_is_omap15xx()) omap_sram_size = 0x30000; /* 192K */ - else if (cpu_is_omap1610() || cpu_is_omap1621() || - cpu_is_omap1710()) + else if (cpu_is_omap1610() || cpu_is_omap1611() || + cpu_is_omap1621() || cpu_is_omap1710()) omap_sram_size = 0x4000; /* 16K */ - else if (cpu_is_omap1611()) - omap_sram_size = SZ_256K; else { pr_err("Could not detect SRAM size\n"); omap_sram_size = 0x4000; From 24ce2705c2dd50e51f325c6e57dec378adc8c135 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 8 Dec 2011 18:01:41 -0800 Subject: [PATCH 6/8] ARM: OMAP1: Move dpll1 rates selection from config to runtime For still better multi-OMAP1 support, expand omap1_rate_table with flags for different SoC types and match them while selecting clock rates. The idea is stolen from current omap24xx clock rate selection algorithm. Since clkdev platform flag definitions are reused here, those had to be expanded with one extra entry for OMAP1710 subtype, as this is the only SoC for which we allow selection of the highest, 216 MHz rate. Once done, remove no longer needed clock rate configure time options. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- arch/arm/configs/omap1_defconfig | 1 - arch/arm/mach-omap1/Kconfig | 64 ------------------- arch/arm/mach-omap1/clock.c | 6 ++ arch/arm/mach-omap1/clock.h | 3 + arch/arm/mach-omap1/clock_data.c | 6 +- arch/arm/mach-omap1/opp.h | 1 + arch/arm/mach-omap1/opp_data.c | 63 +++++++++--------- arch/arm/plat-omap/include/plat/clkdev_omap.h | 1 + 8 files changed, 45 insertions(+), 100 deletions(-) diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index 945a34f2a34d..dde2a1af7b39 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -48,7 +48,6 @@ CONFIG_MACH_SX1=y CONFIG_MACH_NOKIA770=y CONFIG_MACH_AMS_DELTA=y CONFIG_MACH_OMAP_GENERIC=y -CONFIG_OMAP_ARM_182MHZ=y # CONFIG_ARM_THUMB is not set CONFIG_PCCARD=y CONFIG_OMAP_CF=y diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 73f287d6429b..4f8d66f044e7 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -168,70 +168,6 @@ config MACH_OMAP_GENERIC custom OMAP boards. Say Y here if you have a custom board. -comment "OMAP CPU Speed" - depends on ARCH_OMAP1 - -config OMAP_ARM_216MHZ - bool "OMAP ARM 216 MHz CPU (1710 only)" - depends on ARCH_OMAP1 && ARCH_OMAP16XX - help - Enable 216 MHz clock for OMAP1710 CPU. If unsure, say N. - -config OMAP_ARM_195MHZ - bool "OMAP ARM 195 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 195MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_192MHZ - bool "OMAP ARM 192 MHz CPU" - depends on ARCH_OMAP1 && ARCH_OMAP16XX - help - Enable 192MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_182MHZ - bool "OMAP ARM 182 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 182MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_168MHZ - bool "OMAP ARM 168 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 168MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_150MHZ - bool "OMAP ARM 150 MHz CPU" - depends on ARCH_OMAP1 && ARCH_OMAP15XX - help - Enable 150MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_120MHZ - bool "OMAP ARM 120 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 120MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_96MHZ - bool "OMAP ARM 96 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 96MHz clock for OMAP CPU. If unsure, say N. - -config OMAP_ARM_60MHZ - bool "OMAP ARM 60 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - default y - help - Enable 60MHz clock for OMAP CPU. If unsure, say Y. - -config OMAP_ARM_30MHZ - bool "OMAP ARM 30 MHz CPU" - depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850) - help - Enable 30MHz clock for OMAP CPU. If unsure, say N. - endmenu endif diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 84ef70476b51..ff27dbdba3d6 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -197,6 +197,9 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate) ref_rate = ck_ref_p->rate; for (ptr = omap1_rate_table; ptr->rate; ptr++) { + if (!(ptr->flags & cpu_mask)) + continue; + if (ptr->xtal != ref_rate) continue; @@ -290,6 +293,9 @@ long omap1_round_to_table_rate(struct clk *clk, unsigned long rate) highest_rate = -EINVAL; for (ptr = omap1_rate_table; ptr->rate; ptr++) { + if (!(ptr->flags & cpu_mask)) + continue; + if (ptr->xtal != ref_rate) continue; diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index 16b1423b454a..3d04f4f67676 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -111,4 +111,7 @@ extern const struct clkops clkops_dummy; extern const struct clkops clkops_uart_16xx; extern const struct clkops clkops_generic; +/* used for passing SoC type to omap1_{select,round_to}_table_rate() */ +extern u32 cpu_mask; + #endif diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 9ff90a744a21..ff2d5248df23 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -778,12 +778,14 @@ static void __init omap1_show_rates(void) arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); } +u32 cpu_mask; + int __init omap1_clk_init(void) { struct omap_clk *c; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ - u32 reg, cpu_mask; + u32 reg; #ifdef CONFIG_DEBUG_LL /* @@ -808,6 +810,8 @@ int __init omap1_clk_init(void) clk_preinit(c->lk.clk); cpu_mask = 0; + if (cpu_is_omap1710()) + cpu_mask |= CK_1710; if (cpu_is_omap16xx()) cpu_mask |= CK_16XX; if (cpu_is_omap1510()) diff --git a/arch/arm/mach-omap1/opp.h b/arch/arm/mach-omap1/opp.h index 07074d79adce..79a683864a5c 100644 --- a/arch/arm/mach-omap1/opp.h +++ b/arch/arm/mach-omap1/opp.h @@ -21,6 +21,7 @@ struct mpu_rate { unsigned long pll_rate; __u16 ckctl_val; __u16 dpllctl_val; + u32 flags; }; extern struct mpu_rate omap1_rate_table[]; diff --git a/arch/arm/mach-omap1/opp_data.c b/arch/arm/mach-omap1/opp_data.c index 75a546514994..9cd4ddb51397 100644 --- a/arch/arm/mach-omap1/opp_data.c +++ b/arch/arm/mach-omap1/opp_data.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include "opp.h" /*------------------------------------------------------------------------- @@ -20,40 +21,34 @@ struct mpu_rate omap1_rate_table[] = { * NOTE: Comment order here is different from bits in CKCTL value: * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv */ -#if defined(CONFIG_OMAP_ARM_216MHZ) - { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_195MHZ) - { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_192MHZ) - { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ - { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ - { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ - { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */ - { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_182MHZ) - { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_168MHZ) - { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ -#endif -#if defined(CONFIG_OMAP_ARM_150MHZ) - { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ -#endif -#if defined(CONFIG_OMAP_ARM_120MHZ) - { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ -#endif -#if defined(CONFIG_OMAP_ARM_96MHZ) - { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ -#endif -#if defined(CONFIG_OMAP_ARM_60MHZ) - { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */ -#endif -#if defined(CONFIG_OMAP_ARM_30MHZ) - { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */ -#endif + { 216000000, 12000000, 216000000, 0x050d, 0x2910, /* 1/1/2/2/2/8 */ + CK_1710 }, + { 195000000, 13000000, 195000000, 0x050e, 0x2790, /* 1/1/2/2/4/8 */ + CK_7XX }, + { 192000000, 19200000, 192000000, 0x050f, 0x2510, /* 1/1/2/2/8/8 */ + CK_16XX }, + { 192000000, 12000000, 192000000, 0x050f, 0x2810, /* 1/1/2/2/8/8 */ + CK_16XX }, + { 96000000, 12000000, 192000000, 0x055f, 0x2810, /* 2/2/2/2/8/8 */ + CK_16XX }, + { 48000000, 12000000, 192000000, 0x0baf, 0x2810, /* 4/4/4/8/8/8 */ + CK_16XX }, + { 24000000, 12000000, 192000000, 0x0fff, 0x2810, /* 8/8/8/8/8/8 */ + CK_16XX }, + { 182000000, 13000000, 182000000, 0x050e, 0x2710, /* 1/1/2/2/4/8 */ + CK_7XX }, + { 168000000, 12000000, 168000000, 0x010f, 0x2710, /* 1/1/1/2/8/8 */ + CK_16XX|CK_7XX }, + { 150000000, 12000000, 150000000, 0x010a, 0x2cb0, /* 1/1/1/2/4/4 */ + CK_1510 }, + { 120000000, 12000000, 120000000, 0x010a, 0x2510, /* 1/1/1/2/4/4 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, + { 96000000, 12000000, 96000000, 0x0005, 0x2410, /* 1/1/1/1/2/2 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, + { 60000000, 12000000, 60000000, 0x0005, 0x2290, /* 1/1/1/1/2/2 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, + { 30000000, 12000000, 60000000, 0x0555, 0x2290, /* 2/2/2/2/2/2 */ + CK_16XX|CK_1510|CK_310|CK_7XX }, { 0, 0, 0, 0, 0 }, }; diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h index 387a9638991b..b299b8d201c8 100644 --- a/arch/arm/plat-omap/include/plat/clkdev_omap.h +++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h @@ -40,6 +40,7 @@ struct omap_clk { #define CK_443X (1 << 11) #define CK_TI816X (1 << 12) #define CK_446X (1 << 13) +#define CK_1710 (1 << 15) /* 1710 extra for rate selection */ #define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS) From f9e5908fa04e15a681dc4695b53c2c0c1d9b9a03 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 1 Dec 2011 22:16:26 +0100 Subject: [PATCH 7/8] ARM: OMAP1: Update dpll1 default rate reprogramming method According to comments in omap1_select_table_rate(), reprogramming dpll1 is tricky, and should always be done from SRAM. While being at it, move OMAP730 special case handling inside omap_sram_reprogram_clock(). Created on top of version 2 of the series "ARM: OMAP1: Fix dpll1 reprogramming related issues", which it depends on. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/clock.c | 6 +----- arch/arm/mach-omap1/clock_data.c | 7 +++++-- arch/arm/plat-omap/sram.c | 3 +++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index ff27dbdba3d6..6d8f7c640237 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -218,12 +218,8 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate) /* * In most cases we should not need to reprogram DPLL. * Reprogramming the DPLL is tricky, it must be done from SRAM. - * (on 730, bit 13 must always be 1) */ - if (cpu_is_omap7xx()) - omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val | 0x2000); - else - omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); + omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); /* XXX Do we need to recalculate the tree below DPLL1 at this point? */ ck_dpll1_p->rate = ptr->pll_rate; diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index ff2d5248df23..9d1a42a5afd8 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -25,6 +25,7 @@ #include #include #include +#include /* for omap_sram_reprogram_clock() */ #include /* for OTG_BASE */ #include "clock.h" @@ -944,8 +945,10 @@ void __init omap1_clk_late_init(void) /* Find the highest supported frequency and enable it */ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { pr_err("System frequencies not set, using default. Check your config.\n"); - omap_writew(0x2290, DPLL_CTL); - omap_writew(cpu_is_omap7xx() ? 0x2005 : 0x0005, ARM_CKCTL); + /* + * Reprogramming the DPLL is tricky, it must be done from SRAM. + */ + omap_sram_reprogram_clock(0x2290, 0x0005); ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; } propagate_rate(&ck_dpll1); diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 574351902c83..6b058a621e8d 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -222,6 +222,9 @@ static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl); void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) { BUG_ON(!_omap_sram_reprogram_clock); + /* On 730, bit 13 must always be 1 */ + if (cpu_is_omap7xx()) + ckctl |= 0x2000; _omap_sram_reprogram_clock(dpllctl, ckctl); } From c116abc43df9ce3ebe5fbf2fbd6ae2edd6a9bd87 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Sun, 4 Dec 2011 16:07:47 +0100 Subject: [PATCH 8/8] ARM: OMAP1: Always reprogram dpll1 rate at boot DPLL1 reprogramming to a different rate is actually blocked inside omap1_select_table_rate(). However, it is already forced at boot, for boards which boot at unusable clock rates, and this seems to work correctly. OTOH, we now have a fine, run time performed clock selection algorithm implemented, which prevents less powerfull SoCs from being overclocked unintentionally. Allow reprogramming of dpll1 by default, and use it for switching to the higest supported clock rate with all boards, including those already booting at a usable rate of 60 MHz or above. Created against linux-omap/master tip as of Thu Dec 1, commit f83c2a8cbb59981722d1ab610c79adfd034a2667. Requires the just submitted patch "ARM: OMAP1: Move dpll1 rates selection from config to runtime" to prevent from unintentional overclocking. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/clock.c | 4 ---- arch/arm/mach-omap1/clock_data.c | 6 ------ 2 files changed, 10 deletions(-) diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 6d8f7c640237..0c50df05d135 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -203,10 +203,6 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate) if (ptr->xtal != ref_rate) continue; - /* DPLL1 cannot be reprogrammed without risking system crash */ - if (likely(dpll1_rate != 0) && ptr->pll_rate != dpll1_rate) - continue; - /* Can check only after xtal frequency check */ if (ptr->rate <= rate) break; diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 9d1a42a5afd8..94699a82a734 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -936,12 +936,6 @@ void __init omap1_clk_late_init(void) { unsigned long rate = ck_dpll1.rate; - if (rate >= OMAP1_DPLL1_SANE_VALUE) - return; - - /* System booting at unusable rate, force reprogramming of DPLL1 */ - ck_dpll1_p->rate = 0; - /* Find the highest supported frequency and enable it */ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { pr_err("System frequencies not set, using default. Check your config.\n");