提交 724019b0 编写于 作者: B Benoit Cousson 提交者: Paul Walmsley

OMAP2+: hwmod: Fix smart-standby + wakeup support

The commit 86009eb3 was adding
the wakeup support for new OMAP4 IPs. This support is incomplete for
busmaster IPs that need as well to use smart-standby with wakeup.

This new standbymode is suported on HSI and USB_HOST_FS for the moment.

Add the new MSTANDBY_SMART_WKUP flag to mark the IPs that support this
capability.

Enable this new mode when applicable in _enable_wakeup, _disable_wakeup,
_enable_sysc and _idle_sysc.

The omap_hwmod_44xx_data.c will have to be updated to add this new flag.
Signed-off-by: NBenoit Cousson <b-cousson@ti.com>
Signed-off-by: NDjamil Elaidi <d-elaidi@ti.com>
Signed-off-by: NPaul Walmsley <paul@pwsan.com>
上级 ecba3287
...@@ -391,7 +391,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v) ...@@ -391,7 +391,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
if (!oh->class->sysc || if (!oh->class->sysc ||
!((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) || !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
(oh->class->sysc->idlemodes & SIDLE_SMART_WKUP))) (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
(oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
return -EINVAL; return -EINVAL;
if (!oh->class->sysc->sysc_fields) { if (!oh->class->sysc->sysc_fields) {
...@@ -405,6 +406,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v) ...@@ -405,6 +406,8 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v); _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
_set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
/* XXX test pwrdm_get_wken for this hwmod's subsystem */ /* XXX test pwrdm_get_wken for this hwmod's subsystem */
...@@ -426,7 +429,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) ...@@ -426,7 +429,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
if (!oh->class->sysc || if (!oh->class->sysc ||
!((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) || !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
(oh->class->sysc->idlemodes & SIDLE_SMART_WKUP))) (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
(oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
return -EINVAL; return -EINVAL;
if (!oh->class->sysc->sysc_fields) { if (!oh->class->sysc->sysc_fields) {
...@@ -440,6 +444,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) ...@@ -440,6 +444,8 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v); _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
_set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
/* XXX test pwrdm_get_wken for this hwmod's subsystem */ /* XXX test pwrdm_get_wken for this hwmod's subsystem */
...@@ -781,8 +787,16 @@ static void _enable_sysc(struct omap_hwmod *oh) ...@@ -781,8 +787,16 @@ static void _enable_sysc(struct omap_hwmod *oh)
} }
if (sf & SYSC_HAS_MIDLEMODE) { if (sf & SYSC_HAS_MIDLEMODE) {
idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; idlemode = HWMOD_IDLEMODE_NO;
} else {
if (sf & SYSC_HAS_ENAWAKEUP)
_enable_wakeup(oh, &v);
if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
idlemode = HWMOD_IDLEMODE_SMART_WKUP;
else
idlemode = HWMOD_IDLEMODE_SMART;
}
_set_master_standbymode(oh, idlemode, &v); _set_master_standbymode(oh, idlemode, &v);
} }
...@@ -840,8 +854,16 @@ static void _idle_sysc(struct omap_hwmod *oh) ...@@ -840,8 +854,16 @@ static void _idle_sysc(struct omap_hwmod *oh)
} }
if (sf & SYSC_HAS_MIDLEMODE) { if (sf & SYSC_HAS_MIDLEMODE) {
idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; idlemode = HWMOD_IDLEMODE_FORCE;
} else {
if (sf & SYSC_HAS_ENAWAKEUP)
_enable_wakeup(oh, &v);
if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
idlemode = HWMOD_IDLEMODE_SMART_WKUP;
else
idlemode = HWMOD_IDLEMODE_SMART;
}
_set_master_standbymode(oh, idlemode, &v); _set_master_standbymode(oh, idlemode, &v);
} }
......
...@@ -77,7 +77,6 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; ...@@ -77,7 +77,6 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
#define HWMOD_IDLEMODE_FORCE (1 << 0) #define HWMOD_IDLEMODE_FORCE (1 << 0)
#define HWMOD_IDLEMODE_NO (1 << 1) #define HWMOD_IDLEMODE_NO (1 << 1)
#define HWMOD_IDLEMODE_SMART (1 << 2) #define HWMOD_IDLEMODE_SMART (1 << 2)
/* Slave idle mode flag only */
#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) #define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
/** /**
...@@ -258,6 +257,7 @@ struct omap_hwmod_ocp_if { ...@@ -258,6 +257,7 @@ struct omap_hwmod_ocp_if {
#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT) #define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT) #define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT) #define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
#define MSTANDBY_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << MASTER_STANDBY_SHIFT)
/* omap_hwmod_sysconfig.sysc_flags capability flags */ /* omap_hwmod_sysconfig.sysc_flags capability flags */
#define SYSC_HAS_AUTOIDLE (1 << 0) #define SYSC_HAS_AUTOIDLE (1 << 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册