aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm44xx.c
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2012-03-12 11:04:45 -0400
committerKevin Hilman <khilman@ti.com>2012-03-22 19:11:17 -0400
commit68523f4233de5f233478dde0a63047b4efb710b8 (patch)
treeb14340de1407bb518fa9cb40829ba388dd5a7c79 /arch/arm/mach-omap2/pm44xx.c
parentc16fa4f2ad19908a47c63d8fa436a1178438c7e7 (diff)
ARM: OMAP4: Workaround the OCP synchronisation issue with 32K synctimer.
On OMAP4, recently a synchronisation bug is discovered by hardware team, which leads to incorrect timer value read from 32K sync timer IP when the IP is comming out of idle. The issue is due to the synchronization methodology used in the SYNCTIMER IP. The value of the counter register in 32kHz domain is synchronized to the OCP domain register only at count up event, and if the OCP clock is switched off, the OCP register gets out of synch until the first count up event after the clock is switched back -at the next falling edge of the 32kHz clock. Further investigation revealed that it applies to gptimer1 and watchdog timer2 as well which may run on 32KHz. This patch fixes the issue for all the applicable modules. The BUG has not made it yet to the OMAP errata list and it is applicable to OMAP1/2/3/4/5. OMAP1/2/3 it is taken care indirectly by autodeps. By enabling static depedency of wakeup clockdomain with MPU, as soon as MPU is woken up from lowpower state(idle) or whenever MPU is active, PRCM forces the OCP clock to be running and allow the counter value to be updated properly in the OCP clock domain. The bug is going to fixed in future OMAP versions. Reported-Tested-by: dave.long@linaro.org [dave.long@linaro.org: Reported the oprofile time stamp issue with synctimer and helped to test this patch] Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/pm44xx.c')
-rw-r--r--arch/arm/mach-omap2/pm44xx.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index c264ef7219c1..974f7ea19b22 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -196,7 +196,7 @@ static void omap_default_idle(void)
196static int __init omap4_pm_init(void) 196static int __init omap4_pm_init(void)
197{ 197{
198 int ret; 198 int ret;
199 struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; 199 struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
200 struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; 200 struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
201 201
202 if (!cpu_is_omap44xx()) 202 if (!cpu_is_omap44xx())
@@ -220,14 +220,19 @@ static int __init omap4_pm_init(void)
220 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as 220 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
221 * expected. The hardware recommendation is to enable static 221 * expected. The hardware recommendation is to enable static
222 * dependencies for these to avoid system lock ups or random crashes. 222 * dependencies for these to avoid system lock ups or random crashes.
223 * The L4 wakeup depedency is added to workaround the OCP sync hardware
224 * BUG with 32K synctimer which lead to incorrect timer value read
225 * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
226 * are part of L4 wakeup clockdomain.
223 */ 227 */
224 mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); 228 mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
225 emif_clkdm = clkdm_lookup("l3_emif_clkdm"); 229 emif_clkdm = clkdm_lookup("l3_emif_clkdm");
226 l3_1_clkdm = clkdm_lookup("l3_1_clkdm"); 230 l3_1_clkdm = clkdm_lookup("l3_1_clkdm");
227 l3_2_clkdm = clkdm_lookup("l3_2_clkdm"); 231 l3_2_clkdm = clkdm_lookup("l3_2_clkdm");
228 l4_per_clkdm = clkdm_lookup("l4_per_clkdm"); 232 l4_per_clkdm = clkdm_lookup("l4_per_clkdm");
233 l4wkup = clkdm_lookup("l4_wkup_clkdm");
229 ducati_clkdm = clkdm_lookup("ducati_clkdm"); 234 ducati_clkdm = clkdm_lookup("ducati_clkdm");
230 if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || 235 if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
231 (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm)) 236 (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
232 goto err2; 237 goto err2;
233 238
@@ -235,6 +240,7 @@ static int __init omap4_pm_init(void)
235 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); 240 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
236 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); 241 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
237 ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm); 242 ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm);
243 ret |= clkdm_add_wkdep(mpuss_clkdm, l4wkup);
238 ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); 244 ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
239 ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); 245 ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
240 if (ret) { 246 if (ret) {