diff options
author | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2012-03-12 20:34:45 +0530 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 12:58:04 +0200 |
commit | cb0c031bc7a23315458f4da88fdb4dcbf9cb0dcc (patch) | |
tree | 0b301fadb88c8f7c1f66c89e6e14a5b4d6d1a692 | |
parent | 9b3f3d6ea1030553e0c80323e6cfff3adc5ebf01 (diff) | |
download | kernel_samsung_tuna-cb0c031bc7a23315458f4da88fdb4dcbf9cb0dcc.zip kernel_samsung_tuna-cb0c031bc7a23315458f4da88fdb4dcbf9cb0dcc.tar.gz kernel_samsung_tuna-cb0c031bc7a23315458f4da88fdb4dcbf9cb0dcc.tar.bz2 |
OMAP4: Workaround the OCP synchronisation issue with 32K synctimer.
Backport from:
http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap.git;
a=commitdiff;h=68523f4233de5f233478dde0a63047b4efb710b8
Original comment:
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.
Change-Id: I3c7ff239c3dcac180fcae50c1b909d417b2b8e16
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>
Signed-off-by: Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
-rwxr-xr-x | arch/arm/mach-omap2/pm44xx.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 77693e2..e8560a1 100755 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -1390,7 +1390,7 @@ static void __init omap4_pm_setup_errata(void) static int __init omap4_pm_init(void) { int ret = 0; - struct clockdomain *l3_1_clkdm; + struct clockdomain *l3_1_clkdm, *l4wkup; struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per, *l4_cfg; char *init_devices[] = {"mpu", "iva"}; int i; @@ -1439,6 +1439,12 @@ static int __init omap4_pm_init(void) * doesn't work as expected. The hardware recommendation is * to keep above dependencies. Without this system locks up or * randomly crashes. + * + * On 44xx: + * The L4 wakeup depedency is added to workaround the OCP sync hardware + * BUG with 32K synctimer which lead to incorrect timer value read + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which + * are part of L4 wakeup clockdomain. */ mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); emif_clkdm = clkdm_lookup("l3_emif_clkdm"); @@ -1447,7 +1453,8 @@ static int __init omap4_pm_init(void) ducati_clkdm = clkdm_lookup("ducati_clkdm"); l4_per = clkdm_lookup("l4_per_clkdm"); l4_cfg = clkdm_lookup("l4_cfg_clkdm"); - if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || + l4wkup = clkdm_lookup("l4_wkup_clkdm"); + if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) || (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per) || (!l4_cfg)) goto err2; @@ -1464,6 +1471,7 @@ static int __init omap4_pm_init(void) ret |= clkdm_add_wkdep(mpuss_clkdm, l4_cfg); ret |= clkdm_add_wkdep(ducati_clkdm, l4_per); ret |= clkdm_add_wkdep(ducati_clkdm, l4_cfg); + ret |= clkdm_add_wkdep(mpuss_clkdm, l4wkup); if (ret) { pr_err("Failed to add MPUSS -> L3/EMIF, DUCATI -> L3" " and MPUSS -> L4* wakeup dependency\n"); @@ -1487,6 +1495,7 @@ static int __init omap4_pm_init(void) /* There appears to be a problem between the MPUSS and L3_1 */ ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); + ret |= clkdm_add_wkdep(mpuss_clkdm, l4wkup); /* There appears to be a problem between the Ducati and L3/L4 */ ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); |