]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-pxa/standby.S
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux...
[linux-2.6-omap-h63xx.git] / arch / arm / mach-pxa / standby.S
index d774430d02c0c058a038a584723863e1779678dd..167412e6bec894bba22674be98ba1b96f2282681 100644 (file)
@@ -17,6 +17,7 @@
 
                .text
 
+#ifdef CONFIG_PXA27x
 ENTRY(pxa_cpu_standby)
        ldr     r0, =PSSR
        mov     r1, #(PSSR_PH | PSSR_STS)
@@ -29,3 +30,85 @@ ENTRY(pxa_cpu_standby)
 1:     mcr     p14, 0, r2, c7, c0, 0   @ put the system into Standby
        str     r1, [r0]                @ make sure PSSR_PH/STS are clear
        mov     pc, lr
+
+#endif
+
+#ifdef CONFIG_PXA3xx
+
+#define MDCNFG         0x0000
+#define MDCNFG_DMCEN   (1 << 30)
+#define DDR_HCAL       0x0060
+#define DDR_HCAL_HCRNG 0x1f
+#define DDR_HCAL_HCPROG        (1 << 28)
+#define DDR_HCAL_HCEN  (1 << 31)
+#define DMCIER         0x0070
+#define DMCIER_EDLP    (1 << 29)
+#define DMCISR         0x0078
+#define RCOMP          0x0100
+#define RCOMP_SWEVAL   (1 << 31)
+
+ENTRY(pm_enter_standby_start)
+       mov     r1, #0xf6000000         @ DMEMC_REG_BASE (MDCNFG)
+       add     r1, r1, #0x00100000
+
+       /*
+        * Preload the TLB entry for accessing the dynamic memory
+        * controller registers.  Note that page table lookups will
+        * fail until the dynamic memory controller has been
+        * reinitialised - and that includes MMU page table walks.
+        * This also means that only the dynamic memory controller
+        * can be reliably accessed in the code following standby.
+        */
+       ldr     r2, [r1]                @ Dummy read MDCNFG
+
+       mcr     p14, 0, r0, c7, c0, 0
+       .rept   8
+       nop
+       .endr
+
+       ldr     r0, [r1, #DDR_HCAL]     @ Clear (and wait for) HCEN
+       bic     r0, r0, #DDR_HCAL_HCEN
+       str     r0, [r1, #DDR_HCAL]
+1:     ldr     r0, [r1, #DDR_HCAL]
+       tst     r0, #DDR_HCAL_HCEN
+       bne     1b
+
+       ldr     r0, [r1, #RCOMP]        @ Initiate RCOMP
+       orr     r0, r0, #RCOMP_SWEVAL
+       str     r0, [r1, #RCOMP]
+
+       mov     r0, #~0                 @ Clear interrupts
+       str     r0, [r1, #DMCISR]
+
+       ldr     r0, [r1, #DMCIER]       @ set DMIER[EDLP]
+       orr     r0, r0, #DMCIER_EDLP
+       str     r0, [r1, #DMCIER]
+
+       ldr     r0, [r1, #DDR_HCAL]     @ clear HCRNG, set HCPROG, HCEN
+       bic     r0, r0, #DDR_HCAL_HCRNG
+       orr     r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG
+       str     r0, [r1, #DDR_HCAL]
+
+1:     ldr     r0, [r1, #DMCISR]
+       tst     r0, #DMCIER_EDLP
+       beq     1b
+
+       ldr     r0, [r1, #MDCNFG]       @ set MDCNFG[DMCEN]
+       orr     r0, r0, #MDCNFG_DMCEN
+       str     r0, [r1, #MDCNFG]
+1:     ldr     r0, [r1, #MDCNFG]
+       tst     r0, #MDCNFG_DMCEN
+       beq     1b
+
+       ldr     r0, [r1, #DDR_HCAL]     @ set DDR_HCAL[HCRNG]
+       orr     r0, r0, #2 @ HCRNG
+       str     r0, [r1, #DDR_HCAL]
+
+       ldr     r0, [r1, #DMCIER]       @ Clear the interrupt
+       bic     r0, r0, #0x20000000
+       str     r0, [r1, #DMCIER]
+
+       mov     pc, lr
+ENTRY(pm_enter_standby_end)
+
+#endif