aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBenoit Cousson <b-cousson@ti.com>2010-12-21 23:31:28 -0500
committerPaul Walmsley <paul@pwsan.com>2010-12-21 23:31:28 -0500
commit86009eb326afde34ffdc5648cd344aa86b8d58d4 (patch)
tree404f2e19d3082bd8d6eea4871e9f0bb1e78ac82b /arch/arm
parentf2dd7e09db3e18e4c053810b72fe026685d9bf0c (diff)
OMAP2+: hwmod: Add wakeup support for new OMAP4 IPs
The new OMAP4 IPs introduced a new idle mode named smart-idle with wakeup. This new idlemode replaces the enawakeup for the new IPs but seems to coexist as well for some legacy IPs (UART, GPIO, MCSPI...) Add the new SIDLE_SMART_WKUP flag to mark the IPs that support this capability. The omap_hwmod_44xx_data.c will have to be updated to add this new flag. Enable this new mode when applicable in _enable_wakeup, _enable_sysc and _idle_sysc. Signed-off-by: Benoit Cousson <b-cousson@ti.com> Tested-by: Sebastien Guiriec <s-guiriec@ti.com> Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Rajendra Nayak <rnayak@ti.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c16
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h5
2 files changed, 18 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index c576121b58a9..03ffa3b282b1 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -393,7 +393,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
393 u32 wakeup_mask; 393 u32 wakeup_mask;
394 394
395 if (!oh->class->sysc || 395 if (!oh->class->sysc ||
396 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 396 !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
397 (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)))
397 return -EINVAL; 398 return -EINVAL;
398 399
399 if (!oh->class->sysc->sysc_fields) { 400 if (!oh->class->sysc->sysc_fields) {
@@ -405,6 +406,9 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
405 406
406 *v |= wakeup_mask; 407 *v |= wakeup_mask;
407 408
409 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
410 _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
411
408 /* XXX test pwrdm_get_wken for this hwmod's subsystem */ 412 /* XXX test pwrdm_get_wken for this hwmod's subsystem */
409 413
410 oh->_int_flags |= _HWMOD_WAKEUP_ENABLED; 414 oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
@@ -424,7 +428,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
424 u32 wakeup_mask; 428 u32 wakeup_mask;
425 429
426 if (!oh->class->sysc || 430 if (!oh->class->sysc ||
427 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 431 !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
432 (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)))
428 return -EINVAL; 433 return -EINVAL;
429 434
430 if (!oh->class->sysc->sysc_fields) { 435 if (!oh->class->sysc->sysc_fields) {
@@ -436,6 +441,9 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
436 441
437 *v &= ~wakeup_mask; 442 *v &= ~wakeup_mask;
438 443
444 if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
445 _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
446
439 /* XXX test pwrdm_get_wken for this hwmod's subsystem */ 447 /* XXX test pwrdm_get_wken for this hwmod's subsystem */
440 448
441 oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED; 449 oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
@@ -832,6 +840,10 @@ static void _idle_sysc(struct omap_hwmod *oh)
832 _set_master_standbymode(oh, idlemode, &v); 840 _set_master_standbymode(oh, idlemode, &v);
833 } 841 }
834 842
843 /* If slave is in SMARTIDLE, also enable wakeup */
844 if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
845 _enable_wakeup(oh, &v);
846
835 _write_sysconfig(v, oh); 847 _write_sysconfig(v, oh);
836} 848}
837 849
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index ab99b8cca6ad..619877c6b3ab 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -76,6 +76,8 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
76#define HWMOD_IDLEMODE_FORCE (1 << 0) 76#define HWMOD_IDLEMODE_FORCE (1 << 0)
77#define HWMOD_IDLEMODE_NO (1 << 1) 77#define HWMOD_IDLEMODE_NO (1 << 1)
78#define HWMOD_IDLEMODE_SMART (1 << 2) 78#define HWMOD_IDLEMODE_SMART (1 << 2)
79/* Slave idle mode flag only */
80#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
79 81
80/** 82/**
81 * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod 83 * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
@@ -227,11 +229,12 @@ struct omap_hwmod_ocp_if {
227/* Macros for use in struct omap_hwmod_sysconfig */ 229/* Macros for use in struct omap_hwmod_sysconfig */
228 230
229/* Flags for use in omap_hwmod_sysconfig.idlemodes */ 231/* Flags for use in omap_hwmod_sysconfig.idlemodes */
230#define MASTER_STANDBY_SHIFT 2 232#define MASTER_STANDBY_SHIFT 4
231#define SLAVE_IDLE_SHIFT 0 233#define SLAVE_IDLE_SHIFT 0
232#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT) 234#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
233#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT) 235#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
234#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT) 236#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
237#define SIDLE_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << SLAVE_IDLE_SHIFT)
235#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT) 238#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
236#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT) 239#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
237#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT) 240#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)