Merge git://git.infradead.org/~dedekind/ubi-2.6
[linux-2.6] / arch / arm / mach-pxa / standby.S
1 /*
2  * PXA27x standby mode
3  *
4  * Author: David Burrage
5  *
6  * 2005 (c) MontaVista Software, Inc. This file is licensed under
7  * the terms of the GNU General Public License version 2. This program
8  * is licensed "as is" without any warranty of any kind, whether express
9  * or implied.
10  */
11
12 #include <linux/linkage.h>
13 #include <asm/assembler.h>
14 #include <asm/hardware.h>
15
16 #include <asm/arch/pxa-regs.h>
17
18                 .text
19
20 #ifdef CONFIG_PXA27x
21 ENTRY(pxa_cpu_standby)
22         ldr     r0, =PSSR
23         mov     r1, #(PSSR_PH | PSSR_STS)
24         mov     r2, #PWRMODE_STANDBY
25         mov     r3, #UNCACHED_PHYS_0    @ Read mem context in.
26         ldr     ip, [r3]
27         b       1f
28
29         .align  5
30 1:      mcr     p14, 0, r2, c7, c0, 0   @ put the system into Standby
31         str     r1, [r0]                @ make sure PSSR_PH/STS are clear
32         mov     pc, lr
33
34 #endif
35
36 #ifdef CONFIG_PXA3xx
37
38 #define MDCNFG          0x0000
39 #define MDCNFG_DMCEN    (1 << 30)
40 #define DDR_HCAL        0x0060
41 #define DDR_HCAL_HCRNG  0x1f
42 #define DDR_HCAL_HCPROG (1 << 28)
43 #define DDR_HCAL_HCEN   (1 << 31)
44 #define DMCIER          0x0070
45 #define DMCIER_EDLP     (1 << 29)
46 #define DMCISR          0x0078
47 #define RCOMP           0x0100
48 #define RCOMP_SWEVAL    (1 << 31)
49
50 ENTRY(pm_enter_standby_start)
51         mov     r1, #0xf6000000         @ DMEMC_REG_BASE (MDCNFG)
52         add     r1, r1, #0x00100000
53
54         /*
55          * Preload the TLB entry for accessing the dynamic memory
56          * controller registers.  Note that page table lookups will
57          * fail until the dynamic memory controller has been
58          * reinitialised - and that includes MMU page table walks.
59          * This also means that only the dynamic memory controller
60          * can be reliably accessed in the code following standby.
61          */
62         ldr     r2, [r1]                @ Dummy read MDCNFG
63
64         mcr     p14, 0, r0, c7, c0, 0
65         .rept   8
66         nop
67         .endr
68
69         ldr     r0, [r1, #DDR_HCAL]     @ Clear (and wait for) HCEN
70         bic     r0, r0, #DDR_HCAL_HCEN
71         str     r0, [r1, #DDR_HCAL]
72 1:      ldr     r0, [r1, #DDR_HCAL]
73         tst     r0, #DDR_HCAL_HCEN
74         bne     1b
75
76         ldr     r0, [r1, #RCOMP]        @ Initiate RCOMP
77         orr     r0, r0, #RCOMP_SWEVAL
78         str     r0, [r1, #RCOMP]
79
80         mov     r0, #~0                 @ Clear interrupts
81         str     r0, [r1, #DMCISR]
82
83         ldr     r0, [r1, #DMCIER]       @ set DMIER[EDLP]
84         orr     r0, r0, #DMCIER_EDLP
85         str     r0, [r1, #DMCIER]
86
87         ldr     r0, [r1, #DDR_HCAL]     @ clear HCRNG, set HCPROG, HCEN
88         bic     r0, r0, #DDR_HCAL_HCRNG
89         orr     r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG
90         str     r0, [r1, #DDR_HCAL]
91
92 1:      ldr     r0, [r1, #DMCISR]
93         tst     r0, #DMCIER_EDLP
94         beq     1b
95
96         ldr     r0, [r1, #MDCNFG]       @ set MDCNFG[DMCEN]
97         orr     r0, r0, #MDCNFG_DMCEN
98         str     r0, [r1, #MDCNFG]
99 1:      ldr     r0, [r1, #MDCNFG]
100         tst     r0, #MDCNFG_DMCEN
101         beq     1b
102
103         ldr     r0, [r1, #DDR_HCAL]     @ set DDR_HCAL[HCRNG]
104         orr     r0, r0, #2 @ HCRNG
105         str     r0, [r1, #DDR_HCAL]
106
107         ldr     r0, [r1, #DMCIER]       @ Clear the interrupt
108         bic     r0, r0, #0x20000000
109         str     r0, [r1, #DMCIER]
110
111         mov     pc, lr
112 ENTRY(pm_enter_standby_end)
113
114 #endif