提交 883edfdd 编写于 作者: T Thara Gopinath 提交者: Paul Walmsley

OMAP3: hwmod: Adding flag to prevent caching of sysconfig register.

In the current implementation the sysconfig value is read into
 _sysc_cache once and an actual update to the sysconfig register
happens only if the new value paased is differnt from the one in _sysc_cache.
_sysc_cache is updated only if _HWMOD_SYSCONFIG_LOADED is not set.
This can lead to the follwing issue if off mode is enabled in modules
which employs "always-retore" mechanism of context save and restore.

        a. The module sets the sysconfig register through omap_device_enable.
           Here _sysc_cache is updated with the value written to the sysconfig
           register and left.
        b. The power domain containig the module enters off mode and the
           module context is lost.
        c. The module in use becomes active and calls omap_device_enable to
           enable itself. Here a read of sysconfig register does not happen
           as _HWMOD_SYSCONFIG_LOADED flag is set. The value to be written
           to the sysconfig register will be same as the one written in step a.
           Since _sysc_cache reflects the previous written value an update
           of the sysconfig register does not happen.
This means in modules which employs "always-restore" mechanism
after off , the sysconfig regsiters will never get updated.

This patch introduces a flag SYSC_NO_CACHE which if set ensures that the
sysconfig register is always read into _sysc_cache before an update is
attempted.

This flags need to be set only by modules which does not do a context save
but re-initializes the registers every time the module is accessed. This
includes modules like i2c, smartreflex etc.
Signed-off-by: NThara Gopinath <thara@ti.com>
[paul@pwsan.com: tweaked to apply on a different head, added flag comment]
Signed-off-by: NPaul Walmsley <paul@pwsan.com>
上级 7284ce6c
...@@ -94,7 +94,8 @@ static int _update_sysc_cache(struct omap_hwmod *oh) ...@@ -94,7 +94,8 @@ static int _update_sysc_cache(struct omap_hwmod *oh)
oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs); oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED; if (!(oh->sysconfig->sysc_flags & SYSC_NO_CACHE))
oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
return 0; return 0;
} }
......
...@@ -227,6 +227,7 @@ struct omap_hwmod_ocp_if { ...@@ -227,6 +227,7 @@ struct omap_hwmod_ocp_if {
#define SYSC_HAS_SIDLEMODE (1 << 5) #define SYSC_HAS_SIDLEMODE (1 << 5)
#define SYSC_HAS_MIDLEMODE (1 << 6) #define SYSC_HAS_MIDLEMODE (1 << 6)
#define SYSS_MISSING (1 << 7) #define SYSS_MISSING (1 << 7)
#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */
/* omap_hwmod_sysconfig.clockact flags */ /* omap_hwmod_sysconfig.clockact flags */
#define CLOCKACT_TEST_BOTH 0x0 #define CLOCKACT_TEST_BOTH 0x0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册