Commit | Line | Data |
---|---|---|
1579c7b9 MF |
1 | /* |
2 | * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. | |
3 | */ | |
4 | /* | |
5 | * The code contained herein is licensed under the GNU General Public | |
6 | * License. You may obtain a copy of the GNU General Public License | |
7 | * Version 2 or later at the following locations: | |
8 | * | |
9 | * http://www.opensource.org/licenses/gpl-license.html | |
10 | * http://www.gnu.org/copyleft/gpl.html | |
11 | */ | |
12 | ||
13 | #include <linux/linkage.h> | |
14 | ||
15 | #define M4IF_MCR0_OFFSET (0x008C) | |
16 | #define M4IF_MCR0_FDVFS (0x1 << 11) | |
17 | #define M4IF_MCR0_FDVACK (0x1 << 27) | |
18 | ||
19 | .align 3 | |
20 | ||
21 | /* | |
22 | * ==================== low level suspend ==================== | |
23 | * | |
24 | * On entry | |
25 | * r0: pm_info structure address; | |
26 | * | |
27 | * suspend ocram space layout: | |
28 | * ======================== high address ====================== | |
29 | * . | |
30 | * . | |
31 | * . | |
32 | * ^ | |
33 | * ^ | |
34 | * ^ | |
35 | * imx53_suspend code | |
36 | * PM_INFO structure(imx53_suspend_info) | |
37 | * ======================== low address ======================= | |
38 | */ | |
39 | ||
40 | /* Offsets of members of struct imx53_suspend_info */ | |
41 | #define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 | |
42 | #define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 | |
43 | #define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 | |
44 | #define SUSPEND_INFO_MX53_IO_STATE_OFFSET 0xc | |
45 | ||
46 | ENTRY(imx53_suspend) | |
47 | stmfd sp!, {r4,r5,r6,r7} | |
48 | ||
49 | /* Save pad config */ | |
50 | ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] | |
51 | cmp r1, #0 | |
52 | beq skip_pad_conf_1 | |
53 | ||
54 | add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET | |
55 | ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] | |
56 | ||
57 | 1: | |
58 | ldr r5, [r2], #12 /* IOMUXC register offset */ | |
59 | ldr r6, [r3, r5] /* current value */ | |
60 | str r6, [r2], #4 /* save area */ | |
61 | subs r1, r1, #1 | |
62 | bne 1b | |
63 | ||
64 | skip_pad_conf_1: | |
65 | /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */ | |
66 | ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] | |
67 | ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
68 | orr r2, r2, #M4IF_MCR0_FDVFS | |
69 | str r2,[r1, #M4IF_MCR0_OFFSET] | |
70 | ||
71 | /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */ | |
72 | wait_sr_ack: | |
73 | ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
74 | ands r2, r2, #M4IF_MCR0_FDVACK | |
75 | beq wait_sr_ack | |
76 | ||
77 | /* Set pad config */ | |
78 | ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] | |
79 | cmp r1, #0 | |
80 | beq skip_pad_conf_2 | |
81 | ||
82 | add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET | |
83 | ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] | |
84 | ||
85 | 2: | |
86 | ldr r5, [r2], #4 /* IOMUXC register offset */ | |
87 | ldr r6, [r2], #4 /* clear */ | |
88 | ldr r7, [r3, r5] | |
89 | bic r7, r7, r6 | |
90 | ldr r6, [r2], #8 /* set */ | |
91 | orr r7, r7, r6 | |
92 | str r7, [r3, r5] | |
93 | subs r1, r1, #1 | |
94 | bne 2b | |
95 | ||
96 | skip_pad_conf_2: | |
97 | /* Zzz, enter stop mode */ | |
98 | wfi | |
99 | nop | |
100 | nop | |
101 | nop | |
102 | nop | |
103 | ||
104 | /* Restore pad config */ | |
105 | ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] | |
106 | cmp r1, #0 | |
107 | beq skip_pad_conf_3 | |
108 | ||
109 | add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET | |
110 | ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] | |
111 | ||
112 | 3: | |
113 | ldr r5, [r2], #12 /* IOMUXC register offset */ | |
114 | ldr r6, [r2], #4 /* saved value */ | |
115 | str r6, [r3, r5] | |
116 | subs r1, r1, #1 | |
117 | bne 3b | |
118 | ||
119 | skip_pad_conf_3: | |
120 | /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */ | |
121 | ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] | |
122 | ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
123 | bic r2, r2, #M4IF_MCR0_FDVFS | |
124 | str r2,[r1, #M4IF_MCR0_OFFSET] | |
125 | ||
126 | /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */ | |
127 | wait_ar_ack: | |
128 | ldr r2,[r1, #M4IF_MCR0_OFFSET] | |
129 | ands r2, r2, #M4IF_MCR0_FDVACK | |
130 | bne wait_ar_ack | |
131 | ||
132 | /* Restore registers */ | |
133 | ldmfd sp!, {r4,r5,r6,r7} | |
134 | mov pc, lr | |
135 | ||
136 | ENDPROC(imx53_suspend) | |
137 | ||
138 | ENTRY(imx53_suspend_sz) | |
139 | .word . - imx53_suspend |