OMAP3: hwmod: Adding flag to prevent caching of sysconfig register.
authorThara Gopinath <thara@ti.com>
Wed, 20 Jan 2010 00:30:51 +0000 (17:30 -0700)
committerPaul Walmsley <paul@pwsan.com>
Wed, 20 Jan 2010 00:30:51 +0000 (17:30 -0700)
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: Thara Gopinath <thara@ti.com>
[paul@pwsan.com: tweaked to apply on a different head, added flag comment]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/plat-omap/include/plat/omap_hwmod.h

index d8c8545875b18b84aa89449ffa87911d687d129e..478ae585ca39666327500057fd1a85e014e19657 100644 (file)
@@ -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->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
+       if (!(oh->sysconfig->sysc_flags & SYSC_NO_CACHE))
+               oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
 
        return 0;
 }
index 007935a921eaeaa4efd69ab1a0b53d757ad90587..33933256a2265815351307749768e73435d6cc01 100644 (file)
@@ -227,6 +227,7 @@ struct omap_hwmod_ocp_if {
 #define SYSC_HAS_SIDLEMODE     (1 << 5)
 #define SYSC_HAS_MIDLEMODE     (1 << 6)
 #define SYSS_MISSING           (1 << 7)
+#define SYSC_NO_CACHE          (1 << 8)  /* XXX SW flag, belongs elsewhere */
 
 /* omap_hwmod_sysconfig.clockact flags */
 #define CLOCKACT_TEST_BOTH     0x0