1
2
3
4
5
6 #include <linux/linkage.h>
7 #include <asm/assembler.h>
8 #include <asm/asm-offsets.h>
9 #include <asm/hardware/cache-l2x0.h>
10 #include "hardware.h"
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #define PM_INFO_PBASE_OFFSET 0x0
41 #define PM_INFO_RESUME_ADDR_OFFSET 0x4
42 #define PM_INFO_DDR_TYPE_OFFSET 0x8
43 #define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
44 #define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
45 #define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
46 #define PM_INFO_MX6Q_SRC_P_OFFSET 0x18
47 #define PM_INFO_MX6Q_SRC_V_OFFSET 0x1C
48 #define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x20
49 #define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x24
50 #define PM_INFO_MX6Q_CCM_P_OFFSET 0x28
51 #define PM_INFO_MX6Q_CCM_V_OFFSET 0x2C
52 #define PM_INFO_MX6Q_GPC_P_OFFSET 0x30
53 #define PM_INFO_MX6Q_GPC_V_OFFSET 0x34
54 #define PM_INFO_MX6Q_L2_P_OFFSET 0x38
55 #define PM_INFO_MX6Q_L2_V_OFFSET 0x3C
56 #define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
57 #define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
58
59 #define MX6Q_SRC_GPR1 0x20
60 #define MX6Q_SRC_GPR2 0x24
61 #define MX6Q_MMDC_MAPSR 0x404
62 #define MX6Q_MMDC_MPDGCTRL0 0x83c
63 #define MX6Q_GPC_IMR1 0x08
64 #define MX6Q_GPC_IMR2 0x0c
65 #define MX6Q_GPC_IMR3 0x10
66 #define MX6Q_GPC_IMR4 0x14
67 #define MX6Q_CCM_CCR 0x0
68
69 .align 3
70
71 .macro sync_l2_cache
72
73
74 #ifdef CONFIG_CACHE_L2X0
75 ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
76 teq r11, #0
77 beq 6f
78 mov r6, #0x0
79 str r6, [r11, #L2X0_CACHE_SYNC]
80 1:
81 ldr r6, [r11, #L2X0_CACHE_SYNC]
82 ands r6, r6, #0x1
83 bne 1b
84 6:
85 #endif
86
87 .endm
88
89 .macro resume_mmdc
90
91
92 cmp r5, #0x0
93 ldreq r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
94 ldrne r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
95
96 ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
97 ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
98 add r7, r7, r0
99 1:
100 ldr r8, [r7], #0x4
101 ldr r9, [r7], #0x4
102 str r9, [r11, r8]
103 subs r6, r6, #0x1
104 bne 1b
105
106 cmp r5, #0x0
107 ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
108 ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
109
110 cmp r3, #IMX_DDR_TYPE_LPDDR2
111 bne 4f
112
113
114 ldr r7, =MX6Q_MMDC_MPDGCTRL0
115 ldr r6, [r11, r7]
116 orr r6, r6, #(1 << 31)
117 str r6, [r11, r7]
118 2:
119 ldr r6, [r11, r7]
120 ands r6, r6, #(1 << 31)
121 bne 2b
122
123
124 ldr r6, [r11, r7]
125 orr r6, r6, #(1 << 31)
126 str r6, [r11, r7]
127 3:
128 ldr r6, [r11, r7]
129 ands r6, r6, #(1 << 31)
130 bne 3b
131 4:
132
133 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
134 bic r7, r7, #(1 << 21)
135 str r7, [r11, #MX6Q_MMDC_MAPSR]
136 5:
137 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
138 ands r7, r7, #(1 << 25)
139 bne 5b
140
141
142 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
143 bic r7, r7, #0x1
144 str r7, [r11, #MX6Q_MMDC_MAPSR]
145
146 .endm
147
148 ENTRY(imx6_suspend)
149 ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
150 ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
151 ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
152 ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
153
154
155
156
157
158 ldr r6, =imx6_suspend
159 ldr r7, =resume
160 sub r7, r7, r6
161 add r8, r1, r4
162 add r9, r8, r7
163
164
165
166
167
168
169 ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
170 ldr r6, [r11, #0x0]
171 ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
172 ldr r6, [r11, #0x0]
173 ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
174 ldr r6, [r11, #0x0]
175
176
177 ldr r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
178
179 str r9, [r11, #MX6Q_SRC_GPR1]
180 str r1, [r11, #MX6Q_SRC_GPR2]
181
182
183 sync_l2_cache
184
185 ldr r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
186
187
188
189
190 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
191 orr r7, r7, #0x1
192 str r7, [r11, #MX6Q_MMDC_MAPSR]
193
194
195 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
196 orr r7, r7, #(1 << 21)
197 str r7, [r11, #MX6Q_MMDC_MAPSR]
198
199 poll_dvfs_set:
200 ldr r7, [r11, #MX6Q_MMDC_MAPSR]
201 ands r7, r7, #(1 << 25)
202 beq poll_dvfs_set
203
204 ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
205 ldr r6, =0x0
206 ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
207 ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
208 add r8, r8, r0
209
210 cmp r3, #IMX_DDR_TYPE_LPDDR2
211 subeq r7, r7, #0x3
212 set_mmdc_io_lpm:
213 ldr r9, [r8], #0x8
214 str r6, [r11, r9]
215 subs r7, r7, #0x1
216 bne set_mmdc_io_lpm
217
218 cmp r3, #IMX_DDR_TYPE_LPDDR2
219 bne set_mmdc_io_lpm_done
220 ldr r6, =0x1000
221 ldr r9, [r8], #0x8
222 str r6, [r11, r9]
223 ldr r9, [r8], #0x8
224 str r6, [r11, r9]
225 ldr r6, =0x80000
226 ldr r9, [r8]
227 str r6, [r11, r9]
228 set_mmdc_io_lpm_done:
229
230
231
232
233
234
235
236
237 ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
238 ldr r6, [r11, #MX6Q_GPC_IMR1]
239 ldr r7, [r11, #MX6Q_GPC_IMR2]
240 ldr r8, [r11, #MX6Q_GPC_IMR3]
241 ldr r9, [r11, #MX6Q_GPC_IMR4]
242
243 ldr r10, =0xffffffff
244 str r10, [r11, #MX6Q_GPC_IMR1]
245 str r10, [r11, #MX6Q_GPC_IMR2]
246 str r10, [r11, #MX6Q_GPC_IMR3]
247 str r10, [r11, #MX6Q_GPC_IMR4]
248
249
250
251
252
253
254
255 ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
256 ldr r10, [r11, #MX6Q_CCM_CCR]
257 bic r10, r10, #(0x3f << 21)
258 orr r10, r10, #(0x20 << 21)
259 str r10, [r11, #MX6Q_CCM_CCR]
260
261
262 ldr r10, [r11, #MX6Q_CCM_CCR]
263 orr r10, r10, #(0x1 << 27)
264 str r10, [r11, #MX6Q_CCM_CCR]
265
266
267 ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
268 str r6, [r11, #MX6Q_GPC_IMR1]
269 str r7, [r11, #MX6Q_GPC_IMR2]
270 str r8, [r11, #MX6Q_GPC_IMR3]
271 str r9, [r11, #MX6Q_GPC_IMR4]
272
273
274
275
276
277
278
279
280
281
282
283 ldr r6, =2000
284 rbc_loop:
285 subs r6, r6, #0x1
286 bne rbc_loop
287
288
289 wfi
290 nop
291 nop
292 nop
293 nop
294
295
296
297
298
299
300 mov r5, #0x0
301 resume_mmdc
302
303
304 ret lr
305
306 resume:
307
308 mov r6, #0x0
309 mcr p15, 0, r6, c7, c5, 0
310 mcr p15, 0, r6, c7, c5, 6
311
312 mov r6, #0x1800
313 mcr p15, 0, r6, c1, c0, 0
314 isb
315
316
317 ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
318
319 ldr r11, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
320 mov r7, #0x0
321 str r7, [r11, #MX6Q_SRC_GPR1]
322 str r7, [r11, #MX6Q_SRC_GPR2]
323
324 ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
325 mov r5, #0x1
326 resume_mmdc
327
328 ret lr
329 ENDPROC(imx6_suspend)