aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2012-03-12 20:34:45 +0530
committerZiyann <jaraidaniel@gmail.com>2014-10-01 12:58:04 +0200
commitcb0c031bc7a23315458f4da88fdb4dcbf9cb0dcc (patch)
tree0b301fadb88c8f7c1f66c89e6e14a5b4d6d1a692
parent9b3f3d6ea1030553e0c80323e6cfff3adc5ebf01 (diff)
downloadkernel_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-xarch/arm/mach-omap2/pm44xx.c13
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);