]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
OMAP3: PM: Program SDRC to send self refresh on timeout of AUTO_CNT
authorRajendra Nayak <rnayak@ti.com>
Tue, 9 Jun 2009 17:00:41 +0000 (22:30 +0530)
committerKevin Hilman <khilman@deeprootsystems.com>
Wed, 11 Nov 2009 22:42:28 +0000 (14:42 -0800)
Due to an OMAP3 errata (1.142), on HS/EMU devices SDRC should be
programed to issue automatic self refresh on timeout
of AUTO_CNT = 1 prior to any transition to OFF mode.
This is needed only on sil rev's ES3.0 and above.

This patch enables the above needed WA in the SDRC power register
value stored in scratchpad, so that ROM code restores this value
in SDRC POWER on the wakeup path.
The original SDRC POWER register value is stored and restored back
in omap_sram_idle() function.

This fixes some random crashes observed while stressing suspend
on HS/EMU devices.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
arch/arm/mach-omap2/control.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/plat-omap/include/plat/sdrc.h

index 2ff8d7cc60a2022f7ada41c4c5531e95b582b068..cdd1f35636dd246e69db01f073445ae3523ba47f 100644 (file)
@@ -265,7 +265,21 @@ void omap3_save_scratchpad_contents(void)
                        (sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF);
        sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL);
        sdrc_block_contents.dll_b_ctrl = 0x0;
-       sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);
+       /*
+        * Due to a OMAP3 errata (1.142), on EMU/HS devices SRDC should
+        * be programed to issue automatic self refresh on timeout
+        * of AUTO_CNT = 1 prior to any transition to OFF mode.
+        */
+       if ((omap_type() != OMAP2_DEVICE_TYPE_GP)
+                       && (omap_rev() >= OMAP3430_REV_ES3_0))
+               sdrc_block_contents.power = (sdrc_read_reg(SDRC_POWER) &
+                               ~(SDRC_POWER_AUTOCOUNT_MASK|
+                               SDRC_POWER_CLKCTRL_MASK)) |
+                               (1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
+                               SDRC_SELF_REFRESH_ON_AUTOCOUNT;
+       else
+               sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);
+
        sdrc_block_contents.cs_0 = 0x0;
        sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0);
        sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF);
index 511a57dc7015d973f9546d7da76ea509e928d832..01b95eaae75ab88fa8726b607f539e737f4796d2 100644 (file)
 #include "pm.h"
 #include "sdrc.h"
 
-#define SDRC_POWER_AUTOCOUNT_SHIFT 8
-#define SDRC_POWER_AUTOCOUNT_MASK (0xffff << SDRC_POWER_AUTOCOUNT_SHIFT)
-#define SDRC_POWER_CLKCTRL_SHIFT 4
-#define SDRC_POWER_CLKCTRL_MASK (0x3 << SDRC_POWER_CLKCTRL_SHIFT)
-#define SDRC_SELF_REFRESH_ON_AUTOCOUNT (0x2 << SDRC_POWER_CLKCTRL_SHIFT)
-
 /* Scratchpad offsets */
 #define OMAP343X_TABLE_ADDRESS_OFFSET     0x31
 #define OMAP343X_TABLE_VALUE_OFFSET       0x30
@@ -402,19 +396,15 @@ static void omap_sram_idle(void)
        }
 
        /*
-        * Force SDRAM controller to self-refresh mode after timeout on
-        * autocount. This is needed on ES3.0 to avoid SDRAM controller
-        * hang-ups.
-        */
+       * On EMU/HS devices ROM code restores a SRDC value
+       * from scratchpad which has automatic self refresh on timeout
+       * of AUTO_CNT = 1 enabled. This takes care of errata 1.142.
+       * Hence store/restore the SDRC_POWER register here.
+       */
        if (omap_rev() >= OMAP3430_REV_ES3_0 &&
            omap_type() != OMAP2_DEVICE_TYPE_GP &&
-           core_next_state == PWRDM_POWER_OFF) {
+           core_next_state == PWRDM_POWER_OFF)
                sdrc_pwr = sdrc_read_reg(SDRC_POWER);
-               sdrc_write_reg((sdrc_pwr &
-                       ~(SDRC_POWER_AUTOCOUNT_MASK|SDRC_POWER_CLKCTRL_MASK)) |
-                       (1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
-                       SDRC_SELF_REFRESH_ON_AUTOCOUNT, SDRC_POWER);
-       }
 
        /*
         * omap3_arm_context is the location where ARM registers
@@ -424,7 +414,7 @@ static void omap_sram_idle(void)
        _omap_sram_idle(omap3_arm_context, save_state);
        cpu_init();
 
-       /* Restore normal SDRAM settings */
+       /* Restore normal SDRC POWER settings */
        if (omap_rev() >= OMAP3430_REV_ES3_0 &&
            omap_type() != OMAP2_DEVICE_TYPE_GP &&
            core_next_state == PWRDM_POWER_OFF)
index 772b71e8b44f5f46f361046cd362111b3abb0eb3..f704030d2a701f434eeb0defac83637330cb878c 100644 (file)
 #define SDRC_RFR_CTRL_1                0x0D4
 #define SDRC_MANUAL_1          0x0D8
 
+#define SDRC_POWER_AUTOCOUNT_SHIFT     8
+#define SDRC_POWER_AUTOCOUNT_MASK      (0xffff << SDRC_POWER_AUTOCOUNT_SHIFT)
+#define SDRC_POWER_CLKCTRL_SHIFT       4
+#define SDRC_POWER_CLKCTRL_MASK                (0x3 << SDRC_POWER_CLKCTRL_SHIFT)
+#define SDRC_SELF_REFRESH_ON_AUTOCOUNT (0x2 << SDRC_POWER_CLKCTRL_SHIFT)
+
 /*
  * These values represent the number of memory clock cycles between
  * autorefresh initiation.  They assume 1 refresh per 64 ms (JEDEC), 8192