]> err.no Git - linux-2.6/blobdiff - arch/arm/mach-pxa/standby.S
[IA64] allocate multiple contiguous pages via uncached allocator
[linux-2.6] / arch / arm / mach-pxa / standby.S
index 434a6ab0eca517b876c17ee9b2c41a808430bf3b..167412e6bec894bba22674be98ba1b96f2282681 100644 (file)
@@ -32,3 +32,83 @@ ENTRY(pxa_cpu_standby)
        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