ARM: at91: suspend both memory controllers on at91sam9263
authorArnd Bergmann <arnd@arndb.de>
Fri, 25 Jan 2013 22:44:17 +0000 (22:44 +0000)
committerNicolas Ferre <nicolas.ferre@atmel.com>
Thu, 18 Apr 2013 14:31:02 +0000 (16:31 +0200)
For the past three years, we have had a #warning in
mach-at91 about the sdram_selfrefresh_enable or
at91sam9_standby functions possibly not working on
at91sam9263. In the meantime a function was added
to do the right thing on at91sam9g45, which looks like
it should also work on '9263.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
[nicolas.ferre@atmel.com: remove paragraph in commit message]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
arch/arm/mach-at91/cpuidle.c
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h

index 0c63815..4c67946 100644 (file)
@@ -38,6 +38,8 @@ static int at91_enter_idle(struct cpuidle_device *dev,
                at91rm9200_standby();
        else if (cpu_is_at91sam9g45())
                at91sam9g45_standby();
+       else if (cpu_is_at91sam9263())
+               at91sam9263_standby();
        else
                at91sam9_standby();
 
index adb6db8..b8017c1 100644 (file)
@@ -267,6 +267,8 @@ static int at91_pm_enter(suspend_state_t state)
                                at91rm9200_standby();
                        else if (cpu_is_at91sam9g45())
                                at91sam9g45_standby();
+                       else if (cpu_is_at91sam9263())
+                               at91sam9263_standby();
                        else
                                at91sam9_standby();
                        break;
index 38f467c..2f5908f 100644 (file)
@@ -70,13 +70,31 @@ static inline void at91sam9g45_standby(void)
        at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
-#ifdef CONFIG_SOC_AT91SAM9263
-/*
- * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
- * handle those cases both here and in the Suspend-To-RAM support.
+/* We manage both DDRAM/SDRAM controllers, we need more than one value to
+ * remember.
  */
-#warning Assuming EB1 SDRAM controller is *NOT* used
-#endif
+static inline void at91sam9263_standby(void)
+{
+       u32 lpr0, lpr1;
+       u32 saved_lpr0, saved_lpr1;
+
+       saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR);
+       lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB;
+       lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
+
+       saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR);
+       lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB;
+       lpr0 |= AT91_SDRAMC_LPCB_SELF_REFRESH;
+
+       /* self-refresh mode now */
+       at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0);
+       at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1);
+
+       cpu_do_idle();
+
+       at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0);
+       at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
+}
 
 static inline void at91sam9_standby(void)
 {