aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@ti.com>2013-05-15 10:48:37 -0400
committerPaul Walmsley <paul@pwsan.com>2013-05-19 18:34:02 -0400
commit35513171eed4d7245e81d926d311e74f3dca06f3 (patch)
tree120657c7d04f1617052ad92ae795abdc30fe8918 /arch/arm/mach-omap2/omap_hwmod.c
parentf722406faae2d073cc1d01063d1123c35425939e (diff)
ARM: OMAP2+: hwmod: Fix sidle programming in _enable_sysc()/_idle_sysc()
_enable_sysc() and _idle_sysc() handle the midle mode programming correctly and program HWMOD_IDLEMODE_SMART or HWMOD_IDLEMODE_SMART_WKUP respectively for supported IPs (The ones which support hardware controlled midle modes) However the same programming logic is missing when it comes to sidle mode programming. Here they seem to just set HWMOD_IDLEMODE_SMART (Again for the ones which support hardware controlled sidle modes) This problem was hidden due to the fact that a call to _enable_wakeup() in those same functions would overwrite the idlemodes and program them correctly (to HWMOD_IDLEMODE_SMART_WKUP in the supported cases) So fix the sidlemode handling correctly in these functions and handle the _enable_wakeup() for SIDLEMODE supported IPs same as the way its handled for MIDLEMODE supported ones. Tested-by: Vaibhav Bedia <vaibhav.bedia@ti.com> Tested-by: Sourav Poddar <sourav.poddar@ti.com> Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Kevin Hilman <khilman@linaro.org> Tested-by: Kevin Hilman <khilman@linaro.org> # OMAP4/Panda Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index d25a95fe9921..c28552bfeb8d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1356,13 +1356,26 @@ static void _enable_sysc(struct omap_hwmod *oh)
1356 1356
1357 clkdm = _get_clkdm(oh); 1357 clkdm = _get_clkdm(oh);
1358 if (sf & SYSC_HAS_SIDLEMODE) { 1358 if (sf & SYSC_HAS_SIDLEMODE) {
1359 if (oh->flags & HWMOD_SWSUP_SIDLE) {
1360 idlemode = HWMOD_IDLEMODE_NO;
1361 } else {
1362 if (sf & SYSC_HAS_ENAWAKEUP)
1363 _enable_wakeup(oh, &v);
1364 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
1365 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1366 else
1367 idlemode = HWMOD_IDLEMODE_SMART;
1368 }
1369
1370 /*
1371 * This is special handling for some IPs like
1372 * 32k sync timer. Force them to idle!
1373 */
1359 clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU); 1374 clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
1360 if (clkdm_act && !(oh->class->sysc->idlemodes & 1375 if (clkdm_act && !(oh->class->sysc->idlemodes &
1361 (SIDLE_SMART | SIDLE_SMART_WKUP))) 1376 (SIDLE_SMART | SIDLE_SMART_WKUP)))
1362 idlemode = HWMOD_IDLEMODE_FORCE; 1377 idlemode = HWMOD_IDLEMODE_FORCE;
1363 else 1378
1364 idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
1365 HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
1366 _set_slave_idlemode(oh, idlemode, &v); 1379 _set_slave_idlemode(oh, idlemode, &v);
1367 } 1380 }
1368 1381
@@ -1391,10 +1404,6 @@ static void _enable_sysc(struct omap_hwmod *oh)
1391 (sf & SYSC_HAS_CLOCKACTIVITY)) 1404 (sf & SYSC_HAS_CLOCKACTIVITY))
1392 _set_clockactivity(oh, oh->class->sysc->clockact, &v); 1405 _set_clockactivity(oh, oh->class->sysc->clockact, &v);
1393 1406
1394 /* If slave is in SMARTIDLE, also enable wakeup */
1395 if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
1396 _enable_wakeup(oh, &v);
1397
1398 _write_sysconfig(v, oh); 1407 _write_sysconfig(v, oh);
1399 1408
1400 /* 1409 /*
@@ -1430,13 +1439,16 @@ static void _idle_sysc(struct omap_hwmod *oh)
1430 sf = oh->class->sysc->sysc_flags; 1439 sf = oh->class->sysc->sysc_flags;
1431 1440
1432 if (sf & SYSC_HAS_SIDLEMODE) { 1441 if (sf & SYSC_HAS_SIDLEMODE) {
1433 /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ 1442 if (oh->flags & HWMOD_SWSUP_SIDLE) {
1434 if (oh->flags & HWMOD_SWSUP_SIDLE ||
1435 !(oh->class->sysc->idlemodes &
1436 (SIDLE_SMART | SIDLE_SMART_WKUP)))
1437 idlemode = HWMOD_IDLEMODE_FORCE; 1443 idlemode = HWMOD_IDLEMODE_FORCE;
1438 else 1444 } else {
1439 idlemode = HWMOD_IDLEMODE_SMART; 1445 if (sf & SYSC_HAS_ENAWAKEUP)
1446 _enable_wakeup(oh, &v);
1447 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
1448 idlemode = HWMOD_IDLEMODE_SMART_WKUP;
1449 else
1450 idlemode = HWMOD_IDLEMODE_SMART;
1451 }
1440 _set_slave_idlemode(oh, idlemode, &v); 1452 _set_slave_idlemode(oh, idlemode, &v);
1441 } 1453 }
1442 1454
@@ -1455,10 +1467,6 @@ static void _idle_sysc(struct omap_hwmod *oh)
1455 _set_master_standbymode(oh, idlemode, &v); 1467 _set_master_standbymode(oh, idlemode, &v);
1456 } 1468 }
1457 1469
1458 /* If slave is in SMARTIDLE, also enable wakeup */
1459 if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
1460 _enable_wakeup(oh, &v);
1461
1462 _write_sysconfig(v, oh); 1470 _write_sysconfig(v, oh);
1463} 1471}
1464 1472