1. Patch to disable dynamic sleep (as it is not supported
   on AM35xx).
2. Imported the unique suspend/resume sequence for AM3517,
   contained in the new file arch/arm/mach-omap2/sleep3517.S.
3. Added omap3517_ to symbol-names in sleep3517.S which are common
   with sleep34xx.S, and added appropriate checks.

There are still 3 caveats:

1. If "no_console_suspend" is enabled (via boot-args), the device
   doesnot resume but simply hangs.
2. Every second and subsequent attempt to suspend/resume prints this slow-path
   WARNING (for both uart1 and uart2), while resuming :
   [   70.943939] omap_hwmod: uart1: idle state can only be entered from
   enabled state
3. Wakeup using the TSC2004 touch-screen controller is not supported.

Signed-off-by: Ranjith Lohithakshan <[email protected]>
Reviewed-by: Vaibhav Hiremath <[email protected]>
Signed-off-by: Abhilash K V <[email protected]>
---
 arch/arm/mach-omap2/Makefile    |    2 +-
 arch/arm/mach-omap2/control.c   |    7 ++-
 arch/arm/mach-omap2/control.h   |    1 +
 arch/arm/mach-omap2/pm.h        |    4 +
 arch/arm/mach-omap2/pm34xx.c    |   18 ++++-
 arch/arm/mach-omap2/sleep3517.S |  144 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 170 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/mach-omap2/sleep3517.S

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 46f5fbc..3fdf086 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -61,7 +61,7 @@ endif
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)               += pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)               += sleep24xx.o
-obj-$(CONFIG_ARCH_OMAP3)               += pm34xx.o sleep34xx.o \
+obj-$(CONFIG_ARCH_OMAP3)               += pm34xx.o sleep34xx.o sleep3517.o \
                                           cpuidle34xx.o
 obj-$(CONFIG_ARCH_OMAP4)               += pm44xx.o
 obj-$(CONFIG_PM_DEBUG)                 += pm-debug.o
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index da53ba3..7d2d8a8 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -284,10 +284,13 @@ void omap3_save_scratchpad_contents(void)
         * The restore pointer is stored into the scratchpad.
         */
        scratchpad_contents.boot_config_ptr = 0x0;
-       if (cpu_is_omap3630())
+       if (cpu_is_omap3505() || cpu_is_omap3517()) {
+               scratchpad_contents.public_restore_ptr =
+                       virt_to_phys(omap3517_get_restore_pointer());
+       } else if (cpu_is_omap3630()) {
                scratchpad_contents.public_restore_ptr =
                        virt_to_phys(get_omap3630_restore_pointer());
-       else if (omap_rev() != OMAP3430_REV_ES3_0 &&
+       } else if (omap_rev() != OMAP3430_REV_ES3_0 &&
                                        omap_rev() != OMAP3430_REV_ES3_1)
                scratchpad_contents.public_restore_ptr =
                        virt_to_phys(get_restore_pointer());
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index ad024df..3003940 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -389,6 +389,7 @@ extern void omap4_ctrl_pad_writel(u32 val, u16 offset);
 extern void omap3_save_scratchpad_contents(void);
 extern void omap3_clear_scratchpad_contents(void);
 extern u32 *get_restore_pointer(void);
+extern u32 *omap3517_get_restore_pointer(void);
 extern u32 *get_es3_restore_pointer(void);
 extern u32 *get_omap3630_restore_pointer(void);
 extern u32 omap3_arm_context[128];
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 5c2bd2f..d773e07 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -77,13 +77,17 @@ extern void omap24xx_idle_loop_suspend(void);
 extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
                                        void __iomem *sdrc_power);
 extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
+extern void omap3517_cpu_suspend(u32 *addr, int save_state);
 extern int save_secure_ram_context(u32 *addr);
+extern void omap3517_save_secure_ram_context(u32 *addr);
 extern void omap3_save_scratchpad_contents(void);
 
 extern unsigned int omap24xx_idle_loop_suspend_sz;
 extern unsigned int save_secure_ram_context_sz;
+extern unsigned int omap3517_save_secure_ram_context_sz;
 extern unsigned int omap24xx_cpu_suspend_sz;
 extern unsigned int omap34xx_cpu_suspend_sz;
+extern unsigned int omap3517_cpu_suspend_sz;
 
 #define PM_RTA_ERRATUM_i608            (1 << 0)
 #define PM_SDRC_WAKEUP_ERRATUM_i583    (1 << 1)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 96a7624..12af5b9 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -497,6 +497,8 @@ console_still_active:
 
 int omap3_can_sleep(void)
 {
+       if (cpu_is_omap3505() || cpu_is_omap3517())
+               return 0;
        if (!omap_uart_can_sleep())
                return 0;
        return 1;
@@ -848,11 +850,21 @@ static int __init clkdms_setup(struct clockdomain *clkdm, 
void *unused)
 
 void omap_push_sram_idle(void)
 {
-       _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
+       if (cpu_is_omap3505() || cpu_is_omap3517())
+               _omap_sram_idle = omap_sram_push(omap3517_cpu_suspend,
+                                       omap3517_cpu_suspend_sz);
+       else
+               _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
                                        omap34xx_cpu_suspend_sz);
        if (omap_type() != OMAP2_DEVICE_TYPE_GP)
-               _omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
-                               save_secure_ram_context_sz);
+               if (cpu_is_omap3505() || cpu_is_omap3517())
+                       _omap_save_secure_sram = omap_sram_push(
+                                       omap3517_save_secure_ram_context,
+                                       omap3517_save_secure_ram_context_sz);
+               else
+                       _omap_save_secure_sram = omap_sram_push(
+                                       save_secure_ram_context,
+                                       save_secure_ram_context_sz);
 }
 
 static void __init pm_errata_configure(void)
diff --git a/arch/arm/mach-omap2/sleep3517.S b/arch/arm/mach-omap2/sleep3517.S
new file mode 100644
index 0000000..3fceefc
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep3517.S
@@ -0,0 +1,144 @@
+/*
+/* linux/arch/arm/mach-omap2/sleep3517.S
+ *
+ * AM3505/3517 Sleep Code.
+ * Ranjith Lohithakshan <[email protected]>
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <plat/sram.h>
+#include <mach/io.h>
+
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "sdrc.h"
+#include "control.h"
+
+#define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
+#define CM_CLKST_CORE_V   OMAP34XX_CM_REGADDR(CORE_MOD, OMAP3430_CM_CLKSTST)
+#define CM_ICLKEN1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1)
+
+#define EMIF_PM_CTR_V           OMAP2_L3_IO_ADDRESS(0x6D000038)
+#define OMAP3517_CONF1_REG_V    OMAP2_L4_IO_ADDRESS(0x48002584)
+
+/*
+ * Forces OMAP into idle state
+ *
+ * omap34xx_suspend() - This bit of code just executes the WFI
+ * for normal idles.
+ *
+ * Note: This code get's copied to internal SRAM at boot. When the OMAP
+ *      wakes up it continues execution at the point it went to sleep.
+ */
+ENTRY(omap3517_cpu_suspend)
+       stmfd   sp!, {r0-r12, lr}               @ save registers on stack
+loop:
+       /*b     loop*/  @Enable to debug by stepping through code
+
+       /* Put EMIF in self-refresh */
+       ldr     r4, emif_pm_ctrl
+       ldr     r5, [r4]
+       orr     r5, r5, #0x200
+       str     r5, [r4]
+
+       /* Disable SDRC and Control Module */
+       ldr     r4, cm_iclken1_core
+       ldr     r5, clk_core_disable
+       str     r5, [r4]
+wait_sdrc_ok:
+       ldr     r4, cm_idlest1_core
+       ldr     r5, [r4]
+       and     r5, r5, #0x2
+       cmp     r5, #0x2
+       bne     wait_sdrc_ok
+
+       /* Gate DDR Phy clock */
+       ldr     r4, omap3517_conf1
+       ldr     r5, emif_phy_gate
+       str     r5, [r4]
+
+       /* Data memory barrier and Data sync barrier */
+       mov     r1, #0
+       mcr     p15, 0, r1, c7, c10, 4
+       mcr     p15, 0, r1, c7, c10, 5
+
+       wfi
+
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+
+       /* Enable SDRC and Control Module */
+       ldr     r4, cm_iclken1_core
+       ldr     r5, iclk_core_enable
+       str     r5, [r4]
+
+       /* Enable DDR Phy Clock */
+       ldr     r4, omap3517_conf1
+       ldr     r5, emif_phy_enable
+       str     r5, [r4]
+
+       /* Take EMIF out of self-refresh */
+       ldr     r4, emif_pm_ctrl
+       ldr     r5, [r4]
+       bic     r5, r5, #0x200
+       str     r5, [r4]
+
+       ldmfd   sp!, {r0-r12, pc}               @ restore regs and return
+
+clk_core_disable:
+       .word   0x0
+iclk_core_enable:
+       .word   0x42
+emif_phy_gate:
+       .word   0x2620
+emif_phy_enable:
+       .word   0x8620
+cm_idlest1_core:
+       .word   CM_IDLEST1_CORE_V
+cm_clkst_core:
+       .word   CM_CLKST_CORE_V
+emif_pm_ctrl:
+       .word   EMIF_PM_CTR_V
+cm_iclken1_core:
+       .word   CM_ICLKEN1_CORE_V
+omap3517_conf1:
+       .word   OMAP3517_CONF1_REG_V
+ENTRY(omap3517_cpu_suspend_sz)
+       .word   . - omap3517_cpu_suspend
+
+/* Function to call rom code to save secure ram context */
+ENTRY(omap3517_save_secure_ram_context)
+       stmfd   sp!, {r1-r12, lr}   @ save registers on stack
+save_secure_ram_debug:
+       /* b save_secure_ram_debug */   @ enable to debug save code
+       ldmfd   sp!, {r1-r12, pc}
+ENTRY(omap3517_save_secure_ram_context_sz)
+       .word   . - omap3517_save_secure_ram_context
+
+/* Function call to get the restore pointer for resume from OFF */
+ENTRY(omap3517_get_restore_pointer)
+       stmfd   sp!, {lr}     @ save registers on stack
+       ldmfd   sp!, {pc}     @ restore regs and return
+ENTRY(omap3517_get_restore_pointer_sz)
+       .word   . - omap3517_get_restore_pointer
+
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to